• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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 "base/file_path.h"
6 #include "base/file_util.h"
7 #include "base/path_service.h"
8 #include "base/pickle.h"
9 #include "base/sha1.h"
10 #include "base/string_number_conversions.h"
11 #include "base/string_split.h"
12 #include "crypto/rsa_private_key.h"
13 #include "net/base/asn1_util.h"
14 #include "net/base/cert_status_flags.h"
15 #include "net/base/cert_test_util.h"
16 #include "net/base/cert_verify_result.h"
17 #include "net/base/net_errors.h"
18 #include "net/base/test_certificate_data.h"
19 #include "net/base/test_root_certs.h"
20 #include "net/base/x509_certificate.h"
21 #include "testing/gtest/include/gtest/gtest.h"
22 
23 // Unit tests aren't allowed to access external resources. Unfortunately, to
24 // properly verify the EV-ness of a cert, we need to check for its revocation
25 // through online servers. If you're manually running unit tests, feel free to
26 // turn this on to test EV certs. But leave it turned off for the automated
27 // testing.
28 #define ALLOW_EXTERNAL_ACCESS 0
29 
30 #if ALLOW_EXTERNAL_ACCESS && defined(OS_WIN)
31 #define TEST_EV 1  // Test CERT_STATUS_IS_EV
32 #endif
33 
34 using base::HexEncode;
35 using base::SHA1_LENGTH;
36 using base::Time;
37 
38 namespace net {
39 
40 // Certificates for test data. They're obtained with:
41 //
42 // $ openssl s_client -connect [host]:443 -showcerts > /tmp/host.pem < /dev/null
43 // $ openssl x509 -inform PEM -outform DER < /tmp/host.pem > /tmp/host.der
44 //
45 // For fingerprint
46 // $ openssl x509 -inform DER -fingerprint -noout < /tmp/host.der
47 
48 // For valid_start, valid_expiry
49 // $ openssl x509 -inform DER -text -noout < /tmp/host.der |
50 //    grep -A 2 Validity
51 // $ date +%s -d '<date str>'
52 
53 // Google's cert.
54 unsigned char google_fingerprint[] = {
55   0xab, 0xbe, 0x5e, 0xb4, 0x93, 0x88, 0x4e, 0xe4, 0x60, 0xc6, 0xef, 0xf8,
56   0xea, 0xd4, 0xb1, 0x55, 0x4b, 0xc9, 0x59, 0x3c
57 };
58 
59 // webkit.org's cert.
60 unsigned char webkit_fingerprint[] = {
61   0xa1, 0x4a, 0x94, 0x46, 0x22, 0x8e, 0x70, 0x66, 0x2b, 0x94, 0xf9, 0xf8,
62   0x57, 0x83, 0x2d, 0xa2, 0xff, 0xbc, 0x84, 0xc2
63 };
64 
65 // thawte.com's cert (it's EV-licious!).
66 unsigned char thawte_fingerprint[] = {
67   0x85, 0x04, 0x2d, 0xfd, 0x2b, 0x0e, 0xc6, 0xc8, 0xaf, 0x2d, 0x77, 0xd6,
68   0xa1, 0x3a, 0x64, 0x04, 0x27, 0x90, 0x97, 0x37
69 };
70 
71 // A certificate for www.paypal.com with a NULL byte in the common name.
72 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
73 unsigned char paypal_null_fingerprint[] = {
74   0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
75   0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
76 };
77 
78 // A certificate for https://www.unosoft.hu/, whose AIA extension contains
79 // an LDAP URL without a host name.
80 unsigned char unosoft_hu_fingerprint[] = {
81   0x32, 0xff, 0xe3, 0xbe, 0x2c, 0x3b, 0xc7, 0xca, 0xbf, 0x2d, 0x64, 0xbd,
82   0x25, 0x66, 0xf2, 0xec, 0x8b, 0x0f, 0xbf, 0xd8
83 };
84 
85 // The fingerprint of the Google certificate used in the parsing tests,
86 // which is newer than the one included in the x509_certificate_data.h
87 unsigned char google_parse_fingerprint[] = {
88   0x40, 0x50, 0x62, 0xe5, 0xbe, 0xfd, 0xe4, 0xaf, 0x97, 0xe9, 0x38, 0x2a,
89   0xf1, 0x6c, 0xc8, 0x7c, 0x8f, 0xb7, 0xc4, 0xe2
90 };
91 
92 // The fingerprint for the Thawte SGC certificate
93 unsigned char thawte_parse_fingerprint[] = {
94   0xec, 0x07, 0x10, 0x03, 0xd8, 0xf5, 0xa3, 0x7f, 0x42, 0xc4, 0x55, 0x7f,
95   0x65, 0x6a, 0xae, 0x86, 0x65, 0xfa, 0x4b, 0x02
96 };
97 
98 // Dec 18 00:00:00 2009 GMT
99 const double kGoogleParseValidFrom = 1261094400;
100 // Dec 18 23:59:59 2011 GMT
101 const double kGoogleParseValidTo = 1324252799;
102 
103 struct CertificateFormatTestData {
104   const char* file_name;
105   X509Certificate::Format format;
106   unsigned char* chain_fingerprints[3];
107 };
108 
109 const CertificateFormatTestData FormatTestData[] = {
110   // DER Parsing - single certificate, DER encoded
111   { "google.single.der", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
112     { google_parse_fingerprint,
113       NULL, } },
114   // DER parsing - single certificate, PEM encoded
115   { "google.single.pem", X509Certificate::FORMAT_SINGLE_CERTIFICATE,
116     { google_parse_fingerprint,
117       NULL, } },
118   // PEM parsing - single certificate, PEM encoded with a PEB of
119   // "CERTIFICATE"
120   { "google.single.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
121     { google_parse_fingerprint,
122       NULL, } },
123   // PEM parsing - sequence of certificates, PEM encoded with a PEB of
124   // "CERTIFICATE"
125   { "google.chain.pem", X509Certificate::FORMAT_PEM_CERT_SEQUENCE,
126     { google_parse_fingerprint,
127       thawte_parse_fingerprint,
128       NULL, } },
129   // PKCS#7 parsing - "degenerate" SignedData collection of certificates, DER
130   // encoding
131   { "google.binary.p7b", X509Certificate::FORMAT_PKCS7,
132     { google_parse_fingerprint,
133       thawte_parse_fingerprint,
134       NULL, } },
135   // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
136   // encoded with a PEM PEB of "CERTIFICATE"
137   { "google.pem_cert.p7b", X509Certificate::FORMAT_PKCS7,
138     { google_parse_fingerprint,
139       thawte_parse_fingerprint,
140       NULL, } },
141   // PKCS#7 parsing - "degenerate" SignedData collection of certificates, PEM
142   // encoded with a PEM PEB of "PKCS7"
143   { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_PKCS7,
144     { google_parse_fingerprint,
145       thawte_parse_fingerprint,
146       NULL, } },
147   // All of the above, this time using auto-detection
148   { "google.single.der", X509Certificate::FORMAT_AUTO,
149     { google_parse_fingerprint,
150       NULL, } },
151   { "google.single.pem", X509Certificate::FORMAT_AUTO,
152     { google_parse_fingerprint,
153       NULL, } },
154   { "google.chain.pem", X509Certificate::FORMAT_AUTO,
155     { google_parse_fingerprint,
156       thawte_parse_fingerprint,
157       NULL, } },
158   { "google.binary.p7b", X509Certificate::FORMAT_AUTO,
159     { google_parse_fingerprint,
160       thawte_parse_fingerprint,
161       NULL, } },
162   { "google.pem_cert.p7b", X509Certificate::FORMAT_AUTO,
163     { google_parse_fingerprint,
164       thawte_parse_fingerprint,
165       NULL, } },
166   { "google.pem_pkcs7.p7b", X509Certificate::FORMAT_AUTO,
167     { google_parse_fingerprint,
168       thawte_parse_fingerprint,
169       NULL, } },
170 };
171 
CreateCertificateListFromFile(const FilePath & certs_dir,const std::string & cert_file,int format)172 CertificateList CreateCertificateListFromFile(
173     const FilePath& certs_dir,
174     const std::string& cert_file,
175     int format) {
176   FilePath cert_path = certs_dir.AppendASCII(cert_file);
177   std::string cert_data;
178   if (!file_util::ReadFileToString(cert_path, &cert_data))
179     return CertificateList();
180   return X509Certificate::CreateCertificateListFromBytes(cert_data.data(),
181                                                          cert_data.size(),
182                                                          format);
183 }
184 
CheckGoogleCert(const scoped_refptr<X509Certificate> & google_cert,unsigned char * expected_fingerprint,double valid_from,double valid_to)185 void CheckGoogleCert(const scoped_refptr<X509Certificate>& google_cert,
186                      unsigned char* expected_fingerprint,
187                      double valid_from, double valid_to) {
188   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_cert);
189 
190   const CertPrincipal& subject = google_cert->subject();
191   EXPECT_EQ("www.google.com", subject.common_name);
192   EXPECT_EQ("Mountain View", subject.locality_name);
193   EXPECT_EQ("California", subject.state_or_province_name);
194   EXPECT_EQ("US", subject.country_name);
195   EXPECT_EQ(0U, subject.street_addresses.size());
196   ASSERT_EQ(1U, subject.organization_names.size());
197   EXPECT_EQ("Google Inc", subject.organization_names[0]);
198   EXPECT_EQ(0U, subject.organization_unit_names.size());
199   EXPECT_EQ(0U, subject.domain_components.size());
200 
201   const CertPrincipal& issuer = google_cert->issuer();
202   EXPECT_EQ("Thawte SGC CA", issuer.common_name);
203   EXPECT_EQ("", issuer.locality_name);
204   EXPECT_EQ("", issuer.state_or_province_name);
205   EXPECT_EQ("ZA", issuer.country_name);
206   EXPECT_EQ(0U, issuer.street_addresses.size());
207   ASSERT_EQ(1U, issuer.organization_names.size());
208   EXPECT_EQ("Thawte Consulting (Pty) Ltd.", issuer.organization_names[0]);
209   EXPECT_EQ(0U, issuer.organization_unit_names.size());
210   EXPECT_EQ(0U, issuer.domain_components.size());
211 
212   // Use DoubleT because its epoch is the same on all platforms
213   const Time& valid_start = google_cert->valid_start();
214   EXPECT_EQ(valid_from, valid_start.ToDoubleT());
215 
216   const Time& valid_expiry = google_cert->valid_expiry();
217   EXPECT_EQ(valid_to, valid_expiry.ToDoubleT());
218 
219   const SHA1Fingerprint& fingerprint = google_cert->fingerprint();
220   for (size_t i = 0; i < 20; ++i)
221     EXPECT_EQ(expected_fingerprint[i], fingerprint.data[i]);
222 
223   std::vector<std::string> dns_names;
224   google_cert->GetDNSNames(&dns_names);
225   ASSERT_EQ(1U, dns_names.size());
226   EXPECT_EQ("www.google.com", dns_names[0]);
227 
228 #if TEST_EV
229   // TODO(avi): turn this on for the Mac once EV checking is implemented.
230   CertVerifyResult verify_result;
231   int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED |
232                 X509Certificate::VERIFY_EV_CERT;
233   EXPECT_EQ(OK, google_cert->Verify("www.google.com", flags, &verify_result));
234   EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV);
235 #endif
236 }
237 
TEST(X509CertificateTest,GoogleCertParsing)238 TEST(X509CertificateTest, GoogleCertParsing) {
239   scoped_refptr<X509Certificate> google_cert(
240       X509Certificate::CreateFromBytes(
241           reinterpret_cast<const char*>(google_der), sizeof(google_der)));
242 
243   CheckGoogleCert(google_cert, google_fingerprint,
244                   1238192407,   // Mar 27 22:20:07 2009 GMT
245                   1269728407);  // Mar 27 22:20:07 2010 GMT
246 }
247 
TEST(X509CertificateTest,WebkitCertParsing)248 TEST(X509CertificateTest, WebkitCertParsing) {
249   scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
250       reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
251 
252   ASSERT_NE(static_cast<X509Certificate*>(NULL), webkit_cert);
253 
254   const CertPrincipal& subject = webkit_cert->subject();
255   EXPECT_EQ("Cupertino", subject.locality_name);
256   EXPECT_EQ("California", subject.state_or_province_name);
257   EXPECT_EQ("US", subject.country_name);
258   EXPECT_EQ(0U, subject.street_addresses.size());
259   ASSERT_EQ(1U, subject.organization_names.size());
260   EXPECT_EQ("Apple Inc.", subject.organization_names[0]);
261   ASSERT_EQ(1U, subject.organization_unit_names.size());
262   EXPECT_EQ("Mac OS Forge", subject.organization_unit_names[0]);
263   EXPECT_EQ(0U, subject.domain_components.size());
264 
265   const CertPrincipal& issuer = webkit_cert->issuer();
266   EXPECT_EQ("Go Daddy Secure Certification Authority", issuer.common_name);
267   EXPECT_EQ("Scottsdale", issuer.locality_name);
268   EXPECT_EQ("Arizona", issuer.state_or_province_name);
269   EXPECT_EQ("US", issuer.country_name);
270   EXPECT_EQ(0U, issuer.street_addresses.size());
271   ASSERT_EQ(1U, issuer.organization_names.size());
272   EXPECT_EQ("GoDaddy.com, Inc.", issuer.organization_names[0]);
273   ASSERT_EQ(1U, issuer.organization_unit_names.size());
274   EXPECT_EQ("http://certificates.godaddy.com/repository",
275       issuer.organization_unit_names[0]);
276   EXPECT_EQ(0U, issuer.domain_components.size());
277 
278   // Use DoubleT because its epoch is the same on all platforms
279   const Time& valid_start = webkit_cert->valid_start();
280   EXPECT_EQ(1205883319, valid_start.ToDoubleT());  // Mar 18 23:35:19 2008 GMT
281 
282   const Time& valid_expiry = webkit_cert->valid_expiry();
283   EXPECT_EQ(1300491319, valid_expiry.ToDoubleT());  // Mar 18 23:35:19 2011 GMT
284 
285   const SHA1Fingerprint& fingerprint = webkit_cert->fingerprint();
286   for (size_t i = 0; i < 20; ++i)
287     EXPECT_EQ(webkit_fingerprint[i], fingerprint.data[i]);
288 
289   std::vector<std::string> dns_names;
290   webkit_cert->GetDNSNames(&dns_names);
291   ASSERT_EQ(2U, dns_names.size());
292   EXPECT_EQ("*.webkit.org", dns_names[0]);
293   EXPECT_EQ("webkit.org", dns_names[1]);
294 
295 #if TEST_EV
296   int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED |
297                 X509Certificate::VERIFY_EV_CERT;
298   CertVerifyResult verify_result;
299   EXPECT_EQ(OK, webkit_cert->Verify("webkit.org", flags, &verify_result));
300   EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV);
301 #endif
302 
303   // Test that the wildcard cert matches properly.
304   EXPECT_TRUE(webkit_cert->VerifyNameMatch("www.webkit.org"));
305   EXPECT_TRUE(webkit_cert->VerifyNameMatch("foo.webkit.org"));
306   EXPECT_TRUE(webkit_cert->VerifyNameMatch("webkit.org"));
307   EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.webkit.com"));
308   EXPECT_FALSE(webkit_cert->VerifyNameMatch("www.foo.webkit.com"));
309 }
310 
TEST(X509CertificateTest,ThawteCertParsing)311 TEST(X509CertificateTest, ThawteCertParsing) {
312   scoped_refptr<X509Certificate> thawte_cert(X509Certificate::CreateFromBytes(
313       reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
314 
315   ASSERT_NE(static_cast<X509Certificate*>(NULL), thawte_cert);
316 
317   const CertPrincipal& subject = thawte_cert->subject();
318   EXPECT_EQ("www.thawte.com", subject.common_name);
319   EXPECT_EQ("Mountain View", subject.locality_name);
320   EXPECT_EQ("California", subject.state_or_province_name);
321   EXPECT_EQ("US", subject.country_name);
322   EXPECT_EQ(0U, subject.street_addresses.size());
323   ASSERT_EQ(1U, subject.organization_names.size());
324   EXPECT_EQ("Thawte Inc", subject.organization_names[0]);
325   EXPECT_EQ(0U, subject.organization_unit_names.size());
326   EXPECT_EQ(0U, subject.domain_components.size());
327 
328   const CertPrincipal& issuer = thawte_cert->issuer();
329   EXPECT_EQ("thawte Extended Validation SSL CA", issuer.common_name);
330   EXPECT_EQ("", issuer.locality_name);
331   EXPECT_EQ("", issuer.state_or_province_name);
332   EXPECT_EQ("US", issuer.country_name);
333   EXPECT_EQ(0U, issuer.street_addresses.size());
334   ASSERT_EQ(1U, issuer.organization_names.size());
335   EXPECT_EQ("thawte, Inc.", issuer.organization_names[0]);
336   ASSERT_EQ(1U, issuer.organization_unit_names.size());
337   EXPECT_EQ("Terms of use at https://www.thawte.com/cps (c)06",
338             issuer.organization_unit_names[0]);
339   EXPECT_EQ(0U, issuer.domain_components.size());
340 
341   // Use DoubleT because its epoch is the same on all platforms
342   const Time& valid_start = thawte_cert->valid_start();
343   EXPECT_EQ(1227052800, valid_start.ToDoubleT());  // Nov 19 00:00:00 2008 GMT
344 
345   const Time& valid_expiry = thawte_cert->valid_expiry();
346   EXPECT_EQ(1263772799, valid_expiry.ToDoubleT());  // Jan 17 23:59:59 2010 GMT
347 
348   const SHA1Fingerprint& fingerprint = thawte_cert->fingerprint();
349   for (size_t i = 0; i < 20; ++i)
350     EXPECT_EQ(thawte_fingerprint[i], fingerprint.data[i]);
351 
352   std::vector<std::string> dns_names;
353   thawte_cert->GetDNSNames(&dns_names);
354   ASSERT_EQ(1U, dns_names.size());
355   EXPECT_EQ("www.thawte.com", dns_names[0]);
356 
357 #if TEST_EV
358   int flags = X509Certificate::VERIFY_REV_CHECKING_ENABLED |
359                 X509Certificate::VERIFY_EV_CERT;
360   CertVerifyResult verify_result;
361   // EV cert verification requires revocation checking.
362   EXPECT_EQ(OK, thawte_cert->Verify("www.thawte.com", flags, &verify_result));
363   EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_IS_EV);
364   // Consequently, if we don't have revocation checking enabled, we can't claim
365   // any cert is EV.
366   flags = X509Certificate::VERIFY_EV_CERT;
367   EXPECT_EQ(OK, thawte_cert->Verify("www.thawte.com", flags, &verify_result));
368   EXPECT_EQ(0, verify_result.cert_status & CERT_STATUS_IS_EV);
369 #endif
370 }
371 
TEST(X509CertificateTest,PaypalNullCertParsing)372 TEST(X509CertificateTest, PaypalNullCertParsing) {
373   scoped_refptr<X509Certificate> paypal_null_cert(
374       X509Certificate::CreateFromBytes(
375           reinterpret_cast<const char*>(paypal_null_der),
376           sizeof(paypal_null_der)));
377 
378   ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert);
379 
380   const SHA1Fingerprint& fingerprint =
381       paypal_null_cert->fingerprint();
382   for (size_t i = 0; i < 20; ++i)
383     EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]);
384 
385   int flags = 0;
386   CertVerifyResult verify_result;
387   int error = paypal_null_cert->Verify("www.paypal.com", flags,
388                                        &verify_result);
389 #if defined(USE_OPENSSL) || defined(OS_MACOSX) || defined(OS_WIN)
390   // TOOD(bulach): investigate why macosx and win aren't returning
391   // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
392   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
393 #else
394   EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
395 #endif
396   // Either the system crypto library should correctly report a certificate
397   // name mismatch, or our certificate blacklist should cause us to report an
398   // invalid certificate.
399 #if !defined(OS_MACOSX) && !defined(USE_OPENSSL)
400   EXPECT_NE(0, verify_result.cert_status &
401             (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID));
402 #endif
403 }
404 
405 // A certificate whose AIA extension contains an LDAP URL without a host name.
406 // This certificate will expire on 2011-09-08.
TEST(X509CertificateTest,UnoSoftCertParsing)407 TEST(X509CertificateTest, UnoSoftCertParsing) {
408   FilePath certs_dir = GetTestCertsDirectory();
409   scoped_refptr<X509Certificate> unosoft_hu_cert(
410       ImportCertFromFile(certs_dir, "unosoft_hu_cert.der"));
411 
412   ASSERT_NE(static_cast<X509Certificate*>(NULL), unosoft_hu_cert);
413 
414   const SHA1Fingerprint& fingerprint =
415       unosoft_hu_cert->fingerprint();
416   for (size_t i = 0; i < 20; ++i)
417     EXPECT_EQ(unosoft_hu_fingerprint[i], fingerprint.data[i]);
418 
419   int flags = 0;
420   CertVerifyResult verify_result;
421   int error = unosoft_hu_cert->Verify("www.unosoft.hu", flags,
422                                       &verify_result);
423   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
424   EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
425 }
426 
TEST(X509CertificateTest,SerialNumbers)427 TEST(X509CertificateTest, SerialNumbers) {
428   scoped_refptr<X509Certificate> google_cert(
429       X509Certificate::CreateFromBytes(
430           reinterpret_cast<const char*>(google_der), sizeof(google_der)));
431 
432   static const uint8 google_serial[16] = {
433     0x01,0x2a,0x39,0x76,0x0d,0x3f,0x4f,0xc9,
434     0x0b,0xe7,0xbd,0x2b,0xcf,0x95,0x2e,0x7a,
435   };
436 
437   ASSERT_EQ(sizeof(google_serial), google_cert->serial_number().size());
438   EXPECT_TRUE(memcmp(google_cert->serial_number().data(), google_serial,
439                      sizeof(google_serial)) == 0);
440 
441   // We also want to check a serial number where the first byte is >= 0x80 in
442   // case the underlying library tries to pad it.
443   scoped_refptr<X509Certificate> paypal_null_cert(
444       X509Certificate::CreateFromBytes(
445           reinterpret_cast<const char*>(paypal_null_der),
446           sizeof(paypal_null_der)));
447 
448   static const uint8 paypal_null_serial[2] = {0xf0, 0x9b};
449   ASSERT_EQ(sizeof(paypal_null_serial),
450             paypal_null_cert->serial_number().size());
451   EXPECT_TRUE(memcmp(paypal_null_cert->serial_number().data(),
452                      paypal_null_serial, sizeof(paypal_null_serial)) == 0);
453 }
454 
455 // A regression test for http://crbug.com/31497.
456 // This certificate will expire on 2012-04-08.
TEST(X509CertificateTest,IntermediateCARequireExplicitPolicy)457 TEST(X509CertificateTest, IntermediateCARequireExplicitPolicy) {
458   FilePath certs_dir = GetTestCertsDirectory();
459 
460   scoped_refptr<X509Certificate> server_cert =
461       ImportCertFromFile(certs_dir, "www_us_army_mil_cert.der");
462   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
463 
464   // The intermediate CA certificate's policyConstraints extension has a
465   // requireExplicitPolicy field with SkipCerts=0.
466   scoped_refptr<X509Certificate> intermediate_cert =
467       ImportCertFromFile(certs_dir, "dod_ca_17_cert.der");
468   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
469 
470   FilePath root_cert_path = certs_dir.AppendASCII("dod_root_ca_2_cert.der");
471   TestRootCerts* root_certs = TestRootCerts::GetInstance();
472   ASSERT_TRUE(root_certs->AddFromFile(root_cert_path));
473 
474   X509Certificate::OSCertHandles intermediates;
475   intermediates.push_back(intermediate_cert->os_cert_handle());
476   scoped_refptr<X509Certificate> cert_chain =
477       X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
478                                         X509Certificate::SOURCE_FROM_NETWORK,
479                                         intermediates);
480 
481   int flags = 0;
482   CertVerifyResult verify_result;
483   int error = cert_chain->Verify("www.us.army.mil", flags, &verify_result);
484   EXPECT_EQ(OK, error);
485   EXPECT_EQ(0, verify_result.cert_status);
486   root_certs->Clear();
487 }
488 
TEST(X509CertificateTest,TestKnownRoot)489 TEST(X509CertificateTest, TestKnownRoot) {
490   FilePath certs_dir = GetTestCertsDirectory();
491   scoped_refptr<X509Certificate> cert =
492       ImportCertFromFile(certs_dir, "nist.der");
493   ASSERT_NE(static_cast<X509Certificate*>(NULL), cert);
494 
495   // This intermediate is only needed for old Linux machines. Modern NSS
496   // includes it as a root already.
497   scoped_refptr<X509Certificate> intermediate_cert =
498       ImportCertFromFile(certs_dir, "nist_intermediate.der");
499   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
500 
501   X509Certificate::OSCertHandles intermediates;
502   intermediates.push_back(intermediate_cert->os_cert_handle());
503   scoped_refptr<X509Certificate> cert_chain =
504       X509Certificate::CreateFromHandle(cert->os_cert_handle(),
505                                         X509Certificate::SOURCE_FROM_NETWORK,
506                                         intermediates);
507 
508   int flags = 0;
509   CertVerifyResult verify_result;
510   // This is going to blow up in Feb 2012. Sorry! Disable and file a bug
511   // against agl. Also see PublicKeyHashes in this file.
512   int error = cert_chain->Verify("www.nist.gov", flags, &verify_result);
513   EXPECT_EQ(OK, error);
514   EXPECT_EQ(0, verify_result.cert_status);
515   EXPECT_TRUE(verify_result.is_issued_by_known_root);
516 }
517 
518 // This is the SHA1 hash of the SubjectPublicKeyInfo of nist.der.
519 static const char nistSPKIHash[] =
520     "\x15\x60\xde\x65\x4e\x03\x9f\xd0\x08\x82"
521     "\xa9\x6a\xc4\x65\x8e\x6f\x92\x06\x84\x35";
522 
TEST(X509CertificateTest,ExtractSPKIFromDERCert)523 TEST(X509CertificateTest, ExtractSPKIFromDERCert) {
524   FilePath certs_dir = GetTestCertsDirectory();
525   scoped_refptr<X509Certificate> cert =
526       ImportCertFromFile(certs_dir, "nist.der");
527   ASSERT_NE(static_cast<X509Certificate*>(NULL), cert);
528 
529   std::string derBytes;
530   EXPECT_TRUE(cert->GetDEREncoded(&derBytes));
531 
532   base::StringPiece spkiBytes;
533   EXPECT_TRUE(asn1::ExtractSPKIFromDERCert(derBytes, &spkiBytes));
534 
535   uint8 hash[base::SHA1_LENGTH];
536   base::SHA1HashBytes(reinterpret_cast<const uint8*>(spkiBytes.data()),
537                       spkiBytes.size(), hash);
538 
539   EXPECT_TRUE(0 == memcmp(hash, nistSPKIHash, sizeof(hash)));
540 }
541 
TEST(X509CertificateTest,PublicKeyHashes)542 TEST(X509CertificateTest, PublicKeyHashes) {
543   FilePath certs_dir = GetTestCertsDirectory();
544   // This is going to blow up in Feb 2012. Sorry! Disable and file a bug
545   // against agl. Also see TestKnownRoot in this file.
546   scoped_refptr<X509Certificate> cert =
547       ImportCertFromFile(certs_dir, "nist.der");
548   ASSERT_NE(static_cast<X509Certificate*>(NULL), cert);
549 
550   // This intermediate is only needed for old Linux machines. Modern NSS
551   // includes it as a root already.
552   scoped_refptr<X509Certificate> intermediate_cert =
553       ImportCertFromFile(certs_dir, "nist_intermediate.der");
554   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
555 
556   TestRootCerts::GetInstance()->Add(intermediate_cert.get());
557 
558   X509Certificate::OSCertHandles intermediates;
559   intermediates.push_back(intermediate_cert->os_cert_handle());
560   scoped_refptr<X509Certificate> cert_chain =
561       X509Certificate::CreateFromHandle(cert->os_cert_handle(),
562                                         X509Certificate::SOURCE_FROM_NETWORK,
563                                         intermediates);
564 
565   int flags = 0;
566   CertVerifyResult verify_result;
567 
568   int error = cert_chain->Verify("www.nist.gov", flags, &verify_result);
569   EXPECT_EQ(OK, error);
570   EXPECT_EQ(0, verify_result.cert_status);
571   ASSERT_LE(2u, verify_result.public_key_hashes.size());
572   EXPECT_EQ(HexEncode(nistSPKIHash, base::SHA1_LENGTH),
573             HexEncode(verify_result.public_key_hashes[0].data, SHA1_LENGTH));
574   EXPECT_EQ("83244223D6CBF0A26FC7DE27CEBCA4BDA32612AD",
575             HexEncode(verify_result.public_key_hashes[1].data, SHA1_LENGTH));
576 
577   TestRootCerts::GetInstance()->Clear();
578 }
579 
580 // A regression test for http://crbug.com/70293.
581 // The Key Usage extension in this RSA SSL server certificate does not have
582 // the keyEncipherment bit.
TEST(X509CertificateTest,InvalidKeyUsage)583 TEST(X509CertificateTest, InvalidKeyUsage) {
584   FilePath certs_dir = GetTestCertsDirectory();
585 
586   scoped_refptr<X509Certificate> server_cert =
587       ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der");
588   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
589 
590   int flags = 0;
591   CertVerifyResult verify_result;
592   int error = server_cert->Verify("jira.aquameta.com", flags, &verify_result);
593 #if defined(USE_OPENSSL)
594   // This certificate has two errors: "invalid key usage" and "untrusted CA".
595   // However, OpenSSL returns only one (the latter), and we can't detect
596   // the other errors.
597   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
598 #else
599   EXPECT_EQ(ERR_CERT_INVALID, error);
600   EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_INVALID);
601 #endif
602   // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
603   // from NSS.
604 #if !defined(USE_NSS)
605   // The certificate is issued by an unknown CA.
606   EXPECT_NE(0, verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
607 #endif
608 }
609 
610 // Tests X509Certificate::Cache via X509Certificate::CreateFromHandle.  We
611 // call X509Certificate::CreateFromHandle several times and observe whether
612 // it returns a cached or new X509Certificate object.
613 //
614 // All the OS certificate handles in this test are actually from the same
615 // source (the bytes of a lone certificate), but we pretend that some of them
616 // come from the network.
TEST(X509CertificateTest,Cache)617 TEST(X509CertificateTest, Cache) {
618   X509Certificate::OSCertHandle google_cert_handle;
619 
620   // Add a certificate from the source SOURCE_LONE_CERT_IMPORT to our
621   // certificate cache.
622   google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
623       reinterpret_cast<const char*>(google_der), sizeof(google_der));
624   scoped_refptr<X509Certificate> cert1(X509Certificate::CreateFromHandle(
625       google_cert_handle, X509Certificate::SOURCE_LONE_CERT_IMPORT,
626       X509Certificate::OSCertHandles()));
627   X509Certificate::FreeOSCertHandle(google_cert_handle);
628 
629   // Add a certificate from the same source (SOURCE_LONE_CERT_IMPORT).  This
630   // should return the cached certificate (cert1).
631   google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
632       reinterpret_cast<const char*>(google_der), sizeof(google_der));
633   scoped_refptr<X509Certificate> cert2(X509Certificate::CreateFromHandle(
634       google_cert_handle, X509Certificate::SOURCE_LONE_CERT_IMPORT,
635       X509Certificate::OSCertHandles()));
636   X509Certificate::FreeOSCertHandle(google_cert_handle);
637 
638   EXPECT_EQ(cert1, cert2);
639 
640   // Add a certificate from the network.  This should kick out the original
641   // cached certificate (cert1) and return a new certificate.
642   google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
643       reinterpret_cast<const char*>(google_der), sizeof(google_der));
644   scoped_refptr<X509Certificate> cert3(X509Certificate::CreateFromHandle(
645       google_cert_handle, X509Certificate::SOURCE_FROM_NETWORK,
646       X509Certificate::OSCertHandles()));
647   X509Certificate::FreeOSCertHandle(google_cert_handle);
648 
649   EXPECT_NE(cert1, cert3);
650 
651   // Add one certificate from each source.  Both should return the new cached
652   // certificate (cert3).
653   google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
654       reinterpret_cast<const char*>(google_der), sizeof(google_der));
655   scoped_refptr<X509Certificate> cert4(X509Certificate::CreateFromHandle(
656       google_cert_handle, X509Certificate::SOURCE_FROM_NETWORK,
657       X509Certificate::OSCertHandles()));
658   X509Certificate::FreeOSCertHandle(google_cert_handle);
659 
660   EXPECT_EQ(cert3, cert4);
661 
662   google_cert_handle = X509Certificate::CreateOSCertHandleFromBytes(
663       reinterpret_cast<const char*>(google_der), sizeof(google_der));
664   scoped_refptr<X509Certificate> cert5(X509Certificate::CreateFromHandle(
665       google_cert_handle, X509Certificate::SOURCE_FROM_NETWORK,
666       X509Certificate::OSCertHandles()));
667   X509Certificate::FreeOSCertHandle(google_cert_handle);
668 
669   EXPECT_EQ(cert3, cert5);
670 }
671 
TEST(X509CertificateTest,Pickle)672 TEST(X509CertificateTest, Pickle) {
673   X509Certificate::OSCertHandle google_cert_handle =
674       X509Certificate::CreateOSCertHandleFromBytes(
675           reinterpret_cast<const char*>(google_der), sizeof(google_der));
676   X509Certificate::OSCertHandle thawte_cert_handle =
677       X509Certificate::CreateOSCertHandleFromBytes(
678           reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der));
679 
680   X509Certificate::OSCertHandles intermediates;
681   intermediates.push_back(thawte_cert_handle);
682   // Faking SOURCE_LONE_CERT_IMPORT so that when the pickled certificate is
683   // read, it successfully evicts |cert| from the X509Certificate::Cache.
684   // This will be fixed when http://crbug.com/49377 is fixed.
685   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle(
686       google_cert_handle,
687       X509Certificate::SOURCE_LONE_CERT_IMPORT,
688       intermediates);
689   ASSERT_NE(static_cast<X509Certificate*>(NULL), cert.get());
690 
691   X509Certificate::FreeOSCertHandle(google_cert_handle);
692   X509Certificate::FreeOSCertHandle(thawte_cert_handle);
693 
694   Pickle pickle;
695   cert->Persist(&pickle);
696 
697   void* iter = NULL;
698   scoped_refptr<X509Certificate> cert_from_pickle =
699       X509Certificate::CreateFromPickle(
700           pickle, &iter, X509Certificate::PICKLETYPE_CERTIFICATE_CHAIN);
701   ASSERT_NE(static_cast<X509Certificate*>(NULL), cert_from_pickle);
702   EXPECT_NE(cert.get(), cert_from_pickle.get());
703   EXPECT_TRUE(X509Certificate::IsSameOSCert(
704       cert->os_cert_handle(), cert_from_pickle->os_cert_handle()));
705   EXPECT_TRUE(cert->HasIntermediateCertificates(
706       cert_from_pickle->GetIntermediateCertificates()));
707 }
708 
TEST(X509CertificateTest,Policy)709 TEST(X509CertificateTest, Policy) {
710   scoped_refptr<X509Certificate> google_cert(X509Certificate::CreateFromBytes(
711       reinterpret_cast<const char*>(google_der), sizeof(google_der)));
712 
713   scoped_refptr<X509Certificate> webkit_cert(X509Certificate::CreateFromBytes(
714       reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
715 
716   CertPolicy policy;
717 
718   EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::UNKNOWN);
719   EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN);
720   EXPECT_FALSE(policy.HasAllowedCert());
721   EXPECT_FALSE(policy.HasDeniedCert());
722 
723   policy.Allow(google_cert.get());
724 
725   EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::ALLOWED);
726   EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN);
727   EXPECT_TRUE(policy.HasAllowedCert());
728   EXPECT_FALSE(policy.HasDeniedCert());
729 
730   policy.Deny(google_cert.get());
731 
732   EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED);
733   EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::UNKNOWN);
734   EXPECT_FALSE(policy.HasAllowedCert());
735   EXPECT_TRUE(policy.HasDeniedCert());
736 
737   policy.Allow(webkit_cert.get());
738 
739   EXPECT_EQ(policy.Check(google_cert.get()), CertPolicy::DENIED);
740   EXPECT_EQ(policy.Check(webkit_cert.get()), CertPolicy::ALLOWED);
741   EXPECT_TRUE(policy.HasAllowedCert());
742   EXPECT_TRUE(policy.HasDeniedCert());
743 }
744 
745 #if defined(OS_MACOSX) || defined(OS_WIN)
TEST(X509CertificateTest,IntermediateCertificates)746 TEST(X509CertificateTest, IntermediateCertificates) {
747   scoped_refptr<X509Certificate> webkit_cert(
748       X509Certificate::CreateFromBytes(
749           reinterpret_cast<const char*>(webkit_der), sizeof(webkit_der)));
750 
751   scoped_refptr<X509Certificate> thawte_cert(
752       X509Certificate::CreateFromBytes(
753           reinterpret_cast<const char*>(thawte_der), sizeof(thawte_der)));
754 
755   scoped_refptr<X509Certificate> paypal_cert(
756       X509Certificate::CreateFromBytes(
757           reinterpret_cast<const char*>(paypal_null_der),
758           sizeof(paypal_null_der)));
759 
760   X509Certificate::OSCertHandle google_handle;
761   // Create object with no intermediates:
762   google_handle = X509Certificate::CreateOSCertHandleFromBytes(
763       reinterpret_cast<const char*>(google_der), sizeof(google_der));
764   X509Certificate::OSCertHandles intermediates1;
765   scoped_refptr<X509Certificate> cert1;
766   cert1 = X509Certificate::CreateFromHandle(
767       google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates1);
768   EXPECT_TRUE(cert1->HasIntermediateCertificates(intermediates1));
769   EXPECT_FALSE(cert1->HasIntermediateCertificate(
770       webkit_cert->os_cert_handle()));
771 
772   // Create object with 2 intermediates:
773   X509Certificate::OSCertHandles intermediates2;
774   intermediates2.push_back(webkit_cert->os_cert_handle());
775   intermediates2.push_back(thawte_cert->os_cert_handle());
776   scoped_refptr<X509Certificate> cert2;
777   cert2 = X509Certificate::CreateFromHandle(
778       google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates2);
779 
780   // The cache should have stored cert2 'cause it has more intermediates:
781   EXPECT_NE(cert1, cert2);
782 
783   // Verify it has all the intermediates:
784   EXPECT_TRUE(cert2->HasIntermediateCertificate(
785       webkit_cert->os_cert_handle()));
786   EXPECT_TRUE(cert2->HasIntermediateCertificate(
787       thawte_cert->os_cert_handle()));
788   EXPECT_FALSE(cert2->HasIntermediateCertificate(
789       paypal_cert->os_cert_handle()));
790 
791   // Create object with 1 intermediate:
792   X509Certificate::OSCertHandles intermediates3;
793   intermediates2.push_back(thawte_cert->os_cert_handle());
794   scoped_refptr<X509Certificate> cert3;
795   cert3 = X509Certificate::CreateFromHandle(
796       google_handle, X509Certificate::SOURCE_FROM_NETWORK, intermediates3);
797 
798   // The cache should have returned cert2 'cause it has more intermediates:
799   EXPECT_EQ(cert3, cert2);
800 
801   // Cleanup
802   X509Certificate::FreeOSCertHandle(google_handle);
803 }
804 #endif
805 
806 #if defined(OS_MACOSX)
TEST(X509CertificateTest,IsIssuedBy)807 TEST(X509CertificateTest, IsIssuedBy) {
808   FilePath certs_dir = GetTestCertsDirectory();
809 
810   // Test a client certificate from MIT.
811   scoped_refptr<X509Certificate> mit_davidben_cert(
812       ImportCertFromFile(certs_dir, "mit.davidben.der"));
813   ASSERT_NE(static_cast<X509Certificate*>(NULL), mit_davidben_cert);
814 
815   CertPrincipal mit_issuer;
816   mit_issuer.country_name = "US";
817   mit_issuer.state_or_province_name = "Massachusetts";
818   mit_issuer.organization_names.push_back(
819       "Massachusetts Institute of Technology");
820   mit_issuer.organization_unit_names.push_back("Client CA v1");
821 
822   // IsIssuedBy should return true even if it cannot build a chain
823   // with that principal.
824   std::vector<CertPrincipal> mit_issuers(1, mit_issuer);
825   EXPECT_TRUE(mit_davidben_cert->IsIssuedBy(mit_issuers));
826 
827   // Test a client certificate from FOAF.ME.
828   scoped_refptr<X509Certificate> foaf_me_chromium_test_cert(
829       ImportCertFromFile(certs_dir, "foaf.me.chromium-test-cert.der"));
830   ASSERT_NE(static_cast<X509Certificate*>(NULL), foaf_me_chromium_test_cert);
831 
832   CertPrincipal foaf_issuer;
833   foaf_issuer.common_name = "FOAF.ME";
834   foaf_issuer.locality_name = "Wimbledon";
835   foaf_issuer.state_or_province_name = "LONDON";
836   foaf_issuer.country_name = "GB";
837   foaf_issuer.organization_names.push_back("FOAF.ME");
838 
839   std::vector<CertPrincipal> foaf_issuers(1, foaf_issuer);
840   EXPECT_TRUE(foaf_me_chromium_test_cert->IsIssuedBy(foaf_issuers));
841 
842   // And test some combinations and mismatches.
843   std::vector<CertPrincipal> both_issuers;
844   both_issuers.push_back(mit_issuer);
845   both_issuers.push_back(foaf_issuer);
846   EXPECT_TRUE(foaf_me_chromium_test_cert->IsIssuedBy(both_issuers));
847   EXPECT_TRUE(mit_davidben_cert->IsIssuedBy(both_issuers));
848   EXPECT_FALSE(foaf_me_chromium_test_cert->IsIssuedBy(mit_issuers));
849   EXPECT_FALSE(mit_davidben_cert->IsIssuedBy(foaf_issuers));
850 }
851 #endif  // defined(OS_MACOSX)
852 
853 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_MACOSX)
854 // This test creates a self-signed cert from a private key and then verify the
855 // content of the certificate.
TEST(X509CertificateTest,CreateSelfSigned)856 TEST(X509CertificateTest, CreateSelfSigned) {
857   scoped_ptr<crypto::RSAPrivateKey> private_key(
858       crypto::RSAPrivateKey::Create(1024));
859   scoped_refptr<X509Certificate> cert =
860       X509Certificate::CreateSelfSigned(
861           private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1));
862 
863   EXPECT_EQ("subject", cert->subject().GetDisplayName());
864   EXPECT_FALSE(cert->HasExpired());
865 
866   const uint8 private_key_info[] = {
867     0x30, 0x82, 0x02, 0x78, 0x02, 0x01, 0x00, 0x30,
868     0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7,
869     0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x04, 0x82,
870     0x02, 0x62, 0x30, 0x82, 0x02, 0x5e, 0x02, 0x01,
871     0x00, 0x02, 0x81, 0x81, 0x00, 0xb8, 0x7f, 0x2b,
872     0x20, 0xdc, 0x7c, 0x9b, 0x0c, 0xdc, 0x51, 0x61,
873     0x99, 0x0d, 0x36, 0x0f, 0xd4, 0x66, 0x88, 0x08,
874     0x55, 0x84, 0xd5, 0x3a, 0xbf, 0x2b, 0xa4, 0x64,
875     0x85, 0x7b, 0x0c, 0x04, 0x13, 0x3f, 0x8d, 0xf4,
876     0xbc, 0x38, 0x0d, 0x49, 0xfe, 0x6b, 0xc4, 0x5a,
877     0xb0, 0x40, 0x53, 0x3a, 0xd7, 0x66, 0x09, 0x0f,
878     0x9e, 0x36, 0x74, 0x30, 0xda, 0x8a, 0x31, 0x4f,
879     0x1f, 0x14, 0x50, 0xd7, 0xc7, 0x20, 0x94, 0x17,
880     0xde, 0x4e, 0xb9, 0x57, 0x5e, 0x7e, 0x0a, 0xe5,
881     0xb2, 0x65, 0x7a, 0x89, 0x4e, 0xb6, 0x47, 0xff,
882     0x1c, 0xbd, 0xb7, 0x38, 0x13, 0xaf, 0x47, 0x85,
883     0x84, 0x32, 0x33, 0xf3, 0x17, 0x49, 0xbf, 0xe9,
884     0x96, 0xd0, 0xd6, 0x14, 0x6f, 0x13, 0x8d, 0xc5,
885     0xfc, 0x2c, 0x72, 0xba, 0xac, 0xea, 0x7e, 0x18,
886     0x53, 0x56, 0xa6, 0x83, 0xa2, 0xce, 0x93, 0x93,
887     0xe7, 0x1f, 0x0f, 0xe6, 0x0f, 0x02, 0x03, 0x01,
888     0x00, 0x01, 0x02, 0x81, 0x80, 0x03, 0x61, 0x89,
889     0x37, 0xcb, 0xf2, 0x98, 0xa0, 0xce, 0xb4, 0xcb,
890     0x16, 0x13, 0xf0, 0xe6, 0xaf, 0x5c, 0xc5, 0xa7,
891     0x69, 0x71, 0xca, 0xba, 0x8d, 0xe0, 0x4d, 0xdd,
892     0xed, 0xb8, 0x48, 0x8b, 0x16, 0x93, 0x36, 0x95,
893     0xc2, 0x91, 0x40, 0x65, 0x17, 0xbd, 0x7f, 0xd6,
894     0xad, 0x9e, 0x30, 0x28, 0x46, 0xe4, 0x3e, 0xcc,
895     0x43, 0x78, 0xf9, 0xfe, 0x1f, 0x33, 0x23, 0x1e,
896     0x31, 0x12, 0x9d, 0x3c, 0xa7, 0x08, 0x82, 0x7b,
897     0x7d, 0x25, 0x4e, 0x5e, 0x19, 0xa8, 0x9b, 0xed,
898     0x86, 0xb2, 0xcb, 0x3c, 0xfe, 0x4e, 0xa1, 0xfa,
899     0x62, 0x87, 0x3a, 0x17, 0xf7, 0x60, 0xec, 0x38,
900     0x29, 0xe8, 0x4f, 0x34, 0x9f, 0x76, 0x9d, 0xee,
901     0xa3, 0xf6, 0x85, 0x6b, 0x84, 0x43, 0xc9, 0x1e,
902     0x01, 0xff, 0xfd, 0xd0, 0x29, 0x4c, 0xfa, 0x8e,
903     0x57, 0x0c, 0xc0, 0x71, 0xa5, 0xbb, 0x88, 0x46,
904     0x29, 0x5c, 0xc0, 0x4f, 0x01, 0x02, 0x41, 0x00,
905     0xf5, 0x83, 0xa4, 0x64, 0x4a, 0xf2, 0xdd, 0x8c,
906     0x2c, 0xed, 0xa8, 0xd5, 0x60, 0x5a, 0xe4, 0xc7,
907     0xcc, 0x61, 0xcd, 0x38, 0x42, 0x20, 0xd3, 0x82,
908     0x18, 0xf2, 0x35, 0x00, 0x72, 0x2d, 0xf7, 0x89,
909     0x80, 0x67, 0xb5, 0x93, 0x05, 0x5f, 0xdd, 0x42,
910     0xba, 0x16, 0x1a, 0xea, 0x15, 0xc6, 0xf0, 0xb8,
911     0x8c, 0xbc, 0xbf, 0x54, 0x9e, 0xf1, 0xc1, 0xb2,
912     0xb3, 0x8b, 0xb6, 0x26, 0x02, 0x30, 0xc4, 0x81,
913     0x02, 0x41, 0x00, 0xc0, 0x60, 0x62, 0x80, 0xe1,
914     0x22, 0x78, 0xf6, 0x9d, 0x83, 0x18, 0xeb, 0x72,
915     0x45, 0xd7, 0xc8, 0x01, 0x7f, 0xa9, 0xca, 0x8f,
916     0x7d, 0xd6, 0xb8, 0x31, 0x2b, 0x84, 0x7f, 0x62,
917     0xd9, 0xa9, 0x22, 0x17, 0x7d, 0x06, 0x35, 0x6c,
918     0xf3, 0xc1, 0x94, 0x17, 0x85, 0x5a, 0xaf, 0x9c,
919     0x5c, 0x09, 0x3c, 0xcf, 0x2f, 0x44, 0x9d, 0xb6,
920     0x52, 0x68, 0x5f, 0xf9, 0x59, 0xc8, 0x84, 0x2b,
921     0x39, 0x22, 0x8f, 0x02, 0x41, 0x00, 0xb2, 0x04,
922     0xe2, 0x0e, 0x56, 0xca, 0x03, 0x1a, 0xc0, 0xf9,
923     0x12, 0x92, 0xa5, 0x6b, 0x42, 0xb8, 0x1c, 0xda,
924     0x4d, 0x93, 0x9d, 0x5f, 0x6f, 0xfd, 0xc5, 0x58,
925     0xda, 0x55, 0x98, 0x74, 0xfc, 0x28, 0x17, 0x93,
926     0x1b, 0x75, 0x9f, 0x50, 0x03, 0x7f, 0x7e, 0xae,
927     0xc8, 0x95, 0x33, 0x75, 0x2c, 0xd6, 0xa4, 0x35,
928     0xb8, 0x06, 0x03, 0xba, 0x08, 0x59, 0x2b, 0x17,
929     0x02, 0xdc, 0x4c, 0x7a, 0x50, 0x01, 0x02, 0x41,
930     0x00, 0x9d, 0xdb, 0x39, 0x59, 0x09, 0xe4, 0x30,
931     0xa0, 0x24, 0xf5, 0xdb, 0x2f, 0xf0, 0x2f, 0xf1,
932     0x75, 0x74, 0x0d, 0x5e, 0xb5, 0x11, 0x73, 0xb0,
933     0x0a, 0xaa, 0x86, 0x4c, 0x0d, 0xff, 0x7e, 0x1d,
934     0xb4, 0x14, 0xd4, 0x09, 0x91, 0x33, 0x5a, 0xfd,
935     0xa0, 0x58, 0x80, 0x9b, 0xbe, 0x78, 0x2e, 0x69,
936     0x82, 0x15, 0x7c, 0x72, 0xf0, 0x7b, 0x18, 0x39,
937     0xff, 0x6e, 0xeb, 0xc6, 0x86, 0xf5, 0xb4, 0xc7,
938     0x6f, 0x02, 0x41, 0x00, 0x8d, 0x1a, 0x37, 0x0f,
939     0x76, 0xc4, 0x82, 0xfa, 0x5c, 0xc3, 0x79, 0x35,
940     0x3e, 0x70, 0x8a, 0xbf, 0x27, 0x49, 0xb0, 0x99,
941     0x63, 0xcb, 0x77, 0x5f, 0xa8, 0x82, 0x65, 0xf6,
942     0x03, 0x52, 0x51, 0xf1, 0xae, 0x2e, 0x05, 0xb3,
943     0xc6, 0xa4, 0x92, 0xd1, 0xce, 0x6c, 0x72, 0xfb,
944     0x21, 0xb3, 0x02, 0x87, 0xe4, 0xfd, 0x61, 0xca,
945     0x00, 0x42, 0x19, 0xf0, 0xda, 0x5a, 0x53, 0xe3,
946     0xb1, 0xc5, 0x15, 0xf3
947   };
948 
949   std::vector<uint8> input;
950   input.resize(sizeof(private_key_info));
951   memcpy(&input.front(), private_key_info, sizeof(private_key_info));
952 
953   private_key.reset(crypto::RSAPrivateKey::CreateFromPrivateKeyInfo(input));
954   ASSERT_TRUE(private_key.get());
955 
956   cert = X509Certificate::CreateSelfSigned(
957       private_key.get(), "CN=subject", 1, base::TimeDelta::FromDays(1));
958 
959   EXPECT_EQ("subject", cert->subject().GetDisplayName());
960   EXPECT_FALSE(cert->HasExpired());
961 }
962 
TEST(X509CertificateTest,GetDEREncoded)963 TEST(X509CertificateTest, GetDEREncoded) {
964   scoped_ptr<crypto::RSAPrivateKey> private_key(
965       crypto::RSAPrivateKey::Create(1024));
966   scoped_refptr<X509Certificate> cert =
967       X509Certificate::CreateSelfSigned(
968           private_key.get(), "CN=subject", 0, base::TimeDelta::FromDays(1));
969 
970   std::string der_cert;
971   EXPECT_TRUE(cert->GetDEREncoded(&der_cert));
972   EXPECT_FALSE(der_cert.empty());
973 }
974 #endif
975 
976 class X509CertificateParseTest
977     : public testing::TestWithParam<CertificateFormatTestData> {
978  public:
~X509CertificateParseTest()979   virtual ~X509CertificateParseTest() {}
SetUp()980   virtual void SetUp() {
981     test_data_ = GetParam();
982   }
TearDown()983   virtual void TearDown() {}
984 
985  protected:
986   CertificateFormatTestData test_data_;
987 };
988 
TEST_P(X509CertificateParseTest,CanParseFormat)989 TEST_P(X509CertificateParseTest, CanParseFormat) {
990   FilePath certs_dir = GetTestCertsDirectory();
991   CertificateList certs = CreateCertificateListFromFile(
992       certs_dir, test_data_.file_name, test_data_.format);
993   ASSERT_FALSE(certs.empty());
994   ASSERT_LE(certs.size(), arraysize(test_data_.chain_fingerprints));
995   CheckGoogleCert(certs.front(), google_parse_fingerprint,
996                   kGoogleParseValidFrom, kGoogleParseValidTo);
997 
998   size_t i;
999   for (i = 0; i < arraysize(test_data_.chain_fingerprints); ++i) {
1000     if (test_data_.chain_fingerprints[i] == NULL) {
1001       // No more test certificates expected - make sure no more were
1002       // returned before marking this test a success.
1003       EXPECT_EQ(i, certs.size());
1004       break;
1005     }
1006 
1007     // A cert is expected - make sure that one was parsed.
1008     ASSERT_LT(i, certs.size());
1009 
1010     // Compare the parsed certificate with the expected certificate, by
1011     // comparing fingerprints.
1012     const X509Certificate* cert = certs[i];
1013     const SHA1Fingerprint& actual_fingerprint = cert->fingerprint();
1014     unsigned char* expected_fingerprint = test_data_.chain_fingerprints[i];
1015 
1016     for (size_t j = 0; j < 20; ++j)
1017       EXPECT_EQ(expected_fingerprint[j], actual_fingerprint.data[j]);
1018   }
1019 }
1020 
1021 INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
1022                         testing::ValuesIn(FormatTestData));
1023 
1024 struct CertificateNameVerifyTestData {
1025   // true iff we expect hostname to match an entry in cert_names.
1026   bool expected;
1027   // The hostname to match.
1028   const char* hostname;
1029   // '/' separated list of certificate names to match against. Any occurrence
1030   // of '#' will be replaced with a null character before processing.
1031   const char* cert_names;
1032 };
1033 
1034 // Required by valgrind on mac, otherwise it complains when using its default
1035 // printer:
1036 // UninitCondition
1037 // Conditional jump or move depends on uninitialised value(s)
1038 // ...
1039 // snprintf
1040 // testing::(anonymous namespace)::PrintByteSegmentInObjectTo
1041 // testing::internal2::TypeWithoutFormatter
1042 // ...
PrintTo(const CertificateNameVerifyTestData & data,std::ostream * os)1043 void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
1044   *os << " expected: " << data.expected << ", hostname: "
1045       << data.hostname << ", cert_names: " << data.cert_names;
1046 }
1047 
1048 const CertificateNameVerifyTestData kNameVerifyTestData[] = {
1049     { true, "foo.com", "foo.com" },
1050     { true, "foo.com", "foo.com." },
1051     { true, "f", "f" },
1052     { true, "f", "f." },
1053     { true, "bar.foo.com", "*.foo.com" },
1054     { true, "www-3.bar.foo.com", "*.bar.foo.com." },
1055     { true, "www.test.fr", "*.test.com/*.test.co.uk/*.test.de/*.test.fr" },
1056     { true, "wwW.tESt.fr", "//*.*/*.test.de/*.test.FR/www" },
1057     { false, "foo.com", "*.com" },
1058     { false, "f.uk", ".uk" },
1059     { true,  "h.co.uk", "*.co.uk" },
1060     { false, "192.168.1.11", "*.168.1.11" },
1061     { false, "foo.us", "*.us" },
1062     { false, "www.bar.foo.com",
1063       "*.foo.com/*.*.foo.com/*.*.bar.foo.com/*w*.bar.foo.com/*..bar.foo.com" },
1064     { false, "w.bar.foo.com", "?.bar.foo.com" },
1065     { false, "www.foo.com", "(www|ftp).foo.com" },
1066     { false, "www.foo.com", "www.foo.com#*.foo.com/#" },  // # = null char.
1067     { false, "foo", "*" },
1068     { false, "foo.", "*." },
1069     { false, "test.org", "www.test.org/*.test.org/*.org" },
1070     { false, "1.2.3.4.5.6", "*.2.3.4.5.6" },
1071     // IDN tests
1072     { true, "xn--poema-9qae5a.com.br", "xn--poema-9qae5a.com.br" },
1073     { true, "www.xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1074     { false, "xn--poema-9qae5a.com.br", "*.xn--poema-9qae5a.com.br" },
1075     // The following are adapted from the examples in
1076     // http://tools.ietf.org/html/draft-saintandre-tls-server-id-check-09#section-4.4.3
1077     { true, "foo.example.com", "*.example.com" },
1078     { false, "bar.foo.example.com", "*.example.com" },
1079     { false, "example.com", "*.example.com" },
1080     { false, "baz1.example.net", "baz*.example.net" },
1081     { false, "baz2.example.net", "baz*.example.net" },
1082     { false, "bar.*.example.net", "bar.*.example.net" },
1083     { false, "bar.f*o.example.net", "bar.f*o.example.net" },
1084     // IP addresses currently not supported, except for the localhost.
1085     { true, "127.0.0.1", "127.0.0.1" },
1086     { false, "192.168.1.1", "192.168.1.1" },
1087     { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210",
1088       "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210" },
1089     { false, "FEDC:BA98:7654:3210:FEDC:BA98:7654:3210", "*.]" },
1090     { false, "::192.9.5.5", "::192.9.5.5" },
1091     { false, "::192.9.5.5", "*.9.5.5" },
1092     { false, "2010:836B:4179::836B:4179", "*:836B:4179::836B:4179" },
1093     // Invalid host names.
1094     { false, "www%26.foo.com", "www%26.foo.com" },
1095     { false, "www.*.com", "www.*.com" },
1096     { false, "w$w.f.com", "w$w.f.com" },
1097     { false, "www-1.[::FFFF:129.144.52.38]", "*.[::FFFF:129.144.52.38]" },
1098 };
1099 
1100 class X509CertificateNameVerifyTest
1101     : public testing::TestWithParam<CertificateNameVerifyTestData> {
1102 };
1103 
TEST_P(X509CertificateNameVerifyTest,VerifyHostname)1104 TEST_P(X509CertificateNameVerifyTest, VerifyHostname) {
1105   CertificateNameVerifyTestData test_data = GetParam();
1106 
1107   std::string cert_name_line(test_data.cert_names);
1108   std::replace(cert_name_line.begin(), cert_name_line.end(), '#', '\0');
1109   std::vector<std::string> cert_names;
1110   base::SplitString(cert_name_line, '/', &cert_names);
1111 
1112   EXPECT_EQ(test_data.expected,
1113             X509Certificate::VerifyHostname(test_data.hostname, cert_names))
1114       << "Host [" << test_data.hostname
1115       << "], cert name [" << test_data.cert_names << "]";
1116 }
1117 
1118 INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1119                         testing::ValuesIn(kNameVerifyTestData));
1120 
1121 }  // namespace net
1122