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/cert/x509_util_mac.h" | 5 #include "net/cert/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 { |
11 | 11 |
12 namespace x509_util { | 12 namespace x509_util { |
13 | 13 |
14 namespace { | 14 namespace { |
15 | 15 |
16 // Creates a SecPolicyRef for the given OID, with optional value. | 16 // Creates a SecPolicyRef for the given OID, with optional value. |
17 OSStatus CreatePolicy(const CSSM_OID* policy_oid, | 17 OSStatus CreatePolicy(const CSSM_OID* policy_oid, |
18 void* option_data, | 18 void* option_data, |
19 size_t option_length, | 19 size_t option_length, |
20 SecPolicyRef* policy) { | 20 SecPolicyRef* policy) { |
21 SecPolicySearchRef search; | 21 SecPolicySearchRef search; |
22 OSStatus err = SecPolicySearchCreate(CSSM_CERT_X_509v3, policy_oid, NULL, | 22 OSStatus err = |
23 &search); | 23 SecPolicySearchCreate(CSSM_CERT_X_509v3, policy_oid, NULL, &search); |
24 if (err) | 24 if (err) |
25 return err; | 25 return err; |
26 err = SecPolicySearchCopyNext(search, policy); | 26 err = SecPolicySearchCopyNext(search, policy); |
27 CFRelease(search); | 27 CFRelease(search); |
28 if (err) | 28 if (err) |
29 return err; | 29 return err; |
30 | 30 |
31 if (option_data) { | 31 if (option_data) { |
32 CSSM_DATA options_data = { | 32 CSSM_DATA options_data = {option_length, |
33 option_length, | 33 reinterpret_cast<uint8_t*>(option_data)}; |
34 reinterpret_cast<uint8_t*>(option_data) | |
35 }; | |
36 err = SecPolicySetValue(*policy, &options_data); | 34 err = SecPolicySetValue(*policy, &options_data); |
37 if (err) { | 35 if (err) { |
38 CFRelease(*policy); | 36 CFRelease(*policy); |
39 return err; | 37 return err; |
40 } | 38 } |
41 } | 39 } |
42 return noErr; | 40 return noErr; |
43 } | 41 } |
44 | 42 |
45 } // namespace | 43 } // namespace |
46 | 44 |
47 | |
48 OSStatus CreateSSLClientPolicy(SecPolicyRef* policy) { | 45 OSStatus CreateSSLClientPolicy(SecPolicyRef* policy) { |
49 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; | 46 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; |
50 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); | 47 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); |
51 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; | 48 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; |
52 tp_ssl_options.Flags |= CSSM_APPLE_TP_SSL_CLIENT; | 49 tp_ssl_options.Flags |= CSSM_APPLE_TP_SSL_CLIENT; |
53 | 50 |
54 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, | 51 return CreatePolicy( |
55 sizeof(tp_ssl_options), policy); | 52 &CSSMOID_APPLE_TP_SSL, &tp_ssl_options, sizeof(tp_ssl_options), policy); |
56 } | 53 } |
57 | 54 |
58 OSStatus CreateSSLServerPolicy(const std::string& hostname, | 55 OSStatus CreateSSLServerPolicy(const std::string& hostname, |
59 SecPolicyRef* policy) { | 56 SecPolicyRef* policy) { |
60 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; | 57 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options; |
61 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); | 58 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options)); |
62 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; | 59 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION; |
63 if (!hostname.empty()) { | 60 if (!hostname.empty()) { |
64 tp_ssl_options.ServerName = hostname.data(); | 61 tp_ssl_options.ServerName = hostname.data(); |
65 tp_ssl_options.ServerNameLen = hostname.size(); | 62 tp_ssl_options.ServerNameLen = hostname.size(); |
66 } | 63 } |
67 | 64 |
68 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, | 65 return CreatePolicy( |
69 sizeof(tp_ssl_options), policy); | 66 &CSSMOID_APPLE_TP_SSL, &tp_ssl_options, sizeof(tp_ssl_options), policy); |
70 } | 67 } |
71 | 68 |
72 OSStatus CreateBasicX509Policy(SecPolicyRef* policy) { | 69 OSStatus CreateBasicX509Policy(SecPolicyRef* policy) { |
73 return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy); | 70 return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy); |
74 } | 71 } |
75 | 72 |
76 OSStatus CreateRevocationPolicies(bool enable_revocation_checking, | 73 OSStatus CreateRevocationPolicies(bool enable_revocation_checking, |
77 bool enable_ev_checking, | 74 bool enable_ev_checking, |
78 CFMutableArrayRef policies) { | 75 CFMutableArrayRef policies) { |
79 OSStatus status = noErr; | 76 OSStatus status = noErr; |
(...skipping 12 matching lines...) Expand all Loading... |
92 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); | 89 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); |
93 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; | 90 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; |
94 // Only allow network CRL fetches if the caller explicitly requests | 91 // 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 | 92 // 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 | 93 // will set force this flag on according to system policies, so |
97 // online revocation checks cannot be completely disabled. | 94 // online revocation checks cannot be completely disabled. |
98 if (enable_revocation_checking) | 95 if (enable_revocation_checking) |
99 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; | 96 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; |
100 | 97 |
101 SecPolicyRef crl_policy; | 98 SecPolicyRef crl_policy; |
102 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, | 99 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, |
103 sizeof(tp_crl_options), &crl_policy); | 100 &tp_crl_options, |
| 101 sizeof(tp_crl_options), |
| 102 &crl_policy); |
104 if (status) | 103 if (status) |
105 return status; | 104 return status; |
106 CFArrayAppendValue(policies, crl_policy); | 105 CFArrayAppendValue(policies, crl_policy); |
107 CFRelease(crl_policy); | 106 CFRelease(crl_policy); |
108 } | 107 } |
109 | 108 |
110 // If revocation checking is explicitly enabled, then add an OCSP policy | 109 // If revocation checking is explicitly enabled, then add an OCSP policy |
111 // and allow network access. If both revocation checking and EV checking | 110 // and allow network access. If both revocation checking and EV checking |
112 // are disabled, then the added OCSP policy will be prevented from | 111 // 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 | 112 // accessing the network. This is done because the TP will force an OCSP |
(...skipping 16 matching lines...) Expand all Loading... |
130 // Effectively disable OCSP checking by making it impossible to get an | 129 // Effectively disable OCSP checking by making it impossible to get an |
131 // OCSP response. Even if the Apple TP forces OCSP, no checking will | 130 // 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 | 131 // 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 | 132 // that OCSP was unavailable, but this will be handled and suppressed in |
134 // X509Certificate::Verify(). | 133 // X509Certificate::Verify(). |
135 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | | 134 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | |
136 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; | 135 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; |
137 } | 136 } |
138 | 137 |
139 SecPolicyRef ocsp_policy; | 138 SecPolicyRef ocsp_policy; |
140 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, | 139 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, |
141 sizeof(tp_ocsp_options), &ocsp_policy); | 140 &tp_ocsp_options, |
| 141 sizeof(tp_ocsp_options), |
| 142 &ocsp_policy); |
142 if (status) | 143 if (status) |
143 return status; | 144 return status; |
144 CFArrayAppendValue(policies, ocsp_policy); | 145 CFArrayAppendValue(policies, ocsp_policy); |
145 CFRelease(ocsp_policy); | 146 CFRelease(ocsp_policy); |
146 } | 147 } |
147 | 148 |
148 return status; | 149 return status; |
149 } | 150 } |
150 | 151 |
151 CSSMFieldValue::CSSMFieldValue() | 152 CSSMFieldValue::CSSMFieldValue() |
152 : cl_handle_(CSSM_INVALID_HANDLE), | 153 : cl_handle_(CSSM_INVALID_HANDLE), oid_(NULL), field_(NULL) { |
153 oid_(NULL), | |
154 field_(NULL) { | |
155 } | 154 } |
156 CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, | 155 CSSMFieldValue::CSSMFieldValue(CSSM_CL_HANDLE cl_handle, |
157 const CSSM_OID* oid, | 156 const CSSM_OID* oid, |
158 CSSM_DATA_PTR field) | 157 CSSM_DATA_PTR field) |
159 : cl_handle_(cl_handle), | 158 : cl_handle_(cl_handle), |
160 oid_(const_cast<CSSM_OID_PTR>(oid)), | 159 oid_(const_cast<CSSM_OID_PTR>(oid)), |
161 field_(field) { | 160 field_(field) { |
162 } | 161 } |
163 | 162 |
164 CSSMFieldValue::~CSSMFieldValue() { | 163 CSSMFieldValue::~CSSMFieldValue() { |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
205 | 204 |
206 OSStatus CSSMCachedCertificate::GetField(const CSSM_OID* field_oid, | 205 OSStatus CSSMCachedCertificate::GetField(const CSSM_OID* field_oid, |
207 CSSMFieldValue* field) const { | 206 CSSMFieldValue* field) const { |
208 DCHECK(cl_handle_); | 207 DCHECK(cl_handle_); |
209 DCHECK(cached_cert_handle_); | 208 DCHECK(cached_cert_handle_); |
210 | 209 |
211 CSSM_OID_PTR oid = const_cast<CSSM_OID_PTR>(field_oid); | 210 CSSM_OID_PTR oid = const_cast<CSSM_OID_PTR>(field_oid); |
212 CSSM_DATA_PTR field_ptr = NULL; | 211 CSSM_DATA_PTR field_ptr = NULL; |
213 CSSM_HANDLE results_handle = CSSM_INVALID_HANDLE; | 212 CSSM_HANDLE results_handle = CSSM_INVALID_HANDLE; |
214 uint32 field_value_count = 0; | 213 uint32 field_value_count = 0; |
215 CSSM_RETURN status = CSSM_CL_CertGetFirstCachedFieldValue( | 214 CSSM_RETURN status = CSSM_CL_CertGetFirstCachedFieldValue(cl_handle_, |
216 cl_handle_, cached_cert_handle_, oid, &results_handle, | 215 cached_cert_handle_, |
217 &field_value_count, &field_ptr); | 216 oid, |
| 217 &results_handle, |
| 218 &field_value_count, |
| 219 &field_ptr); |
218 if (status) | 220 if (status) |
219 return status; | 221 return status; |
220 | 222 |
221 // Note: |field_value_count| may be > 1, indicating that more than one | 223 // Note: |field_value_count| may be > 1, indicating that more than one |
222 // value is present. This may happen with extensions, but for current | 224 // value is present. This may happen with extensions, but for current |
223 // usages, only the first value is returned. | 225 // usages, only the first value is returned. |
224 CSSM_CL_CertAbortQuery(cl_handle_, results_handle); | 226 CSSM_CL_CertAbortQuery(cl_handle_, results_handle); |
225 field->Reset(cl_handle_, oid, field_ptr); | 227 field->Reset(cl_handle_, oid, field_ptr); |
226 return CSSM_OK; | 228 return CSSM_OK; |
227 } | 229 } |
228 | 230 |
229 } // namespace x509_util | 231 } // namespace x509_util |
230 | 232 |
231 } // namespace net | 233 } // namespace net |
OLD | NEW |