gn: More helpful default args file
[chromium-blink-merge.git] / net / cert / x509_certificate_unittest.cc
blobf5e49f8b3cd1f6053affecdac6acf1b2f935c5b6
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, IsSelfSigned) {
718 base::FilePath certs_dir = GetTestCertsDirectory();
720 scoped_refptr<X509Certificate> cert(
721 ImportCertFromFile(certs_dir, "mit.davidben.der"));
722 ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
723 EXPECT_FALSE(X509Certificate::IsSelfSigned(cert->os_cert_handle()));
725 scoped_refptr<X509Certificate> self_signed(
726 ImportCertFromFile(certs_dir, "aia-root.pem"));
727 ASSERT_NE(static_cast<X509Certificate*>(NULL), self_signed.get());
728 EXPECT_TRUE(X509Certificate::IsSelfSigned(self_signed->os_cert_handle()));
731 TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
732 static const unsigned char kPolicyRootDN[] = {
733 0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
734 0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
735 0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41
737 static const unsigned char kPolicyIntermediateDN[] = {
738 0x30, 0x26, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
739 0x1b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
740 0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
741 0x65, 0x20, 0x43, 0x41
744 base::FilePath certs_dir = GetTestCertsDirectory();
746 CertificateList policy_chain = CreateCertificateListFromFile(
747 certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO);
748 ASSERT_EQ(3u, policy_chain.size());
750 // The intermediate CA certificate's policyConstraints extension has a
751 // requireExplicitPolicy field with SkipCerts=0.
752 std::string policy_intermediate_dn(
753 reinterpret_cast<const char*>(kPolicyIntermediateDN),
754 sizeof(kPolicyIntermediateDN));
755 std::string policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN),
756 sizeof(kPolicyRootDN));
758 X509Certificate::OSCertHandles intermediates;
759 intermediates.push_back(policy_chain[1]->os_cert_handle());
760 scoped_refptr<X509Certificate> cert_chain =
761 X509Certificate::CreateFromHandle(policy_chain[0]->os_cert_handle(),
762 intermediates);
764 std::vector<std::string> issuers;
766 // Check that the chain is issued by the intermediate.
767 issuers.clear();
768 issuers.push_back(policy_intermediate_dn);
769 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
771 // Check that the chain is also issued by the root.
772 issuers.clear();
773 issuers.push_back(policy_root_dn);
774 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
776 // Check that the chain is issued by either the intermediate or the root.
777 issuers.clear();
778 issuers.push_back(policy_intermediate_dn);
779 issuers.push_back(policy_root_dn);
780 EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
782 // Check that an empty issuers list returns false.
783 issuers.clear();
784 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
786 // Check that the chain is not issued by Verisign
787 std::string mit_issuer(reinterpret_cast<const char*>(VerisignDN),
788 sizeof(VerisignDN));
789 issuers.clear();
790 issuers.push_back(mit_issuer);
791 EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
794 // Tests that FreeOSCertHandle ignores NULL on each OS.
795 TEST(X509CertificateTest, FreeNullHandle) {
796 X509Certificate::FreeOSCertHandle(NULL);
799 #if defined(USE_NSS)
800 TEST(X509CertificateTest, GetDefaultNickname) {
801 base::FilePath certs_dir = GetTestCertsDirectory();
803 scoped_refptr<X509Certificate> test_cert(
804 ImportCertFromFile(certs_dir, "no_subject_common_name_cert.pem"));
805 ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
807 std::string nickname = test_cert->GetDefaultNickname(USER_CERT);
808 EXPECT_EQ("wtc@google.com's COMODO Client Authentication and "
809 "Secure Email CA ID", nickname);
811 #endif
813 const struct CertificateFormatTestData {
814 const char* file_name;
815 X509Certificate::Format format;
816 uint8* chain_fingerprints[3];
817 } kFormatTestData[] = {
818 // DER Parsing - single certificate, DER encoded
819 { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
820 { google_parse_fingerprint,
821 NULL, } },
822 // DER parsing - single certificate, PEM encoded
823 { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
824 { google_parse_fingerprint,
825 NULL, } },
826 // PEM parsing - single certificate, PEM encoded with a PEB of
827 // "CERTIFICATE"
828 { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
829 { google_parse_fingerprint,
830 NULL, } },
831 // PEM parsing - sequence of certificates, PEM encoded with a PEB of
832 // "CERTIFICATE"
833 { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
834 { google_parse_fingerprint,
835 thawte_parse_fingerprint,
836 NULL, } },
837 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
838 // encoding
839 { "google.binary.p7b", X509Certificate::FORMAT_PKCS7,
840 { google_parse_fingerprint,
841 thawte_parse_fingerprint,
842 NULL, } },
843 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
844 // encoded with a PEM PEB of "CERTIFICATE"
845 { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7,
846 { google_parse_fingerprint,
847 thawte_parse_fingerprint,
848 NULL, } },
849 // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
850 // encoded with a PEM PEB of "PKCS7"
851 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7,
852 { google_parse_fingerprint,
853 thawte_parse_fingerprint,
854 NULL, } },
855 // All of the above, this time using auto-detection
856 { "google.single.der", X509Certificate::FORMAT_AUTO,
857 { google_parse_fingerprint,
858 NULL, } },
859 { "google.single.pem", X509Certificate::FORMAT_AUTO,
860 { google_parse_fingerprint,
861 NULL, } },
862 { "google.chain.pem", X509Certificate::FORMAT_AUTO,
863 { google_parse_fingerprint,
864 thawte_parse_fingerprint,
865 NULL, } },
866 { "google.binary.p7b", X509Certificate::FORMAT_AUTO,
867 { google_parse_fingerprint,
868 thawte_parse_fingerprint,
869 NULL, } },
870 { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO,
871 { google_parse_fingerprint,
872 thawte_parse_fingerprint,
873 NULL, } },
874 { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO,
875 { google_parse_fingerprint,
876 thawte_parse_fingerprint,
877 NULL, } },
880 class X509CertificateParseTest
881 : public testing::TestWithParam<CertificateFormatTestData> {
882 public:
883 virtual ~X509CertificateParseTest() {}
884 void SetUp() override { test_data_ = GetParam(); }
885 void TearDown() override {}
887 protected:
888 CertificateFormatTestData test_data_;
891 TEST_P(X509CertificateParseTest, CanParseFormat) {
892 base::FilePath certs_dir = GetTestCertsDirectory();
893 CertificateList certs = CreateCertificateListFromFile(
894 certs_dir, test_data_.file_name, test_data_.format);
895 ASSERT_FALSE(certs.empty());
896 ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints));
897 CheckGoogleCert(certs.front(), google_parse_fingerprint,
898 kGoogleParseValidFrom, kGoogleParseValidTo);
900 size_t i;
901 for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) {
902 if (test_data_.chain_fingerprints[i] == NULL) {
903 // No more test certificates expected - make sure no more were
904 // returned before marking this test a success.
905 EXPECT_EQ(i, certs.size());
906 break;
909 // A cert is expected - make sure that one was parsed.
910 ASSERT_LT(i, certs.size());
912 // Compare the parsed certificate with the expected certificate, by
913 // comparing fingerprints.
914 const X509Certificate* cert = certs[i].get();
915 const SHA1HashValue& actual_fingerprint = cert->fingerprint();
916 uint8* expected_fingerprint = test_data_.chain_fingerprints[i];
918 for (size_t j = 0; j < 20; ++j)
919 EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]);
923 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
924 testing::ValuesIn(kFormatTestData));
926 struct CertificateNameVerifyTestData {
927 // true iff we expect hostname to match an entry in cert_names.
928 bool expected;
929 // The hostname to match.
930 const char* hostname;
931 // Common name, may be used if |dns_names| or |ip_addrs| are empty.
932 const char* common_name;
933 // Comma separated list of certificate names to match against. Any occurrence
934 // of '#' will be replaced with a null character before processing.
935 const char* dns_names;
936 // Comma separated list of certificate IP Addresses to match against. Each
937 // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
938 const char* ip_addrs;
941 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
942 // to output the parameter that was passed. Without this, it will simply
943 // attempt to print out the first twenty bytes of the object, which depending
944 // on platform and alignment, may result in an invalid read.
945 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
946 ASSERT_TRUE(data.hostname && data.common_name);
947 // Using StringPiece to allow for optional fields being NULL.
948 *os << " expected: " << data.expected
949 << "; hostname: " << data.hostname
950 << "; common_name: " << data.common_name
951 << "; dns_names: " << base::StringPiece(data.dns_names)
952 << "; ip_addrs: " << base::StringPiece(data.ip_addrs);
955 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
956 { true, "foo.com", "foo.com" },
957 { true, "f", "f" },
958 { false, "h", "i" },
959 { true, "bar.foo.com", "*.foo.com" },
960 { true, "www.test.fr", "common.name",
961 "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
962 { true, "wwW.tESt.fr", "common.name",
963 ",*.*,*.test.de,*.test.FR,www" },
964 { false, "f.uk", ".uk" },
965 { false, "w.bar.foo.com", "?.bar.foo.com" },
966 { false, "www.foo.com", "(www|ftp).foo.com" },
967 { false, "www.foo.com", "www.foo.com#" }, // # = null char.
968 { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
969 { false, "www.house.example", "ww.house.example" },
970 { false, "test.org", "", "www.test.org,*.test.org,*.org" },
971 { false, "w.bar.foo.com", "w*.bar.foo.com" },
972 { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
973 { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
974 { false, "wwww.bar.foo.com", "w*w.bar.foo.com" },
975 { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
976 { false, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
977 { false, "wally.bar.foo.com", "*Ly.bar.foo.com" },
978 { true, "ww%57.foo.com", "", "www.foo.com" },
979 { true, "www&.foo.com", "www%26.foo.com" },
980 // Common name must not be used if subject alternative name was provided.
981 { false, "www.test.co.jp", "www.test.co.jp",
982 "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
983 { false, "www.bar.foo.com", "www.bar.foo.com",
984 "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
985 { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
986 { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
987 // IDN tests
988 { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
989 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
990 { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
991 "xn--poema-*.com.br,"
992 "xn--*-9qae5a.com.br,"
993 "*--poema-9qae5a.com.br" },
994 // The following are adapted from the examples quoted from
995 // http://tools.ietf.org/html/rfc6125#section-6.4.3
996 // (e.g., *.example.com would match foo.example.com but
997 // not bar.foo.example.com or example.com).
998 { true, "foo.example.com", "*.example.com" },
999 { false, "bar.foo.example.com", "*.example.com" },
1000 { false, "example.com", "*.example.com" },
1001 // Partial wildcards are disallowed, though RFC 2818 rules allow them.
1002 // That is, forms such as baz*.example.net, *baz.example.net, and
1003 // b*z.example.net should NOT match domains. Instead, the wildcard must
1004 // always be the left-most label, and only a single label.
1005 { false, "baz1.example.net", "baz*.example.net" },
1006 { false, "foobaz.example.net", "*baz.example.net" },
1007 { false, "buzz.example.net", "b*z.example.net" },
1008 { false, "www.test.example.net", "www.*.example.net" },
1009 // Wildcards should not be valid for public registry controlled domains,
1010 // and unknown/unrecognized domains, at least three domain components must
1011 // be present.
1012 { true, "www.test.example", "*.test.example" },
1013 { true, "test.example.co.uk", "*.example.co.uk" },
1014 { false, "test.example", "*.exmaple" },
1015 { false, "example.co.uk", "*.co.uk" },
1016 { false, "foo.com", "*.com" },
1017 { false, "foo.us", "*.us" },
1018 { false, "foo", "*" },
1019 // IDN variants of wildcards and registry controlled domains.
1020 { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1021 { true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h" },
1022 { false, "xn--poema-9qae5a.com.br", "*.com.br" },
1023 { false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h" },
1024 // Wildcards should be permissible for 'private' registry controlled
1025 // domains.
1026 { true, "www.appspot.com", "*.appspot.com" },
1027 { true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com" },
1028 // Multiple wildcards are not valid.
1029 { false, "foo.example.com", "*.*.com" },
1030 { false, "foo.bar.example.com", "*.bar.*.com" },
1031 // Absolute vs relative DNS name tests. Although not explicitly specified
1032 // in RFC 6125, absolute reference names (those ending in a .) should
1033 // match either absolute or relative presented names.
1034 { true, "foo.com", "foo.com." },
1035 { true, "foo.com.", "foo.com" },
1036 { true, "foo.com.", "foo.com." },
1037 { true, "f", "f." },
1038 { true, "f.", "f" },
1039 { true, "f.", "f." },
1040 { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1041 { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1042 { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1043 { false, ".", "." },
1044 { false, "example.com", "*.com." },
1045 { false, "example.com.", "*.com" },
1046 { false, "example.com.", "*.com." },
1047 { false, "foo.", "*." },
1048 { false, "foo", "*." },
1049 { false, "foo.co.uk", "*.co.uk." },
1050 { false, "foo.co.uk.", "*.co.uk." },
1051 // IP addresses in common name; IPv4 only.
1052 { true, "127.0.0.1", "127.0.0.1" },
1053 { true, "192.168.1.1", "192.168.1.1" },
1054 { true, "676768", "0.10.83.160" },
1055 { true, "1.2.3", "1.2.0.3" },
1056 { false, "192.169.1.1", "192.168.1.1" },
1057 { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1058 { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1059 "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1060 { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1061 "1111:2222:3333:4444:5555:6666:7777:8888" },
1062 { false, "::192.9.5.5", "[::192.9.5.5]" },
1063 // No wildcard matching in valid IP addresses
1064 { false, "::192.9.5.5", "*.9.5.5" },
1065 { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1066 { false, "192.168.1.11", "*.168.1.11" },
1067 { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1068 // IP addresses in subject alternative name (common name ignored)
1069 { true, "10.1.2.3", "", "", "10.1.2.3" },
1070 { true, "14.15", "", "", "14.0.0.15" },
1071 { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1072 { false, "10.1.2.8", "10.20.2.8", "foo" },
1073 { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1074 { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1075 "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1076 "xff000000000000000000000006070809,6.7.8.9" },
1077 { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1078 "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1079 "xff0000000000000000000000060708ff,10.0.0.1" },
1080 // Numeric only hostnames (none of these are considered valid IP addresses).
1081 { false, "12345.6", "12345.6" },
1082 { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1083 "121.2.3.0"},
1084 { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1085 { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1086 // Invalid host names.
1087 { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1088 { false, "www.*.com", "www.*.com" },
1089 { false, "w$w.f.com", "w$w.f.com" },
1090 { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1091 { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1092 { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1095 class X509CertificateNameVerifyTest
1096 : public testing::TestWithParam<CertificateNameVerifyTestData> {
1099 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1100 CertificateNameVerifyTestData test_data = GetParam();
1102 std::string common_name(test_data.common_name);
1103 ASSERT_EQ(std::string::npos, common_name.find(','));
1104 std::replace(common_name.begin(), common_name.end(), '#', '\0');
1106 std::vector<std::string> dns_names, ip_addressses;
1107 if (test_data.dns_names) {
1108 // Build up the certificate DNS names list.
1109 std::string dns_name_line(test_data.dns_names);
1110 std::replace(dns_name_line.begin(), dns_name_line.end(), '#', '\0');
1111 base::SplitString(dns_name_line, ',', &dns_names);
1114 if (test_data.ip_addrs) {
1115 // Build up the certificate IP address list.
1116 std::string ip_addrs_line(test_data.ip_addrs);
1117 std::vector<std::string> ip_addressses_ascii;
1118 base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii);
1119 for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) {
1120 std::string& addr_ascii = ip_addressses_ascii[i];
1121 ASSERT_NE(0U, addr_ascii.length());
1122 if (addr_ascii[0] == 'x') { // Hex encoded address
1123 addr_ascii.erase(0, 1);
1124 std::vector<uint8> bytes;
1125 EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes))
1126 << "Could not parse hex address " << addr_ascii << " i = " << i;
1127 ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]),
1128 bytes.size()));
1129 ASSERT_EQ(16U, ip_addressses.back().size()) << i;
1130 } else { // Decimal groups
1131 std::vector<std::string> decimals_ascii;
1132 base::SplitString(addr_ascii, '.', &decimals_ascii);
1133 EXPECT_EQ(4U, decimals_ascii.size()) << i;
1134 std::string addr_bytes;
1135 for (size_t j = 0; j < decimals_ascii.size(); ++j) {
1136 int decimal_value;
1137 EXPECT_TRUE(base::StringToInt(decimals_ascii[j], &decimal_value));
1138 EXPECT_GE(decimal_value, 0);
1139 EXPECT_LE(decimal_value, 255);
1140 addr_bytes.push_back(static_cast<char>(decimal_value));
1142 ip_addressses.push_back(addr_bytes);
1143 ASSERT_EQ(4U, ip_addressses.back().size()) << i;
1148 bool unused = false;
1149 EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname(
1150 test_data.hostname, common_name, dns_names, ip_addressses, &unused));
1153 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1154 testing::ValuesIn(kNameVerifyTestData));
1156 const struct PublicKeyInfoTestData {
1157 const char* cert_file;
1158 size_t expected_bits;
1159 X509Certificate::PublicKeyType expected_type;
1160 } kPublicKeyInfoTestData[] = {
1161 { "768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1162 X509Certificate::kPublicKeyTypeRSA },
1163 { "1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1164 X509Certificate::kPublicKeyTypeRSA },
1165 { "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1166 X509Certificate::kPublicKeyTypeECDSA },
1169 class X509CertificatePublicKeyInfoTest
1170 : public testing::TestWithParam<PublicKeyInfoTestData> {
1173 TEST_P(X509CertificatePublicKeyInfoTest, GetPublicKeyInfo) {
1174 PublicKeyInfoTestData data = GetParam();
1176 #if defined(OS_WIN)
1177 if (base::win::GetVersion() < base::win::VERSION_VISTA &&
1178 data.expected_type == X509Certificate::kPublicKeyTypeECDSA) {
1179 // ECC is only supported on Vista+. Skip the test.
1180 return;
1182 #endif
1184 scoped_refptr<X509Certificate> cert(
1185 ImportCertFromFile(GetTestCertsDirectory(), data.cert_file));
1186 ASSERT_TRUE(cert.get());
1188 size_t actual_bits = 0;
1189 X509Certificate::PublicKeyType actual_type =
1190 X509Certificate::kPublicKeyTypeUnknown;
1192 X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &actual_bits,
1193 &actual_type);
1195 EXPECT_EQ(data.expected_bits, actual_bits);
1196 EXPECT_EQ(data.expected_type, actual_type);
1199 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest,
1200 testing::ValuesIn(kPublicKeyInfoTestData));
1202 } // namespace net