]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/lib/SecTrust.cpp
Security-57740.51.3.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / lib / SecTrust.cpp
index 8feae2cc675cad1b0db35bd5239b315d85ed7a7d..83984109f5171e93d1841cfe7465a11f82b7f834 100644 (file)
@@ -27,7 +27,6 @@
 #include "SecBase.h"
 #include "SecBridge.h"
 #include "SecInternal.h"
 #include "SecBase.h"
 #include "SecBridge.h"
 #include "SecInternal.h"
-#include "SecInternalP.h"
 #include "SecTrustSettings.h"
 #include "SecTrustSettingsPriv.h"
 #include "SecCertificatePriv.h"
 #include "SecTrustSettings.h"
 #include "SecTrustSettingsPriv.h"
 #include "SecCertificatePriv.h"
 #include <syslog.h>
 
 // forward declarations
 #include <syslog.h>
 
 // forward declarations
-#if !SECTRUST_OSX
-CFArrayRef SecTrustCopyDetails(SecTrustRef trust);
-static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust, CFIndex ix);
-static void SecTrustCheckException(const void *key, const void *value, void *context);
-#else
 CFArrayRef SecTrustCopyInputCertificates(SecTrustRef trust);
 CFArrayRef SecTrustCopyInputAnchors(SecTrustRef trust);
 CFArrayRef SecTrustCopyConstructedChain(SecTrustRef trust);
 static CSSM_TP_APPLE_EVIDENCE_INFO * SecTrustGetEvidenceInfo(SecTrustRef trust);
 CFArrayRef SecTrustCopyInputCertificates(SecTrustRef trust);
 CFArrayRef SecTrustCopyInputAnchors(SecTrustRef trust);
 CFArrayRef SecTrustCopyConstructedChain(SecTrustRef trust);
 static CSSM_TP_APPLE_EVIDENCE_INFO * SecTrustGetEvidenceInfo(SecTrustRef trust);
-#endif
 
 typedef struct SecTrustCheckExceptionContext {
        CFDictionaryRef exception;
 
 typedef struct SecTrustCheckExceptionContext {
        CFDictionaryRef exception;
@@ -74,7 +67,6 @@ struct resultmap_entry_s {
 };
 typedef struct resultmap_entry_s resultmap_entry_t;
 
 };
 typedef struct resultmap_entry_s resultmap_entry_t;
 
-#if SECTRUST_OSX
 const resultmap_entry_t cssmresultmap[] = {
     { CFSTR("SSLHostname"), CSSMERR_APPLETP_HOSTNAME_MISMATCH },
     { CFSTR("email"), CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND },
 const resultmap_entry_t cssmresultmap[] = {
     { CFSTR("SSLHostname"), CSSMERR_APPLETP_HOSTNAME_MISMATCH },
     { CFSTR("email"), CSSMERR_APPLETP_SMIME_EMAIL_ADDRS_NOT_FOUND },
@@ -103,12 +95,13 @@ const resultmap_entry_t cssmresultmap[] = {
     { CFSTR("WeakRoot"), CSSMERR_TP_INVALID_CERTIFICATE },
     { CFSTR("KeySize"), CSSMERR_CSP_UNSUPPORTED_KEY_SIZE },
     { CFSTR("SignatureHashAlgorithms"), CSSMERR_CSP_ALGID_MISMATCH },
     { CFSTR("WeakRoot"), CSSMERR_TP_INVALID_CERTIFICATE },
     { CFSTR("KeySize"), CSSMERR_CSP_UNSUPPORTED_KEY_SIZE },
     { CFSTR("SignatureHashAlgorithms"), CSSMERR_CSP_ALGID_MISMATCH },
+    { CFSTR("SystemTrustedWeakHash"), CSSMERR_CSP_INVALID_DIGEST_ALGORITHM },
     { CFSTR("CriticalExtensions"), CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN },
     { CFSTR("ChainLength"), CSSMERR_APPLETP_PATH_LEN_CONSTRAINT },
     { CFSTR("BasicCertificateProcessing"), CSSMERR_TP_INVALID_CERTIFICATE },
     { CFSTR("ExtendedValidation"), CSSMERR_TP_NOT_TRUSTED },
     { CFSTR("Revocation"), CSSMERR_TP_CERT_REVOKED },
     { CFSTR("CriticalExtensions"), CSSMERR_APPLETP_UNKNOWN_CRITICAL_EXTEN },
     { CFSTR("ChainLength"), CSSMERR_APPLETP_PATH_LEN_CONSTRAINT },
     { CFSTR("BasicCertificateProcessing"), CSSMERR_TP_INVALID_CERTIFICATE },
     { CFSTR("ExtendedValidation"), CSSMERR_TP_NOT_TRUSTED },
     { CFSTR("Revocation"), CSSMERR_TP_CERT_REVOKED },
-    { CFSTR("RevocationResponseRequired"), CSSMERR_TP_VERIFY_ACTION_FAILED },
+    { CFSTR("RevocationResponseRequired"), CSSMERR_APPLETP_INCOMPLETE_REVOCATION_CHECK },
     { CFSTR("CertificateTransparency"), CSSMERR_TP_NOT_TRUSTED },
     { CFSTR("BlackListedLeaf"), CSSMERR_TP_CERT_REVOKED },
     { CFSTR("GrayListedLeaf"), CSSMERR_TP_NOT_TRUSTED },
     { CFSTR("CertificateTransparency"), CSSMERR_TP_NOT_TRUSTED },
     { CFSTR("BlackListedLeaf"), CSSMERR_TP_CERT_REVOKED },
     { CFSTR("GrayListedLeaf"), CSSMERR_TP_NOT_TRUSTED },
@@ -126,49 +119,11 @@ const resultmap_entry_t cssmresultmap[] = {
 //  { CFSTR("AnchorAppleTestRootsOnProduction"),  },
 //  { CFSTR("NoNetworkAccess"),  },
 };
 //  { CFSTR("AnchorAppleTestRootsOnProduction"),  },
 //  { CFSTR("NoNetworkAccess"),  },
 };
-#endif
 
 
-//
-// CF boilerplate
-//
-#if !SECTRUST_OSX
-CFTypeID SecTrustGetTypeID(void)
-{
-       BEGIN_SECAPI
-
-       return gTypes().Trust.typeID;
-
-       END_SECAPI1(_kCFRuntimeNotATypeID)
-}
-#endif
 
 //
 // Sec* API bridge functions
 //
 
 //
 // Sec* API bridge functions
 //
-#if !SECTRUST_OSX
-OSStatus SecTrustCreateWithCertificates(
-       CFTypeRef certificates,
-       CFTypeRef policies,
-       SecTrustRef *trustRef)
-{
-       BEGIN_SECAPI
-       Required(trustRef);
-       *trustRef = (new Trust(certificates, policies))->handle();
-       END_SECAPI
-}
-#endif
-
-#if !SECTRUST_OSX
-OSStatus
-SecTrustSetPolicies(SecTrustRef trustRef, CFTypeRef policies)
-{
-       BEGIN_SECAPI
-       Trust::required(trustRef)->policies(policies);
-       END_SECAPI
-}
-#endif
-
-#if SECTRUST_OSX
 typedef struct {
        SecTrustOptionFlags flags;
        CFIndex certIX;
 typedef struct {
        SecTrustOptionFlags flags;
        CFIndex certIX;
@@ -177,10 +132,6 @@ typedef struct {
        CFDictionaryRef oldException;
 } SecExceptionFilterContext;
 
        CFDictionaryRef oldException;
 } SecExceptionFilterContext;
 
-#if 0
-//%%%FIXME SecCFWrappers produces some conflicting definitions on OSX
-#include <utilities/SecCFWrappers.h>
-#else
 // inline function from SecCFWrappers.h
 static inline char *CFStringToCString(CFStringRef inStr)
 {
 // inline function from SecCFWrappers.h
 static inline char *CFStringToCString(CFStringRef inStr)
 {
@@ -198,7 +149,6 @@ static inline char *CFStringToCString(CFStringRef inStr)
     CFRelease(inStr);
     return buffer;
 }
     CFRelease(inStr);
     return buffer;
 }
-#endif
 
 static void
 filter_exception(const void *key, const void *value, void *context)
 
 static void
 filter_exception(const void *key, const void *value, void *context)
@@ -271,27 +221,10 @@ filter_exception(const void *key, const void *value, void *context)
        }
 }
 
        }
 }
 
-#endif
-
 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
 OSStatus
 SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
 {
 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_7, __IPHONE_NA) */
 OSStatus
 SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-       CSSM_APPLE_TP_ACTION_DATA actionData = {
-               CSSM_APPLE_TP_ACTION_VERSION,
-               (CSSM_APPLE_TP_ACTION_FLAGS)options
-       };
-       Trust *trust = Trust::required(trustRef);
-       CFDataRef actionDataRef = CFDataCreate(NULL,
-               (const UInt8 *)&actionData,
-               (CFIndex)sizeof(CSSM_APPLE_TP_ACTION_DATA));
-       trust->action(CSSM_TP_ACTION_DEFAULT);
-       trust->actionData(actionDataRef);
-       if (actionDataRef) CFRelease(actionDataRef);
-       END_SECAPI
-#else
        /* bridge to support API functionality for legacy callers */
        OSStatus status = errSecSuccess;
        CFDataRef encodedExceptions = SecTrustCopyExceptions(trustRef);
        /* bridge to support API functionality for legacy callers */
        OSStatus status = errSecSuccess;
        CFDataRef encodedExceptions = SecTrustCopyExceptions(trustRef);
@@ -402,8 +335,6 @@ SecTrustSetOptions(SecTrustRef trustRef, SecTrustOptionFlags options)
 #endif
 
        return status;
 #endif
 
        return status;
-
-#endif
 }
 
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 }
 
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
@@ -412,13 +343,6 @@ OSStatus SecTrustSetParameters(
     CSSM_TP_ACTION action,
     CFDataRef actionData)
 {
     CSSM_TP_ACTION action,
     CFDataRef actionData)
 {
-#if !SECTRUST_OSX
-    BEGIN_SECAPI
-    Trust *trust = Trust::required(trustRef);
-    trust->action(action);
-    trust->actionData(actionData);
-    END_SECAPI
-#else
        /* bridge to support API functionality for legacy callers */
        OSStatus status;
        CSSM_APPLE_TP_ACTION_FLAGS actionFlags = 0;
        /* bridge to support API functionality for legacy callers */
        OSStatus status;
        CSSM_APPLE_TP_ACTION_FLAGS actionFlags = 0;
@@ -437,158 +361,18 @@ OSStatus SecTrustSetParameters(
 #endif
 
        return status;
 #endif
 
        return status;
-
-#endif
 }
 
 }
 
-#if !SECTRUST_OSX
-OSStatus SecTrustSetAnchorCertificates(SecTrustRef trust, CFArrayRef anchorCertificates)
-{
-    BEGIN_SECAPI
-    Trust::required(trust)->anchors(anchorCertificates);
-    END_SECAPI
-}
-#endif
-
-#if !SECTRUST_OSX
-OSStatus SecTrustSetAnchorCertificatesOnly(SecTrustRef trust, Boolean anchorCertificatesOnly)
-{
-    BEGIN_SECAPI
-    Trust::AnchorPolicy policy = (anchorCertificatesOnly) ? Trust::useAnchorsOnly : Trust::useAnchorsAndBuiltIns;
-    Trust::required(trust)->anchorPolicy(policy);
-    END_SECAPI
-}
-#endif
-
 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA) */
 OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
 {
 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_3, __IPHONE_NA) */
 OSStatus SecTrustSetKeychains(SecTrustRef trust, CFTypeRef keychainOrArray)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-               StorageManager::KeychainList keychains;
-       // avoid unnecessary global initializations if an empty array is passed in
-       if (!( (keychainOrArray != NULL) &&
-                               (CFGetTypeID(keychainOrArray) == CFArrayGetTypeID()) &&
-                               (CFArrayGetCount((CFArrayRef)keychainOrArray) == 0) )) {
-               globals().storageManager.optionalSearchList(keychainOrArray, keychains);
-       }
-       Trust::required(trust)->searchLibs(keychains);
-       END_SECAPI
-#else
        /* this function is currently unsupported in unified SecTrust */
     // TODO: pull all certs out of the specified keychains for the evaluation?
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustSetKeychains does nothing in 10.11. Use SecTrustSetAnchorCertificates{Only} to provide anchors.");
 #endif
        return errSecSuccess;
        /* this function is currently unsupported in unified SecTrust */
     // TODO: pull all certs out of the specified keychains for the evaluation?
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustSetKeychains does nothing in 10.11. Use SecTrustSetAnchorCertificates{Only} to provide anchors.");
 #endif
        return errSecSuccess;
-#endif
-}
-
-#if !SECTRUST_OSX
-OSStatus SecTrustSetVerifyDate(SecTrustRef trust, CFDateRef verifyDate)
-{
-    BEGIN_SECAPI
-    Trust::required(trust)->time(verifyDate);
-    END_SECAPI
-}
-#endif
-
-#if !SECTRUST_OSX
-CFAbsoluteTime SecTrustGetVerifyTime(SecTrustRef trust)
-{
-       CFAbsoluteTime verifyTime = 0;
-       OSStatus __secapiresult = errSecSuccess;
-       try {
-               CFRef<CFDateRef> verifyDate = Trust::required(trust)->time();
-               verifyTime = CFDateGetAbsoluteTime(verifyDate);
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-       return verifyTime;
 }
 }
-#endif
-
-
-
-#if !SECTRUST_OSX
-OSStatus SecTrustEvaluate(SecTrustRef trust, SecTrustResultType *resultP)
-{
-       SecTrustResultType trustResult = kSecTrustResultInvalid;
-       CFArrayRef exceptions = NULL;
-       OSStatus __secapiresult = errSecSuccess;
-       try {
-               Trust *trustObj = Trust::required(trust);
-               trustObj->evaluate();
-               trustResult = trustObj->result();
-               exceptions = trustObj->exceptions();
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       if (__secapiresult) {
-               return __secapiresult;
-       }
-
-       /* post-process trust result based on exceptions */
-       if (trustResult == kSecTrustResultUnspecified) {
-               /* If leaf is in exceptions -> proceed, otherwise unspecified. */
-               if (SecTrustGetExceptionForCertificateAtIndex(trust, 0))
-                       trustResult = kSecTrustResultProceed;
-       }
-       else if (trustResult == kSecTrustResultRecoverableTrustFailure && exceptions) {
-               /* If we have exceptions get details and match to exceptions. */
-               CFArrayRef details = SecTrustCopyDetails(trust);
-               if (details) {
-                       CFIndex pathLength = CFArrayGetCount(details);
-                       struct SecTrustCheckExceptionContext context = {};
-                       CFIndex ix;
-                       for (ix = 0; ix < pathLength; ++ix) {
-                               CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
-                       //      if ((ix == 0) && CFDictionaryContainsKey(detail, kSecPolicyCheckBlackListedLeaf))
-                       //              trustResult = kSecTrustResultFatalTrustFailure;
-                               context.exception = SecTrustGetExceptionForCertificateAtIndex(trust, ix);
-                               CFDictionaryApplyFunction(detail, SecTrustCheckException, &context);
-                               if (context.exceptionNotFound) {
-                                       break;
-                               }
-                       }
-                       if (!context.exceptionNotFound)
-                               trustResult = kSecTrustResultProceed;
-               }
-       }
-
-
-       secnotice("SecTrustEvaluate", "SecTrustEvaluate trust result = %d", (int)trustResult);
-       if (resultP) {
-               *resultP = trustResult;
-       }
-       return __secapiresult;
-}
-#endif
-
-#if !SECTRUST_OSX
-OSStatus SecTrustEvaluateAsync(SecTrustRef trust,
-       dispatch_queue_t queue, SecTrustCallback result)
-{
-       BEGIN_SECAPI
-       dispatch_async(queue, ^{
-               try {
-                       Trust *trustObj = Trust::required(trust);
-                       trustObj->evaluate();
-                       SecTrustResultType trustResult = trustObj->result();
-                       result(trust, trustResult);
-               }
-               catch (...) {
-                       result(trust, kSecTrustResultInvalid);
-               };
-       });
-       END_SECAPI
-}
-#endif
 
 //
 // Construct the "official" result evidence and return it
 
 //
 // Construct the "official" result evidence and return it
@@ -599,15 +383,6 @@ OSStatus SecTrustGetResult(
     SecTrustResultType *result,
        CFArrayRef *certChain, CSSM_TP_APPLE_EVIDENCE_INFO **statusChain)
 {
     SecTrustResultType *result,
        CFArrayRef *certChain, CSSM_TP_APPLE_EVIDENCE_INFO **statusChain)
 {
-#if !SECTRUST_OSX
-    BEGIN_SECAPI
-    Trust *trust = Trust::required(trustRef);
-    if (result)
-        *result = trust->result();
-    if (certChain && statusChain)
-        trust->buildEvidence(*certChain, TPEvidenceInfo::overlayVar(*statusChain));
-    END_SECAPI
-#else
        /* bridge to support old functionality */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetResult has been deprecated since 10.7. Please use SecTrustGetTrustResult instead.");
        /* bridge to support old functionality */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetResult has been deprecated since 10.7. Please use SecTrustGetTrustResult instead.");
@@ -627,22 +402,7 @@ OSStatus SecTrustGetResult(
         *statusChain = SecTrustGetEvidenceInfo(trustRef);
        }
        return status;
         *statusChain = SecTrustGetEvidenceInfo(trustRef);
        }
        return status;
-#endif
-}
-
-//
-// Retrieve result of trust evaluation only
-//
-#if !SECTRUST_OSX
-OSStatus SecTrustGetTrustResult(SecTrustRef trustRef,
-       SecTrustResultType *result)
-{
-    BEGIN_SECAPI
-    Trust *trust = Trust::required(trustRef);
-    if (result) *result = trust->result();
-    END_SECAPI
 }
 }
-#endif
 
 //
 // Retrieve extended validation trust results
 
 //
 // Retrieve extended validation trust results
@@ -650,25 +410,17 @@ OSStatus SecTrustGetTrustResult(SecTrustRef trustRef,
 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA) */
 OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result)
 {
 /* OS X only: __OSX_AVAILABLE_STARTING(__MAC_10_5, __IPHONE_NA) */
 OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result)
 {
-#if !SECTRUST_OSX
-    BEGIN_SECAPI
-       Trust *trustObj = Trust::required(trust);
-       if (result == nil)
-               return errSecParam;
-       trustObj->extendedResult(*result);
-    END_SECAPI
-#else
        /* bridge to support old functionality */
 #if SECTRUST_DEPRECATION_WARNINGS
     syslog(LOG_ERR, "WARNING: SecTrustCopyExtendedResult will be deprecated in an upcoming release. Please use SecTrustCopyResult instead.");
 #endif
        CFDictionaryRef resultDict = SecTrustCopyResult(trust);
        if (result == nil) {
        /* bridge to support old functionality */
 #if SECTRUST_DEPRECATION_WARNINGS
     syslog(LOG_ERR, "WARNING: SecTrustCopyExtendedResult will be deprecated in an upcoming release. Please use SecTrustCopyResult instead.");
 #endif
        CFDictionaryRef resultDict = SecTrustCopyResult(trust);
        if (result == nil) {
+        CFReleaseNull(resultDict);
                return errSecParam;
        }
        *result = resultDict;
        return errSecSuccess;
                return errSecParam;
        }
        *result = resultDict;
        return errSecSuccess;
-#endif
 }
 
 //
 }
 
 //
@@ -677,11 +429,6 @@ OSStatus SecTrustCopyExtendedResult(SecTrustRef trust, CFDictionaryRef *result)
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 OSStatus SecTrustGetCssmResult(SecTrustRef trust, CSSM_TP_VERIFY_CONTEXT_RESULT_PTR *result)
 {
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 OSStatus SecTrustGetCssmResult(SecTrustRef trust, CSSM_TP_VERIFY_CONTEXT_RESULT_PTR *result)
 {
-#if !SECTRUST_OSX
-    BEGIN_SECAPI
-    Required(result) = Trust::required(trust)->cssmResult();
-    END_SECAPI
-#else
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetCssmResult has been deprecated since 10.7, and has no functional equivalent in 10.11. Please use SecTrustCopyResult instead.");
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetCssmResult has been deprecated since 10.7, and has no functional equivalent in 10.11. Please use SecTrustCopyResult instead.");
@@ -690,10 +437,8 @@ OSStatus SecTrustGetCssmResult(SecTrustRef trust, CSSM_TP_VERIFY_CONTEXT_RESULT_
                *result = NULL;
        }
        return errSecServiceNotAvailable;
                *result = NULL;
        }
        return errSecServiceNotAvailable;
-#endif
 }
 
 }
 
-#if SECTRUST_OSX
 //
 // Returns a malloced array of CSSM_RETURN values, with the length in numStatusCodes,
 // for the certificate specified by chain index in the given SecTrustRef.
 //
 // Returns a malloced array of CSSM_RETURN values, with the length in numStatusCodes,
 // for the certificate specified by chain index in the given SecTrustRef.
@@ -711,9 +456,10 @@ static CSSM_RETURN *copyCssmStatusCodes(SecTrustRef trust,
                return NULL;
        }
        *numStatusCodes = 0;
                return NULL;
        }
        *numStatusCodes = 0;
-       CFArrayRef details = SecTrustGetDetails(trust);
+       CFArrayRef details = SecTrustCopyFilteredDetails(trust);
        CFIndex chainLength = (details) ? CFArrayGetCount(details) : 0;
        if (!(index < chainLength)) {
        CFIndex chainLength = (details) ? CFArrayGetCount(details) : 0;
        if (!(index < chainLength)) {
+               CFReleaseSafe(details);
                return NULL;
        }
        CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, index);
                return NULL;
        }
        CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, index);
@@ -748,6 +494,7 @@ static CSSM_RETURN *copyCssmStatusCodes(SecTrustRef trust,
                statusCodes[ix] = statusCode;
        }
 
                statusCodes[ix] = statusCode;
        }
 
+       CFReleaseSafe(details);
        return statusCodes;
 }
 
        return statusCodes;
 }
 
@@ -799,20 +546,28 @@ static bool isSoftwareUpdateDevelopment(SecTrustRef trust) {
     }
 
     /* Only error was EKU on the leaf */
     }
 
     /* Only error was EKU on the leaf */
-    CFArrayRef details = SecTrustGetDetails(trust);
+    CFArrayRef details = SecTrustCopyFilteredDetails(trust);
     CFIndex ix, count = CFArrayGetCount(details);
     CFIndex ix, count = CFArrayGetCount(details);
+    bool hasDisqualifyingError = false;
     for (ix = 0; ix < count; ix++) {
         CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
         if (ix == 0) { // Leaf
             if (CFDictionaryGetCount(detail) != 1 || // One error
     for (ix = 0; ix < count; ix++) {
         CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
         if (ix == 0) { // Leaf
             if (CFDictionaryGetCount(detail) != 1 || // One error
-                CFDictionaryGetValue(detail, CFSTR("ExtendedKeyUsage")) != kCFBooleanFalse) // kSecPolicyCheckExtendedKeyUsage
-                return false;
+                CFDictionaryGetValue(detail, CFSTR("ExtendedKeyUsage")) != kCFBooleanFalse) { // kSecPolicyCheckExtendedKeyUsage
+                hasDisqualifyingError = true;
+                break;
+            }
         } else {
             if (CFDictionaryGetCount(detail) > 0) { // No errors on other certs
         } else {
             if (CFDictionaryGetCount(detail) > 0) { // No errors on other certs
-                return false;
+                hasDisqualifyingError = true;
+                break;
             }
         }
     }
             }
         }
     }
+    CFReleaseSafe(details);
+    if (hasDisqualifyingError) {
+        return false;
+    }
 
     /* EKU on the leaf is the Apple Development Code Signing OID */
     SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0);
 
     /* EKU on the leaf is the Apple Development Code Signing OID */
     SecCertificateRef leaf = SecTrustGetCertificateAtIndex(trust, 0);
@@ -835,7 +590,6 @@ static bool isSoftwareUpdateDevelopment(SecTrustRef trust) {
     SecCertificateReleaseFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, fieldValue);
     return isEKU;
 }
     SecCertificateReleaseFirstFieldValue(leaf, &CSSMOID_ExtendedKeyUsage, fieldValue);
     return isEKU;
 }
-#endif
 
 //
 // Retrieve CSSM_LEVEL TP return code
 
 //
 // Retrieve CSSM_LEVEL TP return code
@@ -843,15 +597,6 @@ static bool isSoftwareUpdateDevelopment(SecTrustRef trust) {
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
 {
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-               Trust *trust = Trust::required(trustRef);
-       if (trust->result() == kSecTrustResultInvalid)
-               return errSecParam;
-       else
-               Required(result) = trust->cssmResultCode();
-       END_SECAPI
-#else
        /* bridge to support old functionality */
 #if SECTRUST_DEPRECATION_WARNINGS
     syslog(LOG_ERR, "WARNING: SecTrustGetCssmResultCode has been deprecated since 10.7, and will be removed in a future release. Please use SecTrustCopyProperties instead.");
        /* bridge to support old functionality */
 #if SECTRUST_DEPRECATION_WARNINGS
     syslog(LOG_ERR, "WARNING: SecTrustGetCssmResultCode has been deprecated since 10.7, and will be removed in a future release. Please use SecTrustCopyProperties instead.");
@@ -887,10 +632,10 @@ OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
             unsigned int statusIX;
             for (statusIX = 0; statusIX < numStatusCodes; statusIX++) {
                 CSSM_RETURN currStatus = statusCodes[statusIX];
             unsigned int statusIX;
             for (statusIX = 0; statusIX < numStatusCodes; statusIX++) {
                 CSSM_RETURN currStatus = statusCodes[statusIX];
-                uint8_t currPriotiy = convertCssmResultToPriority(currStatus);
-                if (resultCodePriority > currPriotiy) {
+                uint8_t currPriority = convertCssmResultToPriority(currStatus);
+                if (resultCodePriority > currPriority) {
                     cssmResultCode = currStatus;
                     cssmResultCode = currStatus;
-                    resultCodePriority = currPriotiy;
+                    resultCodePriority = currPriority;
                 }
             }
         }
                 }
             }
         }
@@ -902,17 +647,11 @@ OSStatus SecTrustGetCssmResultCode(SecTrustRef trustRef, OSStatus *result)
                *result = cssmResultCode;
        }
        return errSecSuccess;
                *result = cssmResultCode;
        }
        return errSecSuccess;
-#endif
 }
 
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
 {
 }
 
 /* OS X only: __OSX_AVAILABLE_BUT_DEPRECATED(__MAC_10_2, __MAC_10_7, __IPHONE_NA, __IPHONE_NA) */
 OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-               Required(handle) = Trust::required(trust)->getTPHandle();
-       END_SECAPI
-#else
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetTPHandle has been deprecated since 10.7, and cannot return CSSM objects in 10.11. Please stop using it.");
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetTPHandle has been deprecated since 10.7, and cannot return CSSM objects in 10.11. Please stop using it.");
@@ -921,74 +660,7 @@ OSStatus SecTrustGetTPHandle(SecTrustRef trust, CSSM_TP_HANDLE *handle)
                *handle = NULL;
        }
        return errSecServiceNotAvailable;
                *handle = NULL;
        }
        return errSecServiceNotAvailable;
-#endif
-}
-
-#if !SECTRUST_OSX
-OSStatus SecTrustCopyPolicies(SecTrustRef trust, CFArrayRef *policies)
-{
-       BEGIN_SECAPI
-               CFArrayRef currentPolicies = Trust::required(trust)->policies();
-       if (currentPolicies != NULL)
-       {
-               CFRetain(currentPolicies);
-       }
-
-       Required(policies) = currentPolicies;
-       END_SECAPI
-}
-#endif
-
-#if !SECTRUST_OSX
-OSStatus SecTrustSetNetworkFetchAllowed(SecTrustRef trust, Boolean allowFetch)
-{
-       BEGIN_SECAPI
-       Trust *trustObj = Trust::required(trust);
-       Trust::NetworkPolicy netPolicy = (allowFetch) ?
-               Trust::useNetworkEnabled : Trust::useNetworkDisabled;
-       trustObj->networkPolicy(netPolicy);
-       END_SECAPI
-}
-#endif
-
-#if !SECTRUST_OSX
-OSStatus SecTrustGetNetworkFetchAllowed(SecTrustRef trust, Boolean *allowFetch)
-{
-       BEGIN_SECAPI
-       Boolean allowed = false;
-       Trust *trustObj = Trust::required(trust);
-       Trust::NetworkPolicy netPolicy = trustObj->networkPolicy();
-       if (netPolicy == Trust::useNetworkDefault) {
-               // network fetch is enabled by default for SSL only
-               allowed = trustObj->policySpecified(trustObj->policies(), CSSMOID_APPLE_TP_SSL);
-       } else {
-               // caller has explicitly set the network policy
-               allowed = (netPolicy == Trust::useNetworkEnabled);
-       }
-       Required(allowFetch) = allowed;
-       END_SECAPI
 }
 }
-#endif
-
-#if !SECTRUST_OSX
-OSStatus SecTrustSetOCSPResponse(SecTrustRef trust, CFTypeRef responseData)
-{
-       BEGIN_SECAPI
-       Trust::required(trust)->responses(responseData);
-       END_SECAPI
-}
-#endif
-
-#if !SECTRUST_OSX
-OSStatus SecTrustCopyCustomAnchorCertificates(SecTrustRef trust, CFArrayRef *anchorCertificates)
-{
-       BEGIN_SECAPI
-       CFArrayRef customAnchors = Trust::required(trust)->anchors();
-       Required(anchorCertificates) = (customAnchors) ?
-               (const CFArrayRef)CFRetain(customAnchors) : (const CFArrayRef)NULL;
-       END_SECAPI
-}
-#endif
 
 //
 // Get the user's default anchor certificate set
 
 //
 // Get the user's default anchor certificate set
@@ -1005,7 +677,6 @@ OSStatus SecTrustCopyAnchorCertificates(CFArrayRef *anchorCertificates)
        END_SECAPI
 }
 
        END_SECAPI
 }
 
-#if SECTRUST_OSX
 /* We have an iOS-style SecTrustRef, but we need to return a CDSA-based SecKeyRef.
  */
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
 /* We have an iOS-style SecTrustRef, but we need to return a CDSA-based SecKeyRef.
  */
 SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
@@ -1015,145 +686,6 @@ SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
        (void) SecCertificateCopyPublicKey(certificate, &pubKey);
        return pubKey;
 }
        (void) SecCertificateCopyPublicKey(certificate, &pubKey);
        return pubKey;
 }
-#else
-/* new in 10.6 */
-SecKeyRef SecTrustCopyPublicKey(SecTrustRef trust)
-{
-       SecKeyRef pubKey = NULL;
-       CFArrayRef certChain = NULL;
-       CFArrayRef evidenceChain = NULL;
-       CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-       OSStatus __secapiresult = errSecSuccess;
-       try {
-               Trust *trustObj = Trust::required(trust);
-               if (trustObj->result() == kSecTrustResultInvalid) {
-                       // Trust hasn't been evaluated; attempt to retrieve public key from leaf.
-                       SecCertificateRef cert = SecTrustGetCertificateAtIndex(trust, 0);
-                       __secapiresult = SecCertificateCopyPublicKey(cert, &pubKey);
-                       if (pubKey) {
-                               return pubKey;
-                       }
-                       // Otherwise, we must evaluate first.
-                       trustObj->evaluate();
-                       if (trustObj->result() == kSecTrustResultInvalid) {
-                               MacOSError::throwMe(errSecTrustNotAvailable);
-                       }
-               }
-               if (trustObj->evidence() == nil) {
-                       trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
-               }
-               evidenceChain = trustObj->evidence();
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       if (certChain)
-               CFRelease(certChain);
-
-       if (evidenceChain) {
-               if (CFArrayGetCount(evidenceChain) > 0) {
-                       SecCertificateRef cert = (SecCertificateRef) CFArrayGetValueAtIndex(evidenceChain, 0);
-                       __secapiresult = SecCertificateCopyPublicKey(cert, &pubKey);
-               }
-               // do not release evidenceChain, as it is owned by the trust object.
-       }
-       return pubKey;
-}
-#endif
-
-#if !SECTRUST_OSX
-/* new in 10.6 */
-CFIndex SecTrustGetCertificateCount(SecTrustRef trust)
-{
-       CFIndex chainLen = 0;
-       CFArrayRef certChain = NULL;
-       CFArrayRef evidenceChain = NULL;
-       CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-    OSStatus __secapiresult = errSecSuccess;
-       try {
-               Trust *trustObj = Trust::required(trust);
-               if (trustObj->result() == kSecTrustResultInvalid) {
-                       trustObj->evaluate();
-                       if (trustObj->result() == kSecTrustResultInvalid)
-                               MacOSError::throwMe(errSecTrustNotAvailable);
-               }
-               if (trustObj->evidence() == nil)
-                       trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
-               evidenceChain = trustObj->evidence();
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       if (certChain)
-               CFRelease(certChain);
-
-       if (evidenceChain)
-               chainLen = CFArrayGetCount(evidenceChain); // don't release, trust object owns it.
-
-    return chainLen;
-}
-#endif
-
-#if !SECTRUST_OSX
-/* new in 10.6 */
-SecCertificateRef SecTrustGetCertificateAtIndex(SecTrustRef trust, CFIndex ix)
-{
-       SecCertificateRef certificate = NULL;
-       CFArrayRef certChain = NULL;
-       CFArrayRef evidenceChain = NULL;
-       CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-    OSStatus __secapiresult = errSecSuccess;
-       try {
-               Trust *trustObj = Trust::required(trust);
-               if (trustObj->result() == kSecTrustResultInvalid) {
-                       // If caller is asking for the leaf, we can return it without
-                       // having to evaluate the entire chain. Note that we don't retain
-                       // the cert as it's owned by the trust and this is a 'Get' API.
-                       if (ix == 0) {
-                               CFArrayRef certs = trustObj->certificates();
-                               if (certs && (CFArrayGetCount(certs) > 0)) {
-                                       certificate = (SecCertificateRef) CFArrayGetValueAtIndex(certs, 0);
-                                       if (certificate) {
-                                               return certificate;
-                                       }
-                               }
-                       }
-                       // Otherwise, we must evaluate first.
-                       trustObj->evaluate();
-                       if (trustObj->result() == kSecTrustResultInvalid) {
-                               MacOSError::throwMe(errSecTrustNotAvailable);
-                       }
-               }
-               if (trustObj->evidence() == nil) {
-                       trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
-               }
-               evidenceChain = trustObj->evidence();
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       if (certChain)
-               CFRelease(certChain);
-
-       if (evidenceChain) {
-               if (ix < CFArrayGetCount(evidenceChain)) {
-                       certificate = (SecCertificateRef) CFArrayGetValueAtIndex(evidenceChain, ix);
-                       // note: we do not retain this certificate. The assumption here is
-                       // that the certificate is retained by the trust object, so it is
-                       // valid unil the trust is released (or until re-evaluated.)
-                       // also note: we do not release the evidenceChain, as it is owned
-                       // by the trust object.
-               }
-       }
-       return certificate;
-}
-#endif
 
 // cannot link against the new iOS SecTrust from this implementation,
 // so there are no possible accessors for the fields of this struct
 
 // cannot link against the new iOS SecTrust from this implementation,
 // so there are no possible accessors for the fields of this struct
@@ -1177,9 +709,9 @@ typedef struct __TSecTrust {
     void*                   _legacy_info_array;
     void*                   _legacy_status_array;
     SecTrustResultType      _trustResultBeforeExceptions;
     void*                   _legacy_info_array;
     void*                   _legacy_status_array;
     SecTrustResultType      _trustResultBeforeExceptions;
+    dispatch_queue_t        _trustQueue;
 } TSecTrust;
 
 } TSecTrust;
 
-#if SECTRUST_OSX
 CFArrayRef SecTrustCopyInputCertificates(SecTrustRef trust)
 {
        if (!trust) { return NULL; };
 CFArrayRef SecTrustCopyInputCertificates(SecTrustRef trust)
 {
        if (!trust) { return NULL; };
@@ -1189,9 +721,7 @@ CFArrayRef SecTrustCopyInputCertificates(SecTrustRef trust)
        }
        return secTrust->_certificates;
 }
        }
        return secTrust->_certificates;
 }
-#endif
 
 
-#if SECTRUST_OSX
 CFArrayRef SecTrustCopyInputAnchors(SecTrustRef trust)
 {
        if (!trust) { return NULL; };
 CFArrayRef SecTrustCopyInputAnchors(SecTrustRef trust)
 {
        if (!trust) { return NULL; };
@@ -1201,9 +731,7 @@ CFArrayRef SecTrustCopyInputAnchors(SecTrustRef trust)
        }
        return secTrust->_anchors;
 }
        }
        return secTrust->_anchors;
 }
-#endif
 
 
-#if SECTRUST_OSX
 // Return the constructed certificate chain for this trust reference,
 // making output certificates pointer-equivalent to any provided input
 // certificates (where possible) for legacy behavioral compatibility.
 // Return the constructed certificate chain for this trust reference,
 // making output certificates pointer-equivalent to any provided input
 // certificates (where possible) for legacy behavioral compatibility.
@@ -1258,9 +786,7 @@ CFArrayRef SecTrustCopyConstructedChain(SecTrustRef trust)
        }
        return certChain;
 }
        }
        return certChain;
 }
-#endif
 
 
-#if SECTRUST_OSX
 //
 // Here is where backward compatibility gets ugly. CSSM_TP_APPLE_EVIDENCE_INFO does not exist
 // in the unified SecTrust world. Unfortunately, some clients are still calling legacy APIs
 //
 // Here is where backward compatibility gets ugly. CSSM_TP_APPLE_EVIDENCE_INFO does not exist
 // in the unified SecTrust world. Unfortunately, some clients are still calling legacy APIs
@@ -1278,7 +804,7 @@ SecTrustGetEvidenceInfo(SecTrustRef trust)
        if (!secTrust) {
                return NULL;
        }
        if (!secTrust) {
                return NULL;
        }
-       if (secTrust->_trustResult != kSecTrustSettingsResultInvalid &&
+       if (secTrust->_trustResult != kSecTrustResultInvalid &&
                secTrust->_legacy_info_array) {
                // we've already got valid evidence info, return it now.
                return (CSSM_TP_APPLE_EVIDENCE_INFO *)secTrust->_legacy_info_array;
                secTrust->_legacy_info_array) {
                // we've already got valid evidence info, return it now.
                return (CSSM_TP_APPLE_EVIDENCE_INFO *)secTrust->_legacy_info_array;
@@ -1338,7 +864,7 @@ SecTrustGetEvidenceInfo(SecTrustRef trust)
                CSSM_RETURN *errors = NULL;
                uint32 errorCount = 0;
                OSStatus status = 0;
                CSSM_RETURN *errors = NULL;
                uint32 errorCount = 0;
                OSStatus status = 0;
-               SecTrustSettingsDomain foundDomain = 0;
+               SecTrustSettingsDomain foundDomain = kSecTrustSettingsDomainUser;
                SecTrustSettingsResult foundResult = kSecTrustSettingsResultInvalid;
                bool isSelfSigned = false;
                if ((count - 1) == idx) {
                SecTrustSettingsResult foundResult = kSecTrustSettingsResultInvalid;
                bool isSelfSigned = false;
                if ((count - 1) == idx) {
@@ -1460,283 +986,7 @@ SecTrustGetEvidenceInfo(SecTrustRef trust)
 
        return (CSSM_TP_APPLE_EVIDENCE_INFO *)secTrust->_legacy_info_array;
 }
 
        return (CSSM_TP_APPLE_EVIDENCE_INFO *)secTrust->_legacy_info_array;
 }
-#endif
-
-#if !SECTRUST_OSX
-static CFStringRef kSecCertificateDetailSHA1Digest = CFSTR("SHA1Digest");
-static CFStringRef kSecCertificateDetailStatusCodes = CFSTR("StatusCodes");
-
-static void
-_AppendStatusCode(CFMutableArrayRef array, OSStatus statusCode)
-{
-       if (!array)
-               return;
-       SInt32 num = statusCode;
-       CFNumberRef numRef = CFNumberCreate(NULL, kCFNumberSInt32Type, &num);
-       if (!numRef)
-               return;
-       CFArrayAppendValue(array, numRef);
-       CFRelease(numRef);
-}
-#endif
-
-#if !SECTRUST_OSX
-CFArrayRef SecTrustCopyDetails(SecTrustRef trust)
-{
-       // This function returns an array of dictionaries, one per certificate,
-       // holding status info for each certificate in the evaluated chain.
-       //
-       CFIndex count, chainLen = 0;
-       CFArrayRef certChain = NULL;
-       CFMutableArrayRef details = NULL;
-       CSSM_TP_APPLE_EVIDENCE_INFO *statusChain = NULL;
-    OSStatus __secapiresult = errSecSuccess;
-       try {
-               Trust *trustObj = Trust::required(trust);
-               if (trustObj->result() == kSecTrustResultInvalid) {
-                       trustObj->evaluate();
-                       if (trustObj->result() == kSecTrustResultInvalid)
-                               MacOSError::throwMe(errSecTrustNotAvailable);
-               }
-               trustObj->buildEvidence(certChain, TPEvidenceInfo::overlayVar(statusChain));
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       if (certChain) {
-               chainLen = CFArrayGetCount(certChain);
-               CFRelease(certChain);
-       }
-       if (statusChain) {
-               details = CFArrayCreateMutable(NULL, chainLen, &kCFTypeArrayCallBacks);
-               for (count = 0; count < chainLen; count++) {
-                       CFMutableDictionaryRef certDict = CFDictionaryCreateMutable(kCFAllocatorDefault,
-                               0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-                       CFMutableArrayRef statusCodes = CFArrayCreateMutable(kCFAllocatorDefault,
-                               0, &kCFTypeArrayCallBacks);
-                       CSSM_TP_APPLE_EVIDENCE_INFO *evInfo = &statusChain[count];
-                       CSSM_TP_APPLE_CERT_STATUS statBits = evInfo->StatusBits;
-
-                       // translate status bits
-                       if (statBits & CSSM_CERT_STATUS_EXPIRED)
-                               _AppendStatusCode(statusCodes, errSecCertificateExpired);
-                       if (statBits & CSSM_CERT_STATUS_NOT_VALID_YET)
-                               _AppendStatusCode(statusCodes, errSecCertificateNotValidYet);
-                       if (statBits & CSSM_CERT_STATUS_TRUST_SETTINGS_DENY)
-                               _AppendStatusCode(statusCodes, errSecTrustSettingDeny);
-
-                       // translate status codes
-                       unsigned int i;
-                       for (i = 0; i < evInfo->NumStatusCodes; i++) {
-                               CSSM_RETURN scode = evInfo->StatusCodes[i];
-                               _AppendStatusCode(statusCodes, (OSStatus)scode);
-                       }
-
-                       CFDictionarySetValue(certDict, kSecCertificateDetailStatusCodes, statusCodes);
-                       CFRelease(statusCodes);
-                       CFArrayAppendValue(details, certDict);
-                       CFRelease(certDict);
-               }
-       }
-       return details;
-}
-#endif
-
-#if !SECTRUST_OSX
-static CFDictionaryRef SecTrustGetExceptionForCertificateAtIndex(SecTrustRef trust, CFIndex ix)
-{
-       CFArrayRef exceptions = NULL;
-    OSStatus __secapiresult = errSecSuccess;
-       try {
-               exceptions = Trust::required(trust)->exceptions();
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       if (!exceptions || ix >= CFArrayGetCount(exceptions))
-               return NULL;
-       CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, ix);
-       if (CFGetTypeID(exception) != CFDictionaryGetTypeID())
-               return NULL;
-
-       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, ix);
-       if (!certificate)
-               return NULL;
-
-       /* If the exception contains the current certificate's sha1Digest in the
-          kSecCertificateDetailSHA1Digest key then we use it otherwise we ignore it. */
-       CFDataRef sha1Digest = SecCertificateGetSHA1Digest(certificate);
-       CFTypeRef digestValue = CFDictionaryGetValue(exception, kSecCertificateDetailSHA1Digest);
-       if (!digestValue || !CFEqual(sha1Digest, digestValue))
-               exception = NULL;
-
-       return exception;
-}
-#endif
-
-#if !SECTRUST_OSX
-static void SecTrustCheckException(const void *key, const void *value, void *context)
-{
-       struct SecTrustCheckExceptionContext *cec = (struct SecTrustCheckExceptionContext *)context;
-       if (cec->exception) {
-               CFTypeRef exceptionValue = CFDictionaryGetValue(cec->exception, key);
-               if (!exceptionValue || !CFEqual(value, exceptionValue)) {
-                       cec->exceptionNotFound = true;
-               }
-       } else {
-               cec->exceptionNotFound = true;
-       }
-}
-#endif
-
-#if !SECTRUST_OSX
-/* new in 10.9 */
-CFDataRef SecTrustCopyExceptions(SecTrustRef trust)
-{
-       CFArrayRef details = SecTrustCopyDetails(trust);
-       CFIndex pathLength = details ? CFArrayGetCount(details) : 0;
-       CFMutableArrayRef exceptions = CFArrayCreateMutable(kCFAllocatorDefault,
-                       pathLength, &kCFTypeArrayCallBacks);
-       CFIndex ix;
-       for (ix = 0; ix < pathLength; ++ix) {
-               CFDictionaryRef detail = (CFDictionaryRef)CFArrayGetValueAtIndex(details, ix);
-               CFIndex detailCount = CFDictionaryGetCount(detail);
-               CFMutableDictionaryRef exception;
-               if (ix == 0 || detailCount > 0) {
-                       exception = CFDictionaryCreateMutableCopy(kCFAllocatorDefault,
-                               detailCount + 1, detail);
-                       SecCertificateRef certificate = SecTrustGetCertificateAtIndex(trust, ix);
-                       CFDataRef digest = SecCertificateGetSHA1Digest(certificate);
-                       if (digest) {
-                               CFDictionaryAddValue(exception, kSecCertificateDetailSHA1Digest, digest);
-                       }
-               } else {
-                       /* Add empty exception dictionaries for non leaf certs which have no exceptions
-                        * to save space.
-                        */
-                       exception = (CFMutableDictionaryRef)CFDictionaryCreate(kCFAllocatorDefault,
-                               NULL, NULL, 0,
-                               &kCFTypeDictionaryKeyCallBacks,
-                               &kCFTypeDictionaryValueCallBacks);
-               }
-               CFArrayAppendValue(exceptions, exception);
-               CFReleaseNull(exception);
-       }
-       CFReleaseSafe(details);
-
-       /* Remove any trailing empty dictionaries to save even more space (we skip the leaf
-          since it will never be empty). */
-       for (ix = pathLength; ix-- > 1;) {
-               CFDictionaryRef exception = (CFDictionaryRef)CFArrayGetValueAtIndex(exceptions, ix);
-               if (CFDictionaryGetCount(exception) == 0) {
-                       CFArrayRemoveValueAtIndex(exceptions, ix);
-               } else {
-                       break;
-               }
-       }
-
-       CFDataRef encodedExceptions = CFPropertyListCreateData(kCFAllocatorDefault,
-                       exceptions, kCFPropertyListBinaryFormat_v1_0, 0, NULL);
-       CFRelease(exceptions);
-
-       return encodedExceptions;
-}
-#endif
-
-#if !SECTRUST_OSX
-/* new in 10.9 */
-bool SecTrustSetExceptions(SecTrustRef trust, CFDataRef encodedExceptions)
-{
-       CFArrayRef exceptions = NULL;
-
-       if (NULL != encodedExceptions) {
-               exceptions = (CFArrayRef)CFPropertyListCreateWithData(kCFAllocatorDefault,
-                               encodedExceptions, kCFPropertyListImmutable, NULL, NULL);
-       }
-
-       if (exceptions && CFGetTypeID(exceptions) != CFArrayGetTypeID()) {
-               CFRelease(exceptions);
-               exceptions = NULL;
-       }
-
-       OSStatus __secapiresult = errSecSuccess;
-       try {
-               /* Exceptions are being set or cleared, we'll need to re-evaluate trust either way. */
-               Trust::required(trust)->setResult(kSecTrustResultInvalid);
-               Trust::required(trust)->exceptions(exceptions);
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       /* If there is a valid exception entry for our current leaf we're golden. */
-       if (SecTrustGetExceptionForCertificateAtIndex(trust, 0))
-               return true;
-
-       /* The passed in exceptions didn't match our current leaf, so we discard it. */
-       try {
-               Trust::required(trust)->exceptions(NULL);
-               __secapiresult = errSecSuccess;
-       }
-       catch (const MacOSError &err) { __secapiresult=err.osStatus(); }
-       catch (const CommonError &err) { __secapiresult=SecKeychainErrFromOSStatus(err.osStatus()); }
-       catch (const std::bad_alloc &) { __secapiresult=errSecAllocate; }
-       catch (...) { __secapiresult=errSecInternalComponent; }
-
-       return false;
-}
-#endif
 
 
-#if !SECTRUST_OSX
-/* new in 10.9 */
-CFDictionaryRef
-SecTrustCopyResult(SecTrustRef trust)
-{
-       CFDictionaryRef result = NULL;
-       try {
-               result = Trust::required(trust)->results();
-               // merge details into result
-               CFArrayRef details = SecTrustCopyDetails(trust);
-               if (details) {
-                       CFDictionarySetValue((CFMutableDictionaryRef)result,
-                               kSecTrustResultDetails, details);
-                       CFRelease(details);
-               }
-       }
-       catch (...) {
-               if (result) {
-                       CFRelease(result);
-                       result = NULL;
-               }
-       }
-       return result;
-}
-#endif
-
-#if !SECTRUST_OSX
-/* new in 10.7 */
-CFArrayRef
-SecTrustCopyProperties(SecTrustRef trust)
-{
-       /* can't use SECAPI macros, since this function does not return OSStatus */
-       CFArrayRef result = NULL;
-       try {
-               result = Trust::required(trust)->properties();
-       }
-       catch (...) {
-               if (result) {
-                       CFRelease(result);
-                       result = NULL;
-               }
-       }
-       return result;
-}
-#else
 CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
     /* OS X creates a completely different structure with one dictionary for each certificate */
     CFIndex ix, count = SecTrustGetCertificateCount(trust);
 CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
     /* OS X creates a completely different structure with one dictionary for each certificate */
     CFIndex ix, count = SecTrustGetCertificateCount(trust);
@@ -1785,24 +1035,16 @@ CFArrayRef SecTrustCopyProperties(SecTrustRef trust) {
         }
 
         CFArrayAppendValue(properties, certDict);
         }
 
         CFArrayAppendValue(properties, certDict);
+        CFRelease(certDict);
     }
 
     return properties;
 }
     }
 
     return properties;
 }
-#endif
 
 /* deprecated in 10.5 */
 OSStatus SecTrustGetCSSMAnchorCertificates(const CSSM_DATA **cssmAnchors,
        uint32 *cssmAnchorCount)
 {
 
 /* deprecated in 10.5 */
 OSStatus SecTrustGetCSSMAnchorCertificates(const CSSM_DATA **cssmAnchors,
        uint32 *cssmAnchorCount)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-       CertGroup certs;
-       Trust::gStore().getCssmRootCertificates(certs);
-       Required(cssmAnchors) = certs.blobCerts();
-       Required(cssmAnchorCount) = certs.count();
-       END_SECAPI
-#else
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetCSSMAnchorCertificates has been deprecated since 10.5, and cannot return CSSM objects in 10.11. Please stop using it.");
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetCSSMAnchorCertificates has been deprecated since 10.5, and cannot return CSSM objects in 10.11. Please stop using it.");
@@ -1814,7 +1056,6 @@ OSStatus SecTrustGetCSSMAnchorCertificates(const CSSM_DATA **cssmAnchors,
                *cssmAnchorCount = 0;
        }
        return errSecServiceNotAvailable;
                *cssmAnchorCount = 0;
        }
        return errSecServiceNotAvailable;
-#endif
 }
 
 
 }
 
 
@@ -1825,22 +1066,11 @@ OSStatus SecTrustGetCSSMAnchorCertificates(const CSSM_DATA **cssmAnchors,
 OSStatus SecTrustGetUserTrust(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting *trustSetting)
 {
 OSStatus SecTrustGetUserTrust(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting *trustSetting)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-       StorageManager::KeychainList searchList;
-       globals().storageManager.getSearchList(searchList);
-       Required(trustSetting) = Trust::gStore().find(
-               Certificate::required(certificate),
-               Policy::required(policy),
-               searchList);
-       END_SECAPI
-#else
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetUserTrust has been deprecated since 10.5, and does nothing in 10.11. Please stop using it.");
 #endif
        return errSecServiceNotAvailable;
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustGetUserTrust has been deprecated since 10.5, and does nothing in 10.11. Please stop using it.");
 #endif
        return errSecServiceNotAvailable;
-#endif
 }
 
 //
 }
 
 //
@@ -1850,53 +1080,11 @@ OSStatus SecTrustGetUserTrust(SecCertificateRef certificate,
 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting trustSetting)
 {
 OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting trustSetting)
 {
-#if !SECTRUST_OSX
-       SecTrustSettingsResult tsResult = kSecTrustSettingsResultInvalid;
-       OSStatus ortn;
-       Boolean isRoot;
-
-       Policy::required(policy);
-       switch(trustSetting) {
-               case kSecTrustResultProceed:
-                       /* different SecTrustSettingsResult depending in root-ness */
-                       ortn = SecCertificateIsSelfSigned(certificate, &isRoot);
-                       if(ortn) {
-                               return ortn;
-                       }
-                       if(isRoot) {
-                               tsResult = kSecTrustSettingsResultTrustRoot;
-                       }
-                       else {
-                               tsResult = kSecTrustSettingsResultTrustAsRoot;
-                       }
-                       break;
-               case kSecTrustResultDeny:
-                       tsResult = kSecTrustSettingsResultDeny;
-                       break;
-               default:
-                       return errSecUnimplemented;
-       }
-
-       /* make a usage constraints dictionary */
-       CFRef<CFMutableDictionaryRef> usageDict(CFDictionaryCreateMutable(NULL,
-               0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks));
-       CFDictionaryAddValue(usageDict, kSecTrustSettingsPolicy, policy);
-       if(tsResult != kSecTrustSettingsResultTrustRoot) {
-               /* skip if we're specifying the default */
-               SInt32 result = tsResult;
-               CFNumberRef cfNum = CFNumberCreate(NULL, kCFNumberSInt32Type, &result);
-               CFDictionarySetValue(usageDict, kSecTrustSettingsResult, cfNum);
-               CFRelease(cfNum);
-       }
-       return SecTrustSettingsSetTrustSettings(certificate, kSecTrustSettingsDomainUser,
-               usageDict);
-#else
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustSetUserTrust has been deprecated since 10.5, and does nothing in 10.11. Please stop using it.");
 #endif
        return errSecServiceNotAvailable;
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustSetUserTrust has been deprecated since 10.5, and does nothing in 10.11. Please stop using it.");
 #endif
        return errSecServiceNotAvailable;
-#endif
 }
 
 //
 }
 
 //
@@ -1907,27 +1095,9 @@ OSStatus SecTrustSetUserTrust(SecCertificateRef certificate,
 OSStatus SecTrustSetUserTrustLegacy(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting trustSetting)
 {
 OSStatus SecTrustSetUserTrustLegacy(SecCertificateRef certificate,
     SecPolicyRef policy, SecTrustUserSetting trustSetting)
 {
-#if !SECTRUST_OSX
-       BEGIN_SECAPI
-       switch (trustSetting) {
-    case kSecTrustResultProceed:
-    case kSecTrustResultConfirm:
-    case kSecTrustResultDeny:
-    case kSecTrustResultUnspecified:
-               break;
-       default:
-               MacOSError::throwMe(errSecInvalidTrustSetting);
-       }
-       Trust::gStore().assign(
-               Certificate::required(certificate),
-               Policy::required(policy),
-               trustSetting);
-       END_SECAPI
-#else
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustSetUserTrustLegacy does nothing in 10.11. Please stop using it.");
 #endif
        return errSecServiceNotAvailable;
        /* this function is unsupported in unified SecTrust */
 #if SECTRUST_DEPRECATION_WARNINGS
        syslog(LOG_ERR, "WARNING: SecTrustSetUserTrustLegacy does nothing in 10.11. Please stop using it.");
 #endif
        return errSecServiceNotAvailable;
-#endif
 }
 }