OLD | NEW |
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 271 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
282 err = SecPolicySetValue(*policy, &options_data); | 282 err = SecPolicySetValue(*policy, &options_data); |
283 if (err) { | 283 if (err) { |
284 CFRelease(*policy); | 284 CFRelease(*policy); |
285 return err; | 285 return err; |
286 } | 286 } |
287 } | 287 } |
288 return noErr; | 288 return noErr; |
289 } | 289 } |
290 | 290 |
291 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to | 291 // Creates a series of SecPolicyRefs to be added to a SecTrustRef used to |
292 // validate a certificate for an SSL peer. |hostname| contains the name of | 292 // validate a certificate for an SSL server. |hostname| contains the name of |
293 // the SSL peer that the certificate should be verified against. |flags| is | 293 // the SSL server that the certificate should be verified against. |flags| is |
294 // a bitwise-OR of VerifyFlags that can further alter how trust is | 294 // a bitwise-OR of VerifyFlags that can further alter how trust is |
295 // validated, such as how revocation is checked. If successful, returns | 295 // validated, such as how revocation is checked. If successful, returns |
296 // noErr, and stores the resultant array of SecPolicyRefs in |policies|. | 296 // noErr, and stores the resultant array of SecPolicyRefs in |policies|. |
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( |
| 300 CFArrayCreateMutable(kCFAllocatorDefault, 0, &kCFTypeArrayCallBacks)); |
| 301 if (!local_policies) |
| 302 return memFullErr; |
| 303 |
299 // Create an SSL SecPolicyRef, and configure it to perform hostname | 304 // Create an SSL SecPolicyRef, and configure it to perform hostname |
300 // 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 |
301 // exception of dotted IPv4 addreses, which we handle ourselves below. | 306 // exception of dotted IPv4 addreses, which we handle ourselves below. |
302 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { | 307 CSSM_APPLE_TP_SSL_OPTIONS tp_ssl_options = { |
303 CSSM_APPLE_TP_SSL_OPTS_VERSION, | 308 CSSM_APPLE_TP_SSL_OPTS_VERSION, |
304 hostname.size(), | 309 hostname.size(), |
305 hostname.data(), | 310 hostname.data(), |
306 0 | 311 0 |
307 }; | 312 }; |
308 SecPolicyRef ssl_policy; | 313 SecPolicyRef ssl_policy; |
309 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, | 314 OSStatus status = CreatePolicy(&CSSMOID_APPLE_TP_SSL, &tp_ssl_options, |
310 sizeof(tp_ssl_options), &ssl_policy); | 315 sizeof(tp_ssl_options), &ssl_policy); |
311 if (status) | 316 if (status) |
312 return status; | 317 return status; |
313 ScopedCFTypeRef<SecPolicyRef> scoped_ssl_policy(ssl_policy); | 318 CFArrayAppendValue(local_policies, ssl_policy); |
| 319 CFRelease(ssl_policy); |
314 | 320 |
315 // Manually add OCSP and CRL policies. If neither an OCSP or CRL policy is | 321 // Manually add revocation policies. In order to actually disable revocation |
316 // specified, the Apple TP module will add whatever the system settings | 322 // checking, the SecTrustRef must have at least one revocation policy |
317 // are, which is not desirable here. | 323 // associated with it. If none are present, the Apple TP will add policies |
318 // | 324 // according to the system preferences, which will enable revocation |
319 // Note that this causes any locally configured OCSP responder URL to be | 325 // checking even if the caller explicitly disabled it. An OCSP policy is |
320 // ignored. | 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. |
321 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; | 331 CSSM_APPLE_TP_OCSP_OPTIONS tp_ocsp_options; |
322 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); | 332 memset(&tp_ocsp_options, 0, sizeof(tp_ocsp_options)); |
323 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; | 333 tp_ocsp_options.Version = CSSM_APPLE_TP_OCSP_OPTS_VERSION; |
324 | 334 |
325 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; | |
326 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); | |
327 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; | |
328 | |
329 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) { | 335 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) { |
330 // If an OCSP responder is available, use it, and avoid fetching any | 336 // The default for the OCSP policy is to fetch responses via the network, |
331 // CRLs for that certificate if possible, as they may be much larger. | 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. |
332 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; | 341 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_SUFFICIENT; |
333 // Ensure that CRLs can be fetched if a crlDistributionPoint extension | |
334 // is found. Otherwise, only the local CRL cache will be consulted. | |
335 tp_crl_options.CrlFlags |= CSSM_TP_ACTION_FETCH_CRL_FROM_NET; | |
336 } else { | 342 } else { |
337 // Disable OCSP network fetching, but still permit cached OCSP responses | 343 // Effectively disable OCSP checking by making it impossible to get an |
338 // to be used. This is equivalent to the Windows code's usage of | 344 // OCSP response. Even if the Apple TP forces OCSP, no checking will |
339 // CERT_CHAIN_REVOCATION_CHECK_CACHE_ONLY. | 345 // be able to succeed. If this happens, the Apple TP will report an error |
340 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET; | 346 // that OCSP was unavailable, but this will be handled and suppressed in |
341 // The default CrlFlags will ensure only cached CRLs are used. | 347 // X509Certificate::Verify(). |
| 348 tp_ocsp_options.Flags = CSSM_TP_ACTION_OCSP_DISABLE_NET | |
| 349 CSSM_TP_ACTION_OCSP_CACHE_READ_DISABLE; |
342 } | 350 } |
343 | 351 |
344 SecPolicyRef ocsp_policy; | 352 SecPolicyRef ocsp_policy; |
345 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, | 353 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_OCSP, &tp_ocsp_options, |
346 sizeof(tp_ocsp_options), &ocsp_policy); | 354 sizeof(tp_ocsp_options), &ocsp_policy); |
347 if (status) | 355 if (status) |
348 return status; | 356 return status; |
349 ScopedCFTypeRef<SecPolicyRef> scoped_ocsp_policy(ocsp_policy); | 357 CFArrayAppendValue(local_policies, ocsp_policy); |
| 358 CFRelease(ocsp_policy); |
350 | 359 |
351 SecPolicyRef crl_policy; | 360 if (flags & X509Certificate::VERIFY_REV_CHECKING_ENABLED) { |
352 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, | 361 CSSM_APPLE_TP_CRL_OPTIONS tp_crl_options; |
353 sizeof(tp_crl_options), &crl_policy); | 362 memset(&tp_crl_options, 0, sizeof(tp_crl_options)); |
354 if (status) | 363 tp_crl_options.Version = CSSM_APPLE_TP_CRL_OPTS_VERSION; |
355 return status; | 364 tp_crl_options.CrlFlags = CSSM_TP_ACTION_FETCH_CRL_FROM_NET; |
356 ScopedCFTypeRef<SecPolicyRef> scoped_crl_policy(crl_policy); | |
357 | 365 |
358 CFTypeRef local_policies[] = { ssl_policy, ocsp_policy, crl_policy }; | 366 SecPolicyRef crl_policy; |
359 CFArrayRef policy_array = CFArrayCreate(kCFAllocatorDefault, local_policies, | 367 status = CreatePolicy(&CSSMOID_APPLE_TP_REVOCATION_CRL, &tp_crl_options, |
360 arraysize(local_policies), | 368 sizeof(tp_crl_options), &crl_policy); |
361 &kCFTypeArrayCallBacks); | 369 if (status) |
362 if (!policy_array) | 370 return status; |
363 return memFullErr; | 371 CFArrayAppendValue(local_policies, crl_policy); |
| 372 CFRelease(crl_policy); |
| 373 } |
364 | 374 |
365 policies->reset(policy_array); | 375 policies->reset(local_policies.release()); |
366 return noErr; | 376 return noErr; |
367 } | 377 } |
368 | 378 |
369 // Gets the issuer for a given cert, starting with the cert itself and | 379 // Gets the issuer for a given cert, starting with the cert itself and |
370 // including the intermediate and finally root certificates (if any). | 380 // including the intermediate and finally root certificates (if any). |
371 // This function calls SecTrust but doesn't actually pay attention to the trust | 381 // This function calls SecTrust but doesn't actually pay attention to the trust |
372 // result: it shouldn't be used to determine trust, just to traverse the chain. | 382 // result: it shouldn't be used to determine trust, just to traverse the chain. |
373 // Caller is responsible for releasing the value stored into *out_cert_chain. | 383 // Caller is responsible for releasing the value stored into *out_cert_chain. |
374 OSStatus CopyCertChain(SecCertificateRef cert_handle, | 384 OSStatus CopyCertChain(SecCertificateRef cert_handle, |
375 CFArrayRef* out_cert_chain) { | 385 CFArrayRef* out_cert_chain) { |
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
849 // we'll set our own result to include | 859 // we'll set our own result to include |
850 // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are | 860 // CERT_STATUS_NO_REVOCATION_MECHANISM. If one or both extensions are |
851 // present, and a check fails (server unavailable, OCSP retry later, | 861 // present, and a check fails (server unavailable, OCSP retry later, |
852 // signature mismatch), then we'll set our own result to include | 862 // signature mismatch), then we'll set our own result to include |
853 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION. | 863 // CERT_STATUS_UNABLE_TO_CHECK_REVOCATION. |
854 tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT; | 864 tp_action_data.ActionFlags |= CSSM_TP_ACTION_REQUIRE_REV_PER_CERT; |
855 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; | 865 verify_result->cert_status |= CERT_STATUS_REV_CHECKING_ENABLED; |
856 } else { | 866 } else { |
857 // EV requires revocation checking. | 867 // EV requires revocation checking. |
858 // Note, under the hood, SecTrustEvaluate() will modify the OCSP options | 868 // Note, under the hood, SecTrustEvaluate() will modify the OCSP options |
859 // so as to attempt OCSP fetching if it believes a certificate may chain | 869 // so as to attempt OCSP checking if it believes a certificate may chain |
860 // to an EV root. However, because network fetches are disabled in | 870 // to an EV root. However, because network fetches are disabled in |
861 // CreateTrustPolicies() when revocation checking is disabled, these | 871 // CreateTrustPolicies() when revocation checking is disabled, these |
862 // will only go against the local cache. | 872 // will only go against the local cache. |
863 flags &= ~VERIFY_EV_CERT; | 873 flags &= ~VERIFY_EV_CERT; |
864 } | 874 } |
865 | 875 |
866 CFDataRef action_data_ref = | 876 CFDataRef action_data_ref = |
867 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, | 877 CFDataCreateWithBytesNoCopy(kCFAllocatorDefault, |
868 reinterpret_cast<UInt8*>(&tp_action_data), | 878 reinterpret_cast<UInt8*>(&tp_action_data), |
869 sizeof(tp_action_data), kCFAllocatorNull); | 879 sizeof(tp_action_data), kCFAllocatorNull); |
(...skipping 466 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1336 CSSM_DATA cert_data; | 1346 CSSM_DATA cert_data; |
1337 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); | 1347 OSStatus status = SecCertificateGetData(cert_handle, &cert_data); |
1338 if (status) | 1348 if (status) |
1339 return false; | 1349 return false; |
1340 | 1350 |
1341 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), | 1351 return pickle->WriteData(reinterpret_cast<char*>(cert_data.Data), |
1342 cert_data.Length); | 1352 cert_data.Length); |
1343 } | 1353 } |
1344 | 1354 |
1345 } // namespace net | 1355 } // namespace net |
OLD | NEW |