2 * Copyright (c) 2002-2004,2011-2014 Apple Inc. All Rights Reserved.
4 * @APPLE_LICENSE_HEADER_START@
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
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.
21 * @APPLE_LICENSE_HEADER_END@
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
29 #include "SecBridge.h"
33 #pragma clang diagnostic push
34 #pragma clang diagnostic ignored "-Wunused-function"
35 static inline CssmData
cfData(CFDataRef data
)
37 return CssmData(const_cast<UInt8
*>(CFDataGetBytePtr(data
)),
38 CFDataGetLength(data
));
40 #pragma clang diagnostic pop
44 SecTrustedApplicationGetTypeID(void)
48 return gTypes().TrustedApplication
.typeID
;
50 END_SECAPI1(_kCFRuntimeNotATypeID
)
55 SecTrustedApplicationCreateFromPath(const char *path
, SecTrustedApplicationRef
*appRef
)
58 SecPointer
<TrustedApplication
> app
=
59 path
? new TrustedApplication(path
) : new TrustedApplication
;
60 Required(appRef
) = app
->handle();
64 OSStatus
SecTrustedApplicationCopyData(SecTrustedApplicationRef appRef
,
68 const char *path
= TrustedApplication::required(appRef
)->path();
69 Required(dataRef
) = CFDataCreate(NULL
, (const UInt8
*)path
, strlen(path
) + 1);
73 OSStatus
SecTrustedApplicationSetData(SecTrustedApplicationRef appRef
,
79 TrustedApplication::required(appRef
)->data(dataRef
);
85 SecTrustedApplicationValidateWithPath(SecTrustedApplicationRef appRef
, const char *path
)
88 TrustedApplication
&app
= *TrustedApplication::required(appRef
);
89 if (!app
.verifyToDisk(path
))
90 return CSSMERR_CSP_VERIFY_FAILED
;
96 // Convert from/to external data representation
98 OSStatus
SecTrustedApplicationCopyExternalRepresentation(
99 SecTrustedApplicationRef appRef
,
100 CFDataRef
*externalRef
)
103 TrustedApplication
&app
= *TrustedApplication::required(appRef
);
104 Required(externalRef
) = app
.externalForm();
108 OSStatus
SecTrustedApplicationCreateWithExternalRepresentation(
109 CFDataRef externalRef
,
110 SecTrustedApplicationRef
*appRef
)
113 Required(appRef
) = (new TrustedApplication(externalRef
))->handle();
119 SecTrustedApplicationMakeEquivalent(SecTrustedApplicationRef oldRef
,
120 SecTrustedApplicationRef newRef
, UInt32 flags
)
123 if (flags
& ~kSecApplicationValidFlags
)
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
);
134 SecTrustedApplicationRemoveEquivalence(SecTrustedApplicationRef appRef
, UInt32 flags
)
137 if (flags
& ~kSecApplicationValidFlags
)
139 SecurityServer::ClientSession
ss(Allocator::standard(), Allocator::standard());
140 TrustedApplication
*app
= TrustedApplication::required(appRef
);
141 ss
.removeCodeEquivalence(app
->legacyHash(), app
->path(),
142 flags
& kSecApplicationFlagSystemwide
);
148 * Check to see if an application at a given path is a candidate for
149 * pre-emptive code equivalency establishment
152 SecTrustedApplicationIsUpdateCandidate(const char *installroot
, const char *path
)
158 size_t rootlen
= strlen(installroot
);
159 if (!strncmp(installroot
, path
, rootlen
))
160 path
+= rootlen
- 1; // keep the slash
163 // look up in database
164 static ModuleNexus
<PathDatabase
> paths
;
165 static ModuleNexus
<RecursiveMutex
> mutex
;
166 StLock
<Mutex
>_(mutex());
169 return CSSMERR_DL_RECORD_NOT_FOUND
; // whatever
175 * Point the system at another system root for equivalence use.
176 * This is for system update installers (only)!
179 SecTrustedApplicationUseAlternateSystem(const char *systemRoot
)
182 Required(systemRoot
);
183 SecurityServer::ClientSession
ss(Allocator::standard(), Allocator::standard());
184 ss
.setAlternateSystemRoot(systemRoot
);
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.
196 OSStatus
SecTrustedApplicationCreateFromRequirement(const char *description
,
197 SecRequirementRef requirement
, SecTrustedApplicationRef
*appRef
)
200 if (description
== NULL
)
201 description
= "csreq://"; // default to "generic requirement"
202 SecPointer
<TrustedApplication
> app
= new TrustedApplication(description
, requirement
);
203 Required(appRef
) = app
->handle();
207 OSStatus
SecTrustedApplicationCopyRequirement(SecTrustedApplicationRef appRef
,
208 SecRequirementRef
*requirement
)
211 Required(requirement
) = TrustedApplication::required(appRef
)->requirement();
213 CFRetain(*requirement
);
219 * Create an application group reference.
221 OSStatus
SecTrustedApplicationCreateApplicationGroup(const char *groupName
,
222 SecCertificateRef anchor
, SecTrustedApplicationRef
*appRef
)
226 CFRef
<SecRequirementRef
> req
;
227 MacOSError::check(SecRequirementCreateGroup(CFTempString(groupName
), anchor
,
228 kSecCSDefaultFlags
, &req
.aref()));
229 string description
= string("group://") + groupName
;
231 Certificate
*cert
= Certificate::required(anchor
);
232 const CssmData
&hash
= cert
->publicKeyHash();
233 description
= description
+ "?cert=" + cfString(cert
->commonName())
234 + "&hash=" + hash
.toHex();
236 SecPointer
<TrustedApplication
> app
= new TrustedApplication(description
, req
);
237 Required(appRef
) = app
->handle();