]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/StaticCode.h
libsecurity_codesigning-36924.tar.gz
[apple/libsecurity_codesigning.git] / lib / StaticCode.h
1 /*
2 * Copyright (c) 2006-2007 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 // 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
38 namespace Security {
39 namespace CodeSigning {
40
41
42 class 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
52 // responsible for interpreting, caching, and validating them.
53 //
54 class SecStaticCode : public SecCFObject {
55 NOCOPY(SecStaticCode)
56
57 protected:
58 class ValidationContext {
59 public:
60 virtual ~ValidationContext();
61 virtual void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
62 };
63
64 class CollectingContext : public ValidationContext {
65 public:
66 CollectingContext(SecStaticCode &c) : code(c), mStatus(noErr) { }
67 void reportProblem(OSStatus rc, CFStringRef type, CFTypeRef value);
68
69 operator OSStatus () const { return mStatus; }
70 void throwMe() __attribute__((noreturn));
71
72 SecStaticCode &code;
73
74 private:
75 CFRef<CFMutableDictionaryRef> mCollection;
76 OSStatus mStatus;
77 };
78
79 public:
80 SECCFFUNCTIONS(SecStaticCode, SecStaticCodeRef,
81 errSecCSInvalidObjectRef, gCFObjects().StaticCode)
82
83 // implicitly convert SecCodeRefs to their SecStaticCodeRefs
84 static SecStaticCode *requiredStatic(SecStaticCodeRef ref); // convert SecCodeRef
85 static SecCode *optionalDynamic(SecStaticCodeRef ref); // extract SecCodeRef or NULL
86
87 SecStaticCode(DiskRep *rep);
88 virtual ~SecStaticCode() throw();
89
90 void detachedSignature(CFDataRef sig);
91
92 const CodeDirectory *codeDirectory(bool check = true);
93 CFDataRef signature();
94 CFAbsoluteTime signingTime();
95 bool isSigned() { return codeDirectory(false) != NULL; }
96 DiskRep *diskRep() { return mRep; }
97 std::string mainExecutablePath() { return mRep->mainExecutablePath(); }
98 CFURLRef canonicalPath() const { return mRep->canonicalPath(); }
99 std::string identifier() { return codeDirectory()->identifier(); }
100 std::string format() const { return mRep->format(); }
101 CFDataRef component(CodeDirectory::SpecialSlot slot);
102 CFDictionaryRef infoDictionary();
103 CFDictionaryRef entitlements();
104
105 CFDictionaryRef resourceDictionary();
106 CFURLRef resourceBase();
107 CFDataRef resource(std::string path);
108 CFDataRef resource(std::string path, ValidationContext &ctx);
109
110 bool flag(uint32_t tested);
111
112 void resetValidity();
113
114 bool validated() const { return mValidated; }
115 bool valid() const
116 { assert(validated()); return mValidated && (mValidationResult == noErr); }
117
118 void validateDirectory();
119 void validateComponent(CodeDirectory::SpecialSlot slot);
120 void validateResources();
121 void validateExecutable();
122
123 const Requirements *internalRequirements();
124 const Requirement *internalRequirement(SecRequirementType type);
125 const Requirement *designatedRequirement();
126 const Requirement *defaultDesignatedRequirement();
127
128 void validateRequirements(SecRequirementType type, SecStaticCode *target,
129 OSStatus nullError = noErr);
130 void validateRequirements(const Requirement *req, OSStatus failure);
131
132 SecCertificateRef cert(int ix); // get a cert from the cert chain
133 CFArrayRef certificates(); // get the entire certificate chain
134
135 CFDictionaryRef signingInformation(SecCSFlags flags); // information-gathering API
136
137 protected:
138 CFDictionaryRef getDictionary(CodeDirectory::SpecialSlot slot);
139 bool verifySignature();
140 SecPolicyRef verificationPolicy();
141
142 void defaultDesignatedAppleAnchor(Requirement::Maker &maker);
143 void defaultDesignatedNonAppleAnchor(Requirement::Maker &maker);
144 bool isAppleSDKSignature();
145
146 static void checkOptionalResource(CFTypeRef key, CFTypeRef value, void *context);
147
148 private:
149 RefPointer<DiskRep> mRep; // on-disk representation
150
151 // master validation state
152 bool mValidated; // core validation was attempted
153 OSStatus mValidationResult; // outcome of core validation
154 bool mValidationExpired; // outcome had expired certificates
155
156 // static executable validation state (nested within mValidated/mValid)
157 bool mExecutableValidated; // tried to validate executable file
158 bool mExecutableValid; // outcome if mExecutableValidated
159
160 // cached contents
161 CFRef<CFDataRef> mDir; // code directory data
162 CFRef<CFDataRef> mSignature; // CMS signature data
163 CFAbsoluteTime mSigningTime; // (signed) signing time
164 CFRef<CFDataRef> mCache[cdSlotCount]; // NULL => not tried, kCFNull => absent, other => present
165
166 // alternative cache forms (storage may depend on cached contents above)
167 CFRef<CFDictionaryRef> mInfoDict; // derived from mCache slot
168 CFRef<CFDictionaryRef> mEntitlements; // derived from mCache slot
169 CFRef<CFDictionaryRef> mResourceDict; // derived from mCache slot
170 const Requirement *mDesignatedReq; // cached designated req if we made one up
171
172 bool mGotResourceBase; // asked mRep for resourceBasePath
173 CFRef<CFURLRef> mResourceBase; // URL form of resource base directory
174
175 // signature verification outcome (mTrust == NULL => not done yet)
176 CFRef<SecTrustRef> mTrust; // outcome of crypto validation (valid or not)
177 CFRef<CFArrayRef> mCertChain;
178 CSSM_TP_APPLE_EVIDENCE_INFO *mEvalDetails;
179
180 // cached verification policy
181 CFRef<SecPolicyRef> mPolicy;
182 };
183
184
185 } // end namespace CodeSigning
186 } // end namespace Security
187
188 #endif // !_H_STATICCODE