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/base/x509_certificate.h" | |
| 6 | |
| 7 #include "base/basictypes.h" | |
| 5 #include "base/file_path.h" | 8 #include "base/file_path.h" |
| 6 #include "base/memory/scoped_ptr.h" | 9 #include "base/memory/scoped_ptr.h" |
| 7 #include "base/pickle.h" | 10 #include "base/pickle.h" |
| 8 #include "base/sha1.h" | 11 #include "base/sha1.h" |
| 9 #include "base/string_number_conversions.h" | 12 #include "base/string_number_conversions.h" |
| 10 #include "base/string_split.h" | 13 #include "base/string_split.h" |
| 11 #include "crypto/rsa_private_key.h" | 14 #include "crypto/rsa_private_key.h" |
| 12 #include "net/base/asn1_util.h" | 15 #include "net/base/asn1_util.h" |
| 13 #include "net/base/cert_test_util.h" | 16 #include "net/base/cert_test_util.h" |
| 14 #include "net/base/net_errors.h" | 17 #include "net/base/net_errors.h" |
| 15 #include "net/base/test_certificate_data.h" | 18 #include "net/base/test_certificate_data.h" |
| 16 #include "net/base/x509_certificate.h" | |
| 17 #include "testing/gtest/include/gtest/gtest.h" | 19 #include "testing/gtest/include/gtest/gtest.h" |
| 18 | 20 |
| 19 #if defined(USE_NSS) | 21 #if defined(USE_NSS) |
| 20 #include <cert.h> | 22 #include <cert.h> |
| 21 #endif | 23 #endif |
| 22 | 24 |
| 23 using base::HexEncode; | 25 using base::HexEncode; |
| 24 using base::Time; | 26 using base::Time; |
| 25 | 27 |
| 26 namespace net { | 28 namespace net { |
| 27 | 29 |
| 28 // Certificates for test data. They're obtained with: | 30 // Certificates for test data. They're obtained with: |
| 29 // | 31 // |
| 30 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null | 32 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null |
| 31 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der | 33 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der |
| 32 // | 34 // |
| 33 // For fingerprint | 35 // For fingerprint |
| 34 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der | 36 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der |
| 35 | 37 |
| 36 // For valid_start, valid_expiry | 38 // For valid_start, valid_expiry |
| 37 // $ openssl x509 -inform DER -text -noout < /tmp/host.der | | 39 // $ openssl x509 -inform DER -text -noout < /tmp/host.der | |
| 38 // grep -A 2 Validity | 40 // grep -A 2 Validity |
| 39 // $ date +%s -d '<date str>' | 41 // $ date +%s -d '<date str>' |
| 40 | 42 |
| 41 // Google's cert. | 43 // Google's cert. |
| 42 unsigned char google_fingerprint[] = { | 44 uint8 google_fingerprint[] = { |
|
wtc
2012/04/03 23:11:42
We sometimes use 'unsigned char' to mean a byte, b
| |
| 43 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8, | 45 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8, |
| 44 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c | 46 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c |
| 45 }; | 47 }; |
| 46 | 48 |
| 47 // webkit.org's cert. | 49 // webkit.org's cert. |
| 48 unsigned char webkit_fingerprint[] = { | 50 uint8 webkit_fingerprint[] = { |
| 49 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8, | 51 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8, |
| 50 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2 | 52 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2 |
| 51 }; | 53 }; |
| 52 | 54 |
| 53 // thawte.com's cert (it's EV-licious!). | 55 // thawte.com's cert (it's EV-licious!). |
| 54 unsigned char thawte_fingerprint[] = { | 56 uint8 thawte_fingerprint[] = { |
| 55 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6, | 57 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6, |
| 56 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37 | 58 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37 |
| 57 }; | 59 }; |
| 58 | 60 |
| 59 // A certificate for https://www.unosoft.hu/, whose AIA extension contains | 61 // A certificate for https://www.unosoft.hu/, whose AIA extension contains |
| 60 // an LDAP URL without a host name. | 62 // an LDAP URL without a host name. |
| 61 unsigned char unosoft_hu_fingerprint[] = { | 63 uint8 unosoft_hu_fingerprint[] = { |
| 62 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd, | 64 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd, |
| 63 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8 | 65 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8 |
| 64 }; | 66 }; |
| 65 | 67 |
| 66 // The fingerprint of the Google certificate used in the parsing tests, | 68 // The fingerprint of the Google certificate used in the parsing tests, |
| 67 // which is newer than the one included in the x509_certificate_data.h | 69 // which is newer than the one included in the x509_certificate_data.h |
| 68 unsigned char google_parse_fingerprint[] = { | 70 uint8 google_parse_fingerprint[] = { |
| 69 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a, | 71 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a, |
| 70 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2 | 72 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2 |
| 71 }; | 73 }; |
| 72 | 74 |
| 73 // The fingerprint for the Thawte SGC certificate | 75 // The fingerprint for the Thawte SGC certificate |
| 74 unsigned char thawte_parse_fingerprint[] = { | 76 uint8 thawte_parse_fingerprint[] = { |
| 75 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f, | 77 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f, |
| 76 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02 | 78 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02 |
| 77 }; | 79 }; |
| 78 | 80 |
| 79 // Dec 18 00:00:00 2009 GMT | 81 // Dec 18 00:00:00 2009 GMT |
| 80 const double kGoogleParseValidFrom = 1261094400; | 82 const double kGoogleParseValidFrom = 1261094400; |
| 81 // Dec 18 23:59:59 2011 GMT | 83 // Dec 18 23:59:59 2011 GMT |
| 82 const double kGoogleParseValidTo = 1324252799; | 84 const double kGoogleParseValidTo = 1324252799; |
| 83 | 85 |
| 84 struct CertificateFormatTestData { | 86 struct CertificateFormatTestData { |
| 85 const char* file_name; | 87 const char* file_name; |
| 86 X509Certificate::Format format; | 88 X509Certificate::Format format; |
| 87 unsigned char* chain_fingerprints[3]; | 89 uint8* chain_fingerprints[3]; |
| 88 }; | 90 }; |
| 89 | 91 |
| 90 const CertificateFormatTestData FormatTestData[] = { | 92 const CertificateFormatTestData FormatTestData[] = { |
| 91 // DER Parsing - single certificate, DER encoded | 93 // DER Parsing - single certificate, DER encoded |
| 92 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE, | 94 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE, |
| 93 { google_parse_fingerprint, | 95 { google_parse_fingerprint, |
| 94 NULL, } }, | 96 NULL, } }, |
| 95 // DER parsing - single certificate, PEM encoded | 97 // DER parsing - single certificate, PEM encoded |
| 96 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE, | 98 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE, |
| 97 { google_parse_fingerprint, | 99 { google_parse_fingerprint, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 144 { google_parse_fingerprint, | 146 { google_parse_fingerprint, |
| 145 thawte_parse_fingerprint, | 147 thawte_parse_fingerprint, |
| 146 NULL, } }, | 148 NULL, } }, |
| 147 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO, | 149 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO, |
| 148 { google_parse_fingerprint, | 150 { google_parse_fingerprint, |
| 149 thawte_parse_fingerprint, | 151 thawte_parse_fingerprint, |
| 150 NULL, } }, | 152 NULL, } }, |
| 151 }; | 153 }; |
| 152 | 154 |
| 153 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert, | 155 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert, |
| 154 unsigned char* expected_fingerprint, | 156 uint8* expected_fingerprint, |
| 155 double valid_from, double valid_to) { | 157 double valid_from, double valid_to) { |
| 156 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); | 158 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert); |
| 157 | 159 |
| 158 const CertPrincipal& subject = google_cert->subject(); | 160 const CertPrincipal& subject = google_cert->subject(); |
| 159 EXPECT_EQ("www.google.com", subject.common_name); | 161 EXPECT_EQ("www.google.com", subject.common_name); |
| 160 EXPECT_EQ("Mountain View", subject.locality_name); | 162 EXPECT_EQ("Mountain View", subject.locality_name); |
| 161 EXPECT_EQ("California", subject.state_or_province_name); | 163 EXPECT_EQ("California", subject.state_or_province_name); |
| 162 EXPECT_EQ("US", subject.country_name); | 164 EXPECT_EQ("US", subject.country_name); |
| 163 EXPECT_EQ(0U, subject.street_addresses.size()); | 165 EXPECT_EQ(0U, subject.street_addresses.size()); |
| 164 ASSERT_EQ(1U, subject.organization_names.size()); | 166 ASSERT_EQ(1U, subject.organization_names.size()); |
| (...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 | 433 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09 |
| 432 }; | 434 }; |
| 433 EXPECT_TRUE(memcmp(cert_chain1->ca_fingerprint().data, | 435 EXPECT_TRUE(memcmp(cert_chain1->ca_fingerprint().data, |
| 434 cert_chain1_ca_fingerprint, 20) == 0); | 436 cert_chain1_ca_fingerprint, 20) == 0); |
| 435 EXPECT_TRUE(memcmp(cert_chain2->ca_fingerprint().data, | 437 EXPECT_TRUE(memcmp(cert_chain2->ca_fingerprint().data, |
| 436 cert_chain2_ca_fingerprint, 20) == 0); | 438 cert_chain2_ca_fingerprint, 20) == 0); |
| 437 EXPECT_TRUE(memcmp(cert_chain3->ca_fingerprint().data, | 439 EXPECT_TRUE(memcmp(cert_chain3->ca_fingerprint().data, |
| 438 cert_chain3_ca_fingerprint, 20) == 0); | 440 cert_chain3_ca_fingerprint, 20) == 0); |
| 439 } | 441 } |
| 440 | 442 |
| 443 TEST(X509CertificateTest, ParseSubjectAltNames) { | |
| 444 FilePath certs_dir = GetTestCertsDirectory(); | |
| 445 | |
| 446 scoped_refptr<X509Certificate> san_cert = | |
| 447 ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem"); | |
| 448 ASSERT_NE(static_cast<X509Certificate*>(NULL), san_cert); | |
| 449 | |
| 450 std::vector<std::string> dns_names; | |
| 451 std::vector<std::string> ip_addresses; | |
| 452 san_cert->GetSubjectAltName(&dns_names, &ip_addresses); | |
| 453 | |
| 454 // Ensure that DNS names are correctly parsed. | |
| 455 ASSERT_EQ(1U, dns_names.size()); | |
| 456 EXPECT_EQ("test.example", dns_names[0]); | |
| 457 | |
| 458 // Ensure that both IPv4 and IPv6 addresses are correctly parsed. | |
| 459 ASSERT_EQ(2U, ip_addresses.size()); | |
| 460 | |
| 461 static const uint8 kIPv4Address[] = { | |
| 462 0x7F, 0x00, 0x00, 0x02 | |
| 463 }; | |
| 464 ASSERT_EQ(arraysize(kIPv4Address), ip_addresses[0].size()); | |
| 465 EXPECT_EQ(0, memcmp(ip_addresses[0].data(), kIPv4Address, | |
| 466 arraysize(kIPv4Address))); | |
| 467 | |
| 468 static const uint8 kIPv6Address[] = { | |
| 469 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, | |
| 470 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01 | |
| 471 }; | |
| 472 ASSERT_EQ(arraysize(kIPv6Address), ip_addresses[1].size()); | |
| 473 EXPECT_EQ(0, memcmp(ip_addresses[1].data(), kIPv6Address, | |
| 474 arraysize(kIPv6Address))); | |
| 475 | |
| 476 // Ensure the subjectAltName dirName has not influenced the handling of | |
| 477 // the subject commonName. | |
| 478 EXPECT_EQ("127.0.0.1", san_cert->subject().common_name); | |
| 479 } | |
| 480 | |
| 441 TEST(X509CertificateTest, ExtractSPKIFromDERCert) { | 481 TEST(X509CertificateTest, ExtractSPKIFromDERCert) { |
| 442 FilePath certs_dir = GetTestCertsDirectory(); | 482 FilePath certs_dir = GetTestCertsDirectory(); |
| 443 scoped_refptr<X509Certificate> cert = | 483 scoped_refptr<X509Certificate> cert = |
| 444 ImportCertFromFile(certs_dir, "nist.der"); | 484 ImportCertFromFile(certs_dir, "nist.der"); |
| 445 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); | 485 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert); |
| 446 | 486 |
| 447 std::string derBytes; | 487 std::string derBytes; |
| 448 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), | 488 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(), |
| 449 &derBytes)); | 489 &derBytes)); |
| 450 | 490 |
| (...skipping 391 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 842 break; | 882 break; |
| 843 } | 883 } |
| 844 | 884 |
| 845 // A cert is expected - make sure that one was parsed. | 885 // A cert is expected - make sure that one was parsed. |
| 846 ASSERT_LT(i, certs.size()); | 886 ASSERT_LT(i, certs.size()); |
| 847 | 887 |
| 848 // Compare the parsed certificate with the expected certificate, by | 888 // Compare the parsed certificate with the expected certificate, by |
| 849 // comparing fingerprints. | 889 // comparing fingerprints. |
| 850 const X509Certificate* cert = certs[i]; | 890 const X509Certificate* cert = certs[i]; |
| 851 const SHA1Fingerprint& actual_fingerprint = cert->fingerprint(); | 891 const SHA1Fingerprint& actual_fingerprint = cert->fingerprint(); |
| 852 unsigned char* expected_fingerprint = test_data_.chain_fingerprints[i]; | 892 uint8* expected_fingerprint = test_data_.chain_fingerprints[i]; |
| 853 | 893 |
| 854 for (size_t j = 0; j < 20; ++j) | 894 for (size_t j = 0; j < 20; ++j) |
| 855 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]); | 895 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]); |
| 856 } | 896 } |
| 857 } | 897 } |
| 858 | 898 |
| 859 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest, | 899 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest, |
| 860 testing::ValuesIn(FormatTestData)); | 900 testing::ValuesIn(FormatTestData)); |
| 861 | 901 |
| 862 struct CertificateNameVerifyTestData { | 902 struct CertificateNameVerifyTestData { |
| (...skipping 202 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1065 } | 1105 } |
| 1066 | 1106 |
| 1067 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( | 1107 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname( |
| 1068 test_data.hostname, common_name, dns_names, ip_addressses)); | 1108 test_data.hostname, common_name, dns_names, ip_addressses)); |
| 1069 } | 1109 } |
| 1070 | 1110 |
| 1071 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, | 1111 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest, |
| 1072 testing::ValuesIn(kNameVerifyTestData)); | 1112 testing::ValuesIn(kNameVerifyTestData)); |
| 1073 | 1113 |
| 1074 } // namespace net | 1114 } // namespace net |
| OLD | NEW |