OLD | NEW |
1 // Copyright (c) 2006-2008 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2006-2008 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 "base/file_path.h" | 5 #include "base/file_path.h" |
6 #include "base/file_util.h" | 6 #include "base/file_util.h" |
7 #include "base/path_service.h" | 7 #include "base/path_service.h" |
8 #include "base/pickle.h" | 8 #include "base/pickle.h" |
9 #include "net/base/cert_status_flags.h" | 9 #include "net/base/cert_status_flags.h" |
10 #include "net/base/cert_test_util.h" | 10 #include "net/base/cert_test_util.h" |
(...skipping 11 matching lines...) Expand all Loading... |
22 #define ALLOW_EXTERNAL_ACCESS 0 | 22 #define ALLOW_EXTERNAL_ACCESS 0 |
23 | 23 |
24 #if ALLOW_EXTERNAL_ACCESS && defined(OS_WIN) | 24 #if ALLOW_EXTERNAL_ACCESS && defined(OS_WIN) |
25 #define TEST_EV 1 // Test CERT_STATUS_IS_EV | 25 #define TEST_EV 1 // Test CERT_STATUS_IS_EV |
26 #endif | 26 #endif |
27 | 27 |
28 using base::Time; | 28 using base::Time; |
29 | 29 |
30 namespace net { | 30 namespace net { |
31 | 31 |
32 namespace { | |
33 | |
34 // Certificates for test data. They're obtained with: | 32 // Certificates for test data. They're obtained with: |
35 // | 33 // |
36 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null | 34 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null |
37 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der | 35 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der |
38 // | 36 // |
39 // For fingerprint | 37 // For fingerprint |
40 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der | 38 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der |
41 | 39 |
42 // For valid_start, valid_expiry | 40 // For valid_start, valid_expiry |
43 // $ openssl x509 -inform DER -text -noout < /tmp/host.der | | 41 // $ openssl x509 -inform DER -text -noout < /tmp/host.der | |
(...skipping 25 matching lines...) Expand all Loading... |
69 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 | 67 0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7 |
70 }; | 68 }; |
71 | 69 |
72 // A certificate for https://www.unosoft.hu/, whose AIA extension contains | 70 // A certificate for https://www.unosoft.hu/, whose AIA extension contains |
73 // an LDAP URL without a host name. | 71 // an LDAP URL without a host name. |
74 unsigned char unosoft_hu_fingerprint[] = { | 72 unsigned char unosoft_hu_fingerprint[] = { |
75 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd, | 73 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd, |
76 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8 | 74 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8 |
77 }; | 75 }; |
78 | 76 |
| 77 // The fingerprint of the Google certificate used in the parsing tests, |
| 78 // which is newer than the one included in the x509_certificate_data.h |
| 79 unsigned char google_parse_fingerprint[] = { |
| 80 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a, |
| 81 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2 |
| 82 }; |
| 83 |
| 84 // The fingerprint for the Thawte SGC certificate |
| 85 unsigned char thawte_parse_fingerprint[] = { |
| 86 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f, |
| 87 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02 |
| 88 }; |
| 89 |
| 90 // Dec 18 00:00:00 2009 GMT |
| 91 const double kGoogleParseValidFrom = 1261094400; |
| 92 // Dec 18 23:59:59 2011 GMT |
| 93 const double kGoogleParseValidTo = 1324252799; |
| 94 |
| 95 struct CertificateFormatTestData { |
| 96 const char* file_name; |
| 97 X509Certificate::Format format; |
| 98 unsigned char* chain_fingerprints[3]; |
| 99 }; |
| 100 |
| 101 const CertificateFormatTestData FormatTestData[] = { |
| 102 // DER Parsing - single certificate, DER encoded |
| 103 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE, |
| 104 { google_parse_fingerprint, |
| 105 NULL, } }, |
| 106 // DER parsing - single certificate, PEM encoded |
| 107 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE, |
| 108 { google_parse_fingerprint, |
| 109 NULL, } }, |
| 110 // PEM parsing - single certificate, PEM encoded with a PEB of |
| 111 // "CERTIFICATE" |
| 112 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE, |
| 113 { google_parse_fingerprint, |
| 114 NULL, } }, |
| 115 // PEM parsing - sequence of certificates, PEM encoded with a PEB of |
| 116 // "CERTIFICATE" |
| 117 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE, |
| 118 { google_parse_fingerprint, |
| 119 thawte_parse_fingerprint, |
| 120 NULL, } }, |
| 121 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER |
| 122 // encoding |
| 123 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7, |
| 124 { google_parse_fingerprint, |
| 125 thawte_parse_fingerprint, |
| 126 NULL, } }, |
| 127 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM |
| 128 // encoded with a PEM PEB of "CERTIFICATE" |
| 129 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7, |
| 130 { google_parse_fingerprint, |
| 131 thawte_parse_fingerprint, |
| 132 NULL, } }, |
| 133 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM |
| 134 // encoded with a PEM PEB of "PKCS7" |
| 135 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7, |
| 136 { google_parse_fingerprint, |
| 137 thawte_parse_fingerprint, |
| 138 NULL, } }, |
| 139 // All of the above, this time using auto-detection |
| 140 { "google.single.der", X509Certificate::FORMAT_AUTO, |
| 141 { google_parse_fingerprint, |
| 142 NULL, } }, |
| 143 { "google.single.pem", X509Certificate::FORMAT_AUTO, |
| 144 { google_parse_fingerprint, |
| 145 NULL, } }, |
| 146 { "google.chain.pem", X509Certificate::FORMAT_AUTO, |
| 147 { google_parse_fingerprint, |
| 148 thawte_parse_fingerprint, |
| 149 NULL, } }, |
| 150 { "google.binary.p7b", X509Certificate::FORMAT_AUTO, |
| 151 { google_parse_fingerprint, |
| 152 thawte_parse_fingerprint, |
| 153 NULL, } }, |
| 154 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO, |
| 155 { google_parse_fingerprint, |
| 156 thawte_parse_fingerprint, |
| 157 NULL, } }, |
| 158 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO, |
| 159 { google_parse_fingerprint, |
| 160 thawte_parse_fingerprint, |
| 161 NULL, } }, |
| 162 }; |
| 163 |
79 // Returns a FilePath object representing the src/net/data/ssl/certificates | 164 // Returns a FilePath object representing the src/net/data/ssl/certificates |
80 // directory in the source tree. | 165 // directory in the source tree. |
81 FilePath GetTestCertsDirectory() { | 166 FilePath GetTestCertsDirectory() { |
82 FilePath certs_dir; | 167 FilePath certs_dir; |
83 PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir); | 168 PathService::Get(base::DIR_SOURCE_ROOT, &certs_dir); |
84 certs_dir = certs_dir.AppendASCII("net"); | 169 certs_dir = certs_dir.AppendASCII("net"); |
85 certs_dir = certs_dir.AppendASCII("data"); | 170 certs_dir = certs_dir.AppendASCII("data"); |
86 certs_dir = certs_dir.AppendASCII("ssl"); | 171 certs_dir = certs_dir.AppendASCII("ssl"); |
87 certs_dir = certs_dir.AppendASCII("certificates"); | 172 certs_dir = certs_dir.AppendASCII("certificates"); |
88 return certs_dir; | 173 return certs_dir; |
89 } | 174 } |
90 | 175 |
91 // Imports a certificate file in the src/net/data/ssl/certificates directory. | 176 // Imports a certificate file in the src/net/data/ssl/certificates directory. |
92 // certs_dir represents the test certificates directory. cert_file is the | 177 // certs_dir represents the test certificates directory. cert_file is the |
93 // name of the certificate file. | 178 // name of the certificate file. |
94 X509Certificate* ImportCertFromFile(const FilePath& certs_dir, | 179 X509Certificate* ImportCertFromFile(const FilePath& certs_dir, |
95 const std::string& cert_file) { | 180 const std::string& cert_file) { |
96 FilePath cert_path = certs_dir.AppendASCII(cert_file); | 181 FilePath cert_path = certs_dir.AppendASCII(cert_file); |
97 std::string cert_data; | 182 std::string cert_data; |
98 if (!file_util::ReadFileToString(cert_path, &cert_data)) | 183 if (!file_util::ReadFileToString(cert_path, &cert_data)) |
99 return NULL; | 184 return NULL; |
100 return X509Certificate::CreateFromBytes(cert_data.data(), cert_data.size()); | 185 return X509Certificate::CreateFromBytes(cert_data.data(), cert_data.size()); |
101 } | 186 } |
102 | 187 |
103 } // namespace | 188 CertificateList CreateCertificateListFromFile( |
| 189 const FilePath& certs_dir, |
| 190 const std::string& cert_file, |
| 191 int format) { |
| 192 FilePath cert_path = certs_dir.AppendASCII(cert_file); |
| 193 std::string cert_data; |
| 194 if (!file_util::ReadFileToString(cert_path, &cert_data)) |
| 195 return CertificateList(); |
| 196 return X509Certificate::CreateCertificateListFromBytes(cert_data.data(), |
| 197 cert_data.size(), |
| 198 format); |
| 199 } |
104 | 200 |
105 TEST(X509CertificateTest, GoogleCertParsing) { | 201 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert, |
106 scoped_refptr<X509Certificate> google_cert = X509Certificate::CreateFromBytes( | 202 unsigned char* expected_fingerprint, |
107 reinterpret_cast<const char*>(google_der), sizeof(google_der)); | 203 double valid_from, double valid_to) { |
108 | |
109 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); | 204 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
110 | 205 |
111 const CertPrincipal& subject = google_cert->subject(); | 206 const CertPrincipal& subject = google_cert->subject(); |
112 EXPECT_EQ("www.google.com", subject.common_name); | 207 EXPECT_EQ("www.google.com", subject.common_name); |
113 EXPECT_EQ("Mountain View", subject.locality_name); | 208 EXPECT_EQ("Mountain View", subject.locality_name); |
114 EXPECT_EQ("California", subject.state_or_province_name); | 209 EXPECT_EQ("California", subject.state_or_province_name); |
115 EXPECT_EQ("US", subject.country_name); | 210 EXPECT_EQ("US", subject.country_name); |
116 EXPECT_EQ(0U, subject.street_addresses.size()); | 211 EXPECT_EQ(0U, subject.street_addresses.size()); |
117 EXPECT_EQ(1U, subject.organization_names.size()); | 212 EXPECT_EQ(1U, subject.organization_names.size()); |
118 EXPECT_EQ("Google Inc", subject.organization_names[0]); | 213 EXPECT_EQ("Google Inc", subject.organization_names[0]); |
119 EXPECT_EQ(0U, subject.organization_unit_names.size()); | 214 EXPECT_EQ(0U, subject.organization_unit_names.size()); |
120 EXPECT_EQ(0U, subject.domain_components.size()); | 215 EXPECT_EQ(0U, subject.domain_components.size()); |
121 | 216 |
122 const CertPrincipal& issuer = google_cert->issuer(); | 217 const CertPrincipal& issuer = google_cert->issuer(); |
123 EXPECT_EQ("Thawte SGC CA", issuer.common_name); | 218 EXPECT_EQ("Thawte SGC CA", issuer.common_name); |
124 EXPECT_EQ("", issuer.locality_name); | 219 EXPECT_EQ("", issuer.locality_name); |
125 EXPECT_EQ("", issuer.state_or_province_name); | 220 EXPECT_EQ("", issuer.state_or_province_name); |
126 EXPECT_EQ("ZA", issuer.country_name); | 221 EXPECT_EQ("ZA", issuer.country_name); |
127 EXPECT_EQ(0U, issuer.street_addresses.size()); | 222 EXPECT_EQ(0U, issuer.street_addresses.size()); |
128 EXPECT_EQ(1U, issuer.organization_names.size()); | 223 EXPECT_EQ(1U, issuer.organization_names.size()); |
129 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]); | 224 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]); |
130 EXPECT_EQ(0U, issuer.organization_unit_names.size()); | 225 EXPECT_EQ(0U, issuer.organization_unit_names.size()); |
131 EXPECT_EQ(0U, issuer.domain_components.size()); | 226 EXPECT_EQ(0U, issuer.domain_components.size()); |
132 | 227 |
133 // Use DoubleT because its epoch is the same on all platforms | 228 // Use DoubleT because its epoch is the same on all platforms |
134 const Time& valid_start = google_cert->valid_start(); | 229 const Time& valid_start = google_cert->valid_start(); |
135 EXPECT_EQ(1238192407, valid_start.ToDoubleT()); // Mar 27 22:20:07 2009 GMT | 230 EXPECT_EQ(valid_from, valid_start.ToDoubleT()); |
136 | 231 |
137 const Time& valid_expiry = google_cert->valid_expiry(); | 232 const Time& valid_expiry = google_cert->valid_expiry(); |
138 EXPECT_EQ(1269728407, valid_expiry.ToDoubleT()); // Mar 27 22:20:07 2010 GMT | 233 EXPECT_EQ(valid_to, valid_expiry.ToDoubleT()); |
139 | 234 |
140 const SHA1Fingerprint& fingerprint = google_cert->fingerprint(); | 235 const SHA1Fingerprint& fingerprint = google_cert->fingerprint(); |
141 for (size_t i = 0; i < 20; ++i) | 236 for (size_t i = 0; i < 20; ++i) |
142 EXPECT_EQ(google_fingerprint[i], fingerprint.data[i]); | 237 EXPECT_EQ(expected_fingerprint[i], fingerprint.data[i]); |
143 | 238 |
144 std::vector<std::string> dns_names; | 239 std::vector<std::string> dns_names; |
145 google_cert->GetDNSNames(&dns_names); | 240 google_cert->GetDNSNames(&dns_names); |
146 EXPECT_EQ(1U, dns_names.size()); | 241 EXPECT_EQ(1U, dns_names.size()); |
147 EXPECT_EQ("www.google.com", dns_names[0]); | 242 EXPECT_EQ("www.google.com", dns_names[0]); |
148 | 243 |
149 #if TEST_EV | 244 #if TEST_EV |
150 // TODO(avi): turn this on for the Mac once EV checking is implemented. | 245 // TODO(avi): turn this on for the Mac once EV checking is implemented. |
151 CertVerifyResult verify_result; | 246 CertVerifyResult verify_result; |
152 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | | 247 int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED | |
153 X509Certificate::VERIFY_EV_CERT; | 248 X509Certificate::VERIFY_EV_CERT; |
154 EXPECT_EQ(OK, google_cert->Verify("www.google.com", flags, &verify_result)); | 249 EXPECT_EQ(OK, google_cert->Verify("www.google.com", flags, &verify_result)); |
155 EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV); | 250 EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV); |
156 #endif | 251 #endif |
157 } | 252 } |
158 | 253 |
| 254 TEST(X509CertificateTest, GoogleCertParsing) { |
| 255 scoped_refptr<X509Certificate> google_cert = |
| 256 X509Certificate::CreateFromBytes( |
| 257 reinterpret_cast<const char*>(google_der), sizeof(google_der)); |
| 258 |
| 259 CheckGoogleCert(google_cert, google_fingerprint, |
| 260 1238192407, // Mar 27 22:20:07 2009 GMT |
| 261 1269728407); // Mar 27 22:20:07 2010 GMT |
| 262 } |
| 263 |
159 TEST(X509CertificateTest, WebkitCertParsing) { | 264 TEST(X509CertificateTest, WebkitCertParsing) { |
160 scoped_refptr<X509Certificate> webkit_cert = X509Certificate::CreateFromBytes( | 265 scoped_refptr<X509Certificate> webkit_cert = X509Certificate::CreateFromBytes( |
161 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); | 266 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)); |
162 | 267 |
163 ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert); | 268 ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert); |
164 | 269 |
165 const CertPrincipal& subject = webkit_cert->subject(); | 270 const CertPrincipal& subject = webkit_cert->subject(); |
166 EXPECT_EQ("Cupertino", subject.locality_name); | 271 EXPECT_EQ("Cupertino", subject.locality_name); |
167 EXPECT_EQ("California", subject.state_or_province_name); | 272 EXPECT_EQ("California", subject.state_or_province_name); |
168 EXPECT_EQ("US", subject.country_name); | 273 EXPECT_EQ("US", subject.country_name); |
(...skipping 352 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
521 google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates3); | 626 google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates3); |
522 | 627 |
523 // The cache should have returned cert2 'cause it has more intermediates: | 628 // The cache should have returned cert2 'cause it has more intermediates: |
524 EXPECT_EQ(cert3, cert2); | 629 EXPECT_EQ(cert3, cert2); |
525 | 630 |
526 // Cleanup | 631 // Cleanup |
527 X509Certificate::FreeOSCertHandle(google_handle); | 632 X509Certificate::FreeOSCertHandle(google_handle); |
528 } | 633 } |
529 #endif | 634 #endif |
530 | 635 |
| 636 class X509CertificateParseTest |
| 637 : public testing::TestWithParam<CertificateFormatTestData> { |
| 638 public: |
| 639 virtual ~X509CertificateParseTest() {} |
| 640 virtual void SetUp() { |
| 641 test_data_ = GetParam(); |
| 642 } |
| 643 virtual void TearDown() {} |
| 644 |
| 645 protected: |
| 646 CertificateFormatTestData test_data_; |
| 647 }; |
| 648 |
| 649 TEST_P(X509CertificateParseTest, CanParseFormat) { |
| 650 FilePath certs_dir = GetTestCertsDirectory(); |
| 651 CertificateList certs = CreateCertificateListFromFile( |
| 652 certs_dir, test_data_.file_name, test_data_.format); |
| 653 ASSERT_FALSE(certs.empty()); |
| 654 ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints)); |
| 655 CheckGoogleCert(certs.front(), google_parse_fingerprint, |
| 656 kGoogleParseValidFrom, kGoogleParseValidTo); |
| 657 |
| 658 size_t i; |
| 659 for (i = 0; i < arraysize(test_data_.chain_fingerprints) && |
| 660 i < certs.size() && test_data_.chain_fingerprints[i] != NULL; ++i) { |
| 661 const X509Certificate* cert = certs[i]; |
| 662 const SHA1Fingerprint& actual_fingerprint = cert->fingerprint(); |
| 663 unsigned char* expected_fingerprint = test_data_.chain_fingerprints[i]; |
| 664 |
| 665 for (size_t j = 0; j < 20; ++j) |
| 666 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]); |
| 667 } |
| 668 } |
| 669 |
| 670 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest, |
| 671 testing::ValuesIn(FormatTestData)); |
| 672 |
531 } // namespace net | 673 } // namespace net |
OLD | NEW |