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