2 * Copyright (c) 2002-2010 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@
25 #include "SecTrustPriv.h"
27 #include <security_keychain/SecTrustSettingsPriv.h>
28 #include "SecBridge.h"
29 #include "SecTrustSettings.h"
30 #include "SecCertificatePriv.h"
31 #include <security_utilities/cfutilities.h>
32 #include <CoreFoundation/CoreFoundation.h>
38 CFTypeID
SecTrustGetTypeID(void)
42 return gTypes().Trust
.typeID
;
44 END_SECAPI1(_kCFRuntimeNotATypeID
)
49 // Sec* API bridge functions
51 OSStatus
SecTrustCreateWithCertificates(
52 CFArrayRef certificates
,
54 SecTrustRef
*trustRef
)
58 *trustRef
= (new Trust(certificates
, policies
))->handle();
63 SecTrustSetPolicies(SecTrustRef trustRef
, CFTypeRef policies
)
66 Trust::required(trustRef
)->policies(policies
);
71 SecTrustSetOptions(SecTrustRef trustRef
, SecTrustOptionFlags options
)
74 CSSM_APPLE_TP_ACTION_DATA actionData
= {
75 CSSM_APPLE_TP_ACTION_VERSION
,
76 (CSSM_APPLE_TP_ACTION_FLAGS
)options
78 Trust
*trust
= Trust::required(trustRef
);
79 CFDataRef actionDataRef
= CFDataCreate(NULL
,
80 (const UInt8
*)&actionData
,
81 (CFIndex
)sizeof(CSSM_APPLE_TP_ACTION_DATA
));
82 trust
->action(CSSM_TP_ACTION_DEFAULT
);
83 trust
->actionData(actionDataRef
);
84 if (actionDataRef
) CFRelease(actionDataRef
);
88 OSStatus
SecTrustSetParameters(
90 CSSM_TP_ACTION action
,
94 Trust
*trust
= Trust::required(trustRef
);
95 trust
->action(action
);
96 trust
->actionData(actionData
);
101 OSStatus
SecTrustSetAnchorCertificates(SecTrustRef trust
, CFArrayRef anchorCertificates
)
104 Trust::required(trust
)->anchors(anchorCertificates
);
108 OSStatus
SecTrustSetAnchorCertificatesOnly(SecTrustRef trust
, Boolean anchorCertificatesOnly
)
111 Trust::AnchorPolicy policy
= (anchorCertificatesOnly
) ? Trust::useAnchorsOnly
: Trust::useAnchorsAndBuiltIns
;
112 Trust::required(trust
)->anchorPolicy(policy
);
116 OSStatus
SecTrustSetKeychains(SecTrustRef trust
, CFTypeRef keychainOrArray
)
119 StorageManager::KeychainList keychains
;
120 // avoid unnecessary global initializations if an empty array is passed in
121 if (!( (keychainOrArray
!= NULL
) &&
122 (CFGetTypeID(keychainOrArray
) == CFArrayGetTypeID()) &&
123 (CFArrayGetCount((CFArrayRef
)keychainOrArray
) == 0) )) {
124 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
);
126 Trust::required(trust
)->searchLibs(keychains
);
131 OSStatus
SecTrustSetVerifyDate(SecTrustRef trust
, CFDateRef verifyDate
)
134 Trust::required(trust
)->time(verifyDate
);
139 CFAbsoluteTime
SecTrustGetVerifyTime(SecTrustRef trust
)
141 CFAbsoluteTime verifyTime
= 0;
142 OSStatus __secapiresult
;
144 CFRef
<CFDateRef
> verifyDate
= Trust::required(trust
)->time();
145 verifyTime
= CFDateGetAbsoluteTime(verifyDate
);
147 __secapiresult
=noErr
;
149 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
150 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
151 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
152 catch (...) { __secapiresult
=internalComponentErr
; }
156 OSStatus
SecTrustEvaluate(SecTrustRef trustRef
, SecTrustResultType
*resultP
)
159 Trust
*trust
= Trust::required(trustRef
);
162 *resultP
= trust
->result();
163 secdebug("SecTrustEvaluate", "SecTrustEvaluate trust result = %d", (int)*resultP
);
168 OSStatus
SecTrustEvaluateAsync(SecTrustRef trust
,
169 dispatch_queue_t queue
, SecTrustCallback result
)
172 dispatch_async(queue
, ^{
174 Trust
*trustObj
= Trust::required(trust
);
175 trustObj
->evaluate();
176 result(trust
, trustObj
->result());
179 result(trust
, kSecTrustResultInvalid
);
186 // Construct the "official" result evidence and return it
188 OSStatus
SecTrustGetResult(
189 SecTrustRef trustRef
,
190 SecTrustResultType
*result
,
191 CFArrayRef
*certChain
, CSSM_TP_APPLE_EVIDENCE_INFO
**statusChain
)
194 Trust
*trust
= Trust::required(trustRef
);
196 *result
= trust
->result();
197 if (certChain
&& statusChain
)
198 trust
->buildEvidence(*certChain
, TPEvidenceInfo::overlayVar(*statusChain
));
203 // Retrieve result of trust evaluation only
205 OSStatus
SecTrustGetTrustResult(SecTrustRef trustRef
,
206 SecTrustResultType
*result
)
209 Trust
*trust
= Trust::required(trustRef
);
210 if (result
) *result
= trust
->result();
215 // Retrieve extended validation trust results
217 OSStatus
SecTrustCopyExtendedResult(SecTrustRef trust
, CFDictionaryRef
*result
)
220 Trust
*trustObj
= Trust::required(trust
);
223 trustObj
->extendedResult(*result
);
228 // Retrieve CSSM-level information for those who want to dig down
230 OSStatus
SecTrustGetCssmResult(SecTrustRef trust
, CSSM_TP_VERIFY_CONTEXT_RESULT_PTR
*result
)
233 Required(result
) = Trust::required(trust
)->cssmResult();
238 // Retrieve CSSM_LEVEL TP return code
240 OSStatus
SecTrustGetCssmResultCode(SecTrustRef trustRef
, OSStatus
*result
)
243 Trust
*trust
= Trust::required(trustRef
);
244 if (trust
->result() == kSecTrustResultInvalid
)
247 Required(result
) = trust
->cssmResultCode();
251 OSStatus
SecTrustGetTPHandle(SecTrustRef trust
, CSSM_TP_HANDLE
*handle
)
254 Required(handle
) = Trust::required(trust
)->getTPHandle();
258 OSStatus
SecTrustCopyPolicies(SecTrustRef trust
, CFArrayRef
*policies
)
261 CFArrayRef currentPolicies
= Trust::required(trust
)->policies();
262 if (currentPolicies
!= NULL
)
264 CFRetain(currentPolicies
);
267 Required(policies
) = currentPolicies
;
271 OSStatus
SecTrustCopyCustomAnchorCertificates(SecTrustRef trust
, CFArrayRef
*anchorCertificates
)
274 CFRef
<CFArrayRef
> customAnchors(Trust::required(trust
)->anchors());
275 Required(anchorCertificates
) = (customAnchors
) ?
276 (const CFArrayRef
)CFRetain(customAnchors
) : (const CFArrayRef
)NULL
;
281 // Get the user's default anchor certificate set
283 OSStatus
SecTrustCopyAnchorCertificates(CFArrayRef
*anchorCertificates
)
287 return SecTrustSettingsCopyUnrestrictedRoots(
288 true, true, true, /* all domains */
295 SecKeyRef
SecTrustCopyPublicKey(SecTrustRef trust
)
297 SecKeyRef pubKey
= NULL
;
298 CFArrayRef certChain
= NULL
;
299 CFArrayRef evidenceChain
= NULL
;
300 CSSM_TP_APPLE_EVIDENCE_INFO
*statusChain
= NULL
;
301 OSStatus __secapiresult
;
303 Trust
*trustObj
= Trust::required(trust
);
304 if (trustObj
->result() == kSecTrustResultInvalid
)
305 MacOSError::throwMe(errSecTrustNotAvailable
);
306 if (trustObj
->evidence() == nil
)
307 trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
));
308 evidenceChain
= trustObj
->evidence();
309 __secapiresult
=noErr
;
311 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
312 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
313 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
314 catch (...) { __secapiresult
=internalComponentErr
; }
317 CFRelease(certChain
);
320 if (CFArrayGetCount(evidenceChain
) > 0) {
321 SecCertificateRef cert
= (SecCertificateRef
) CFArrayGetValueAtIndex(evidenceChain
, 0);
322 __secapiresult
= SecCertificateCopyPublicKey(cert
, &pubKey
);
324 // do not release evidenceChain, as it is owned by the trust object.
330 CFIndex
SecTrustGetCertificateCount(SecTrustRef trust
)
332 CFIndex chainLen
= 0;
333 CFArrayRef certChain
= NULL
;
334 CFArrayRef evidenceChain
= NULL
;
335 CSSM_TP_APPLE_EVIDENCE_INFO
*statusChain
= NULL
;
336 OSStatus __secapiresult
;
338 Trust
*trustObj
= Trust::required(trust
);
339 if (trustObj
->result() == kSecTrustResultInvalid
)
340 MacOSError::throwMe(errSecTrustNotAvailable
);
341 if (trustObj
->evidence() == nil
)
342 trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
));
343 evidenceChain
= trustObj
->evidence();
344 __secapiresult
=noErr
;
346 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
347 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
348 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
349 catch (...) { __secapiresult
=internalComponentErr
; }
352 CFRelease(certChain
);
355 chainLen
= CFArrayGetCount(evidenceChain
); // don't release, trust object owns it.
361 SecCertificateRef
SecTrustGetCertificateAtIndex(SecTrustRef trust
, CFIndex ix
)
363 SecCertificateRef certificate
= NULL
;
364 CFArrayRef certChain
= NULL
;
365 CFArrayRef evidenceChain
= NULL
;
366 CSSM_TP_APPLE_EVIDENCE_INFO
*statusChain
= NULL
;
367 OSStatus __secapiresult
;
369 Trust
*trustObj
= Trust::required(trust
);
370 if (trustObj
->result() == kSecTrustResultInvalid
)
371 MacOSError::throwMe(errSecTrustNotAvailable
);
372 if (trustObj
->evidence() == nil
)
373 trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
));
374 evidenceChain
= trustObj
->evidence();
375 __secapiresult
=noErr
;
377 catch (const MacOSError
&err
) { __secapiresult
=err
.osStatus(); }
378 catch (const CommonError
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); }
379 catch (const std::bad_alloc
&) { __secapiresult
=memFullErr
; }
380 catch (...) { __secapiresult
=internalComponentErr
; }
383 CFRelease(certChain
);
386 if (ix
< CFArrayGetCount(evidenceChain
)) {
387 certificate
= (SecCertificateRef
) CFArrayGetValueAtIndex(evidenceChain
, ix
);
388 // note: we do not retain this certificate. The assumption here is
389 // that the certificate is retained by the trust object, so it is
390 // valid unil the trust is released (or until re-evaluated.)
391 // also note: we do not release the evidenceChain, as it is owned
392 // by the trust object.
400 SecTrustCopyProperties(SecTrustRef trust
)
402 /* can't use SECAPI macros, since this function does not return OSStatus */
403 CFArrayRef result
= NULL
;
405 result
= Trust::required(trust
)->properties();
417 /* deprecated in 10.5 */
418 OSStatus
SecTrustGetCSSMAnchorCertificates(const CSSM_DATA
**cssmAnchors
,
419 uint32
*cssmAnchorCount
)
423 Trust::gStore().getCssmRootCertificates(certs
);
424 Required(cssmAnchors
) = certs
.blobCerts();
425 Required(cssmAnchorCount
) = certs
.count();
431 // Get and set user trust settings. Deprecated in 10.5.
432 // User Trust getter, deprecated, works as it always has.
434 OSStatus
SecTrustGetUserTrust(SecCertificateRef certificate
,
435 SecPolicyRef policy
, SecTrustUserSetting
*trustSetting
)
438 StorageManager::KeychainList searchList
;
439 globals().storageManager
.getSearchList(searchList
);
440 Required(trustSetting
) = Trust::gStore().find(
441 Certificate::required(certificate
),
442 Policy::required(policy
),
448 // The public setter, also deprecated; it maps to the appropriate
449 // Trust Settings call if possible, else throws unimpErr.
451 OSStatus
SecTrustSetUserTrust(SecCertificateRef certificate
,
452 SecPolicyRef policy
, SecTrustUserSetting trustSetting
)
454 SecTrustSettingsResult tsResult
= kSecTrustSettingsResultInvalid
;
458 Policy::required(policy
);
459 switch(trustSetting
) {
460 case kSecTrustResultProceed
:
461 /* different SecTrustSettingsResult depending in root-ness */
462 ortn
= SecCertificateIsSelfSigned(certificate
, &isRoot
);
467 tsResult
= kSecTrustSettingsResultTrustRoot
;
470 tsResult
= kSecTrustSettingsResultTrustAsRoot
;
473 case kSecTrustResultDeny
:
474 tsResult
= kSecTrustSettingsResultDeny
;
480 /* make a usage constraints dictionary */
481 CFRef
<CFMutableDictionaryRef
> usageDict(CFDictionaryCreateMutable(NULL
,
482 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
));
483 CFDictionaryAddValue(usageDict
, kSecTrustSettingsPolicy
, policy
);
484 if(tsResult
!= kSecTrustSettingsResultTrustRoot
) {
485 /* skip if we're specifying the default */
486 SInt32 result
= tsResult
;
487 CFNumberRef cfNum
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &result
);
488 CFDictionarySetValue(usageDict
, kSecTrustSettingsResult
, cfNum
);
491 return SecTrustSettingsSetTrustSettings(certificate
, kSecTrustSettingsDomainUser
,
496 // This one is the now-private version of what SecTrustSetUserTrust() used to
497 // be. The public API can no longer manipulate User Trust settings, only
500 OSStatus
SecTrustSetUserTrustLegacy(SecCertificateRef certificate
,
501 SecPolicyRef policy
, SecTrustUserSetting trustSetting
)
504 switch (trustSetting
) {
505 case kSecTrustResultProceed
:
506 case kSecTrustResultConfirm
:
507 case kSecTrustResultDeny
:
508 case kSecTrustResultUnspecified
:
511 MacOSError::throwMe(errSecInvalidTrustSetting
);
513 Trust::gStore().assign(
514 Certificate::required(certificate
),
515 Policy::required(policy
),
520 /* SecGetAppleTPHandle - @@@NOT EXPORTED YET; copied from SecurityInterface,
521 but could be useful in the future.
525 SecGetAppleTPHandle()
528 return TP(gGuidAppleX509TP)->handle();