]> git.saurik.com Git - apple/security.git/blobdiff - OSX/libsecurity_keychain/Security/TrustRevocation.cpp
Security-57336.10.29.tar.gz
[apple/security.git] / OSX / libsecurity_keychain / Security / TrustRevocation.cpp
diff --git a/OSX/libsecurity_keychain/Security/TrustRevocation.cpp b/OSX/libsecurity_keychain/Security/TrustRevocation.cpp
deleted file mode 100644 (file)
index b30f76e..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-/*
- * Copyright (c) 2002-2004,2011-2012,2014 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@
- */
-
-/*
-* TrustRevocation.cpp - private revocation policy manipulation
-*/
-
-#include <security_keychain/Trust.h>
-#include <security_utilities/cfutilities.h>
-#include <security_utilities/simpleprefs.h>
-#include <CoreFoundation/CFData.h>
-#include "SecBridge.h"
-#include <Security/cssmapplePriv.h>
-#include <Security/oidsalg.h>
-
-/*
- * These may go into an SPI header for the SecTrust object.
- */
-typedef enum {
-       /* this revocation policy disabled */
-       kSecDisabled,
-       /* try, but tolerate inability to complete */
-       kSecBestAttempt,
-       /* require successful revocation check if certificate indicates
-     * the policy is supported */
-       kSecRequireIfPresentInCertificate,
-       /* require for every cert */
-       kSecRequireForAllCertificates
-} SecRevocationPolicyStyle;
-
-using namespace KeychainCore;
-
-/*
- * Given an app-specified array of Policies, determine if at least one of them
- * matches the given policy OID.
- */
-bool Trust::policySpecified(CFArrayRef policies, const CSSM_OID &inOid)
-{
-       if(policies == NULL) {
-               return false;
-       }
-       CFIndex numPolicies = CFArrayGetCount(policies);
-       for(CFIndex dex=0; dex<numPolicies; dex++) {
-               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policies, dex);
-               SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
-               const CssmOid &oid = pol->oid();
-               if(oid == CssmOid::overlay(inOid)) {
-                       return true;
-               }
-       }
-       return false;
-}
-
-/*
- * Given an app-specified array of Policies, determine if at least one of them
- * is an explicit revocation policy.
- */
-bool Trust::revocationPolicySpecified(CFArrayRef policies)
-{
-       if(policies == NULL) {
-               return false;
-       }
-       CFIndex numPolicies = CFArrayGetCount(policies);
-       for(CFIndex dex=0; dex<numPolicies; dex++) {
-               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policies, dex);
-               SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
-               const CssmOid &oid = pol->oid();
-               if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL)) {
-                       return true;
-               }
-               if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP)) {
-                       return true;
-               }
-       }
-       return false;
-}
-
-/*
- * Replace a unified revocation policy instance in the mPolicies array
- * with specific instances of the OCSP and/or CRL policies which the TP
- * module understands. Returns a (possibly) modified copy of the mPolicies
- * array, which the caller is responsible for releasing.
- */
-CFMutableArrayRef Trust::convertRevocationPolicy(
-       uint32 &numAdded,
-       Allocator &alloc)
-{
-       numAdded = 0;
-       if (!mPolicies) {
-               return NULL;
-       }
-       CFIndex numPolicies = CFArrayGetCount(mPolicies);
-       CFAllocatorRef allocator = CFGetAllocator(mPolicies);
-       CFMutableArrayRef policies = CFArrayCreateMutableCopy(allocator, numPolicies, mPolicies);
-       SecPolicyRef revPolicy = NULL;
-       for(CFIndex dex=0; dex<numPolicies; dex++) {
-               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policies, dex);
-               SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
-               const CssmOid &oid = pol->oid();
-               if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION)) {
-                       CFRetain(secPol);
-                       if (revPolicy)
-                               CFRelease(revPolicy);
-                       revPolicy = secPol;
-                       CFArrayRemoveValueAtIndex(policies, dex--);
-                       numPolicies--;
-               }
-       }
-       if(!revPolicy) {
-               CFRelease(policies);
-               return NULL;
-       }
-
-       SecPointer<Policy> ocspPolicy;
-       SecPointer<Policy> crlPolicy;
-
-       // fetch policy value
-       CFOptionFlags policyFlags = kSecRevocationUseAnyAvailableMethod;
-       CSSM_DATA policyValue = { 0, NULL };
-       try {
-               policyValue = Policy::required(revPolicy)->value();
-       }
-       catch (...) {
-               policyValue.Data = NULL;
-       }
-       if (policyValue.Data) {
-               policyFlags = (CFOptionFlags) *((CFOptionFlags*)policyValue.Data);
-       }
-       if (mNetworkPolicy == useNetworkDisabled) {
-               policyFlags = 0 | kSecRevocationNetworkAccessDisabled;
-       }
-       CFRelease(revPolicy); // all done with this policy reference
-
-       if (policyFlags & kSecRevocationOCSPMethod) {
-               /* cook up a new Policy object */
-               ocspPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP));
-               CSSM_APPLE_TP_OCSP_OPT_FLAGS ocspFlags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
-               if (policyFlags & kSecRevocationRequirePositiveResponse) {
-                       ocspFlags |= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT;
-               }
-               CSSM_APPLE_TP_OCSP_OPTIONS opts;
-               memset(&opts, 0, sizeof(opts));
-               opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
-               opts.Flags = ocspFlags;
-
-               /* Policy manages its own copy of this data */
-               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
-               ocspPolicy->value() = optData;
-
-               /* Policies array retains the Policy object */
-               CFArrayAppendValue(policies, ocspPolicy->handle(false));
-               numAdded++;
-       }
-       if (policyFlags & kSecRevocationCRLMethod) {
-               /* cook up a new Policy object */
-               crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
-               CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags = 0;
-               if (policyFlags & kSecRevocationRequirePositiveResponse) {
-                       crlFlags |= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT;
-               }
-               CSSM_APPLE_TP_CRL_OPTIONS opts;
-               memset(&opts, 0, sizeof(opts));
-               opts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
-               opts.CrlFlags = crlFlags;
-
-               /* Policy manages its own copy of this data */
-               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
-               crlPolicy->value() = optData;
-
-               /* Policies array retains the Policy object */
-               CFArrayAppendValue(policies, crlPolicy->handle(false));
-               numAdded++;
-       }
-       return policies;
-}
-
-static SecRevocationPolicyStyle parseRevStyle(CFStringRef val)
-{
-       if(CFEqual(val, kSecRevocationOff)) {
-               return kSecDisabled;
-       }
-       else if(CFEqual(val, kSecRevocationBestAttempt)) {
-               return kSecBestAttempt;
-       }
-       else if(CFEqual(val, kSecRevocationRequireIfPresent)) {
-               return kSecRequireIfPresentInCertificate;
-       }
-       else if(CFEqual(val, kSecRevocationRequireForAll)) {
-               return kSecRequireForAllCertificates;
-       }
-       else {
-               return kSecDisabled;
-       }
-}
-
-CFDictionaryRef Trust::defaultRevocationSettings()
-{
-    /*
-        defaults read ~/Library/Preferences/com.apple.security.revocation
-        {
-            CRLStyle = BestAttempt;
-            CRLSufficientPerCert = 1;
-            OCSPStyle = BestAttempt;
-            OCSPSufficientPerCert = 1;
-            RevocationFirst = OCSP;
-        }
-    */
-    const void *keys[] = {
-               kSecRevocationCrlStyle,
-        kSecRevocationCRLSufficientPerCert,
-        kSecRevocationOcspStyle,
-        kSecRevocationOCSPSufficientPerCert,
-        kSecRevocationWhichFirst
-       };
-       const void *values[] = {
-               kSecRevocationBestAttempt,
-               kCFBooleanTrue,
-               kSecRevocationBestAttempt,
-               kCFBooleanTrue,
-               kSecRevocationOcspFirst
-       };
-
-    return CFDictionaryCreate(kCFAllocatorDefault, keys,
-               values, sizeof(keys) / sizeof(*keys),
-               &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks);
-}
-
-CFMutableArrayRef Trust::addPreferenceRevocationPolicies(
-       bool ocspEnabledOnBestAttempt,
-       bool crlEnabledOnBestAttempt,
-       uint32 &numAdded,
-       Allocator &alloc)
-{
-       numAdded = 0;
-
-       /* any per-user prefs? */
-       Dictionary* pd = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_User, true);
-       if (pd)
-       {
-               if (!pd->dict()) {
-                       delete pd;
-                       pd = NULL;
-               }
-       }
-
-       if(pd == NULL)
-       {
-               pd = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_System, true);
-               if (!pd->dict()) {
-                       delete pd;
-                       pd = NULL;
-               }
-       }
-
-    if(pd == NULL)
-    {
-        CFDictionaryRef tempDict = defaultRevocationSettings();
-        if (tempDict == NULL)
-            return NULL;
-
-        pd = new Dictionary(tempDict);
-        CFRelease(tempDict);
-    }
-
-       auto_ptr<Dictionary> prefsDict(pd);
-
-       bool doOcsp = false;
-       bool doCrl = false;
-       CFStringRef val;
-       SecRevocationPolicyStyle ocspStyle = kSecBestAttempt;
-       SecRevocationPolicyStyle crlStyle = kSecBestAttempt;
-       SecPointer<Policy> ocspPolicy;
-       SecPointer<Policy> crlPolicy;
-
-       /* Are any revocation policies enabled? */
-       val = prefsDict->getStringValue(kSecRevocationOcspStyle);
-       if(val != NULL) {
-               ocspStyle = parseRevStyle(val);
-               if(ocspStyle != kSecDisabled) {
-                       doOcsp = true;
-               }
-               if(ocspStyle == kSecBestAttempt) {
-                       doOcsp = ocspEnabledOnBestAttempt;
-               }
-       }
-       val = prefsDict->getStringValue(kSecRevocationCrlStyle);
-       if(val != NULL) {
-               crlStyle = parseRevStyle(val);
-               if(crlStyle != kSecDisabled) {
-                       doCrl = true;
-               }
-               if(crlStyle == kSecBestAttempt) {
-                       doCrl = crlEnabledOnBestAttempt;
-               }
-       }
-
-       if(!doCrl && !doOcsp) {
-               return NULL;
-       }
-
-       /* which policy first? */
-       bool ocspFirst = true;          // default if both present
-       if(doCrl && doOcsp) {
-               val = prefsDict->getStringValue(kSecRevocationWhichFirst);
-               if((val != NULL) && CFEqual(val, kSecRevocationCrlFirst)) {
-                       ocspFirst = false;
-               }
-       }
-
-       /* Must have at least one caller-specified policy
-        * (if they didn't specify any, it's a no-op evaluation, and if they wanted
-        * revocation checking only, that policy would already be in mPolicies) */
-       if (!mPolicies || !CFArrayGetCount(mPolicies))
-               return NULL;
-
-       /* We're adding something to mPolicies, so make a copy we can work with */
-       CFMutableArrayRef policies = CFArrayCreateMutableCopy(NULL, 0, mPolicies);
-       if(policies == NULL) {
-               throw std::bad_alloc();
-       }
-
-       if(doOcsp) {
-               /* Cook up a new Policy object */
-               ocspPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP));
-               CSSM_APPLE_TP_OCSP_OPTIONS opts;
-               memset(&opts, 0, sizeof(opts));
-               opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
-
-               /* Now fill in the OCSP-related blanks */
-               switch(ocspStyle) {
-                       case kSecDisabled:
-                               assert(0);
-                               break;
-                       case kSecBestAttempt:
-                               /* default, nothing to set */
-                               break;
-                       case kSecRequireIfPresentInCertificate:
-                               opts.Flags |= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT;
-                               break;
-                       case kSecRequireForAllCertificates:
-                               opts.Flags |= CSSM_TP_ACTION_OCSP_REQUIRE_PER_CERT;
-                               break;
-               }
-
-               if(prefsDict->getBoolValue(kSecRevocationOCSPSufficientPerCert)) {
-                       opts.Flags |= CSSM_TP_ACTION_OCSP_SUFFICIENT;
-               }
-
-               val = prefsDict->getStringValue(kSecOCSPLocalResponder);
-               if(val != NULL) {
-                       CFDataRef cfData = CFStringCreateExternalRepresentation(NULL,
-                               val, kCFStringEncodingUTF8, 0);
-                       CFIndex len = CFDataGetLength(cfData);
-                       opts.LocalResponder = (CSSM_DATA_PTR)alloc.malloc(sizeof(CSSM_DATA));
-                       opts.LocalResponder->Data = (uint8 *)alloc.malloc(len);
-                       opts.LocalResponder->Length = len;
-                       memmove(opts.LocalResponder->Data, CFDataGetBytePtr(cfData), len);
-                       CFRelease(cfData);
-               }
-
-               /* Policy manages its own copy of this data */
-               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
-               ocspPolicy->value() = optData;
-               numAdded++;
-       }
-
-       if(doCrl) {
-               /* Cook up a new Policy object */
-               crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
-               CSSM_APPLE_TP_CRL_OPTIONS opts;
-               memset(&opts, 0, sizeof(opts));
-               opts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
-
-               /* Now fill in the CRL-related blanks */
-               opts.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET;      // default true
-               switch(crlStyle) {
-                       case kSecDisabled:
-                               assert(0);
-                               break;
-                       case kSecBestAttempt:
-                               /* default, nothing to set */
-                               break;
-                       case kSecRequireIfPresentInCertificate:
-                               opts.CrlFlags |= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT;
-                               break;
-                       case kSecRequireForAllCertificates:
-                               opts.CrlFlags |= CSSM_TP_ACTION_REQUIRE_CRL_PER_CERT;
-                               break;
-               }
-               if(prefsDict->getBoolValue(kSecRevocationCRLSufficientPerCert)) {
-                       opts.CrlFlags |= CSSM_TP_ACTION_CRL_SUFFICIENT;
-               }
-
-               /* Policy manages its own copy of this data */
-               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
-               crlPolicy->value() = optData;
-               numAdded++;
-       }
-
-       /* append in order */
-       if(doOcsp) {
-               if(doCrl) {
-                       if(ocspFirst) {
-                               /* these SecCFObject go away when the policies array does */
-                               CFArrayAppendValue(policies, ocspPolicy->handle(false));
-                               CFArrayAppendValue(policies, crlPolicy->handle(false));
-                       }
-                       else {
-                               CFArrayAppendValue(policies, crlPolicy->handle(false));
-                               CFArrayAppendValue(policies, ocspPolicy->handle(false));
-                       }
-               }
-               else {
-                       CFArrayAppendValue(policies, ocspPolicy->handle(false));
-               }
-
-       }
-       else if(doCrl) {
-               CFArrayAppendValue(policies, crlPolicy->handle(false));
-       }
-       return policies;
-}
-
-/*
- * Called when we created the last numAdded Policies in the specified Policy array
- * (only frees the policy data associated with the extra policies that we inserted;
- * this does not free the policies array itself.)
- */
-void Trust::freeAddedRevocationPolicyData(
-       CFArrayRef policies,
-       uint32 numAdded,
-       Allocator &alloc)
-{
-       uint32 numPolicies = (uint32)CFArrayGetCount(policies);
-       if(numPolicies < numAdded) {
-               /* should never happen - throw? */
-               assert(0);
-               return;
-       }
-       for(unsigned dex=numPolicies-numAdded; dex<numPolicies; dex++) {
-               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policies, dex);
-               //SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
-               Policy *pol = Policy::required(secPol);
-               const CssmOid &oid = pol->oid();                // required
-               const CssmData &optData = pol->value(); // optional
-
-               if(optData.Data) {
-                       if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL)) {
-                               /* currently no CRL-specific policy data */
-                       }
-                       else if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP)) {
-                               CSSM_APPLE_TP_OCSP_OPTIONS *opts = (CSSM_APPLE_TP_OCSP_OPTIONS *)optData.Data;
-                               if(opts->LocalResponder != NULL) {
-                                  if(opts->LocalResponder->Data != NULL) {
-                                               alloc.free(opts->LocalResponder->Data);
-                                       }
-                                       alloc.free(opts->LocalResponder);
-                               }
-                       }
-                       // managed by Policy alloc.free(optData.Data);
-               }
-       }
-}
-
-/*
- * Comparator function to correctly order revocation policies.
- */
-static CFComparisonResult compareRevocationPolicies(
-       const void *policy1,
-       const void *policy2,
-       void *context)
-{
-       SecPointer<Policy> pol1 = Policy::required(SecPolicyRef(policy1));
-       SecPointer<Policy> pol2 = Policy::required(SecPolicyRef(policy2));
-       const CssmOid &oid1 = pol1->oid();
-       const CssmOid &oid2 = pol2->oid();
-       if(oid1 == oid2) {
-               return kCFCompareEqualTo;
-       }
-       bool ocspFirst = true;
-       if(context != NULL && CFEqual((CFBooleanRef)context, kCFBooleanFalse)) {
-               ocspFirst = false;
-       }
-       const CssmOid lastRevocationOid = (ocspFirst) ?
-               CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL) :
-               CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP);
-       const CssmOid firstRevocationOid = (ocspFirst) ?
-               CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP) :
-               CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL);
-       if(oid1 == lastRevocationOid) {
-               /* should be ordered last, after all other policies */
-               return kCFCompareGreaterThan;
-       }
-       if(oid1 == firstRevocationOid) {
-               /* should be ordered after any policy except lastRevocationOid */
-               if(oid2 == lastRevocationOid) {
-                       return kCFCompareLessThan;
-               }
-               return kCFCompareGreaterThan;
-       }
-       /* normal policy in first position, anything else in second position */
-       return kCFCompareLessThan;
-}
-
-/*
- * This method reorders any revocation policies which may be present
- * in the provided array so they are at the end and evaluated last.
- */
-void Trust::orderRevocationPolicies(
-       CFMutableArrayRef policies)
-{
-       if(!policies || CFGetTypeID(policies) != CFArrayGetTypeID()) {
-               return;
-       }
-       /* check revocation prefs to determine which policy goes first */
-       CFBooleanRef ocspFirst = kCFBooleanTrue;
-       Dictionary* pd = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_User, true);
-       if (pd) {
-               if (!pd->dict()) {
-                       delete pd;
-               } else {
-                       auto_ptr<Dictionary> prefsDict(pd);
-                       CFStringRef val = prefsDict->getStringValue(kSecRevocationWhichFirst);
-                       if((val != NULL) && CFEqual(val, kSecRevocationCrlFirst)) {
-                               ocspFirst = kCFBooleanFalse;
-                       }
-               }
-       }
-#if POLICIES_DEBUG
-       CFShow(policies); // before sort
-       CFArraySortValues(policies, CFRangeMake(0, CFArrayGetCount(policies)), compareRevocationPolicies, (void*)ocspFirst);
-       CFShow(policies); // after sort, to see what changed
-       // check that policy order is what we expect
-       CFIndex numPolicies = CFArrayGetCount(policies);
-       for(CFIndex dex=0; dex<numPolicies; dex++) {
-               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(policies, dex);
-               SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
-               const CssmOid &oid = pol->oid();
-               if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP)) {
-                       CFStringRef s = CFStringCreateWithFormat(NULL, NULL, CFSTR("idx %d = OCSP"), dex);
-                       CFShow(s);
-                       CFRelease(s);
-               }
-               else if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL)) {
-                       CFStringRef s = CFStringCreateWithFormat(NULL, NULL, CFSTR("idx %d = CRL"), dex);
-                       CFShow(s);
-                       CFRelease(s);
-               }
-               else {
-                       CFStringRef s = CFStringCreateWithFormat(NULL, NULL, CFSTR("idx %d = normal"), dex);
-                       CFShow(s);
-                       CFRelease(s);
-               }
-       }
-#else
-       CFArraySortValues(policies, CFRangeMake(0, CFArrayGetCount(policies)), compareRevocationPolicies, (void*)ocspFirst);
-#endif
-}
-
-/*
- * This method returns a copy of the mPolicies array which ensures that
- * revocation checking (preferably OCSP, otherwise CRL) will be attempted.
- *
- * If OCSP is already in the mPolicies array, this makes sure the
- * CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT and CSSM_TP_ACTION_OCSP_SUFFICIENT
- * flags are set. If it's not already in the array, a new policy object is added.
- *
- * If CRL is already in the mPolicies array, this makes sure the
- * CSSM_TP_ACTION_FETCH_CRL_FROM_NET and CSSM_TP_ACTION_CRL_SUFFICIENT flags are
- * set. If it's not already in the array, a new policy object is added.
- *
- * Caller is responsible for releasing the returned policies array.
- */
-CFMutableArrayRef Trust::forceRevocationPolicies(
-       bool ocspEnabled,
-       bool crlEnabled,
-       uint32 &numAdded,
-       Allocator &alloc,
-       bool requirePerCert)
-{
-       SecPointer<Policy> ocspPolicy;
-       SecPointer<Policy> crlPolicy;
-       CSSM_APPLE_TP_OCSP_OPT_FLAGS ocspFlags;
-       CSSM_APPLE_TP_CRL_OPT_FLAGS crlFlags;
-       bool hasOcspPolicy = false;
-       bool hasCrlPolicy = false;
-       numAdded = 0;
-
-       ocspFlags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
-       crlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET | CSSM_TP_ACTION_CRL_SUFFICIENT;
-       if (requirePerCert) {
-               ocspFlags |= CSSM_TP_ACTION_OCSP_REQUIRE_IF_RESP_PRESENT;
-               crlFlags |= CSSM_TP_ACTION_REQUIRE_CRL_IF_PRESENT;
-       }
-
-       CFIndex numPolicies = (mPolicies) ? CFArrayGetCount(mPolicies) : 0;
-       for(CFIndex dex=0; dex<numPolicies; dex++) {
-               SecPolicyRef secPol = (SecPolicyRef)CFArrayGetValueAtIndex(mPolicies, dex);
-               SecPointer<Policy> pol = Policy::required(SecPolicyRef(secPol));
-               const CssmOid &oid = pol->oid();
-               const CssmData &optData = pol->value();
-               if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP)) {
-                       // make sure OCSP options are set correctly
-                       CSSM_APPLE_TP_OCSP_OPTIONS *opts = (CSSM_APPLE_TP_OCSP_OPTIONS *)optData.Data;
-                       if (opts) {
-                               opts->Flags |= ocspFlags;
-                       } else {
-                               CSSM_APPLE_TP_OCSP_OPTIONS newOpts;
-                               memset(&newOpts, 0, sizeof(newOpts));
-                               newOpts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
-                               newOpts.Flags = ocspFlags;
-                               CSSM_DATA optData = {sizeof(newOpts), (uint8 *)&newOpts};
-                               pol->value() = optData;
-                       }
-                       hasOcspPolicy = true;
-               }
-               else if(oid == CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL)) {
-                       // make sure CRL options are set correctly
-                       CSSM_APPLE_TP_CRL_OPTIONS *opts = (CSSM_APPLE_TP_CRL_OPTIONS *)optData.Data;
-                       if (opts) {
-                               opts->CrlFlags |= crlFlags;
-                       } else {
-                               CSSM_APPLE_TP_CRL_OPTIONS newOpts;
-                               memset(&newOpts, 0, sizeof(newOpts));
-                               newOpts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
-                               newOpts.CrlFlags = crlFlags;
-                               CSSM_DATA optData = {sizeof(newOpts), (uint8 *)&newOpts};
-                               pol->value() = optData;
-                       }
-                       hasCrlPolicy = true;
-               }
-       }
-
-       /* We're potentially adding something to mPolicies, so make a copy we can work with */
-       CFMutableArrayRef policies = CFArrayCreateMutableCopy(NULL, 0, mPolicies);
-       if(policies == NULL) {
-               throw std::bad_alloc();
-       }
-
-       if(!hasOcspPolicy && ocspEnabled) {
-               /* Cook up a new Policy object */
-               ocspPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_OCSP));
-               CSSM_APPLE_TP_OCSP_OPTIONS opts;
-               memset(&opts, 0, sizeof(opts));
-               opts.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
-               opts.Flags = ocspFlags;
-
-               /* Check prefs dict for local responder info */
-               Dictionary *prefsDict = NULL;
-               try { /* per-user prefs */
-                       prefsDict = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_User, true);
-                       if (!prefsDict->dict()) {
-                               delete prefsDict;
-                               prefsDict = NULL;
-                       }
-               }
-               catch(...) {}
-               if(prefsDict == NULL) {
-                       try { /* system prefs */
-                               prefsDict = Dictionary::CreateDictionary(kSecRevocationDomain, Dictionary::US_System, true);
-                               if (!prefsDict->dict()) {
-                                       delete prefsDict;
-                                       prefsDict = NULL;
-                               }
-                       }
-                       catch(...) {}
-               }
-               if(prefsDict != NULL) {
-                       CFStringRef val = prefsDict->getStringValue(kSecOCSPLocalResponder);
-                       if(val != NULL) {
-                               CFDataRef cfData = CFStringCreateExternalRepresentation(NULL,
-                                       val, kCFStringEncodingUTF8, 0);
-                               CFIndex len = CFDataGetLength(cfData);
-                               opts.LocalResponder = (CSSM_DATA_PTR)alloc.malloc(sizeof(CSSM_DATA));
-                               opts.LocalResponder->Data = (uint8 *)alloc.malloc(len);
-                               opts.LocalResponder->Length = len;
-                               memmove(opts.LocalResponder->Data, CFDataGetBytePtr(cfData), len);
-                               CFRelease(cfData);
-                       }
-               }
-
-               /* Policy manages its own copy of the options data */
-               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
-               ocspPolicy->value() = optData;
-
-               /* Policies array retains the Policy object */
-               CFArrayAppendValue(policies, ocspPolicy->handle(false));
-               numAdded++;
-
-               if(prefsDict != NULL)
-                       delete prefsDict;
-       }
-
-       if(!hasCrlPolicy && crlEnabled) {
-               /* Cook up a new Policy object */
-               crlPolicy = new Policy(mTP, CssmOid::overlay(CSSMOID_APPLE_TP_REVOCATION_CRL));
-               CSSM_APPLE_TP_CRL_OPTIONS opts;
-               memset(&opts, 0, sizeof(opts));
-               opts.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
-               opts.CrlFlags = crlFlags;
-
-               /* Policy manages its own copy of this data */
-               CSSM_DATA optData = {sizeof(opts), (uint8 *)&opts};
-               crlPolicy->value() = optData;
-
-               /* Policies array retains the Policy object */
-               CFArrayAppendValue(policies, crlPolicy->handle(false));
-               numAdded++;
-       }
-
-       return policies;
-}