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