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