Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(594)

Side by Side Diff: net/base/x509_certificate_mac.cc

Issue 7082031: Don't block the UI thread for OCSP/CRLs when viewing a cert on Mac. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 9 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« net/base/x509_certificate.h ('K') | « net/base/x509_certificate.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_certificate.h" 5 #include "net/base/x509_certificate.h"
6 6
7 #include <CommonCrypto/CommonDigest.h> 7 #include <CommonCrypto/CommonDigest.h>
8 #include <CoreServices/CoreServices.h> 8 #include <CoreServices/CoreServices.h>
9 #include <Security/Security.h> 9 #include <Security/Security.h>
10 #include <time.h> 10 #include <time.h>
(...skipping 286 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 OSStatus CreateTrustPolicies(const std::string& hostname, int flags, 297 OSStatus CreateTrustPolicies(const std::string& hostname, int flags,
298 ScopedCFTypeRef<CFArrayRef>* policies) { 298 ScopedCFTypeRef<CFArrayRef>* policies) {
299 ScopedCFTypeRef<CFMutableArrayRef> local_policies( 299 ScopedCFTypeRef<CFMutableArrayRef> local_policies(
300 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); 300 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks));
301 if (!local_policies) 301 if (!local_policies)
302 return memFullErr; 302 return memFullErr;
303 303
304 // Create an SSL SecPolicyRef, and configure it to perform hostname 304 // Create an SSL SecPolicyRef, and configure it to perform hostname
305 // validation. The hostname check does 99% of what we want, with the 305 // validation. The hostname check does 99% of what we want, with the
306 // exception of dotted IPv4 addreses, which we handle ourselves below. 306 // exception of dotted IPv4 addreses, which we handle ourselves below.
307 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = {
308 CSSM_APPLE_TP_SSL_OPTS_VERSION,
309 hostname.size(),
310 hostname.data(),
311 0
312 };
313 SecPolicyRef ssl_policy; 307 SecPolicyRef ssl_policy;
314 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, 308 OSStatus status = X509Certificate::CreateSSLPolicy(true, hostname,
315 sizeof(tp_ssl_options), &ssl_policy); 309 &ssl_policy);
316 if (status) 310 if (status)
317 return status; 311 return status;
318 CFArrayAppendValue(local_policies, ssl_policy); 312 CFArrayAppendValue(local_policies, ssl_policy);
319 CFRelease(ssl_policy); 313 CFRelease(ssl_policy);
320 314
321 // Manually add revocation policies. In order to actually disable revocation 315 // Explicitly add revocation policies, in order to override system checks.
wtc 2011/06/03 01:58:04 Nit: it's not clear what "system checks" means.
322 // checking, the SecTrustRef must have at least one revocation policy 316 status = X509Certificate::CreateRevocationPolicies(
323 // associated with it. If none are present, the Apple TP will add policies 317 (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED),
324 // according to the system preferences, which will enable revocation 318 local_policies);
wtc 2011/06/03 01:58:04 Add if (status) return status;
325 // checking even if the caller explicitly disabled it. An OCSP policy is
326 // used, rather than a CRL policy, because the Apple TP will force an OCSP
327 // policy to be present and enabled if it believes the certificate may chain
328 // to an EV root. By explicitly disabling network and OCSP cache access,
329 // then even if the Apple TP enables OCSP checking, no revocation checking
330 // will actually succeed.
331 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options;
332 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options));
333 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
334
335 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) {
336 // The default for the OCSP policy is to fetch responses via the network,
337 // unlike the CRL policy default. The policy is further modified to
338 // prefer OCSP over CRLs, if both are specified on the certificate. This
339 // is because an OCSP response is both sufficient and typically
340 // significantly smaller than the CRL counterpart.
341 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
342 } else {
343 // Effectively disable OCSP checking by making it impossible to get an
344 // OCSP response. Even if the Apple TP forces OCSP, no checking will
345 // be able to succeed. If this happens, the Apple TP will report an error
346 // that OCSP was unavailable, but this will be handled and suppressed in
347 // X509Certificate::Verify().
348 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET |
349 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE;
350 }
351
352 SecPolicyRef ocsp_policy;
353 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options,
354 sizeof(tp_ocsp_options), &ocsp_policy);
355 if (status)
356 return status;
357 CFArrayAppendValue(local_policies, ocsp_policy);
358 CFRelease(ocsp_policy);
359
360 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) {
361 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options;
362 memset(&tp_crl_options, 0, sizeof(tp_crl_options));
363 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
364 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET;
365
366 SecPolicyRef crl_policy;
367 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options,
368 sizeof(tp_crl_options), &crl_policy);
369 if (status)
370 return status;
371 CFArrayAppendValue(local_policies, crl_policy);
372 CFRelease(crl_policy);
373 }
374 319
375 policies->reset(local_policies.release()); 320 policies->reset(local_policies.release());
376 return noErr; 321 return noErr;
377 } 322 }
378 323
379 // Gets the issuer for a given cert, starting with the cert itself and 324 // Gets the issuer for a given cert, starting with the cert itself and
380 // including the intermediate and finally root certificates (if any). 325 // including the intermediate and finally root certificates (if any).
381 // This function calls SecTrust but doesn't actually pay attention to the trust 326 // This function calls SecTrust but doesn't actually pay attention to the trust
382 // result: it shouldn't be used to determine trust, just to traverse the chain. 327 // result: it shouldn't be used to determine trust, just to traverse the chain.
383 // Caller is responsible for releasing the value stored into *out_cert_chain. 328 // Caller is responsible for releasing the value stored into *out_cert_chain.
384 OSStatus CopyCertChain(SecCertificateRef cert_handle, 329 OSStatus CopyCertChain(SecCertificateRef cert_handle,
385 CFArrayRef* out_cert_chain) { 330 CFArrayRef* out_cert_chain) {
386 DCHECK(cert_handle); 331 DCHECK(cert_handle);
387 DCHECK(out_cert_chain); 332 DCHECK(out_cert_chain);
388 // Create an SSL policy ref configured for client cert evaluation. 333 // Create an SSL policy ref configured for client cert evaluation.
389 SecPolicyRef ssl_policy; 334 SecPolicyRef ssl_policy;
390 OSStatus result = X509Certificate::CreateSSLClientPolicy(&ssl_policy); 335 OSStatus result = X509Certificate::CreateSSLPolicy(false, std::string(),
336 &ssl_policy);
391 if (result) 337 if (result)
392 return result; 338 return result;
393 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy); 339 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy);
394 340
395 // Create a SecTrustRef. 341 // Create a SecTrustRef.
396 ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate( 342 ScopedCFTypeRef<CFArrayRef> input_certs(CFArrayCreate(
397 NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)), 343 NULL, const_cast<const void**>(reinterpret_cast<void**>(&cert_handle)),
398 1, &kCFTypeArrayCallBacks)); 344 1, &kCFTypeArrayCallBacks));
399 SecTrustRef trust_ref = NULL; 345 SecTrustRef trust_ref = NULL;
400 result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref); 346 result = SecTrustCreateWithCertificates(input_certs, ssl_policy, &trust_ref);
(...skipping 794 matching lines...) Expand 10 before | Expand all | Expand 10 after
1195 X509Certificate::OSCertHandles())); 1141 X509Certificate::OSCertHandles()));
1196 for (unsigned j = 0; j < valid_issuers.size(); j++) { 1142 for (unsigned j = 0; j < valid_issuers.size(); j++) {
1197 if (cert->issuer().Matches(valid_issuers[j])) 1143 if (cert->issuer().Matches(valid_issuers[j]))
1198 return true; 1144 return true;
1199 } 1145 }
1200 } 1146 }
1201 return false; 1147 return false;
1202 } 1148 }
1203 1149
1204 // static 1150 // static
1205 OSStatus X509Certificate::CreateSSLClientPolicy(SecPolicyRef* out_policy) { 1151 OSStatus X509Certificate::CreateSSLPolicy(bool is_server,
1206 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { 1152 const std::string& hostname,
1207 CSSM_APPLE_TP_SSL_OPTS_VERSION, 1153 SecPolicyRef* policy) {
1208 0, 1154 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options;
1209 NULL, 1155 memset(&tp_ssl_options, 0, sizeof(tp_ssl_options));
1210 CSSM_APPLE_TP_SSL_CLIENT 1156 tp_ssl_options.Version = CSSM_APPLE_TP_SSL_OPTS_VERSION;
1211 }; 1157 if (is_server && !hostname.empty()) {
1212 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, 1158 tp_ssl_options.ServerName = hostname.c_str();
wtc 2011/06/03 01:58:04 Use hostname.data(), which does not require conver
1213 &tp_ssl_options, 1159 tp_ssl_options.ServerNameLen = hostname.size();
1214 sizeof(tp_ssl_options), 1160 }
1215 out_policy); 1161 if (!is_server)
1162 tp_ssl_options.Flags |= CSSM_APPLE_TP_SSL_CLIENT;
1163
1164 return CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options,
1165 sizeof(tp_ssl_options), policy);
1216 } 1166 }
1217 1167
1218 // static 1168 // static
1169 OSStatus X509Certificate::CreateBasicX509Policy(SecPolicyRef* policy) {
1170 return CreatePolicy(&CSSMOID_APPLE_X509_BASIC, NULL, 0, policy);
1171 }
1172
1173 // static
1174 OSStatus X509Certificate::CreateRevocationPolicies(
1175 bool enable_revocation_checking,
1176 CFMutableArrayRef policies) {
1177 // In order to actually disable revocation checking, the SecTrustRef must
1178 // have at least one revocation policy associated with it. If none are
1179 // present, the Apple TP will add policies according to the system
1180 // preferences, which will enable revocation checking even if the caller
1181 // explicitly disabled it. An OCSP policy is used, rather than a CRL policy,
1182 // because the Apple TP will force an OCSP policy to be present and enabled
1183 // if it believes the certificate may chain to an EV root. By explicitly
1184 // disabling network and OCSP cache access, then even if the Apple TP
1185 // enables OCSP checking, no revocation checking will actually succeed.
1186 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options;
1187 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options));
1188 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION;
1189
1190 if (enable_revocation_checking) {
1191 // The default for the OCSP policy is to fetch responses via the network,
1192 // unlike the CRL policy default. The policy is further modified to
1193 // prefer OCSP over CRLs, if both are specified on the certificate. This
1194 // is because an OCSP response is both sufficient and typically
1195 // significantly smaller than the CRL counterpart.
1196 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT;
1197 } else {
1198 // Effectively disable OCSP checking by making it impossible to get an
1199 // OCSP response. Even if the Apple TP forces OCSP, no checking will
1200 // be able to succeed. If this happens, the Apple TP will report an error
1201 // that OCSP was unavailable, but this will be handled and suppressed in
1202 // X509Certificate::Verify().
1203 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET |
1204 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE;
1205 }
1206
1207 SecPolicyRef ocsp_policy;
1208 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP,
1209 &tp_ocsp_options, sizeof(tp_ocsp_options),
1210 &ocsp_policy);
1211 if (status)
1212 return status;
1213 CFArrayAppendValue(policies, ocsp_policy);
1214 CFRelease(ocsp_policy);
1215
1216 if (enable_revocation_checking) {
1217 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options;
1218 memset(&tp_crl_options, 0, sizeof(tp_crl_options));
1219 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION;
1220 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET;
1221
1222 SecPolicyRef crl_policy;
1223 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options,
1224 sizeof(tp_crl_options), &crl_policy);
1225 if (status)
1226 return status;
1227 CFArrayAppendValue(policies, crl_policy);
1228 CFRelease(crl_policy);
1229 }
1230
1231 return status;
1232 }
1233
1234
1235 // static
1219 bool X509Certificate::GetSSLClientCertificates( 1236 bool X509Certificate::GetSSLClientCertificates(
1220 const std::string& server_domain, 1237 const std::string& server_domain,
1221 const std::vector<CertPrincipal>& valid_issuers, 1238 const std::vector<CertPrincipal>& valid_issuers,
1222 CertificateList* certs) { 1239 CertificateList* certs) {
1223 ScopedCFTypeRef<SecIdentityRef> preferred_identity; 1240 ScopedCFTypeRef<SecIdentityRef> preferred_identity;
1224 if (!server_domain.empty()) { 1241 if (!server_domain.empty()) {
1225 // See if there's an identity preference for this domain: 1242 // See if there's an identity preference for this domain:
1226 ScopedCFTypeRef<CFStringRef> domain_str( 1243 ScopedCFTypeRef<CFStringRef> domain_str(
1227 base::SysUTF8ToCFStringRef("https://" + server_domain)); 1244 base::SysUTF8ToCFStringRef("https://" + server_domain));
1228 SecIdentityRef identity = NULL; 1245 SecIdentityRef identity = NULL;
(...skipping 117 matching lines...) Expand 10 before | Expand all | Expand 10 after
1346 CSSM_DATA cert_data; 1363 CSSM_DATA cert_data;
1347 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); 1364 OSStatus status = SecCertificateGetData(cert_handle, &cert_data);
1348 if (status) 1365 if (status)
1349 return false; 1366 return false;
1350 1367
1351 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), 1368 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data),
1352 cert_data.Length); 1369 cert_data.Length);
1353 } 1370 }
1354 1371
1355 } // namespace net 1372 } // namespace net
OLDNEW
« net/base/x509_certificate.h ('K') | « net/base/x509_certificate.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698