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
34using base::HexEncode;
35using base::SHA1_LENGTH;
36using base::Time;
37
38namespace 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.
54unsigned 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.
60unsigned 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!).
66unsigned 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
73unsigned 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.
80unsigned 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
87unsigned 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
93unsigned 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
99const double kGoogleParseValidFrom = 1261094400;
100// Dec 18 23:59:59 2011 GMT
101const double kGoogleParseValidTo = 1324252799;
102
103struct CertificateFormatTestData {
104  const char* file_name;
105  X509Certificate::Format format;
106  unsigned char* chain_fingerprints[3];
107};
108
109const 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
172CertificateList 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
185void 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
238TEST(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
248TEST(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
311TEST(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
372TEST(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.
407TEST(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
427TEST(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.
457TEST(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
489TEST(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.
519static 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
523TEST(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
542TEST(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.
583TEST(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.
617TEST(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
672TEST(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
709TEST(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)
746TEST(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)
807TEST(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.
856TEST(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
963TEST(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
976class X509CertificateParseTest
977    : public testing::TestWithParam<CertificateFormatTestData> {
978 public:
979  virtual ~X509CertificateParseTest() {}
980  virtual void SetUp() {
981    test_data_ = GetParam();
982  }
983  virtual void TearDown() {}
984
985 protected:
986  CertificateFormatTestData test_data_;
987};
988
989TEST_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
1021INSTANTIATE_TEST_CASE_P(, X509CertificateParseTest,
1022                        testing::ValuesIn(FormatTestData));
1023
1024struct 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// ...
1043void PrintTo(const CertificateNameVerifyTestData& data, std::ostream* os) {
1044  *os << " expected: " << data.expected << ", hostname: "
1045      << data.hostname << ", cert_names: " << data.cert_names;
1046}
1047
1048const 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
1100class X509CertificateNameVerifyTest
1101    : public testing::TestWithParam<CertificateNameVerifyTestData> {
1102};
1103
1104TEST_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
1118INSTANTIATE_TEST_CASE_P(, X509CertificateNameVerifyTest,
1119                        testing::ValuesIn(kNameVerifyTestData));
1120
1121}  // namespace net
1122