]> git.saurik.com Git - apple/libsecurity_codesigning.git/blob - lib/SecCode.cpp
f5b300f6dc9ae15e815f5c125375ecfab6de198c
[apple/libsecurity_codesigning.git] / lib / SecCode.cpp
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 // SecCode - API frame for SecCode objects.
26 //
27 // Note that some SecCode* functions take SecStaticCodeRef arguments in order to
28 // accept either static or dynamic code references, operating on the respective
29 // StaticCode. Those functions are in SecStaticCode.cpp, not here, despite their name.
30 //
31 #include "cs.h"
32 #include "Code.h"
33 #include "cskernel.h"
34 #include <security_utilities/cfmunge.h>
35
36 using namespace CodeSigning;
37
38
39 //
40 // CFError user info keys
41 //
42 const CFStringRef kSecCFErrorArchitecture = CFSTR("SecCSArchitecture");
43 const CFStringRef kSecCFErrorPattern = CFSTR("SecCSPattern");
44 const CFStringRef kSecCFErrorResourceSeal = CFSTR("SecCSResourceSeal");
45 const CFStringRef kSecCFErrorResourceAdded = CFSTR("SecCSResourceAdded");
46 const CFStringRef kSecCFErrorResourceAltered = CFSTR("SecCSResourceAltered");
47 const CFStringRef kSecCFErrorResourceMissing = CFSTR("SecCSResourceMissing");
48 const CFStringRef kSecCFErrorInfoPlist = CFSTR("SecCSInfoPlist");
49 const CFStringRef kSecCFErrorGuestAttributes = CFSTR("SecCSGuestAttributes");
50 const CFStringRef kSecCFErrorRequirementSyntax = CFSTR("SecRequirementSyntax");
51 const CFStringRef kSecCFErrorPath = CFSTR("SecComponentPath");
52
53
54 //
55 // CF-standard type code functions
56 //
57 CFTypeID SecCodeGetTypeID(void)
58 {
59 BEGIN_CSAPI
60 return gCFObjects().Code.typeID;
61 END_CSAPI1(_kCFRuntimeNotATypeID)
62 }
63
64
65 //
66 // Get a reference to the calling code.
67 //
68 OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *selfRef)
69 {
70 BEGIN_CSAPI
71
72 checkFlags(flags);
73 CFRef<CFMutableDictionaryRef> attributes = makeCFMutableDictionary(1,
74 kSecGuestAttributePid, CFTempNumber(getpid()).get());
75 CodeSigning::Required(selfRef) = SecCode::autoLocateGuest(attributes, flags)->handle(false);
76
77 END_CSAPI
78 }
79
80
81 //
82 // Get the dynamic status of a code.
83 //
84 OSStatus SecCodeGetStatus(SecCodeRef codeRef, SecCSFlags flags, SecCodeStatus *status)
85 {
86 BEGIN_CSAPI
87
88 checkFlags(flags);
89 CodeSigning::Required(status) = SecCode::required(codeRef)->status();
90
91 END_CSAPI
92 }
93
94
95 //
96 // Change the dynamic status of a code
97 //
98 OSStatus SecCodeSetStatus(SecCodeRef codeRef, SecCodeStatusOperation operation,
99 CFDictionaryRef arguments, SecCSFlags flags)
100 {
101 BEGIN_CSAPI
102
103 checkFlags(flags);
104 SecCode::required(codeRef)->status(operation, arguments);
105
106 END_CSAPI
107 }
108
109
110 //
111 // Get the StaticCode for an Code
112 //
113 OSStatus SecCodeCopyStaticCode(SecCodeRef codeRef, SecCSFlags flags, SecStaticCodeRef *staticCodeRef)
114 {
115 BEGIN_CSAPI
116
117 checkFlags(flags);
118 SecPointer<SecStaticCode> staticCode = SecCode::required(codeRef)->staticCode();
119 CodeSigning::Required(staticCodeRef) = staticCode ? staticCode->handle() : NULL;
120
121 END_CSAPI
122 }
123
124
125 //
126 // Get the host for an Code
127 //
128 OSStatus SecCodeCopyHost(SecCodeRef guestRef, SecCSFlags flags, SecCodeRef *hostRef)
129 {
130 BEGIN_CSAPI
131
132 checkFlags(flags);
133 SecPointer<SecCode> host = SecCode::required(guestRef)->host();
134 CodeSigning::Required(hostRef) = host ? host->handle() : NULL;
135
136 END_CSAPI
137 }
138
139
140 //
141 // Find a guest by attribute(s)
142 //
143 const CFStringRef kSecGuestAttributeCanonical = CFSTR("canonical");
144 const CFStringRef kSecGuestAttributeHash = CFSTR("codedirectory-hash");
145 const CFStringRef kSecGuestAttributeMachPort = CFSTR("mach-port");
146 const CFStringRef kSecGuestAttributePid = CFSTR("pid");
147 const CFStringRef kSecGuestAttributeArchitecture = CFSTR("architecture");
148 const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture");
149
150 OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef hostRef,
151 CFDictionaryRef attributes, SecCSFlags flags, SecCodeRef *guestRef)
152 {
153 BEGIN_CSAPI
154
155 checkFlags(flags);
156 if (hostRef) {
157 if (SecCode *guest = SecCode::required(hostRef)->locateGuest(attributes))
158 CodeSigning::Required(guestRef) = guest->handle(false);
159 else
160 return errSecCSNoSuchCode;
161 } else
162 CodeSigning::Required(guestRef) = SecCode::autoLocateGuest(attributes, flags)->handle(false);
163
164 END_CSAPI
165 }
166
167
168 //
169 // Shorthand for getting the SecCodeRef for a UNIX process
170 //
171 OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRef)
172 {
173 BEGIN_CSAPI
174
175 checkFlags(flags);
176 if (SecCode *guest = KernelCode::active()->locateGuest(CFTemp<CFDictionaryRef>("{%O=%d}", kSecGuestAttributePid, pid)))
177 CodeSigning::Required(processRef) = guest->handle(false);
178 else
179 return errSecCSNoSuchCode;
180
181 END_CSAPI
182 }
183
184
185 //
186 // Check validity of an Code
187 //
188 OSStatus SecCodeCheckValidity(SecCodeRef codeRef, SecCSFlags flags,
189 SecRequirementRef requirementRef)
190 {
191 return SecCodeCheckValidityWithErrors(codeRef, flags, requirementRef, NULL);
192 }
193
194 OSStatus SecCodeCheckValidityWithErrors(SecCodeRef codeRef, SecCSFlags flags,
195 SecRequirementRef requirementRef, CFErrorRef *errors)
196 {
197 BEGIN_CSAPI
198
199 checkFlags(flags,
200 kSecCSConsiderExpiration
201 | kSecCSEnforceRevocationChecks);
202 SecPointer<SecCode> code = SecCode::required(codeRef);
203 code->checkValidity(flags);
204 if (const SecRequirement *req = SecRequirement::optional(requirementRef))
205 code->staticCode()->validateRequirement(req->requirement(), errSecCSReqFailed);
206
207 END_CSAPI_ERRORS
208 }
209
210
211 //
212 // Collect suitably laundered information about the code signature of a SecStaticCode
213 // and return it as a CFDictionary.
214 //
215 // This API contracts to return a few pieces of information even for unsigned
216 // code. This means that a SecStaticCodeRef is usable as a basic indentifier
217 // (i.e. handle) for any code out there.
218 //
219 const CFStringRef kSecCodeInfoCertificates = CFSTR("certificates");
220 const CFStringRef kSecCodeInfoChangedFiles = CFSTR("changed-files");
221 const CFStringRef kSecCodeInfoCMS = CFSTR("cms");
222 const CFStringRef kSecCodeInfoDesignatedRequirement = CFSTR("designated-requirement");
223 const CFStringRef kSecCodeInfoEntitlements = CFSTR("entitlements");
224 const CFStringRef kSecCodeInfoEntitlementsDict = CFSTR("entitlements-dict");
225 const CFStringRef kSecCodeInfoFormat = CFSTR("format");
226 const CFStringRef kSecCodeInfoDigestAlgorithm = CFSTR("digest-algorithm");
227 const CFStringRef kSecCodeInfoIdentifier = CFSTR("identifier");
228 const CFStringRef kSecCodeInfoImplicitDesignatedRequirement = CFSTR("implicit-requirement");
229 const CFStringRef kSecCodeInfoMainExecutable = CFSTR("main-executable");
230 const CFStringRef kSecCodeInfoPList = CFSTR("info-plist");
231 const CFStringRef kSecCodeInfoRequirements = CFSTR("requirements");
232 const CFStringRef kSecCodeInfoRequirementData = CFSTR("requirement-data");
233 const CFStringRef kSecCodeInfoSource = CFSTR("source");
234 const CFStringRef kSecCodeInfoStatus = CFSTR("status");
235 const CFStringRef kSecCodeInfoTime = CFSTR("signing-time");
236 const CFStringRef kSecCodeInfoTimestamp = CFSTR("signing-timestamp");
237 const CFStringRef kSecCodeInfoTrust = CFSTR("trust");
238 const CFStringRef kSecCodeInfoUnique = CFSTR("unique");
239
240 const CFStringRef kSecCodeInfoCodeDirectory = CFSTR("CodeDirectory");
241 const CFStringRef kSecCodeInfoCodeOffset = CFSTR("CodeOffset");
242 const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory");
243
244
245 OSStatus SecCodeCopySigningInformation(SecStaticCodeRef codeRef, SecCSFlags flags,
246 CFDictionaryRef *infoRef)
247 {
248 BEGIN_CSAPI
249
250 checkFlags(flags,
251 kSecCSInternalInformation
252 | kSecCSSigningInformation
253 | kSecCSRequirementInformation
254 | kSecCSDynamicInformation
255 | kSecCSContentInformation);
256
257 SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
258 CFRef<CFDictionaryRef> info = code->signingInformation(flags);
259
260 if (flags & kSecCSDynamicInformation)
261 if (SecPointer<SecCode> dcode = SecStaticCode::optionalDynamic(codeRef))
262 info.take(cfmake<CFDictionaryRef>("{+%O,%O=%u}", info.get(), kSecCodeInfoStatus, dcode->status()));
263
264 CodeSigning::Required(infoRef) = info.yield();
265
266 END_CSAPI
267 }
268