Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(134)

Side by Side Diff: net/base/x509_certificate_unittest.cc

Issue 2819018: Add support for parsing certificate formats other than raw, DER-encoded cert... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: Fixup some variables/comments per wtc Created 10 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « net/base/x509_certificate_nss.cc ('k') | net/base/x509_certificate_win.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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
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
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
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
OLDNEW
« no previous file with comments | « net/base/x509_certificate_nss.cc ('k') | net/base/x509_certificate_win.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698