]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/SecStaticCode.cpp
a099dfbda5b0fea684fa1e368a288edd909c2e95
[apple/libsecurity_codesigning.git] / lib / SecStaticCode.cpp
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 // SecStaticCode - API frame for SecStaticCode objects
26 //
27 #include "cs.h"
28 #include "StaticCode.h"
29 #include <fcntl.h>
30
31 using namespace CodeSigning;
32
33
34 //
35 // CF-standard type code function
36 //
37 CFTypeID SecStaticCodeGetTypeID(void)
38 {
39 BEGIN_CSAPI
40 return gCFObjects().StaticCode.typeID;
41 END_CSAPI1(_kCFRuntimeNotATypeID)
42 }
43
44
45 //
46 // Create an StaticCode directly from disk path.
47 //
48 OSStatus SecStaticCodeCreateWithPath(CFURLRef path, SecCSFlags flags, SecStaticCodeRef *staticCodeRef)
49 {
50 BEGIN_CSAPI
51
52 checkFlags(flags);
53 Required(staticCodeRef) = (new SecStaticCode(DiskRep::bestGuess(cfString(path).c_str())))->handle();
54
55 END_CSAPI
56 }
57
58
59 //
60 // Check static validity of a StaticCode
61 //
62 OSStatus SecStaticCodeCheckValidity(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
63 SecRequirementRef requirementRef)
64 {
65 return SecStaticCodeCheckValidityWithErrors(staticCodeRef, flags, requirementRef, NULL);
66 }
67
68 OSStatus SecStaticCodeCheckValidityWithErrors(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
69 SecRequirementRef requirementRef, CFErrorRef *errors)
70 {
71 BEGIN_CSAPI
72
73 checkFlags(flags,
74 kSecCSCheckAllArchitectures
75 | kSecCSDoNotValidateExecutable
76 | kSecCSDoNotValidateResources
77 | kSecCSConsiderExpiration);
78
79 SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(staticCodeRef);
80 DTRACK(CODESIGN_EVAL_STATIC, code, (char*)code->mainExecutablePath().c_str());
81 code->validateDirectory();
82 if (!(flags & kSecCSDoNotValidateExecutable))
83 code->validateExecutable();
84 if (!(flags & kSecCSDoNotValidateResources))
85 code->validateResources();
86 if (const SecRequirement *req = SecRequirement::optional(requirementRef))
87 code->validateRequirements(req->requirement(), errSecCSReqFailed);
88
89 END_CSAPI_ERRORS
90 }
91
92
93 //
94 // ====================================================================================
95 //
96 // The following API functions are called SecCode* but accept both SecCodeRef and
97 // SecStaticCodeRef arguments, operating on the implied SecStaticCodeRef as appropriate.
98 // Hence they're here, rather than in SecCode.cpp.
99 //
100
101
102 //
103 // Retrieve location information for an StaticCode.
104 //
105 OSStatus SecCodeCopyPath(SecStaticCodeRef staticCodeRef, SecCSFlags flags, CFURLRef *path)
106 {
107 BEGIN_CSAPI
108
109 checkFlags(flags);
110 SecPointer<SecStaticCode> staticCode = SecStaticCode::requiredStatic(staticCodeRef);
111 Required(path) = staticCode->canonicalPath();
112
113 END_CSAPI
114 }
115
116
117 //
118 // Fetch or make up a designated requirement
119 //
120 OSStatus SecCodeCopyDesignatedRequirement(SecStaticCodeRef staticCodeRef, SecCSFlags flags,
121 SecRequirementRef *requirementRef)
122 {
123 BEGIN_CSAPI
124
125 checkFlags(flags);
126 const Requirement *req =
127 SecStaticCode::requiredStatic(staticCodeRef)->designatedRequirement();
128 Required(requirementRef) = (new SecRequirement(req))->handle();
129
130 END_CSAPI
131 }
132
133
134 //
135 // Fetch a particular internal requirement, if present
136 //
137 OSStatus SecCodeCopyInternalRequirement(SecStaticCodeRef staticCodeRef, SecRequirementType type,
138 SecCSFlags flags, SecRequirementRef *requirementRef)
139 {
140 BEGIN_CSAPI
141
142 checkFlags(flags);
143 const Requirement *req =
144 SecStaticCode::requiredStatic(staticCodeRef)->internalRequirement(type);
145 Required(requirementRef) = req ? (new SecRequirement(req))->handle() : NULL;
146
147 END_CSAPI
148 }
149
150
151 //
152 // Record for future use a detached code signature.
153 //
154 OSStatus SecCodeSetDetachedSignature(SecStaticCodeRef codeRef, CFDataRef signature,
155 SecCSFlags flags)
156 {
157 BEGIN_CSAPI
158
159 checkFlags(flags);
160 SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
161
162 if (signature)
163 CFRetain(signature); // own a reference...
164 code->detachedSignature(signature); // ... and pass it to the code
165 code->resetValidity();
166
167 END_CSAPI
168 }
169
170
171 //
172 // Attach a code signature to a kernel memory mapping for page-in validation.
173 //
174 OSStatus SecCodeMapMemory(SecStaticCodeRef codeRef, SecCSFlags flags)
175 {
176 BEGIN_CSAPI
177
178 checkFlags(flags);
179 SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
180 if (const CodeDirectory *cd = code->codeDirectory(false)) {
181 fsignatures args = { code->diskRep()->signingBase(), (void *)cd, cd->length() };
182 UnixError::check(::fcntl(code->diskRep()->fd(), F_ADDSIGS, &args));
183 } else
184 MacOSError::throwMe(errSecCSUnsigned);
185
186 END_CSAPI
187 }