]> git.saurik.com Git - apple/security.git/blame - OSX/libsecurity_codesigning/lib/SecCode.cpp
Security-58286.41.2.tar.gz
[apple/security.git] / OSX / libsecurity_codesigning / lib / SecCode.cpp
CommitLineData
b1ab9ed8 1/*
5c19dc3a
A
2 * Copyright (c) 2006-2015 Apple Inc. All Rights Reserved.
3 *
b1ab9ed8 4 * @APPLE_LICENSE_HEADER_START@
5c19dc3a 5 *
b1ab9ed8
A
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.
5c19dc3a 12 *
b1ab9ed8
A
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.
5c19dc3a 20 *
b1ab9ed8
A
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>
5c19dc3a 35#include <security_utilities/logging.h>
b1ab9ed8
A
36
37using namespace CodeSigning;
38
39
40//
41// CFError user info keys
42//
43const CFStringRef kSecCFErrorArchitecture = CFSTR("SecCSArchitecture");
44const CFStringRef kSecCFErrorPattern = CFSTR("SecCSPattern");
45const CFStringRef kSecCFErrorResourceSeal = CFSTR("SecCSResourceSeal");
46const CFStringRef kSecCFErrorResourceAdded = CFSTR("SecCSResourceAdded");
47const CFStringRef kSecCFErrorResourceAltered = CFSTR("SecCSResourceAltered");
48const CFStringRef kSecCFErrorResourceMissing = CFSTR("SecCSResourceMissing");
fa7225c8 49const CFStringRef kSecCFErrorResourceSideband = CFSTR("SecCSResourceHasSidebandData");
b1ab9ed8
A
50const CFStringRef kSecCFErrorInfoPlist = CFSTR("SecCSInfoPlist");
51const CFStringRef kSecCFErrorGuestAttributes = CFSTR("SecCSGuestAttributes");
52const CFStringRef kSecCFErrorRequirementSyntax = CFSTR("SecRequirementSyntax");
53const CFStringRef kSecCFErrorPath = CFSTR("SecComponentPath");
54
55
56//
57// CF-standard type code functions
58//
59CFTypeID SecCodeGetTypeID(void)
60{
61 BEGIN_CSAPI
62 return gCFObjects().Code.typeID;
63 END_CSAPI1(_kCFRuntimeNotATypeID)
64}
65
66
67//
68// Get a reference to the calling code.
69//
70OSStatus SecCodeCopySelf(SecCSFlags flags, SecCodeRef *selfRef)
71{
72 BEGIN_CSAPI
5c19dc3a 73
b1ab9ed8
A
74 checkFlags(flags);
75 CFRef<CFMutableDictionaryRef> attributes = makeCFMutableDictionary(1,
76 kSecGuestAttributePid, CFTempNumber(getpid()).get());
77 CodeSigning::Required(selfRef) = SecCode::autoLocateGuest(attributes, flags)->handle(false);
5c19dc3a 78
b1ab9ed8
A
79 END_CSAPI
80}
81
82
83//
84// Get the dynamic status of a code.
85//
86OSStatus SecCodeGetStatus(SecCodeRef codeRef, SecCSFlags flags, SecCodeStatus *status)
87{
88 BEGIN_CSAPI
5c19dc3a 89
b1ab9ed8
A
90 checkFlags(flags);
91 CodeSigning::Required(status) = SecCode::required(codeRef)->status();
5c19dc3a 92
b1ab9ed8
A
93 END_CSAPI
94}
95
96
97//
98// Change the dynamic status of a code
99//
100OSStatus SecCodeSetStatus(SecCodeRef codeRef, SecCodeStatusOperation operation,
101 CFDictionaryRef arguments, SecCSFlags flags)
102{
103 BEGIN_CSAPI
5c19dc3a 104
b1ab9ed8
A
105 checkFlags(flags);
106 SecCode::required(codeRef)->status(operation, arguments);
5c19dc3a 107
b1ab9ed8
A
108 END_CSAPI
109}
110
111
112//
113// Get the StaticCode for an Code
114//
115OSStatus SecCodeCopyStaticCode(SecCodeRef codeRef, SecCSFlags flags, SecStaticCodeRef *staticCodeRef)
116{
117 BEGIN_CSAPI
5c19dc3a 118
427c49bc 119 checkFlags(flags, kSecCSUseAllArchitectures);
b1ab9ed8 120 SecPointer<SecStaticCode> staticCode = SecCode::required(codeRef)->staticCode();
427c49bc
A
121 if (flags & kSecCSUseAllArchitectures)
122 if (Universal* macho = staticCode->diskRep()->mainExecutableImage()) // Mach-O main executable
123 if (macho->narrowed()) {
124 // create a new StaticCode comprising the whole fat file
125 RefPointer<DiskRep> rep = DiskRep::bestGuess(staticCode->diskRep()->mainExecutablePath());
126 staticCode = new SecStaticCode(rep);
127 }
b1ab9ed8
A
128 CodeSigning::Required(staticCodeRef) = staticCode ? staticCode->handle() : NULL;
129
130 END_CSAPI
131}
132
133
134//
135// Get the host for an Code
136//
137OSStatus SecCodeCopyHost(SecCodeRef guestRef, SecCSFlags flags, SecCodeRef *hostRef)
138{
139 BEGIN_CSAPI
5c19dc3a 140
b1ab9ed8
A
141 checkFlags(flags);
142 SecPointer<SecCode> host = SecCode::required(guestRef)->host();
143 CodeSigning::Required(hostRef) = host ? host->handle() : NULL;
144
145 END_CSAPI
146}
147
148
149//
150// Find a guest by attribute(s)
151//
152const CFStringRef kSecGuestAttributeCanonical = CFSTR("canonical");
153const CFStringRef kSecGuestAttributeHash = CFSTR("codedirectory-hash");
154const CFStringRef kSecGuestAttributeMachPort = CFSTR("mach-port");
155const CFStringRef kSecGuestAttributePid = CFSTR("pid");
fa7225c8
A
156const CFStringRef kSecGuestAttributeAudit = CFSTR("audit");
157const CFStringRef kSecGuestAttributeDynamicCode = CFSTR("dynamicCode");
158const CFStringRef kSecGuestAttributeDynamicCodeInfoPlist = CFSTR("dynamicCodeInfoPlist");
b1ab9ed8
A
159const CFStringRef kSecGuestAttributeArchitecture = CFSTR("architecture");
160const CFStringRef kSecGuestAttributeSubarchitecture = CFSTR("subarchitecture");
161
162OSStatus SecCodeCopyGuestWithAttributes(SecCodeRef hostRef,
163 CFDictionaryRef attributes, SecCSFlags flags, SecCodeRef *guestRef)
164{
165 BEGIN_CSAPI
5c19dc3a 166
b1ab9ed8
A
167 checkFlags(flags);
168 if (hostRef) {
169 if (SecCode *guest = SecCode::required(hostRef)->locateGuest(attributes))
170 CodeSigning::Required(guestRef) = guest->handle(false);
171 else
172 return errSecCSNoSuchCode;
173 } else
174 CodeSigning::Required(guestRef) = SecCode::autoLocateGuest(attributes, flags)->handle(false);
5c19dc3a 175
b1ab9ed8
A
176 END_CSAPI
177}
178
179
180//
181// Shorthand for getting the SecCodeRef for a UNIX process
182//
183OSStatus SecCodeCreateWithPID(pid_t pid, SecCSFlags flags, SecCodeRef *processRef)
184{
185 BEGIN_CSAPI
5c19dc3a 186
b1ab9ed8
A
187 checkFlags(flags);
188 if (SecCode *guest = KernelCode::active()->locateGuest(CFTemp<CFDictionaryRef>("{%O=%d}", kSecGuestAttributePid, pid)))
189 CodeSigning::Required(processRef) = guest->handle(false);
190 else
191 return errSecCSNoSuchCode;
5c19dc3a 192
b1ab9ed8
A
193 END_CSAPI
194}
195
196
197//
198// Check validity of an Code
199//
200OSStatus SecCodeCheckValidity(SecCodeRef codeRef, SecCSFlags flags,
201 SecRequirementRef requirementRef)
202{
203 return SecCodeCheckValidityWithErrors(codeRef, flags, requirementRef, NULL);
204}
205
206OSStatus SecCodeCheckValidityWithErrors(SecCodeRef codeRef, SecCSFlags flags,
207 SecRequirementRef requirementRef, CFErrorRef *errors)
208{
209 BEGIN_CSAPI
5c19dc3a 210
b1ab9ed8
A
211 checkFlags(flags,
212 kSecCSConsiderExpiration
e3d460c9 213 | kSecCSStrictValidate
fa7225c8 214 | kSecCSRestrictSidebandData
b1ab9ed8
A
215 | kSecCSEnforceRevocationChecks);
216 SecPointer<SecCode> code = SecCode::required(codeRef);
217 code->checkValidity(flags);
218 if (const SecRequirement *req = SecRequirement::optional(requirementRef))
219 code->staticCode()->validateRequirement(req->requirement(), errSecCSReqFailed);
220
221 END_CSAPI_ERRORS
222}
223
224
225//
226// Collect suitably laundered information about the code signature of a SecStaticCode
227// and return it as a CFDictionary.
228//
229// This API contracts to return a few pieces of information even for unsigned
230// code. This means that a SecStaticCodeRef is usable as a basic indentifier
231// (i.e. handle) for any code out there.
232//
233const CFStringRef kSecCodeInfoCertificates = CFSTR("certificates");
234const CFStringRef kSecCodeInfoChangedFiles = CFSTR("changed-files");
235const CFStringRef kSecCodeInfoCMS = CFSTR("cms");
236const CFStringRef kSecCodeInfoDesignatedRequirement = CFSTR("designated-requirement");
237const CFStringRef kSecCodeInfoEntitlements = CFSTR("entitlements");
238const CFStringRef kSecCodeInfoEntitlementsDict = CFSTR("entitlements-dict");
427c49bc 239const CFStringRef kSecCodeInfoFlags = CFSTR("flags");
b1ab9ed8
A
240const CFStringRef kSecCodeInfoFormat = CFSTR("format");
241const CFStringRef kSecCodeInfoDigestAlgorithm = CFSTR("digest-algorithm");
e3d460c9 242const CFStringRef kSecCodeInfoDigestAlgorithms = CFSTR("digest-algorithms");
5c19dc3a 243const CFStringRef kSecCodeInfoPlatformIdentifier = CFSTR("platform-identifier");
b1ab9ed8
A
244const CFStringRef kSecCodeInfoIdentifier = CFSTR("identifier");
245const CFStringRef kSecCodeInfoImplicitDesignatedRequirement = CFSTR("implicit-requirement");
246const CFStringRef kSecCodeInfoMainExecutable = CFSTR("main-executable");
247const CFStringRef kSecCodeInfoPList = CFSTR("info-plist");
248const CFStringRef kSecCodeInfoRequirements = CFSTR("requirements");
249const CFStringRef kSecCodeInfoRequirementData = CFSTR("requirement-data");
250const CFStringRef kSecCodeInfoSource = CFSTR("source");
251const CFStringRef kSecCodeInfoStatus = CFSTR("status");
420ff9d9 252const CFStringRef kSecCodeInfoTeamIdentifier = CFSTR("teamid");
b1ab9ed8
A
253const CFStringRef kSecCodeInfoTime = CFSTR("signing-time");
254const CFStringRef kSecCodeInfoTimestamp = CFSTR("signing-timestamp");
255const CFStringRef kSecCodeInfoTrust = CFSTR("trust");
256const CFStringRef kSecCodeInfoUnique = CFSTR("unique");
e3d460c9
A
257const CFStringRef kSecCodeInfoCdHashes = CFSTR("cdhashes");
258
b1ab9ed8
A
259
260const CFStringRef kSecCodeInfoCodeDirectory = CFSTR("CodeDirectory");
261const CFStringRef kSecCodeInfoCodeOffset = CFSTR("CodeOffset");
fa7225c8 262const CFStringRef kSecCodeInfoDiskRepInfo = CFSTR("DiskRepInfo");
b1ab9ed8
A
263const CFStringRef kSecCodeInfoResourceDirectory = CFSTR("ResourceDirectory");
264
fa7225c8
A
265/* DiskInfoRepInfo types */
266const CFStringRef kSecCodeInfoDiskRepOSPlatform = CFSTR("OSPlatform");
267const CFStringRef kSecCodeInfoDiskRepOSVersionMin = CFSTR("OSVersionMin");
268const CFStringRef kSecCodeInfoDiskRepOSSDKVersion = CFSTR("SDKVersion");
269const CFStringRef kSecCodeInfoDiskRepNoLibraryValidation = CFSTR("NoLibraryValidation");
270
b1ab9ed8
A
271
272OSStatus SecCodeCopySigningInformation(SecStaticCodeRef codeRef, SecCSFlags flags,
273 CFDictionaryRef *infoRef)
274{
275 BEGIN_CSAPI
5c19dc3a 276
b1ab9ed8
A
277 checkFlags(flags,
278 kSecCSInternalInformation
279 | kSecCSSigningInformation
280 | kSecCSRequirementInformation
281 | kSecCSDynamicInformation
866f8763
A
282 | kSecCSContentInformation
283 | kSecCSSkipResourceDirectory);
5c19dc3a 284
b1ab9ed8
A
285 SecPointer<SecStaticCode> code = SecStaticCode::requiredStatic(codeRef);
286 CFRef<CFDictionaryRef> info = code->signingInformation(flags);
5c19dc3a 287
b1ab9ed8
A
288 if (flags & kSecCSDynamicInformation)
289 if (SecPointer<SecCode> dcode = SecStaticCode::optionalDynamic(codeRef))
290 info.take(cfmake<CFDictionaryRef>("{+%O,%O=%u}", info.get(), kSecCodeInfoStatus, dcode->status()));
5c19dc3a 291
b1ab9ed8 292 CodeSigning::Required(infoRef) = info.yield();
5c19dc3a 293
b1ab9ed8
A
294 END_CSAPI
295}