6567d1656fccc9e47c5f7435712dc39b27b26ae4
[platform/framework/web/crosswalk.git] / src / net / cert / cert_verify_proc_unittest.cc
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "net/cert/cert_verify_proc.h"
6
7 #include <vector>
8
9 #include "base/callback_helpers.h"
10 #include "base/files/file_path.h"
11 #include "base/logging.h"
12 #include "base/sha1.h"
13 #include "base/strings/string_number_conversions.h"
14 #include "crypto/sha2.h"
15 #include "net/base/net_errors.h"
16 #include "net/base/test_data_directory.h"
17 #include "net/cert/asn1_util.h"
18 #include "net/cert/cert_status_flags.h"
19 #include "net/cert/cert_verifier.h"
20 #include "net/cert/cert_verify_result.h"
21 #include "net/cert/crl_set.h"
22 #include "net/cert/test_root_certs.h"
23 #include "net/cert/x509_certificate.h"
24 #include "net/test/cert_test_util.h"
25 #include "net/test/test_certificate_data.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27
28 #if defined(OS_WIN)
29 #include "base/win/windows_version.h"
30 #elif defined(OS_MACOSX) && !defined(OS_IOS)
31 #include "base/mac/mac_util.h"
32 #elif defined(OS_ANDROID)
33 #include "base/android/build_info.h"
34 #endif
35
36 using base::HexEncode;
37
38 namespace net {
39
40 namespace {
41
42 // A certificate for www.paypal.com with a NULL byte in the common name.
43 // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363
44 unsigned char paypal_null_fingerprint[] = {
45   0x4c, 0x88, 0x9e, 0x28, 0xd7, 0x7a, 0x44, 0x1e, 0x13, 0xf2, 0x6a, 0xba,
46   0x1f, 0xe8, 0x1b, 0xd6, 0xab, 0x7b, 0xe8, 0xd7
47 };
48
49 // Mock CertVerifyProc that will set |verify_result->is_issued_by_known_root|
50 // for all certificates that are Verified.
51 class WellKnownCaCertVerifyProc : public CertVerifyProc {
52  public:
53   // Initialize a CertVerifyProc that will set
54   // |verify_result->is_issued_by_known_root| to |is_well_known|.
55   explicit WellKnownCaCertVerifyProc(bool is_well_known)
56       : is_well_known_(is_well_known) {}
57
58   // CertVerifyProc implementation:
59   virtual bool SupportsAdditionalTrustAnchors() const OVERRIDE { return false; }
60
61  protected:
62   virtual ~WellKnownCaCertVerifyProc() {}
63
64  private:
65   virtual int VerifyInternal(X509Certificate* cert,
66                              const std::string& hostname,
67                              int flags,
68                              CRLSet* crl_set,
69                              const CertificateList& additional_trust_anchors,
70                              CertVerifyResult* verify_result) OVERRIDE;
71
72   const bool is_well_known_;
73
74   DISALLOW_COPY_AND_ASSIGN(WellKnownCaCertVerifyProc);
75 };
76
77 int WellKnownCaCertVerifyProc::VerifyInternal(
78     X509Certificate* cert,
79     const std::string& hostname,
80     int flags,
81     CRLSet* crl_set,
82     const CertificateList& additional_trust_anchors,
83     CertVerifyResult* verify_result) {
84   verify_result->is_issued_by_known_root = is_well_known_;
85   return OK;
86 }
87
88 bool SupportsReturningVerifiedChain() {
89 #if defined(OS_ANDROID)
90   // Before API level 17, Android does not expose the APIs necessary to get at
91   // the verified certificate chain.
92   if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
93     return false;
94 #endif
95   return true;
96 }
97
98 bool SupportsDetectingKnownRoots() {
99 #if defined(OS_ANDROID)
100   // Before API level 17, Android does not expose the APIs necessary to get at
101   // the verified certificate chain and detect known roots.
102   if (base::android::BuildInfo::GetInstance()->sdk_int() < 17)
103     return false;
104 #endif
105   return true;
106 }
107
108 }  // namespace
109
110 class CertVerifyProcTest : public testing::Test {
111  public:
112   CertVerifyProcTest()
113       : verify_proc_(CertVerifyProc::CreateDefault()) {
114   }
115   virtual ~CertVerifyProcTest() {}
116
117  protected:
118   bool SupportsAdditionalTrustAnchors() {
119     return verify_proc_->SupportsAdditionalTrustAnchors();
120   }
121
122   int Verify(X509Certificate* cert,
123              const std::string& hostname,
124              int flags,
125              CRLSet* crl_set,
126              const CertificateList& additional_trust_anchors,
127              CertVerifyResult* verify_result) {
128     return verify_proc_->Verify(cert, hostname, flags, crl_set,
129                                 additional_trust_anchors, verify_result);
130   }
131
132   const CertificateList empty_cert_list_;
133   scoped_refptr<CertVerifyProc> verify_proc_;
134 };
135
136 TEST_F(CertVerifyProcTest, DISABLED_WithoutRevocationChecking) {
137   // Check that verification without revocation checking works.
138   CertificateList certs = CreateCertificateListFromFile(
139       GetTestCertsDirectory(),
140       "googlenew.chain.pem",
141       X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
142
143   X509Certificate::OSCertHandles intermediates;
144   intermediates.push_back(certs[1]->os_cert_handle());
145
146   scoped_refptr<X509Certificate> google_full_chain =
147       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
148                                         intermediates);
149
150   CertVerifyResult verify_result;
151   EXPECT_EQ(OK,
152             Verify(google_full_chain.get(),
153                    "www.google.com",
154                    0 /* flags */,
155                    NULL,
156                    empty_cert_list_,
157                    &verify_result));
158 }
159
160 #if defined(OS_ANDROID) || defined(USE_OPENSSL_CERTS)
161 // TODO(jnd): http://crbug.com/117478 - EV verification is not yet supported.
162 #define MAYBE_EVVerification DISABLED_EVVerification
163 #else
164 #define MAYBE_EVVerification EVVerification
165 #endif
166 TEST_F(CertVerifyProcTest, MAYBE_EVVerification) {
167   CertificateList certs = CreateCertificateListFromFile(
168       GetTestCertsDirectory(),
169       "comodo.chain.pem",
170       X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
171   ASSERT_EQ(3U, certs.size());
172
173   X509Certificate::OSCertHandles intermediates;
174   intermediates.push_back(certs[1]->os_cert_handle());
175   intermediates.push_back(certs[2]->os_cert_handle());
176
177   scoped_refptr<X509Certificate> comodo_chain =
178       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
179                                         intermediates);
180
181   scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, NULL, ""));
182   CertVerifyResult verify_result;
183   int flags = CertVerifier::VERIFY_EV_CERT;
184   int error = Verify(comodo_chain.get(),
185                      "comodo.com",
186                      flags,
187                      crl_set.get(),
188                      empty_cert_list_,
189                      &verify_result);
190   EXPECT_EQ(OK, error);
191   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
192 }
193
194 TEST_F(CertVerifyProcTest, PaypalNullCertParsing) {
195   scoped_refptr<X509Certificate> paypal_null_cert(
196       X509Certificate::CreateFromBytes(
197           reinterpret_cast<const char*>(paypal_null_der),
198           sizeof(paypal_null_der)));
199
200   ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert);
201
202   const SHA1HashValue& fingerprint =
203       paypal_null_cert->fingerprint();
204   for (size_t i = 0; i < 20; ++i)
205     EXPECT_EQ(paypal_null_fingerprint[i], fingerprint.data[i]);
206
207   int flags = 0;
208   CertVerifyResult verify_result;
209   int error = Verify(paypal_null_cert.get(),
210                      "www.paypal.com",
211                      flags,
212                      NULL,
213                      empty_cert_list_,
214                      &verify_result);
215 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_ANDROID)
216   EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
217 #else
218   // TOOD(bulach): investigate why macosx and win aren't returning
219   // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID.
220   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
221 #endif
222   // Either the system crypto library should correctly report a certificate
223   // name mismatch, or our certificate blacklist should cause us to report an
224   // invalid certificate.
225 #if defined(USE_NSS) || defined(OS_WIN) || defined(OS_IOS)
226   EXPECT_TRUE(verify_result.cert_status &
227               (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID));
228 #endif
229 }
230
231 // A regression test for http://crbug.com/31497.
232 #if defined(OS_ANDROID)
233 // Disabled on Android, as the Android verification libraries require an
234 // explicit policy to be specified, even when anyPolicy is permitted.
235 #define MAYBE_IntermediateCARequireExplicitPolicy \
236     DISABLED_IntermediateCARequireExplicitPolicy
237 #else
238 #define MAYBE_IntermediateCARequireExplicitPolicy \
239     IntermediateCARequireExplicitPolicy
240 #endif
241 TEST_F(CertVerifyProcTest, MAYBE_IntermediateCARequireExplicitPolicy) {
242   base::FilePath certs_dir = GetTestCertsDirectory();
243
244   CertificateList certs = CreateCertificateListFromFile(
245       certs_dir, "explicit-policy-chain.pem",
246       X509Certificate::FORMAT_AUTO);
247   ASSERT_EQ(3U, certs.size());
248
249   X509Certificate::OSCertHandles intermediates;
250   intermediates.push_back(certs[1]->os_cert_handle());
251
252   scoped_refptr<X509Certificate> cert =
253       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
254                                         intermediates);
255   ASSERT_TRUE(cert.get());
256
257   ScopedTestRoot scoped_root(certs[2].get());
258
259   int flags = 0;
260   CertVerifyResult verify_result;
261   int error = Verify(cert.get(),
262                      "policy_test.example",
263                      flags,
264                      NULL,
265                      empty_cert_list_,
266                      &verify_result);
267   EXPECT_EQ(OK, error);
268   EXPECT_EQ(0u, verify_result.cert_status);
269 }
270
271 // Test for bug 58437.
272 // This certificate will expire on 2011-12-21. The test will still
273 // pass if error == ERR_CERT_DATE_INVALID.
274 // This test is DISABLED because it appears that we cannot do
275 // certificate revocation checking when running all of the net unit tests.
276 // This test passes when run individually, but when run with all of the net
277 // unit tests, the call to PKIXVerifyCert returns the NSS error -8180, which is
278 // SEC_ERROR_REVOKED_CERTIFICATE. This indicates a lack of revocation
279 // status, i.e. that the revocation check is failing for some reason.
280 TEST_F(CertVerifyProcTest, DISABLED_GlobalSignR3EVTest) {
281   base::FilePath certs_dir = GetTestCertsDirectory();
282
283   scoped_refptr<X509Certificate> server_cert =
284       ImportCertFromFile(certs_dir, "2029_globalsign_com_cert.pem");
285   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
286
287   scoped_refptr<X509Certificate> intermediate_cert =
288       ImportCertFromFile(certs_dir, "globalsign_ev_sha256_ca_cert.pem");
289   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
290
291   X509Certificate::OSCertHandles intermediates;
292   intermediates.push_back(intermediate_cert->os_cert_handle());
293   scoped_refptr<X509Certificate> cert_chain =
294       X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
295                                         intermediates);
296
297   CertVerifyResult verify_result;
298   int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED |
299               CertVerifier::VERIFY_EV_CERT;
300   int error = Verify(cert_chain.get(),
301                      "2029.globalsign.com",
302                      flags,
303                      NULL,
304                      empty_cert_list_,
305                      &verify_result);
306   if (error == OK)
307     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV);
308   else
309     EXPECT_EQ(ERR_CERT_DATE_INVALID, error);
310 }
311
312 // Test that verifying an ECDSA certificate doesn't crash on XP. (See
313 // crbug.com/144466).
314 TEST_F(CertVerifyProcTest, ECDSA_RSA) {
315   base::FilePath certs_dir = GetTestCertsDirectory();
316
317   scoped_refptr<X509Certificate> cert =
318       ImportCertFromFile(certs_dir,
319                          "prime256v1-ecdsa-ee-by-1024-rsa-intermediate.pem");
320
321   CertVerifyResult verify_result;
322   Verify(cert.get(), "127.0.0.1", 0, NULL, empty_cert_list_, &verify_result);
323
324   // We don't check verify_result because the certificate is signed by an
325   // unknown CA and will be considered invalid on XP because of the ECDSA
326   // public key.
327 }
328
329 // Currently, only RSA and DSA keys are checked for weakness, and our example
330 // weak size is 768. These could change in the future.
331 //
332 // Note that this means there may be false negatives: keys for other
333 // algorithms and which are weak will pass this test.
334 static bool IsWeakKeyType(const std::string& key_type) {
335   size_t pos = key_type.find("-");
336   std::string size = key_type.substr(0, pos);
337   std::string type = key_type.substr(pos + 1);
338
339   if (type == "rsa" || type == "dsa")
340     return size == "768";
341
342   return false;
343 }
344
345 TEST_F(CertVerifyProcTest, RejectWeakKeys) {
346   base::FilePath certs_dir = GetTestCertsDirectory();
347   typedef std::vector<std::string> Strings;
348   Strings key_types;
349
350   // generate-weak-test-chains.sh currently has:
351   //     key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa"
352   // We must use the same key types here. The filenames generated look like:
353   //     2048-rsa-ee-by-768-rsa-intermediate.pem
354   key_types.push_back("768-rsa");
355   key_types.push_back("1024-rsa");
356   key_types.push_back("2048-rsa");
357
358   bool use_ecdsa = true;
359 #if defined(OS_WIN)
360   use_ecdsa = base::win::GetVersion() > base::win::VERSION_XP;
361 #endif
362
363   if (use_ecdsa)
364     key_types.push_back("prime256v1-ecdsa");
365
366   // Add the root that signed the intermediates for this test.
367   scoped_refptr<X509Certificate> root_cert =
368       ImportCertFromFile(certs_dir, "2048-rsa-root.pem");
369   ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
370   ScopedTestRoot scoped_root(root_cert.get());
371
372   // Now test each chain.
373   for (Strings::const_iterator ee_type = key_types.begin();
374        ee_type != key_types.end(); ++ee_type) {
375     for (Strings::const_iterator signer_type = key_types.begin();
376          signer_type != key_types.end(); ++signer_type) {
377       std::string basename = *ee_type + "-ee-by-" + *signer_type +
378           "-intermediate.pem";
379       SCOPED_TRACE(basename);
380       scoped_refptr<X509Certificate> ee_cert =
381           ImportCertFromFile(certs_dir, basename);
382       ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
383
384       basename = *signer_type + "-intermediate.pem";
385       scoped_refptr<X509Certificate> intermediate =
386           ImportCertFromFile(certs_dir, basename);
387       ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate);
388
389       X509Certificate::OSCertHandles intermediates;
390       intermediates.push_back(intermediate->os_cert_handle());
391       scoped_refptr<X509Certificate> cert_chain =
392           X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
393                                             intermediates);
394
395       CertVerifyResult verify_result;
396       int error = Verify(cert_chain.get(),
397                          "127.0.0.1",
398                          0,
399                          NULL,
400                          empty_cert_list_,
401                          &verify_result);
402
403       if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) {
404         EXPECT_NE(OK, error);
405         EXPECT_EQ(CERT_STATUS_WEAK_KEY,
406                   verify_result.cert_status & CERT_STATUS_WEAK_KEY);
407         EXPECT_NE(CERT_STATUS_INVALID,
408                   verify_result.cert_status & CERT_STATUS_INVALID);
409       } else {
410         EXPECT_EQ(OK, error);
411         EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY);
412       }
413     }
414   }
415 }
416
417 // Regression test for http://crbug.com/108514.
418 #if defined(OS_MACOSX) && !defined(OS_IOS)
419 // Disabled on OS X - Security.framework doesn't ignore superflous certificates
420 // provided by servers. See CertVerifyProcTest.CybertrustGTERoot for further
421 // details.
422 #define MAYBE_ExtraneousMD5RootCert DISABLED_ExtraneousMD5RootCert
423 #else
424 #define MAYBE_ExtraneousMD5RootCert ExtraneousMD5RootCert
425 #endif
426 TEST_F(CertVerifyProcTest, MAYBE_ExtraneousMD5RootCert) {
427   if (!SupportsReturningVerifiedChain()) {
428     LOG(INFO) << "Skipping this test in this platform.";
429     return;
430   }
431
432   base::FilePath certs_dir = GetTestCertsDirectory();
433
434   scoped_refptr<X509Certificate> server_cert =
435       ImportCertFromFile(certs_dir, "cross-signed-leaf.pem");
436   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get());
437
438   scoped_refptr<X509Certificate> extra_cert =
439       ImportCertFromFile(certs_dir, "cross-signed-root-md5.pem");
440   ASSERT_NE(static_cast<X509Certificate*>(NULL), extra_cert.get());
441
442   scoped_refptr<X509Certificate> root_cert =
443       ImportCertFromFile(certs_dir, "cross-signed-root-sha1.pem");
444   ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get());
445
446   ScopedTestRoot scoped_root(root_cert.get());
447
448   X509Certificate::OSCertHandles intermediates;
449   intermediates.push_back(extra_cert->os_cert_handle());
450   scoped_refptr<X509Certificate> cert_chain =
451       X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
452                                         intermediates);
453
454   CertVerifyResult verify_result;
455   int flags = 0;
456   int error = Verify(cert_chain.get(),
457                      "127.0.0.1",
458                      flags,
459                      NULL,
460                      empty_cert_list_,
461                      &verify_result);
462   EXPECT_EQ(OK, error);
463
464   // The extra MD5 root should be discarded
465   ASSERT_TRUE(verify_result.verified_cert.get());
466   ASSERT_EQ(1u,
467             verify_result.verified_cert->GetIntermediateCertificates().size());
468   EXPECT_TRUE(X509Certificate::IsSameOSCert(
469         verify_result.verified_cert->GetIntermediateCertificates().front(),
470         root_cert->os_cert_handle()));
471
472   EXPECT_FALSE(verify_result.has_md5);
473 }
474
475 // Test for bug 94673.
476 TEST_F(CertVerifyProcTest, GoogleDigiNotarTest) {
477   base::FilePath certs_dir = GetTestCertsDirectory();
478
479   scoped_refptr<X509Certificate> server_cert =
480       ImportCertFromFile(certs_dir, "google_diginotar.pem");
481   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
482
483   scoped_refptr<X509Certificate> intermediate_cert =
484       ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem");
485   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
486
487   X509Certificate::OSCertHandles intermediates;
488   intermediates.push_back(intermediate_cert->os_cert_handle());
489   scoped_refptr<X509Certificate> cert_chain =
490       X509Certificate::CreateFromHandle(server_cert->os_cert_handle(),
491                                         intermediates);
492
493   CertVerifyResult verify_result;
494   int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED;
495   int error = Verify(cert_chain.get(),
496                      "mail.google.com",
497                      flags,
498                      NULL,
499                      empty_cert_list_,
500                      &verify_result);
501   EXPECT_NE(OK, error);
502
503   // Now turn off revocation checking.  Certificate verification should still
504   // fail.
505   flags = 0;
506   error = Verify(cert_chain.get(),
507                  "mail.google.com",
508                  flags,
509                  NULL,
510                  empty_cert_list_,
511                  &verify_result);
512   EXPECT_NE(OK, error);
513 }
514
515 TEST_F(CertVerifyProcTest, DigiNotarCerts) {
516   static const char* const kDigiNotarFilenames[] = {
517     "diginotar_root_ca.pem",
518     "diginotar_cyber_ca.pem",
519     "diginotar_services_1024_ca.pem",
520     "diginotar_pkioverheid.pem",
521     "diginotar_pkioverheid_g2.pem",
522     NULL,
523   };
524
525   base::FilePath certs_dir = GetTestCertsDirectory();
526
527   for (size_t i = 0; kDigiNotarFilenames[i]; i++) {
528     scoped_refptr<X509Certificate> diginotar_cert =
529         ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]);
530     std::string der_bytes;
531     ASSERT_TRUE(X509Certificate::GetDEREncoded(
532         diginotar_cert->os_cert_handle(), &der_bytes));
533
534     base::StringPiece spki;
535     ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki));
536
537     std::string spki_sha1 = base::SHA1HashString(spki.as_string());
538
539     HashValueVector public_keys;
540     HashValue hash(HASH_VALUE_SHA1);
541     ASSERT_EQ(hash.size(), spki_sha1.size());
542     memcpy(hash.data(), spki_sha1.data(), spki_sha1.size());
543     public_keys.push_back(hash);
544
545     EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) <<
546         "Public key not blocked for " << kDigiNotarFilenames[i];
547   }
548 }
549
550 TEST_F(CertVerifyProcTest, NameConstraintsOk) {
551   CertificateList ca_cert_list =
552       CreateCertificateListFromFile(GetTestCertsDirectory(),
553                                     "root_ca_cert.pem",
554                                     X509Certificate::FORMAT_AUTO);
555   ASSERT_EQ(1U, ca_cert_list.size());
556   ScopedTestRoot test_root(ca_cert_list[0]);
557
558   CertificateList cert_list = CreateCertificateListFromFile(
559       GetTestCertsDirectory(), "name_constraint_ok.crt",
560       X509Certificate::FORMAT_AUTO);
561   ASSERT_EQ(1U, cert_list.size());
562
563   X509Certificate::OSCertHandles intermediates;
564   scoped_refptr<X509Certificate> leaf =
565       X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
566                                         intermediates);
567
568   int flags = 0;
569   CertVerifyResult verify_result;
570   int error = Verify(leaf.get(),
571                      "test.example.com",
572                      flags,
573                      NULL,
574                      empty_cert_list_,
575                      &verify_result);
576   EXPECT_EQ(OK, error);
577   EXPECT_EQ(0U, verify_result.cert_status);
578 }
579
580 TEST_F(CertVerifyProcTest, NameConstraintsFailure) {
581   if (!SupportsReturningVerifiedChain()) {
582     LOG(INFO) << "Skipping this test in this platform.";
583     return;
584   }
585
586   CertificateList ca_cert_list =
587       CreateCertificateListFromFile(GetTestCertsDirectory(),
588                                     "root_ca_cert.pem",
589                                     X509Certificate::FORMAT_AUTO);
590   ASSERT_EQ(1U, ca_cert_list.size());
591   ScopedTestRoot test_root(ca_cert_list[0]);
592
593   CertificateList cert_list = CreateCertificateListFromFile(
594       GetTestCertsDirectory(), "name_constraint_bad.crt",
595       X509Certificate::FORMAT_AUTO);
596   ASSERT_EQ(1U, cert_list.size());
597
598   X509Certificate::OSCertHandles intermediates;
599   scoped_refptr<X509Certificate> leaf =
600       X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
601                                         intermediates);
602
603   int flags = 0;
604   CertVerifyResult verify_result;
605   int error = Verify(leaf.get(),
606                      "test.example.com",
607                      flags,
608                      NULL,
609                      empty_cert_list_,
610                      &verify_result);
611   EXPECT_EQ(ERR_CERT_NAME_CONSTRAINT_VIOLATION, error);
612   EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION,
613             verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION);
614 }
615
616 TEST_F(CertVerifyProcTest, TestKnownRoot) {
617   if (!SupportsDetectingKnownRoots()) {
618     LOG(INFO) << "Skipping this test in this platform.";
619     return;
620   }
621
622   base::FilePath certs_dir = GetTestCertsDirectory();
623   CertificateList certs = CreateCertificateListFromFile(
624       certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
625   ASSERT_EQ(2U, certs.size());
626
627   X509Certificate::OSCertHandles intermediates;
628   intermediates.push_back(certs[1]->os_cert_handle());
629
630   scoped_refptr<X509Certificate> cert_chain =
631       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
632                                         intermediates);
633
634   int flags = 0;
635   CertVerifyResult verify_result;
636   // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
637   // against agl. See also PublicKeyHashes.
638   int error = Verify(cert_chain.get(),
639                      "satveda.com",
640                      flags,
641                      NULL,
642                      empty_cert_list_,
643                      &verify_result);
644   EXPECT_EQ(OK, error);
645   EXPECT_EQ(0U, verify_result.cert_status);
646   EXPECT_TRUE(verify_result.is_issued_by_known_root);
647 }
648
649 // The certse.pem certificate has been revoked. crbug.com/259723.
650 TEST_F(CertVerifyProcTest, PublicKeyHashes) {
651   if (!SupportsReturningVerifiedChain()) {
652     LOG(INFO) << "Skipping this test in this platform.";
653     return;
654   }
655
656   base::FilePath certs_dir = GetTestCertsDirectory();
657   CertificateList certs = CreateCertificateListFromFile(
658       certs_dir, "satveda.pem", X509Certificate::FORMAT_AUTO);
659   ASSERT_EQ(2U, certs.size());
660
661   X509Certificate::OSCertHandles intermediates;
662   intermediates.push_back(certs[1]->os_cert_handle());
663
664   scoped_refptr<X509Certificate> cert_chain =
665       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
666                                         intermediates);
667   int flags = 0;
668   CertVerifyResult verify_result;
669
670   // This will blow up, May 24th, 2019. Sorry! Please disable and file a bug
671   // against agl. See also TestKnownRoot.
672   int error = Verify(cert_chain.get(),
673                      "satveda.com",
674                      flags,
675                      NULL,
676                      empty_cert_list_,
677                      &verify_result);
678   EXPECT_EQ(OK, error);
679   EXPECT_EQ(0U, verify_result.cert_status);
680   ASSERT_LE(2U, verify_result.public_key_hashes.size());
681
682   HashValueVector sha1_hashes;
683   for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
684     if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1)
685       continue;
686     sha1_hashes.push_back(verify_result.public_key_hashes[i]);
687   }
688   ASSERT_LE(2u, sha1_hashes.size());
689
690   for (size_t i = 0; i < 2; ++i) {
691     EXPECT_EQ(HexEncode(kSatvedaSPKIs[i], base::kSHA1Length),
692               HexEncode(sha1_hashes[i].data(), base::kSHA1Length));
693   }
694
695   HashValueVector sha256_hashes;
696   for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) {
697     if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA256)
698       continue;
699     sha256_hashes.push_back(verify_result.public_key_hashes[i]);
700   }
701   ASSERT_LE(2u, sha256_hashes.size());
702
703   for (size_t i = 0; i < 2; ++i) {
704     EXPECT_EQ(HexEncode(kSatvedaSPKIsSHA256[i], crypto::kSHA256Length),
705               HexEncode(sha256_hashes[i].data(), crypto::kSHA256Length));
706   }
707 }
708
709 // A regression test for http://crbug.com/70293.
710 // The Key Usage extension in this RSA SSL server certificate does not have
711 // the keyEncipherment bit.
712 TEST_F(CertVerifyProcTest, InvalidKeyUsage) {
713   base::FilePath certs_dir = GetTestCertsDirectory();
714
715   scoped_refptr<X509Certificate> server_cert =
716       ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der");
717   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert);
718
719   int flags = 0;
720   CertVerifyResult verify_result;
721   int error = Verify(server_cert.get(),
722                      "jira.aquameta.com",
723                      flags,
724                      NULL,
725                      empty_cert_list_,
726                      &verify_result);
727 #if defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID)
728   // This certificate has two errors: "invalid key usage" and "untrusted CA".
729   // However, OpenSSL returns only one (the latter), and we can't detect
730   // the other errors.
731   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
732 #else
733   EXPECT_EQ(ERR_CERT_INVALID, error);
734   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID);
735 #endif
736   // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors
737   // from NSS.
738 #if !defined(USE_NSS) && !defined(OS_IOS) && !defined(OS_ANDROID)
739   // The certificate is issued by an unknown CA.
740   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID);
741 #endif
742 }
743
744 // Basic test for returning the chain in CertVerifyResult. Note that the
745 // returned chain may just be a reflection of the originally supplied chain;
746 // that is, if any errors occur, the default chain returned is an exact copy
747 // of the certificate to be verified. The remaining VerifyReturn* tests are
748 // used to ensure that the actual, verified chain is being returned by
749 // Verify().
750 TEST_F(CertVerifyProcTest, VerifyReturnChainBasic) {
751   if (!SupportsReturningVerifiedChain()) {
752     LOG(INFO) << "Skipping this test in this platform.";
753     return;
754   }
755
756   base::FilePath certs_dir = GetTestCertsDirectory();
757   CertificateList certs = CreateCertificateListFromFile(
758       certs_dir, "x509_verify_results.chain.pem",
759       X509Certificate::FORMAT_AUTO);
760   ASSERT_EQ(3U, certs.size());
761
762   X509Certificate::OSCertHandles intermediates;
763   intermediates.push_back(certs[1]->os_cert_handle());
764   intermediates.push_back(certs[2]->os_cert_handle());
765
766   ScopedTestRoot scoped_root(certs[2].get());
767
768   scoped_refptr<X509Certificate> google_full_chain =
769       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
770                                         intermediates);
771   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
772   ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
773
774   CertVerifyResult verify_result;
775   EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
776   int error = Verify(google_full_chain.get(),
777                      "127.0.0.1",
778                      0,
779                      NULL,
780                      empty_cert_list_,
781                      &verify_result);
782   EXPECT_EQ(OK, error);
783   ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
784
785   EXPECT_NE(google_full_chain, verify_result.verified_cert);
786   EXPECT_TRUE(X509Certificate::IsSameOSCert(
787       google_full_chain->os_cert_handle(),
788       verify_result.verified_cert->os_cert_handle()));
789   const X509Certificate::OSCertHandles& return_intermediates =
790       verify_result.verified_cert->GetIntermediateCertificates();
791   ASSERT_EQ(2U, return_intermediates.size());
792   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
793                                             certs[1]->os_cert_handle()));
794   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
795                                             certs[2]->os_cert_handle()));
796 }
797
798 // Test that certificates issued for 'intranet' names (that is, containing no
799 // known public registry controlled domain information) issued by well-known
800 // CAs are flagged appropriately, while certificates that are issued by
801 // internal CAs are not flagged.
802 TEST_F(CertVerifyProcTest, IntranetHostsRejected) {
803   if (!SupportsDetectingKnownRoots()) {
804     LOG(INFO) << "Skipping this test in this platform.";
805     return;
806   }
807
808   CertificateList cert_list = CreateCertificateListFromFile(
809       GetTestCertsDirectory(), "ok_cert.pem",
810       X509Certificate::FORMAT_AUTO);
811   ASSERT_EQ(1U, cert_list.size());
812   scoped_refptr<X509Certificate> cert(cert_list[0]);
813
814   CertVerifyResult verify_result;
815   int error = 0;
816
817   // Intranet names for public CAs should be flagged:
818   verify_proc_ = new WellKnownCaCertVerifyProc(true);
819   error =
820       Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
821   EXPECT_EQ(OK, error);
822   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
823
824   // However, if the CA is not well known, these should not be flagged:
825   verify_proc_ = new WellKnownCaCertVerifyProc(false);
826   error =
827       Verify(cert.get(), "intranet", 0, NULL, empty_cert_list_, &verify_result);
828   EXPECT_EQ(OK, error);
829   EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME);
830 }
831
832 // Test that the certificate returned in CertVerifyResult is able to reorder
833 // certificates that are not ordered from end-entity to root. While this is
834 // a protocol violation if sent during a TLS handshake, if multiple sources
835 // of intermediate certificates are combined, it's possible that order may
836 // not be maintained.
837 TEST_F(CertVerifyProcTest, VerifyReturnChainProperlyOrdered) {
838   if (!SupportsReturningVerifiedChain()) {
839     LOG(INFO) << "Skipping this test in this platform.";
840     return;
841   }
842
843   base::FilePath certs_dir = GetTestCertsDirectory();
844   CertificateList certs = CreateCertificateListFromFile(
845       certs_dir, "x509_verify_results.chain.pem",
846       X509Certificate::FORMAT_AUTO);
847   ASSERT_EQ(3U, certs.size());
848
849   // Construct the chain out of order.
850   X509Certificate::OSCertHandles intermediates;
851   intermediates.push_back(certs[2]->os_cert_handle());
852   intermediates.push_back(certs[1]->os_cert_handle());
853
854   ScopedTestRoot scoped_root(certs[2].get());
855
856   scoped_refptr<X509Certificate> google_full_chain =
857       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
858                                         intermediates);
859   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
860   ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size());
861
862   CertVerifyResult verify_result;
863   EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
864   int error = Verify(google_full_chain.get(),
865                      "127.0.0.1",
866                      0,
867                      NULL,
868                      empty_cert_list_,
869                      &verify_result);
870   EXPECT_EQ(OK, error);
871   ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
872
873   EXPECT_NE(google_full_chain, verify_result.verified_cert);
874   EXPECT_TRUE(X509Certificate::IsSameOSCert(
875       google_full_chain->os_cert_handle(),
876       verify_result.verified_cert->os_cert_handle()));
877   const X509Certificate::OSCertHandles& return_intermediates =
878       verify_result.verified_cert->GetIntermediateCertificates();
879   ASSERT_EQ(2U, return_intermediates.size());
880   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
881                                             certs[1]->os_cert_handle()));
882   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
883                                             certs[2]->os_cert_handle()));
884 }
885
886 // Test that Verify() filters out certificates which are not related to
887 // or part of the certificate chain being verified.
888 TEST_F(CertVerifyProcTest, VerifyReturnChainFiltersUnrelatedCerts) {
889   if (!SupportsReturningVerifiedChain()) {
890     LOG(INFO) << "Skipping this test in this platform.";
891     return;
892   }
893
894   base::FilePath certs_dir = GetTestCertsDirectory();
895   CertificateList certs = CreateCertificateListFromFile(
896       certs_dir, "x509_verify_results.chain.pem",
897       X509Certificate::FORMAT_AUTO);
898   ASSERT_EQ(3U, certs.size());
899   ScopedTestRoot scoped_root(certs[2].get());
900
901   scoped_refptr<X509Certificate> unrelated_certificate =
902       ImportCertFromFile(certs_dir, "duplicate_cn_1.pem");
903   scoped_refptr<X509Certificate> unrelated_certificate2 =
904       ImportCertFromFile(certs_dir, "aia-cert.pem");
905   ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate);
906   ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2);
907
908   // Interject unrelated certificates into the list of intermediates.
909   X509Certificate::OSCertHandles intermediates;
910   intermediates.push_back(unrelated_certificate->os_cert_handle());
911   intermediates.push_back(certs[1]->os_cert_handle());
912   intermediates.push_back(unrelated_certificate2->os_cert_handle());
913   intermediates.push_back(certs[2]->os_cert_handle());
914
915   scoped_refptr<X509Certificate> google_full_chain =
916       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
917                                         intermediates);
918   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain);
919   ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size());
920
921   CertVerifyResult verify_result;
922   EXPECT_EQ(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
923   int error = Verify(google_full_chain.get(),
924                      "127.0.0.1",
925                      0,
926                      NULL,
927                      empty_cert_list_,
928                      &verify_result);
929   EXPECT_EQ(OK, error);
930   ASSERT_NE(static_cast<X509Certificate*>(NULL), verify_result.verified_cert);
931
932   EXPECT_NE(google_full_chain, verify_result.verified_cert);
933   EXPECT_TRUE(X509Certificate::IsSameOSCert(
934       google_full_chain->os_cert_handle(),
935       verify_result.verified_cert->os_cert_handle()));
936   const X509Certificate::OSCertHandles& return_intermediates =
937       verify_result.verified_cert->GetIntermediateCertificates();
938   ASSERT_EQ(2U, return_intermediates.size());
939   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0],
940                                             certs[1]->os_cert_handle()));
941   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1],
942                                             certs[2]->os_cert_handle()));
943 }
944
945 TEST_F(CertVerifyProcTest, AdditionalTrustAnchors) {
946   if (!SupportsAdditionalTrustAnchors()) {
947     LOG(INFO) << "Skipping this test in this platform.";
948     return;
949   }
950
951   // |ca_cert| is the issuer of |cert|.
952   CertificateList ca_cert_list = CreateCertificateListFromFile(
953       GetTestCertsDirectory(), "root_ca_cert.pem",
954       X509Certificate::FORMAT_AUTO);
955   ASSERT_EQ(1U, ca_cert_list.size());
956   scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]);
957
958   CertificateList cert_list = CreateCertificateListFromFile(
959       GetTestCertsDirectory(), "ok_cert.pem",
960       X509Certificate::FORMAT_AUTO);
961   ASSERT_EQ(1U, cert_list.size());
962   scoped_refptr<X509Certificate> cert(cert_list[0]);
963
964   // Verification of |cert| fails when |ca_cert| is not in the trust anchors
965   // list.
966   int flags = 0;
967   CertVerifyResult verify_result;
968   int error = Verify(
969       cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
970   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
971   EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
972   EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
973
974   // Now add the |ca_cert| to the |trust_anchors|, and verification should pass.
975   CertificateList trust_anchors;
976   trust_anchors.push_back(ca_cert);
977   error = Verify(
978       cert.get(), "127.0.0.1", flags, NULL, trust_anchors, &verify_result);
979   EXPECT_EQ(OK, error);
980   EXPECT_EQ(0U, verify_result.cert_status);
981   EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor);
982
983   // Clearing the |trust_anchors| makes verification fail again (the cache
984   // should be skipped).
985   error = Verify(
986       cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
987   EXPECT_EQ(ERR_CERT_AUTHORITY_INVALID, error);
988   EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status);
989   EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
990 }
991
992 // Tests that certificates issued by user-supplied roots are not flagged as
993 // issued by a known root. This should pass whether or not the platform supports
994 // detecting known roots.
995 TEST_F(CertVerifyProcTest, IsIssuedByKnownRootIgnoresTestRoots) {
996   // Load root_ca_cert.pem into the test root store.
997   TestRootCerts* root_certs = TestRootCerts::GetInstance();
998   root_certs->AddFromFile(
999       GetTestCertsDirectory().AppendASCII("root_ca_cert.pem"));
1000
1001   CertificateList cert_list = CreateCertificateListFromFile(
1002       GetTestCertsDirectory(), "ok_cert.pem",
1003       X509Certificate::FORMAT_AUTO);
1004   ASSERT_EQ(1U, cert_list.size());
1005   scoped_refptr<X509Certificate> cert(cert_list[0]);
1006
1007   // Verification should pass.
1008   int flags = 0;
1009   CertVerifyResult verify_result;
1010   int error = Verify(
1011       cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
1012   EXPECT_EQ(OK, error);
1013   EXPECT_EQ(0U, verify_result.cert_status);
1014   // But should not be marked as a known root.
1015   EXPECT_FALSE(verify_result.is_issued_by_known_root);
1016
1017   root_certs->Clear();
1018   EXPECT_TRUE(root_certs->IsEmpty());
1019 }
1020
1021 #if defined(OS_MACOSX) && !defined(OS_IOS)
1022 // Tests that, on OS X, issues with a cross-certified Baltimore CyberTrust
1023 // Root can be successfully worked around once Apple completes removing the
1024 // older GTE CyberTrust Root from its trusted root store.
1025 //
1026 // The issue is caused by servers supplying the cross-certified intermediate
1027 // (necessary for certain mobile platforms), which OS X does not recognize
1028 // as already existing within its trust store.
1029 TEST_F(CertVerifyProcTest, CybertrustGTERoot) {
1030   CertificateList certs = CreateCertificateListFromFile(
1031       GetTestCertsDirectory(),
1032       "cybertrust_omniroot_chain.pem",
1033       X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
1034   ASSERT_EQ(2U, certs.size());
1035
1036   X509Certificate::OSCertHandles intermediates;
1037   intermediates.push_back(certs[1]->os_cert_handle());
1038
1039   scoped_refptr<X509Certificate> cybertrust_basic =
1040       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(),
1041                                         intermediates);
1042   ASSERT_TRUE(cybertrust_basic.get());
1043
1044   scoped_refptr<X509Certificate> baltimore_root =
1045       ImportCertFromFile(GetTestCertsDirectory(),
1046                          "cybertrust_baltimore_root.pem");
1047   ASSERT_TRUE(baltimore_root.get());
1048
1049   ScopedTestRoot scoped_root(baltimore_root.get());
1050
1051   // Ensure that ONLY the Baltimore CyberTrust Root is trusted. This
1052   // simulates Keychain removing support for the GTE CyberTrust Root.
1053   TestRootCerts::GetInstance()->SetAllowSystemTrust(false);
1054   base::ScopedClosureRunner reset_system_trust(
1055       base::Bind(&TestRootCerts::SetAllowSystemTrust,
1056                  base::Unretained(TestRootCerts::GetInstance()),
1057                  true));
1058
1059   // First, make sure a simple certificate chain from
1060   //   EE -> Public SureServer SV -> Baltimore CyberTrust
1061   // works. Only the first two certificates are included in the chain.
1062   int flags = 0;
1063   CertVerifyResult verify_result;
1064   int error = Verify(cybertrust_basic.get(),
1065                      "cacert.omniroot.com",
1066                      flags,
1067                      NULL,
1068                      empty_cert_list_,
1069                      &verify_result);
1070   EXPECT_EQ(OK, error);
1071   EXPECT_EQ(0U, verify_result.cert_status);
1072
1073   // Attempt to verify with the first known cross-certified intermediate
1074   // provided.
1075   scoped_refptr<X509Certificate> baltimore_intermediate_1 =
1076       ImportCertFromFile(GetTestCertsDirectory(),
1077                          "cybertrust_baltimore_cross_certified_1.pem");
1078   ASSERT_TRUE(baltimore_intermediate_1.get());
1079
1080   X509Certificate::OSCertHandles intermediate_chain_1 =
1081       cybertrust_basic->GetIntermediateCertificates();
1082   intermediate_chain_1.push_back(baltimore_intermediate_1->os_cert_handle());
1083
1084   scoped_refptr<X509Certificate> baltimore_chain_1 =
1085       X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1086                                         intermediate_chain_1);
1087   error = Verify(baltimore_chain_1.get(),
1088                  "cacert.omniroot.com",
1089                  flags,
1090                  NULL,
1091                  empty_cert_list_,
1092                  &verify_result);
1093   EXPECT_EQ(OK, error);
1094   EXPECT_EQ(0U, verify_result.cert_status);
1095
1096   // Attempt to verify with the second known cross-certified intermediate
1097   // provided.
1098   scoped_refptr<X509Certificate> baltimore_intermediate_2 =
1099       ImportCertFromFile(GetTestCertsDirectory(),
1100                          "cybertrust_baltimore_cross_certified_2.pem");
1101   ASSERT_TRUE(baltimore_intermediate_2.get());
1102
1103   X509Certificate::OSCertHandles intermediate_chain_2 =
1104       cybertrust_basic->GetIntermediateCertificates();
1105   intermediate_chain_2.push_back(baltimore_intermediate_2->os_cert_handle());
1106
1107   scoped_refptr<X509Certificate> baltimore_chain_2 =
1108       X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1109                                         intermediate_chain_2);
1110   error = Verify(baltimore_chain_2.get(),
1111                  "cacert.omniroot.com",
1112                  flags,
1113                  NULL,
1114                  empty_cert_list_,
1115                  &verify_result);
1116   EXPECT_EQ(OK, error);
1117   EXPECT_EQ(0U, verify_result.cert_status);
1118
1119   // Attempt to verify when both a cross-certified intermediate AND
1120   // the legacy GTE root are provided.
1121   scoped_refptr<X509Certificate> cybertrust_root =
1122       ImportCertFromFile(GetTestCertsDirectory(),
1123                          "cybertrust_gte_root.pem");
1124   ASSERT_TRUE(cybertrust_root.get());
1125
1126   intermediate_chain_2.push_back(cybertrust_root->os_cert_handle());
1127   scoped_refptr<X509Certificate> baltimore_chain_with_root =
1128       X509Certificate::CreateFromHandle(cybertrust_basic->os_cert_handle(),
1129                                         intermediate_chain_2);
1130   error = Verify(baltimore_chain_with_root.get(),
1131                  "cacert.omniroot.com",
1132                  flags,
1133                  NULL,
1134                  empty_cert_list_,
1135                  &verify_result);
1136   EXPECT_EQ(OK, error);
1137   EXPECT_EQ(0U, verify_result.cert_status);
1138
1139   TestRootCerts::GetInstance()->Clear();
1140   EXPECT_TRUE(TestRootCerts::GetInstance()->IsEmpty());
1141 }
1142 #endif
1143
1144 #if defined(USE_NSS) || defined(OS_IOS) || defined(OS_WIN) || defined(OS_MACOSX)
1145 static const uint8 kCRLSetLeafSPKIBlocked[] = {
1146   0x8e, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1147   0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1148   0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1149   0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1150   0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1151   0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1152   0x30, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1153   0x49, 0x73, 0x22, 0x3a, 0x5b, 0x22, 0x43, 0x38, 0x4d, 0x4a, 0x46, 0x55, 0x55,
1154   0x5a, 0x38, 0x43, 0x79, 0x54, 0x2b, 0x4e, 0x57, 0x64, 0x68, 0x69, 0x7a, 0x51,
1155   0x68, 0x54, 0x49, 0x65, 0x46, 0x49, 0x37, 0x76, 0x41, 0x77, 0x7a, 0x64, 0x54,
1156   0x79, 0x52, 0x59, 0x45, 0x6e, 0x78, 0x6c, 0x33, 0x62, 0x67, 0x3d, 0x22, 0x5d,
1157   0x7d,
1158 };
1159
1160 static const uint8 kCRLSetLeafSerialBlocked[] = {
1161   0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1162   0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1163   0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1164   0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1165   0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1166   0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1167   0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1168   0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d, 0x0f, 0x87, 0xe4, 0xc7, 0x75, 0xea,
1169   0x46, 0x7e, 0xf3, 0xfd, 0x82, 0xb7, 0x46, 0x7b, 0x10, 0xda, 0xc5, 0xbf, 0xd8,
1170   0xd1, 0x29, 0xb2, 0xc6, 0xac, 0x7f, 0x51, 0x42, 0x15, 0x28, 0x51, 0x06, 0x7f,
1171   0x01, 0x00, 0x00, 0x00,  // number of serials
1172   0x01, 0xed,  // serial 0xed
1173 };
1174
1175 static const uint8 kCRLSetQUICSerialBlocked[] = {
1176   0x60, 0x00, 0x7b, 0x22, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x22, 0x3a,
1177   0x30, 0x2c, 0x22, 0x43, 0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x54, 0x79, 0x70,
1178   0x65, 0x22, 0x3a, 0x22, 0x43, 0x52, 0x4c, 0x53, 0x65, 0x74, 0x22, 0x2c, 0x22,
1179   0x53, 0x65, 0x71, 0x75, 0x65, 0x6e, 0x63, 0x65, 0x22, 0x3a, 0x30, 0x2c, 0x22,
1180   0x44, 0x65, 0x6c, 0x74, 0x61, 0x46, 0x72, 0x6f, 0x6d, 0x22, 0x3a, 0x30, 0x2c,
1181   0x22, 0x4e, 0x75, 0x6d, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x73, 0x22, 0x3a,
1182   0x31, 0x2c, 0x22, 0x42, 0x6c, 0x6f, 0x63, 0x6b, 0x65, 0x64, 0x53, 0x50, 0x4b,
1183   0x49, 0x73, 0x22, 0x3a, 0x5b, 0x5d, 0x7d,
1184   // Issuer SPKI SHA-256 hash:
1185   0xe4, 0x3a, 0xa3, 0xdb, 0x98, 0x31, 0x61, 0x05, 0xdd, 0x57, 0x6d, 0xc6, 0x2f,
1186   0x71, 0x26, 0xba, 0xdd, 0xf4, 0x98, 0x3e, 0x62, 0x22, 0xf8, 0xf9, 0xe4, 0x18,
1187   0x62, 0x77, 0x79, 0xdb, 0x9b, 0x31,
1188   0x01, 0x00, 0x00, 0x00,  // number of serials
1189   0x01, 0x03,  // serial 3
1190 };
1191
1192 // Test that CRLSets are effective in making a certificate appear to be
1193 // revoked.
1194 TEST_F(CertVerifyProcTest, CRLSet) {
1195   CertificateList ca_cert_list =
1196       CreateCertificateListFromFile(GetTestCertsDirectory(),
1197                                     "root_ca_cert.pem",
1198                                     X509Certificate::FORMAT_AUTO);
1199   ASSERT_EQ(1U, ca_cert_list.size());
1200   ScopedTestRoot test_root(ca_cert_list[0]);
1201
1202   CertificateList cert_list = CreateCertificateListFromFile(
1203       GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO);
1204   ASSERT_EQ(1U, cert_list.size());
1205   scoped_refptr<X509Certificate> cert(cert_list[0]);
1206
1207   int flags = 0;
1208   CertVerifyResult verify_result;
1209   int error = Verify(
1210       cert.get(), "127.0.0.1", flags, NULL, empty_cert_list_, &verify_result);
1211   EXPECT_EQ(OK, error);
1212   EXPECT_EQ(0U, verify_result.cert_status);
1213
1214   // First test blocking by SPKI.
1215   base::StringPiece crl_set_bytes(
1216       reinterpret_cast<const char*>(kCRLSetLeafSPKIBlocked),
1217       sizeof(kCRLSetLeafSPKIBlocked));
1218   scoped_refptr<CRLSet> crl_set;
1219   ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1220
1221   error = Verify(cert.get(),
1222                  "127.0.0.1",
1223                  flags,
1224                  crl_set.get(),
1225                  empty_cert_list_,
1226                  &verify_result);
1227   EXPECT_EQ(ERR_CERT_REVOKED, error);
1228
1229   // Second, test revocation by serial number of a cert directly under the
1230   // root.
1231   crl_set_bytes =
1232       base::StringPiece(reinterpret_cast<const char*>(kCRLSetLeafSerialBlocked),
1233                         sizeof(kCRLSetLeafSerialBlocked));
1234   ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1235
1236   error = Verify(cert.get(),
1237                  "127.0.0.1",
1238                  flags,
1239                  crl_set.get(),
1240                  empty_cert_list_,
1241                  &verify_result);
1242   EXPECT_EQ(ERR_CERT_REVOKED, error);
1243 }
1244
1245 TEST_F(CertVerifyProcTest, CRLSetLeafSerial) {
1246   CertificateList ca_cert_list =
1247       CreateCertificateListFromFile(GetTestCertsDirectory(),
1248                                     "quic_root.crt",
1249                                     X509Certificate::FORMAT_AUTO);
1250   ASSERT_EQ(1U, ca_cert_list.size());
1251   ScopedTestRoot test_root(ca_cert_list[0]);
1252
1253   CertificateList intermediate_cert_list =
1254       CreateCertificateListFromFile(GetTestCertsDirectory(),
1255                                     "quic_intermediate.crt",
1256                                     X509Certificate::FORMAT_AUTO);
1257   ASSERT_EQ(1U, intermediate_cert_list.size());
1258   X509Certificate::OSCertHandles intermediates;
1259   intermediates.push_back(intermediate_cert_list[0]->os_cert_handle());
1260
1261   CertificateList cert_list = CreateCertificateListFromFile(
1262       GetTestCertsDirectory(), "quic_test.example.com.crt",
1263       X509Certificate::FORMAT_AUTO);
1264   ASSERT_EQ(1U, cert_list.size());
1265
1266   scoped_refptr<X509Certificate> leaf =
1267       X509Certificate::CreateFromHandle(cert_list[0]->os_cert_handle(),
1268                                         intermediates);
1269
1270   int flags = 0;
1271   CertVerifyResult verify_result;
1272   int error = Verify(leaf.get(),
1273                      "test.example.com",
1274                      flags,
1275                      NULL,
1276                      empty_cert_list_,
1277                      &verify_result);
1278   EXPECT_EQ(OK, error);
1279   EXPECT_EQ(0U, verify_result.cert_status);
1280
1281   // Test revocation by serial number of a certificate not under the root.
1282   scoped_refptr<CRLSet> crl_set;
1283   base::StringPiece crl_set_bytes =
1284       base::StringPiece(reinterpret_cast<const char*>(kCRLSetQUICSerialBlocked),
1285                         sizeof(kCRLSetQUICSerialBlocked));
1286   ASSERT_TRUE(CRLSet::Parse(crl_set_bytes, &crl_set));
1287
1288   error = Verify(leaf.get(),
1289                  "test.example.com",
1290                  flags,
1291                  crl_set.get(),
1292                  empty_cert_list_,
1293                  &verify_result);
1294   EXPECT_EQ(ERR_CERT_REVOKED, error);
1295 }
1296 #endif
1297
1298 struct WeakDigestTestData {
1299   const char* root_cert_filename;
1300   const char* intermediate_cert_filename;
1301   const char* ee_cert_filename;
1302   bool expected_has_md5;
1303   bool expected_has_md4;
1304   bool expected_has_md2;
1305 };
1306
1307 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1308 // to output the parameter that was passed. Without this, it will simply
1309 // attempt to print out the first twenty bytes of the object, which depending
1310 // on platform and alignment, may result in an invalid read.
1311 void PrintTo(const WeakDigestTestData& data, std::ostream* os) {
1312   *os << "root: "
1313       << (data.root_cert_filename ? data.root_cert_filename : "none")
1314       << "; intermediate: " << data.intermediate_cert_filename
1315       << "; end-entity: " << data.ee_cert_filename;
1316 }
1317
1318 class CertVerifyProcWeakDigestTest
1319     : public CertVerifyProcTest,
1320       public testing::WithParamInterface<WeakDigestTestData> {
1321  public:
1322   CertVerifyProcWeakDigestTest() {}
1323   virtual ~CertVerifyProcWeakDigestTest() {}
1324 };
1325
1326 TEST_P(CertVerifyProcWeakDigestTest, Verify) {
1327   WeakDigestTestData data = GetParam();
1328   base::FilePath certs_dir = GetTestCertsDirectory();
1329
1330   ScopedTestRoot test_root;
1331   if (data.root_cert_filename) {
1332      scoped_refptr<X509Certificate> root_cert =
1333          ImportCertFromFile(certs_dir, data.root_cert_filename);
1334      ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert);
1335      test_root.Reset(root_cert.get());
1336   }
1337
1338   scoped_refptr<X509Certificate> intermediate_cert =
1339       ImportCertFromFile(certs_dir, data.intermediate_cert_filename);
1340   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert);
1341   scoped_refptr<X509Certificate> ee_cert =
1342       ImportCertFromFile(certs_dir, data.ee_cert_filename);
1343   ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert);
1344
1345   X509Certificate::OSCertHandles intermediates;
1346   intermediates.push_back(intermediate_cert->os_cert_handle());
1347
1348   scoped_refptr<X509Certificate> ee_chain =
1349       X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(),
1350                                         intermediates);
1351   ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_chain);
1352
1353   int flags = 0;
1354   CertVerifyResult verify_result;
1355   int rv = Verify(ee_chain.get(),
1356                   "127.0.0.1",
1357                   flags,
1358                   NULL,
1359                   empty_cert_list_,
1360                   &verify_result);
1361   EXPECT_EQ(data.expected_has_md5, verify_result.has_md5);
1362   EXPECT_EQ(data.expected_has_md4, verify_result.has_md4);
1363   EXPECT_EQ(data.expected_has_md2, verify_result.has_md2);
1364   EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor);
1365
1366   // Ensure that MD4 and MD2 are tagged as invalid.
1367   if (data.expected_has_md4 || data.expected_has_md2) {
1368     EXPECT_EQ(CERT_STATUS_INVALID,
1369               verify_result.cert_status & CERT_STATUS_INVALID);
1370   }
1371
1372   // Ensure that MD5 is flagged as weak.
1373   if (data.expected_has_md5) {
1374     EXPECT_EQ(
1375         CERT_STATUS_WEAK_SIGNATURE_ALGORITHM,
1376         verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM);
1377   }
1378
1379   // If a root cert is present, then check that the chain was rejected if any
1380   // weak algorithms are present. This is only checked when a root cert is
1381   // present because the error reported for incomplete chains with weak
1382   // algorithms depends on which implementation was used to validate (NSS,
1383   // OpenSSL, CryptoAPI, Security.framework) and upon which weak algorithm
1384   // present (MD2, MD4, MD5).
1385   if (data.root_cert_filename) {
1386     if (data.expected_has_md4 || data.expected_has_md2) {
1387       EXPECT_EQ(ERR_CERT_INVALID, rv);
1388     } else if (data.expected_has_md5) {
1389       EXPECT_EQ(ERR_CERT_WEAK_SIGNATURE_ALGORITHM, rv);
1390     } else {
1391       EXPECT_EQ(OK, rv);
1392     }
1393   }
1394 }
1395
1396 // Unlike TEST/TEST_F, which are macros that expand to further macros,
1397 // INSTANTIATE_TEST_CASE_P is a macro that expands directly to code that
1398 // stringizes the arguments. As a result, macros passed as parameters (such as
1399 // prefix or test_case_name) will not be expanded by the preprocessor. To work
1400 // around this, indirect the macro for INSTANTIATE_TEST_CASE_P, so that the
1401 // pre-processor will expand macros such as MAYBE_test_name before
1402 // instantiating the test.
1403 #define WRAPPED_INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator) \
1404     INSTANTIATE_TEST_CASE_P(prefix, test_case_name, generator)
1405
1406 // The signature algorithm of the root CA should not matter.
1407 const WeakDigestTestData kVerifyRootCATestData[] = {
1408   { "weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem",
1409     "weak_digest_sha1_ee.pem", false, false, false },
1410 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1411   // MD4 is not supported by OS X / NSS
1412   { "weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem",
1413     "weak_digest_sha1_ee.pem", false, false, false },
1414 #endif
1415   { "weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem",
1416     "weak_digest_sha1_ee.pem", false, false, false },
1417 };
1418 INSTANTIATE_TEST_CASE_P(VerifyRoot, CertVerifyProcWeakDigestTest,
1419                         testing::ValuesIn(kVerifyRootCATestData));
1420
1421 // The signature algorithm of intermediates should be properly detected.
1422 const WeakDigestTestData kVerifyIntermediateCATestData[] = {
1423   { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1424     "weak_digest_sha1_ee.pem", true, false, false },
1425 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1426   // MD4 is not supported by OS X / NSS
1427   { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1428     "weak_digest_sha1_ee.pem", false, true, false },
1429 #endif
1430   { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1431     "weak_digest_sha1_ee.pem", false, false, true },
1432 };
1433 // Disabled on NSS - MD4 is not supported, and MD2 and MD5 are disabled.
1434 #if defined(USE_NSS) || defined(OS_IOS)
1435 #define MAYBE_VerifyIntermediate DISABLED_VerifyIntermediate
1436 #else
1437 #define MAYBE_VerifyIntermediate VerifyIntermediate
1438 #endif
1439 WRAPPED_INSTANTIATE_TEST_CASE_P(
1440     MAYBE_VerifyIntermediate,
1441     CertVerifyProcWeakDigestTest,
1442     testing::ValuesIn(kVerifyIntermediateCATestData));
1443
1444 // The signature algorithm of end-entity should be properly detected.
1445 const WeakDigestTestData kVerifyEndEntityTestData[] = {
1446   { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1447     "weak_digest_md5_ee.pem", true, false, false },
1448 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1449   // MD4 is not supported by OS X / NSS
1450   { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1451     "weak_digest_md4_ee.pem", false, true, false },
1452 #endif
1453   { "weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem",
1454     "weak_digest_md2_ee.pem", false, false, true },
1455 };
1456 // Disabled on NSS - NSS caches chains/signatures in such a way that cannot
1457 // be cleared until NSS is cleanly shutdown, which is not presently supported
1458 // in Chromium.
1459 #if defined(USE_NSS) || defined(OS_IOS)
1460 #define MAYBE_VerifyEndEntity DISABLED_VerifyEndEntity
1461 #else
1462 #define MAYBE_VerifyEndEntity VerifyEndEntity
1463 #endif
1464 WRAPPED_INSTANTIATE_TEST_CASE_P(MAYBE_VerifyEndEntity,
1465                                 CertVerifyProcWeakDigestTest,
1466                                 testing::ValuesIn(kVerifyEndEntityTestData));
1467
1468 // Incomplete chains should still report the status of the intermediate.
1469 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = {
1470   { NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem",
1471     true, false, false },
1472 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1473   // MD4 is not supported by OS X / NSS
1474   { NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem",
1475     false, true, false },
1476 #endif
1477   { NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem",
1478     false, false, true },
1479 };
1480 // Disabled on NSS - libpkix does not return constructed chains on error,
1481 // preventing us from detecting/inspecting the verified chain.
1482 #if defined(USE_NSS) || defined(OS_IOS)
1483 #define MAYBE_VerifyIncompleteIntermediate \
1484     DISABLED_VerifyIncompleteIntermediate
1485 #else
1486 #define MAYBE_VerifyIncompleteIntermediate VerifyIncompleteIntermediate
1487 #endif
1488 WRAPPED_INSTANTIATE_TEST_CASE_P(
1489     MAYBE_VerifyIncompleteIntermediate,
1490     CertVerifyProcWeakDigestTest,
1491     testing::ValuesIn(kVerifyIncompleteIntermediateTestData));
1492
1493 // Incomplete chains should still report the status of the end-entity.
1494 const WeakDigestTestData kVerifyIncompleteEETestData[] = {
1495   { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem",
1496     true, false, false },
1497 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1498   // MD4 is not supported by OS X / NSS
1499   { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem",
1500     false, true, false },
1501 #endif
1502   { NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem",
1503     false, false, true },
1504 };
1505 // Disabled on NSS - libpkix does not return constructed chains on error,
1506 // preventing us from detecting/inspecting the verified chain.
1507 #if defined(USE_NSS) || defined(OS_IOS)
1508 #define MAYBE_VerifyIncompleteEndEntity DISABLED_VerifyIncompleteEndEntity
1509 #else
1510 #define MAYBE_VerifyIncompleteEndEntity VerifyIncompleteEndEntity
1511 #endif
1512 WRAPPED_INSTANTIATE_TEST_CASE_P(
1513     MAYBE_VerifyIncompleteEndEntity,
1514     CertVerifyProcWeakDigestTest,
1515     testing::ValuesIn(kVerifyIncompleteEETestData));
1516
1517 // Differing algorithms between the intermediate and the EE should still be
1518 // reported.
1519 const WeakDigestTestData kVerifyMixedTestData[] = {
1520   { "weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem",
1521     "weak_digest_md2_ee.pem", true, false, true },
1522   { "weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem",
1523     "weak_digest_md5_ee.pem", true, false, true },
1524 #if defined(USE_OPENSSL_CERTS) || defined(OS_WIN)
1525   // MD4 is not supported by OS X / NSS
1526   { "weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem",
1527     "weak_digest_md2_ee.pem", false, true, true },
1528 #endif
1529 };
1530 // NSS does not support MD4 and does not enable MD2 by default, making all
1531 // permutations invalid.
1532 #if defined(USE_NSS) || defined(OS_IOS)
1533 #define MAYBE_VerifyMixed DISABLED_VerifyMixed
1534 #else
1535 #define MAYBE_VerifyMixed VerifyMixed
1536 #endif
1537 WRAPPED_INSTANTIATE_TEST_CASE_P(
1538     MAYBE_VerifyMixed,
1539     CertVerifyProcWeakDigestTest,
1540     testing::ValuesIn(kVerifyMixedTestData));
1541
1542 // For the list of valid hostnames, see
1543 // net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem
1544 static const struct CertVerifyProcNameData {
1545   const char* hostname;
1546   bool valid;  // Whether or not |hostname| matches a subjectAltName.
1547 } kVerifyNameData[] = {
1548   { "127.0.0.1", false },  // Don't match the common name
1549   { "127.0.0.2", true },  // Matches the iPAddress SAN (IPv4)
1550   { "FE80:0:0:0:0:0:0:1", true },  // Matches the iPAddress SAN (IPv6)
1551   { "[FE80:0:0:0:0:0:0:1]", false },  // Should not match the iPAddress SAN
1552   { "FE80::1", true },  // Compressed form matches the iPAddress SAN (IPv6)
1553   { "::127.0.0.2", false },  // IPv6 mapped form should NOT match iPAddress SAN
1554   { "test.example", true },  // Matches the dNSName SAN
1555   { "test.example.", true },  // Matches the dNSName SAN (trailing . ignored)
1556   { "www.test.example", false },  // Should not match the dNSName SAN
1557   { "test..example", false },  // Should not match the dNSName SAN
1558   { "test.example..", false },  // Should not match the dNSName SAN
1559   { ".test.example.", false },  // Should not match the dNSName SAN
1560   { ".test.example", false },  // Should not match the dNSName SAN
1561 };
1562
1563 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how
1564 // to output the parameter that was passed. Without this, it will simply
1565 // attempt to print out the first twenty bytes of the object, which depending
1566 // on platform and alignment, may result in an invalid read.
1567 void PrintTo(const CertVerifyProcNameData& data, std::ostream* os) {
1568   *os << "Hostname: " << data.hostname << "; valid=" << data.valid;
1569 }
1570
1571 class CertVerifyProcNameTest
1572     : public CertVerifyProcTest,
1573       public testing::WithParamInterface<CertVerifyProcNameData> {
1574  public:
1575   CertVerifyProcNameTest() {}
1576   virtual ~CertVerifyProcNameTest() {}
1577 };
1578
1579 TEST_P(CertVerifyProcNameTest, VerifyCertName) {
1580   CertVerifyProcNameData data = GetParam();
1581
1582   CertificateList cert_list = CreateCertificateListFromFile(
1583       GetTestCertsDirectory(), "subjectAltName_sanity_check.pem",
1584       X509Certificate::FORMAT_AUTO);
1585   ASSERT_EQ(1U, cert_list.size());
1586   scoped_refptr<X509Certificate> cert(cert_list[0]);
1587
1588   ScopedTestRoot scoped_root(cert.get());
1589
1590   CertVerifyResult verify_result;
1591   int error = Verify(cert.get(), data.hostname, 0, NULL, empty_cert_list_,
1592                      &verify_result);
1593   if (data.valid) {
1594     EXPECT_EQ(OK, error);
1595     EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1596   } else {
1597     EXPECT_EQ(ERR_CERT_COMMON_NAME_INVALID, error);
1598     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID);
1599   }
1600 }
1601
1602 WRAPPED_INSTANTIATE_TEST_CASE_P(
1603     VerifyName,
1604     CertVerifyProcNameTest,
1605     testing::ValuesIn(kVerifyNameData));
1606
1607 }  // namespace net