Fix "#if defined(DEBUG)" statements
[chromium-blink-merge.git] / net / cert / x509_certificate_unittest.cc
blob339851042c62fbc7663165be8cf69f13d89662cd
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
3 // found in the LICENSE file.
5 #include "net/cert/x509_certificate.h"
7 #include "base/basictypes.h"
8 #include "base/files/file_path.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/pickle.h"
11 #include "base/sha1.h"
12 #include "base/strings/string_number_conversions.h"
13 #include "base/strings/string_split.h"
14 #include "base/strings/string_util.h"
15 #include "crypto/rsa_private_key.h"
16 #include "net/base/net_errors.h"
17 #include "net/base/test_data_directory.h"
18 #include "net/cert/asn1_util.h"
19 #include "net/test/cert_test_util.h"
20 #include "net/test/test_certificate_data.h"
21 #include "testing/gtest/include/gtest/gtest.h"
23 #if defined(USE_NSS)
24 #include <cert.h>
25 #endif
27 #if defined(OS_WIN)
28 #include "base/win/windows_version.h"
29 #endif
31 using base::HexEncode;
32 using base::Time;
34 namespace net {
36 // Certificates for test data. They're obtained with:
38 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null
39 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der
41 // For fingerprint
42 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
44 // For valid_start, valid_expiry
45 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
46 // grep -A 2 Validity
47 // $ date +%s -d '<date str>'
49 // Google's cert.
50 uint8 google_fingerprint[] = {
51 0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8,
52 0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c
55 // webkit.org's cert.
56 uint8 webkit_fingerprint[] = {
57 0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8,
58 0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2
61 // thawte.com's cert (it's EV-licious!).
62 uint8 thawte_fingerprint[] = {
63 0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6,
64 0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37
67 // A certificate for https://www.unosoft.hu/, whose AIA extension contains
68 // an LDAP URL without a host name.
69 uint8 unosoft_hu_fingerprint[] = {
70 0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd,
71 0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8
74 // The fingerprint of the Google certificate used in the parsing tests,
75 // which is newer than the one included in the x509_certificate_data.h
76 uint8 google_parse_fingerprint[] = {
77 0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a,
78 0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2
81 // The fingerprint for the Thawte SGC certificate
82 uint8 thawte_parse_fingerprint[] = {
83 0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f,
84 0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02
87 // Dec 18 00:00:00 2009 GMT
88 const double kGoogleParseValidFrom = 1261094400;
89 // Dec 18 23:59:59 2011 GMT
90 const double kGoogleParseValidTo = 1324252799;
92 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert,
93 uint8* expected_fingerprint,
94 double valid_from, double valid_to) {
95 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert.get());
97 const CertPrincipal& subject = google_cert->subject();
98 EXPECT_EQ("www.google.com", subject.common_name);
99 EXPECT_EQ("Mountain View", subject.locality_name);
100 EXPECT_EQ("California", subject.state_or_province_name);
101 EXPECT_EQ("US", subject.country_name);
102 EXPECT_EQ(0U, subject.street_addresses.size());
103 ASSERT_EQ(1U, subject.organization_names.size());
104 EXPECT_EQ("Google Inc", subject.organization_names[0]);
105 EXPECT_EQ(0U, subject.organization_unit_names.size());
106 EXPECT_EQ(0U, subject.domain_components.size());
108 const CertPrincipal& issuer = google_cert->issuer();
109 EXPECT_EQ("Thawte SGC CA", issuer.common_name);
110 EXPECT_EQ("", issuer.locality_name);
111 EXPECT_EQ("", issuer.state_or_province_name);
112 EXPECT_EQ("ZA", issuer.country_name);
113 EXPECT_EQ(0U, issuer.street_addresses.size());
114 ASSERT_EQ(1U, issuer.organization_names.size());
115 EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]);
116 EXPECT_EQ(0U, issuer.organization_unit_names.size());
117 EXPECT_EQ(0U, issuer.domain_components.size());
119 // Use DoubleT because its epoch is the same on all platforms
120 const Time& valid_start = google_cert->valid_start();
121 EXPECT_EQ(valid_from, valid_start.ToDoubleT());
123 const Time& valid_expiry = google_cert->valid_expiry();
124 EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
126 const SHA1HashValue& fingerprint = google_cert->fingerprint();
127 for (size_t i = 0; i < 20; ++i)
128 EXPECT_EQ(expected_fingerprint[i], fingerprint.data[i]);
130 std::vector<std::string> dns_names;
131 google_cert->GetDNSNames(&dns_names);
132 ASSERT_EQ(1U, dns_names.size());
133 EXPECT_EQ("www.google.com", dns_names[0]);
136 TEST(X509CertificateTest, GoogleCertParsing) {
137 scoped_refptr<X509Certificate> google_cert(
138 X509Certificate::CreateFromBytes(
139 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
141 CheckGoogleCert(google_cert, google_fingerprint,
142 1238192407, // Mar 27 22:20:07 2009 GMT
143 1269728407); // Mar 27 22:20:07 2010 GMT
146 TEST(X509CertificateTest, WebkitCertParsing) {
147 scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
148 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
150 ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert.get());
152 const CertPrincipal& subject = webkit_cert->subject();
153 EXPECT_EQ("Cupertino", subject.locality_name);
154 EXPECT_EQ("California", subject.state_or_province_name);
155 EXPECT_EQ("US", subject.country_name);
156 EXPECT_EQ(0U, subject.street_addresses.size());
157 ASSERT_EQ(1U, subject.organization_names.size());
158 EXPECT_EQ("Apple Inc.", subject.organization_names[0]);
159 ASSERT_EQ(1U, subject.organization_unit_names.size());
160 EXPECT_EQ("Mac OS Forge", subject.organization_unit_names[0]);
161 EXPECT_EQ(0U, subject.domain_components.size());
163 const CertPrincipal& issuer = webkit_cert->issuer();
164 EXPECT_EQ("Go Daddy Secure Certification Authority", issuer.common_name);
165 EXPECT_EQ("Scottsdale", issuer.locality_name);
166 EXPECT_EQ("Arizona", issuer.state_or_province_name);
167 EXPECT_EQ("US", issuer.country_name);
168 EXPECT_EQ(0U, issuer.street_addresses.size());
169 ASSERT_EQ(1U, issuer.organization_names.size());
170 EXPECT_EQ("GoDaddy.com, Inc.", issuer.organization_names[0]);
171 ASSERT_EQ(1U, issuer.organization_unit_names.size());
172 EXPECT_EQ("http://certificates.godaddy.com/repository",
173 issuer.organization_unit_names[0]);
174 EXPECT_EQ(0U, issuer.domain_components.size());
176 // Use DoubleT because its epoch is the same on all platforms
177 const Time& valid_start = webkit_cert->valid_start();
178 EXPECT_EQ(1205883319, valid_start.ToDoubleT()); // Mar 18 23:35:19 2008 GMT
180 const Time& valid_expiry = webkit_cert->valid_expiry();
181 EXPECT_EQ(1300491319, valid_expiry.ToDoubleT()); // Mar 18 23:35:19 2011 GMT
183 const SHA1HashValue& fingerprint = webkit_cert->fingerprint();
184 for (size_t i = 0; i < 20; ++i)
185 EXPECT_EQ(webkit_fingerprint[i], fingerprint.data[i]);
187 std::vector<std::string> dns_names;
188 webkit_cert->GetDNSNames(&dns_names);
189 ASSERT_EQ(2U, dns_names.size());
190 EXPECT_EQ("*.webkit.org", dns_names[0]);
191 EXPECT_EQ("webkit.org", dns_names[1]);
193 // Test that the wildcard cert matches properly.
194 bool unused = false;
195 EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org", &unused));
196 EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org", &unused));
197 EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org", &unused));
198 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com", &unused));
199 EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com", &unused));
202 TEST(X509CertificateTest, ThawteCertParsing) {
203 scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes(
204 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
206 ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert.get());
208 const CertPrincipal& subject = thawte_cert->subject();
209 EXPECT_EQ("www.thawte.com", subject.common_name);
210 EXPECT_EQ("Mountain View", subject.locality_name);
211 EXPECT_EQ("California", subject.state_or_province_name);
212 EXPECT_EQ("US", subject.country_name);
213 EXPECT_EQ(0U, subject.street_addresses.size());
214 ASSERT_EQ(1U, subject.organization_names.size());
215 EXPECT_EQ("Thawte Inc", subject.organization_names[0]);
216 EXPECT_EQ(0U, subject.organization_unit_names.size());
217 EXPECT_EQ(0U, subject.domain_components.size());
219 const CertPrincipal& issuer = thawte_cert->issuer();
220 EXPECT_EQ("thawte Extended Validation SSL CA", issuer.common_name);
221 EXPECT_EQ("", issuer.locality_name);
222 EXPECT_EQ("", issuer.state_or_province_name);
223 EXPECT_EQ("US", issuer.country_name);
224 EXPECT_EQ(0U, issuer.street_addresses.size());
225 ASSERT_EQ(1U, issuer.organization_names.size());
226 EXPECT_EQ("thawte, Inc.", issuer.organization_names[0]);
227 ASSERT_EQ(1U, issuer.organization_unit_names.size());
228 EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06",
229 issuer.organization_unit_names[0]);
230 EXPECT_EQ(0U, issuer.domain_components.size());
232 // Use DoubleT because its epoch is the same on all platforms
233 const Time& valid_start = thawte_cert->valid_start();
234 EXPECT_EQ(1227052800, valid_start.ToDoubleT()); // Nov 19 00:00:00 2008 GMT
236 const Time& valid_expiry = thawte_cert->valid_expiry();
237 EXPECT_EQ(1263772799, valid_expiry.ToDoubleT()); // Jan 17 23:59:59 2010 GMT
239 const SHA1HashValue& fingerprint = thawte_cert->fingerprint();
240 for (size_t i = 0; i < 20; ++i)
241 EXPECT_EQ(thawte_fingerprint[i], fingerprint.data[i]);
243 std::vector<std::string> dns_names;
244 thawte_cert->GetDNSNames(&dns_names);
245 ASSERT_EQ(1U, dns_names.size());
246 EXPECT_EQ("www.thawte.com", dns_names[0]);
249 // Test that all desired AttributeAndValue pairs can be extracted when only
250 // a single RelativeDistinguishedName is present. "Normally" there is only
251 // one AVA per RDN, but some CAs place all AVAs within a single RDN.
252 // This is a regression test for http://crbug.com/101009
253 TEST(X509CertificateTest, MultivalueRDN) {
254 base::FilePath certs_dir = GetTestCertsDirectory();
256 scoped_refptr<X509Certificate> multivalue_rdn_cert =
257 ImportCertFromFile(certs_dir, "multivalue_rdn.pem");
258 ASSERT_NE(static_cast<X509Certificate*>(NULL), multivalue_rdn_cert.get());
260 const CertPrincipal& subject = multivalue_rdn_cert->subject();
261 EXPECT_EQ("Multivalue RDN Test", subject.common_name);
262 EXPECT_EQ("", subject.locality_name);
263 EXPECT_EQ("", subject.state_or_province_name);
264 EXPECT_EQ("US", subject.country_name);
265 EXPECT_EQ(0U, subject.street_addresses.size());
266 ASSERT_EQ(1U, subject.organization_names.size());
267 EXPECT_EQ("Chromium", subject.organization_names[0]);
268 ASSERT_EQ(1U, subject.organization_unit_names.size());
269 EXPECT_EQ("Chromium net_unittests", subject.organization_unit_names[0]);
270 ASSERT_EQ(1U, subject.domain_components.size());
271 EXPECT_EQ("Chromium", subject.domain_components[0]);
274 // Test that characters which would normally be escaped in the string form,
275 // such as '=' or '"', are not escaped when parsed as individual components.
276 // This is a regression test for http://crbug.com/102839
277 TEST(X509CertificateTest, UnescapedSpecialCharacters) {
278 base::FilePath certs_dir = GetTestCertsDirectory();
280 scoped_refptr<X509Certificate> unescaped_cert =
281 ImportCertFromFile(certs_dir, "unescaped.pem");
282 ASSERT_NE(static_cast<X509Certificate*>(NULL), unescaped_cert.get());
284 const CertPrincipal& subject = unescaped_cert->subject();
285 EXPECT_EQ("127.0.0.1", subject.common_name);
286 EXPECT_EQ("Mountain View", subject.locality_name);
287 EXPECT_EQ("California", subject.state_or_province_name);
288 EXPECT_EQ("US", subject.country_name);
289 ASSERT_EQ(1U, subject.street_addresses.size());
290 EXPECT_EQ("1600 Amphitheatre Parkway", subject.street_addresses[0]);
291 ASSERT_EQ(1U, subject.organization_names.size());
292 EXPECT_EQ("Chromium = \"net_unittests\"", subject.organization_names[0]);
293 ASSERT_EQ(2U, subject.organization_unit_names.size());
294 EXPECT_EQ("net_unittests", subject.organization_unit_names[0]);
295 EXPECT_EQ("Chromium", subject.organization_unit_names[1]);
296 EXPECT_EQ(0U, subject.domain_components.size());
299 TEST(X509CertificateTest, SerialNumbers) {
300 scoped_refptr<X509Certificate> google_cert(
301 X509Certificate::CreateFromBytes(
302 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
304 static const uint8 google_serial[16] = {
305 0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,
306 0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a,
309 ASSERT_EQ(sizeof(google_serial), google_cert->serial_number().size());
310 EXPECT_TRUE(memcmp(google_cert->serial_number().data(), google_serial,
311 sizeof(google_serial)) == 0);
313 // We also want to check a serial number where the first byte is >= 0x80 in
314 // case the underlying library tries to pad it.
315 scoped_refptr<X509Certificate> paypal_null_cert(
316 X509Certificate::CreateFromBytes(
317 reinterpret_cast<const char*>(paypal_null_der),
318 sizeof(paypal_null_der)));
320 static const uint8 paypal_null_serial[3] = {0x00, 0xf0, 0x9b};
321 ASSERT_EQ(sizeof(paypal_null_serial),
322 paypal_null_cert->serial_number().size());
323 EXPECT_TRUE(memcmp(paypal_null_cert->serial_number().data(),
324 paypal_null_serial, sizeof(paypal_null_serial)) == 0);
327 TEST(X509CertificateTest, SHA256FingerprintsCorrectly) {
328 scoped_refptr<X509Certificate> google_cert(X509Certificate::CreateFromBytes(
329 reinterpret_cast<const char*>(google_der), sizeof(google_der)));
331 static const uint8 google_sha256_fingerprint[32] = {
332 0x21, 0xaf, 0x58, 0x74, 0xea, 0x6b, 0xad, 0xbd, 0xe4, 0xb3, 0xb1,
333 0xaa, 0x53, 0x32, 0x80, 0x8f, 0xbf, 0x8a, 0x24, 0x7d, 0x98, 0xec,
334 0x7f, 0x77, 0x49, 0x38, 0x42, 0x81, 0x26, 0x7f, 0xed, 0x38};
336 SHA256HashValue fingerprint =
337 X509Certificate::CalculateFingerprint256(google_cert->os_cert_handle());
339 for (size_t i = 0; i < 32; ++i)
340 EXPECT_EQ(google_sha256_fingerprint[i], fingerprint.data[i]);
343 TEST(X509CertificateTest, CAFingerprints) {
344 base::FilePath certs_dir = GetTestCertsDirectory();
346 scoped_refptr<X509Certificate> server_cert =
347 ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
348 ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
350 scoped_refptr<X509Certificate> intermediate_cert1 =
351 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2011.pem");
352 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert1.get());
354 scoped_refptr<X509Certificate> intermediate_cert2 =
355 ImportCertFromFile(certs_dir, "verisign_intermediate_ca_2016.pem");
356 ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert2.get());
358 X509Certificate::OSCertHandles intermediates;
359 intermediates.push_back(intermediate_cert1->os_cert_handle());
360 scoped_refptr<X509Certificate> cert_chain1 =
361 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
362 intermediates);
364 intermediates.clear();
365 intermediates.push_back(intermediate_cert2->os_cert_handle());
366 scoped_refptr<X509Certificate> cert_chain2 =
367 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
368 intermediates);
370 // No intermediate CA certicates.
371 intermediates.clear();
372 scoped_refptr<X509Certificate> cert_chain3 =
373 X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
374 intermediates);
376 static const uint8 cert_chain1_ca_fingerprint[20] = {
377 0xc2, 0xf0, 0x08, 0x7d, 0x01, 0xe6, 0x86, 0x05, 0x3a, 0x4d,
378 0x63, 0x3e, 0x7e, 0x70, 0xd4, 0xef, 0x65, 0xc2, 0xcc, 0x4f
380 static const uint8 cert_chain2_ca_fingerprint[20] = {
381 0xd5, 0x59, 0xa5, 0x86, 0x66, 0x9b, 0x08, 0xf4, 0x6a, 0x30,
382 0xa1, 0x33, 0xf8, 0xa9, 0xed, 0x3d, 0x03, 0x8e, 0x2e, 0xa8
384 // The SHA-1 hash of nothing.
385 static const uint8 cert_chain3_ca_fingerprint[20] = {
386 0xda, 0x39, 0xa3, 0xee, 0x5e, 0x6b, 0x4b, 0x0d, 0x32, 0x55,
387 0xbf, 0xef, 0x95, 0x60, 0x18, 0x90, 0xaf, 0xd8, 0x07, 0x09
389 EXPECT_TRUE(memcmp(cert_chain1->ca_fingerprint().data,
390 cert_chain1_ca_fingerprint, 20) == 0);
391 EXPECT_TRUE(memcmp(cert_chain2->ca_fingerprint().data,
392 cert_chain2_ca_fingerprint, 20) == 0);
393 EXPECT_TRUE(memcmp(cert_chain3->ca_fingerprint().data,
394 cert_chain3_ca_fingerprint, 20) == 0);
396 // Test the SHA-256 hash calculation functions explicitly since they are not
397 // used by X509Certificate internally.
398 static const uint8 cert_chain1_ca_fingerprint_256[32] = {
399 0x51, 0x15, 0x30, 0x49, 0x97, 0x54, 0xf8, 0xb4, 0x17, 0x41,
400 0x6b, 0x58, 0x78, 0xb0, 0x89, 0xd2, 0xc3, 0xae, 0x66, 0xc1,
401 0x16, 0x80, 0xa0, 0x78, 0xe7, 0x53, 0x45, 0xa2, 0xfb, 0x80,
402 0xe1, 0x07
404 static const uint8 cert_chain2_ca_fingerprint_256[32] = {
405 0x00, 0xbd, 0x2b, 0x0e, 0xdd, 0x83, 0x40, 0xb1, 0x74, 0x6c,
406 0xc3, 0x95, 0xc0, 0xe3, 0x55, 0xb2, 0x16, 0x58, 0x53, 0xfd,
407 0xb9, 0x3c, 0x52, 0xda, 0xdd, 0xa8, 0x22, 0x8b, 0x07, 0x00,
408 0x2d, 0xce
410 // The SHA-256 hash of nothing.
411 static const uint8 cert_chain3_ca_fingerprint_256[32] = {
412 0xe3, 0xb0, 0xc4, 0x42, 0x98, 0xfc, 0x1c, 0x14, 0x9a, 0xfb,
413 0xf4, 0xc8, 0x99, 0x6f, 0xb9, 0x24, 0x27, 0xae, 0x41, 0xe4,
414 0x64, 0x9b, 0x93, 0x4c, 0xa4, 0x95, 0x99, 0x1b, 0x78, 0x52,
415 0xb8, 0x55
417 SHA256HashValue ca_fingerprint_256_1 =
418 X509Certificate::CalculateCAFingerprint256(
419 cert_chain1->GetIntermediateCertificates());
420 SHA256HashValue ca_fingerprint_256_2 =
421 X509Certificate::CalculateCAFingerprint256(
422 cert_chain2->GetIntermediateCertificates());
423 SHA256HashValue ca_fingerprint_256_3 =
424 X509Certificate::CalculateCAFingerprint256(
425 cert_chain3->GetIntermediateCertificates());
426 EXPECT_TRUE(memcmp(ca_fingerprint_256_1.data,
427 cert_chain1_ca_fingerprint_256, 32) == 0);
428 EXPECT_TRUE(memcmp(ca_fingerprint_256_2.data,
429 cert_chain2_ca_fingerprint_256, 32) == 0);
430 EXPECT_TRUE(memcmp(ca_fingerprint_256_3.data,
431 cert_chain3_ca_fingerprint_256, 32) == 0);
433 static const uint8 cert_chain1_chain_fingerprint_256[32] = {
434 0xac, 0xff, 0xcc, 0x63, 0x0d, 0xd0, 0xa7, 0x19, 0x78, 0xb5,
435 0x8a, 0x47, 0x8b, 0x67, 0x97, 0xcb, 0x8d, 0xe1, 0x6a, 0x8a,
436 0x57, 0x70, 0xda, 0x9a, 0x53, 0x72, 0xe2, 0xa0, 0x08, 0xab,
437 0xcc, 0x8f
439 static const uint8 cert_chain2_chain_fingerprint_256[32] = {
440 0x67, 0x3a, 0x11, 0x20, 0xd6, 0x94, 0x14, 0xe4, 0x16, 0x9f,
441 0x58, 0xe2, 0x8b, 0xf7, 0x27, 0xed, 0xbb, 0xe8, 0xa7, 0xff,
442 0x1c, 0x8c, 0x0f, 0x21, 0x38, 0x16, 0x7c, 0xad, 0x1f, 0x22,
443 0x6f, 0x9b
445 static const uint8 cert_chain3_chain_fingerprint_256[32] = {
446 0x16, 0x7a, 0xbd, 0xb4, 0x57, 0x04, 0x65, 0x3c, 0x3b, 0xef,
447 0x6e, 0x6a, 0xa6, 0x02, 0x73, 0x30, 0x3e, 0x34, 0x1b, 0x43,
448 0xc2, 0x7c, 0x98, 0x52, 0x9f, 0x34, 0x7f, 0x55, 0x97, 0xe9,
449 0x1a, 0x10
451 SHA256HashValue chain_fingerprint_256_1 =
452 X509Certificate::CalculateChainFingerprint256(
453 cert_chain1->os_cert_handle(),
454 cert_chain1->GetIntermediateCertificates());
455 SHA256HashValue chain_fingerprint_256_2 =
456 X509Certificate::CalculateChainFingerprint256(
457 cert_chain2->os_cert_handle(),
458 cert_chain2->GetIntermediateCertificates());
459 SHA256HashValue chain_fingerprint_256_3 =
460 X509Certificate::CalculateChainFingerprint256(
461 cert_chain3->os_cert_handle(),
462 cert_chain3->GetIntermediateCertificates());
463 EXPECT_TRUE(memcmp(chain_fingerprint_256_1.data,
464 cert_chain1_chain_fingerprint_256, 32) == 0);
465 EXPECT_TRUE(memcmp(chain_fingerprint_256_2.data,
466 cert_chain2_chain_fingerprint_256, 32) == 0);
467 EXPECT_TRUE(memcmp(chain_fingerprint_256_3.data,
468 cert_chain3_chain_fingerprint_256, 32) == 0);
471 TEST(X509CertificateTest, ParseSubjectAltNames) {
472 base::FilePath certs_dir = GetTestCertsDirectory();
474 scoped_refptr<X509Certificate> san_cert =
475 ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem");
476 ASSERT_NE(static_cast<X509Certificate*>(NULL), san_cert.get());
478 std::vector<std::string> dns_names;
479 std::vector<std::string> ip_addresses;
480 san_cert->GetSubjectAltName(&dns_names, &ip_addresses);
482 // Ensure that DNS names are correctly parsed.
483 ASSERT_EQ(1U, dns_names.size());
484 EXPECT_EQ("test.example", dns_names[0]);
486 // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
487 ASSERT_EQ(2U, ip_addresses.size());
489 static const uint8 kIPv4Address[] = {
490 0x7F, 0x00, 0x00, 0x02
492 ASSERT_EQ(arraysize(kIPv4Address), ip_addresses[0].size());
493 EXPECT_EQ(0, memcmp(ip_addresses[0].data(), kIPv4Address,
494 arraysize(kIPv4Address)));
496 static const uint8 kIPv6Address[] = {
497 0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
498 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
500 ASSERT_EQ(arraysize(kIPv6Address), ip_addresses[1].size());
501 EXPECT_EQ(0, memcmp(ip_addresses[1].data(), kIPv6Address,
502 arraysize(kIPv6Address)));
504 // Ensure the subjectAltName dirName has not influenced the handling of
505 // the subject commonName.
506 EXPECT_EQ("127.0.0.1", san_cert->subject().common_name);
509 TEST(X509CertificateTest, ExtractSPKIFromDERCert) {
510 base::FilePath certs_dir = GetTestCertsDirectory();
511 scoped_refptr<X509Certificate> cert =
512 ImportCertFromFile(certs_dir, "nist.der");
513 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
515 std::string derBytes;
516 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
517 &derBytes));
519 base::StringPiece spkiBytes;
520 EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes));
522 uint8 hash[base::kSHA1Length];
523 base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()),
524 spkiBytes.size(), hash);
526 EXPECT_EQ(0, memcmp(hash, kNistSPKIHash, sizeof(hash)));
529 TEST(X509CertificateTest, ExtractCRLURLsFromDERCert) {
530 base::FilePath certs_dir = GetTestCertsDirectory();
531 scoped_refptr<X509Certificate> cert =
532 ImportCertFromFile(certs_dir, "nist.der");
533 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
535 std::string derBytes;
536 EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
537 &derBytes));
539 std::vector<base::StringPiece> crl_urls;
540 EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes, &crl_urls));
542 EXPECT_EQ(1u, crl_urls.size());
543 if (crl_urls.size() > 0) {
544 EXPECT_EQ("http://SVRSecure-G3-crl.verisign.com/SVRSecureG3.crl",
545 crl_urls[0].as_string());
549 // Tests X509CertificateCache via X509Certificate::CreateFromHandle. We
550 // call X509Certificate::CreateFromHandle several times and observe whether
551 // it returns a cached or new OSCertHandle.
552 TEST(X509CertificateTest, Cache) {
553 X509Certificate::OSCertHandle google_cert_handle;
554 X509Certificate::OSCertHandle thawte_cert_handle;
556 // Add a single certificate to the certificate cache.
557 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
558 reinterpret_cast<const char*>(google_der), sizeof(google_der));
559 scoped_refptr<X509Certificate> cert1(X509Certificate::CreateFromHandle(
560 google_cert_handle, X509Certificate::OSCertHandles()));
561 X509Certificate::FreeOSCertHandle(google_cert_handle);
563 // Add the same certificate, but as a new handle.
564 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
565 reinterpret_cast<const char*>(google_der), sizeof(google_der));
566 scoped_refptr<X509Certificate> cert2(X509Certificate::CreateFromHandle(
567 google_cert_handle, X509Certificate::OSCertHandles()));
568 X509Certificate::FreeOSCertHandle(google_cert_handle);
570 // A new X509Certificate should be returned.
571 EXPECT_NE(cert1.get(), cert2.get());
572 // But both instances should share the underlying OS certificate handle.
573 EXPECT_EQ(cert1->os_cert_handle(), cert2->os_cert_handle());
574 EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
575 EXPECT_EQ(0u, cert2->GetIntermediateCertificates().size());
577 // Add the same certificate, but this time with an intermediate. This
578 // should result in the intermediate being cached. Note that this is not
579 // a legitimate chain, but is suitable for testing.
580 google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
581 reinterpret_cast<const char*>(google_der), sizeof(google_der));
582 thawte_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
583 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
584 X509Certificate::OSCertHandles intermediates;
585 intermediates.push_back(thawte_cert_handle);
586 scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromHandle(
587 google_cert_handle, intermediates));
588 X509Certificate::FreeOSCertHandle(google_cert_handle);
589 X509Certificate::FreeOSCertHandle(thawte_cert_handle);
591 // Test that the new certificate, even with intermediates, results in the
592 // same underlying handle being used.
593 EXPECT_EQ(cert1->os_cert_handle(), cert3->os_cert_handle());
594 // Though they use the same OS handle, the intermediates should be different.
595 EXPECT_NE(cert1->GetIntermediateCertificates().size(),
596 cert3->GetIntermediateCertificates().size());
599 TEST(X509CertificateTest, Pickle) {
600 X509Certificate::OSCertHandle google_cert_handle =
601 X509Certificate::CreateOSCertHandleFromBytes(
602 reinterpret_cast<const char*>(google_der), sizeof(google_der));
603 X509Certificate::OSCertHandle thawte_cert_handle =
604 X509Certificate::CreateOSCertHandleFromBytes(
605 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
607 X509Certificate::OSCertHandles intermediates;
608 intermediates.push_back(thawte_cert_handle);
609 scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
610 google_cert_handle, intermediates);
611 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
613 X509Certificate::FreeOSCertHandle(google_cert_handle);
614 X509Certificate::FreeOSCertHandle(thawte_cert_handle);
616 Pickle pickle;
617 cert->Persist(&pickle);
619 PickleIterator iter(pickle);
620 scoped_refptr<X509Certificate> cert_from_pickle =
621 X509Certificate::CreateFromPickle(
622 pickle, &iter, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN_V3);
623 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert_from_pickle.get());
624 EXPECT_TRUE(X509Certificate::IsSameOSCert(
625 cert->os_cert_handle(), cert_from_pickle->os_cert_handle()));
626 const X509Certificate::OSCertHandles& cert_intermediates =
627 cert->GetIntermediateCertificates();
628 const X509Certificate::OSCertHandles& pickle_intermediates =
629 cert_from_pickle->GetIntermediateCertificates();
630 ASSERT_EQ(cert_intermediates.size(), pickle_intermediates.size());
631 for (size_t i = 0; i < cert_intermediates.size(); ++i) {
632 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert_intermediates[i],
633 pickle_intermediates[i]));
637 TEST(X509CertificateTest, IntermediateCertificates) {
638 scoped_refptr<X509Certificate> webkit_cert(
639 X509Certificate::CreateFromBytes(
640 reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
642 scoped_refptr<X509Certificate> thawte_cert(
643 X509Certificate::CreateFromBytes(
644 reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
646 X509Certificate::OSCertHandle google_handle;
647 // Create object with no intermediates:
648 google_handle = X509Certificate::CreateOSCertHandleFromBytes(
649 reinterpret_cast<const char*>(google_der), sizeof(google_der));
650 X509Certificate::OSCertHandles intermediates1;
651 scoped_refptr<X509Certificate> cert1;
652 cert1 = X509Certificate::CreateFromHandle(google_handle, intermediates1);
653 EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
655 // Create object with 2 intermediates:
656 X509Certificate::OSCertHandles intermediates2;
657 intermediates2.push_back(webkit_cert->os_cert_handle());
658 intermediates2.push_back(thawte_cert->os_cert_handle());
659 scoped_refptr<X509Certificate> cert2;
660 cert2 = X509Certificate::CreateFromHandle(google_handle, intermediates2);
662 // Verify it has all the intermediates:
663 const X509Certificate::OSCertHandles& cert2_intermediates =
664 cert2->GetIntermediateCertificates();
665 ASSERT_EQ(2u, cert2_intermediates.size());
666 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[0],
667 webkit_cert->os_cert_handle()));
668 EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[1],
669 thawte_cert->os_cert_handle()));
671 // Cleanup
672 X509Certificate::FreeOSCertHandle(google_handle);
675 TEST(X509CertificateTest, IsIssuedByEncoded) {
676 base::FilePath certs_dir = GetTestCertsDirectory();
678 // Test a client certificate from MIT.
679 scoped_refptr<X509Certificate> mit_davidben_cert(
680 ImportCertFromFile(certs_dir, "mit.davidben.der"));
681 ASSERT_NE(static_cast<X509Certificate*>(NULL), mit_davidben_cert.get());
683 std::string mit_issuer(reinterpret_cast<const char*>(MITDN),
684 sizeof(MITDN));
686 // Test a certificate from Google, issued by Thawte
687 scoped_refptr<X509Certificate> google_cert(
688 ImportCertFromFile(certs_dir, "google.single.der"));
689 ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert.get());
691 std::string thawte_issuer(reinterpret_cast<const char*>(ThawteDN),
692 sizeof(ThawteDN));
694 // Check that the David Ben certificate is issued by MIT, but not
695 // by Thawte.
696 std::vector<std::string> issuers;
697 issuers.clear();
698 issuers.push_back(mit_issuer);
699 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
700 EXPECT_FALSE(google_cert->IsIssuedByEncoded(issuers));
702 // Check that the Google certificate is issued by Thawte and not
703 // by MIT.
704 issuers.clear();
705 issuers.push_back(thawte_issuer);
706 EXPECT_FALSE(mit_davidben_cert->IsIssuedByEncoded(issuers));
707 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
709 // Check that they both pass when given a list of the two issuers.
710 issuers.clear();
711 issuers.push_back(mit_issuer);
712 issuers.push_back(thawte_issuer);
713 EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
714 EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
717 TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
718 static const unsigned char kPolicyRootDN[] = {
719 0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
720 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
721 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41
723 static const unsigned char kPolicyIntermediateDN[] = {
724 0x30, 0x26, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
725 0x1b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
726 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
727 0x65, 0x20, 0x43, 0x41
730 base::FilePath certs_dir = GetTestCertsDirectory();
732 CertificateList policy_chain = CreateCertificateListFromFile(
733 certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO);
734 ASSERT_EQ(3u, policy_chain.size());
736 // The intermediate CA certificate's policyConstraints extension has a
737 // requireExplicitPolicy field with SkipCerts=0.
738 std::string policy_intermediate_dn(
739 reinterpret_cast<const char*>(kPolicyIntermediateDN),
740 sizeof(kPolicyIntermediateDN));
741 std::string policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN),
742 sizeof(kPolicyRootDN));
744 X509Certificate::OSCertHandles intermediates;
745 intermediates.push_back(policy_chain[1]->os_cert_handle());
746 scoped_refptr<X509Certificate> cert_chain =
747 X509Certificate::CreateFromHandle(policy_chain[0]->os_cert_handle(),
748 intermediates);
750 std::vector<std::string> issuers;
752 // Check that the chain is issued by the intermediate.
753 issuers.clear();
754 issuers.push_back(policy_intermediate_dn);
755 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
757 // Check that the chain is also issued by the root.
758 issuers.clear();
759 issuers.push_back(policy_root_dn);
760 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
762 // Check that the chain is issued by either the intermediate or the root.
763 issuers.clear();
764 issuers.push_back(policy_intermediate_dn);
765 issuers.push_back(policy_root_dn);
766 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
768 // Check that an empty issuers list returns false.
769 issuers.clear();
770 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
772 // Check that the chain is not issued by Verisign
773 std::string mit_issuer(reinterpret_cast<const char*>(VerisignDN),
774 sizeof(VerisignDN));
775 issuers.clear();
776 issuers.push_back(mit_issuer);
777 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
780 // Tests that FreeOSCertHandle ignores NULL on each OS.
781 TEST(X509CertificateTest, FreeNullHandle) {
782 X509Certificate::FreeOSCertHandle(NULL);
785 #if defined(USE_NSS)
786 TEST(X509CertificateTest, GetDefaultNickname) {
787 base::FilePath certs_dir = GetTestCertsDirectory();
789 scoped_refptr<X509Certificate> test_cert(
790 ImportCertFromFile(certs_dir, "no_subject_common_name_cert.pem"));
791 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
793 std::string nickname = test_cert->GetDefaultNickname(USER_CERT);
794 EXPECT_EQ("wtc@google.com's COMODO Client Authentication and "
795 "Secure Email CA ID", nickname);
797 #endif
799 const struct CertificateFormatTestData {
800 const char* file_name;
801 X509Certificate::Format format;
802 uint8* chain_fingerprints[3];
803 } kFormatTestData[] = {
804 // DER Parsing - single certificate, DER encoded
805 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
806 { google_parse_fingerprint,
807 NULL, } },
808 // DER parsing - single certificate, PEM encoded
809 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
810 { google_parse_fingerprint,
811 NULL, } },
812 // PEM parsing - single certificate, PEM encoded with a PEB of
813 // "CERTIFICATE"
814 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
815 { google_parse_fingerprint,
816 NULL, } },
817 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
818 // "CERTIFICATE"
819 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
820 { google_parse_fingerprint,
821 thawte_parse_fingerprint,
822 NULL, } },
823 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
824 // encoding
825 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7,
826 { google_parse_fingerprint,
827 thawte_parse_fingerprint,
828 NULL, } },
829 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
830 // encoded with a PEM PEB of "CERTIFICATE"
831 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7,
832 { google_parse_fingerprint,
833 thawte_parse_fingerprint,
834 NULL, } },
835 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
836 // encoded with a PEM PEB of "PKCS7"
837 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7,
838 { google_parse_fingerprint,
839 thawte_parse_fingerprint,
840 NULL, } },
841 // All of the above, this time using auto-detection
842 { "google.single.der", X509Certificate::FORMAT_AUTO,
843 { google_parse_fingerprint,
844 NULL, } },
845 { "google.single.pem", X509Certificate::FORMAT_AUTO,
846 { google_parse_fingerprint,
847 NULL, } },
848 { "google.chain.pem", X509Certificate::FORMAT_AUTO,
849 { google_parse_fingerprint,
850 thawte_parse_fingerprint,
851 NULL, } },
852 { "google.binary.p7b", X509Certificate::FORMAT_AUTO,
853 { google_parse_fingerprint,
854 thawte_parse_fingerprint,
855 NULL, } },
856 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO,
857 { google_parse_fingerprint,
858 thawte_parse_fingerprint,
859 NULL, } },
860 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO,
861 { google_parse_fingerprint,
862 thawte_parse_fingerprint,
863 NULL, } },
866 class X509CertificateParseTest
867 : public testing::TestWithParam<CertificateFormatTestData> {
868 public:
869 virtual ~X509CertificateParseTest() {}
870 virtual void SetUp() {
871 test_data_ = GetParam();
873 virtual void TearDown() {}
875 protected:
876 CertificateFormatTestData test_data_;
879 TEST_P(X509CertificateParseTest, CanParseFormat) {
880 base::FilePath certs_dir = GetTestCertsDirectory();
881 CertificateList certs = CreateCertificateListFromFile(
882 certs_dir, test_data_.file_name, test_data_.format);
883 ASSERT_FALSE(certs.empty());
884 ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints));
885 CheckGoogleCert(certs.front(), google_parse_fingerprint,
886 kGoogleParseValidFrom, kGoogleParseValidTo);
888 size_t i;
889 for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) {
890 if (test_data_.chain_fingerprints[i] == NULL) {
891 // No more test certificates expected - make sure no more were
892 // returned before marking this test a success.
893 EXPECT_EQ(i, certs.size());
894 break;
897 // A cert is expected - make sure that one was parsed.
898 ASSERT_LT(i, certs.size());
900 // Compare the parsed certificate with the expected certificate, by
901 // comparing fingerprints.
902 const X509Certificate* cert = certs[i].get();
903 const SHA1HashValue& actual_fingerprint = cert->fingerprint();
904 uint8* expected_fingerprint = test_data_.chain_fingerprints[i];
906 for (size_t j = 0; j < 20; ++j)
907 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]);
911 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
912 testing::ValuesIn(kFormatTestData));
914 struct CertificateNameVerifyTestData {
915 // true iff we expect hostname to match an entry in cert_names.
916 bool expected;
917 // The hostname to match.
918 const char* hostname;
919 // Common name, may be used if |dns_names| or |ip_addrs| are empty.
920 const char* common_name;
921 // Comma separated list of certificate names to match against. Any occurrence
922 // of '#' will be replaced with a null character before processing.
923 const char* dns_names;
924 // Comma separated list of certificate IP Addresses to match against. Each
925 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
926 const char* ip_addrs;
929 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
930 // to output the parameter that was passed. Without this, it will simply
931 // attempt to print out the first twenty bytes of the object, which depending
932 // on platform and alignment, may result in an invalid read.
933 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
934 ASSERT_TRUE(data.hostname && data.common_name);
935 // Using StringPiece to allow for optional fields being NULL.
936 *os << " expected: " << data.expected
937 << "; hostname: " << data.hostname
938 << "; common_name: " << data.common_name
939 << "; dns_names: " << base::StringPiece(data.dns_names)
940 << "; ip_addrs: " << base::StringPiece(data.ip_addrs);
943 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
944 { true, "foo.com", "foo.com" },
945 { true, "f", "f" },
946 { false, "h", "i" },
947 { true, "bar.foo.com", "*.foo.com" },
948 { true, "www.test.fr", "common.name",
949 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
950 { true, "wwW.tESt.fr", "common.name",
951 ",*.*,*.test.de,*.test.FR,www" },
952 { false, "f.uk", ".uk" },
953 { false, "w.bar.foo.com", "?.bar.foo.com" },
954 { false, "www.foo.com", "(www|ftp).foo.com" },
955 { false, "www.foo.com", "www.foo.com#" }, // # = null char.
956 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
957 { false, "www.house.example", "ww.house.example" },
958 { false, "test.org", "", "www.test.org,*.test.org,*.org" },
959 { false, "w.bar.foo.com", "w*.bar.foo.com" },
960 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
961 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
962 { true, "wwww.bar.foo.com", "w*w.bar.foo.com" },
963 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
964 { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
965 { true, "wally.bar.foo.com", "*Ly.bar.foo.com" },
966 { true, "ww%57.foo.com", "", "www.foo.com" },
967 { true, "www&.foo.com", "www%26.foo.com" },
968 // Common name must not be used if subject alternative name was provided.
969 { false, "www.test.co.jp", "www.test.co.jp",
970 "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
971 { false, "www.bar.foo.com", "www.bar.foo.com",
972 "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
973 { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
974 { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
975 // IDN tests
976 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
977 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
978 { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
979 "xn--poema-*.com.br,"
980 "xn--*-9qae5a.com.br,"
981 "*--poema-9qae5a.com.br" },
982 // The following are adapted from the examples quoted from
983 // http://tools.ietf.org/html/rfc6125#section-6.4.3
984 // (e.g., *.example.com would match foo.example.com but
985 // not bar.foo.example.com or example.com).
986 { true, "foo.example.com", "*.example.com" },
987 { false, "bar.foo.example.com", "*.example.com" },
988 { false, "example.com", "*.example.com" },
989 // (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
990 // be taken to match baz1.example.net and foobaz.example.net and
991 // buzz.example.net, respectively
992 { true, "baz1.example.net", "baz*.example.net" },
993 { true, "foobaz.example.net", "*baz.example.net" },
994 { true, "buzz.example.net", "b*z.example.net" },
995 // Wildcards should not be valid for public registry controlled domains,
996 // and unknown/unrecognized domains, at least three domain components must
997 // be present.
998 { true, "www.test.example", "*.test.example" },
999 { true, "test.example.co.uk", "*.example.co.uk" },
1000 { false, "test.example", "*.exmaple" },
1001 { false, "example.co.uk", "*.co.uk" },
1002 { false, "foo.com", "*.com" },
1003 { false, "foo.us", "*.us" },
1004 { false, "foo", "*" },
1005 // IDN variants of wildcards and registry controlled domains.
1006 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1007 { true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h" },
1008 { false, "xn--poema-9qae5a.com.br", "*.com.br" },
1009 { false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h" },
1010 // Wildcards should be permissible for 'private' registry controlled
1011 // domains.
1012 { true, "www.appspot.com", "*.appspot.com" },
1013 { true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com" },
1014 // Multiple wildcards are not valid.
1015 { false, "foo.example.com", "*.*.com" },
1016 { false, "foo.bar.example.com", "*.bar.*.com" },
1017 // Absolute vs relative DNS name tests. Although not explicitly specified
1018 // in RFC 6125, absolute reference names (those ending in a .) should
1019 // match either absolute or relative presented names.
1020 { true, "foo.com", "foo.com." },
1021 { true, "foo.com.", "foo.com" },
1022 { true, "foo.com.", "foo.com." },
1023 { true, "f", "f." },
1024 { true, "f.", "f" },
1025 { true, "f.", "f." },
1026 { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1027 { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1028 { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1029 { false, ".", "." },
1030 { false, "example.com", "*.com." },
1031 { false, "example.com.", "*.com" },
1032 { false, "example.com.", "*.com." },
1033 { false, "foo.", "*." },
1034 { false, "foo", "*." },
1035 { false, "foo.co.uk", "*.co.uk." },
1036 { false, "foo.co.uk.", "*.co.uk." },
1037 // IP addresses in common name; IPv4 only.
1038 { true, "127.0.0.1", "127.0.0.1" },
1039 { true, "192.168.1.1", "192.168.1.1" },
1040 { true, "676768", "0.10.83.160" },
1041 { true, "1.2.3", "1.2.0.3" },
1042 { false, "192.169.1.1", "192.168.1.1" },
1043 { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1044 { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1045 "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1046 { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1047 "1111:2222:3333:4444:5555:6666:7777:8888" },
1048 { false, "::192.9.5.5", "[::192.9.5.5]" },
1049 // No wildcard matching in valid IP addresses
1050 { false, "::192.9.5.5", "*.9.5.5" },
1051 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1052 { false, "192.168.1.11", "*.168.1.11" },
1053 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1054 // IP addresses in subject alternative name (common name ignored)
1055 { true, "10.1.2.3", "", "", "10.1.2.3" },
1056 { true, "14.15", "", "", "14.0.0.15" },
1057 { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1058 { false, "10.1.2.8", "10.20.2.8", "foo" },
1059 { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1060 { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1061 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1062 "xff000000000000000000000006070809,6.7.8.9" },
1063 { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1064 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1065 "xff0000000000000000000000060708ff,10.0.0.1" },
1066 // Numeric only hostnames (none of these are considered valid IP addresses).
1067 { false, "12345.6", "12345.6" },
1068 { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1069 "121.2.3.0"},
1070 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1071 { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1072 // Invalid host names.
1073 { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1074 { false, "www.*.com", "www.*.com" },
1075 { false, "w$w.f.com", "w$w.f.com" },
1076 { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1077 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1078 { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1081 class X509CertificateNameVerifyTest
1082 : public testing::TestWithParam<CertificateNameVerifyTestData> {
1085 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1086 CertificateNameVerifyTestData test_data = GetParam();
1088 std::string common_name(test_data.common_name);
1089 ASSERT_EQ(std::string::npos, common_name.find(','));
1090 std::replace(common_name.begin(), common_name.end(), '#', '\0');
1092 std::vector<std::string> dns_names, ip_addressses;
1093 if (test_data.dns_names) {
1094 // Build up the certificate DNS names list.
1095 std::string dns_name_line(test_data.dns_names);
1096 std::replace(dns_name_line.begin(), dns_name_line.end(), '#', '\0');
1097 base::SplitString(dns_name_line, ',', &dns_names);
1100 if (test_data.ip_addrs) {
1101 // Build up the certificate IP address list.
1102 std::string ip_addrs_line(test_data.ip_addrs);
1103 std::vector<std::string> ip_addressses_ascii;
1104 base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii);
1105 for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) {
1106 std::string& addr_ascii = ip_addressses_ascii[i];
1107 ASSERT_NE(0U, addr_ascii.length());
1108 if (addr_ascii[0] == 'x') { // Hex encoded address
1109 addr_ascii.erase(0, 1);
1110 std::vector<uint8> bytes;
1111 EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes))
1112 << "Could not parse hex address " << addr_ascii << " i = " << i;
1113 ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]),
1114 bytes.size()));
1115 ASSERT_EQ(16U, ip_addressses.back().size()) << i;
1116 } else { // Decimal groups
1117 std::vector<std::string> decimals_ascii;
1118 base::SplitString(addr_ascii, '.', &decimals_ascii);
1119 EXPECT_EQ(4U, decimals_ascii.size()) << i;
1120 std::string addr_bytes;
1121 for (size_t j = 0; j < decimals_ascii.size(); ++j) {
1122 int decimal_value;
1123 EXPECT_TRUE(base::StringToInt(decimals_ascii[j], &decimal_value));
1124 EXPECT_GE(decimal_value, 0);
1125 EXPECT_LE(decimal_value, 255);
1126 addr_bytes.push_back(static_cast<char>(decimal_value));
1128 ip_addressses.push_back(addr_bytes);
1129 ASSERT_EQ(4U, ip_addressses.back().size()) << i;
1134 bool unused = false;
1135 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname(
1136 test_data.hostname, common_name, dns_names, ip_addressses, &unused));
1139 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1140 testing::ValuesIn(kNameVerifyTestData));
1142 const struct PublicKeyInfoTestData {
1143 const char* cert_file;
1144 size_t expected_bits;
1145 X509Certificate::PublicKeyType expected_type;
1146 } kPublicKeyInfoTestData[] = {
1147 { "768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1148 X509Certificate::kPublicKeyTypeRSA },
1149 { "1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1150 X509Certificate::kPublicKeyTypeRSA },
1151 { "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1152 X509Certificate::kPublicKeyTypeECDSA },
1155 class X509CertificatePublicKeyInfoTest
1156 : public testing::TestWithParam<PublicKeyInfoTestData> {
1159 TEST_P(X509CertificatePublicKeyInfoTest, GetPublicKeyInfo) {
1160 PublicKeyInfoTestData data = GetParam();
1162 #if defined(OS_WIN)
1163 if (base::win::GetVersion() < base::win::VERSION_VISTA &&
1164 data.expected_type == X509Certificate::kPublicKeyTypeECDSA) {
1165 // ECC is only supported on Vista+. Skip the test.
1166 return;
1168 #endif
1170 scoped_refptr<X509Certificate> cert(
1171 ImportCertFromFile(GetTestCertsDirectory(), data.cert_file));
1172 ASSERT_TRUE(cert.get());
1174 size_t actual_bits = 0;
1175 X509Certificate::PublicKeyType actual_type =
1176 X509Certificate::kPublicKeyTypeUnknown;
1178 X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &actual_bits,
1179 &actual_type);
1181 EXPECT_EQ(data.expected_bits, actual_bits);
1182 EXPECT_EQ(data.expected_type, actual_type);
1185 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest,
1186 testing::ValuesIn(kPublicKeyInfoTestData));
1188 } // namespace net