]> git.saurik.com Git - apple/libsecurity_codesigning.git/blame_incremental - lib/SecCode.cpp
libsecurity_codesigning-55037.15.tar.gz
[apple/libsecurity_codesigning.git] / lib / SecCode.cpp
... / ...
CommitLineData
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
36using namespace CodeSigning;
37
38
39//
40// CFError user info keys
41//
42const CFStringRef kSecCFErrorArchitecture = CFSTR("SecCSArchitecture");
43const CFStringRef kSecCFErrorPattern = CFSTR("SecCSPattern");
44const CFStringRef kSecCFErrorResourceSeal = CFSTR("SecCSResourceSeal");
45const CFStringRef kSecCFErrorResourceAdded = CFSTR("SecCSResourceAdded");
46const CFStringRef kSecCFErrorResourceAltered = CFSTR("SecCSResourceAltered");
47const CFStringRef kSecCFErrorResourceMissing = CFSTR("SecCSResourceMissing");
48const CFStringRef kSecCFErrorInfoPlist = CFSTR("SecCSInfoPlist");
49const CFStringRef kSecCFErrorGuestAttributes = CFSTR("SecCSGuestAttributes");
50const CFStringRef kSecCFErrorRequirementSyntax = CFSTR("SecRequirementSyntax");
51const CFStringRef kSecCFErrorPath = CFSTR("SecComponentPath");
52
53
54//
55// CF-standard type code functions
56//
57CFTypeID 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//
68OSStatus 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//
84OSStatus 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//
98OSStatus 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//
113OSStatus 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//
128OSStatus 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//
143const CFStringRef kSecGuestAttributeCanonical = CFSTR("canonical");
144const CFStringRef kSecGuestAttributeHash = CFSTR("codedirectory-hash");
145const CFStringRef kSecGuestAttributeMachPort = CFSTR("mach-port");
146const CFStringRef kSecGuestAttributePid = CFSTR("pid");
147const CFStringRef kSecGuestAttributeArchitecture = CFSTR("architecture");
148const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture");
149
150OSStatus 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//
171OSStatus 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//
188OSStatus SecCodeCheckValidity(SecCodeRef codeRef, SecCSFlags flags,
189 SecRequirementRef requirementRef)
190{
191 return SecCodeCheckValidityWithErrors(codeRef, flags, requirementRef, NULL);
192}
193
194OSStatus 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//
219const CFStringRef kSecCodeInfoCertificates = CFSTR("certificates");
220const CFStringRef kSecCodeInfoChangedFiles = CFSTR("changed-files");
221const CFStringRef kSecCodeInfoCMS = CFSTR("cms");
222const CFStringRef kSecCodeInfoDesignatedRequirement = CFSTR("designated-requirement");
223const CFStringRef kSecCodeInfoEntitlements = CFSTR("entitlements");
224const CFStringRef kSecCodeInfoEntitlementsDict = CFSTR("entitlements-dict");
225const CFStringRef kSecCodeInfoFormat = CFSTR("format");
226const CFStringRef kSecCodeInfoDigestAlgorithm = CFSTR("digest-algorithm");
227const CFStringRef kSecCodeInfoIdentifier = CFSTR("identifier");
228const CFStringRef kSecCodeInfoImplicitDesignatedRequirement = CFSTR("implicit-requirement");
229const CFStringRef kSecCodeInfoMainExecutable = CFSTR("main-executable");
230const CFStringRef kSecCodeInfoPList = CFSTR("info-plist");
231const CFStringRef kSecCodeInfoRequirements = CFSTR("requirements");
232const CFStringRef kSecCodeInfoRequirementData = CFSTR("requirement-data");
233const CFStringRef kSecCodeInfoSource = CFSTR("source");
234const CFStringRef kSecCodeInfoStatus = CFSTR("status");
235const CFStringRef kSecCodeInfoTime = CFSTR("signing-time");
236const CFStringRef kSecCodeInfoTimestamp = CFSTR("signing-timestamp");
237const CFStringRef kSecCodeInfoTrust = CFSTR("trust");
238const CFStringRef kSecCodeInfoUnique = CFSTR("unique");
239
240const CFStringRef kSecCodeInfoCodeDirectory = CFSTR("CodeDirectory");
241const CFStringRef kSecCodeInfoCodeOffset = CFSTR("CodeOffset");
242const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory");
243
244
245OSStatus 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