OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/x509_util_mac.h" | 5 #include "net/base/x509_util_mac.h" |
6 | 6 |
7 #include "base/logging.h" | 7 #include "base/logging.h" |
8 #include "third_party/apple_apsl/cssmapplePriv.h" | 8 #include "third_party/apple_apsl/cssmapplePriv.h" |
9 | 9 |
10 namespace net { | 10 namespace net { |
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
67 | 67 |
68 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, | 68 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, |
69 sizeof(tp_ssl_options), policy); | 69 sizeof(tp_ssl_options), policy); |
70 } | 70 } |
71 | 71 |
72 OSStatus CreateBasicX509Policy(SecPolicyRef* policy) { | 72 OSStatus CreateBasicX509Policy(SecPolicyRef* policy) { |
73 return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy); | 73 return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy); |
74 } | 74 } |
75 | 75 |
76 OSStatus CreateRevocationPolicies(bool enable_revocation_checking, | 76 OSStatus CreateRevocationPolicies(bool enable_revocation_checking, |
| 77 bool enable_ev_checking, |
77 CFMutableArrayRef policies) { | 78 CFMutableArrayRef policies) { |
78 // In order to actually disable revocation checking, the SecTrustRef must | 79 OSStatus status = noErr; |
79 // have at least one revocation policy associated with it. If none are | |
80 // present, the Apple TP will add policies according to the system | |
81 // preferences, which will enable revocation checking even if the caller | |
82 // explicitly disabled it. An OCSP policy is used, rather than a CRL policy, | |
83 // because the Apple TP will force an OCSP policy to be present and enabled | |
84 // if it believes the certificate may chain to an EV root. By explicitly | |
85 // disabling network and OCSP cache access, then even if the Apple TP | |
86 // enables OCSP checking, no revocation checking will actually succeed. | |
87 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; | |
88 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); | |
89 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; | |
90 | 80 |
91 if (enable_revocation_checking) { | 81 // In order to bypass the system revocation checking settings, the |
92 // The default for the OCSP policy is to fetch responses via the network, | 82 // SecTrustRef must have at least one revocation policy associated with it. |
93 // unlike the CRL policy default. The policy is further modified to | 83 // Since it is not known prior to verification whether the Apple TP will |
94 // prefer OCSP over CRLs, if both are specified on the certificate. This | 84 // consider a certificate as an EV candidate, the default policy used is a |
95 // is because an OCSP response is both sufficient and typically | 85 // CRL policy, since it does not communicate over the network. |
96 // significantly smaller than the CRL counterpart. | 86 // If the TP believes the leaf is an EV cert, it will explicitly add an |
97 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; | 87 // OCSP policy to perform the online checking, and if it doesn't believe |
98 } else { | 88 // that the leaf is EV, then the default CRL policy will effectively no-op. |
99 // Effectively disable OCSP checking by making it impossible to get an | 89 // This behaviour is used to implement EV-only revocation checking. |
100 // OCSP response. Even if the Apple TP forces OCSP, no checking will | 90 if (enable_ev_checking || enable_revocation_checking) { |
101 // be able to succeed. If this happens, the Apple TP will report an error | |
102 // that OCSP was unavailable, but this will be handled and suppressed in | |
103 // X509Certificate::Verify(). | |
104 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | | |
105 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; | |
106 } | |
107 | |
108 SecPolicyRef ocsp_policy; | |
109 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, | |
110 &tp_ocsp_options, sizeof(tp_ocsp_options), | |
111 &ocsp_policy); | |
112 if (status) | |
113 return status; | |
114 CFArrayAppendValue(policies, ocsp_policy); | |
115 CFRelease(ocsp_policy); | |
116 | |
117 if (enable_revocation_checking) { | |
118 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; | 91 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; |
119 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); | 92 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); |
120 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; | 93 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; |
121 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; | 94 // Only allow network CRL fetches if the caller explicitly requests |
| 95 // online revocation checking. Note that, as of OS X 10.7.2, the system |
| 96 // will set force this flag on according to system policies, so |
| 97 // online revocation checks cannot be completely disabled. |
| 98 if (enable_revocation_checking) |
| 99 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; |
122 | 100 |
123 SecPolicyRef crl_policy; | 101 SecPolicyRef crl_policy; |
124 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, | 102 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, |
125 sizeof(tp_crl_options), &crl_policy); | 103 sizeof(tp_crl_options), &crl_policy); |
126 if (status) | 104 if (status) |
127 return status; | 105 return status; |
128 CFArrayAppendValue(policies, crl_policy); | 106 CFArrayAppendValue(policies, crl_policy); |
129 CFRelease(crl_policy); | 107 CFRelease(crl_policy); |
130 } | 108 } |
131 | 109 |
| 110 // If revocation checking is explicitly enabled, then add an OCSP policy |
| 111 // and allow network access. If both revocation checking and EV checking |
| 112 // are disabled, then the added OCSP policy will be prevented from |
| 113 // accessing the network. This is done because the TP will force an OCSP |
| 114 // policy to be present when it believes the certificate is EV. If network |
| 115 // fetching was not explicitly disabled, then it would be as if |
| 116 // enable_ev_checking was always set to true. |
| 117 if (enable_revocation_checking || !enable_ev_checking) { |
| 118 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; |
| 119 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); |
| 120 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; |
| 121 |
| 122 if (enable_revocation_checking) { |
| 123 // The default for the OCSP policy is to fetch responses via the network, |
| 124 // unlike the CRL policy default. The policy is further modified to |
| 125 // prefer OCSP over CRLs, if both are specified on the certificate. This |
| 126 // is because an OCSP response is both sufficient and typically |
| 127 // significantly smaller than the CRL counterpart. |
| 128 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; |
| 129 } else { |
| 130 // Effectively disable OCSP checking by making it impossible to get an |
| 131 // OCSP response. Even if the Apple TP forces OCSP, no checking will |
| 132 // be able to succeed. If this happens, the Apple TP will report an error |
| 133 // that OCSP was unavailable, but this will be handled and suppressed in |
| 134 // X509Certificate::Verify(). |
| 135 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | |
| 136 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; |
| 137 } |
| 138 |
| 139 SecPolicyRef ocsp_policy; |
| 140 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, |
| 141 sizeof(tp_ocsp_options), &ocsp_policy); |
| 142 if (status) |
| 143 return status; |
| 144 CFArrayAppendValue(policies, ocsp_policy); |
| 145 CFRelease(ocsp_policy); |
| 146 } |
| 147 |
132 return status; | 148 return status; |
133 } | 149 } |
134 | 150 |
135 CSSMFieldValue::CSSMFieldValue() | 151 CSSMFieldValue::CSSMFieldValue() |
136 : cl_handle_(CSSM_INVALID_HANDLE), | 152 : cl_handle_(CSSM_INVALID_HANDLE), |
137 oid_(NULL), | 153 oid_(NULL), |
138 field_(NULL) { | 154 field_(NULL) { |
139 } | 155 } |
140 CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, | 156 CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, |
141 const CSSM_OID* oid, | 157 const CSSM_OID* oid, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
206 // value is present. This may happen with extensions, but for current | 222 // value is present. This may happen with extensions, but for current |
207 // usages, only the first value is returned. | 223 // usages, only the first value is returned. |
208 CSSM_CL_CertAbortQuery(cl_handle_, results_handle); | 224 CSSM_CL_CertAbortQuery(cl_handle_, results_handle); |
209 field->Reset(cl_handle_, oid, field_ptr); | 225 field->Reset(cl_handle_, oid, field_ptr); |
210 return CSSM_OK; | 226 return CSSM_OK; |
211 } | 227 } |
212 | 228 |
213 } // namespace x509_util | 229 } // namespace x509_util |
214 | 230 |
215 } // namespace net | 231 } // namespace net |
OLD | NEW |