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