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, these should not 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* 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 // 'internal'/non-IANA assigned domains. |
| 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 that internal/non-unique names are properly identified as such, but |
| 1205 // that IP addresses and hosts beneath registry-controlled domains are flagged |
| 1206 // as unique names. |
| 1207 TEST_P(CertVerifyProcNonUniqueNameTest, IsHostnameNonUnique) { |
| 1208 const NonUniqueNameTestData& test_data = GetParam(); |
| 1209 |
| 1210 EXPECT_EQ(test_data.is_unique, IsUnique(test_data.hostname)); |
| 1211 } |
| 1212 |
| 1213 INSTANTIATE_TEST_CASE_P(, CertVerifyProcNonUniqueNameTest, |
| 1214 testing::ValuesIn(kNonUniqueNameTestData)); |
| 1215 |
1082 } // namespace net | 1216 } // namespace net |
OLD | NEW |