]> git.saurik.com Git - apple/libsecurity_codesigning.git/blame - lib/StaticCode.h
libsecurity_codesigning-55037.15.tar.gz
[apple/libsecurity_codesigning.git] / lib / StaticCode.h
CommitLineData
7d31e928 1/*
62e4ed3d 2 * Copyright (c) 2006-2012 Apple Inc. All Rights Reserved.
7d31e928
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// StaticCode - SecStaticCode API objects
26//
27#ifndef _H_STATICCODE
28#define _H_STATICCODE
29
30#include "cs.h"
31#include "Requirements.h"
32#include "requirement.h"
33#include "diskrep.h"
34#include "codedirectory.h"
35#include <Security/SecTrust.h>
36#include <CoreFoundation/CFData.h>
37
38namespace Security {
39namespace CodeSigning {
40
41
42class SecCode;
43
44
45//
46// A SecStaticCode object represents the file system version of some code.
47// There's a lot of pieces to this, and we'll bring them all into
48// memory here (lazily) and let you fondle them with ease.
49//
50// Note that concrete knowledge of where stuff is stored resides in the DiskRep
51// object we hold. DiskReps allocate, retrieve, and return data to us. We are
f60086fc
A
52// responsible for interpreting, caching, and validating them. (In other words,
53// DiskReps know where stuff is and how it is stored, but we know what it means.)
54//
55// Data accessors (returning CFDataRef, CFDictionaryRef, various pointers, etc.)
56// cache those values internally and return unretained(!) references ("Get" style)
57// that are valid as long as the SecStaticCode object's lifetime, or until
58// resetValidity() is called, whichever is sooner. If you need to keep them,
59// retain or copy them as needed.
7d31e928
A
60//
61class SecStaticCode : public SecCFObject {
62 NOCOPY(SecStaticCode)
63
64protected:
d1c1ab47
A
65 //
66 // A context for resource validation operations, to tailor error response.
67 // The base class throws an exception immediately and ignores detail data.
68 //
7d31e928
A
69 class ValidationContext {
70 public:
71 virtual ~ValidationContext();
72 virtual void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
73 };
74
d1c1ab47
A
75 //
76 // A CollectingContext collects all error details and throws an annotated final error.
77 //
7d31e928
A
78 class CollectingContext : public ValidationContext {
79 public:
80 CollectingContext(SecStaticCode &c) : code(c), mStatus(noErr) { }
81 void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
82
935e6928 83 OSStatus osStatus() { return mStatus; }
7d31e928
A
84 operator OSStatus () const { return mStatus; }
85 void throwMe() __attribute__((noreturn));
86
87 SecStaticCode &code;
88
89 private:
90 CFRef<CFMutableDictionaryRef> mCollection;
91 OSStatus mStatus;
92 };
93
94public:
95 SECCFFUNCTIONS(SecStaticCode, SecStaticCodeRef,
96 errSecCSInvalidObjectRef, gCFObjects().StaticCode)
97
98 // implicitly convert SecCodeRefs to their SecStaticCodeRefs
99 static SecStaticCode *requiredStatic(SecStaticCodeRef ref); // convert SecCodeRef
100 static SecCode *optionalDynamic(SecStaticCodeRef ref); // extract SecCodeRef or NULL
101
102 SecStaticCode(DiskRep *rep);
103 virtual ~SecStaticCode() throw();
104
d1c1ab47
A
105 bool equal(SecCFObject &other);
106 CFHashCode hash();
107
108 void detachedSignature(CFDataRef sig); // attach an explicitly given detached signature
109 void checkForSystemSignature(); // check for and attach system-supplied detached signature
7d31e928
A
110
111 const CodeDirectory *codeDirectory(bool check = true);
d1c1ab47 112 CFDataRef cdHash();
7d31e928
A
113 CFDataRef signature();
114 CFAbsoluteTime signingTime();
62e4ed3d 115 CFAbsoluteTime signingTimestamp();
7d31e928
A
116 bool isSigned() { return codeDirectory(false) != NULL; }
117 DiskRep *diskRep() { return mRep; }
118 std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
119 CFURLRef canonicalPath() const { return mRep->canonicalPath(); }
120 std::string identifier() { return codeDirectory()->identifier(); }
121 std::string format() const { return mRep->format(); }
d1c1ab47 122 std::string signatureSource();
f60086fc 123 CFDataRef component(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
7d31e928 124 CFDictionaryRef infoDictionary();
516ae477 125 CFDictionaryRef entitlements();
7d31e928
A
126
127 CFDictionaryRef resourceDictionary();
128 CFURLRef resourceBase();
129 CFDataRef resource(std::string path);
130 CFDataRef resource(std::string path, ValidationContext &ctx);
f60086fc 131 void validateResource(std::string path, ValidationContext &ctx);
7d31e928
A
132
133 bool flag(uint32_t tested);
134
f60086fc 135 void resetValidity(); // clear validation caches (if something may have changed)
7d31e928
A
136
137 bool validated() const { return mValidated; }
138 bool valid() const
139 { assert(validated()); return mValidated && (mValidationResult == noErr); }
935e6928
A
140 bool validatedExecutable() const { return mExecutableValidated; }
141 bool validatedResources() const { return mResourcesValidated; }
142
7d31e928 143 void validateDirectory();
f60086fc 144 void validateComponent(CodeDirectory::SpecialSlot slot, OSStatus fail = errSecCSSignatureFailed);
935e6928 145 void validateNonResourceComponents();
7d31e928
A
146 void validateResources();
147 void validateExecutable();
148
149 const Requirements *internalRequirements();
150 const Requirement *internalRequirement(SecRequirementType type);
151 const Requirement *designatedRequirement();
d1c1ab47 152 const Requirement *defaultDesignatedRequirement(); // newly allocated (caller owns)
7d31e928
A
153
154 void validateRequirements(SecRequirementType type, SecStaticCode *target,
f60086fc
A
155 OSStatus nullError = noErr); // target against my [type], throws
156 void validateRequirement(const Requirement *req, OSStatus failure); // me against [req], throws
157 bool satisfiesRequirement(const Requirement *req, OSStatus failure); // me against [req], returns on clean miss
7d31e928 158
f60086fc 159 // certificates are available after signature validation (they are stored in the CMS signature)
7d31e928
A
160 SecCertificateRef cert(int ix); // get a cert from the cert chain
161 CFArrayRef certificates(); // get the entire certificate chain
162
f60086fc
A
163 CFDictionaryRef signingInformation(SecCSFlags flags); // omnibus information-gathering API (creates new dictionary)
164
165public:
166 class AllArchitectures;
7d31e928
A
167
168protected:
f60086fc 169 CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot, OSStatus fail); // component value as a dictionary
7d31e928 170 bool verifySignature();
935e6928 171 CFTypeRef verificationPolicy(SecCSFlags flags);
7d31e928
A
172
173 static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
174
175private:
176 RefPointer<DiskRep> mRep; // on-disk representation
177
178 // master validation state
179 bool mValidated; // core validation was attempted
180 OSStatus mValidationResult; // outcome of core validation
181 bool mValidationExpired; // outcome had expired certificates
182
183 // static executable validation state (nested within mValidated/mValid)
184 bool mExecutableValidated; // tried to validate executable file
935e6928
A
185 OSStatus mExecutableValidResult; // outcome if mExecutableValidated
186
187 // static resource validation state (nested within mValidated/mValid)
188 bool mResourcesValidated; // tried to validate resources
189 OSStatus mResourcesValidResult; // outcome if mResourceValidated or..
190 CollectingContext *mResourcesValidContext; // other outcome
7d31e928
A
191
192 // cached contents
193 CFRef<CFDataRef> mDir; // code directory data
194 CFRef<CFDataRef> mSignature; // CMS signature data
195 CFAbsoluteTime mSigningTime; // (signed) signing time
62e4ed3d 196 CFAbsoluteTime mSigningTimestamp; // Timestamp time (from timestamping authority)
7d31e928
A
197 CFRef<CFDataRef> mCache[cdSlotCount]; // NULL => not tried, kCFNull => absent, other => present
198
199 // alternative cache forms (storage may depend on cached contents above)
200 CFRef<CFDictionaryRef> mInfoDict; // derived from mCache slot
516ae477 201 CFRef<CFDictionaryRef> mEntitlements; // derived from mCache slot
7d31e928
A
202 CFRef<CFDictionaryRef> mResourceDict; // derived from mCache slot
203 const Requirement *mDesignatedReq; // cached designated req if we made one up
d1c1ab47 204 CFRef<CFDataRef> mCDHash; // hash of CodeDirectory
7d31e928
A
205
206 bool mGotResourceBase; // asked mRep for resourceBasePath
207 CFRef<CFURLRef> mResourceBase; // URL form of resource base directory
208
209 // signature verification outcome (mTrust == NULL => not done yet)
210 CFRef<SecTrustRef> mTrust; // outcome of crypto validation (valid or not)
211 CFRef<CFArrayRef> mCertChain;
212 CSSM_TP_APPLE_EVIDENCE_INFO *mEvalDetails;
7d31e928
A
213};
214
215
f60086fc
A
216//
217// Given a SecStaticCode, create an iterator that produces SecStaticCodes
218// for all architectures encompassed by this static code reference.
219//
220class SecStaticCode::AllArchitectures : public SecPointer<SecStaticCode> {
221public:
222 AllArchitectures(SecStaticCode *code);
223
224 SecStaticCode *operator () ();
225
226private:
227 SecPointer<SecStaticCode> mBase;
228 enum { fatBinary, firstNonFat, atEnd } mState;
229 Universal::Architectures mArchitectures;
230 Universal::Architectures::const_iterator mCurrent;
231};
232
233
7d31e928
A
234} // end namespace CodeSigning
235} // end namespace Security
236
237#endif // !_H_STATICCODE