/ OSX / libsecurity_codesigning / lib / reqmaker.h
reqmaker.h
  1  /*
  2   * Copyright (c) 2006,2011-2014 Apple Inc. All Rights Reserved.
  3   * 
  4   * @APPLE_LICENSE_HEADER_START@
  5   * 
  6   * This file contains Original Code and/or Modifications of Original Code
  7   * as defined in and that are subject to the Apple Public Source License
  8   * Version 2.0 (the 'License'). You may not use this file except in
  9   * compliance with the License. Please obtain a copy of the License at
 10   * http://www.opensource.apple.com/apsl/ and read it before using this
 11   * file.
 12   * 
 13   * The Original Code and all software distributed under the License are
 14   * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
 15   * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
 16   * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
 17   * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
 18   * Please see the License for the specific language governing rights and
 19   * limitations under the License.
 20   * 
 21   * @APPLE_LICENSE_HEADER_END@
 22   */
 23  
 24  //
 25  // reqmaker - Requirement assembler
 26  //
 27  #ifndef _H_REQMAKER
 28  #define _H_REQMAKER
 29  
 30  #include "requirement.h"
 31  
 32  namespace Security {
 33  namespace CodeSigning {
 34  
 35  
 36  //
 37  // A Requirement::Maker is a tool for creating a Requirement blob.
 38  // It's primarily an assember for the binary requirements (exprOp) language.
 39  // Initialize it, call put() methods to generate the exprOp program, then
 40  // call make() to get the assembled Requirement blob, malloc'ed for you.
 41  // The Maker is not reusable.
 42  //
 43  class Requirement::Maker {
 44  public:
 45  	Maker(Kind k = exprForm);
 46  	~Maker() { free(mBuffer); }
 47  	
 48  	template <class T>
 49  	T *alloc(size_t size) { return reinterpret_cast<T *>(alloc(size)); }
 50  
 51  	template <class T>
 52  	void put(const T &value) { *alloc<Endian<T> >(sizeof(T)) = value; }
 53  	void put(ExprOp op) { put(uint32_t(op)); }
 54  	void put(MatchOperation op) { put(uint32_t(op)); }
 55  	void put(const std::string &s) { putData(s.data(), s.size()); }
 56  	void put(const char *s) { putData(s, strlen(s)); }
 57  	void putData(const void *data, size_t length);
 58  	void putData(CFStringRef s) { put(cfString(s)); }
 59  	
 60  	void anchor(int slot, SHA1::Digest digest);			// given slot/digest
 61  	void anchor(int slot, const void *cert, size_t length); // given slot/cert
 62  	void anchor();										// made-by-Apple
 63  	void anchorGeneric();								// anything drawn from the Apple anchor
 64  	
 65  	void trustedAnchor();
 66  	void trustedAnchor(int slot);
 67  	
 68  	void infoKey(const std::string &key, const std::string &value);
 69  	void ident(const std::string &identHash);
 70  	void cdhash(SHA1::Digest digest);
 71  	void cdhash(CFDataRef digest);
 72  	void platform(int platformIdentifier);
 73  
 74  	void copy(const void *data, size_t length)
 75  		{ memcpy(this->alloc(length), data, length); }
 76  	void copy(const Requirement *req);				// inline expand
 77  	
 78  	//
 79  	// Keep labels into exprOp code, and allow for "shifting in"
 80  	// prefix code as needed (exprOp is a prefix-code language).
 81  	//
 82  	struct Label {
 83  		const Offset pos;
 84  		Label(const Maker &maker) : pos((const Offset)maker.length()) { }
 85  	};
 86  	void *insert(const Label &label, size_t length = sizeof(uint32_t));
 87  	
 88  	template <class T>
 89  	Endian<T> &insert(const Label &label, size_t length = sizeof(T))
 90  	{ return *reinterpret_cast<Endian<T>*>(insert(label, length)); }
 91  
 92  	//
 93  	// Help with making operator chains (foo AND bar AND baz...).
 94  	// Note that the empty case (no elements at all) must be resolved by the caller.
 95  	//
 96  	class Chain : public Label {
 97  	public:
 98  		Chain(Maker &myMaker, ExprOp op)
 99  			: Label(myMaker), maker(myMaker), mJoiner(op), mCount(0) { }
100  
101  		void add() const
102  			{ if (mCount++) maker.insert<ExprOp>(*this) = mJoiner; }
103  	
104  		Maker &maker;
105  		bool empty() const { return mCount == 0; }
106  
107  	private:
108  		ExprOp mJoiner;
109  		mutable unsigned mCount;
110  	};
111  	
112  	
113  	//
114  	// Over-all construction management
115  	//
116  	void kind(Kind k) { mBuffer->kind(k); }
117  	size_t length() const { return mPC; }
118  	Requirement *make();
119  	Requirement *operator () () { return make(); }
120  	
121  protected:
122  	void require(size_t size);	
123  	void *alloc(size_t size);
124  
125  private:
126  	Requirement *mBuffer;
127  	Offset mSize;
128  	Offset mPC;
129  };
130  
131  
132  }	// CodeSigning
133  }	// Security
134  
135  #endif //_H_REQMAKER