| 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/cert_verify_proc_mac.h" | 5 #include "net/cert/cert_verify_proc_mac.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 | 10 |
| (...skipping 184 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 195 verified_chain.push_back(chain_cert); | 195 verified_chain.push_back(chain_cert); |
| 196 } | 196 } |
| 197 } | 197 } |
| 198 if (!verified_cert) { | 198 if (!verified_cert) { |
| 199 NOTREACHED(); | 199 NOTREACHED(); |
| 200 verify_result->cert_status |= CERT_STATUS_INVALID; | 200 verify_result->cert_status |= CERT_STATUS_INVALID; |
| 201 return; | 201 return; |
| 202 } | 202 } |
| 203 | 203 |
| 204 scoped_refptr<X509Certificate> verified_cert_with_chain = | 204 scoped_refptr<X509Certificate> verified_cert_with_chain = |
| 205 X509Certificate::CreateFromHandle(verified_cert, verified_chain); | 205 x509_util::CreateX509CertificateFromSecCertificate(verified_cert, |
| 206 verified_chain); |
| 206 if (verified_cert_with_chain) | 207 if (verified_cert_with_chain) |
| 207 verify_result->verified_cert = std::move(verified_cert_with_chain); | 208 verify_result->verified_cert = std::move(verified_cert_with_chain); |
| 208 else | 209 else |
| 209 verify_result->cert_status |= CERT_STATUS_INVALID; | 210 verify_result->cert_status |= CERT_STATUS_INVALID; |
| 210 } | 211 } |
| 211 | 212 |
| 212 // Returns true if the certificate uses MD2, MD4, MD5, or SHA1, and false | 213 // Returns true if the certificate uses MD2, MD4, MD5, or SHA1, and false |
| 213 // otherwise. A return of false also includes the case where the signature | 214 // otherwise. A return of false also includes the case where the signature |
| 214 // algorithm couldn't be conclusively labeled as weak. | 215 // algorithm couldn't be conclusively labeled as weak. |
| 215 bool CertUsesWeakHash(X509Certificate::OSCertHandle cert_handle) { | 216 bool CertUsesWeakHash(SecCertificateRef cert_handle) { |
| 216 x509_util::CSSMCachedCertificate cached_cert; | 217 x509_util::CSSMCachedCertificate cached_cert; |
| 217 OSStatus status = cached_cert.Init(cert_handle); | 218 OSStatus status = cached_cert.Init(cert_handle); |
| 218 if (status) | 219 if (status) |
| 219 return false; | 220 return false; |
| 220 | 221 |
| 221 x509_util::CSSMFieldValue signature_field; | 222 x509_util::CSSMFieldValue signature_field; |
| 222 status = | 223 status = |
| 223 cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, &signature_field); | 224 cached_cert.GetField(&CSSMOID_X509V1SignatureAlgorithm, &signature_field); |
| 224 if (status || !signature_field.field()) | 225 if (status || !signature_field.field()) |
| 225 return false; | 226 return false; |
| (...skipping 410 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 636 // If there are no known roots, then an API failure occurred. For safety, | 637 // If there are no known roots, then an API failure occurred. For safety, |
| 637 // assume that all certificates are issued by known roots. | 638 // assume that all certificates are issued by known roots. |
| 638 if (known_roots_.empty()) | 639 if (known_roots_.empty()) |
| 639 return true; | 640 return true; |
| 640 | 641 |
| 641 CFIndex n = CFArrayGetCount(chain); | 642 CFIndex n = CFArrayGetCount(chain); |
| 642 if (n < 1) | 643 if (n < 1) |
| 643 return false; | 644 return false; |
| 644 SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>( | 645 SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>( |
| 645 const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1))); | 646 const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1))); |
| 646 SHA256HashValue hash = X509Certificate::CalculateFingerprint256(root_ref); | 647 SHA256HashValue hash = x509_util::CalculateFingerprint256(root_ref); |
| 647 return known_roots_.find(hash) != known_roots_.end(); | 648 return known_roots_.find(hash) != known_roots_.end(); |
| 648 } | 649 } |
| 649 | 650 |
| 650 private: | 651 private: |
| 651 friend struct base::LazyInstanceTraitsBase<OSXKnownRootHelper>; | 652 friend struct base::LazyInstanceTraitsBase<OSXKnownRootHelper>; |
| 652 | 653 |
| 653 OSXKnownRootHelper() { | 654 OSXKnownRootHelper() { |
| 654 CFArrayRef cert_array = NULL; | 655 CFArrayRef cert_array = NULL; |
| 655 OSStatus rv = SecTrustSettingsCopyCertificates( | 656 OSStatus rv = SecTrustSettingsCopyCertificates( |
| 656 kSecTrustSettingsDomainSystem, &cert_array); | 657 kSecTrustSettingsDomainSystem, &cert_array); |
| 657 if (rv != noErr) { | 658 if (rv != noErr) { |
| 658 LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are " | 659 LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are " |
| 659 << "trusted! Error " << rv; | 660 << "trusted! Error " << rv; |
| 660 return; | 661 return; |
| 661 } | 662 } |
| 662 base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array); | 663 base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array); |
| 663 for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) { | 664 for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) { |
| 664 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( | 665 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>( |
| 665 const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i))); | 666 const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i))); |
| 666 known_roots_.insert(X509Certificate::CalculateFingerprint256(cert)); | 667 known_roots_.insert(x509_util::CalculateFingerprint256(cert)); |
| 667 } | 668 } |
| 668 } | 669 } |
| 669 | 670 |
| 670 ~OSXKnownRootHelper() {} | 671 ~OSXKnownRootHelper() {} |
| 671 | 672 |
| 672 std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_; | 673 std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_; |
| 673 }; | 674 }; |
| 674 | 675 |
| 675 base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots = | 676 base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots = |
| 676 LAZY_INSTANCE_INITIALIZER; | 677 LAZY_INSTANCE_INITIALIZER; |
| (...skipping 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 802 "/System/Library/Keychains/SystemRootCertificates.keychain", | 803 "/System/Library/Keychains/SystemRootCertificates.keychain", |
| 803 &keychain); | 804 &keychain); |
| 804 if (status) | 805 if (status) |
| 805 return NetErrorFromOSStatus(status); | 806 return NetErrorFromOSStatus(status); |
| 806 ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); | 807 ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); |
| 807 | 808 |
| 808 CFArrayInsertValueAtIndex(mutable_keychain_search_list, 0, keychain); | 809 CFArrayInsertValueAtIndex(mutable_keychain_search_list, 0, keychain); |
| 809 } | 810 } |
| 810 | 811 |
| 811 ScopedCFTypeRef<CFMutableArrayRef> cert_array( | 812 ScopedCFTypeRef<CFMutableArrayRef> cert_array( |
| 812 cert->CreateOSCertChainForCert()); | 813 x509_util::CreateSecCertificateArrayForX509Certificate(cert)); |
| 814 if (!cert_array) |
| 815 return ERR_CERT_INVALID; |
| 813 | 816 |
| 814 // Beginning with the certificate chain as supplied by the server, attempt | 817 // Beginning with the certificate chain as supplied by the server, attempt |
| 815 // to verify the chain. If a failure is encountered, trim a certificate | 818 // to verify the chain. If a failure is encountered, trim a certificate |
| 816 // from the end (so long as one remains) and retry, in the hope of forcing | 819 // from the end (so long as one remains) and retry, in the hope of forcing |
| 817 // OS X to find a better path. | 820 // OS X to find a better path. |
| 818 while (CFArrayGetCount(cert_array) > 0) { | 821 while (CFArrayGetCount(cert_array) > 0) { |
| 819 ScopedCFTypeRef<SecTrustRef> temp_ref; | 822 ScopedCFTypeRef<SecTrustRef> temp_ref; |
| 820 SecTrustResultType temp_trust_result = kSecTrustResultDeny; | 823 SecTrustResultType temp_trust_result = kSecTrustResultDeny; |
| 821 ScopedCFTypeRef<CFArrayRef> temp_chain; | 824 ScopedCFTypeRef<CFArrayRef> temp_chain; |
| 822 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL; | 825 CSSM_TP_APPLE_EVIDENCE_INFO* temp_chain_info = NULL; |
| (...skipping 282 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1105 // EV cert and it was covered by CRLSets or revocation checking passed. | 1108 // EV cert and it was covered by CRLSets or revocation checking passed. |
| 1106 verify_result->cert_status |= CERT_STATUS_IS_EV; | 1109 verify_result->cert_status |= CERT_STATUS_IS_EV; |
| 1107 } | 1110 } |
| 1108 | 1111 |
| 1109 return OK; | 1112 return OK; |
| 1110 } | 1113 } |
| 1111 | 1114 |
| 1112 } // namespace net | 1115 } // namespace net |
| 1113 | 1116 |
| 1114 #pragma clang diagnostic pop // "-Wdeprecated-declarations" | 1117 #pragma clang diagnostic pop // "-Wdeprecated-declarations" |
| OLD | NEW |