]> git.saurik.com Git - apple/security.git/blob - Security/libsecurity_codesigning/lib/signerutils.h
Security-57031.40.6.tar.gz
[apple/security.git] / Security / libsecurity_codesigning / lib / signerutils.h
1 /*
2 * Copyright (c) 2006-2012 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 // 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
38 namespace Security {
39 namespace CodeSigning {
40
41
42 //
43 // A helper to deal with the magic merger logic of internal requirements
44 //
45 class InternalRequirements : public Requirements::Maker {
46 public:
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
52 private:
53 const Requirements *mReqs;
54 };
55
56
57 //
58 // A DiskRep::Writer that assembles data in a SuperBlob (in memory)
59 //
60 class BlobWriter : public DiskRep::Writer, public EmbeddedSignatureBlob::Maker {
61 public:
62 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
63 };
64
65
66 class DetachedBlobWriter : public BlobWriter {
67 public:
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 //
82 class ArchEditor : public DiskRep::Writer {
83 public:
84 ArchEditor(Universal &fat, CodeDirectory::HashAlgorithm hashType, uint32_t attrs);
85 virtual ~ArchEditor();
86
87 public:
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
96 CodeDirectory::Builder cdbuilder; // builder for CodeDirectory
97 InternalRequirements ireqs; // consolidated internal requirements
98 size_t blobSize; // calculated SuperBlob size
99
100 Arch(const Architecture &arch, CodeDirectory::HashAlgorithm hashType)
101 : architecture(arch), cdbuilder(hashType) { }
102 };
103
104 //
105 // Our callers access the architectural universe through a map
106 // from Architectures to Arch objects.
107 //
108 typedef std::map<Architecture, Arch *> ArchMap;
109 typedef ArchMap::iterator Iterator;
110 ArchMap::iterator begin() { return architecture.begin(); }
111 ArchMap::iterator end() { return architecture.end(); }
112 unsigned count() const { return (unsigned)architecture.size(); }
113
114 // methods needed for an actual implementation
115 virtual void allocate() = 0; // interpass allocations
116 virtual void reset(Arch &arch) = 0; // pass 2 prep
117 virtual void write(Arch &arch, EmbeddedSignatureBlob *blob) = 0; // takes ownership of blob
118 virtual void commit() = 0; // write/flush result
119
120 protected:
121 ArchMap architecture;
122 };
123
124
125 //
126 // An ArchEditor that collects all architectures into a single SuperBlob,
127 // usually for writing a detached multi-architecture signature.
128 //
129 class BlobEditor : public ArchEditor {
130 public:
131 BlobEditor(Universal &fat, SecCodeSigner::Signer &s);
132
133 SecCodeSigner::Signer &signer;
134
135 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
136 void allocate() { }
137 void reset(Arch &arch) { }
138 void write(Arch &arch, EmbeddedSignatureBlob *blob);
139 void commit();
140
141 private:
142 DetachedSignatureBlob::Maker mMaker;
143 EmbeddedSignatureBlob::Maker mGlobal;
144 };
145
146
147 //
148 // An ArchEditor that writes its signatures into a (fat) binary file.
149 // We do this by forking a helper tool (codesign_allocate) and asking
150 // it to make a copy with suitable space "opened up" in the right spots.
151 //
152 class MachOEditor : public ArchEditor, private UnixPlusPlus::Child {
153 public:
154 MachOEditor(DiskRep::Writer *w, Universal &code, CodeDirectory::HashAlgorithm hashType, std::string srcPath);
155 ~MachOEditor();
156
157 const RefPointer<DiskRep::Writer> writer;
158 const std::string sourcePath;
159 const std::string tempPath;
160
161 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
162 void allocate();
163 void reset(Arch &arch);
164 void write(Arch &arch, EmbeddedSignatureBlob *blob);
165 void commit();
166
167 private:
168 // fork operation
169 void childAction();
170 void parentAction();
171
172 // controlling the temporary file copy
173 Universal *mNewCode;
174 UnixPlusPlus::AutoFileDesc mFd;
175 bool mTempMayExist;
176
177 // finding and managing the helper tool
178 const char *mHelperPath;
179 bool mHelperOverridden;
180 };
181
182
183 //
184 // A Requirement::Context populated from a signing request.
185 // We use this to help generate the explicit Designated Requirement
186 // during signing ops, and thus this must be constructed BEFORE we
187 // actually have a signed object.
188 //
189 class PreSigningContext : public Requirement::Context {
190 public:
191 PreSigningContext(const SecCodeSigner::Signer &signer);
192
193 private:
194 CFRef<CFArrayRef> mCerts; // hold cert chain
195 };
196
197
198 } // end namespace CodeSigning
199 } // end namespace Security
200
201 #endif // !_H_SIGNERUTILS