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