]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_codesigning/lib/diskrep.h
Security-57337.60.2.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / diskrep.h
CommitLineData
b1ab9ed8 1/*
d8f41ccd 2 * Copyright (c) 2006-2007,2011-2012,2014 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// diskrep - disk representations of code
26//
27#ifndef _H_DISKREP
28#define _H_DISKREP
29
30#include "cs.h"
31#include "codedirectory.h"
32#include "cdbuilder.h"
33#include "requirement.h"
34#include "resources.h"
35#include <security_utilities/macho++.h> // for class Architecture
36#include <security_utilities/refcount.h>
37#include <security_utilities/superblob.h>
38#include <CoreFoundation/CFData.h>
39
40namespace Security {
41namespace CodeSigning {
42
427c49bc 43class ResourceBuilder;
e3d460c9 44class SecCodeSigner;
427c49bc 45
b1ab9ed8
A
46
47//
48// DiskRep is an abstract interface to code somewhere located by
49// a file system path. It presents the ability to read and write
50// Code Signing-related information about such code without exposing
51// the details of the storage locations or formats.
52//
53class DiskRep : public RefCount {
54public:
55 class SigningContext;
56
80e23899
A
57 typedef std::set<OSStatus> ToleratedErrors;
58
b1ab9ed8
A
59public:
60 DiskRep();
61 virtual ~DiskRep();
62 virtual DiskRep *base();
63 virtual CFDataRef component(CodeDirectory::SpecialSlot slot) = 0; // fetch component
64 virtual CFDataRef identification() = 0; // binary lookup identifier
65 virtual std::string mainExecutablePath() = 0; // path to main executable
80e23899 66 virtual CFURLRef copyCanonicalPath() = 0; // path to whole code
b1ab9ed8
A
67 virtual std::string resourcesRootPath(); // resource directory if any [none]
68 virtual void adjustResources(ResourceBuilder &builder); // adjust resource rule set [no change]
e3d460c9 69 virtual void prepareForSigning(SigningContext& context); // pre-adjust signing defaults before argument preparation [none]
b1ab9ed8
A
70 virtual Universal *mainExecutableImage(); // Mach-O image if Mach-O based [null]
71 virtual size_t signingBase(); // start offset of signed area in main executable [zero]
72 virtual size_t signingLimit() = 0; // size of signed area in main executable
73 virtual std::string format() = 0; // human-readable type string
74 virtual CFArrayRef modifiedFiles(); // list of files modified by signing [main execcutable only]
75 virtual UnixPlusPlus::FileDesc &fd() = 0; // a cached file descriptor for main executable file
76 virtual void flush(); // flush caches (refetch as needed)
77
78 // default values for signing operations
79 virtual std::string recommendedIdentifier(const SigningContext &ctx) = 0; // default identifier
80 virtual CFDictionaryRef defaultResourceRules(const SigningContext &ctx); // default resource rules [none]
81 virtual const Requirements *defaultRequirements(const Architecture *arch,
82 const SigningContext &ctx); // default internal requirements [none]
83 virtual size_t pageSize(const SigningContext &ctx); // default main executable page size [infinite, i.e. no paging]
80e23899 84
e3d460c9 85 virtual void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags); // perform strict validation
80e23899
A
86 virtual CFArrayRef allowedResourceOmissions(); // allowed (default) resource omission rules
87
b1ab9ed8 88 bool mainExecutableIsMachO() { return mainExecutableImage() != NULL; }
d8f41ccd 89
b1ab9ed8 90 // shorthands
b1ab9ed8
A
91 CFDataRef signature() { return component(cdSignatureSlot); }
92
93public:
94 class Writer;
95 virtual Writer *writer(); // Writer factory
96
97public:
98 // optional information that might be used to create a suitable DiskRep. All optional
99 struct Context {
80e23899 100 Context() : arch(Architecture::none), version(NULL), offset(0), fileOnly(false), inMemory(NULL), size(0) { }
b1ab9ed8
A
101 Architecture arch; // explicit architecture (choose amongst universal variants)
102 const char *version; // bundle version (string)
103 off_t offset; // explicit file offset
104 bool fileOnly; // only consider single-file representations (no bundles etc.)
105 const void *inMemory; // consider using in-memory copy at this address
80e23899 106 size_t size; // size of this mach-o slice
b1ab9ed8
A
107 };
108
109 static DiskRep *bestGuess(const char *path, const Context *ctx = NULL); // canonical heuristic, any path
110 static DiskRep *bestFileGuess(const char *path, const Context *ctx = NULL); // ctx (if any) + fileOnly
111 static DiskRep *bestGuess(const char *path, size_t archOffset); // Mach-O at given file offset only
112
113 // versions using std::string paths (merely a convenience)
114 static DiskRep *bestGuess(const std::string &path, const Context *ctx = NULL)
115 { return bestGuess(path.c_str(), ctx); }
116 static DiskRep *bestGuess(const std::string &path, size_t archOffset) { return bestGuess(path.c_str(), archOffset); }
117 static DiskRep *bestFileGuess(const std::string &path, const Context *ctx = NULL) { return bestFileGuess(path.c_str(), ctx); }
118
119public:
120 // see DiskRep::Writer docs for why this is here
121 class SigningContext {
122 protected:
123 SigningContext() { }
124
125 public:
126 virtual std::string sdkPath(const std::string &path) const = 0;
127 virtual bool isAdhoc() const = 0;
427c49bc 128 virtual SecCSFlags signingFlags() const = 0;
e3d460c9
A
129
130 virtual const CodeDirectory::HashAlgorithms &digestAlgorithms() const = 0;
131 virtual void setDigestAlgorithms(CodeDirectory::HashAlgorithms types) = 0;
132
133 void setDigestAlgorithm(CodeDirectory::HashAlgorithm type)
134 {
135 CodeDirectory::HashAlgorithms types;
136 types.insert(type);
137 setDigestAlgorithms(types);
138 }
b1ab9ed8
A
139 };
140
141protected:
142 // canonically derive a suggested signing identifier from some string
143 static std::string canonicalIdentifier(const std::string &name);
144
145public:
146 static const size_t segmentedPageSize = 4096; // default page size for system-paged signatures
147 static const size_t monolithicPageSize = 0; // default page size for non-Mach-O executables
148};
149
150
151//
152// Write-access objects.
153// At this layer they are quite abstract, carrying just the functionality needed
154// for the signing machinery to place data wherever it should go. Each DiskRep subclass
155// that supports writing signing data to a place inside the code needs to implement
156// a subclass of Writer and return an instance in the DiskRep::writer() method when asked.
157//
158// The Writer class is subclassed interestingly by the Mach-O multi-architecture signing code,
159// which is handled as a special case. This means that not all Writer subclass objects were made
160// by DiskRep::writer, and it is unwise to assume so.
161//
162// Note that the methods that provide defaults for signing operations are in DiskRep rather
163// than here. That's because writers abstract data *sending*, and are virtual on management
164// of stored data, while DiskRep is virtual on the existing code object, which is where
165// we get our defaults from.
166//
167class DiskRep::Writer : public RefCount {
168public:
169 Writer(uint32_t attrs = 0);
170 virtual ~Writer();
171 virtual void component(CodeDirectory::SpecialSlot slot, CFDataRef data) = 0;
172 virtual uint32_t attributes() const;
173 virtual void addDiscretionary(CodeDirectory::Builder &builder);
174 virtual void remove();
175 virtual void flush();
176
177 bool attribute(uint32_t attr) const { return mAttributes & attr; }
178
179 void signature(CFDataRef data) { component(cdSignatureSlot, data); }
e3d460c9
A
180 void codeDirectory(const CodeDirectory *cd, CodeDirectory::SpecialSlot slot)
181 { component(slot, CFTempData(cd->data(), cd->length())); }
b1ab9ed8
A
182
183private:
184 Architecture mArch;
185 uint32_t mAttributes;
186};
187
188//
189// Writer attributes. Defaults should be off-bits.
190//
191enum {
192 writerLastResort = 0x0001, // prefers not to store attributes itself
193 writerNoGlobal = 0x0002, // has only per-architecture storage
194};
195
196
197//
198// A prefix DiskRep that filters (only) signature-dependent behavior and passes
199// all code-dependent behavior off to an underlying (different) DiskRep.
200// FilterRep subclasses are typically "stacked" on top of their base DiskRep, and
201// then used in their place.
202//
203class FilterRep : public DiskRep {
204public:
205 FilterRep(DiskRep *orig) : mOriginal(orig) { }
206
207 DiskRep *base() { return mOriginal; }
208
209 // things that look at signature components are filtered
210 CFDataRef component(CodeDirectory::SpecialSlot slot) = 0;
211
212 // the rest of the virtual behavior devolves on the original DiskRep
213 CFDataRef identification() { return mOriginal->identification(); }
214 std::string mainExecutablePath() { return mOriginal->mainExecutablePath(); }
80e23899 215 CFURLRef copyCanonicalPath() { return mOriginal->copyCanonicalPath(); }
b1ab9ed8
A
216 std::string resourcesRootPath() { return mOriginal->resourcesRootPath(); }
217 void adjustResources(ResourceBuilder &builder) { return mOriginal->adjustResources(builder); }
218 Universal *mainExecutableImage() { return mOriginal->mainExecutableImage(); }
219 size_t signingBase() { return mOriginal->signingBase(); }
220 size_t signingLimit() { return mOriginal->signingLimit(); }
221 std::string format() { return mOriginal->format(); }
222 CFArrayRef modifiedFiles() { return mOriginal->modifiedFiles(); }
223 UnixPlusPlus::FileDesc &fd() { return mOriginal->fd(); }
224 void flush() { return mOriginal->flush(); }
225
226 std::string recommendedIdentifier(const SigningContext &ctx)
227 { return mOriginal->recommendedIdentifier(ctx); }
228 CFDictionaryRef defaultResourceRules(const SigningContext &ctx)
229 { return mOriginal->defaultResourceRules(ctx); }
d8f41ccd
A
230 const Requirements *defaultRequirements(const Architecture *arch, const SigningContext &ctx)
231 { return mOriginal->defaultRequirements(arch, ctx); }
232 size_t pageSize(const SigningContext &ctx) { return mOriginal->pageSize(ctx); }
233
e3d460c9 234 void strictValidate(const CodeDirectory* cd, const ToleratedErrors& tolerated, SecCSFlags flags) { mOriginal->strictValidate(cd, tolerated, flags); }
d8f41ccd 235 CFArrayRef allowedResourceOmissions() { return mOriginal->allowedResourceOmissions(); }
b1ab9ed8
A
236
237private:
238 RefPointer<DiskRep> mOriginal; // underlying representation
239};
240
241
242} // end namespace CodeSigning
243} // end namespace Security
244
245#endif // !_H_DISKREP