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