]> git.saurik.com Git - apple/security.git/blame - Security/libsecurity_keychain/lib/SecTrustedApplication.cpp
Security-57031.30.12.tar.gz
[apple/security.git] / Security / libsecurity_keychain / lib / SecTrustedApplication.cpp
CommitLineData
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
35static 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
43CFTypeID
44SecTrustedApplicationGetTypeID(void)
45{
46 BEGIN_SECAPI
47
48 return gTypes().TrustedApplication.typeID;
49
50 END_SECAPI1(_kCFRuntimeNotATypeID)
51}
52
53
54OSStatus
55SecTrustedApplicationCreateFromPath(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
64OSStatus 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
73OSStatus 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
84OSStatus
85SecTrustedApplicationValidateWithPath(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//
98OSStatus 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
108OSStatus SecTrustedApplicationCreateWithExternalRepresentation(
109 CFDataRef externalRef,
110 SecTrustedApplicationRef *appRef)
111{
112 BEGIN_SECAPI
113 Required(appRef) = (new TrustedApplication(externalRef))->handle();
114 END_SECAPI
115}
116
117
118OSStatus
119SecTrustedApplicationMakeEquivalent(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
133OSStatus
134SecTrustedApplicationRemoveEquivalence(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 */
151OSStatus
152SecTrustedApplicationIsUpdateCandidate(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 */
178OSStatus
179SecTrustedApplicationUseAlternateSystem(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 */
196OSStatus 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
207OSStatus 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 */
221OSStatus 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}