2  * Copyright (c) 2002-2015 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> 
  29 #include "SecBridge.h" 
  30 #include "SecInternal.h" 
  31 #include "SecInternalP.h" 
  32 #include "SecTrustSettings.h" 
  33 #include "SecCertificatePriv.h" 
  34 #include "SecCertificateP.h" 
  35 #include "SecCertificatePrivP.h" 
  36 #include "SecPolicyPriv.h" 
  37 #include <security_utilities/cfutilities.h> 
  38 #include <security_utilities/cfmunge.h> 
  39 #include <CoreFoundation/CoreFoundation.h> 
  42 // forward declarations 
  44 CFArrayRef 
SecTrustCopyDetails(SecTrustRef trust
); 
  45 static CFDictionaryRef 
SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust
, CFIndex ix
); 
  46 static void SecTrustCheckException(const void *key
, const void *value
, void *context
); 
  49 typedef struct SecTrustCheckExceptionContext 
{ 
  50         CFDictionaryRef exception
; 
  51         bool exceptionNotFound
; 
  52 } SecTrustCheckExceptionContext
; 
  54 // public trust result constants 
  55 const CFStringRef kSecTrustEvaluationDate           
= CFSTR("TrustEvaluationDate"); 
  56 const CFStringRef kSecTrustExtendedValidation       
= CFSTR("TrustExtendedValidation"); 
  57 const CFStringRef kSecTrustOrganizationName         
= CFSTR("Organization"); 
  58 const CFStringRef kSecTrustResultValue              
= CFSTR("TrustResultValue"); 
  59 const CFStringRef kSecTrustRevocationChecked        
= CFSTR("TrustRevocationChecked"); 
  60 const CFStringRef kSecTrustRevocationReason         
= CFSTR("TrustRevocationReason"); 
  61 const CFStringRef kSecTrustRevocationValidUntilDate 
= CFSTR("TrustExpirationDate"); 
  62 const CFStringRef kSecTrustResultDetails            
= CFSTR("TrustResultDetails"); 
  68 CFTypeID 
SecTrustGetTypeID(void) 
  72         return gTypes().Trust
.typeID
; 
  74         END_SECAPI1(_kCFRuntimeNotATypeID
) 
  79 // Sec* API bridge functions 
  82 OSStatus 
SecTrustCreateWithCertificates( 
  83         CFTypeRef certificates
, 
  85         SecTrustRef 
*trustRef
) 
  89         *trustRef 
= (new Trust(certificates
, policies
))->handle(); 
  96 SecTrustSetPolicies(SecTrustRef trustRef
, CFTypeRef policies
) 
  99         Trust::required(trustRef
)->policies(policies
); 
 104 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */ 
 106 SecTrustSetOptions(SecTrustRef trustRef
, SecTrustOptionFlags options
) 
 110         CSSM_APPLE_TP_ACTION_DATA actionData 
= { 
 111                 CSSM_APPLE_TP_ACTION_VERSION
, 
 112                 (CSSM_APPLE_TP_ACTION_FLAGS
)options
 
 114         Trust 
*trust 
= Trust::required(trustRef
); 
 115         CFDataRef actionDataRef 
= CFDataCreate(NULL
, 
 116                 (const UInt8 
*)&actionData
, 
 117                 (CFIndex
)sizeof(CSSM_APPLE_TP_ACTION_DATA
)); 
 118         trust
->action(CSSM_TP_ACTION_DEFAULT
); 
 119         trust
->actionData(actionDataRef
); 
 120         if (actionDataRef
) CFRelease(actionDataRef
); 
 123         /* bridge to support API functionality for legacy callers */ 
 124         OSStatus status 
= errSecSuccess
; 
 126 #warning STU: <rdar://21328005> 
 127 //%%% need to ensure that the exception covers only the requested options 
 129         CFArrayRef details 
= SecTrustGetDetails(trustRef
); // NOTE: performs the evaluation if not done already 
 130         CFIndex pathLength 
= details 
? CFArrayGetCount(details
) : 0; 
 132         for (ix 
= 0; ix 
< pathLength
; ++ix
) { 
 133                 CFDictionaryRef detail 
= (CFDictionaryRef
)CFArrayGetValueAtIndex(details
, ix
); 
 134                 CFIndex detailCount 
= CFDictionaryGetCount(detail
); 
 135                 if (detailCount 
> 0) { 
 136                         // see if we can ignore this error 
 137                         syslog(LOG_ERR
, "SecTrustSetOptions: examining detail dictionary items at ix %ld", (long)ix
); 
 141         syslog(LOG_ERR
, "SecTrustSetOptions: creating trust exception"); 
 143         CFDataRef exceptions 
= SecTrustCopyExceptions(trustRef
); 
 145                 SecTrustSetExceptions(trustRef
, exceptions
); 
 146                 CFRelease(exceptions
); 
 150 #if SECTRUST_DEPRECATION_WARNINGS 
 151         bool displayModifyMsg 
= false; 
 152         bool displayNetworkMsg 
= false; 
 153         bool displayPolicyMsg 
= false; 
 154         const char *baseMsg 
= "WARNING: SecTrustSetOptions called with"; 
 155         const char *modifyMsg 
= "Use SecTrustSetExceptions and SecTrustCopyExceptions to modify default trust results."; 
 156         const char *networkMsg 
= "Use SecTrustSetNetworkFetchAllowed to specify whether missing certificates can be fetched from the network."; 
 157         const char *policyMsg 
= "Use SecPolicyCreateRevocation to specify revocation policy requirements."; 
 159         if (options 
& kSecTrustOptionAllowExpired
) { 
 160                 syslog(LOG_ERR
, "%s %s.", baseMsg
, "kSecTrustOptionAllowExpired"); 
 161                 displayModifyMsg 
= true; 
 163         if (options 
& kSecTrustOptionAllowExpiredRoot
) { 
 164                 syslog(LOG_ERR
, "%s %s.", baseMsg
, "kSecTrustOptionAllowExpiredRoot"); 
 165                 displayModifyMsg 
= true; 
 167         if (options 
& kSecTrustOptionFetchIssuerFromNet
) { 
 168                 syslog(LOG_ERR
, "%s %s.", baseMsg
, "kSecTrustOptionFetchIssuerFromNet"); 
 169                 displayNetworkMsg 
= true; 
 171         if (options 
& kSecTrustOptionRequireRevPerCert
) { 
 172                 syslog(LOG_ERR
, "%s %s.", baseMsg
, "kSecTrustOptionRequireRevPerCert"); 
 173                 displayPolicyMsg 
= true; 
 175         if (displayModifyMsg 
|| displayNetworkMsg 
|| displayPolicyMsg
) { 
 176                 syslog(LOG_ERR
, "%s %s %s", 
 177                         (displayModifyMsg
) ? modifyMsg 
: "", 
 178                         (displayNetworkMsg
) ? networkMsg 
: "", 
 179                         (displayPolicyMsg
) ? policyMsg 
: ""); 
 188 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ 
 189 OSStatus 
SecTrustSetParameters( 
 190     SecTrustRef trustRef
, 
 191     CSSM_TP_ACTION action
, 
 192     CFDataRef actionData
) 
 196     Trust 
*trust 
= Trust::required(trustRef
); 
 197     trust
->action(action
); 
 198     trust
->actionData(actionData
); 
 201         /* bridge to support API functionality for legacy callers */ 
 203         CSSM_APPLE_TP_ACTION_FLAGS actionFlags 
= 0; 
 205                 CSSM_APPLE_TP_ACTION_DATA 
*actionDataPtr 
= (CSSM_APPLE_TP_ACTION_DATA 
*) CFDataGetBytePtr(actionData
); 
 207                         actionFlags 
= actionDataPtr
->ActionFlags
; 
 210         // note that SecTrustOptionFlags == CSSM_APPLE_TP_ACTION_FLAGS; 
 211         // both are sizeof(uint32) and the flag values have identical meanings 
 212     status 
= SecTrustSetOptions(trustRef
, (SecTrustOptionFlags
)actionFlags
); 
 214 #if SECTRUST_DEPRECATION_WARNINGS 
 215         syslog(LOG_ERR
, "WARNING: SecTrustSetParameters was deprecated in 10.7. Use SecTrustSetOptions instead."); 
 224 OSStatus 
SecTrustSetAnchorCertificates(SecTrustRef trust
, CFArrayRef anchorCertificates
) 
 227     Trust::required(trust
)->anchors(anchorCertificates
); 
 233 OSStatus 
SecTrustSetAnchorCertificatesOnly(SecTrustRef trust
, Boolean anchorCertificatesOnly
) 
 236     Trust::AnchorPolicy policy 
= (anchorCertificatesOnly
) ? Trust::useAnchorsOnly 
: Trust::useAnchorsAndBuiltIns
; 
 237     Trust::required(trust
)->anchorPolicy(policy
); 
 242 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA) */ 
 243 OSStatus 
SecTrustSetKeychains(SecTrustRef trust
, CFTypeRef keychainOrArray
) 
 247                 StorageManager::KeychainList keychains
; 
 248         // avoid unnecessary global initializations if an empty array is passed in 
 249         if (!( (keychainOrArray 
!= NULL
) && 
 250                                 (CFGetTypeID(keychainOrArray
) == CFArrayGetTypeID()) && 
 251                                 (CFArrayGetCount((CFArrayRef
)keychainOrArray
) == 0) )) { 
 252                 globals().storageManager
.optionalSearchList(keychainOrArray
, keychains
); 
 254         Trust::required(trust
)->searchLibs(keychains
); 
 257         /* this function is currently unsupported in unified SecTrust */ 
 258     // TODO: pull all certs out of the specified keychains for the evaluation? 
 259 #if SECTRUST_DEPRECATION_WARNINGS 
 260         syslog(LOG_ERR
, "WARNING: SecTrustSetKeychains does nothing in 10.11. Use SecTrustSetAnchorCertificates{Only} to provide anchors."); 
 262         return errSecSuccess
; 
 267 OSStatus 
SecTrustSetVerifyDate(SecTrustRef trust
, CFDateRef verifyDate
) 
 270     Trust::required(trust
)->time(verifyDate
); 
 276 CFAbsoluteTime 
SecTrustGetVerifyTime(SecTrustRef trust
) 
 278         CFAbsoluteTime verifyTime 
= 0; 
 279         OSStatus __secapiresult 
= errSecSuccess
; 
 281                 CFRef
<CFDateRef
> verifyDate 
= Trust::required(trust
)->time(); 
 282                 verifyTime 
= CFDateGetAbsoluteTime(verifyDate
); 
 284         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 285         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 286         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 287         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 295 OSStatus 
SecTrustEvaluate(SecTrustRef trust
, SecTrustResultType 
*resultP
) 
 297         SecTrustResultType trustResult 
= kSecTrustResultInvalid
; 
 298         CFArrayRef exceptions 
= NULL
; 
 299         OSStatus __secapiresult 
= errSecSuccess
; 
 301                 Trust 
*trustObj 
= Trust::required(trust
); 
 302                 trustObj
->evaluate(); 
 303                 trustResult 
= trustObj
->result(); 
 304                 exceptions 
= trustObj
->exceptions(); 
 306         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 307         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 308         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 309         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 311         if (__secapiresult
) { 
 312                 return __secapiresult
; 
 315         /* post-process trust result based on exceptions */ 
 316         if (trustResult 
== kSecTrustResultUnspecified
) { 
 317                 /* If leaf is in exceptions -> proceed, otherwise unspecified. */ 
 318                 if (SecTrustGetExceptionForCertificateAtIndex(trust
, 0)) 
 319                         trustResult 
= kSecTrustResultProceed
; 
 321         else if (trustResult 
== kSecTrustResultRecoverableTrustFailure 
&& exceptions
) { 
 322                 /* If we have exceptions get details and match to exceptions. */ 
 323                 CFArrayRef details 
= SecTrustCopyDetails(trust
); 
 325                         CFIndex pathLength 
= CFArrayGetCount(details
); 
 326                         struct SecTrustCheckExceptionContext context 
= {}; 
 328                         for (ix 
= 0; ix 
< pathLength
; ++ix
) { 
 329                                 CFDictionaryRef detail 
= (CFDictionaryRef
)CFArrayGetValueAtIndex(details
, ix
); 
 330                         //      if ((ix == 0) && CFDictionaryContainsKey(detail, kSecPolicyCheckBlackListedLeaf)) 
 331                         //              trustResult = kSecTrustResultFatalTrustFailure; 
 332                                 context
.exception 
= SecTrustGetExceptionForCertificateAtIndex(trust
, ix
); 
 333                                 CFDictionaryApplyFunction(detail
, SecTrustCheckException
, &context
); 
 334                                 if (context
.exceptionNotFound
) { 
 338                         if (!context
.exceptionNotFound
) 
 339                                 trustResult 
= kSecTrustResultProceed
; 
 344         secdebug("SecTrustEvaluate", "SecTrustEvaluate trust result = %d", (int)trustResult
); 
 346                 *resultP 
= trustResult
; 
 348         return __secapiresult
; 
 353 OSStatus 
SecTrustEvaluateAsync(SecTrustRef trust
, 
 354         dispatch_queue_t queue
, SecTrustCallback result
) 
 357         dispatch_async(queue
, ^{ 
 359                         Trust 
*trustObj 
= Trust::required(trust
); 
 360                         trustObj
->evaluate(); 
 361                         SecTrustResultType trustResult 
= trustObj
->result(); 
 362                         result(trust
, trustResult
); 
 365                         result(trust
, kSecTrustResultInvalid
); 
 373 // Construct the "official" result evidence and return it 
 375 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ 
 376 OSStatus 
SecTrustGetResult( 
 377     SecTrustRef trustRef
, 
 378     SecTrustResultType 
*result
, 
 379         CFArrayRef 
*certChain
, CSSM_TP_APPLE_EVIDENCE_INFO 
**statusChain
) 
 383     Trust 
*trust 
= Trust::required(trustRef
); 
 385         *result 
= trust
->result(); 
 386     if (certChain 
&& statusChain
) 
 387         trust
->buildEvidence(*certChain
, TPEvidenceInfo::overlayVar(*statusChain
)); 
 390         /* bridge to support old functionality */ 
 391 #if SECTRUST_DEPRECATION_WARNINGS 
 392         syslog(LOG_ERR
, "WARNING: SecTrustGetResult has been deprecated since 10.7, and may not return a statusChain in 10.11. Please use SecTrustGetTrustResult instead."); 
 394         SecTrustResultType trustResult
; 
 395         OSStatus status 
= SecTrustGetTrustResult(trustRef
, &trustResult
); 
 397                 *result 
= trustResult
; 
 399         if (certChain 
&& !statusChain
) { 
 400                 /* This is the easy case; caller only wants cert chain and not status chain. */ 
 401                 CFMutableArrayRef certArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 402                 CFIndex idx
, count 
= SecTrustGetCertificateCount(trustRef
); 
 403                 for (idx
=0; idx 
< count
; idx
++) { 
 404                         SecCertificateRef certificate 
= SecTrustGetCertificateAtIndex(trustRef
, idx
); 
 406                                 CFArrayAppendValue(certArray
, certificate
); 
 409                 *certChain 
= certArray
; 
 411         else if (certChain 
&& statusChain
) { 
 413                  * Here is where backward compatibility gets ugly. CSSM_TP_APPLE_EVIDENCE_INFO* is tied to a 
 414                  * Trust object and does not exist in the new unified world. Unfortunately, some clients are 
 415                  * still calling this legacy API and grubbing through the info for StatusBits and StatusCodes. 
 416                  * If they want this info, then we have to do a legacy evaluation to get it. The info struct 
 417                  * goes away once the old-style object does, so we must keep the old-style object alive after 
 418                  * returning from the function. 
 420                  * TODO: keep a dictionary and figure out how to expire entries when no longer needed., 
 421                  * or build the evidence info ourselves: rdar://21005914 
 423                 static CFMutableArrayRef sTrustArray 
= NULL
; 
 425                 // make array of Certificate instances from unified SecCertificateRefs 
 426                 CFMutableArrayRef certArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 427                 CFIndex idx
, count 
= SecTrustGetCertificateCount(trustRef
); 
 428                 for (idx
=0; idx 
< count
; idx
++) { 
 429                         SecCertificateRef certificate 
= SecTrustGetCertificateAtIndex(trustRef
, idx
); 
 431                                 SecCertificateRef itemImplRef 
= SecCertificateCreateItemImplInstance(certificate
); 
 433                                         CFArrayAppendValue(certArray
, itemImplRef
); 
 434                                         CFRelease(itemImplRef
); 
 438                 // make array of Policy instances from unified SecPolicyRefs 
 439                 CFMutableArrayRef policyArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 440                 CFArrayRef policies 
= NULL
; 
 441                 status 
= SecTrustCopyPolicies(trustRef
, &policies
); 
 442                 count 
= (!status 
&& policies
) ? CFArrayGetCount(policies
) : 0; 
 443                 for (idx
=0; idx 
< count
; idx
++) { 
 444                         SecPolicyRef policy 
= (SecPolicyRef
) CFArrayGetValueAtIndex(policies
, idx
); 
 446                                 SecPolicyRef itemImplRef 
= SecPolicyCreateItemImplInstance(policy
); 
 448                                         CFArrayAppendValue(policyArray
, itemImplRef
); 
 449                                         CFRelease(itemImplRef
); 
 453                 // now make a Trust instance and evaluate it 
 455                         Trust 
*trustObj 
= new Trust(certArray
, policyArray
); 
 456                         SecTrustRef trust 
= trustObj
->handle(); 
 458                                 MacOSError::throwMe(errSecTrustNotAvailable
); 
 461                                 sTrustArray 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 463                                         MacOSError::throwMe(errSecAllocate
); 
 466                         // fetch the built cert chain and status chain 
 467                         CFArrayRef itemImplCertArray 
= NULL
; 
 468                         trustObj
->evaluate(); 
 469                         trustObj
->buildEvidence(itemImplCertArray
, TPEvidenceInfo::overlayVar(*statusChain
)); 
 471                         // convert each Certificate in the built chain to a unified SecCertificateRef 
 472                         CFMutableArrayRef outCertChain 
= CFArrayCreateMutable(NULL
, 0, &kCFTypeArrayCallBacks
); 
 473                         CFIndex idx
, count 
= (itemImplCertArray
) ? CFArrayGetCount(itemImplCertArray
) : 0; 
 474                         for (idx
=0; idx 
< count
; idx
++) { 
 475                                 SecCertificateRef inCert 
= (SecCertificateRef
) CFArrayGetValueAtIndex(itemImplCertArray
, idx
); 
 476                                 SecCertificateRef outCert 
= SecCertificateCreateFromItemImplInstance(inCert
); 
 478                                         CFArrayAppendValue(outCertChain
, outCert
); 
 482                         *certChain 
= outCertChain
; 
 483                         if (itemImplCertArray
) { 
 484                                 CFRelease(itemImplCertArray
); 
 486                         CFArrayAppendValue(sTrustArray
, trust
); 
 487                         status 
= errSecSuccess
; 
 489                 catch (const MacOSError 
&err
) { status
=err
.osStatus(); } 
 490                 catch (const CommonError 
&err
) { status
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 491                 catch (const std::bad_alloc 
&) { status
=errSecAllocate
; } 
 492                 catch (...) { status
=errSecInternalComponent
; } 
 495                         CFRelease(policyArray
); 
 497                         CFRelease(certArray
); 
 504 // Retrieve result of trust evaluation only 
 507 OSStatus 
SecTrustGetTrustResult(SecTrustRef trustRef
, 
 508         SecTrustResultType 
*result
) 
 511     Trust 
*trust 
= Trust::required(trustRef
); 
 512     if (result
) *result 
= trust
->result(); 
 518 // Retrieve extended validation trust results 
 520 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA) */ 
 521 OSStatus 
SecTrustCopyExtendedResult(SecTrustRef trust
, CFDictionaryRef 
*result
) 
 525         Trust 
*trustObj 
= Trust::required(trust
); 
 528         trustObj
->extendedResult(*result
); 
 531         /* bridge to support old functionality */ 
 532 #if SECTRUST_DEPRECATION_WARNINGS 
 533     syslog(LOG_ERR
, "WARNING: SecTrustCopyExtendedResult will be deprecated in an upcoming release. Please use SecTrustCopyResult instead."); 
 535         CFDictionaryRef resultDict 
= SecTrustCopyResult(trust
); 
 539         *result 
= resultDict
; 
 540         return errSecSuccess
; 
 545 // Retrieve CSSM-level information for those who want to dig down 
 547 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ 
 548 OSStatus 
SecTrustGetCssmResult(SecTrustRef trust
, CSSM_TP_VERIFY_CONTEXT_RESULT_PTR 
*result
) 
 552     Required(result
) = Trust::required(trust
)->cssmResult(); 
 555         /* this function is unsupported in unified SecTrust */ 
 556 #if SECTRUST_DEPRECATION_WARNINGS 
 557         syslog(LOG_ERR
, "WARNING: SecTrustGetCssmResult has been deprecated since 10.7, and has no functional equivalent in 10.11. Please use SecTrustCopyResult instead."); 
 562         return errSecServiceNotAvailable
; 
 567 static void applyPropertyToCssmResultCode(const void *_key
, const void *_value
, void *context
) { 
 568         CFStringRef key 
= (CFStringRef
)_key
; 
 569         CFStringRef value 
= (CFStringRef
)_value
; 
 570         OSStatus 
*result 
= (OSStatus 
*)context
; 
 571         if (CFGetTypeID(_value
) != CFStringGetTypeID()) { 
 574         if (!CFEqual(CFSTR("value"), key
)) { 
 577         if (CFEqual(CFSTR("Invalid certificate chain linkage."), value
)) { 
 578                 *result 
= CSSMERR_APPLETP_INVALID_ID_LINKAGE
; 
 579         } else if (CFEqual(CFSTR("One or more unsupported critical extensions found."), value
)) { 
 580                 *result 
= CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN
; 
 581         } else if (CFEqual(CFSTR("Root certificate is not trusted."), value
)) { 
 582                 *result 
= CSSMERR_TP_NOT_TRUSTED
; 
 583         } else if (CFEqual(CFSTR("Hostname mismatch."), value
)) { 
 584                 *result 
= CSSMERR_APPLETP_HOSTNAME_MISMATCH
; 
 585         } else if (CFEqual(CFSTR("One or more certificates have expired or are not valid yet."), value
)) { 
 586                 *result 
= CSSMERR_TP_CERT_EXPIRED
; 
 587         } else if (CFEqual(CFSTR("Policy requirements not met."), value
)) { 
 588                 *result 
= CSSMERR_TP_VERIFY_ACTION_FAILED
; 
 594 // Retrieve CSSM_LEVEL TP return code 
 596 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ 
 597 OSStatus 
SecTrustGetCssmResultCode(SecTrustRef trustRef
, OSStatus 
*result
) 
 601                 Trust 
*trust 
= Trust::required(trustRef
); 
 602         if (trust
->result() == kSecTrustResultInvalid
) 
 605                 Required(result
) = trust
->cssmResultCode(); 
 608         /* bridge to support old functionality */ 
 609 #if SECTRUST_DEPRECATION_WARNINGS 
 610     syslog(LOG_ERR
, "WARNING: SecTrustGetCssmResultCode has been deprecated since 10.7, and will be removed in a future release. Please use SecTrustCopyProperties instead."); 
 612         if (!trustRef 
|| !result
) { 
 615         CFArrayRef properties 
= SecTrustCopyProperties(trustRef
); 
 618                 return errSecSuccess
; 
 620         OSStatus cssmResultCode 
= 0; 
 621         CFIndex ix
, count 
= CFArrayGetCount(properties
); 
 622         for (ix 
= 0; ix 
< count
; ++ix
) { 
 623                 CFDictionaryRef property 
= (CFDictionaryRef
) 
 624                         CFArrayGetValueAtIndex(properties
, ix
); 
 625                 CFDictionaryApplyFunction(property
, applyPropertyToCssmResultCode
, &cssmResultCode
); 
 628                 *result 
= cssmResultCode
; 
 631                 CFRelease(properties
); 
 633         return errSecSuccess
; 
 637 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */ 
 638 OSStatus 
SecTrustGetTPHandle(SecTrustRef trust
, CSSM_TP_HANDLE 
*handle
) 
 642                 Required(handle
) = Trust::required(trust
)->getTPHandle(); 
 645         /* this function is unsupported in unified SecTrust */ 
 646 #if SECTRUST_DEPRECATION_WARNINGS 
 647         syslog(LOG_ERR
, "WARNING: SecTrustGetTPHandle has been deprecated since 10.7, and cannot return CSSM objects in 10.11. Please stop using it."); 
 652         return errSecServiceNotAvailable
; 
 657 OSStatus 
SecTrustCopyPolicies(SecTrustRef trust
, CFArrayRef 
*policies
) 
 660                 CFArrayRef currentPolicies 
= Trust::required(trust
)->policies(); 
 661         if (currentPolicies 
!= NULL
) 
 663                 CFRetain(currentPolicies
); 
 666         Required(policies
) = currentPolicies
; 
 672 OSStatus 
SecTrustSetNetworkFetchAllowed(SecTrustRef trust
, Boolean allowFetch
) 
 675         Trust 
*trustObj 
= Trust::required(trust
); 
 676         Trust::NetworkPolicy netPolicy 
= (allowFetch
) ? 
 677                 Trust::useNetworkEnabled 
: Trust::useNetworkDisabled
; 
 678         trustObj
->networkPolicy(netPolicy
); 
 684 OSStatus 
SecTrustGetNetworkFetchAllowed(SecTrustRef trust
, Boolean 
*allowFetch
) 
 687         Boolean allowed 
= false; 
 688         Trust 
*trustObj 
= Trust::required(trust
); 
 689         Trust::NetworkPolicy netPolicy 
= trustObj
->networkPolicy(); 
 690         if (netPolicy 
== Trust::useNetworkDefault
) { 
 691                 // network fetch is enabled by default for SSL only 
 692                 allowed 
= trustObj
->policySpecified(trustObj
->policies(), CSSMOID_APPLE_TP_SSL
); 
 694                 // caller has explicitly set the network policy 
 695                 allowed 
= (netPolicy 
== Trust::useNetworkEnabled
); 
 697         Required(allowFetch
) = allowed
; 
 703 OSStatus 
SecTrustSetOCSPResponse(SecTrustRef trust
, CFTypeRef responseData
) 
 706         Trust::required(trust
)->responses(responseData
); 
 712 OSStatus 
SecTrustCopyCustomAnchorCertificates(SecTrustRef trust
, CFArrayRef 
*anchorCertificates
) 
 715         CFArrayRef customAnchors 
= Trust::required(trust
)->anchors(); 
 716         Required(anchorCertificates
) = (customAnchors
) ? 
 717                 (const CFArrayRef
)CFRetain(customAnchors
) : (const CFArrayRef
)NULL
; 
 723 // Get the user's default anchor certificate set 
 726 OSStatus 
SecTrustCopyAnchorCertificates(CFArrayRef 
*anchorCertificates
) 
 730         return SecTrustSettingsCopyUnrestrictedRoots( 
 731                         true, true, true,               /* all domains */ 
 738 /* We have an iOS-style SecTrustRef, but we need to return a CDSA-based SecKeyRef. 
 740 SecKeyRef 
SecTrustCopyPublicKey(SecTrustRef trust
) 
 742         SecKeyRef pubKey 
= NULL
; 
 743         SecCertificateRef certificate 
= SecTrustGetCertificateAtIndex(trust
, 0); 
 744         (void) SecCertificateCopyPublicKey(certificate
, &pubKey
); 
 749 SecKeyRef 
SecTrustCopyPublicKey(SecTrustRef trust
) 
 751         SecKeyRef pubKey 
= NULL
; 
 752         CFArrayRef certChain 
= NULL
; 
 753         CFArrayRef evidenceChain 
= NULL
; 
 754         CSSM_TP_APPLE_EVIDENCE_INFO 
*statusChain 
= NULL
; 
 755         OSStatus __secapiresult 
= errSecSuccess
; 
 757                 Trust 
*trustObj 
= Trust::required(trust
); 
 758                 if (trustObj
->result() == kSecTrustResultInvalid
) { 
 759                         // Trust hasn't been evaluated; attempt to retrieve public key from leaf. 
 760                         SecCertificateRef cert 
= SecTrustGetCertificateAtIndex(trust
, 0); 
 761                         __secapiresult 
= SecCertificateCopyPublicKey(cert
, &pubKey
); 
 765                         // Otherwise, we must evaluate first. 
 766                         trustObj
->evaluate(); 
 767                         if (trustObj
->result() == kSecTrustResultInvalid
) { 
 768                                 MacOSError::throwMe(errSecTrustNotAvailable
); 
 771                 if (trustObj
->evidence() == nil
) { 
 772                         trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
)); 
 774                 evidenceChain 
= trustObj
->evidence(); 
 776         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 777         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 778         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 779         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 782                 CFRelease(certChain
); 
 785                 if (CFArrayGetCount(evidenceChain
) > 0) { 
 786                         SecCertificateRef cert 
= (SecCertificateRef
) CFArrayGetValueAtIndex(evidenceChain
, 0); 
 787                         __secapiresult 
= SecCertificateCopyPublicKey(cert
, &pubKey
); 
 789                 // do not release evidenceChain, as it is owned by the trust object. 
 797 CFIndex 
SecTrustGetCertificateCount(SecTrustRef trust
) 
 799         CFIndex chainLen 
= 0; 
 800         CFArrayRef certChain 
= NULL
; 
 801         CFArrayRef evidenceChain 
= NULL
; 
 802         CSSM_TP_APPLE_EVIDENCE_INFO 
*statusChain 
= NULL
; 
 803     OSStatus __secapiresult 
= errSecSuccess
; 
 805                 Trust 
*trustObj 
= Trust::required(trust
); 
 806                 if (trustObj
->result() == kSecTrustResultInvalid
) { 
 807                         trustObj
->evaluate(); 
 808                         if (trustObj
->result() == kSecTrustResultInvalid
) 
 809                                 MacOSError::throwMe(errSecTrustNotAvailable
); 
 811                 if (trustObj
->evidence() == nil
) 
 812                         trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
)); 
 813                 evidenceChain 
= trustObj
->evidence(); 
 815         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 816         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 817         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 818         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 821                 CFRelease(certChain
); 
 824                 chainLen 
= CFArrayGetCount(evidenceChain
); // don't release, trust object owns it. 
 832 SecCertificateRef 
SecTrustGetCertificateAtIndex(SecTrustRef trust
, CFIndex ix
) 
 834         SecCertificateRef certificate 
= NULL
; 
 835         CFArrayRef certChain 
= NULL
; 
 836         CFArrayRef evidenceChain 
= NULL
; 
 837         CSSM_TP_APPLE_EVIDENCE_INFO 
*statusChain 
= NULL
; 
 838     OSStatus __secapiresult 
= errSecSuccess
; 
 840                 Trust 
*trustObj 
= Trust::required(trust
); 
 841                 if (trustObj
->result() == kSecTrustResultInvalid
) { 
 842                         // If caller is asking for the leaf, we can return it without 
 843                         // having to evaluate the entire chain. Note that we don't retain 
 844                         // the cert as it's owned by the trust and this is a 'Get' API. 
 846                                 CFArrayRef certs 
= trustObj
->certificates(); 
 847                                 if (certs 
&& (CFArrayGetCount(certs
) > 0)) { 
 848                                         certificate 
= (SecCertificateRef
) CFArrayGetValueAtIndex(certs
, 0); 
 854                         // Otherwise, we must evaluate first. 
 855                         trustObj
->evaluate(); 
 856                         if (trustObj
->result() == kSecTrustResultInvalid
) { 
 857                                 MacOSError::throwMe(errSecTrustNotAvailable
); 
 860                 if (trustObj
->evidence() == nil
) { 
 861                         trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
)); 
 863                 evidenceChain 
= trustObj
->evidence(); 
 865         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 866         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 867         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 868         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 871                 CFRelease(certChain
); 
 874                 if (ix 
< CFArrayGetCount(evidenceChain
)) { 
 875                         certificate 
= (SecCertificateRef
) CFArrayGetValueAtIndex(evidenceChain
, ix
); 
 876                         // note: we do not retain this certificate. The assumption here is 
 877                         // that the certificate is retained by the trust object, so it is 
 878                         // valid unil the trust is released (or until re-evaluated.) 
 879                         // also note: we do not release the evidenceChain, as it is owned 
 880                         // by the trust object. 
 889 static CFStringRef kSecCertificateDetailSHA1Digest 
= CFSTR("SHA1Digest"); 
 890 static CFStringRef kSecCertificateDetailStatusCodes 
= CFSTR("StatusCodes"); 
 893 _AppendStatusCode(CFMutableArrayRef array
, OSStatus statusCode
) 
 897         SInt32 num 
= statusCode
; 
 898         CFNumberRef numRef 
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &num
); 
 901         CFArrayAppendValue(array
, numRef
); 
 907 CFArrayRef 
SecTrustCopyDetails(SecTrustRef trust
) 
 909         // This function returns an array of dictionaries, one per certificate, 
 910         // holding status info for each certificate in the evaluated chain. 
 912         CFIndex count
, chainLen 
= 0; 
 913         CFArrayRef certChain 
= NULL
; 
 914         CFMutableArrayRef details 
= NULL
; 
 915         CSSM_TP_APPLE_EVIDENCE_INFO 
*statusChain 
= NULL
; 
 916     OSStatus __secapiresult 
= errSecSuccess
; 
 918                 Trust 
*trustObj 
= Trust::required(trust
); 
 919                 if (trustObj
->result() == kSecTrustResultInvalid
) { 
 920                         trustObj
->evaluate(); 
 921                         if (trustObj
->result() == kSecTrustResultInvalid
) 
 922                                 MacOSError::throwMe(errSecTrustNotAvailable
); 
 924                 trustObj
->buildEvidence(certChain
, TPEvidenceInfo::overlayVar(statusChain
)); 
 926         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 927         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 928         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 929         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 932                 chainLen 
= CFArrayGetCount(certChain
); 
 933                 CFRelease(certChain
); 
 936                 details 
= CFArrayCreateMutable(NULL
, chainLen
, &kCFTypeArrayCallBacks
); 
 937                 for (count 
= 0; count 
< chainLen
; count
++) { 
 938                         CFMutableDictionaryRef certDict 
= CFDictionaryCreateMutable(kCFAllocatorDefault
, 
 939                                 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
); 
 940                         CFMutableArrayRef statusCodes 
= CFArrayCreateMutable(kCFAllocatorDefault
, 
 941                                 0, &kCFTypeArrayCallBacks
); 
 942                         CSSM_TP_APPLE_EVIDENCE_INFO 
*evInfo 
= &statusChain
[count
]; 
 943                         CSSM_TP_APPLE_CERT_STATUS statBits 
= evInfo
->StatusBits
; 
 945                         // translate status bits 
 946                         if (statBits 
& CSSM_CERT_STATUS_EXPIRED
) 
 947                                 _AppendStatusCode(statusCodes
, errSecCertificateExpired
); 
 948                         if (statBits 
& CSSM_CERT_STATUS_NOT_VALID_YET
) 
 949                                 _AppendStatusCode(statusCodes
, errSecCertificateNotValidYet
); 
 950                         if (statBits 
& CSSM_CERT_STATUS_TRUST_SETTINGS_DENY
) 
 951                                 _AppendStatusCode(statusCodes
, errSecTrustSettingDeny
); 
 953                         // translate status codes 
 955                         for (i 
= 0; i 
< evInfo
->NumStatusCodes
; i
++) { 
 956                                 CSSM_RETURN scode 
= evInfo
->StatusCodes
[i
]; 
 957                                 _AppendStatusCode(statusCodes
, (OSStatus
)scode
); 
 960                         CFDictionarySetValue(certDict
, kSecCertificateDetailStatusCodes
, statusCodes
); 
 961                         CFRelease(statusCodes
); 
 962                         CFArrayAppendValue(details
, certDict
); 
 971 static CFDictionaryRef 
SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust
, CFIndex ix
) 
 973         CFArrayRef exceptions 
= NULL
; 
 974     OSStatus __secapiresult 
= errSecSuccess
; 
 976                 exceptions 
= Trust::required(trust
)->exceptions(); 
 978         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
 979         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
 980         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
 981         catch (...) { __secapiresult
=errSecInternalComponent
; } 
 983         if (!exceptions 
|| ix 
>= CFArrayGetCount(exceptions
)) 
 985         CFDictionaryRef exception 
= (CFDictionaryRef
)CFArrayGetValueAtIndex(exceptions
, ix
); 
 986         if (CFGetTypeID(exception
) != CFDictionaryGetTypeID()) 
 989         SecCertificateRef certificate 
= SecTrustGetCertificateAtIndex(trust
, ix
); 
 993         /* If the exception contains the current certificate's sha1Digest in the 
 994            kSecCertificateDetailSHA1Digest key then we use it otherwise we ignore it. */ 
 995         CFDataRef sha1Digest 
= SecCertificateGetSHA1Digest(certificate
); 
 996         CFTypeRef digestValue 
= CFDictionaryGetValue(exception
, kSecCertificateDetailSHA1Digest
); 
 997         if (!digestValue 
|| !CFEqual(sha1Digest
, digestValue
)) 
1005 static void SecTrustCheckException(const void *key
, const void *value
, void *context
) 
1007         struct SecTrustCheckExceptionContext 
*cec 
= (struct SecTrustCheckExceptionContext 
*)context
; 
1008         if (cec
->exception
) { 
1009                 CFTypeRef exceptionValue 
= CFDictionaryGetValue(cec
->exception
, key
); 
1010                 if (!exceptionValue 
|| !CFEqual(value
, exceptionValue
)) { 
1011                         cec
->exceptionNotFound 
= true; 
1014                 cec
->exceptionNotFound 
= true; 
1021 CFDataRef 
SecTrustCopyExceptions(SecTrustRef trust
) 
1023         CFArrayRef details 
= SecTrustCopyDetails(trust
); 
1024         CFIndex pathLength 
= details 
? CFArrayGetCount(details
) : 0; 
1025         CFMutableArrayRef exceptions 
= CFArrayCreateMutable(kCFAllocatorDefault
, 
1026                         pathLength
, &kCFTypeArrayCallBacks
); 
1028         for (ix 
= 0; ix 
< pathLength
; ++ix
) { 
1029                 CFDictionaryRef detail 
= (CFDictionaryRef
)CFArrayGetValueAtIndex(details
, ix
); 
1030                 CFIndex detailCount 
= CFDictionaryGetCount(detail
); 
1031                 CFMutableDictionaryRef exception
; 
1032                 if (ix 
== 0 || detailCount 
> 0) { 
1033                         exception 
= CFDictionaryCreateMutableCopy(kCFAllocatorDefault
, 
1034                                 detailCount 
+ 1, detail
); 
1035                         SecCertificateRef certificate 
= SecTrustGetCertificateAtIndex(trust
, ix
); 
1036                         CFDataRef digest 
= SecCertificateGetSHA1Digest(certificate
); 
1038                                 CFDictionaryAddValue(exception
, kSecCertificateDetailSHA1Digest
, digest
); 
1041                         /* Add empty exception dictionaries for non leaf certs which have no exceptions 
1044                         exception 
= (CFMutableDictionaryRef
)CFDictionaryCreate(kCFAllocatorDefault
, 
1046                                 &kCFTypeDictionaryKeyCallBacks
, 
1047                                 &kCFTypeDictionaryValueCallBacks
); 
1049                 CFArrayAppendValue(exceptions
, exception
); 
1050                 CFReleaseNull(exception
); 
1052         CFReleaseSafe(details
); 
1054         /* Remove any trailing empty dictionaries to save even more space (we skip the leaf 
1055            since it will never be empty). */ 
1056         for (ix 
= pathLength
; ix
-- > 1;) { 
1057                 CFDictionaryRef exception 
= (CFDictionaryRef
)CFArrayGetValueAtIndex(exceptions
, ix
); 
1058                 if (CFDictionaryGetCount(exception
) == 0) { 
1059                         CFArrayRemoveValueAtIndex(exceptions
, ix
); 
1065         CFDataRef encodedExceptions 
= CFPropertyListCreateData(kCFAllocatorDefault
, 
1066                         exceptions
, kCFPropertyListBinaryFormat_v1_0
, 0, NULL
); 
1067         CFRelease(exceptions
); 
1069         return encodedExceptions
; 
1075 bool SecTrustSetExceptions(SecTrustRef trust
, CFDataRef encodedExceptions
) 
1077         CFArrayRef exceptions
; 
1078         exceptions 
= (CFArrayRef
)CFPropertyListCreateWithData(kCFAllocatorDefault
, 
1079                 encodedExceptions
, kCFPropertyListImmutable
, NULL
, NULL
); 
1080         if (exceptions 
&& CFGetTypeID(exceptions
) != CFArrayGetTypeID()) { 
1081                 CFRelease(exceptions
); 
1085         OSStatus __secapiresult 
= errSecSuccess
; 
1087                 Trust::required(trust
)->exceptions(exceptions
); 
1089         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1090         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1091         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1092         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1094         /* If there is a valid exception entry for our current leaf we're golden. */ 
1095         if (SecTrustGetExceptionForCertificateAtIndex(trust
, 0)) 
1098         /* The passed in exceptions didn't match our current leaf, so we discard it. */ 
1100                 Trust::required(trust
)->exceptions(NULL
); 
1101                 __secapiresult 
= errSecSuccess
; 
1103         catch (const MacOSError 
&err
) { __secapiresult
=err
.osStatus(); } 
1104         catch (const CommonError 
&err
) { __secapiresult
=SecKeychainErrFromOSStatus(err
.osStatus()); } 
1105         catch (const std::bad_alloc 
&) { __secapiresult
=errSecAllocate
; } 
1106         catch (...) { __secapiresult
=errSecInternalComponent
; } 
1115 SecTrustCopyResult(SecTrustRef trust
) 
1117         CFDictionaryRef result 
= NULL
; 
1119                 result 
= Trust::required(trust
)->results(); 
1120                 // merge details into result 
1121                 CFArrayRef details 
= SecTrustCopyDetails(trust
); 
1123                         CFDictionarySetValue((CFMutableDictionaryRef
)result
, 
1124                                 kSecTrustResultDetails
, details
); 
1141 SecTrustCopyProperties(SecTrustRef trust
) 
1143         /* can't use SECAPI macros, since this function does not return OSStatus */ 
1144         CFArrayRef result 
= NULL
; 
1146                 result 
= Trust::required(trust
)->properties(); 
1158 /* deprecated in 10.5 */ 
1159 OSStatus 
SecTrustGetCSSMAnchorCertificates(const CSSM_DATA 
**cssmAnchors
, 
1160         uint32 
*cssmAnchorCount
) 
1165         Trust::gStore().getCssmRootCertificates(certs
); 
1166         Required(cssmAnchors
) = certs
.blobCerts(); 
1167         Required(cssmAnchorCount
) = certs
.count(); 
1170         /* this function is unsupported in unified SecTrust */ 
1171 #if SECTRUST_DEPRECATION_WARNINGS 
1172         syslog(LOG_ERR
, "WARNING: SecTrustGetCSSMAnchorCertificates has been deprecated since 10.5, and cannot return CSSM objects in 10.11. Please stop using it."); 
1175                 *cssmAnchors 
= NULL
; 
1177         if (cssmAnchorCount
) { 
1178                 *cssmAnchorCount 
= 0; 
1180         return errSecServiceNotAvailable
; 
1186 // Get and set user trust settings. Deprecated in 10.5. 
1187 // User Trust getter, deprecated, works as it always has. 
1189 OSStatus 
SecTrustGetUserTrust(SecCertificateRef certificate
, 
1190     SecPolicyRef policy
, SecTrustUserSetting 
*trustSetting
) 
1194         StorageManager::KeychainList searchList
; 
1195         globals().storageManager
.getSearchList(searchList
); 
1196         Required(trustSetting
) = Trust::gStore().find( 
1197                 Certificate::required(certificate
), 
1198                 Policy::required(policy
), 
1202         /* this function is unsupported in unified SecTrust */ 
1203 #if SECTRUST_DEPRECATION_WARNINGS 
1204         syslog(LOG_ERR
, "WARNING: SecTrustGetUserTrust has been deprecated since 10.5, and does nothing in 10.11. Please stop using it."); 
1206         return errSecServiceNotAvailable
; 
1211 // The public setter, also deprecated; it maps to the appropriate 
1212 // Trust Settings call if possible, else throws errSecUnimplemented. 
1214 OSStatus 
SecTrustSetUserTrust(SecCertificateRef certificate
, 
1215     SecPolicyRef policy
, SecTrustUserSetting trustSetting
) 
1218         SecTrustSettingsResult tsResult 
= kSecTrustSettingsResultInvalid
; 
1222         Policy::required(policy
); 
1223         switch(trustSetting
) { 
1224                 case kSecTrustResultProceed
: 
1225                         /* different SecTrustSettingsResult depending in root-ness */ 
1226                         ortn 
= SecCertificateIsSelfSigned(certificate
, &isRoot
); 
1231                                 tsResult 
= kSecTrustSettingsResultTrustRoot
; 
1234                                 tsResult 
= kSecTrustSettingsResultTrustAsRoot
; 
1237                 case kSecTrustResultDeny
: 
1238                         tsResult 
= kSecTrustSettingsResultDeny
; 
1241                         return errSecUnimplemented
; 
1244         /* make a usage constraints dictionary */ 
1245         CFRef
<CFMutableDictionaryRef
> usageDict(CFDictionaryCreateMutable(NULL
, 
1246                 0, &kCFTypeDictionaryKeyCallBacks
, &kCFTypeDictionaryValueCallBacks
)); 
1247         CFDictionaryAddValue(usageDict
, kSecTrustSettingsPolicy
, policy
); 
1248         if(tsResult 
!= kSecTrustSettingsResultTrustRoot
) { 
1249                 /* skip if we're specifying the default */ 
1250                 SInt32 result 
= tsResult
; 
1251                 CFNumberRef cfNum 
= CFNumberCreate(NULL
, kCFNumberSInt32Type
, &result
); 
1252                 CFDictionarySetValue(usageDict
, kSecTrustSettingsResult
, cfNum
); 
1255         return SecTrustSettingsSetTrustSettings(certificate
, kSecTrustSettingsDomainUser
, 
1258         /* this function is unsupported in unified SecTrust */ 
1259 #if SECTRUST_DEPRECATION_WARNINGS 
1260         syslog(LOG_ERR
, "WARNING: SecTrustSetUserTrust has been deprecated since 10.5, and does nothing in 10.11. Please stop using it."); 
1262         return errSecServiceNotAvailable
; 
1267 // This one is the now-private version of what SecTrustSetUserTrust() used to 
1268 // be. The public API can no longer manipulate User Trust settings, only 
1271 OSStatus 
SecTrustSetUserTrustLegacy(SecCertificateRef certificate
, 
1272     SecPolicyRef policy
, SecTrustUserSetting trustSetting
) 
1276         switch (trustSetting
) { 
1277     case kSecTrustResultProceed
: 
1278     case kSecTrustResultConfirm
: 
1279     case kSecTrustResultDeny
: 
1280     case kSecTrustResultUnspecified
: 
1283                 MacOSError::throwMe(errSecInvalidTrustSetting
); 
1285         Trust::gStore().assign( 
1286                 Certificate::required(certificate
), 
1287                 Policy::required(policy
), 
1291         /* this function is unsupported in unified SecTrust */ 
1292 #if SECTRUST_DEPRECATION_WARNINGS 
1293         syslog(LOG_ERR
, "WARNING: SecTrustSetUserTrustLegacy does nothing in 10.11. Please stop using it."); 
1295         return errSecServiceNotAvailable
;