]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_codesigning/lib/signerutils.h
Security-59306.11.20.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / signerutils.h
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
b1ab9ed8
A
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// signerutils - utilities for signature generation
26//
27#ifndef _H_SIGNERUTILS
28#define _H_SIGNERUTILS
29
30#include "CodeSigner.h"
31#include "sigblob.h"
32#include "cdbuilder.h"
90dc47c2
A
33
34#include <Security/SecCmsBase.h>
35
b1ab9ed8
A
36#include <security_utilities/utilities.h>
37#include <security_utilities/blob.h>
38#include <security_utilities/unix++.h>
39#include <security_utilities/unixchild.h>
40
79b9da22
A
41#include <sys/cdefs.h>
42
43#if TARGET_OS_OSX
44__BEGIN_DECLS
45#include <AppleFSCompression/AppleFSCompression.h>
46__END_DECLS
47#endif
48
b1ab9ed8
A
49namespace Security {
50namespace CodeSigning {
51
52
53//
54// A helper to deal with the magic merger logic of internal requirements
55//
56class InternalRequirements : public Requirements::Maker {
57public:
58 InternalRequirements() : mReqs(NULL) { }
59 ~InternalRequirements() { ::free((void *)mReqs); }
60 void operator () (const Requirements *given, const Requirements *defaulted, const Requirement::Context &context);
61 operator const Requirements * () const { return mReqs; }
62
63private:
64 const Requirements *mReqs;
65};
66
67
68//
69// A DiskRep::Writer that assembles data in a SuperBlob (in memory)
70//
71class BlobWriter : public DiskRep::Writer, public EmbeddedSignatureBlob::Maker {
72public:
73 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
74};
75
76
77class DetachedBlobWriter : public BlobWriter {
78public:
79 DetachedBlobWriter(SecCodeSigner::Signer &s) : signer(s) { }
80
81 SecCodeSigner::Signer &signer;
82
83 void flush();
84};
85
86
87//
88// A multi-architecture editing assistant.
dbe77505 89// ArchEditor collects (Mach-O) architectures in use, and maintains per-architecture
b1ab9ed8
A
90// data structures. It must be subclassed to express a particular way to handle the signing
91// data.
92//
93class ArchEditor : public DiskRep::Writer {
94public:
e3d460c9 95 ArchEditor(Universal &fat, CodeDirectory::HashAlgorithms hashTypes, uint32_t attrs);
b1ab9ed8
A
96 virtual ~ArchEditor();
97
98public:
99 //
100 // One architecture's signing construction element.
101 // This also implements DispRep::Writer so generic writing code
102 // can work with both Mach-O and other files.
103 //
104 struct Arch : public BlobWriter {
105 Architecture architecture; // our architecture
106 auto_ptr<MachO> source; // Mach-O object to be signed
e3d460c9 107 std::map<CodeDirectory::HashAlgorithm, RefPointer<CodeDirectory::Builder> > cdBuilders;
b1ab9ed8
A
108 InternalRequirements ireqs; // consolidated internal requirements
109 size_t blobSize; // calculated SuperBlob size
110
e3d460c9
A
111 Arch(const Architecture &arch, CodeDirectory::HashAlgorithms hashTypes);
112
113 void eachDigest(void (^op)(CodeDirectory::Builder& builder))
114 {
115 for (auto type = cdBuilders.begin(); type != cdBuilders.end(); ++type)
116 op(*type->second);
117 }
b1ab9ed8
A
118 };
119
120 //
121 // Our callers access the architectural universe through a map
122 // from Architectures to Arch objects.
123 //
124 typedef std::map<Architecture, Arch *> ArchMap;
125 typedef ArchMap::iterator Iterator;
126 ArchMap::iterator begin() { return architecture.begin(); }
127 ArchMap::iterator end() { return architecture.end(); }
427c49bc 128 unsigned count() const { return (unsigned)architecture.size(); }
b1ab9ed8
A
129
130 // methods needed for an actual implementation
131 virtual void allocate() = 0; // interpass allocations
132 virtual void reset(Arch &arch) = 0; // pass 2 prep
133 virtual void write(Arch &arch, EmbeddedSignatureBlob *blob) = 0; // takes ownership of blob
134 virtual void commit() = 0; // write/flush result
135
136protected:
137 ArchMap architecture;
138};
139
140
141//
142// An ArchEditor that collects all architectures into a single SuperBlob,
143// usually for writing a detached multi-architecture signature.
144//
145class BlobEditor : public ArchEditor {
146public:
147 BlobEditor(Universal &fat, SecCodeSigner::Signer &s);
148
149 SecCodeSigner::Signer &signer;
150
151 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
152 void allocate() { }
153 void reset(Arch &arch) { }
154 void write(Arch &arch, EmbeddedSignatureBlob *blob);
155 void commit();
156
157private:
158 DetachedSignatureBlob::Maker mMaker;
159 EmbeddedSignatureBlob::Maker mGlobal;
160};
161
162
163//
164// An ArchEditor that writes its signatures into a (fat) binary file.
165// We do this by forking a helper tool (codesign_allocate) and asking
166// it to make a copy with suitable space "opened up" in the right spots.
167//
168class MachOEditor : public ArchEditor, private UnixPlusPlus::Child {
169public:
e3d460c9 170 MachOEditor(DiskRep::Writer *w, Universal &code, CodeDirectory::HashAlgorithms hashTypes, std::string srcPath);
b1ab9ed8
A
171 ~MachOEditor();
172
173 const RefPointer<DiskRep::Writer> writer;
174 const std::string sourcePath;
175 const std::string tempPath;
176
177 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
178 void allocate();
179 void reset(Arch &arch);
180 void write(Arch &arch, EmbeddedSignatureBlob *blob);
181 void commit();
182
183private:
e3d460c9
A
184 CodeDirectory::HashAlgorithms mHashTypes;
185
b1ab9ed8
A
186 // fork operation
187 void childAction();
188 void parentAction();
189
190 // controlling the temporary file copy
191 Universal *mNewCode;
192 UnixPlusPlus::AutoFileDesc mFd;
193 bool mTempMayExist;
194
195 // finding and managing the helper tool
196 const char *mHelperPath;
197 bool mHelperOverridden;
198};
199
200
201//
202// A Requirement::Context populated from a signing request.
203// We use this to help generate the explicit Designated Requirement
204// during signing ops, and thus this must be constructed BEFORE we
205// actually have a signed object.
206//
207class PreSigningContext : public Requirement::Context {
208public:
209 PreSigningContext(const SecCodeSigner::Signer &signer);
210
211private:
212 CFRef<CFArrayRef> mCerts; // hold cert chain
213};
e3d460c9
A
214
215
216//
217// A collector of CodeDirectories for hash-agile construction of signatures.
218//
219class CodeDirectorySet : public std::map<CodeDirectory::HashAlgorithm, const CodeDirectory *> {
220public:
221 CodeDirectorySet() { mPrimary = NULL; }
222 ~CodeDirectorySet();
223
224 void add(const CodeDirectory* cd);
225 void populate(DiskRep::Writer* writer) const;
226
227 const CodeDirectory* primary() const;
90dc47c2
A
228
229 // Note that the order of the hashList is relevant.
230 // (Which is also why there are separate methods, CFDictionary is not ordered.)
231 CFArrayRef hashList() const;
232 CFDictionaryRef hashDict() const;
233
234 static SECOidTag SECOidTagForAlgorithm(CodeDirectory::HashAlgorithm algorithm);
235
e3d460c9
A
236private:
237 mutable const CodeDirectory* mPrimary;
238};
b1ab9ed8
A
239
240
241} // end namespace CodeSigning
242} // end namespace Security
243
244#endif // !_H_SIGNERUTILS