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