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

Side by Side Diff: net/cert/cert_verify_proc_mac.cc

Issue 2833623002: Extract IsKnownRoot() functionality for testing if a certificate is a (Closed)
Patch Set: checkpoint Created 3 years, 8 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
OLDNEW
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 14 matching lines...) Expand all
25 #include "net/base/hash_value.h" 25 #include "net/base/hash_value.h"
26 #include "net/base/net_errors.h" 26 #include "net/base/net_errors.h"
27 #include "net/cert/asn1_util.h" 27 #include "net/cert/asn1_util.h"
28 #include "net/cert/cert_status_flags.h" 28 #include "net/cert/cert_status_flags.h"
29 #include "net/cert/cert_verifier.h" 29 #include "net/cert/cert_verifier.h"
30 #include "net/cert/cert_verify_result.h" 30 #include "net/cert/cert_verify_result.h"
31 #include "net/cert/crl_set.h" 31 #include "net/cert/crl_set.h"
32 #include "net/cert/ev_root_ca_metadata.h" 32 #include "net/cert/ev_root_ca_metadata.h"
33 #include "net/cert/internal/certificate_policies.h" 33 #include "net/cert/internal/certificate_policies.h"
34 #include "net/cert/internal/parsed_certificate.h" 34 #include "net/cert/internal/parsed_certificate.h"
35 #include "net/cert/known_roots_mac.h"
35 #include "net/cert/test_keychain_search_list_mac.h" 36 #include "net/cert/test_keychain_search_list_mac.h"
36 #include "net/cert/test_root_certs.h" 37 #include "net/cert/test_root_certs.h"
37 #include "net/cert/x509_certificate.h" 38 #include "net/cert/x509_certificate.h"
38 #include "net/cert/x509_util.h" 39 #include "net/cert/x509_util.h"
39 #include "net/cert/x509_util_mac.h" 40 #include "net/cert/x509_util_mac.h"
40 41
41 // CSSM functions are deprecated as of OSX 10.7, but have no replacement. 42 // CSSM functions are deprecated as of OSX 10.7, but have no replacement.
42 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1 43 // https://bugs.chromium.org/p/chromium/issues/detail?id=590914#c1
43 #pragma clang diagnostic push 44 #pragma clang diagnostic push
44 #pragma clang diagnostic ignored "-Wdeprecated-declarations" 45 #pragma clang diagnostic ignored "-Wdeprecated-declarations"
(...skipping 544 matching lines...) Expand 10 before | Expand all | Expand 10 after
589 return NetErrorFromOSStatus(status); 590 return NetErrorFromOSStatus(status);
590 591
591 trust_ref->swap(scoped_tmp_trust); 592 trust_ref->swap(scoped_tmp_trust);
592 *trust_result = tmp_trust_result; 593 *trust_result = tmp_trust_result;
593 verified_chain->reset(tmp_verified_chain); 594 verified_chain->reset(tmp_verified_chain);
594 *chain_info = tmp_chain_info; 595 *chain_info = tmp_chain_info;
595 596
596 return OK; 597 return OK;
597 } 598 }
598 599
599 // Helper class for managing the set of OS X Known Roots. This is only safe 600 // IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA
600 // to initialize while the crypto::GetMacSecurityServicesLock() is held, due 601 // that we recognise as a standard root.
601 // to calling into Security.framework functions; however, once initialized, 602 bool IsIssuedByKnownRoot(CFArrayRef chain) {
602 // it can be called at any time. 603 CFIndex n = CFArrayGetCount(chain);
603 // In practice, due to lazy initialization, it's best to just always guard 604 if (n < 1)
604 // accesses with the lock. 605 return false;
605 class OSXKnownRootHelper { 606 SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
606 public: 607 const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
607 // IsIssuedByKnownRoot returns true if the given chain is rooted at a root CA 608 return IsKnownRoot(root_ref);
608 // that we recognise as a standard root. 609 }
609 bool IsIssuedByKnownRoot(CFArrayRef chain) {
610 // If there are no known roots, then an API failure occurred. For safety,
611 // assume that all certificates are issued by known roots.
612 if (known_roots_.empty())
613 return true;
614
615 CFIndex n = CFArrayGetCount(chain);
616 if (n < 1)
617 return false;
618 SecCertificateRef root_ref = reinterpret_cast<SecCertificateRef>(
619 const_cast<void*>(CFArrayGetValueAtIndex(chain, n - 1)));
620 SHA256HashValue hash = x509_util::CalculateFingerprint256(root_ref);
621 return known_roots_.find(hash) != known_roots_.end();
622 }
623
624 private:
625 friend struct base::LazyInstanceTraitsBase<OSXKnownRootHelper>;
626
627 OSXKnownRootHelper() {
628 CFArrayRef cert_array = NULL;
629 OSStatus rv = SecTrustSettingsCopyCertificates(
630 kSecTrustSettingsDomainSystem, &cert_array);
631 if (rv != noErr) {
632 LOG(ERROR) << "Unable to determine trusted roots; assuming all roots are "
633 << "trusted! Error " << rv;
634 return;
635 }
636 base::ScopedCFTypeRef<CFArrayRef> scoped_array(cert_array);
637 for (CFIndex i = 0, size = CFArrayGetCount(cert_array); i < size; ++i) {
638 SecCertificateRef cert = reinterpret_cast<SecCertificateRef>(
639 const_cast<void*>(CFArrayGetValueAtIndex(cert_array, i)));
640 known_roots_.insert(x509_util::CalculateFingerprint256(cert));
641 }
642 }
643
644 ~OSXKnownRootHelper() {}
645
646 std::set<SHA256HashValue, SHA256HashValueLessThan> known_roots_;
647 };
648
649 base::LazyInstance<OSXKnownRootHelper>::Leaky g_known_roots =
650 LAZY_INSTANCE_INITIALIZER;
651 610
652 // Runs path building & verification loop for |cert|, given |flags|. This is 611 // Runs path building & verification loop for |cert|, given |flags|. This is
653 // split into a separate function so verification can be repeated with different 612 // split into a separate function so verification can be repeated with different
654 // flags. This function does not handle EV. 613 // flags. This function does not handle EV.
655 int VerifyWithGivenFlags(X509Certificate* cert, 614 int VerifyWithGivenFlags(X509Certificate* cert,
656 const std::string& hostname, 615 const std::string& hostname,
657 const int flags, 616 const int flags,
658 CRLSet* crl_set, 617 CRLSet* crl_set,
659 CertVerifyResult* verify_result, 618 CertVerifyResult* verify_result,
660 CRLSetResult* completed_chain_crl_result) { 619 CRLSetResult* completed_chain_crl_result) {
(...skipping 338 matching lines...) Expand 10 before | Expand all | Expand 10 after
999 // Hostname validation is handled by CertVerifyProc, so mask off any errors 958 // Hostname validation is handled by CertVerifyProc, so mask off any errors
1000 // that SecTrustEvaluate may have set, as its results are not used. 959 // that SecTrustEvaluate may have set, as its results are not used.
1001 verify_result->cert_status &= ~CERT_STATUS_COMMON_NAME_INVALID; 960 verify_result->cert_status &= ~CERT_STATUS_COMMON_NAME_INVALID;
1002 961
1003 // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be 962 // TODO(wtc): Suppress CERT_STATUS_NO_REVOCATION_MECHANISM for now to be
1004 // compatible with Windows, which in turn implements this behavior to be 963 // compatible with Windows, which in turn implements this behavior to be
1005 // compatible with WinHTTP, which doesn't report this error (bug 3004). 964 // compatible with WinHTTP, which doesn't report this error (bug 3004).
1006 verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM; 965 verify_result->cert_status &= ~CERT_STATUS_NO_REVOCATION_MECHANISM;
1007 966
1008 AppendPublicKeyHashes(completed_chain, &verify_result->public_key_hashes); 967 AppendPublicKeyHashes(completed_chain, &verify_result->public_key_hashes);
1009 verify_result->is_issued_by_known_root = 968 verify_result->is_issued_by_known_root = IsIssuedByKnownRoot(completed_chain);
1010 g_known_roots.Get().IsIssuedByKnownRoot(completed_chain);
1011 969
1012 if (IsCertStatusError(verify_result->cert_status)) 970 if (IsCertStatusError(verify_result->cert_status))
1013 return MapCertStatusToNetError(verify_result->cert_status); 971 return MapCertStatusToNetError(verify_result->cert_status);
1014 972
1015 return OK; 973 return OK;
1016 } 974 }
1017 975
1018 } // namespace 976 } // namespace
1019 977
1020 CertVerifyProcMac::CertVerifyProcMac() {} 978 CertVerifyProcMac::CertVerifyProcMac() {}
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
1081 // EV cert and it was covered by CRLSets or revocation checking passed. 1039 // EV cert and it was covered by CRLSets or revocation checking passed.
1082 verify_result->cert_status |= CERT_STATUS_IS_EV; 1040 verify_result->cert_status |= CERT_STATUS_IS_EV;
1083 } 1041 }
1084 1042
1085 return OK; 1043 return OK;
1086 } 1044 }
1087 1045
1088 } // namespace net 1046 } // namespace net
1089 1047
1090 #pragma clang diagnostic pop // "-Wdeprecated-declarations" 1048 #pragma clang diagnostic pop // "-Wdeprecated-declarations"
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698