]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/signerutils.h
92d48f37256cbeaa6b552ce4eceb02e3c1de2eef
[apple/libsecurity_codesigning.git] / lib / signerutils.h
1 /*
2 * Copyright (c) 2006-2010 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 DiskRep::Writer that assembles data in a SuperBlob (in memory)
44 //
45 class BlobWriter : public DiskRep::Writer, public EmbeddedSignatureBlob::Maker {
46 public:
47 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
48 };
49
50
51 class DetachedBlobWriter : public BlobWriter {
52 public:
53 DetachedBlobWriter(SecCodeSigner::Signer &s) : signer(s) { }
54
55 SecCodeSigner::Signer &signer;
56
57 void flush();
58 };
59
60
61 //
62 // A multi-architecture editing assistant.
63 // ArchEditor collects (Mach-O) architectures in use, and maintains per-archtitecture
64 // data structures. It must be subclassed to express a particular way to handle the signing
65 // data.
66 //
67 class ArchEditor : public DiskRep::Writer {
68 public:
69 ArchEditor(Universal &fat, CodeDirectory::HashAlgorithm hashType, uint32_t attrs);
70 virtual ~ArchEditor();
71
72 public:
73 //
74 // One architecture's signing construction element.
75 // This also implements DispRep::Writer so generic writing code
76 // can work with both Mach-O and other files.
77 //
78 struct Arch : public BlobWriter {
79 Architecture architecture; // our architecture
80 auto_ptr<MachO> source; // Mach-O object to be signed
81 CodeDirectory::Builder cdbuilder; // builder for CodeDirectory
82 InternalRequirements ireqs; // consolidated internal requirements
83 size_t blobSize; // calculated SuperBlob size
84
85 Arch(const Architecture &arch, CodeDirectory::HashAlgorithm hashType)
86 : architecture(arch), cdbuilder(hashType) { }
87 };
88
89 //
90 // Our callers access the architectural universe through a map
91 // from Architectures to Arch objects.
92 //
93 typedef std::map<Architecture, Arch *> ArchMap;
94 typedef ArchMap::iterator Iterator;
95 ArchMap::iterator begin() { return architecture.begin(); }
96 ArchMap::iterator end() { return architecture.end(); }
97 unsigned count() const { return architecture.size(); }
98
99 // methods needed for an actual implementation
100 virtual void allocate() = 0; // interpass allocations
101 virtual void reset(Arch &arch) = 0; // pass 2 prep
102 virtual void write(Arch &arch, EmbeddedSignatureBlob *blob) = 0; // takes ownership of blob
103 virtual void commit() = 0; // write/flush result
104
105 protected:
106 ArchMap architecture;
107 };
108
109
110 //
111 // An ArchEditor that collects all architectures into a single SuperBlob,
112 // usually for writing a detached multi-architecture signature.
113 //
114 class BlobEditor : public ArchEditor {
115 public:
116 BlobEditor(Universal &fat, SecCodeSigner::Signer &s);
117
118 SecCodeSigner::Signer &signer;
119
120 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
121 void allocate() { }
122 void reset(Arch &arch) { }
123 void write(Arch &arch, EmbeddedSignatureBlob *blob);
124 void commit();
125
126 private:
127 DetachedSignatureBlob::Maker mMaker;
128 EmbeddedSignatureBlob::Maker mGlobal;
129 };
130
131
132 //
133 // An ArchEditor that writes its signatures into a (fat) binary file.
134 // We do this by forking a helper tool (codesign_allocate) and asking
135 // it to make a copy with suitable space "opened up" in the right spots.
136 //
137 class MachOEditor : public ArchEditor, private UnixPlusPlus::Child {
138 public:
139 MachOEditor(DiskRep::Writer *w, Universal &code, CodeDirectory::HashAlgorithm hashType, std::string srcPath);
140 ~MachOEditor();
141
142 const RefPointer<DiskRep::Writer> writer;
143 const std::string sourcePath;
144 const std::string tempPath;
145
146 void component(CodeDirectory::SpecialSlot slot, CFDataRef data);
147 void allocate();
148 void reset(Arch &arch);
149 void write(Arch &arch, EmbeddedSignatureBlob *blob);
150 void commit();
151
152 private:
153 // fork operation
154 void childAction();
155 void parentAction();
156
157 // controlling the temporary file copy
158 Universal *mNewCode;
159 UnixPlusPlus::AutoFileDesc mFd;
160 bool mTempMayExist;
161
162 // finding and managing the helper tool
163 const char *mHelperPath;
164 bool mHelperOverridden;
165 };
166
167
168 } // end namespace CodeSigning
169 } // end namespace Security
170
171 #endif // !_H_SIGNERUTILS