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