]>
git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_codesigning/lib/reqmaker.h
a3ac0eedcab6fc7a02cda116aca144f586eacde7
   2  * Copyright (c) 2006,2011-2014 Apple Inc. All Rights Reserved. 
   4  * @APPLE_LICENSE_HEADER_START@ 
   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 
  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. 
  21  * @APPLE_LICENSE_HEADER_END@ 
  25 // reqmaker - Requirement assembler 
  30 #include "requirement.h" 
  33 namespace CodeSigning 
{ 
  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. 
  43 class Requirement::Maker 
{ 
  45         Maker(Kind k 
= exprForm
); 
  46         ~Maker() { free(mBuffer
); } 
  49         T 
*alloc(size_t size
) { return reinterpret_cast<T 
*>(alloc(size
)); } 
  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
)); } 
  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 
  66         void trustedAnchor(int slot
); 
  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
); 
  74         void copy(const void *data
, size_t length
) 
  75                 { memcpy(this->alloc(length
), data
, length
); } 
  76         void copy(const Requirement 
*req
);                              // inline expand 
  79         // Keep labels into exprOp code, and allow for "shifting in" 
  80         // prefix code as needed (exprOp is a prefix-code language). 
  84                 Label(const Maker 
&maker
) : pos((const Offset
)maker
.length()) { } 
  86         void *insert(const Label 
&label
, size_t length 
= sizeof(uint32_t)); 
  89         Endian
<T
> &insert(const Label 
&label
, size_t length 
= sizeof(T
)) 
  90         { return *reinterpret_cast<Endian
<T
>*>(insert(label
, length
)); } 
  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. 
  96         class Chain 
: public Label 
{ 
  98                 Chain(Maker 
&myMaker
, ExprOp op
) 
  99                         : Label(myMaker
), maker(myMaker
), mJoiner(op
), mCount(0) { } 
 102                         { if (mCount
++) maker
.insert
<ExprOp
>(*this) = mJoiner
; } 
 105                 bool empty() const { return mCount 
== 0; } 
 109                 mutable unsigned mCount
; 
 114         // Over-all construction management 
 116         void kind(Kind k
) { mBuffer
->kind(k
); } 
 117         size_t length() const { return mPC
; } 
 119         Requirement 
*operator () () { return make(); } 
 122         void require(size_t size
);       
 123         void *alloc(size_t size
); 
 126         Requirement 
*mBuffer
;