Index: net/base/x509_util_mac.cc |
diff --git a/net/base/x509_util_mac.cc b/net/base/x509_util_mac.cc |
index d06009e08f022e519be4591103ed716eca0c113a..a53b5ac37ab70712d496665a5df595babb860eb2 100644 |
--- a/net/base/x509_util_mac.cc |
+++ b/net/base/x509_util_mac.cc |
@@ -74,51 +74,29 @@ OSStatus CreateBasicX509Policy(SecPolicyRef* policy) { |
} |
OSStatus CreateRevocationPolicies(bool enable_revocation_checking, |
+ bool enable_ev_checking, |
CFMutableArrayRef policies) { |
- // In order to actually disable revocation checking, the SecTrustRef must |
- // have at least one revocation policy associated with it. If none are |
- // present, the Apple TP will add policies according to the system |
- // preferences, which will enable revocation checking even if the caller |
- // explicitly disabled it. An OCSP policy is used, rather than a CRL policy, |
- // because the Apple TP will force an OCSP policy to be present and enabled |
- // if it believes the certificate may chain to an EV root. By explicitly |
- // disabling network and OCSP cache access, then even if the Apple TP |
- // enables OCSP checking, no revocation checking will actually succeed. |
- CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; |
- memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); |
- tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; |
- |
- if (enable_revocation_checking) { |
- // The default for the OCSP policy is to fetch responses via the network, |
- // unlike the CRL policy default. The policy is further modified to |
- // prefer OCSP over CRLs, if both are specified on the certificate. This |
- // is because an OCSP response is both sufficient and typically |
- // significantly smaller than the CRL counterpart. |
- tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; |
- } else { |
- // Effectively disable OCSP checking by making it impossible to get an |
- // OCSP response. Even if the Apple TP forces OCSP, no checking will |
- // be able to succeed. If this happens, the Apple TP will report an error |
- // that OCSP was unavailable, but this will be handled and suppressed in |
- // X509Certificate::Verify(). |
- tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | |
- CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; |
- } |
- |
- SecPolicyRef ocsp_policy; |
- OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, |
- &tp_ocsp_options, sizeof(tp_ocsp_options), |
- &ocsp_policy); |
- if (status) |
- return status; |
- CFArrayAppendValue(policies, ocsp_policy); |
- CFRelease(ocsp_policy); |
- |
- if (enable_revocation_checking) { |
+ OSStatus status = noErr; |
+ |
+ // In order to bypass the system revocation checking settings, the |
+ // SecTrustRef must have at least one revocation policy associated with it. |
+ // Since it is not known prior to verification whether the Apple TP will |
+ // consider a certificate as an EV candidate, the default policy used is a |
+ // CRL policy, since it does not communicate over the network. |
+ // If the TP believes the leaf is an EV cert, it will explicitly add an |
+ // OCSP policy to perform the online checking, and if it doesn't believe |
+ // that the leaf is EV, then the default CRL policy will effectively no-op. |
+ // This behaviour is used to implement EV-only revocation checking. |
+ if (enable_ev_checking || enable_revocation_checking) { |
CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; |
memset(&tp_crl_options, 0, sizeof(tp_crl_options)); |
tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; |
- tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; |
+ // Only allow network CRL fetches if the caller explicitly requests |
+ // online revocation checking. Note that, as of OS X 10.7.2, the system |
+ // will set force this flag on according to system policies, so |
+ // online revocation checks cannot be completely disabled. |
+ if (enable_revocation_checking) |
+ tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; |
SecPolicyRef crl_policy; |
status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, |
@@ -129,6 +107,44 @@ OSStatus CreateRevocationPolicies(bool enable_revocation_checking, |
CFRelease(crl_policy); |
} |
+ // If revocation checking is explicitly enabled, then add an OCSP policy |
+ // and allow network access. If both revocation checking and EV checking |
+ // are disabled, then the added OCSP policy will be prevented from |
+ // accessing the network. This is done because the TP will force an OCSP |
+ // policy to be present when it believes the certificate is EV. If network |
+ // fetching was not explicitly disabled, then it would be as if |
+ // enable_ev_checking was always set to true. |
+ if (enable_revocation_checking || !enable_ev_checking) { |
+ CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; |
+ memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); |
+ tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; |
+ |
+ if (enable_revocation_checking) { |
+ // The default for the OCSP policy is to fetch responses via the network, |
+ // unlike the CRL policy default. The policy is further modified to |
+ // prefer OCSP over CRLs, if both are specified on the certificate. This |
+ // is because an OCSP response is both sufficient and typically |
+ // significantly smaller than the CRL counterpart. |
+ tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; |
+ } else { |
+ // Effectively disable OCSP checking by making it impossible to get an |
+ // OCSP response. Even if the Apple TP forces OCSP, no checking will |
+ // be able to succeed. If this happens, the Apple TP will report an error |
+ // that OCSP was unavailable, but this will be handled and suppressed in |
+ // X509Certificate::Verify(). |
+ tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | |
+ CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; |
+ } |
+ |
+ SecPolicyRef ocsp_policy; |
+ status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, |
+ sizeof(tp_ocsp_options), &ocsp_policy); |
+ if (status) |
+ return status; |
+ CFArrayAppendValue(policies, ocsp_policy); |
+ CFRelease(ocsp_policy); |
+ } |
+ |
return status; |
} |