]> git.saurik.com Git - apple/security.git/blobdiff - sec/securityd/SecTrustServer.c
Security-57031.1.35.tar.gz
[apple/security.git] / sec / securityd / SecTrustServer.c
diff --git a/sec/securityd/SecTrustServer.c b/sec/securityd/SecTrustServer.c
deleted file mode 100644 (file)
index fc12a77..0000000
+++ /dev/null
@@ -1,1339 +0,0 @@
-/*
- * Copyright (c) 2006-2010 Apple Inc. All Rights Reserved.
- *
- * @APPLE_LICENSE_HEADER_START@
- *
- * This file contains Original Code and/or Modifications of Original Code
- * as defined in and that are subject to the Apple Public Source License
- * Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
- *
- * The Original Code and all software distributed under the License are
- * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
- * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
- * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
- * Please see the License for the specific language governing rights and
- * limitations under the License.
- *
- * @APPLE_LICENSE_HEADER_END@
- *
- * SecTrustServer.c - certificate trust evaluation engine
- *
- *  Created by Michael Brouwer on 12/12/08.
- *
- */
-
-#include <securityd/SecTrustServer.h>
-#include <securityd/SecPolicyServer.h>
-#include <securityd/SecTrustStoreServer.h>
-#include <securityd/SecCAIssuerRequest.h>
-#include <securityd/SecItemServer.h>
-
-#include <utilities/SecIOFormat.h>
-#include <utilities/SecDispatchRelease.h>
-
-#include <Security/SecTrustPriv.h>
-#include <Security/SecItem.h>
-#include <Security/SecCertificateInternal.h>
-#include <Security/SecCertificatePath.h>
-#include <Security/SecFramework.h>
-#include <Security/SecPolicyInternal.h>
-#include <CoreFoundation/CFRuntime.h>
-#include <CoreFoundation/CFSet.h>
-#include <CoreFoundation/CFString.h>
-#include <CoreFoundation/CFNumber.h>
-#include <CoreFoundation/CFArray.h>
-#include <CoreFoundation/CFPropertyList.h>
-#include <AssertMacros.h>
-#include <stdbool.h>
-#include <string.h>
-#include <stdlib.h>
-#include <limits.h>
-#include <Security/SecBase.h>
-#include "SecRSAKey.h"
-#include <libDER/oids.h>
-#include <utilities/debugging.h>
-#include <utilities/SecCFWrappers.h>
-#include <Security/SecInternal.h>
-#include "securityd_client.h"
-#include <CommonCrypto/CommonDigest.h>
-#include "OTATrustUtilities.h"
-
-
-/********************************************************
- ***************** OTA Trust support ********************
- ********************************************************/
-
-
-#ifndef SECITEM_SHIM_OSX
-
-static CFArrayRef subject_to_anchors(CFDataRef nic);
-static CFArrayRef CopyCertsFromIndices(CFArrayRef offsets);
-
-static CFArrayRef subject_to_anchors(CFDataRef nic)
-{
-    CFArrayRef result = NULL;
-
-    if (NULL == nic)
-    {
-        return result;
-    }
-
-       SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
-       if (NULL == otapkiref)
-       {
-               return result;
-       }
-       
-       CFDictionaryRef lookupTable = SecOTAPKICopyAnchorLookupTable(otapkiref);
-       CFRelease(otapkiref);
-
-       if (NULL == lookupTable)
-       {
-               return result;
-       }
-
-    unsigned char subject_digest[CC_SHA1_DIGEST_LENGTH];
-    memset(subject_digest, 0, CC_SHA1_DIGEST_LENGTH);
-
-    (void)CC_SHA1(CFDataGetBytePtr(nic), (CC_LONG)CFDataGetLength(nic), subject_digest);
-    CFDataRef sha1Digest = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, subject_digest, CC_SHA1_DIGEST_LENGTH, kCFAllocatorNull);
-
-
-    result = (CFArrayRef)CFDictionaryGetValue(lookupTable, sha1Digest);
-       CFReleaseSafe(lookupTable);
-    CFReleaseSafe(sha1Digest);
-
-    return result;
-}
-
-static CFArrayRef CopyCertDataFromIndices(CFArrayRef offsets)
-{
-    CFMutableArrayRef result = NULL;
-
-       SecOTAPKIRef otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
-       if (NULL == otapkiref)
-       {
-               return result;
-       }
-       
-       const char* anchorTable = SecOTAPKIGetAnchorTable(otapkiref);   
-       if (NULL == anchorTable)
-       {
-               CFReleaseSafe(otapkiref);
-               return result;
-       }
-
-       CFIndex num_offsets = CFArrayGetCount(offsets);
-       
-       result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-       
-       for (CFIndex idx = 0; idx < num_offsets; idx++)
-    {
-               CFNumberRef offset = (CFNumberRef)CFArrayGetValueAtIndex(offsets, idx);
-               uint32_t offset_value = 0;
-               if (CFNumberGetValue(offset, kCFNumberSInt32Type, &offset_value))
-               {
-                       char* pDataPtr = (char *)(anchorTable + offset_value);
-                       //int32_t record_length = *((int32_t * )pDataPtr);
-                       //record_length = record_length;
-                       pDataPtr += sizeof(uint32_t);
-
-                       int32_t cert_data_length = *((int32_t * )pDataPtr);
-                       pDataPtr += sizeof(uint32_t);
-
-                       CFDataRef cert_data = CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, (const UInt8 *)pDataPtr,
-                                                              cert_data_length, kCFAllocatorNull);
-                       if (NULL != cert_data)
-                       {
-                CFArrayAppendValue(result, cert_data);
-                CFReleaseSafe(cert_data);
-            }
-               }
-       }
-       CFReleaseSafe(otapkiref);
-       return result;
-}
-
-static CFArrayRef CopyCertsFromIndices(CFArrayRef offsets)
-{
-       CFMutableArrayRef result = NULL;
-
-    CFArrayRef cert_data_array = CopyCertDataFromIndices(offsets);
-
-    if (NULL != cert_data_array)
-    {
-        result = CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks);
-        CFIndex num_cert_datas = CFArrayGetCount(cert_data_array);
-        for (CFIndex idx = 0; idx < num_cert_datas; idx++)
-        {
-            CFDataRef cert_data = (CFDataRef)CFArrayGetValueAtIndex(cert_data_array, idx);
-            if (NULL != cert_data)
-            {
-                SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, cert_data);
-                if (NULL != cert)
-                {
-                    CFArrayAppendValue(result, cert);
-                    CFRelease(cert);
-                }
-            }
-        }
-        CFRelease(cert_data_array);
-    }
-    return result;
-
-}
-#endif
-
-/********************************************************
- *************** END OTA Trust support ******************
- ********************************************************/
-
-#define MAX_CHAIN_LENGTH  15
-
-/* Forward declaration for use in SecCertificateSource. */
-static void SecPathBuilderExtendPaths(void *context, CFArrayRef parents);
-
-
-// MARK: -
-// MARK: SecCertificateSource
-/********************************************************
- ************ SecCertificateSource object ***************
- ********************************************************/
-
-typedef struct SecCertificateSource *SecCertificateSourceRef;
-typedef void(*SecCertificateSourceParents)(void *, CFArrayRef);
-typedef bool(*CopyParents)(SecCertificateSourceRef source,
-       SecCertificateRef certificate, void *context, SecCertificateSourceParents);
-typedef bool(*Contains)(SecCertificateSourceRef source,
-       SecCertificateRef certificate);
-
-struct SecCertificateSource {
-       CopyParents             copyParents;
-       Contains                contains;
-};
-
-static bool SecCertificateSourceCopyParents(SecCertificateSourceRef source,
-    SecCertificateRef certificate,
-    void *context, SecCertificateSourceParents callback) {
-    return source->copyParents(source, certificate, context, callback);
-}
-
-static bool SecCertificateSourceContains(SecCertificateSourceRef source,
-       SecCertificateRef certificate) {
-       return source->contains(source, certificate);
-}
-
-// MARK: -
-// MARK: SecItemCertificateSource
-/********************************************************
- *********** SecItemCertificateSource object ************
- ********************************************************/
-struct SecItemCertificateSource {
-       struct SecCertificateSource base;
-       CFArrayRef accessGroups;
-};
-typedef struct SecItemCertificateSource *SecItemCertificateSourceRef;
-
-static CFTypeRef SecItemCertificateSourceResultsPost(CFTypeRef raw_results) {
-    if (isArray(raw_results)) {
-        CFMutableArrayRef result = CFArrayCreateMutable(kCFAllocatorDefault, CFArrayGetCount(raw_results), &kCFTypeArrayCallBacks);
-        CFArrayForEach(raw_results, ^(const void *value) {
-            SecCertificateRef cert = SecCertificateCreateWithData(kCFAllocatorDefault, value);
-            if (cert) {
-                CFArrayAppendValue(result, cert);
-                               CFRelease(cert);
-                       }
-        });
-        return result;
-    } else if (isData(raw_results)) {
-        return SecCertificateCreateWithData(kCFAllocatorDefault, (CFDataRef)raw_results);
-    }
-    return NULL;
-}
-
-static bool SecItemCertificateSourceCopyParents(
-       SecCertificateSourceRef source, SecCertificateRef certificate,
-        void *context, SecCertificateSourceParents callback) {
-       SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
-    /* FIXME: Search for things other than just subject of our issuer if we
-       have a subjectID or authorityKeyIdentifier. */
-    CFDataRef normalizedIssuer =
-        SecCertificateGetNormalizedIssuerContent(certificate);
-    const void *keys[] = {
-        kSecClass,
-        kSecReturnData,
-        kSecMatchLimit,
-        kSecAttrSubject
-    },
-    *values[] = {
-        kSecClassCertificate,
-        kCFBooleanTrue,
-        kSecMatchLimitAll,
-        normalizedIssuer
-    };
-    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 4,
-               NULL, NULL);
-    CFTypeRef results = NULL;
-    /* We can make this async or run this on a queue now easily. */
-    CFErrorRef localError = NULL;
-    if (!_SecItemCopyMatching(query, msource->accessGroups, &results, &localError)) {
-        if (CFErrorGetCode(localError) != errSecItemNotFound) {
-            secdebug("trust", "_SecItemCopyMatching: %@", localError);
-        }
-        CFRelease(localError);
-    }
-    CFRelease(query);
-    CFTypeRef certs = SecItemCertificateSourceResultsPost(results);
-    CFReleaseSafe(results);
-    callback(context, certs);
-    CFReleaseSafe(certs);
-    return true;
-}
-
-static bool SecItemCertificateSourceContains(SecCertificateSourceRef source,
-       SecCertificateRef certificate) {
-       SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
-    /* Lookup a certificate by issuer and serial number. */
-    CFDataRef normalizedSubject =
-        SecCertificateGetNormalizedSubjectContent(certificate);
-    CFDataRef serialNumber =
-        SecCertificateCopySerialNumber(certificate);
-    const void *keys[] = {
-        kSecClass,
-        kSecMatchLimit,
-        kSecAttrIssuer,
-               kSecAttrSerialNumber
-    },
-    *values[] = {
-        kSecClassCertificate,
-        kSecMatchLimitOne,
-        normalizedSubject,
-               serialNumber
-    };
-    CFDictionaryRef query = CFDictionaryCreate(NULL, keys, values, 5,
-        NULL, NULL);
-    CFErrorRef localError = NULL;
-    CFTypeRef results = NULL;
-    bool ok = _SecItemCopyMatching(query, msource->accessGroups, &results, &localError);
-    CFRelease(query);
-    CFRelease(serialNumber);
-    CFReleaseSafe(results);
-    if (!ok) {
-        if (CFErrorGetCode(localError) != errSecItemNotFound) {
-            secdebug("trust", "_SecItemCopyMatching: %@", localError);
-        }
-        CFRelease(localError);
-               return false;
-    }
-    return true;
-}
-
-static SecCertificateSourceRef SecItemCertificateSourceCreate(CFArrayRef accessGroups) {
-       SecItemCertificateSourceRef result = (SecItemCertificateSourceRef)malloc(sizeof(*result));
-       result->base.copyParents = SecItemCertificateSourceCopyParents;
-       result->base.contains = SecItemCertificateSourceContains;
-       result->accessGroups = accessGroups;
-    CFRetainSafe(accessGroups);
-       return (SecCertificateSourceRef)result;
-}
-
-static void SecItemCertificateSourceDestroy(SecCertificateSourceRef source) {
-       SecItemCertificateSourceRef msource = (SecItemCertificateSourceRef)source;
-       CFReleaseSafe(msource->accessGroups);
-       free(msource);
-}
-
-// MARK: -
-// MARK: SecSystemAnchorSource
-/********************************************************
- *********** SecSystemAnchorSource object ************
- ********************************************************/
-
-static bool SecSystemAnchorSourceCopyParents(
-       SecCertificateSourceRef source, SecCertificateRef certificate,
-        void *context, SecCertificateSourceParents callback) {
-#ifndef SECITEM_SHIM_OSX
-    CFArrayRef parents = NULL;
-       CFArrayRef anchors = NULL;
-       SecOTAPKIRef otapkiref = NULL;
-       
-    CFDataRef nic = SecCertificateGetNormalizedIssuerContent(certificate);
-    /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor.
-       It does not matter since we would be returning the wrong anchors */
-    assert((unsigned long)CFDataGetLength(nic)<UINT_MAX); /* Debug check. correct as long as CFIndex is signed long */
-
-       otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
-       require_quiet(otapkiref, errOut);
-       anchors = subject_to_anchors(nic);
-       require_quiet(anchors, errOut);
-       parents = CopyCertsFromIndices(anchors);
-
-errOut:
-    callback(context, parents);
-    CFReleaseSafe(parents);
-       CFReleaseSafe(otapkiref);
-#endif
-    return true;
-}
-
-/* Quick thought: we can eliminate this method if we search anchor sources
-   before all others and we remember if we got a cert from an anchorsource. */
-static bool SecSystemAnchorSourceContains(SecCertificateSourceRef source,
-       SecCertificateRef certificate) {
-       bool result = false;
-#ifndef SECITEM_SHIM_OSX
-       CFArrayRef anchors = NULL;
-       SecOTAPKIRef otapkiref = NULL;
-       CFArrayRef cert_datas = NULL;
-       
-    CFDataRef nic = SecCertificateGetNormalizedSubjectContent(certificate);
-    /* 64 bits cast: the worst that can happen here is we truncate the length and match an actual anchor.
-     It does not matter since we would be returning the wrong anchors */
-    assert((unsigned long)CFDataGetLength(nic)<UINT_MAX); /* Debug check. correct as long as CFIndex is signed long */
-    
-       otapkiref = SecOTAPKICopyCurrentOTAPKIRef();
-       require_quiet(otapkiref, errOut);
-    anchors = subject_to_anchors(nic);
-       require_quiet(anchors, errOut);
-    cert_datas = CopyCertDataFromIndices(anchors);
-    require_quiet(cert_datas, errOut);
-  
-    CFIndex cert_length = SecCertificateGetLength(certificate);
-    const UInt8 *cert_data_ptr = SecCertificateGetBytePtr(certificate);
-    
-    CFIndex num_cert_datas = CFArrayGetCount(cert_datas);
-    for (CFIndex idx = 0; idx < num_cert_datas; idx++)
-    {
-        CFDataRef cert_data = (CFDataRef)CFArrayGetValueAtIndex(cert_datas, idx);
-               
-               if (NULL != cert_data)
-               {
-            if (CFGetTypeID(cert_data) == CFDataGetTypeID())
-            {
-                CFIndex  aCert_Length = CFDataGetLength(cert_data);
-                const UInt8*  aCert_Data_Ptr = CFDataGetBytePtr(cert_data);
-                
-                if (aCert_Length == cert_length)
-                {
-                    if (!memcmp(cert_data_ptr, aCert_Data_Ptr, cert_length))
-                    {
-                                               result = true;
-                                               break;
-                    }
-                }
-            }
-               }
-    }
-
-errOut:
-       CFReleaseSafe(cert_datas);
-       CFReleaseSafe(otapkiref);
-#endif
-    return result;
-}
-
-
-
-struct SecCertificateSource kSecSystemAnchorSource = {
-       SecSystemAnchorSourceCopyParents,
-       SecSystemAnchorSourceContains
-};
-
-// MARK: -
-// MARK: SecUserAnchorSource
-/********************************************************
- *********** SecUserAnchorSource object ************
- ********************************************************/
-static bool SecUserAnchorSourceCopyParents(
-       SecCertificateSourceRef source, SecCertificateRef certificate,
-        void *context, SecCertificateSourceParents callback) {
-    CFArrayRef parents = SecTrustStoreCopyParents(
-        SecTrustStoreForDomain(kSecTrustStoreDomainUser), certificate, NULL);
-    callback(context, parents);
-    CFReleaseSafe(parents);
-    return true;
-}
-
-static bool SecUserAnchorSourceContains(SecCertificateSourceRef source,
-       SecCertificateRef certificate) {
-    return SecTrustStoreContains(
-        SecTrustStoreForDomain(kSecTrustStoreDomainUser), certificate);
-}
-
-struct SecCertificateSource kSecUserAnchorSource = {
-       SecUserAnchorSourceCopyParents,
-       SecUserAnchorSourceContains
-};
-
-// MARK: -
-// MARK: SecMemoryCertificateSource
-/********************************************************
- *********** SecMemoryCertificateSource object ************
- ********************************************************/
-struct SecMemoryCertificateSource {
-       struct SecCertificateSource base;
-       CFMutableSetRef certificates;
-       CFMutableDictionaryRef subjects;
-};
-typedef struct SecMemoryCertificateSource *SecMemoryCertificateSourceRef;
-
-static bool SecMemoryCertificateSourceCopyParents(
-       SecCertificateSourceRef source, SecCertificateRef certificate,
-        void *context, SecCertificateSourceParents callback) {
-       SecMemoryCertificateSourceRef msource =
-               (SecMemoryCertificateSourceRef)source;
-       CFDataRef normalizedIssuer =
-        SecCertificateGetNormalizedIssuerContent(certificate);
-       CFArrayRef parents = CFDictionaryGetValue(msource->subjects,
-               normalizedIssuer);
-    /* FIXME filter parents by subjectID if certificate has an
-       authorityKeyIdentifier. */
-    secdebug("trust", "%@ parents -> %@", certificate, parents);
-    callback(context, parents);
-    return true;
-}
-
-static bool SecMemoryCertificateSourceContains(SecCertificateSourceRef source,
-       SecCertificateRef certificate) {
-       SecMemoryCertificateSourceRef msource =
-               (SecMemoryCertificateSourceRef)source;
-       return CFSetContainsValue(msource->certificates, certificate);
-}
-
-static void dictAddValueToArrayForKey(CFMutableDictionaryRef dict,
-       const void *key, const void *value) {
-       if (!key)
-               return;
-
-       CFMutableArrayRef values =
-               (CFMutableArrayRef)CFDictionaryGetValue(dict, key);
-       if (!values) {
-               values = CFArrayCreateMutable(kCFAllocatorDefault, 0,
-                       &kCFTypeArrayCallBacks);
-               CFDictionaryAddValue(dict, key, values);
-               CFRelease(values);
-       }
-
-       if (values)
-               CFArrayAppendValue(values, value);
-}
-
-static void SecMemoryCertificateSourceApplierFunction(const void *value,
-       void *context) {
-       SecMemoryCertificateSourceRef msource =
-               (SecMemoryCertificateSourceRef)context;
-       SecCertificateRef certificate = (SecCertificateRef)value;
-
-       /* CFSet's API has no way to combine these 2 operations into 1 sadly. */
-       if (CFSetContainsValue(msource->certificates, certificate))
-               return;
-       CFSetAddValue(msource->certificates, certificate);
-
-       CFDataRef key = SecCertificateGetNormalizedSubjectContent(certificate);
-       dictAddValueToArrayForKey(msource->subjects, key, value);
-}
-
-static SecCertificateSourceRef SecMemoryCertificateSourceCreate(
-       CFArrayRef certificates) {
-       SecMemoryCertificateSourceRef result = (SecMemoryCertificateSourceRef)
-               malloc(sizeof(*result));
-       result->base.copyParents = SecMemoryCertificateSourceCopyParents;
-       result->base.contains = SecMemoryCertificateSourceContains;
-       CFIndex count = CFArrayGetCount(certificates);
-       result->certificates = CFSetCreateMutable(kCFAllocatorDefault, count,
-               &kCFTypeSetCallBacks);
-       result->subjects = CFDictionaryCreateMutable(kCFAllocatorDefault,
-               count, &kCFTypeDictionaryKeyCallBacks,
-               &kCFTypeDictionaryValueCallBacks);
-       CFRange range = { 0, count };
-       CFArrayApplyFunction(certificates, range,
-               SecMemoryCertificateSourceApplierFunction, result);
-
-       return (SecCertificateSourceRef)result;
-}
-
-static void SecMemoryCertificateSourceDestroy(
-       SecCertificateSourceRef source) {
-       SecMemoryCertificateSourceRef msource =
-               (SecMemoryCertificateSourceRef)source;
-       CFRelease(msource->certificates);
-       CFRelease(msource->subjects);
-       free(msource);
-}
-
-// MARK: -
-// MARK: SecCAIssuerCertificateSource
-/********************************************************
- ********* SecCAIssuerCertificateSource object **********
- ********************************************************/
-static bool SecCAIssuerCertificateSourceCopyParents(
-       SecCertificateSourceRef source, SecCertificateRef certificate,
-        void *context, SecCertificateSourceParents callback) {
-    return SecCAIssuerCopyParents(certificate, SecPathBuilderGetQueue((SecPathBuilderRef)context), context, callback);
-}
-
-static bool SecCAIssuerCertificateSourceContains(
-    SecCertificateSourceRef source, SecCertificateRef certificate) {
-       return false;
-}
-
-struct SecCertificateSource kSecCAIssuerSource = {
-       SecCAIssuerCertificateSourceCopyParents,
-       SecCAIssuerCertificateSourceContains
-};
-
-// MARK: -
-// MARK: SecPathBuilder
-/********************************************************
- *************** SecPathBuilder object ******************
- ********************************************************/
-struct SecPathBuilder {
-    dispatch_queue_t queue;
-       SecCertificateSourceRef certificateSource;
-       SecCertificateSourceRef itemCertificateSource;
-       SecCertificateSourceRef anchorSource;
-       CFMutableArrayRef               anchorSources;
-       CFIndex                                 nextParentSource;
-       CFMutableArrayRef               parentSources;
-
-    /* Hashed set of all paths we've constructed so far, used to prevent
-       re-considering a path that was already constructed once before.
-       Note that this is the only container in which certificatePath
-       objects are retained.
-       Every certificatePath being considered is always in allPaths and in at
-       most one of partialPaths, rejectedPaths, candidatePath or extendedPaths
-       all of which don't retain their values.  */
-       CFMutableSetRef                 allPaths;
-
-    /* No trusted anchor, satisfies the linking to intermediates for all
-       policies (unless considerRejected is true). */
-       CFMutableArrayRef               partialPaths;
-    /* No trusted anchor, does not satisfy linking to intermediates for all
-       policies. */
-       CFMutableArrayRef               rejectedPaths;
-    /* Trusted anchor, satisfies the policies so far. */
-       CFMutableArrayRef               candidatePaths;
-
-       CFIndex                                 partialIX;
-
-       CFArrayRef              leafDetails;
-
-       CFIndex                                 rejectScore;
-
-       bool                    considerRejected;
-       bool                    considerPartials;
-       bool                    canAccessNetwork;
-
-    struct OpaqueSecPVC     path;
-       SecCertificatePathRef   bestPath;
-    bool                    bestPathIsEV;
-
-    CFIndex                 activations;
-    bool (*state)(SecPathBuilderRef);
-    SecPathBuilderCompleted completed;
-    const void *context;
-};
-
-/* State functions.  Return false if a async job was scheduled, return
-   true to execute the next state. */
-static bool SecPathBuilderGetNext(SecPathBuilderRef builder);
-static bool SecPathBuilderValidatePath(SecPathBuilderRef builder);
-static bool SecPathBuilderDidValidatePath(SecPathBuilderRef builder);
-static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder);
-static bool SecPathBuilderReportResult(SecPathBuilderRef builder);
-
-/* Forward declarations. */
-static bool SecPathBuilderIsAnchor(SecPathBuilderRef builder,
-       SecCertificateRef certificate);
-
-/* IDEA: policies could be made cabable of replacing incoming anchors and
-   anchorsOnly argument values.  For example some policies require the
-   Apple Inc. CA and not any other anchor.  This can be done in
-   SecPathBuilderLeafCertificateChecks since this only runs once. */
-static void SecPathBuilderLeafCertificateChecks(SecPathBuilderRef builder,
-    SecCertificatePathRef path) {
-    CFMutableDictionaryRef certDetail = CFDictionaryCreateMutable(
-        kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
-        &kCFTypeDictionaryValueCallBacks);
-    builder->leafDetails = CFArrayCreate(kCFAllocatorDefault,
-        (const void **)&certDetail, 1, &kCFTypeArrayCallBacks);
-    CFRelease(certDetail);
-    SecPVCRef pvc = &builder->path;
-    SecPVCSetPath(pvc, path, builder->leafDetails);
-    builder->considerRejected = !SecPVCLeafChecks(pvc);
-}
-
-static void SecPathBuilderInit(SecPathBuilderRef builder,
-       CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly,
-    CFArrayRef policies, CFAbsoluteTime verifyTime, CFArrayRef accessGroups,
-    SecPathBuilderCompleted completed, const void *context) {
-    secdebug("alloc", "%p", builder);
-       CFAllocatorRef allocator = kCFAllocatorDefault;
-
-    builder->queue = dispatch_queue_create("builder", DISPATCH_QUEUE_SERIAL);
-
-       builder->nextParentSource = 1;
-       builder->considerPartials = false;
-    builder->canAccessNetwork = true;
-
-    builder->anchorSources = CFArrayCreateMutable(allocator, 0, NULL);
-    builder->parentSources = CFArrayCreateMutable(allocator, 0, NULL);
-    builder->allPaths = CFSetCreateMutable(allocator, 0,
-               &kCFTypeSetCallBacks);
-
-    builder->partialPaths = CFArrayCreateMutable(allocator, 0, NULL);
-    builder->rejectedPaths = CFArrayCreateMutable(allocator, 0, NULL);
-    builder->candidatePaths = CFArrayCreateMutable(allocator, 0, NULL);
-    builder->partialIX = 0;
-
-    /* Init the policy verification context. */
-    SecPVCInit(&builder->path, builder, policies, verifyTime);
-       builder->bestPath = NULL;
-       builder->bestPathIsEV = false;
-       builder->rejectScore = 0;
-
-       /* Let's create all the certificate sources we might want to use. */
-       builder->certificateSource =
-               SecMemoryCertificateSourceCreate(certificates);
-       if (anchors)
-               builder->anchorSource = SecMemoryCertificateSourceCreate(anchors);
-       else
-               builder->anchorSource = NULL;
-
-       /* We always search certificateSource for parents since it includes the
-          leaf itself and it might be self signed. */
-       CFArrayAppendValue(builder->parentSources, builder->certificateSource);
-       if (builder->anchorSource) {
-               CFArrayAppendValue(builder->anchorSources, builder->anchorSource);
-       }
-    builder->itemCertificateSource = SecItemCertificateSourceCreate(accessGroups);
-       CFArrayAppendValue(builder->parentSources, builder->itemCertificateSource);
-    if (anchorsOnly) {
-        /* Add the system and user anchor certificate db to the search list
-           if we don't explicitly trust them. */
-        CFArrayAppendValue(builder->parentSources, &kSecSystemAnchorSource);
-        CFArrayAppendValue(builder->parentSources, &kSecUserAnchorSource);
-    } else {
-        /* Only add the system and user anchor certificate db to the
-           anchorSources if we are supposed to trust them. */
-        CFArrayAppendValue(builder->anchorSources, &kSecSystemAnchorSource);
-        CFArrayAppendValue(builder->anchorSources, &kSecUserAnchorSource);
-    }
-    CFArrayAppendValue(builder->parentSources, &kSecCAIssuerSource);
-
-       /* Now let's get the leaf cert and turn it into a path. */
-       SecCertificateRef leaf =
-               (SecCertificateRef)CFArrayGetValueAtIndex(certificates, 0);
-       SecCertificatePathRef path = SecCertificatePathCreate(NULL, leaf);
-       CFSetAddValue(builder->allPaths, path);
-       CFArrayAppendValue(builder->partialPaths, path);
-    if (SecPathBuilderIsAnchor(builder, leaf)) {
-        SecCertificatePathSetIsAnchored(path);
-        CFArrayAppendValue(builder->candidatePaths, path);
-    }
-    SecPathBuilderLeafCertificateChecks(builder, path);
-       CFRelease(path);
-
-    builder->activations = 0;
-    builder->state = SecPathBuilderGetNext;
-    builder->completed = completed;
-    builder->context = context;
-}
-
-SecPathBuilderRef SecPathBuilderCreate(CFArrayRef certificates,
-    CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies,
-    CFAbsoluteTime verifyTime, CFArrayRef accessGroups,
-    SecPathBuilderCompleted completed, const void *context) {
-    SecPathBuilderRef builder = malloc(sizeof(*builder));
-    SecPathBuilderInit(builder, certificates, anchors, anchorsOnly,
-        policies, verifyTime, accessGroups, completed, context);
-    return builder;
-}
-
-static void SecPathBuilderDestroy(SecPathBuilderRef builder) {
-    secdebug("alloc", "%p", builder);
-    dispatch_release_null(builder->queue);
-       if (builder->anchorSource)
-               SecMemoryCertificateSourceDestroy(builder->anchorSource);
-       if (builder->certificateSource)
-               SecMemoryCertificateSourceDestroy(builder->certificateSource);
-    if (builder->itemCertificateSource)
-        SecItemCertificateSourceDestroy(builder->itemCertificateSource);
-       CFReleaseSafe(builder->anchorSources);
-       CFReleaseSafe(builder->parentSources);
-       CFReleaseSafe(builder->allPaths);
-       CFReleaseSafe(builder->partialPaths);
-       CFReleaseSafe(builder->rejectedPaths);
-       CFReleaseSafe(builder->candidatePaths);
-       CFReleaseSafe(builder->leafDetails);
-
-    SecPVCDelete(&builder->path);
-}
-
-bool SecPathBuilderCanAccessNetwork(SecPathBuilderRef builder) {
-    return builder->canAccessNetwork;
-}
-
-void SecPathBuilderSetCanAccessNetwork(SecPathBuilderRef builder, bool allow) {
-    if (builder->canAccessNetwork != allow) {
-        builder->canAccessNetwork = allow;
-        if (allow) {
-            secdebug("http", "network access re-enabled by policy");
-            /* re-enabling network_access re-adds kSecCAIssuerSource as
-               a parent source. */
-            CFArrayAppendValue(builder->parentSources, &kSecCAIssuerSource);
-        } else {
-            secdebug("http", "network access disabled by policy");
-            /* disabling network_access removes kSecCAIssuerSource from
-               the list of parent sources. */
-            CFIndex ix = CFArrayGetFirstIndexOfValue(builder->parentSources,
-                CFRangeMake(0, CFArrayGetCount(builder->parentSources)),
-                &kSecCAIssuerSource);
-            if (ix >= 0)
-                CFArrayRemoveValueAtIndex(builder->parentSources, ix);
-        }
-    }
-}
-
-static bool SecPathBuilderIsAnchor(SecPathBuilderRef builder,
-       SecCertificateRef certificate) {
-       /* We always look through all anchor sources. */
-       CFIndex count = CFArrayGetCount(builder->anchorSources);
-       CFIndex ix;
-       for (ix = 0; ix < count; ++ix) {
-               SecCertificateSourceRef source = (SecCertificateSourceRef)
-                       CFArrayGetValueAtIndex(builder->anchorSources, ix);
-               if (SecCertificateSourceContains(source, certificate)) {
-                       return true;
-               }
-       }
-       return false;
-}
-
-/* Return false if path is not a partial, if path was a valid candidate it
-   will have been added to builder->candidatePaths, if path was rejected
-   by the parent certificate checks (because it's expired or some other
-   static chaining check failed) it will have been added to rejectedPaths.
-   Return true path if path is a partial. */
-static bool SecPathBuilderIsPartial(SecPathBuilderRef builder,
-       SecCertificatePathRef path) {
-    SecPVCRef pvc = &builder->path;
-    SecPVCSetPath(pvc, path, NULL);
-
-    if (!builder->considerRejected && !SecPVCParentCertificateChecks(pvc,
-        SecPVCGetCertificateCount(pvc) - 1)) {
-        secdebug("trust", "Found rejected path %@", path);
-               CFArrayAppendValue(builder->rejectedPaths, path);
-               return false;
-       }
-
-       SecPathVerifyStatus vstatus = SecCertificatePathVerify(path);
-       /* Candidate paths with failed signatures are discarded. */
-       if (vstatus == kSecPathVerifyFailed) {
-        secdebug("trust", "Verify failed for path %@", path);
-               return false;
-       }
-
-       if (vstatus == kSecPathVerifySuccess) {
-               /* The signature chain verified sucessfully, now let's find
-                  out if we have an anchor for path.  */
-               if (SecCertificatePathIsAnchored(path)) {
-            secdebug("trust", "Adding candidate %@", path);
-                       CFArrayAppendValue(builder->candidatePaths, path);
-                       return false;
-               }
-       }
-
-       return true;
-}
-
-/* Given the builder, a partial chain partial and the parents array, construct
-   a SecCertificatePath for each parent.  After discarding previously
-   considered paths and paths with cycles, sort out which array each path
-   should go in, if any. */
-static void SecPathBuilderProccessParents(SecPathBuilderRef builder,
-    SecCertificatePathRef partial, CFArrayRef parents) {
-    CFIndex rootIX = SecCertificatePathGetCount(partial) - 1;
-    CFIndex num_parents = parents ? CFArrayGetCount(parents) : 0;
-    CFIndex parentIX;
-    bool is_anchor = SecCertificatePathGetNextSourceIndex(partial) <=
-        CFArrayGetCount(builder->anchorSources);
-    secdebug("trust", "found %" PRIdCFIndex " candidate %s", num_parents,
-             (is_anchor ? "anchors" : "parents"));
-    for (parentIX = 0; parentIX < num_parents; ++parentIX) {
-        SecCertificateRef parent = (SecCertificateRef)
-            CFArrayGetValueAtIndex(parents, parentIX);
-        CFIndex ixOfParent = SecCertificatePathGetIndexOfCertificate(partial,
-            parent);
-        if (ixOfParent != kCFNotFound) {
-            /* partial already contains parent.  Let's not add the same
-               certificate again. */
-            if (ixOfParent == rootIX) {
-                /* parent is equal to the root of the partial, so partial
-                   looks to be self issued. */
-                SecCertificatePathSetSelfIssued(partial);
-            }
-            continue;
-        }
-
-        /* FIXME Add more sanity checks to see that parent really can be
-           a parent of partial_root.  subjectKeyID == authorityKeyID,
-           signature algorithm matches public key algorithm, etc. */
-        SecCertificatePathRef path = SecCertificatePathCreate(partial, parent);
-        if (!path)
-            continue;
-        if (!CFSetContainsValue(builder->allPaths, path)) {
-            CFSetAddValue(builder->allPaths, path);
-            if (is_anchor)
-                SecCertificatePathSetIsAnchored(path);
-            if (SecPathBuilderIsPartial(builder, path)) {
-                /* Insert path right at the current position since it's a new
-                   candiate partial. */
-                CFArrayInsertValueAtIndex(builder->partialPaths,
-                    ++builder->partialIX, path);
-                secdebug("trust", "Adding partial for parent %" PRIdCFIndex "/%" PRIdCFIndex " %@",
-                    parentIX + 1, num_parents, path);
-            }
-            secdebug("trust", "found new path %@", path);
-        }
-        CFRelease(path);
-    }
-}
-
-/* Callback for the SecPathBuilderGetNext() functions call to
-   SecCertificateSourceCopyParents(). */
-static void SecPathBuilderExtendPaths(void *context, CFArrayRef parents) {
-    SecPathBuilderRef builder = (SecPathBuilderRef)context;
-    SecCertificatePathRef partial = (SecCertificatePathRef)
-        CFArrayGetValueAtIndex(builder->partialPaths, builder->partialIX);
-    secdebug("async", "%@ parents %@", partial, parents);
-    SecPathBuilderProccessParents(builder, partial, parents);
-
-    builder->state = SecPathBuilderGetNext;
-    SecPathBuilderStep(builder);
-}
-
-static bool SecPathBuilderGetNext(SecPathBuilderRef builder) {
-    /* If we have any candidates left to go return those first. */
-    if (CFArrayGetCount(builder->candidatePaths)) {
-        SecCertificatePathRef path = (SecCertificatePathRef)
-            CFArrayGetValueAtIndex(builder->candidatePaths, 0);
-        CFArrayRemoveValueAtIndex(builder->candidatePaths, 0);
-        secdebug("trust", "SecPathBuilderGetNext returning candidate %@",
-            path);
-        SecPVCSetPath(&builder->path, path, NULL);
-        builder->state = SecPathBuilderValidatePath;
-        return true;
-    }
-
-    /* If we are considering rejected chains we check each rejected path
-       with SecPathBuilderIsPartial() which checks the signature chain and
-       either drops the path if it's not properly signed, add it as a
-       candidate if it has a trusted anchor, or adds it as a partial
-       to be considered once we finish considering all the rejects. */
-    if (builder->considerRejected) {
-        CFIndex rejectedIX = CFArrayGetCount(builder->rejectedPaths);
-        if (rejectedIX) {
-            rejectedIX--;
-            SecCertificatePathRef path = (SecCertificatePathRef)
-                CFArrayGetValueAtIndex(builder->rejectedPaths, rejectedIX);
-            if (SecPathBuilderIsPartial(builder, path)) {
-                CFArrayInsertValueAtIndex(builder->partialPaths,
-                    ++builder->partialIX, path);
-            }
-            CFArrayRemoveValueAtIndex(builder->rejectedPaths, rejectedIX);
-
-            /* Keep going until we have moved all rejected partials into
-               the regular partials or candidates array. */
-            return true;
-        }
-    }
-
-    /* If builder->partialIX is < 0 we have considered all partial chains
-       this block must ensure partialIX >= 0 if execution continues past
-       it's end. */
-    if (builder->partialIX < 0) {
-        CFIndex num_sources = CFArrayGetCount(builder->parentSources);
-        if (builder->nextParentSource < num_sources) {
-            builder->nextParentSource++;
-            secdebug("trust", "broading search to %" PRIdCFIndex "/%" PRIdCFIndex " sources",
-                builder->nextParentSource, num_sources);
-        } else {
-            /* We've run out of new sources to consider so let's look at
-               rejected chains and after that even consider partials
-               directly.
-               FIXME we might not want to consider partial paths that
-               are subsets of other partial paths, or not consider them
-               at all if we already have an anchored reject. */
-            if (!builder->considerRejected) {
-                builder->considerRejected = true;
-                secdebug("trust", "considering rejected paths");
-            } else if (!builder->considerPartials) {
-                builder->considerPartials = true;
-                secdebug("trust", "considering partials");
-            } else {
-                /* We're all out of options, so we can't produce any more
-                   candidates.  Let's calculate details and return the best
-                   path we found. */
-                builder->state = SecPathBuilderComputeDetails;
-                return true;
-            }
-        }
-        builder->partialIX = CFArrayGetCount(builder->partialPaths) - 1;
-        secdebug("trust", "re-checking %" PRIdCFIndex " partials", builder->partialIX + 1);
-        return true;
-    }
-
-    /* We know builder->partialIX >= 0 if we get here.  */
-    SecCertificatePathRef partial = (SecCertificatePathRef)
-        CFArrayGetValueAtIndex(builder->partialPaths, builder->partialIX);
-    /* Don't try to extend partials anymore once we are in the considerPartials
-       state, since at this point every partial has been extended with every
-       possible parentSource already. */
-    if (builder->considerPartials) {
-        --builder->partialIX;
-        SecPVCSetPath(&builder->path, partial, NULL);
-        builder->state = SecPathBuilderValidatePath;
-        return true;
-    }
-
-    /* Attempt to extend this partial path with another certificate. This
-       should give us a list of potential parents to consider. */
-    secdebug("trust", "looking for parents of partial %" PRIdCFIndex "/%" PRIdCFIndex ": %@",
-        builder->partialIX + 1, CFArrayGetCount(builder->partialPaths),
-        partial);
-
-    /* Attempt to extend partial, leaving all possible extended versions
-       of partial in builder->extendedPaths. */
-       CFIndex sourceIX = SecCertificatePathGetNextSourceIndex(partial);
-    CFIndex num_anchor_sources = CFArrayGetCount(builder->anchorSources);
-    if (sourceIX < num_anchor_sources + builder->nextParentSource) {
-        SecCertificateSourceRef source;
-        if (sourceIX < num_anchor_sources) {
-            source = (SecCertificateSourceRef)
-                CFArrayGetValueAtIndex(builder->anchorSources, sourceIX);
-            secdebug("trust", "searching anchor source %" PRIdCFIndex "/%" PRIdCFIndex, sourceIX + 1,
-                     num_anchor_sources);
-        } else {
-            CFIndex parentIX = sourceIX - num_anchor_sources;
-            source = (SecCertificateSourceRef)
-                CFArrayGetValueAtIndex(builder->parentSources, parentIX);
-            secdebug("trust", "searching parent source %" PRIdCFIndex "/%" PRIdCFIndex, parentIX + 1,
-                     builder->nextParentSource);
-        }
-        SecCertificatePathSetNextSourceIndex(partial, sourceIX + 1);
-        SecCertificateRef root = SecCertificatePathGetRoot(partial);
-               return SecCertificateSourceCopyParents(source, root,
-            builder, SecPathBuilderExtendPaths);
-    } else {
-        --builder->partialIX;
-    }
-
-    return true;
-}
-
-/* One or more of the policies did not accept the candidate path. */
-static void SecPathBuilderReject(SecPathBuilderRef builder) {
-    check(builder);
-    SecPVCRef pvc = &builder->path;
-
-    builder->state = SecPathBuilderGetNext;
-
-    if (builder->bestPathIsEV && !pvc->is_ev) {
-        /* We never replace an ev reject with a non ev reject. */
-        return;
-    }
-
-    CFIndex rejectScore = builder->rejectScore;
-       CFIndex score = SecCertificatePathScore(builder->path.path,
-        SecPVCGetVerifyTime(&builder->path));
-
-    /* The current chain is valid for EV, but revocation checking failed.  We
-       replace any previously accepted or rejected non EV chains with the
-       current one. */
-    if (pvc->is_ev && !builder->bestPathIsEV) {
-        rejectScore = 0;
-    }
-
-#if 0
-    if (pvc->is_ev) {
-        /* Since this means we found a valid ev chain that was revoked,
-           we might want to switch directly to the
-           SecPathBuilderComputeDetails state here if we think further
-           searching for new chains is pointless.  For now we'll keep
-           going, since we could accept an alternate EV certification
-           path that isn't revoked. */
-        builder->state = SecPathBuilderComputeDetails;
-    }
-#endif
-
-    /* Do this last so that changes to rejectScore above will take affect. */
-       if (!builder->bestPath || score > rejectScore) {
-        if (builder->bestPath) {
-            secdebug("reject",
-                "replacing %sev %s score: %ld with %sev reject score: %" PRIdCFIndex " %@",
-                (builder->bestPathIsEV ? "" : "non "),
-                (builder->rejectScore == INTPTR_MAX ? "accept" : "reject"),
-                builder->rejectScore,
-                (pvc->is_ev ? "" : "non "), (long)score, builder->path.path);
-        } else {
-            secdebug("reject", "%sev reject score: %" PRIdCFIndex " %@",
-                (pvc->is_ev ? "" : "non "), score, builder->path.path);
-        }
-
-               builder->rejectScore = score;
-        builder->bestPath = pvc->path;
-        builder->bestPathIsEV = pvc->is_ev;
-       } else {
-        secdebug("reject", "%sev reject score: %" PRIdCFIndex " lower than %" PRIdCFIndex " %@",
-            (pvc->is_ev ? "" : "non "), score, rejectScore, builder->path.path);
-    }
-}
-
-/* All policies accepted the candidate path. */
-static void SecPathBuilderAccept(SecPathBuilderRef builder) {
-    check(builder);
-    SecPVCRef pvc = &builder->path;
-    if (pvc->is_ev || !builder->bestPathIsEV) {
-               secdebug("accept", "replacing %sev accept with %sev %@",
-            (builder->bestPathIsEV ? "" : "non "),
-            (pvc->is_ev ? "" : "non "), builder->path.path);
-        builder->rejectScore = INTPTR_MAX; /* CFIndex is signed long which is INTPTR_T */
-               builder->bestPathIsEV = pvc->is_ev;
-        builder->bestPath = pvc->path;
-    }
-
-    /* If we found the best accept we can we want to switch directly to the
-       SecPathBuilderComputeDetails state here, since we're done. */
-    if (pvc->is_ev || !pvc->optionally_ev)
-        builder->state = SecPathBuilderComputeDetails;
-    else
-        builder->state = SecPathBuilderGetNext;
-}
-
-/* Return true iff a given path satisfies all the specified policies at
-   verifyTime. */
-static bool SecPathBuilderValidatePath(SecPathBuilderRef builder) {
-    SecPVCRef pvc = &builder->path;
-
-    if (builder->considerRejected) {
-        SecPathBuilderReject(builder);
-        return true;
-    }
-
-    builder->state = SecPathBuilderDidValidatePath;
-    return SecPVCPathChecks(pvc);
-}
-
-static bool SecPathBuilderDidValidatePath(SecPathBuilderRef builder) {
-    SecPVCRef pvc = &builder->path;
-    if (pvc->result) {
-        SecPathBuilderAccept(builder);
-    } else {
-        SecPathBuilderReject(builder);
-    }
-    assert(builder->state != SecPathBuilderDidValidatePath);
-    return true;
-}
-
-static bool SecPathBuilderComputeDetails(SecPathBuilderRef builder) {
-    // foobar
-    SecPVCRef pvc = &builder->path;
-#if 0
-    if (!builder->caller_wants_details) {
-        SecPVCSetPath(pvc, builder->bestPath, NULL);
-        pvc->result = builder->rejectScore == INTPTR_MAX;
-        builder->state = SecPathBuilderReportResult;
-        return true;
-    }
-#endif
-    CFIndex ix, pathLength = SecCertificatePathGetCount(builder->bestPath);
-    CFMutableArrayRef details = CFArrayCreateMutableCopy(kCFAllocatorDefault,
-        pathLength, builder->leafDetails);
-    SecPVCSetPath(pvc, builder->bestPath, details);
-    /* Only report on EV stuff if the bestPath actually was valid for EV. */
-    pvc->optionally_ev = builder->bestPathIsEV;
-    pvc->info = CFDictionaryCreateMutable(kCFAllocatorDefault,
-        0, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-    for (ix = 1; ix < pathLength; ++ix) {
-        CFMutableDictionaryRef certDetail = CFDictionaryCreateMutable(
-            kCFAllocatorDefault, 0, &kCFTypeDictionaryKeyCallBacks,
-            &kCFTypeDictionaryValueCallBacks);
-        CFArrayAppendValue(details, certDetail);
-        CFRelease(certDetail);
-        SecPVCParentCertificateChecks(pvc, ix);
-               SecPVCGrayListedKeyChecks(pvc, ix);
-               SecPVCBlackListedKeyChecks(pvc, ix);
-    }
-    builder->state = SecPathBuilderReportResult;
-    bool completed = SecPVCPathChecks(pvc);
-
-    /* Reject the certificate if it was accepted before but we failed it now. */
-    if (builder->rejectScore == INTPTR_MAX && !pvc->result) {
-        builder->rejectScore = 0;
-    }
-
-    return completed;
-}
-
-static bool SecPathBuilderReportResult(SecPathBuilderRef builder) {
-    SecPVCRef pvc = &builder->path;
-    if (pvc->info && pvc->is_ev && pvc->result) {
-        CFDictionarySetValue(pvc->info, kSecTrustInfoExtendedValidationKey,
-            kCFBooleanTrue);
-        SecCertificateRef leaf = SecPVCGetCertificateAtIndex(pvc, 0);
-        CFStringRef leafCompanyName = SecCertificateCopyCompanyName(leaf);
-        if (leafCompanyName) {
-            CFDictionarySetValue(pvc->info, kSecTrustInfoCompanyNameKey,
-                leafCompanyName);
-            CFRelease(leafCompanyName);
-        }
-        if (pvc->rvcs) {
-            CFAbsoluteTime nextUpdate = SecPVCGetEarliestNextUpdate(pvc);
-            if (nextUpdate == 0) {
-                CFDictionarySetValue(pvc->info, kSecTrustInfoRevocationKey,
-                    kCFBooleanFalse);
-            } else {
-                CFDateRef validUntil = CFDateCreate(kCFAllocatorDefault, nextUpdate);
-                CFDictionarySetValue(pvc->info, kSecTrustInfoRevocationValidUntilKey,
-                    validUntil);
-                CFRelease(validUntil);
-                CFDictionarySetValue(pvc->info, kSecTrustInfoRevocationKey,
-                    kCFBooleanTrue);
-            }
-        }
-    }
-
-    /* This will trigger the outer step function to call the completion
-       function. */
-    builder->state = NULL;
-    return false;
-}
-
-/* @function SecPathBuilderStep
-   @summary This is the core of the async engine.
-   @description Return false iff job is complete, true if a network request
-   is pending.
-   builder->state is a function pointer which is to be invoked.
-   If you call this function from within a builder->state invocation it
-   immediately returns true.
-   Otherwise the following steps are repeated endlessly (unless a step returns)
-   builder->state is invoked.  If it returns true and builder->state is still
-   non NULL this proccess is repeated.
-   If a state returns false, SecPathBuilder will return true
-   if builder->state is non NULL.
-   If builder->state is NULL then regardless of what the state function returns
-   the completion callback will be invoked and the builder will be deallocated.
- */
-bool SecPathBuilderStep(SecPathBuilderRef builder) {
-    if (builder->activations) {
-        secdebug("async", "activations: %lu returning true",
-            builder->activations);
-        return true;
-    }
-
-    secdebug("async", "activations: %lu", builder->activations);
-    builder->activations++;
-    while (builder->state && builder->state(builder));
-    --builder->activations;
-
-    if (builder->state) {
-        secdebug("async", "waiting for async reply, exiting");
-        /* A state returned false, it's waiting for network traffic.  Let's
-           return. */
-        return true;
-    }
-
-    if (builder->activations) {
-        /* There is still at least one other running instance of this builder
-           somewhere on the stack, we let that instance take care of sending
-           the client a response. */
-        return false;
-    }
-
-    SecTrustResultType result = (builder->rejectScore == INTPTR_MAX
-        ? kSecTrustResultUnspecified : kSecTrustResultRecoverableTrustFailure);
-    
-    secdebug("trust", "completed: %@ details: %@ result: %d",
-        builder->bestPath, builder->path.details, result);
-    
-    if (builder->completed) {
-        builder->completed(builder->context, builder->bestPath,
-            builder->path.details, builder->path.info, result);
-    }
-
-    /* Finally, destroy the builder and free it. */
-    SecPathBuilderDestroy(builder);
-    free(builder);
-
-    return false;
-}
-
-dispatch_queue_t SecPathBuilderGetQueue(SecPathBuilderRef builder) {
-    return builder->queue;
-}
-
-// MARK: -
-// MARK: SecTrustServer
-/********************************************************
- ****************** SecTrustServer **********************
- ********************************************************/
-
-typedef void (^SecTrustServerEvaluationCompleted)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error);
-
-static void
-SecTrustServerEvaluateCompleted(const void *userData,
-                                SecCertificatePathRef chain, CFArrayRef details, CFDictionaryRef info,
-                                SecTrustResultType result) {
-    SecTrustServerEvaluationCompleted evaluated = (SecTrustServerEvaluationCompleted)userData;
-    evaluated(result, details, info, chain, NULL);
-    Block_release(evaluated);
-}
-
-void
-SecTrustServerEvaluateBlock(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, void (^evaluated)(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error)) {
-    SecTrustServerEvaluationCompleted userData = Block_copy(evaluated);
-    /* Call the actual evaluator function. */
-    SecPathBuilderRef builder = SecPathBuilderCreate(certificates, anchors,
-                                                     anchorsOnly, policies,
-                                                     verifyTime, accessGroups,
-                                                     SecTrustServerEvaluateCompleted, userData);
-    dispatch_async(builder->queue, ^{ SecPathBuilderStep(builder); });
-}
-
-
-// NO_SERVER Shim code only, xpc interface should call SecTrustServerEvaluateBlock() directly
-SecTrustResultType SecTrustServerEvaluate(CFArrayRef certificates, CFArrayRef anchors, bool anchorsOnly, CFArrayRef policies, CFAbsoluteTime verifyTime, __unused CFArrayRef accessGroups, CFArrayRef *pdetails, CFDictionaryRef *pinfo, SecCertificatePathRef *pchain, CFErrorRef *perror) {
-    dispatch_semaphore_t done = dispatch_semaphore_create(0);
-    __block SecTrustResultType result = kSecTrustResultInvalid;
-    SecTrustServerEvaluateBlock(certificates, anchors, anchorsOnly, policies, verifyTime, accessGroups, ^(SecTrustResultType tr, CFArrayRef details, CFDictionaryRef info, SecCertificatePathRef chain, CFErrorRef error) {
-        result = tr;
-        if (tr == kSecTrustResultInvalid) {
-            if (perror) {
-                *perror = error;
-                CFRetainSafe(error);
-            }
-        } else {
-            if (pdetails) {
-                *pdetails = details;
-                CFRetainSafe(details);
-            }
-            if (pinfo) {
-                *pinfo = info;
-                CFRetainSafe(info);
-            }
-            if (pchain) {
-                *pchain = chain;
-                CFRetainSafe(chain);
-            }
-        }
-        dispatch_semaphore_signal(done);
-    });
-    dispatch_semaphore_wait(done, DISPATCH_TIME_FOREVER);
-
-    return result;
-}