2 * Copyright (c) 2006-2007 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
25 // SecCode - API frame for SecCode objects.
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.
34 #include <security_utilities/cfmunge.h>
36 using namespace CodeSigning
;
40 // CFError user info keys
42 const CFStringRef kSecCFErrorPattern
= CFSTR("SecCSPattern");
43 const CFStringRef kSecCFErrorResourceSeal
= CFSTR("SecCSResourceSeal");
44 const CFStringRef kSecCFErrorResourceAdded
= CFSTR("SecCSResourceAdded");
45 const CFStringRef kSecCFErrorResourceAltered
= CFSTR("SecCSResourceAltered");
46 const CFStringRef kSecCFErrorResourceMissing
= CFSTR("SecCSResourceMissing");
47 const CFStringRef kSecCFErrorInfoPlist
= CFSTR("SecCSInfoPlist");
48 const CFStringRef kSecCFErrorGuestAttributes
= CFSTR("SecCSGuestAttributes");
49 const CFStringRef kSecCFErrorRequirementSyntax
= CFSTR("SecRequirementSyntax");
52 // CF-standard type code functions
54 CFTypeID
SecCodeGetTypeID(void)
57 return gCFObjects().Code
.typeID
;
58 END_CSAPI1(_kCFRuntimeNotATypeID
)
63 // Get a reference to the calling code.
65 OSStatus
SecCodeCopySelf(SecCSFlags flags
, SecCodeRef
*selfRef
)
70 CFRef
<CFMutableDictionaryRef
> attributes
= makeCFMutableDictionary(1,
71 kSecGuestAttributePid
, CFTempNumber(getpid()).get());
72 Required(selfRef
) = SecCode::autoLocateGuest(attributes
, flags
)->handle(false);
79 // Get the dynamic status of a code.
81 OSStatus
SecCodeGetStatus(SecCodeRef codeRef
, SecCSFlags flags
, SecCodeStatus
*status
)
86 Required(status
) = SecCode::required(codeRef
)->status();
93 // Change the dynamic status of a code
95 OSStatus
SecCodeSetStatus(SecCodeRef codeRef
, SecCodeStatusOperation operation
,
96 CFDictionaryRef arguments
, SecCSFlags flags
)
101 SecCode::required(codeRef
)->status(operation
, arguments
);
108 // Get the StaticCode for an Code
110 OSStatus
SecCodeCopyStaticCode(SecCodeRef codeRef
, SecCSFlags flags
, SecStaticCodeRef
*staticCodeRef
)
115 SecPointer
<SecStaticCode
> staticCode
= SecCode::required(codeRef
)->staticCode();
116 Required(staticCodeRef
) = staticCode
? staticCode
->handle() : NULL
;
123 // Get the host for an Code
125 OSStatus
SecCodeCopyHost(SecCodeRef guestRef
, SecCSFlags flags
, SecCodeRef
*hostRef
)
130 SecPointer
<SecCode
> host
= SecCode::required(guestRef
)->host();
131 Required(hostRef
) = host
? host
->handle() : NULL
;
138 // Find a guest by attribute(s)
140 const CFStringRef kSecGuestAttributeCanonical
= CFSTR("canonical");
141 const CFStringRef kSecGuestAttributeHash
= CFSTR("codedirectory-hash");
142 const CFStringRef kSecGuestAttributeMachPort
= CFSTR("mach-port");
143 const CFStringRef kSecGuestAttributePid
= CFSTR("pid");
144 const CFStringRef kSecGuestAttributeArchitecture
= CFSTR("architecture");
145 const CFStringRef kSecGuestAttributeSubarchitecture
= CFSTR("subarchitecture");
147 OSStatus
SecCodeCopyGuestWithAttributes(SecCodeRef hostRef
,
148 CFDictionaryRef attributes
, SecCSFlags flags
, SecCodeRef
*guestRef
)
154 if (SecCode
*guest
= SecCode::required(hostRef
)->locateGuest(attributes
))
155 Required(guestRef
) = guest
->handle(false);
157 return errSecCSNoSuchCode
;
159 Required(guestRef
) = SecCode::autoLocateGuest(attributes
, flags
)->handle(false);
166 // Shorthand for getting the SecCodeRef for a UNIX process
168 OSStatus
SecCodeCreateWithPID(pid_t pid
, SecCSFlags flags
, SecCodeRef
*processRef
)
173 if (SecCode
*guest
= KernelCode::active()->locateGuest(CFTemp
<CFDictionaryRef
>("{%O=%d}", kSecGuestAttributePid
, pid
)))
174 Required(processRef
) = guest
->handle(false);
176 return errSecCSNoSuchCode
;
183 // Check validity of an Code
185 OSStatus
SecCodeCheckValidity(SecCodeRef codeRef
, SecCSFlags flags
,
186 SecRequirementRef requirementRef
)
188 return SecCodeCheckValidityWithErrors(codeRef
, flags
, requirementRef
, NULL
);
191 OSStatus
SecCodeCheckValidityWithErrors(SecCodeRef codeRef
, SecCSFlags flags
,
192 SecRequirementRef requirementRef
, CFErrorRef
*errors
)
197 kSecCSConsiderExpiration
);
198 SecPointer
<SecCode
> code
= SecCode::required(codeRef
);
199 code
->checkValidity(flags
);
200 if (const SecRequirement
*req
= SecRequirement::optional(requirementRef
))
201 code
->staticCode()->validateRequirements(req
->requirement(), errSecCSReqFailed
);
208 // Collect suitably laundered information about the code signature of a SecStaticCode
209 // and return it as a CFDictionary.
211 // This API contracts to return a few pieces of information even for unsigned
212 // code. This means that a SecStaticCodeRef is usable as a basic indentifier
213 // (i.e. handle) for any code out there.
215 const CFStringRef kSecCodeInfoCertificates
= CFSTR("certificates");
216 const CFStringRef kSecCodeInfoChangedFiles
= CFSTR("changed-files");
217 const CFStringRef kSecCodeInfoCMS
= CFSTR("cms");
218 const CFStringRef kSecCodeInfoDesignatedRequirement
= CFSTR("designated-requirement");
219 const CFStringRef kSecCodeInfoEntitlements
= CFSTR("entitlements");
220 const CFStringRef kSecCodeInfoFormat
= CFSTR("format");
221 const CFStringRef kSecCodeInfoIdentifier
= CFSTR("identifier");
222 const CFStringRef kSecCodeInfoImplicitDesignatedRequirement
= CFSTR("implicit-requirement");
223 const CFStringRef kSecCodeInfoMainExecutable
= CFSTR("main-executable");
224 const CFStringRef kSecCodeInfoPList
= CFSTR("info-plist");
225 const CFStringRef kSecCodeInfoRequirements
= CFSTR("requirements");
226 const CFStringRef kSecCodeInfoRequirementData
= CFSTR("requirement-data");
227 const CFStringRef kSecCodeInfoSource
= CFSTR("source");
228 const CFStringRef kSecCodeInfoStatus
= CFSTR("status");
229 const CFStringRef kSecCodeInfoTime
= CFSTR("signing-time");
230 const CFStringRef kSecCodeInfoTrust
= CFSTR("trust");
231 const CFStringRef kSecCodeInfoUnique
= CFSTR("unique");
233 const CFStringRef kSecCodeInfoCodeDirectory
= CFSTR("CodeDirectory");
234 const CFStringRef kSecCodeInfoCodeOffset
= CFSTR("CodeOffset");
235 const CFStringRef kSecCodeInfoResourceDirectory
= CFSTR("ResourceDirectory");
238 OSStatus
SecCodeCopySigningInformation(SecStaticCodeRef codeRef
, SecCSFlags flags
,
239 CFDictionaryRef
*infoRef
)
244 kSecCSInternalInformation
245 | kSecCSSigningInformation
246 | kSecCSRequirementInformation
247 | kSecCSDynamicInformation
248 | kSecCSContentInformation
);
250 SecPointer
<SecStaticCode
> code
= SecStaticCode::requiredStatic(codeRef
);
251 CFRef
<CFDictionaryRef
> info
= code
->signingInformation(flags
);
253 if (flags
& kSecCSDynamicInformation
)
254 if (SecPointer
<SecCode
> dcode
= SecStaticCode::optionalDynamic(codeRef
))
255 info
= cfmake
<CFDictionaryRef
>("{+%O,%O=%u}", info
.get(),
256 kSecCodeInfoStatus
, dcode
->status());
258 Required(infoRef
) = info
.yield();