• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #include "net/cert/x509_certificate.h"
6 
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"
21 
22 #if defined(USE_NSS)
23 #include <cert.h>
24 #endif
25 
26 #if defined(OS_WIN)
27 #include "base/win/windows_version.h"
28 #endif
29 
30 using base::HexEncode;
31 using base::Time;
32 
33 namespace net {
34 
35 // Certificates for test data. They're obtained with:
36 //
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
39 //
40 // For fingerprint
41 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
42 
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>'
47 
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
52 };
53 
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
58 };
59 
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
64 };
65 
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
71 };
72 
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
78 };
79 
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
84 };
85 
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;
90 
CheckGoogleCert(const scoped_refptr<X509Certificate> & google_cert,uint8 * expected_fingerprint,double valid_from,double valid_to)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());
95 
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());
106 
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());
117 
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());
121 
122   const Time& valid_expiry = google_cert->valid_expiry();
123   EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
124 
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]);
128 
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]);
133 }
134 
TEST(X509CertificateTest,GoogleCertParsing)135 TEST(X509CertificateTest, GoogleCertParsing) {
136   scoped_refptr<X509Certificate> google_cert(
137       X509Certificate::CreateFromBytes(
138           reinterpret_cast<const char*>(google_der), sizeof(google_der)));
139 
140   CheckGoogleCert(google_cert, google_fingerprint,
141                   1238192407,   // Mar 27 22:20:07 2009 GMT
142                   1269728407);  // Mar 27 22:20:07 2010 GMT
143 }
144 
TEST(X509CertificateTest,WebkitCertParsing)145 TEST(X509CertificateTest, WebkitCertParsing) {
146   scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
147       reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
148 
149   ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert.get());
150 
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());
161 
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());
174 
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
178 
179   const Time& valid_expiry = webkit_cert->valid_expiry();
180   EXPECT_EQ(1300491319, valid_expiry.ToDoubleT());  // Mar 18 23:35:19 2011 GMT
181 
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]);
185 
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]);
191 
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));
199 }
200 
TEST(X509CertificateTest,ThawteCertParsing)201 TEST(X509CertificateTest, ThawteCertParsing) {
202   scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes(
203       reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
204 
205   ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert.get());
206 
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());
217 
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());
230 
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
234 
235   const Time& valid_expiry = thawte_cert->valid_expiry();
236   EXPECT_EQ(1263772799, valid_expiry.ToDoubleT());  // Jan 17 23:59:59 2010 GMT
237 
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]);
241 
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]);
246 }
247 
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
TEST(X509CertificateTest,MultivalueRDN)252 TEST(X509CertificateTest, MultivalueRDN) {
253   base::FilePath certs_dir = GetTestCertsDirectory();
254 
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());
258 
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]);
271 }
272 
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
TEST(X509CertificateTest,UnescapedSpecialCharacters)276 TEST(X509CertificateTest, UnescapedSpecialCharacters) {
277   base::FilePath certs_dir = GetTestCertsDirectory();
278 
279   scoped_refptr<X509Certificate> unescaped_cert =
280       ImportCertFromFile(certs_dir, "unescaped.pem");
281   ASSERT_NE(static_cast<X509Certificate*>(NULL), unescaped_cert.get());
282 
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());
296 }
297 
TEST(X509CertificateTest,SerialNumbers)298 TEST(X509CertificateTest, SerialNumbers) {
299   scoped_refptr<X509Certificate> google_cert(
300       X509Certificate::CreateFromBytes(
301           reinterpret_cast<const char*>(google_der), sizeof(google_der)));
302 
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,
306   };
307 
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);
311 
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)));
318 
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);
324 }
325 
TEST(X509CertificateTest,CAFingerprints)326 TEST(X509CertificateTest, CAFingerprints) {
327   base::FilePath certs_dir = GetTestCertsDirectory();
328 
329   scoped_refptr<X509Certificate> server_cert =
330       ImportCertFromFile(certs_dir, "salesforce_com_test.pem");
331   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
332 
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());
336 
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());
340 
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);
346 
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);
352 
353   // No intermediate CA certicates.
354   intermediates.clear();
355   scoped_refptr<X509Certificate> cert_chain3 =
356       X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
357                                         intermediates);
358 
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
362   };
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
366   };
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
371   };
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);
378 
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
386   };
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
392   };
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
399   };
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);
415 
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
421   };
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
427   };
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
433   };
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);
452 }
453 
TEST(X509CertificateTest,ParseSubjectAltNames)454 TEST(X509CertificateTest, ParseSubjectAltNames) {
455   base::FilePath certs_dir = GetTestCertsDirectory();
456 
457   scoped_refptr<X509Certificate> san_cert =
458       ImportCertFromFile(certs_dir, "subjectAltName_sanity_check.pem");
459   ASSERT_NE(static_cast<X509Certificate*>(NULL), san_cert.get());
460 
461   std::vector<std::string> dns_names;
462   std::vector<std::string> ip_addresses;
463   san_cert->GetSubjectAltName(&dns_names, &ip_addresses);
464 
465   // Ensure that DNS names are correctly parsed.
466   ASSERT_EQ(1U, dns_names.size());
467   EXPECT_EQ("test.example", dns_names[0]);
468 
469   // Ensure that both IPv4 and IPv6 addresses are correctly parsed.
470   ASSERT_EQ(2U, ip_addresses.size());
471 
472   static const uint8 kIPv4Address[] = {
473       0x7F, 0x00, 0x00, 0x02
474   };
475   ASSERT_EQ(arraysize(kIPv4Address), ip_addresses[0].size());
476   EXPECT_EQ(0, memcmp(ip_addresses[0].data(), kIPv4Address,
477                       arraysize(kIPv4Address)));
478 
479   static const uint8 kIPv6Address[] = {
480       0xFE, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
481       0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01
482   };
483   ASSERT_EQ(arraysize(kIPv6Address), ip_addresses[1].size());
484   EXPECT_EQ(0, memcmp(ip_addresses[1].data(), kIPv6Address,
485                       arraysize(kIPv6Address)));
486 
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);
490 }
491 
TEST(X509CertificateTest,ExtractSPKIFromDERCert)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());
497 
498   std::string derBytes;
499   EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
500                                              &derBytes));
501 
502   base::StringPiece spkiBytes;
503   EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes));
504 
505   uint8 hash[base::kSHA1Length];
506   base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()),
507                       spkiBytes.size(), hash);
508 
509   EXPECT_EQ(0, memcmp(hash, kNistSPKIHash, sizeof(hash)));
510 }
511 
TEST(X509CertificateTest,ExtractCRLURLsFromDERCert)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());
517 
518   std::string derBytes;
519   EXPECT_TRUE(X509Certificate::GetDEREncoded(cert->os_cert_handle(),
520                                              &derBytes));
521 
522   std::vector<base::StringPiece> crl_urls;
523   EXPECT_TRUE(asn1::ExtractCRLURLsFromDERCert(derBytes, &crl_urls));
524 
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());
529   }
530 }
531 
532 // Tests X509CertificateCache via X509Certificate::CreateFromHandle.  We
533 // call X509Certificate::CreateFromHandle several times and observe whether
534 // it returns a cached or new OSCertHandle.
TEST(X509CertificateTest,Cache)535 TEST(X509CertificateTest, Cache) {
536   X509Certificate::OSCertHandle google_cert_handle;
537   X509Certificate::OSCertHandle thawte_cert_handle;
538 
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);
545 
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);
552 
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());
559 
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);
573 
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());
580 }
581 
TEST(X509CertificateTest,Pickle)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));
589 
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());
595 
596   X509Certificate::FreeOSCertHandle(google_cert_handle);
597   X509Certificate::FreeOSCertHandle(thawte_cert_handle);
598 
599   Pickle pickle;
600   cert->Persist(&pickle);
601 
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]));
617   }
618 }
619 
TEST(X509CertificateTest,IntermediateCertificates)620 TEST(X509CertificateTest, IntermediateCertificates) {
621   scoped_refptr<X509Certificate> webkit_cert(
622       X509Certificate::CreateFromBytes(
623           reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
624 
625   scoped_refptr<X509Certificate> thawte_cert(
626       X509Certificate::CreateFromBytes(
627           reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
628 
629   X509Certificate::OSCertHandle google_handle;
630   // Create object with no intermediates:
631   google_handle = X509Certificate::CreateOSCertHandleFromBytes(
632       reinterpret_cast<const char*>(google_der), sizeof(google_der));
633   X509Certificate::OSCertHandles intermediates1;
634   scoped_refptr<X509Certificate> cert1;
635   cert1 = X509Certificate::CreateFromHandle(google_handle, intermediates1);
636   EXPECT_EQ(0u, cert1->GetIntermediateCertificates().size());
637 
638   // Create object with 2 intermediates:
639   X509Certificate::OSCertHandles intermediates2;
640   intermediates2.push_back(webkit_cert->os_cert_handle());
641   intermediates2.push_back(thawte_cert->os_cert_handle());
642   scoped_refptr<X509Certificate> cert2;
643   cert2 = X509Certificate::CreateFromHandle(google_handle, intermediates2);
644 
645   // Verify it has all the intermediates:
646   const X509Certificate::OSCertHandles& cert2_intermediates =
647       cert2->GetIntermediateCertificates();
648   ASSERT_EQ(2u, cert2_intermediates.size());
649   EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[0],
650                                             webkit_cert->os_cert_handle()));
651   EXPECT_TRUE(X509Certificate::IsSameOSCert(cert2_intermediates[1],
652                                             thawte_cert->os_cert_handle()));
653 
654   // Cleanup
655   X509Certificate::FreeOSCertHandle(google_handle);
656 }
657 
TEST(X509CertificateTest,IsIssuedByEncoded)658 TEST(X509CertificateTest, IsIssuedByEncoded) {
659   base::FilePath certs_dir = GetTestCertsDirectory();
660 
661   // Test a client certificate from MIT.
662   scoped_refptr<X509Certificate> mit_davidben_cert(
663       ImportCertFromFile(certs_dir, "mit.davidben.der"));
664   ASSERT_NE(static_cast<X509Certificate*>(NULL), mit_davidben_cert.get());
665 
666   std::string mit_issuer(reinterpret_cast<const char*>(MITDN),
667                          sizeof(MITDN));
668 
669   // Test a certificate from Google, issued by Thawte
670   scoped_refptr<X509Certificate> google_cert(
671       ImportCertFromFile(certs_dir, "google.single.der"));
672   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert.get());
673 
674   std::string thawte_issuer(reinterpret_cast<const char*>(ThawteDN),
675                             sizeof(ThawteDN));
676 
677   // Check that the David Ben certificate is issued by MIT, but not
678   // by Thawte.
679   std::vector<std::string> issuers;
680   issuers.clear();
681   issuers.push_back(mit_issuer);
682   EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
683   EXPECT_FALSE(google_cert->IsIssuedByEncoded(issuers));
684 
685   // Check that the Google certificate is issued by Thawte and not
686   // by MIT.
687   issuers.clear();
688   issuers.push_back(thawte_issuer);
689   EXPECT_FALSE(mit_davidben_cert->IsIssuedByEncoded(issuers));
690   EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
691 
692   // Check that they both pass when given a list of the two issuers.
693   issuers.clear();
694   issuers.push_back(mit_issuer);
695   issuers.push_back(thawte_issuer);
696   EXPECT_TRUE(mit_davidben_cert->IsIssuedByEncoded(issuers));
697   EXPECT_TRUE(google_cert->IsIssuedByEncoded(issuers));
698 }
699 
TEST(X509CertificateTest,IsIssuedByEncodedWithIntermediates)700 TEST(X509CertificateTest, IsIssuedByEncodedWithIntermediates) {
701   static const unsigned char kPolicyRootDN[] = {
702     0x30, 0x1e, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
703     0x13, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
704     0x20, 0x52, 0x6f, 0x6f, 0x74, 0x20, 0x43, 0x41
705   };
706   static const unsigned char kPolicyIntermediateDN[] = {
707     0x30, 0x26, 0x31, 0x24, 0x30, 0x22, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c,
708     0x1b, 0x50, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x20, 0x54, 0x65, 0x73, 0x74,
709     0x20, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6d, 0x65, 0x64, 0x69, 0x61, 0x74,
710     0x65, 0x20, 0x43, 0x41
711   };
712 
713   base::FilePath certs_dir = GetTestCertsDirectory();
714 
715   CertificateList policy_chain = CreateCertificateListFromFile(
716       certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO);
717   ASSERT_EQ(3u, policy_chain.size());
718 
719   // The intermediate CA certificate's policyConstraints extension has a
720   // requireExplicitPolicy field with SkipCerts=0.
721   std::string policy_intermediate_dn(
722       reinterpret_cast<const char*>(kPolicyIntermediateDN),
723       sizeof(kPolicyIntermediateDN));
724   std::string policy_root_dn(reinterpret_cast<const char*>(kPolicyRootDN),
725                              sizeof(kPolicyRootDN));
726 
727   X509Certificate::OSCertHandles intermediates;
728   intermediates.push_back(policy_chain[1]->os_cert_handle());
729   scoped_refptr<X509Certificate> cert_chain =
730       X509Certificate::CreateFromHandle(policy_chain[0]->os_cert_handle(),
731                                         intermediates);
732 
733   std::vector<std::string> issuers;
734 
735   // Check that the chain is issued by the intermediate.
736   issuers.clear();
737   issuers.push_back(policy_intermediate_dn);
738   EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
739 
740   // Check that the chain is also issued by the root.
741   issuers.clear();
742   issuers.push_back(policy_root_dn);
743   EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
744 
745   // Check that the chain is issued by either the intermediate or the root.
746   issuers.clear();
747   issuers.push_back(policy_intermediate_dn);
748   issuers.push_back(policy_root_dn);
749   EXPECT_TRUE(cert_chain->IsIssuedByEncoded(issuers));
750 
751   // Check that an empty issuers list returns false.
752   issuers.clear();
753   EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
754 
755   // Check that the chain is not issued by Verisign
756   std::string mit_issuer(reinterpret_cast<const char*>(VerisignDN),
757                          sizeof(VerisignDN));
758   issuers.clear();
759   issuers.push_back(mit_issuer);
760   EXPECT_FALSE(cert_chain->IsIssuedByEncoded(issuers));
761 }
762 
763 // Tests that FreeOSCertHandle ignores NULL on each OS.
TEST(X509CertificateTest,FreeNullHandle)764 TEST(X509CertificateTest, FreeNullHandle) {
765   X509Certificate::FreeOSCertHandle(NULL);
766 }
767 
768 #if defined(USE_NSS)
TEST(X509CertificateTest,GetDefaultNickname)769 TEST(X509CertificateTest, GetDefaultNickname) {
770   base::FilePath certs_dir = GetTestCertsDirectory();
771 
772   scoped_refptr<X509Certificate> test_cert(
773       ImportCertFromFile(certs_dir, "no_subject_common_name_cert.pem"));
774   ASSERT_NE(static_cast<X509Certificate*>(NULL), test_cert.get());
775 
776   std::string nickname = test_cert->GetDefaultNickname(USER_CERT);
777   EXPECT_EQ("wtc@google.com's COMODO Client Authentication and "
778             "Secure Email CA ID", nickname);
779 }
780 #endif
781 
782 const struct CertificateFormatTestData {
783   const char* file_name;
784   X509Certificate::Format format;
785   uint8* chain_fingerprints[3];
786 } kFormatTestData[] = {
787   // DER Parsing - single certificate, DER encoded
788   { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
789     { google_parse_fingerprint,
790       NULL, } },
791   // DER parsing - single certificate, PEM encoded
792   { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
793     { google_parse_fingerprint,
794       NULL, } },
795   // PEM parsing - single certificate, PEM encoded with a PEB of
796   // "CERTIFICATE"
797   { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
798     { google_parse_fingerprint,
799       NULL, } },
800   // PEM parsing - sequence of certificates, PEM encoded with a PEB of
801   // "CERTIFICATE"
802   { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
803     { google_parse_fingerprint,
804       thawte_parse_fingerprint,
805       NULL, } },
806   // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
807   // encoding
808   { "google.binary.p7b", X509Certificate::FORMAT_PKCS7,
809     { google_parse_fingerprint,
810       thawte_parse_fingerprint,
811       NULL, } },
812   // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
813   // encoded with a PEM PEB of "CERTIFICATE"
814   { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7,
815     { google_parse_fingerprint,
816       thawte_parse_fingerprint,
817       NULL, } },
818   // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
819   // encoded with a PEM PEB of "PKCS7"
820   { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7,
821     { google_parse_fingerprint,
822       thawte_parse_fingerprint,
823       NULL, } },
824   // All of the above, this time using auto-detection
825   { "google.single.der", X509Certificate::FORMAT_AUTO,
826     { google_parse_fingerprint,
827       NULL, } },
828   { "google.single.pem", X509Certificate::FORMAT_AUTO,
829     { google_parse_fingerprint,
830       NULL, } },
831   { "google.chain.pem", X509Certificate::FORMAT_AUTO,
832     { google_parse_fingerprint,
833       thawte_parse_fingerprint,
834       NULL, } },
835   { "google.binary.p7b", X509Certificate::FORMAT_AUTO,
836     { google_parse_fingerprint,
837       thawte_parse_fingerprint,
838       NULL, } },
839   { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO,
840     { google_parse_fingerprint,
841       thawte_parse_fingerprint,
842       NULL, } },
843   { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO,
844     { google_parse_fingerprint,
845       thawte_parse_fingerprint,
846       NULL, } },
847 };
848 
849 class X509CertificateParseTest
850     : public testing::TestWithParam<CertificateFormatTestData> {
851  public:
~X509CertificateParseTest()852   virtual ~X509CertificateParseTest() {}
SetUp()853   virtual void SetUp() {
854     test_data_ = GetParam();
855   }
TearDown()856   virtual void TearDown() {}
857 
858  protected:
859   CertificateFormatTestData test_data_;
860 };
861 
TEST_P(X509CertificateParseTest,CanParseFormat)862 TEST_P(X509CertificateParseTest, CanParseFormat) {
863   base::FilePath certs_dir = GetTestCertsDirectory();
864   CertificateList certs = CreateCertificateListFromFile(
865       certs_dir, test_data_.file_name, test_data_.format);
866   ASSERT_FALSE(certs.empty());
867   ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints));
868   CheckGoogleCert(certs.front(), google_parse_fingerprint,
869                   kGoogleParseValidFrom, kGoogleParseValidTo);
870 
871   size_t i;
872   for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) {
873     if (test_data_.chain_fingerprints[i] == NULL) {
874       // No more test certificates expected - make sure no more were
875       // returned before marking this test a success.
876       EXPECT_EQ(i, certs.size());
877       break;
878     }
879 
880     // A cert is expected - make sure that one was parsed.
881     ASSERT_LT(i, certs.size());
882 
883     // Compare the parsed certificate with the expected certificate, by
884     // comparing fingerprints.
885     const X509Certificate* cert = certs[i].get();
886     const SHA1HashValue& actual_fingerprint = cert->fingerprint();
887     uint8* expected_fingerprint = test_data_.chain_fingerprints[i];
888 
889     for (size_t j = 0; j < 20; ++j)
890       EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]);
891   }
892 }
893 
894 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
895                         testing::ValuesIn(kFormatTestData));
896 
897 struct CertificateNameVerifyTestData {
898   // true iff we expect hostname to match an entry in cert_names.
899   bool expected;
900   // The hostname to match.
901   const char* hostname;
902   // Common name, may be used if |dns_names| or |ip_addrs| are empty.
903   const char* common_name;
904   // Comma separated list of certificate names to match against. Any occurrence
905   // of '#' will be replaced with a null character before processing.
906   const char* dns_names;
907   // Comma separated list of certificate IP Addresses to match against. Each
908   // address is x prefixed 16 byte hex code for v6 or dotted-decimals for v4.
909   const char* ip_addrs;
910 };
911 
912 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
913 // to output the parameter that was passed. Without this, it will simply
914 // attempt to print out the first twenty bytes of the object, which depending
915 // on platform and alignment, may result in an invalid read.
PrintTo(const CertificateNameVerifyTestData & data,std::ostream * os)916 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
917   ASSERT_TRUE(data.hostname && data.common_name);
918   // Using StringPiece to allow for optional fields being NULL.
919   *os << " expected: " << data.expected
920       << "; hostname: " << data.hostname
921       << "; common_name: " << data.common_name
922       << "; dns_names: " << base::StringPiece(data.dns_names)
923       << "; ip_addrs: " << base::StringPiece(data.ip_addrs);
924 }
925 
926 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
927     { true, "foo.com", "foo.com" },
928     { true, "f", "f" },
929     { false, "h", "i" },
930     { true, "bar.foo.com", "*.foo.com" },
931     { true, "www.test.fr", "common.name",
932         "*.test.com,*.test.co.uk,*.test.de,*.test.fr" },
933     { true, "wwW.tESt.fr",  "common.name",
934         ",*.*,*.test.de,*.test.FR,www" },
935     { false, "f.uk", ".uk" },
936     { false, "w.bar.foo.com", "?.bar.foo.com" },
937     { false, "www.foo.com", "(www|ftp).foo.com" },
938     { false, "www.foo.com", "www.foo.com#" },  // # = null char.
939     { false, "www.foo.com", "", "www.foo.com#*.foo.com,#,#" },
940     { false, "www.house.example", "ww.house.example" },
941     { false, "test.org", "", "www.test.org,*.test.org,*.org" },
942     { false, "w.bar.foo.com", "w*.bar.foo.com" },
943     { false, "www.bar.foo.com", "ww*ww.bar.foo.com" },
944     { false, "wwww.bar.foo.com", "ww*ww.bar.foo.com" },
945     { true, "wwww.bar.foo.com", "w*w.bar.foo.com" },
946     { false, "wwww.bar.foo.com", "w*w.bar.foo.c0m" },
947     { true, "WALLY.bar.foo.com", "wa*.bar.foo.com" },
948     { true, "wally.bar.foo.com", "*Ly.bar.foo.com" },
949     { true, "ww%57.foo.com", "", "www.foo.com" },
950     { true, "www&.foo.com", "www%26.foo.com" },
951     // Common name must not be used if subject alternative name was provided.
952     { false, "www.test.co.jp",  "www.test.co.jp",
953         "*.test.de,*.jp,www.test.co.uk,www.*.co.jp" },
954     { false, "www.bar.foo.com", "www.bar.foo.com",
955       "*.foo.com,*.*.foo.com,*.*.bar.foo.com,*..bar.foo.com," },
956     { false, "www.bath.org", "www.bath.org", "", "20.30.40.50" },
957     { false, "66.77.88.99", "www.bath.org", "www.bath.org" },
958     // IDN tests
959     { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
960     { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
961     { false, "xn--poema-9qae5a.com.br", "", "*.xn--poema-9qae5a.com.br,"
962                                             "xn--poema-*.com.br,"
963                                             "xn--*-9qae5a.com.br,"
964                                             "*--poema-9qae5a.com.br" },
965     // The following are adapted from the  examples quoted from
966     // http://tools.ietf.org/html/rfc6125#section-6.4.3
967     //  (e.g., *.example.com would match foo.example.com but
968     //   not bar.foo.example.com or example.com).
969     { true, "foo.example.com", "*.example.com" },
970     { false, "bar.foo.example.com", "*.example.com" },
971     { false, "example.com", "*.example.com" },
972     //   (e.g., baz*.example.net and *baz.example.net and b*z.example.net would
973     //   be taken to match baz1.example.net and foobaz.example.net and
974     //   buzz.example.net, respectively
975     { true, "baz1.example.net", "baz*.example.net" },
976     { true, "foobaz.example.net", "*baz.example.net" },
977     { true, "buzz.example.net", "b*z.example.net" },
978     // Wildcards should not be valid for public registry controlled domains,
979     // and unknown/unrecognized domains, at least three domain components must
980     // be present.
981     { true, "www.test.example", "*.test.example" },
982     { true, "test.example.co.uk", "*.example.co.uk" },
983     { false, "test.example", "*.exmaple" },
984     { false, "example.co.uk", "*.co.uk" },
985     { false, "foo.com", "*.com" },
986     { false, "foo.us", "*.us" },
987     { false, "foo", "*" },
988     // IDN variants of wildcards and registry controlled domains.
989     { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
990     { true, "test.example.xn--mgbaam7a8h", "*.example.xn--mgbaam7a8h" },
991     { false, "xn--poema-9qae5a.com.br", "*.com.br" },
992     { false, "example.xn--mgbaam7a8h", "*.xn--mgbaam7a8h" },
993     // Wildcards should be permissible for 'private' registry controlled
994     // domains.
995     { true, "www.appspot.com", "*.appspot.com" },
996     { true, "foo.s3.amazonaws.com", "*.s3.amazonaws.com" },
997     // Multiple wildcards are not valid.
998     { false, "foo.example.com", "*.*.com" },
999     { false, "foo.bar.example.com", "*.bar.*.com" },
1000     // Absolute vs relative DNS name tests. Although not explicitly specified
1001     // in RFC 6125, absolute reference names (those ending in a .) should
1002     // match either absolute or relative presented names.
1003     { true, "foo.com", "foo.com." },
1004     { true, "foo.com.", "foo.com" },
1005     { true, "foo.com.", "foo.com." },
1006     { true, "f", "f." },
1007     { true, "f.", "f" },
1008     { true, "f.", "f." },
1009     { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1010     { true, "www-3.bar.foo.com.", "*.bar.foo.com" },
1011     { true, "www-3.bar.foo.com.", "*.bar.foo.com." },
1012     { false, ".", "." },
1013     { false, "example.com", "*.com." },
1014     { false, "example.com.", "*.com" },
1015     { false, "example.com.", "*.com." },
1016     { false, "foo.", "*." },
1017     { false, "foo", "*." },
1018     { false, "foo.co.uk", "*.co.uk." },
1019     { false, "foo.co.uk.", "*.co.uk." },
1020     // IP addresses in common name; IPv4 only.
1021     { true, "127.0.0.1", "127.0.0.1" },
1022     { true, "192.168.1.1", "192.168.1.1" },
1023     { true,  "676768", "0.10.83.160" },
1024     { true,  "1.2.3", "1.2.0.3" },
1025     { false, "192.169.1.1", "192.168.1.1" },
1026     { false, "12.19.1.1", "12.19.1.1/255.255.255.0" },
1027     { false, "FEDC:ba98:7654:3210:FEDC:BA98:7654:3210",
1028       "FEDC:BA98:7654:3210:FEDC:ba98:7654:3210" },
1029     { false, "1111:2222:3333:4444:5555:6666:7777:8888",
1030       "1111:2222:3333:4444:5555:6666:7777:8888" },
1031     { false, "::192.9.5.5", "[::192.9.5.5]" },
1032     // No wildcard matching in valid IP addresses
1033     { false, "::192.9.5.5", "*.9.5.5" },
1034     { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1035     { false, "192.168.1.11", "*.168.1.11" },
1036     { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1037     // IP addresses in subject alternative name (common name ignored)
1038     { true, "10.1.2.3", "", "", "10.1.2.3" },
1039     { true,  "14.15", "", "", "14.0.0.15" },
1040     { false, "10.1.2.7", "10.1.2.7", "", "10.1.2.6,10.1.2.8" },
1041     { false, "10.1.2.8", "10.20.2.8", "foo" },
1042     { true, "::4.5.6.7", "", "", "x00000000000000000000000004050607" },
1043     { false, "::6.7.8.9", "::6.7.8.9", "::6.7.8.9",
1044         "x00000000000000000000000006070808,x0000000000000000000000000607080a,"
1045         "xff000000000000000000000006070809,6.7.8.9" },
1046     { true, "FE80::200:f8ff:fe21:67cf", "no.common.name", "",
1047         "x00000000000000000000000006070808,xfe800000000000000200f8fffe2167cf,"
1048         "xff0000000000000000000000060708ff,10.0.0.1" },
1049     // Numeric only hostnames (none of these are considered valid IP addresses).
1050     { false,  "12345.6", "12345.6" },
1051     { false, "121.2.3.512", "", "1*1.2.3.512,*1.2.3.512,1*.2.3.512,*.2.3.512",
1052         "121.2.3.0"},
1053     { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1054     { true, "1.2.3.4.5", "", "1.2.3.4.5" },
1055     // Invalid host names.
1056     { false, "junk)(£)$*!@~#", "junk)(£)$*!@~#" },
1057     { false, "www.*.com", "www.*.com" },
1058     { false, "w$w.f.com", "w$w.f.com" },
1059     { false, "nocolonallowed:example", "", "nocolonallowed:example" },
1060     { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1061     { false, "[::4.5.6.9]", "", "", "x00000000000000000000000004050609" },
1062 };
1063 
1064 class X509CertificateNameVerifyTest
1065     : public testing::TestWithParam<CertificateNameVerifyTestData> {
1066 };
1067 
TEST_P(X509CertificateNameVerifyTest,VerifyHostname)1068 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1069   CertificateNameVerifyTestData test_data = GetParam();
1070 
1071   std::string common_name(test_data.common_name);
1072   ASSERT_EQ(std::string::npos, common_name.find(','));
1073   std::replace(common_name.begin(), common_name.end(), '#', '\0');
1074 
1075   std::vector<std::string> dns_names, ip_addressses;
1076   if (test_data.dns_names) {
1077     // Build up the certificate DNS names list.
1078     std::string dns_name_line(test_data.dns_names);
1079     std::replace(dns_name_line.begin(), dns_name_line.end(), '#', '\0');
1080     base::SplitString(dns_name_line, ',', &dns_names);
1081   }
1082 
1083   if (test_data.ip_addrs) {
1084     // Build up the certificate IP address list.
1085     std::string ip_addrs_line(test_data.ip_addrs);
1086     std::vector<std::string> ip_addressses_ascii;
1087     base::SplitString(ip_addrs_line, ',', &ip_addressses_ascii);
1088     for (size_t i = 0; i < ip_addressses_ascii.size(); ++i) {
1089       std::string& addr_ascii = ip_addressses_ascii[i];
1090       ASSERT_NE(0U, addr_ascii.length());
1091       if (addr_ascii[0] == 'x') {  // Hex encoded address
1092         addr_ascii.erase(0, 1);
1093         std::vector<uint8> bytes;
1094         EXPECT_TRUE(base::HexStringToBytes(addr_ascii, &bytes))
1095             << "Could not parse hex address " << addr_ascii << " i = " << i;
1096         ip_addressses.push_back(std::string(reinterpret_cast<char*>(&bytes[0]),
1097                                             bytes.size()));
1098         ASSERT_EQ(16U, ip_addressses.back().size()) << i;
1099       } else {  // Decimal groups
1100         std::vector<std::string> decimals_ascii;
1101         base::SplitString(addr_ascii, '.', &decimals_ascii);
1102         EXPECT_EQ(4U, decimals_ascii.size()) << i;
1103         std::string addr_bytes;
1104         for (size_t j = 0; j < decimals_ascii.size(); ++j) {
1105           int decimal_value;
1106           EXPECT_TRUE(base::StringToInt(decimals_ascii[j], &decimal_value));
1107           EXPECT_GE(decimal_value, 0);
1108           EXPECT_LE(decimal_value, 255);
1109           addr_bytes.push_back(static_cast<char>(decimal_value));
1110         }
1111         ip_addressses.push_back(addr_bytes);
1112         ASSERT_EQ(4U, ip_addressses.back().size()) << i;
1113       }
1114     }
1115   }
1116 
1117   bool unused = false;
1118   EXPECT_EQ(test_data.expected, X509Certificate::VerifyHostname(
1119       test_data.hostname, common_name, dns_names, ip_addressses, &unused));
1120 }
1121 
1122 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1123                         testing::ValuesIn(kNameVerifyTestData));
1124 
1125 const struct PublicKeyInfoTestData {
1126   const char* cert_file;
1127   size_t expected_bits;
1128   X509Certificate::PublicKeyType expected_type;
1129 } kPublicKeyInfoTestData[] = {
1130   { "768-rsa-ee-by-768-rsa-intermediate.pem", 768,
1131     X509Certificate::kPublicKeyTypeRSA },
1132   { "1024-rsa-ee-by-768-rsa-intermediate.pem", 1024,
1133     X509Certificate::kPublicKeyTypeRSA },
1134   { "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem", 256,
1135     X509Certificate::kPublicKeyTypeECDSA },
1136 };
1137 
1138 class X509CertificatePublicKeyInfoTest
1139     : public testing::TestWithParam<PublicKeyInfoTestData> {
1140 };
1141 
TEST_P(X509CertificatePublicKeyInfoTest,GetPublicKeyInfo)1142 TEST_P(X509CertificatePublicKeyInfoTest, GetPublicKeyInfo) {
1143   PublicKeyInfoTestData data = GetParam();
1144 
1145 #if defined(OS_WIN)
1146   if (base::win::GetVersion() < base::win::VERSION_VISTA &&
1147       data.expected_type == X509Certificate::kPublicKeyTypeECDSA) {
1148     // ECC is only supported on Vista+. Skip the test.
1149     return;
1150   }
1151 #endif
1152 
1153   scoped_refptr<X509Certificate> cert(
1154       ImportCertFromFile(GetTestCertsDirectory(), data.cert_file));
1155   ASSERT_TRUE(cert.get());
1156 
1157   size_t actual_bits = 0;
1158   X509Certificate::PublicKeyType actual_type =
1159       X509Certificate::kPublicKeyTypeUnknown;
1160 
1161   X509Certificate::GetPublicKeyInfo(cert->os_cert_handle(), &actual_bits,
1162                                     &actual_type);
1163 
1164   EXPECT_EQ(data.expected_bits, actual_bits);
1165   EXPECT_EQ(data.expected_type, actual_type);
1166 }
1167 
1168 INSTANTIATE_TEST_CASE_P(, X509CertificatePublicKeyInfoTest,
1169                         testing::ValuesIn(kPublicKeyInfoTestData));
1170 
1171 }  // namespace net
1172