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