Chromium Code Reviews| 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.h" | 5 #include "net/cert/cert_verify_proc.h" |
| 6 | 6 |
| 7 #include <vector> | 7 #include <vector> |
| 8 | 8 |
| 9 #include "base/files/file_path.h" | 9 #include "base/files/file_path.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 25 matching lines...) Expand all Loading... | |
| 36 | 36 |
| 37 namespace { | 37 namespace { |
| 38 | 38 |
| 39 // A certificate for www.paypal.com with a NULL byte in the common name. | 39 // A certificate for www.paypal.com with a NULL byte in the common name. |
| 40 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 | 40 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 |
| 41 unsigned char paypal_null_fingerprint[] = { | 41 unsigned char paypal_null_fingerprint[] = { |
| 42 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba, | 42 0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba, |
| 43 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 | 43 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 |
| 44 }; | 44 }; |
| 45 | 45 |
| 46 // Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root| | |
| 47 // for all certificates that are Verified. | |
| 48 class WellKnownCaCertVerifyProc : public CertVerifyProc { | |
| 49 public: | |
| 50 // Initialize a CertVerifyProc that will set | |
| 51 // |verify_result->is_issued_by_known_root| to |is_well_known|. | |
| 52 explicit WellKnownCaCertVerifyProc(bool is_well_known) | |
| 53 : is_well_known_(is_well_known) {} | |
| 54 | |
| 55 // CertVerifyProc implementation: | |
| 56 virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE { return false; } | |
| 57 | |
| 58 protected: | |
| 59 virtual ~WellKnownCaCertVerifyProc() {} | |
| 60 | |
| 61 private: | |
| 62 virtual int VerifyInternal(X509Certificate* cert, | |
| 63 const std::string& hostname, | |
| 64 int flags, | |
| 65 CRLSet* crl_set, | |
| 66 const CertificateList& additional_trust_anchors, | |
| 67 CertVerifyResult* verify_result) OVERRIDE; | |
| 68 | |
| 69 const bool is_well_known_; | |
| 70 | |
| 71 DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc); | |
| 72 }; | |
| 73 | |
| 74 int WellKnownCaCertVerifyProc::VerifyInternal( | |
| 75 X509Certificate* cert, | |
| 76 const std::string& hostname, | |
| 77 int flags, | |
| 78 CRLSet* crl_set, | |
| 79 const CertificateList& additional_trust_anchors, | |
| 80 CertVerifyResult* verify_result) { | |
| 81 verify_result->is_issued_by_known_root = is_well_known_; | |
| 82 return OK; | |
| 83 } | |
| 84 | |
| 46 } // namespace | 85 } // namespace |
| 47 | 86 |
| 48 class CertVerifyProcTest : public testing::Test { | 87 class CertVerifyProcTest : public testing::Test { |
| 49 public: | 88 public: |
| 50 CertVerifyProcTest() | 89 CertVerifyProcTest() |
| 51 : verify_proc_(CertVerifyProc::CreateDefault()) { | 90 : verify_proc_(CertVerifyProc::CreateDefault()) { |
| 52 } | 91 } |
| 53 virtual ~CertVerifyProcTest() {} | 92 virtual ~CertVerifyProcTest() {} |
| 54 | 93 |
| 55 protected: | 94 protected: |
| 56 bool SupportsAdditionalTrustAnchors() { | 95 bool SupportsAdditionalTrustAnchors() { |
| 57 return verify_proc_->SupportsAdditionalTrustAnchors(); | 96 return verify_proc_->SupportsAdditionalTrustAnchors(); |
| 58 } | 97 } |
| 59 | 98 |
| 60 int Verify(X509Certificate* cert, | 99 int Verify(X509Certificate* cert, |
| 61 const std::string& hostname, | 100 const std::string& hostname, |
| 62 int flags, | 101 int flags, |
| 63 CRLSet* crl_set, | 102 CRLSet* crl_set, |
| 64 const CertificateList& additional_trust_anchors, | 103 const CertificateList& additional_trust_anchors, |
| 65 CertVerifyResult* verify_result) { | 104 CertVerifyResult* verify_result) { |
| 66 return verify_proc_->Verify(cert, hostname, flags, crl_set, | 105 return verify_proc_->Verify(cert, hostname, flags, crl_set, |
| 67 additional_trust_anchors, verify_result); | 106 additional_trust_anchors, verify_result); |
| 68 } | 107 } |
| 69 | 108 |
| 70 const CertificateList empty_cert_list_; | 109 const CertificateList empty_cert_list_; |
| 71 | |
| 72 private: | |
| 73 scoped_refptr<CertVerifyProc> verify_proc_; | 110 scoped_refptr<CertVerifyProc> verify_proc_; |
| 74 }; | 111 }; |
| 75 | 112 |
| 76 TEST_F(CertVerifyProcTest, WithoutRevocationChecking) { | 113 TEST_F(CertVerifyProcTest, WithoutRevocationChecking) { |
| 77 // Check that verification without revocation checking works. | 114 // Check that verification without revocation checking works. |
| 78 CertificateList certs = CreateCertificateListFromFile( | 115 CertificateList certs = CreateCertificateListFromFile( |
| 79 GetTestCertsDirectory(), | 116 GetTestCertsDirectory(), |
| 80 "googlenew.chain.pem", | 117 "googlenew.chain.pem", |
| 81 X509Certificate::FORMAT_PEM_CERT_SEQUENCE); | 118 X509Certificate::FORMAT_PEM_CERT_SEQUENCE); |
| 82 | 119 |
| (...skipping 500 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 583 verify_result.verified_cert->os_cert_handle())); | 620 verify_result.verified_cert->os_cert_handle())); |
| 584 const X509Certificate::OSCertHandles& return_intermediates = | 621 const X509Certificate::OSCertHandles& return_intermediates = |
| 585 verify_result.verified_cert->GetIntermediateCertificates(); | 622 verify_result.verified_cert->GetIntermediateCertificates(); |
| 586 ASSERT_EQ(2U, return_intermediates.size()); | 623 ASSERT_EQ(2U, return_intermediates.size()); |
| 587 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], | 624 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |
| 588 certs[1]->os_cert_handle())); | 625 certs[1]->os_cert_handle())); |
| 589 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], | 626 EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |
| 590 certs[2]->os_cert_handle())); | 627 certs[2]->os_cert_handle())); |
| 591 } | 628 } |
| 592 | 629 |
| 630 // Test that certificates issued for 'intranet' names (that is, containing no | |
| 631 // known public registry controlled domain information) issued by well-known | |
| 632 // CAs are flagged appropriately, while certificates that are issued by | |
| 633 // internal CAs are not flagged. | |
| 634 TEST_F(CertVerifyProcTest, IntranetHostsRejected) { | |
| 635 CertificateList cert_list = CreateCertificateListFromFile( | |
| 636 GetTestCertsDirectory(), "ok_cert.pem", | |
| 637 X509Certificate::FORMAT_AUTO); | |
| 638 ASSERT_EQ(1U, cert_list.size()); | |
| 639 scoped_refptr<X509Certificate> cert(cert_list[0]); | |
| 640 | |
| 641 CertVerifyResult verify_result; | |
| 642 int error = 0; | |
| 643 | |
| 644 // Intranet names for public CAs should be flagged: | |
| 645 verify_proc_ = new WellKnownCaCertVerifyProc(true); | |
| 646 error = Verify(cert, "intranet", 0, NULL, empty_cert_list_, | |
| 647 &verify_result); | |
| 648 EXPECT_EQ(OK, error); | |
| 649 EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME); | |
| 650 | |
| 651 // However, if the CA is not well known, none of these should be flagged: | |
| 652 verify_proc_ = new WellKnownCaCertVerifyProc(false); | |
| 653 error = Verify(cert, "intranet", 0, NULL, empty_cert_list_, | |
| 654 &verify_result); | |
| 655 EXPECT_EQ(OK, error); | |
| 656 EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME); | |
| 657 } | |
| 658 | |
| 593 // Test that the certificate returned in CertVerifyResult is able to reorder | 659 // Test that the certificate returned in CertVerifyResult is able to reorder |
| 594 // certificates that are not ordered from end-entity to root. While this is | 660 // certificates that are not ordered from end-entity to root. While this is |
| 595 // a protocol violation if sent during a TLS handshake, if multiple sources | 661 // a protocol violation if sent during a TLS handshake, if multiple sources |
| 596 // of intermediate certificates are combined, it's possible that order may | 662 // of intermediate certificates are combined, it's possible that order may |
| 597 // not be maintained. | 663 // not be maintained. |
| 598 TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) { | 664 TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) { |
| 599 base::FilePath certs_dir = GetTestCertsDirectory(); | 665 base::FilePath certs_dir = GetTestCertsDirectory(); |
| 600 CertificateList certs = CreateCertificateListFromFile( | 666 CertificateList certs = CreateCertificateListFromFile( |
| 601 certs_dir, "x509_verify_results.chain.pem", | 667 certs_dir, "x509_verify_results.chain.pem", |
| 602 X509Certificate::FORMAT_AUTO); | 668 X509Certificate::FORMAT_AUTO); |
| (...skipping 469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1072 #if defined(USE_NSS) || defined(OS_IOS) | 1138 #if defined(USE_NSS) || defined(OS_IOS) |
| 1073 #define MAYBE_VerifyMixed DISABLED_VerifyMixed | 1139 #define MAYBE_VerifyMixed DISABLED_VerifyMixed |
| 1074 #else | 1140 #else |
| 1075 #define MAYBE_VerifyMixed VerifyMixed | 1141 #define MAYBE_VerifyMixed VerifyMixed |
| 1076 #endif | 1142 #endif |
| 1077 WRAPPED_INSTANTIATE_TEST_CASE_P( | 1143 WRAPPED_INSTANTIATE_TEST_CASE_P( |
| 1078 MAYBE_VerifyMixed, | 1144 MAYBE_VerifyMixed, |
| 1079 CertVerifyProcWeakDigestTest, | 1145 CertVerifyProcWeakDigestTest, |
| 1080 testing::ValuesIn(kVerifyMixedTestData)); | 1146 testing::ValuesIn(kVerifyMixedTestData)); |
| 1081 | 1147 |
| 1148 struct NonUniqueNameTestData { | |
| 1149 bool is_unique; | |
| 1150 const char* const hostname; | |
| 1151 }; | |
| 1152 | |
| 1153 // Google Test pretty-printer. | |
| 1154 void PrintTo(const NonUniqueNameTestData& data, std::ostream* os) { | |
| 1155 ASSERT_TRUE(data.hostname); | |
| 1156 *os << " hostname: " << testing::PrintToString(data.hostname) | |
| 1157 << "; is_unique: " << testing::PrintToString(data.is_unique); | |
| 1158 } | |
| 1159 | |
| 1160 const NonUniqueNameTestData kNonUniqueNameTestData[] = { | |
| 1161 // Domains under ICANN-assigned domains. | |
| 1162 { true, "google.com" }, | |
| 1163 { true, "google.co.uk" }, | |
| 1164 // Domains under private registries. | |
| 1165 { true, "appspot.com" }, | |
| 1166 { true, "test.appspot.com" }, | |
| 1167 // IPv4 addresses (in various forms). | |
| 1168 { true, "8.8.8.8" }, | |
| 1169 { true, "1.2.3" }, | |
| 1170 { true, "14.15" }, | |
| 1171 { true, "676768" }, | |
| 1172 // IPv6 addresses | |
| 1173 { true, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210" }, | |
| 1174 { true, "::192.9.5.5" }, | |
| 1175 { true, "FEED::BEEF" }, | |
| 1176 // "Intanet" domains | |
|
agl
2013/05/16 20:08:25
Intra
| |
| 1177 { false, "intranet" }, | |
| 1178 { false, "intranet." }, | |
| 1179 { false, "intranet.example" }, | |
| 1180 { false, "host.intranet.example" }, | |
| 1181 // gTLDs under discussion, but not yet assigned | |
| 1182 { false, "intranet.corp" }, | |
| 1183 { false, "example.tech" }, | |
| 1184 { false, "intranet.internal" }, | |
| 1185 // Invalid host names are treated as unique - but expected to be | |
| 1186 // filtered out before then. | |
| 1187 { true, "junk)(£)$*!@~#" }, | |
| 1188 { true, "w$w.example.com" }, | |
| 1189 { true, "nocolonsallowed:example" }, | |
| 1190 { true, "[::4.5.6.9]" }, | |
| 1191 }; | |
| 1192 | |
| 1193 class CertVerifyProcNonUniqueNameTest | |
| 1194 : public testing::TestWithParam<NonUniqueNameTestData> { | |
| 1195 public: | |
| 1196 virtual ~CertVerifyProcNonUniqueNameTest() {} | |
| 1197 | |
| 1198 protected: | |
| 1199 bool IsUnique(const std::string& hostname) { | |
| 1200 return !CertVerifyProc::IsHostnameNonUnique(hostname); | |
| 1201 } | |
| 1202 }; | |
| 1203 | |
| 1204 TEST_P(CertVerifyProcNonUniqueNameTest, IsHostnameNonUnique) { | |
| 1205 const NonUniqueNameTestData& test_data = GetParam(); | |
| 1206 | |
| 1207 EXPECT_EQ(test_data.is_unique, IsUnique(test_data.hostname)); | |
| 1208 } | |
| 1209 | |
| 1210 INSTANTIATE_TEST_CASE_P(, CertVerifyProcNonUniqueNameTest, | |
| 1211 testing::ValuesIn(kNonUniqueNameTestData)); | |
| 1212 | |
| 1082 } // namespace net | 1213 } // namespace net |
| OLD | NEW |