]>
Commit | Line | Data |
---|---|---|
b1ab9ed8 | 1 | /* |
d8f41ccd | 2 | * Copyright (c) 2002-2004,2011-2014 Apple Inc. All Rights Reserved. |
427c49bc | 3 | * |
b1ab9ed8 | 4 | * @APPLE_LICENSE_HEADER_START@ |
d8f41ccd | 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. | |
d8f41ccd | 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. | |
d8f41ccd | 20 | * |
b1ab9ed8 A |
21 | * @APPLE_LICENSE_HEADER_END@ |
22 | */ | |
23 | ||
24 | #include <Security/SecTrustedApplicationPriv.h> | |
25 | #include <security_keychain/TrustedApplication.h> | |
26 | #include <security_keychain/Certificate.h> | |
27 | #include <securityd_client/ssclient.h> // for code equivalence SPIs | |
28 | ||
29 | #include "SecBridge.h" | |
30 | ||
427c49bc A |
31 | |
32 | ||
d8f41ccd A |
33 | #pragma clang diagnostic push |
34 | #pragma clang diagnostic ignored "-Wunused-function" | |
b1ab9ed8 A |
35 | static inline CssmData cfData(CFDataRef data) |
36 | { | |
37 | return CssmData(const_cast<UInt8 *>(CFDataGetBytePtr(data)), | |
38 | CFDataGetLength(data)); | |
39 | } | |
d8f41ccd | 40 | #pragma clang diagnostic pop |
b1ab9ed8 A |
41 | |
42 | ||
43 | CFTypeID | |
44 | SecTrustedApplicationGetTypeID(void) | |
45 | { | |
46 | BEGIN_SECAPI | |
47 | ||
48 | return gTypes().TrustedApplication.typeID; | |
49 | ||
50 | END_SECAPI1(_kCFRuntimeNotATypeID) | |
51 | } | |
52 | ||
53 | ||
54 | OSStatus | |
55 | SecTrustedApplicationCreateFromPath(const char *path, SecTrustedApplicationRef *appRef) | |
56 | { | |
57 | BEGIN_SECAPI | |
58 | SecPointer<TrustedApplication> app = | |
59 | path ? new TrustedApplication(path) : new TrustedApplication; | |
60 | Required(appRef) = app->handle(); | |
61 | END_SECAPI | |
62 | } | |
63 | ||
64 | OSStatus SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef, | |
65 | CFDataRef *dataRef) | |
66 | { | |
67 | BEGIN_SECAPI | |
68 | const char *path = TrustedApplication::required(appRef)->path(); | |
69 | Required(dataRef) = CFDataCreate(NULL, (const UInt8 *)path, strlen(path) + 1); | |
70 | END_SECAPI | |
71 | } | |
72 | ||
73 | OSStatus SecTrustedApplicationSetData(SecTrustedApplicationRef appRef, | |
74 | CFDataRef dataRef) | |
75 | { | |
76 | BEGIN_SECAPI | |
427c49bc A |
77 | if (!dataRef) |
78 | return errSecParam; | |
79 | TrustedApplication::required(appRef)->data(dataRef); | |
b1ab9ed8 A |
80 | END_SECAPI |
81 | } | |
82 | ||
83 | ||
84 | OSStatus | |
85 | SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef, const char *path) | |
86 | { | |
87 | BEGIN_SECAPI | |
88 | TrustedApplication &app = *TrustedApplication::required(appRef); | |
89 | if (!app.verifyToDisk(path)) | |
90 | return CSSMERR_CSP_VERIFY_FAILED; | |
91 | END_SECAPI | |
92 | } | |
93 | ||
94 | ||
95 | // | |
96 | // Convert from/to external data representation | |
97 | // | |
98 | OSStatus SecTrustedApplicationCopyExternalRepresentation( | |
427c49bc | 99 | SecTrustedApplicationRef appRef, |
b1ab9ed8 A |
100 | CFDataRef *externalRef) |
101 | { | |
102 | BEGIN_SECAPI | |
103 | TrustedApplication &app = *TrustedApplication::required(appRef); | |
104 | Required(externalRef) = app.externalForm(); | |
105 | END_SECAPI | |
106 | } | |
107 | ||
108 | OSStatus SecTrustedApplicationCreateWithExternalRepresentation( | |
109 | CFDataRef externalRef, | |
110 | SecTrustedApplicationRef *appRef) | |
111 | { | |
112 | BEGIN_SECAPI | |
113 | Required(appRef) = (new TrustedApplication(externalRef))->handle(); | |
114 | END_SECAPI | |
115 | } | |
116 | ||
117 | ||
118 | OSStatus | |
119 | SecTrustedApplicationMakeEquivalent(SecTrustedApplicationRef oldRef, | |
120 | SecTrustedApplicationRef newRef, UInt32 flags) | |
121 | { | |
122 | BEGIN_SECAPI | |
123 | if (flags & ~kSecApplicationValidFlags) | |
427c49bc | 124 | return errSecParam; |
b1ab9ed8 A |
125 | SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard()); |
126 | TrustedApplication *oldApp = TrustedApplication::required(oldRef); | |
127 | TrustedApplication *newApp = TrustedApplication::required(newRef); | |
128 | ss.addCodeEquivalence(oldApp->legacyHash(), newApp->legacyHash(), oldApp->path(), | |
129 | flags & kSecApplicationFlagSystemwide); | |
130 | END_SECAPI | |
131 | } | |
132 | ||
133 | OSStatus | |
134 | SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef, UInt32 flags) | |
135 | { | |
136 | BEGIN_SECAPI | |
137 | if (flags & ~kSecApplicationValidFlags) | |
427c49bc | 138 | return errSecParam; |
b1ab9ed8 A |
139 | SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard()); |
140 | TrustedApplication *app = TrustedApplication::required(appRef); | |
141 | ss.removeCodeEquivalence(app->legacyHash(), app->path(), | |
142 | flags & kSecApplicationFlagSystemwide); | |
143 | END_SECAPI | |
144 | } | |
145 | ||
146 | ||
147 | /* | |
148 | * Check to see if an application at a given path is a candidate for | |
149 | * pre-emptive code equivalency establishment | |
150 | */ | |
151 | OSStatus | |
152 | SecTrustedApplicationIsUpdateCandidate(const char *installroot, const char *path) | |
153 | { | |
154 | BEGIN_SECAPI | |
427c49bc | 155 | |
b1ab9ed8 A |
156 | // strip installroot |
157 | if (installroot) { | |
158 | size_t rootlen = strlen(installroot); | |
159 | if (!strncmp(installroot, path, rootlen)) | |
160 | path += rootlen - 1; // keep the slash | |
161 | } | |
427c49bc | 162 | |
b1ab9ed8 A |
163 | // look up in database |
164 | static ModuleNexus<PathDatabase> paths; | |
165 | static ModuleNexus<RecursiveMutex> mutex; | |
166 | StLock<Mutex>_(mutex()); | |
427c49bc | 167 | |
b1ab9ed8 A |
168 | if (!paths()[path]) |
169 | return CSSMERR_DL_RECORD_NOT_FOUND; // whatever | |
170 | END_SECAPI | |
171 | } | |
172 | ||
173 | ||
174 | /* | |
175 | * Point the system at another system root for equivalence use. | |
176 | * This is for system update installers (only)! | |
177 | */ | |
178 | OSStatus | |
179 | SecTrustedApplicationUseAlternateSystem(const char *systemRoot) | |
180 | { | |
181 | BEGIN_SECAPI | |
182 | Required(systemRoot); | |
183 | SecurityServer::ClientSession ss(Allocator::standard(), Allocator::standard()); | |
184 | ss.setAlternateSystemRoot(systemRoot); | |
185 | END_SECAPI | |
186 | } | |
187 | ||
188 | ||
189 | /* | |
190 | * Gateway between traditional SecTrustedApplicationRefs and the Code Signing | |
191 | * subsystem. Invisible to the naked eye, as of 10.5 (Leopard), these reference | |
192 | * may contain Cod e Signing Requirement objects (SecRequirementRefs). For backward | |
193 | * compatibility, these are handled implicitly at the SecAccess/SecACL layer. | |
194 | * However, Those Who Know can bridge the gap for additional functionality. | |
195 | */ | |
196 | OSStatus SecTrustedApplicationCreateFromRequirement(const char *description, | |
197 | SecRequirementRef requirement, SecTrustedApplicationRef *appRef) | |
198 | { | |
199 | BEGIN_SECAPI | |
200 | if (description == NULL) | |
201 | description = "csreq://"; // default to "generic requirement" | |
202 | SecPointer<TrustedApplication> app = new TrustedApplication(description, requirement); | |
427c49bc | 203 | Required(appRef) = app->handle(); |
b1ab9ed8 A |
204 | END_SECAPI |
205 | } | |
206 | ||
207 | OSStatus SecTrustedApplicationCopyRequirement(SecTrustedApplicationRef appRef, | |
208 | SecRequirementRef *requirement) | |
209 | { | |
210 | BEGIN_SECAPI | |
211 | Required(requirement) = TrustedApplication::required(appRef)->requirement(); | |
212 | if (*requirement) | |
213 | CFRetain(*requirement); | |
214 | END_SECAPI | |
215 | } | |
216 | ||
217 | ||
218 | /* | |
219 | * Create an application group reference. | |
220 | */ | |
221 | OSStatus SecTrustedApplicationCreateApplicationGroup(const char *groupName, | |
222 | SecCertificateRef anchor, SecTrustedApplicationRef *appRef) | |
223 | { | |
224 | BEGIN_SECAPI | |
225 | ||
226 | CFRef<SecRequirementRef> req; | |
227 | MacOSError::check(SecRequirementCreateGroup(CFTempString(groupName), anchor, | |
228 | kSecCSDefaultFlags, &req.aref())); | |
229 | string description = string("group://") + groupName; | |
230 | if (anchor) { | |
231 | Certificate *cert = Certificate::required(anchor); | |
232 | const CssmData &hash = cert->publicKeyHash(); | |
233 | description = description + "?cert=" + cfString(cert->commonName()) | |
234 | + "&hash=" + hash.toHex(); | |
235 | } | |
236 | SecPointer<TrustedApplication> app = new TrustedApplication(description, req); | |
237 | Required(appRef) = app->handle(); | |
238 | ||
239 | END_SECAPI | |
240 | } |