]>
git.saurik.com Git - apple/security.git/blob - Security/libsecurity_codesigning/lib/reqmaker.h
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 <security_codesigning/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
);
73 void copy(const void *data
, size_t length
)
74 { memcpy(this->alloc(length
), data
, length
); }
75 void copy(const Requirement
*req
); // inline expand
78 // Keep labels into exprOp code, and allow for "shifting in"
79 // prefix code as needed (exprOp is a prefix-code language).
83 Label(const Maker
&maker
) : pos((const Offset
)maker
.length()) { }
85 void *insert(const Label
&label
, size_t length
= sizeof(uint32_t));
88 Endian
<T
> &insert(const Label
&label
, size_t length
= sizeof(T
))
89 { return *reinterpret_cast<Endian
<T
>*>(insert(label
, length
)); }
92 // Help with making operator chains (foo AND bar AND baz...).
93 // Note that the empty case (no elements at all) must be resolved by the caller.
95 class Chain
: public Label
{
97 Chain(Maker
&myMaker
, ExprOp op
)
98 : Label(myMaker
), maker(myMaker
), mJoiner(op
), mCount(0) { }
101 { if (mCount
++) maker
.insert
<ExprOp
>(*this) = mJoiner
; }
104 bool empty() const { return mCount
== 0; }
108 mutable unsigned mCount
;
113 // Over-all construction management
115 void kind(Kind k
) { mBuffer
->kind(k
); }
116 size_t length() const { return mPC
; }
118 Requirement
*operator () () { return make(); }
121 void require(size_t size
);
122 void *alloc(size_t size
);
125 Requirement
*mBuffer
;