| OLD | NEW | 
|     1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |     1 // Copyright 2017 The Chromium Authors. All rights reserved. | 
|     2 // Use of this source code is governed by a BSD-style license that can be |     2 // Use of this source code is governed by a BSD-style license that can be | 
|     3 // found in the LICENSE file. |     3 // found in the LICENSE file. | 
|     4  |     4  | 
|     5 #include "net/cert/cert_verify_proc.h" |     5 #include "net/cert/cert_verify_proc_mac.h" | 
|     6  |     6  | 
|     7 #include <vector> |  | 
|     8  |  | 
|     9 #include "base/callback_helpers.h" |  | 
|    10 #include "base/files/file_path.h" |     7 #include "base/files/file_path.h" | 
|    11 #include "base/files/file_util.h" |     8 #include "base/files/file_util.h" | 
|    12 #include "base/logging.h" |     9 #include "base/logging.h" | 
 |    10 #include "base/mac/mac_util.h" | 
|    13 #include "base/macros.h" |    11 #include "base/macros.h" | 
|    14 #include "base/sha1.h" |    12 #include "base/memory/ptr_util.h" | 
|    15 #include "base/strings/string_number_conversions.h" |  | 
|    16 #include "base/test/histogram_tester.h" |  | 
|    17 #include "base/test/scoped_feature_list.h" |  | 
|    18 #include "build/build_config.h" |  | 
|    19 #include "crypto/sha2.h" |  | 
|    20 #include "net/base/net_errors.h" |    13 #include "net/base/net_errors.h" | 
|    21 #include "net/cert/asn1_util.h" |  | 
|    22 #include "net/cert/cert_status_flags.h" |  | 
|    23 #include "net/cert/cert_verifier.h" |    14 #include "net/cert/cert_verifier.h" | 
|    24 #include "net/cert/cert_verify_result.h" |    15 #include "net/cert/cert_verify_result.h" | 
|    25 #include "net/cert/crl_set.h" |    16 #include "net/cert/crl_set.h" | 
|    26 #include "net/cert/crl_set_storage.h" |    17 #include "net/cert/crl_set_storage.h" | 
 |    18 #include "net/cert/test_keychain_search_list_mac.h" | 
|    27 #include "net/cert/test_root_certs.h" |    19 #include "net/cert/test_root_certs.h" | 
|    28 #include "net/cert/x509_certificate.h" |    20 #include "net/cert/x509_certificate.h" | 
|    29 #include "net/test/cert_test_util.h" |    21 #include "net/test/cert_test_util.h" | 
|    30 #include "net/test/gtest_util.h" |    22 #include "net/test/gtest_util.h" | 
|    31 #include "net/test/test_certificate_data.h" |  | 
|    32 #include "net/test/test_data_directory.h" |    23 #include "net/test/test_data_directory.h" | 
|    33 #include "testing/gmock/include/gmock/gmock.h" |    24 #include "testing/gmock/include/gmock/gmock.h" | 
|    34 #include "testing/gtest/include/gtest/gtest.h" |    25 #include "testing/gtest/include/gtest/gtest.h" | 
|    35  |    26  | 
|    36 #if defined(OS_ANDROID) |  | 
|    37 #include "base/android/build_info.h" |  | 
|    38 #endif |  | 
|    39  |  | 
|    40 #if defined(OS_MACOSX) && !defined(OS_IOS) |  | 
|    41 #include "base/mac/mac_util.h" |  | 
|    42 #include "net/cert/test_keychain_search_list_mac.h" |  | 
|    43 #endif |  | 
|    44  |  | 
|    45 #if defined(OS_WIN) |  | 
|    46 #include "base/win/windows_version.h" |  | 
|    47 #endif |  | 
|    48  |  | 
|    49 using net::test::IsError; |    27 using net::test::IsError; | 
|    50 using net::test::IsOk; |    28 using net::test::IsOk; | 
|    51  |    29  | 
|    52 using base::HexEncode; |  | 
|    53  |  | 
|    54 namespace net { |    30 namespace net { | 
|    55  |    31  | 
|    56 namespace { |    32 namespace { | 
|    57  |    33  | 
|    58 const char kTLSFeatureExtensionHistogram[] = |  | 
|    59     "Net.Certificate.TLSFeatureExtensionWithPrivateRoot"; |  | 
|    60 const char kTLSFeatureExtensionOCSPHistogram[] = |  | 
|    61     "Net.Certificate.TLSFeatureExtensionWithPrivateRootHasOCSP"; |  | 
|    62  |  | 
|    63 // Mock CertVerifyProc that sets the CertVerifyResult to a given value for |  | 
|    64 // all certificates that are Verify()'d |  | 
|    65 class MockCertVerifyProc : public CertVerifyProc { |  | 
|    66  public: |  | 
|    67   explicit MockCertVerifyProc(const CertVerifyResult& result) |  | 
|    68       : result_(result) {} |  | 
|    69   // CertVerifyProc implementation: |  | 
|    70   bool SupportsAdditionalTrustAnchors() const override { return false; } |  | 
|    71   bool SupportsOCSPStapling() const override { return false; } |  | 
|    72  |  | 
|    73  protected: |  | 
|    74   ~MockCertVerifyProc() override {} |  | 
|    75  |  | 
|    76  private: |  | 
|    77   int VerifyInternal(X509Certificate* cert, |  | 
|    78                      const std::string& hostname, |  | 
|    79                      const std::string& ocsp_response, |  | 
|    80                      int flags, |  | 
|    81                      CRLSet* crl_set, |  | 
|    82                      const CertificateList& additional_trust_anchors, |  | 
|    83                      CertVerifyResult* verify_result) override; |  | 
|    84  |  | 
|    85   const CertVerifyResult result_; |  | 
|    86  |  | 
|    87   DISALLOW_COPY_AND_ASSIGN(MockCertVerifyProc); |  | 
|    88 }; |  | 
|    89  |  | 
|    90 int MockCertVerifyProc::VerifyInternal( |  | 
|    91     X509Certificate* cert, |  | 
|    92     const std::string& hostname, |  | 
|    93     const std::string& ocsp_response, |  | 
|    94     int flags, |  | 
|    95     CRLSet* crl_set, |  | 
|    96     const CertificateList& additional_trust_anchors, |  | 
|    97     CertVerifyResult* verify_result) { |  | 
|    98   *verify_result = result_; |  | 
|    99   verify_result->verified_cert = cert; |  | 
|   100   return OK; |  | 
|   101 } |  | 
|   102  |  | 
|   103 // This enum identifies a concrete implemenation of CertVerifyProc. |  | 
|   104 // |  | 
|   105 // The type is erased by CertVerifyProc::CreateDefault(), however |  | 
|   106 // needs to be known for some of the test expectations. |  | 
|   107 enum CertVerifyProcType { |  | 
|   108   CERT_VERIFY_PROC_NSS, |  | 
|   109   CERT_VERIFY_PROC_OPENSSL, |  | 
|   110   CERT_VERIFY_PROC_ANDROID, |  | 
|   111   CERT_VERIFY_PROC_IOS, |  | 
|   112   CERT_VERIFY_PROC_MAC, |  | 
|   113   CERT_VERIFY_PROC_WIN, |  | 
|   114 }; |  | 
|   115  |  | 
|   116 // Returns the CertVerifyProcType corresponding to what |  | 
|   117 // CertVerifyProc::CreateDefault() returns. This needs to be kept in sync with |  | 
|   118 // CreateDefault(). |  | 
|   119 CertVerifyProcType GetDefaultCertVerifyProcType() { |  | 
|   120 #if defined(USE_NSS_CERTS) |  | 
|   121   return CERT_VERIFY_PROC_NSS; |  | 
|   122 #elif defined(USE_OPENSSL_CERTS) && !defined(OS_ANDROID) |  | 
|   123   return CERT_VERIFY_PROC_OPENSSL; |  | 
|   124 #elif defined(OS_ANDROID) |  | 
|   125   return CERT_VERIFY_PROC_ANDROID; |  | 
|   126 #elif defined(OS_IOS) |  | 
|   127   return CERT_VERIFY_PROC_IOS; |  | 
|   128 #elif defined(OS_MACOSX) |  | 
|   129   return CERT_VERIFY_PROC_MAC; |  | 
|   130 #elif defined(OS_WIN) |  | 
|   131   return CERT_VERIFY_PROC_WIN; |  | 
|   132 #else |  | 
|   133 // Will fail to compile. |  | 
|   134 #endif |  | 
|   135 } |  | 
|   136  |  | 
|   137 // Whether the test is running within the iphone simulator. |  | 
|   138 const bool kTargetIsIphoneSimulator = |  | 
|   139 #if TARGET_IPHONE_SIMULATOR |  | 
|   140     true; |  | 
|   141 #else |  | 
|   142     false; |  | 
|   143 #endif |  | 
|   144  |  | 
|   145 // Template helper to load a series of certificate files into a CertificateList. |  | 
|   146 // Like CertTestUtil's CreateCertificateListFromFile, except it can load a |  | 
|   147 // series of individual certificates (to make the tests clearer). |  | 
|   148 template <size_t N> |  | 
|   149 void LoadCertificateFiles(const char* const (&cert_files)[N], |  | 
|   150                           CertificateList* certs) { |  | 
|   151   certs->clear(); |  | 
|   152   for (size_t i = 0; i < N; ++i) { |  | 
|   153     SCOPED_TRACE(cert_files[i]); |  | 
|   154     scoped_refptr<X509Certificate> cert = CreateCertificateChainFromFile( |  | 
|   155         GetTestCertsDirectory(), cert_files[i], X509Certificate::FORMAT_AUTO); |  | 
|   156     ASSERT_TRUE(cert); |  | 
|   157     certs->push_back(cert); |  | 
|   158   } |  | 
|   159 } |  | 
|   160  |  | 
|   161 // Returns a textual description of the CertVerifyProc implementation |  | 
|   162 // that is being tested, used to give better names to parameterized |  | 
|   163 // tests. |  | 
|   164 std::string VerifyProcTypeToName( |  | 
|   165     const testing::TestParamInfo<CertVerifyProcType>& params) { |  | 
|   166   switch (params.param) { |  | 
|   167     case CERT_VERIFY_PROC_NSS: |  | 
|   168       return "CertVerifyProcNSS"; |  | 
|   169     case CERT_VERIFY_PROC_OPENSSL: |  | 
|   170       return "CertVerifyProcOpenSSL"; |  | 
|   171     case CERT_VERIFY_PROC_ANDROID: |  | 
|   172       return "CertVerifyProcAndroid"; |  | 
|   173     case CERT_VERIFY_PROC_IOS: |  | 
|   174       return "CertVerifyProcIOS"; |  | 
|   175     case CERT_VERIFY_PROC_MAC: |  | 
|   176       return "CertVerifyProcMac"; |  | 
|   177     case CERT_VERIFY_PROC_WIN: |  | 
|   178       return "CertVerifyProcWin"; |  | 
|   179   } |  | 
|   180  |  | 
|   181   return nullptr; |  | 
|   182 } |  | 
|   183  |  | 
|   184 // The set of all CertVerifyProcTypes that tests should be |  | 
|   185 // parameterized on. |  | 
|   186 const std::vector<CertVerifyProcType> kAllCertVerifiers = { |  | 
|   187     GetDefaultCertVerifyProcType()}; |  | 
|   188  |  | 
|   189 }  // namespace |  | 
|   190  |  | 
|   191 // This fixture is for tests that apply to concrete implementations of |  | 
|   192 // CertVerifyProc. It will be run for all of the concrete |  | 
|   193 // CertVerifyProc types. |  | 
|   194 // |  | 
|   195 // It is called "Internal" as it tests the internal methods like |  | 
|   196 // "VerifyInternal()". |  | 
|   197 class CertVerifyProcInternalTest |  | 
|   198     : public testing::TestWithParam<CertVerifyProcType> { |  | 
|   199  protected: |  | 
|   200   void SetUp() override { |  | 
|   201     EXPECT_EQ(verify_proc_type(), GetDefaultCertVerifyProcType()); |  | 
|   202     verify_proc_ = CertVerifyProc::CreateDefault(); |  | 
|   203   } |  | 
|   204  |  | 
|   205   int Verify(X509Certificate* cert, |  | 
|   206              const std::string& hostname, |  | 
|   207              int flags, |  | 
|   208              CRLSet* crl_set, |  | 
|   209              const CertificateList& additional_trust_anchors, |  | 
|   210              CertVerifyResult* verify_result) { |  | 
|   211     return verify_proc_->Verify(cert, hostname, std::string(), flags, crl_set, |  | 
|   212                                 additional_trust_anchors, verify_result); |  | 
|   213   } |  | 
|   214  |  | 
|   215   CertVerifyProcType verify_proc_type() const { return GetParam(); } |  | 
|   216  |  | 
|   217   bool SupportsAdditionalTrustAnchors() const { |  | 
|   218     return verify_proc_->SupportsAdditionalTrustAnchors(); |  | 
|   219   } |  | 
|   220  |  | 
|   221   bool SupportsReturningVerifiedChain() const { |  | 
|   222 #if defined(OS_ANDROID) |  | 
|   223     // Before API level 17, Android does not expose the APIs necessary to get at |  | 
|   224     // the verified certificate chain. |  | 
|   225     if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID && |  | 
|   226         base::android::BuildInfo::GetInstance()->sdk_int() < 17) |  | 
|   227       return false; |  | 
|   228 #endif |  | 
|   229     return true; |  | 
|   230   } |  | 
|   231  |  | 
|   232   bool SupportsDetectingKnownRoots() const { |  | 
|   233 #if defined(OS_ANDROID) |  | 
|   234     // Before API level 17, Android does not expose the APIs necessary to get at |  | 
|   235     // the verified certificate chain and detect known roots. |  | 
|   236     if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) |  | 
|   237       return base::android::BuildInfo::GetInstance()->sdk_int() >= 17; |  | 
|   238 #endif |  | 
|   239  |  | 
|   240     // iOS does not expose the APIs necessary to get the known system roots. |  | 
|   241     if (verify_proc_type() == CERT_VERIFY_PROC_IOS) |  | 
|   242       return false; |  | 
|   243  |  | 
|   244     return true; |  | 
|   245   } |  | 
|   246  |  | 
|   247   bool WeakKeysAreInvalid() const { |  | 
|   248 #if defined(OS_MACOSX) && !defined(OS_IOS) |  | 
|   249     // Starting with Mac OS 10.12, certs with weak keys are treated as |  | 
|   250     // (recoverable) invalid certificate errors. |  | 
|   251     if (verify_proc_type() == CERT_VERIFY_PROC_MAC && |  | 
|   252         base::mac::IsAtLeastOS10_12()) { |  | 
|   253       return true; |  | 
|   254     } |  | 
|   255 #endif |  | 
|   256     return false; |  | 
|   257   } |  | 
|   258  |  | 
|   259   bool SupportsCRLSet() const { |  | 
|   260     return verify_proc_type() == CERT_VERIFY_PROC_NSS || |  | 
|   261            verify_proc_type() == CERT_VERIFY_PROC_WIN || |  | 
|   262            verify_proc_type() == CERT_VERIFY_PROC_MAC; |  | 
|   263   } |  | 
|   264  |  | 
|   265   bool SupportsCRLSetsInPathBuilding() const { |  | 
|   266     return verify_proc_type() == CERT_VERIFY_PROC_WIN || |  | 
|   267            verify_proc_type() == CERT_VERIFY_PROC_NSS; |  | 
|   268   } |  | 
|   269  |  | 
|   270   CertVerifyProc* verify_proc() const { return verify_proc_.get(); } |  | 
|   271  |  | 
|   272  private: |  | 
|   273   scoped_refptr<CertVerifyProc> verify_proc_; |  | 
|   274 }; |  | 
|   275  |  | 
|   276 INSTANTIATE_TEST_CASE_P(, |  | 
|   277                         CertVerifyProcInternalTest, |  | 
|   278                         testing::ValuesIn(kAllCertVerifiers), |  | 
|   279                         VerifyProcTypeToName); |  | 
|   280  |  | 
|   281 // TODO(rsleevi): Reenable this test once comodo.chaim.pem is no longer |  | 
|   282 // expired, http://crbug.com/502818 |  | 
|   283 TEST_P(CertVerifyProcInternalTest, DISABLED_EVVerification) { |  | 
|   284   if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID || |  | 
|   285       verify_proc_type() == CERT_VERIFY_PROC_OPENSSL) { |  | 
|   286     // TODO(jnd): http://crbug.com/117478 - EV verification is not yet |  | 
|   287     // supported. |  | 
|   288     LOG(INFO) << "Skipping test as EV verification is not yet supported"; |  | 
|   289     return; |  | 
|   290   } |  | 
|   291  |  | 
|   292   CertificateList certs = |  | 
|   293       CreateCertificateListFromFile(GetTestCertsDirectory(), "comodo.chain.pem", |  | 
|   294                                     X509Certificate::FORMAT_PEM_CERT_SEQUENCE); |  | 
|   295   ASSERT_EQ(3U, certs.size()); |  | 
|   296  |  | 
|   297   X509Certificate::OSCertHandles intermediates; |  | 
|   298   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|   299   intermediates.push_back(certs[2]->os_cert_handle()); |  | 
|   300  |  | 
|   301   scoped_refptr<X509Certificate> comodo_chain = |  | 
|   302       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |  | 
|   303                                         intermediates); |  | 
|   304  |  | 
|   305   scoped_refptr<CRLSet> crl_set(CRLSet::ForTesting(false, NULL, "")); |  | 
|   306   CertVerifyResult verify_result; |  | 
|   307   int flags = CertVerifier::VERIFY_EV_CERT; |  | 
|   308   int error = Verify(comodo_chain.get(), "comodo.com", flags, crl_set.get(), |  | 
|   309                      CertificateList(), &verify_result); |  | 
|   310   EXPECT_THAT(error, IsOk()); |  | 
|   311   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_IS_EV); |  | 
|   312 } |  | 
|   313  |  | 
|   314 // TODO(crbug.com/605457): the test expectation was incorrect on some |  | 
|   315 // configurations, so disable the test until it is fixed (better to have |  | 
|   316 // a bug to track a failing test than a false sense of security due to |  | 
|   317 // false positive). |  | 
|   318 TEST_P(CertVerifyProcInternalTest, DISABLED_PaypalNullCertParsing) { |  | 
|   319   // A certificate for www.paypal.com with a NULL byte in the common name. |  | 
|   320   // From http://www.gossamer-threads.com/lists/fulldisc/full-disclosure/70363 |  | 
|   321   SHA256HashValue paypal_null_fingerprint = {{0x00}}; |  | 
|   322  |  | 
|   323   scoped_refptr<X509Certificate> paypal_null_cert( |  | 
|   324       X509Certificate::CreateFromBytes( |  | 
|   325           reinterpret_cast<const char*>(paypal_null_der), |  | 
|   326           sizeof(paypal_null_der))); |  | 
|   327  |  | 
|   328   ASSERT_NE(static_cast<X509Certificate*>(NULL), paypal_null_cert.get()); |  | 
|   329  |  | 
|   330   EXPECT_EQ(paypal_null_fingerprint, X509Certificate::CalculateFingerprint256( |  | 
|   331                                          paypal_null_cert->os_cert_handle())); |  | 
|   332  |  | 
|   333   int flags = 0; |  | 
|   334   CertVerifyResult verify_result; |  | 
|   335   int error = Verify(paypal_null_cert.get(), "www.paypal.com", flags, NULL, |  | 
|   336                      CertificateList(), &verify_result); |  | 
|   337  |  | 
|   338   if (verify_proc_type() == CERT_VERIFY_PROC_NSS || |  | 
|   339       verify_proc_type() == CERT_VERIFY_PROC_ANDROID) { |  | 
|   340     EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID)); |  | 
|   341   } else if (verify_proc_type() == CERT_VERIFY_PROC_IOS && |  | 
|   342              kTargetIsIphoneSimulator) { |  | 
|   343     // iOS returns a ERR_CERT_INVALID error on the simulator, while returning |  | 
|   344     // ERR_CERT_AUTHORITY_INVALID on the real device. |  | 
|   345     EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); |  | 
|   346   } else { |  | 
|   347     // TOOD(bulach): investigate why macosx and win aren't returning |  | 
|   348     // ERR_CERT_INVALID or ERR_CERT_COMMON_NAME_INVALID. |  | 
|   349     EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); |  | 
|   350   } |  | 
|   351  |  | 
|   352   // Either the system crypto library should correctly report a certificate |  | 
|   353   // name mismatch, or our certificate blacklist should cause us to report an |  | 
|   354   // invalid certificate. |  | 
|   355   if (verify_proc_type() == CERT_VERIFY_PROC_NSS || |  | 
|   356       verify_proc_type() == CERT_VERIFY_PROC_WIN) { |  | 
|   357     EXPECT_TRUE(verify_result.cert_status & |  | 
|   358                 (CERT_STATUS_COMMON_NAME_INVALID | CERT_STATUS_INVALID)); |  | 
|   359   } |  | 
|   360  |  | 
|   361   // TODO(crbug.com/649017): What expectations to use for the other verifiers? |  | 
|   362 } |  | 
|   363  |  | 
|   364 // A regression test for http://crbug.com/31497. |  | 
|   365 TEST_P(CertVerifyProcInternalTest, IntermediateCARequireExplicitPolicy) { |  | 
|   366   if (verify_proc_type() == CERT_VERIFY_PROC_ANDROID) { |  | 
|   367     // Disabled on Android, as the Android verification libraries require an |  | 
|   368     // explicit policy to be specified, even when anyPolicy is permitted. |  | 
|   369     LOG(INFO) << "Skipping test on Android"; |  | 
|   370     return; |  | 
|   371   } |  | 
|   372  |  | 
|   373   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   374  |  | 
|   375   CertificateList certs = CreateCertificateListFromFile( |  | 
|   376       certs_dir, "explicit-policy-chain.pem", X509Certificate::FORMAT_AUTO); |  | 
|   377   ASSERT_EQ(3U, certs.size()); |  | 
|   378  |  | 
|   379   X509Certificate::OSCertHandles intermediates; |  | 
|   380   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|   381  |  | 
|   382   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |  | 
|   383       certs[0]->os_cert_handle(), intermediates); |  | 
|   384   ASSERT_TRUE(cert.get()); |  | 
|   385  |  | 
|   386   ScopedTestRoot scoped_root(certs[2].get()); |  | 
|   387  |  | 
|   388   int flags = 0; |  | 
|   389   CertVerifyResult verify_result; |  | 
|   390   int error = Verify(cert.get(), "policy_test.example", flags, NULL, |  | 
|   391                      CertificateList(), &verify_result); |  | 
|   392   EXPECT_THAT(error, IsOk()); |  | 
|   393   EXPECT_EQ(0u, verify_result.cert_status); |  | 
|   394 } |  | 
|   395  |  | 
|   396 TEST_P(CertVerifyProcInternalTest, RejectExpiredCert) { |  | 
|   397   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   398  |  | 
|   399   // Load root_ca_cert.pem into the test root store. |  | 
|   400   ScopedTestRoot test_root( |  | 
|   401       ImportCertFromFile(certs_dir, "root_ca_cert.pem").get()); |  | 
|   402  |  | 
|   403   CertificateList certs = CreateCertificateListFromFile( |  | 
|   404       certs_dir, "expired_cert.pem", X509Certificate::FORMAT_AUTO); |  | 
|   405   ASSERT_EQ(1U, certs.size()); |  | 
|   406  |  | 
|   407   X509Certificate::OSCertHandles intermediates; |  | 
|   408   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |  | 
|   409       certs[0]->os_cert_handle(), intermediates); |  | 
|   410  |  | 
|   411   int flags = 0; |  | 
|   412   CertVerifyResult verify_result; |  | 
|   413   int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(), |  | 
|   414                      &verify_result); |  | 
|   415   EXPECT_THAT(error, IsError(ERR_CERT_DATE_INVALID)); |  | 
|   416   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_DATE_INVALID); |  | 
|   417 } |  | 
|   418  |  | 
|   419 // Currently, only RSA and DSA keys are checked for weakness, and our example |  | 
|   420 // weak size is 768. These could change in the future. |  | 
|   421 // |  | 
|   422 // Note that this means there may be false negatives: keys for other |  | 
|   423 // algorithms and which are weak will pass this test. |  | 
|   424 static bool IsWeakKeyType(const std::string& key_type) { |  | 
|   425   size_t pos = key_type.find("-"); |  | 
|   426   std::string size = key_type.substr(0, pos); |  | 
|   427   std::string type = key_type.substr(pos + 1); |  | 
|   428  |  | 
|   429   if (type == "rsa" || type == "dsa") |  | 
|   430     return size == "768"; |  | 
|   431  |  | 
|   432   return false; |  | 
|   433 } |  | 
|   434  |  | 
|   435 TEST_P(CertVerifyProcInternalTest, RejectWeakKeys) { |  | 
|   436   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   437   typedef std::vector<std::string> Strings; |  | 
|   438   Strings key_types; |  | 
|   439  |  | 
|   440   // generate-weak-test-chains.sh currently has: |  | 
|   441   //     key_types="768-rsa 1024-rsa 2048-rsa prime256v1-ecdsa" |  | 
|   442   // We must use the same key types here. The filenames generated look like: |  | 
|   443   //     2048-rsa-ee-by-768-rsa-intermediate.pem |  | 
|   444   key_types.push_back("768-rsa"); |  | 
|   445   key_types.push_back("1024-rsa"); |  | 
|   446   key_types.push_back("2048-rsa"); |  | 
|   447   key_types.push_back("prime256v1-ecdsa"); |  | 
|   448  |  | 
|   449   // Add the root that signed the intermediates for this test. |  | 
|   450   scoped_refptr<X509Certificate> root_cert = |  | 
|   451       ImportCertFromFile(certs_dir, "2048-rsa-root.pem"); |  | 
|   452   ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); |  | 
|   453   ScopedTestRoot scoped_root(root_cert.get()); |  | 
|   454  |  | 
|   455   // Now test each chain. |  | 
|   456   for (Strings::const_iterator ee_type = key_types.begin(); |  | 
|   457        ee_type != key_types.end(); ++ee_type) { |  | 
|   458     for (Strings::const_iterator signer_type = key_types.begin(); |  | 
|   459          signer_type != key_types.end(); ++signer_type) { |  | 
|   460       std::string basename = |  | 
|   461           *ee_type + "-ee-by-" + *signer_type + "-intermediate.pem"; |  | 
|   462       SCOPED_TRACE(basename); |  | 
|   463       scoped_refptr<X509Certificate> ee_cert = |  | 
|   464           ImportCertFromFile(certs_dir, basename); |  | 
|   465       ASSERT_NE(static_cast<X509Certificate*>(NULL), ee_cert.get()); |  | 
|   466  |  | 
|   467       basename = *signer_type + "-intermediate.pem"; |  | 
|   468       scoped_refptr<X509Certificate> intermediate = |  | 
|   469           ImportCertFromFile(certs_dir, basename); |  | 
|   470       ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate.get()); |  | 
|   471  |  | 
|   472       X509Certificate::OSCertHandles intermediates; |  | 
|   473       intermediates.push_back(intermediate->os_cert_handle()); |  | 
|   474       scoped_refptr<X509Certificate> cert_chain = |  | 
|   475           X509Certificate::CreateFromHandle(ee_cert->os_cert_handle(), |  | 
|   476                                             intermediates); |  | 
|   477  |  | 
|   478       CertVerifyResult verify_result; |  | 
|   479       int error = Verify(cert_chain.get(), "127.0.0.1", 0, NULL, |  | 
|   480                          CertificateList(), &verify_result); |  | 
|   481  |  | 
|   482       if (IsWeakKeyType(*ee_type) || IsWeakKeyType(*signer_type)) { |  | 
|   483         EXPECT_NE(OK, error); |  | 
|   484         EXPECT_EQ(CERT_STATUS_WEAK_KEY, |  | 
|   485                   verify_result.cert_status & CERT_STATUS_WEAK_KEY); |  | 
|   486         EXPECT_EQ(WeakKeysAreInvalid() ? CERT_STATUS_INVALID : 0, |  | 
|   487                   verify_result.cert_status & CERT_STATUS_INVALID); |  | 
|   488       } else { |  | 
|   489         EXPECT_THAT(error, IsOk()); |  | 
|   490         EXPECT_EQ(0U, verify_result.cert_status & CERT_STATUS_WEAK_KEY); |  | 
|   491       } |  | 
|   492     } |  | 
|   493   } |  | 
|   494 } |  | 
|   495  |  | 
|   496 // Regression test for http://crbug.com/108514. |  | 
|   497 TEST_P(CertVerifyProcInternalTest, ExtraneousMD5RootCert) { |  | 
|   498   if (!SupportsReturningVerifiedChain()) { |  | 
|   499     LOG(INFO) << "Skipping this test in this platform."; |  | 
|   500     return; |  | 
|   501   } |  | 
|   502  |  | 
|   503   if (verify_proc_type() == CERT_VERIFY_PROC_MAC) { |  | 
|   504     // Disabled on OS X - Security.framework doesn't ignore superflous |  | 
|   505     // certificates provided by servers. |  | 
|   506     // TODO(eroman): Is this still needed? |  | 
|   507     LOG(INFO) << "Skipping this test as Security.framework doesn't ignore " |  | 
|   508                  "superflous certificates provided by servers."; |  | 
|   509     return; |  | 
|   510   } |  | 
|   511  |  | 
|   512   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   513  |  | 
|   514   scoped_refptr<X509Certificate> server_cert = |  | 
|   515       ImportCertFromFile(certs_dir, "cross-signed-leaf.pem"); |  | 
|   516   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get()); |  | 
|   517  |  | 
|   518   scoped_refptr<X509Certificate> extra_cert = |  | 
|   519       ImportCertFromFile(certs_dir, "cross-signed-root-md5.pem"); |  | 
|   520   ASSERT_NE(static_cast<X509Certificate*>(NULL), extra_cert.get()); |  | 
|   521  |  | 
|   522   scoped_refptr<X509Certificate> root_cert = |  | 
|   523       ImportCertFromFile(certs_dir, "cross-signed-root-sha256.pem"); |  | 
|   524   ASSERT_NE(static_cast<X509Certificate*>(NULL), root_cert.get()); |  | 
|   525  |  | 
|   526   ScopedTestRoot scoped_root(root_cert.get()); |  | 
|   527  |  | 
|   528   X509Certificate::OSCertHandles intermediates; |  | 
|   529   intermediates.push_back(extra_cert->os_cert_handle()); |  | 
|   530   scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle( |  | 
|   531       server_cert->os_cert_handle(), intermediates); |  | 
|   532  |  | 
|   533   CertVerifyResult verify_result; |  | 
|   534   int flags = 0; |  | 
|   535   int error = Verify(cert_chain.get(), "127.0.0.1", flags, NULL, |  | 
|   536                      CertificateList(), &verify_result); |  | 
|   537   EXPECT_THAT(error, IsOk()); |  | 
|   538  |  | 
|   539   // The extra MD5 root should be discarded |  | 
|   540   ASSERT_TRUE(verify_result.verified_cert.get()); |  | 
|   541   ASSERT_EQ(1u, |  | 
|   542             verify_result.verified_cert->GetIntermediateCertificates().size()); |  | 
|   543   EXPECT_TRUE(X509Certificate::IsSameOSCert( |  | 
|   544       verify_result.verified_cert->GetIntermediateCertificates().front(), |  | 
|   545       root_cert->os_cert_handle())); |  | 
|   546  |  | 
|   547   EXPECT_FALSE(verify_result.has_md5); |  | 
|   548 } |  | 
|   549  |  | 
|   550 // Test for bug 94673. |  | 
|   551 TEST_P(CertVerifyProcInternalTest, GoogleDigiNotarTest) { |  | 
|   552   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   553  |  | 
|   554   scoped_refptr<X509Certificate> server_cert = |  | 
|   555       ImportCertFromFile(certs_dir, "google_diginotar.pem"); |  | 
|   556   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get()); |  | 
|   557  |  | 
|   558   scoped_refptr<X509Certificate> intermediate_cert = |  | 
|   559       ImportCertFromFile(certs_dir, "diginotar_public_ca_2025.pem"); |  | 
|   560   ASSERT_NE(static_cast<X509Certificate*>(NULL), intermediate_cert.get()); |  | 
|   561  |  | 
|   562   X509Certificate::OSCertHandles intermediates; |  | 
|   563   intermediates.push_back(intermediate_cert->os_cert_handle()); |  | 
|   564   scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle( |  | 
|   565       server_cert->os_cert_handle(), intermediates); |  | 
|   566  |  | 
|   567   CertVerifyResult verify_result; |  | 
|   568   int flags = CertVerifier::VERIFY_REV_CHECKING_ENABLED; |  | 
|   569   int error = Verify(cert_chain.get(), "mail.google.com", flags, NULL, |  | 
|   570                      CertificateList(), &verify_result); |  | 
|   571   EXPECT_NE(OK, error); |  | 
|   572  |  | 
|   573   // Now turn off revocation checking.  Certificate verification should still |  | 
|   574   // fail. |  | 
|   575   flags = 0; |  | 
|   576   error = Verify(cert_chain.get(), "mail.google.com", flags, NULL, |  | 
|   577                  CertificateList(), &verify_result); |  | 
|   578   EXPECT_NE(OK, error); |  | 
|   579 } |  | 
|   580  |  | 
|   581 // Ensures the CertVerifyProc blacklist remains in sorted order, so that it |  | 
|   582 // can be binary-searched. |  | 
|   583 TEST(CertVerifyProcTest, BlacklistIsSorted) { |  | 
|   584 // Defines kBlacklistedSPKIs. |  | 
|   585 #include "net/cert/cert_verify_proc_blacklist.inc" |  | 
|   586   for (size_t i = 0; i < arraysize(kBlacklistedSPKIs) - 1; ++i) { |  | 
|   587     EXPECT_GT(0, memcmp(kBlacklistedSPKIs[i], kBlacklistedSPKIs[i + 1], |  | 
|   588                         crypto::kSHA256Length)) |  | 
|   589         << " at index " << i; |  | 
|   590   } |  | 
|   591 } |  | 
|   592  |  | 
|   593 TEST(CertVerifyProcTest, DigiNotarCerts) { |  | 
|   594   static const char* const kDigiNotarFilenames[] = { |  | 
|   595       "diginotar_root_ca.pem",          "diginotar_cyber_ca.pem", |  | 
|   596       "diginotar_services_1024_ca.pem", "diginotar_pkioverheid.pem", |  | 
|   597       "diginotar_pkioverheid_g2.pem",   NULL, |  | 
|   598   }; |  | 
|   599  |  | 
|   600   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   601  |  | 
|   602   for (size_t i = 0; kDigiNotarFilenames[i]; i++) { |  | 
|   603     scoped_refptr<X509Certificate> diginotar_cert = |  | 
|   604         ImportCertFromFile(certs_dir, kDigiNotarFilenames[i]); |  | 
|   605     std::string der_bytes; |  | 
|   606     ASSERT_TRUE(X509Certificate::GetDEREncoded(diginotar_cert->os_cert_handle(), |  | 
|   607                                                &der_bytes)); |  | 
|   608  |  | 
|   609     base::StringPiece spki; |  | 
|   610     ASSERT_TRUE(asn1::ExtractSPKIFromDERCert(der_bytes, &spki)); |  | 
|   611  |  | 
|   612     std::string spki_sha256 = crypto::SHA256HashString(spki.as_string()); |  | 
|   613  |  | 
|   614     HashValueVector public_keys; |  | 
|   615     HashValue hash(HASH_VALUE_SHA256); |  | 
|   616     ASSERT_EQ(hash.size(), spki_sha256.size()); |  | 
|   617     memcpy(hash.data(), spki_sha256.data(), spki_sha256.size()); |  | 
|   618     public_keys.push_back(hash); |  | 
|   619  |  | 
|   620     EXPECT_TRUE(CertVerifyProc::IsPublicKeyBlacklisted(public_keys)) |  | 
|   621         << "Public key not blocked for " << kDigiNotarFilenames[i]; |  | 
|   622   } |  | 
|   623 } |  | 
|   624  |  | 
|   625 TEST_P(CertVerifyProcInternalTest, NameConstraintsOk) { |  | 
|   626   CertificateList ca_cert_list = |  | 
|   627       CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem", |  | 
|   628                                     X509Certificate::FORMAT_AUTO); |  | 
|   629   ASSERT_EQ(1U, ca_cert_list.size()); |  | 
|   630   ScopedTestRoot test_root(ca_cert_list[0].get()); |  | 
|   631  |  | 
|   632   CertificateList cert_list = CreateCertificateListFromFile( |  | 
|   633       GetTestCertsDirectory(), "name_constraint_good.pem", |  | 
|   634       X509Certificate::FORMAT_AUTO); |  | 
|   635   ASSERT_EQ(1U, cert_list.size()); |  | 
|   636  |  | 
|   637   X509Certificate::OSCertHandles intermediates; |  | 
|   638   scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle( |  | 
|   639       cert_list[0]->os_cert_handle(), intermediates); |  | 
|   640  |  | 
|   641   int flags = 0; |  | 
|   642   CertVerifyResult verify_result; |  | 
|   643   int error = Verify(leaf.get(), "test.example.com", flags, NULL, |  | 
|   644                      CertificateList(), &verify_result); |  | 
|   645   EXPECT_THAT(error, IsOk()); |  | 
|   646   EXPECT_EQ(0U, verify_result.cert_status); |  | 
|   647  |  | 
|   648   error = Verify(leaf.get(), "foo.test2.example.com", flags, NULL, |  | 
|   649                  CertificateList(), &verify_result); |  | 
|   650   EXPECT_THAT(error, IsOk()); |  | 
|   651   EXPECT_EQ(0U, verify_result.cert_status); |  | 
|   652 } |  | 
|   653  |  | 
|   654 TEST_P(CertVerifyProcInternalTest, NameConstraintsFailure) { |  | 
|   655   if (!SupportsReturningVerifiedChain()) { |  | 
|   656     LOG(INFO) << "Skipping this test in this platform."; |  | 
|   657     return; |  | 
|   658   } |  | 
|   659  |  | 
|   660   CertificateList ca_cert_list = |  | 
|   661       CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem", |  | 
|   662                                     X509Certificate::FORMAT_AUTO); |  | 
|   663   ASSERT_EQ(1U, ca_cert_list.size()); |  | 
|   664   ScopedTestRoot test_root(ca_cert_list[0].get()); |  | 
|   665  |  | 
|   666   CertificateList cert_list = CreateCertificateListFromFile( |  | 
|   667       GetTestCertsDirectory(), "name_constraint_bad.pem", |  | 
|   668       X509Certificate::FORMAT_AUTO); |  | 
|   669   ASSERT_EQ(1U, cert_list.size()); |  | 
|   670  |  | 
|   671   X509Certificate::OSCertHandles intermediates; |  | 
|   672   scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle( |  | 
|   673       cert_list[0]->os_cert_handle(), intermediates); |  | 
|   674  |  | 
|   675   int flags = 0; |  | 
|   676   CertVerifyResult verify_result; |  | 
|   677   int error = Verify(leaf.get(), "test.example.com", flags, NULL, |  | 
|   678                      CertificateList(), &verify_result); |  | 
|   679   EXPECT_THAT(error, IsError(ERR_CERT_NAME_CONSTRAINT_VIOLATION)); |  | 
|   680   EXPECT_EQ(CERT_STATUS_NAME_CONSTRAINT_VIOLATION, |  | 
|   681             verify_result.cert_status & CERT_STATUS_NAME_CONSTRAINT_VIOLATION); |  | 
|   682 } |  | 
|   683  |  | 
|   684 TEST(CertVerifyProcTest, TestHasTooLongValidity) { |  | 
|   685   struct { |  | 
|   686     const char* const file; |  | 
|   687     bool is_valid_too_long; |  | 
|   688   } tests[] = { |  | 
|   689       {"twitter-chain.pem", false}, |  | 
|   690       {"start_after_expiry.pem", true}, |  | 
|   691       {"pre_br_validity_ok.pem", false}, |  | 
|   692       {"pre_br_validity_bad_121.pem", true}, |  | 
|   693       {"pre_br_validity_bad_2020.pem", true}, |  | 
|   694       {"10_year_validity.pem", false}, |  | 
|   695       {"11_year_validity.pem", true}, |  | 
|   696       {"39_months_after_2015_04.pem", false}, |  | 
|   697       {"40_months_after_2015_04.pem", true}, |  | 
|   698       {"60_months_after_2012_07.pem", false}, |  | 
|   699       {"61_months_after_2012_07.pem", true}, |  | 
|   700   }; |  | 
|   701  |  | 
|   702   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   703  |  | 
|   704   for (size_t i = 0; i < arraysize(tests); ++i) { |  | 
|   705     scoped_refptr<X509Certificate> certificate = |  | 
|   706         ImportCertFromFile(certs_dir, tests[i].file); |  | 
|   707     SCOPED_TRACE(tests[i].file); |  | 
|   708     ASSERT_TRUE(certificate); |  | 
|   709     EXPECT_EQ(tests[i].is_valid_too_long, |  | 
|   710               CertVerifyProc::HasTooLongValidity(*certificate)); |  | 
|   711   } |  | 
|   712 } |  | 
|   713  |  | 
|   714 // TODO(crbug.com/610546): Fix and re-enable this test. |  | 
|   715 TEST_P(CertVerifyProcInternalTest, DISABLED_TestKnownRoot) { |  | 
|   716   if (!SupportsDetectingKnownRoots()) { |  | 
|   717     LOG(INFO) << "Skipping this test on this platform."; |  | 
|   718     return; |  | 
|   719   } |  | 
|   720  |  | 
|   721   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   722   CertificateList certs = CreateCertificateListFromFile( |  | 
|   723       certs_dir, "twitter-chain.pem", X509Certificate::FORMAT_AUTO); |  | 
|   724   ASSERT_EQ(3U, certs.size()); |  | 
|   725  |  | 
|   726   X509Certificate::OSCertHandles intermediates; |  | 
|   727   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|   728  |  | 
|   729   scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle( |  | 
|   730       certs[0]->os_cert_handle(), intermediates); |  | 
|   731  |  | 
|   732   int flags = 0; |  | 
|   733   CertVerifyResult verify_result; |  | 
|   734   // This will blow up, May 9th, 2016. Sorry! Please disable and file a bug |  | 
|   735   // against agl. See also PublicKeyHashes. |  | 
|   736   int error = Verify(cert_chain.get(), "twitter.com", flags, NULL, |  | 
|   737                      CertificateList(), &verify_result); |  | 
|   738   EXPECT_THAT(error, IsOk()); |  | 
|   739   EXPECT_TRUE(verify_result.is_issued_by_known_root); |  | 
|   740 } |  | 
|   741  |  | 
|   742 // TODO(crbug.com/610546): Fix and re-enable this test. |  | 
|   743 TEST_P(CertVerifyProcInternalTest, DISABLED_PublicKeyHashes) { |  | 
|   744   if (!SupportsReturningVerifiedChain()) { |  | 
|   745     LOG(INFO) << "Skipping this test in this platform."; |  | 
|   746     return; |  | 
|   747   } |  | 
|   748  |  | 
|   749   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   750   CertificateList certs = CreateCertificateListFromFile( |  | 
|   751       certs_dir, "twitter-chain.pem", X509Certificate::FORMAT_AUTO); |  | 
|   752   ASSERT_EQ(3U, certs.size()); |  | 
|   753  |  | 
|   754   X509Certificate::OSCertHandles intermediates; |  | 
|   755   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|   756  |  | 
|   757   scoped_refptr<X509Certificate> cert_chain = X509Certificate::CreateFromHandle( |  | 
|   758       certs[0]->os_cert_handle(), intermediates); |  | 
|   759   int flags = 0; |  | 
|   760   CertVerifyResult verify_result; |  | 
|   761  |  | 
|   762   // This will blow up, May 9th, 2016. Sorry! Please disable and file a bug |  | 
|   763   // against agl. See also TestKnownRoot. |  | 
|   764   int error = Verify(cert_chain.get(), "twitter.com", flags, NULL, |  | 
|   765                      CertificateList(), &verify_result); |  | 
|   766   EXPECT_THAT(error, IsOk()); |  | 
|   767   ASSERT_LE(3U, verify_result.public_key_hashes.size()); |  | 
|   768  |  | 
|   769   HashValueVector sha1_hashes; |  | 
|   770   for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) { |  | 
|   771     if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA1) |  | 
|   772       continue; |  | 
|   773     sha1_hashes.push_back(verify_result.public_key_hashes[i]); |  | 
|   774   } |  | 
|   775   ASSERT_LE(3u, sha1_hashes.size()); |  | 
|   776  |  | 
|   777   for (size_t i = 0; i < 3; ++i) { |  | 
|   778     EXPECT_EQ(HexEncode(kTwitterSPKIs[i], base::kSHA1Length), |  | 
|   779               HexEncode(sha1_hashes[i].data(), base::kSHA1Length)); |  | 
|   780   } |  | 
|   781  |  | 
|   782   HashValueVector sha256_hashes; |  | 
|   783   for (size_t i = 0; i < verify_result.public_key_hashes.size(); ++i) { |  | 
|   784     if (verify_result.public_key_hashes[i].tag != HASH_VALUE_SHA256) |  | 
|   785       continue; |  | 
|   786     sha256_hashes.push_back(verify_result.public_key_hashes[i]); |  | 
|   787   } |  | 
|   788   ASSERT_LE(3u, sha256_hashes.size()); |  | 
|   789  |  | 
|   790   for (size_t i = 0; i < 3; ++i) { |  | 
|   791     EXPECT_EQ(HexEncode(kTwitterSPKIsSHA256[i], crypto::kSHA256Length), |  | 
|   792               HexEncode(sha256_hashes[i].data(), crypto::kSHA256Length)); |  | 
|   793   } |  | 
|   794 } |  | 
|   795  |  | 
|   796 // A regression test for http://crbug.com/70293. |  | 
|   797 // The Key Usage extension in this RSA SSL server certificate does not have |  | 
|   798 // the keyEncipherment bit. |  | 
|   799 TEST_P(CertVerifyProcInternalTest, InvalidKeyUsage) { |  | 
|   800   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   801  |  | 
|   802   scoped_refptr<X509Certificate> server_cert = |  | 
|   803       ImportCertFromFile(certs_dir, "invalid_key_usage_cert.der"); |  | 
|   804   ASSERT_NE(static_cast<X509Certificate*>(NULL), server_cert.get()); |  | 
|   805  |  | 
|   806   int flags = 0; |  | 
|   807   CertVerifyResult verify_result; |  | 
|   808   int error = Verify(server_cert.get(), "jira.aquameta.com", flags, NULL, |  | 
|   809                      CertificateList(), &verify_result); |  | 
|   810  |  | 
|   811   // TODO(eroman): Change the test data so results are consistent across |  | 
|   812   //               verifiers. |  | 
|   813   if (verify_proc_type() == CERT_VERIFY_PROC_OPENSSL) { |  | 
|   814     // This certificate has two errors: "invalid key usage" and "untrusted CA". |  | 
|   815     // However, OpenSSL returns only one (the latter), and we can't detect |  | 
|   816     // the other errors. |  | 
|   817     EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); |  | 
|   818   } else { |  | 
|   819     EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); |  | 
|   820     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); |  | 
|   821   } |  | 
|   822   // TODO(wtc): fix http://crbug.com/75520 to get all the certificate errors |  | 
|   823   // from NSS. |  | 
|   824   if (verify_proc_type() != CERT_VERIFY_PROC_NSS && |  | 
|   825       verify_proc_type() != CERT_VERIFY_PROC_IOS && |  | 
|   826       verify_proc_type() != CERT_VERIFY_PROC_ANDROID) { |  | 
|   827     // The certificate is issued by an unknown CA. |  | 
|   828     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_AUTHORITY_INVALID); |  | 
|   829   } |  | 
|   830 } |  | 
|   831  |  | 
|   832 // Basic test for returning the chain in CertVerifyResult. Note that the |  | 
|   833 // returned chain may just be a reflection of the originally supplied chain; |  | 
|   834 // that is, if any errors occur, the default chain returned is an exact copy |  | 
|   835 // of the certificate to be verified. The remaining VerifyReturn* tests are |  | 
|   836 // used to ensure that the actual, verified chain is being returned by |  | 
|   837 // Verify(). |  | 
|   838 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainBasic) { |  | 
|   839   if (!SupportsReturningVerifiedChain()) { |  | 
|   840     LOG(INFO) << "Skipping this test in this platform."; |  | 
|   841     return; |  | 
|   842   } |  | 
|   843  |  | 
|   844   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|   845   CertificateList certs = CreateCertificateListFromFile( |  | 
|   846       certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO); |  | 
|   847   ASSERT_EQ(3U, certs.size()); |  | 
|   848  |  | 
|   849   X509Certificate::OSCertHandles intermediates; |  | 
|   850   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|   851   intermediates.push_back(certs[2]->os_cert_handle()); |  | 
|   852  |  | 
|   853   ScopedTestRoot scoped_root(certs[2].get()); |  | 
|   854  |  | 
|   855   scoped_refptr<X509Certificate> google_full_chain = |  | 
|   856       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |  | 
|   857                                         intermediates); |  | 
|   858   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get()); |  | 
|   859   ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); |  | 
|   860  |  | 
|   861   CertVerifyResult verify_result; |  | 
|   862   EXPECT_EQ(static_cast<X509Certificate*>(NULL), |  | 
|   863             verify_result.verified_cert.get()); |  | 
|   864   int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL, |  | 
|   865                      CertificateList(), &verify_result); |  | 
|   866   EXPECT_THAT(error, IsOk()); |  | 
|   867   ASSERT_NE(static_cast<X509Certificate*>(NULL), |  | 
|   868             verify_result.verified_cert.get()); |  | 
|   869  |  | 
|   870   EXPECT_NE(google_full_chain, verify_result.verified_cert); |  | 
|   871   EXPECT_TRUE(X509Certificate::IsSameOSCert( |  | 
|   872       google_full_chain->os_cert_handle(), |  | 
|   873       verify_result.verified_cert->os_cert_handle())); |  | 
|   874   const X509Certificate::OSCertHandles& return_intermediates = |  | 
|   875       verify_result.verified_cert->GetIntermediateCertificates(); |  | 
|   876   ASSERT_EQ(2U, return_intermediates.size()); |  | 
|   877   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |  | 
|   878                                             certs[1]->os_cert_handle())); |  | 
|   879   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |  | 
|   880                                             certs[2]->os_cert_handle())); |  | 
|   881 } |  | 
|   882  |  | 
|   883 // Test that certificates issued for 'intranet' names (that is, containing no |  | 
|   884 // known public registry controlled domain information) issued by well-known |  | 
|   885 // CAs are flagged appropriately, while certificates that are issued by |  | 
|   886 // internal CAs are not flagged. |  | 
|   887 TEST(CertVerifyProcTest, IntranetHostsRejected) { |  | 
|   888   CertificateList cert_list = CreateCertificateListFromFile( |  | 
|   889       GetTestCertsDirectory(), "reject_intranet_hosts.pem", |  | 
|   890       X509Certificate::FORMAT_AUTO); |  | 
|   891   ASSERT_EQ(1U, cert_list.size()); |  | 
|   892   scoped_refptr<X509Certificate> cert(cert_list[0]); |  | 
|   893  |  | 
|   894   CertVerifyResult verify_result; |  | 
|   895   int error = 0; |  | 
|   896  |  | 
|   897   // Intranet names for public CAs should be flagged: |  | 
|   898   CertVerifyResult dummy_result; |  | 
|   899   dummy_result.is_issued_by_known_root = true; |  | 
|   900   scoped_refptr<CertVerifyProc> verify_proc = |  | 
|   901       new MockCertVerifyProc(dummy_result); |  | 
|   902   error = verify_proc->Verify(cert.get(), "intranet", std::string(), 0, NULL, |  | 
|   903                               CertificateList(), &verify_result); |  | 
|   904   EXPECT_THAT(error, IsOk()); |  | 
|   905   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME); |  | 
|   906  |  | 
|   907   // However, if the CA is not well known, these should not be flagged: |  | 
|   908   dummy_result.Reset(); |  | 
|   909   dummy_result.is_issued_by_known_root = false; |  | 
|   910   verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result)); |  | 
|   911   error = verify_proc->Verify(cert.get(), "intranet", std::string(), 0, NULL, |  | 
|   912                               CertificateList(), &verify_result); |  | 
|   913   EXPECT_THAT(error, IsOk()); |  | 
|   914   EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_NON_UNIQUE_NAME); |  | 
|   915 } |  | 
|   916  |  | 
|   917 // While all SHA-1 certificates should be rejected, in the event that there |  | 
|   918 // emerges some unexpected bug, test that the 'legacy' behaviour works |  | 
|   919 // correctly - rejecting all SHA-1 certificates from publicly trusted CAs |  | 
|   920 // that were issued after 1 January 2016, while still allowing those from |  | 
|   921 // before that date, with SHA-1 in the intermediate, or from an enterprise |  | 
|   922 // CA. |  | 
|   923 TEST(CertVerifyProcTest, VerifyRejectsSHA1AfterDeprecationLegacyMode) { |  | 
|   924   base::test::ScopedFeatureList scoped_feature_list; |  | 
|   925   scoped_feature_list.InitAndEnableFeature(CertVerifyProc::kSHA1LegacyMode); |  | 
|   926  |  | 
|   927   CertVerifyResult dummy_result; |  | 
|   928   CertVerifyResult verify_result; |  | 
|   929   int error = 0; |  | 
|   930   scoped_refptr<X509Certificate> cert; |  | 
|   931  |  | 
|   932   // Publicly trusted SHA-1 leaf certificates issued before 1 January 2016 |  | 
|   933   // are accepted. |  | 
|   934   verify_result.Reset(); |  | 
|   935   dummy_result.Reset(); |  | 
|   936   dummy_result.is_issued_by_known_root = true; |  | 
|   937   dummy_result.has_sha1 = true; |  | 
|   938   dummy_result.has_sha1_leaf = true; |  | 
|   939   scoped_refptr<CertVerifyProc> verify_proc = |  | 
|   940       new MockCertVerifyProc(dummy_result); |  | 
|   941   cert = CreateCertificateChainFromFile(GetTestCertsDirectory(), |  | 
|   942                                         "sha1_dec_2015.pem", |  | 
|   943                                         X509Certificate::FORMAT_AUTO); |  | 
|   944   ASSERT_TRUE(cert); |  | 
|   945   error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL, |  | 
|   946                               CertificateList(), &verify_result); |  | 
|   947   EXPECT_THAT(error, IsOk()); |  | 
|   948   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); |  | 
|   949  |  | 
|   950   // Publicly trusted SHA-1 leaf certificates issued on/after 1 January 2016 |  | 
|   951   // are rejected. |  | 
|   952   verify_result.Reset(); |  | 
|   953   dummy_result.Reset(); |  | 
|   954   dummy_result.is_issued_by_known_root = true; |  | 
|   955   dummy_result.has_sha1 = true; |  | 
|   956   dummy_result.has_sha1_leaf = true; |  | 
|   957   verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result)); |  | 
|   958   cert = CreateCertificateChainFromFile(GetTestCertsDirectory(), |  | 
|   959                                         "sha1_jan_2016.pem", |  | 
|   960                                         X509Certificate::FORMAT_AUTO); |  | 
|   961   ASSERT_TRUE(cert); |  | 
|   962   error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL, |  | 
|   963                               CertificateList(), &verify_result); |  | 
|   964   EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); |  | 
|   965   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM); |  | 
|   966  |  | 
|   967   // Enterprise issued SHA-1 leaf certificates issued on/after 1 January 2016 |  | 
|   968   // remain accepted. |  | 
|   969   verify_result.Reset(); |  | 
|   970   dummy_result.Reset(); |  | 
|   971   dummy_result.is_issued_by_known_root = false; |  | 
|   972   dummy_result.has_sha1 = true; |  | 
|   973   dummy_result.has_sha1_leaf = true; |  | 
|   974   verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result)); |  | 
|   975   cert = CreateCertificateChainFromFile(GetTestCertsDirectory(), |  | 
|   976                                         "sha1_jan_2016.pem", |  | 
|   977                                         X509Certificate::FORMAT_AUTO); |  | 
|   978   ASSERT_TRUE(cert); |  | 
|   979   error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL, |  | 
|   980                               CertificateList(), &verify_result); |  | 
|   981   EXPECT_THAT(error, IsOk()); |  | 
|   982   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); |  | 
|   983  |  | 
|   984   // Publicly trusted SHA-1 intermediates issued on/after 1 January 2016 are, |  | 
|   985   // unfortunately, accepted. This can arise due to OS path building quirks. |  | 
|   986   verify_result.Reset(); |  | 
|   987   dummy_result.Reset(); |  | 
|   988   dummy_result.is_issued_by_known_root = true; |  | 
|   989   dummy_result.has_sha1 = true; |  | 
|   990   dummy_result.has_sha1_leaf = false; |  | 
|   991   verify_proc = make_scoped_refptr(new MockCertVerifyProc(dummy_result)); |  | 
|   992   cert = CreateCertificateChainFromFile(GetTestCertsDirectory(), |  | 
|   993                                         "sha1_jan_2016.pem", |  | 
|   994                                         X509Certificate::FORMAT_AUTO); |  | 
|   995   ASSERT_TRUE(cert); |  | 
|   996   error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), 0, NULL, |  | 
|   997                               CertificateList(), &verify_result); |  | 
|   998   EXPECT_THAT(error, IsOk()); |  | 
|   999   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); |  | 
|  1000 } |  | 
|  1001  |  | 
|  1002 // Test that the certificate returned in CertVerifyResult is able to reorder |  | 
|  1003 // certificates that are not ordered from end-entity to root. While this is |  | 
|  1004 // a protocol violation if sent during a TLS handshake, if multiple sources |  | 
|  1005 // of intermediate certificates are combined, it's possible that order may |  | 
|  1006 // not be maintained. |  | 
|  1007 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainProperlyOrdered) { |  | 
|  1008   if (!SupportsReturningVerifiedChain()) { |  | 
|  1009     LOG(INFO) << "Skipping this test in this platform."; |  | 
|  1010     return; |  | 
|  1011   } |  | 
|  1012  |  | 
|  1013   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|  1014   CertificateList certs = CreateCertificateListFromFile( |  | 
|  1015       certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO); |  | 
|  1016   ASSERT_EQ(3U, certs.size()); |  | 
|  1017  |  | 
|  1018   // Construct the chain out of order. |  | 
|  1019   X509Certificate::OSCertHandles intermediates; |  | 
|  1020   intermediates.push_back(certs[2]->os_cert_handle()); |  | 
|  1021   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|  1022  |  | 
|  1023   ScopedTestRoot scoped_root(certs[2].get()); |  | 
|  1024  |  | 
|  1025   scoped_refptr<X509Certificate> google_full_chain = |  | 
|  1026       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |  | 
|  1027                                         intermediates); |  | 
|  1028   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get()); |  | 
|  1029   ASSERT_EQ(2U, google_full_chain->GetIntermediateCertificates().size()); |  | 
|  1030  |  | 
|  1031   CertVerifyResult verify_result; |  | 
|  1032   EXPECT_EQ(static_cast<X509Certificate*>(NULL), |  | 
|  1033             verify_result.verified_cert.get()); |  | 
|  1034   int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL, |  | 
|  1035                      CertificateList(), &verify_result); |  | 
|  1036   EXPECT_THAT(error, IsOk()); |  | 
|  1037   ASSERT_NE(static_cast<X509Certificate*>(NULL), |  | 
|  1038             verify_result.verified_cert.get()); |  | 
|  1039  |  | 
|  1040   EXPECT_NE(google_full_chain, verify_result.verified_cert); |  | 
|  1041   EXPECT_TRUE(X509Certificate::IsSameOSCert( |  | 
|  1042       google_full_chain->os_cert_handle(), |  | 
|  1043       verify_result.verified_cert->os_cert_handle())); |  | 
|  1044   const X509Certificate::OSCertHandles& return_intermediates = |  | 
|  1045       verify_result.verified_cert->GetIntermediateCertificates(); |  | 
|  1046   ASSERT_EQ(2U, return_intermediates.size()); |  | 
|  1047   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |  | 
|  1048                                             certs[1]->os_cert_handle())); |  | 
|  1049   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |  | 
|  1050                                             certs[2]->os_cert_handle())); |  | 
|  1051 } |  | 
|  1052  |  | 
|  1053 // Test that Verify() filters out certificates which are not related to |  | 
|  1054 // or part of the certificate chain being verified. |  | 
|  1055 TEST_P(CertVerifyProcInternalTest, VerifyReturnChainFiltersUnrelatedCerts) { |  | 
|  1056   if (!SupportsReturningVerifiedChain()) { |  | 
|  1057     LOG(INFO) << "Skipping this test in this platform."; |  | 
|  1058     return; |  | 
|  1059   } |  | 
|  1060  |  | 
|  1061   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|  1062   CertificateList certs = CreateCertificateListFromFile( |  | 
|  1063       certs_dir, "x509_verify_results.chain.pem", X509Certificate::FORMAT_AUTO); |  | 
|  1064   ASSERT_EQ(3U, certs.size()); |  | 
|  1065   ScopedTestRoot scoped_root(certs[2].get()); |  | 
|  1066  |  | 
|  1067   scoped_refptr<X509Certificate> unrelated_certificate = |  | 
|  1068       ImportCertFromFile(certs_dir, "duplicate_cn_1.pem"); |  | 
|  1069   scoped_refptr<X509Certificate> unrelated_certificate2 = |  | 
|  1070       ImportCertFromFile(certs_dir, "aia-cert.pem"); |  | 
|  1071   ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate.get()); |  | 
|  1072   ASSERT_NE(static_cast<X509Certificate*>(NULL), unrelated_certificate2.get()); |  | 
|  1073  |  | 
|  1074   // Interject unrelated certificates into the list of intermediates. |  | 
|  1075   X509Certificate::OSCertHandles intermediates; |  | 
|  1076   intermediates.push_back(unrelated_certificate->os_cert_handle()); |  | 
|  1077   intermediates.push_back(certs[1]->os_cert_handle()); |  | 
|  1078   intermediates.push_back(unrelated_certificate2->os_cert_handle()); |  | 
|  1079   intermediates.push_back(certs[2]->os_cert_handle()); |  | 
|  1080  |  | 
|  1081   scoped_refptr<X509Certificate> google_full_chain = |  | 
|  1082       X509Certificate::CreateFromHandle(certs[0]->os_cert_handle(), |  | 
|  1083                                         intermediates); |  | 
|  1084   ASSERT_NE(static_cast<X509Certificate*>(NULL), google_full_chain.get()); |  | 
|  1085   ASSERT_EQ(4U, google_full_chain->GetIntermediateCertificates().size()); |  | 
|  1086  |  | 
|  1087   CertVerifyResult verify_result; |  | 
|  1088   EXPECT_EQ(static_cast<X509Certificate*>(NULL), |  | 
|  1089             verify_result.verified_cert.get()); |  | 
|  1090   int error = Verify(google_full_chain.get(), "127.0.0.1", 0, NULL, |  | 
|  1091                      CertificateList(), &verify_result); |  | 
|  1092   EXPECT_THAT(error, IsOk()); |  | 
|  1093   ASSERT_NE(static_cast<X509Certificate*>(NULL), |  | 
|  1094             verify_result.verified_cert.get()); |  | 
|  1095  |  | 
|  1096   EXPECT_NE(google_full_chain, verify_result.verified_cert); |  | 
|  1097   EXPECT_TRUE(X509Certificate::IsSameOSCert( |  | 
|  1098       google_full_chain->os_cert_handle(), |  | 
|  1099       verify_result.verified_cert->os_cert_handle())); |  | 
|  1100   const X509Certificate::OSCertHandles& return_intermediates = |  | 
|  1101       verify_result.verified_cert->GetIntermediateCertificates(); |  | 
|  1102   ASSERT_EQ(2U, return_intermediates.size()); |  | 
|  1103   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[0], |  | 
|  1104                                             certs[1]->os_cert_handle())); |  | 
|  1105   EXPECT_TRUE(X509Certificate::IsSameOSCert(return_intermediates[1], |  | 
|  1106                                             certs[2]->os_cert_handle())); |  | 
|  1107 } |  | 
|  1108  |  | 
|  1109 TEST_P(CertVerifyProcInternalTest, AdditionalTrustAnchors) { |  | 
|  1110   if (!SupportsAdditionalTrustAnchors()) { |  | 
|  1111     LOG(INFO) << "Skipping this test in this platform."; |  | 
|  1112     return; |  | 
|  1113   } |  | 
|  1114  |  | 
|  1115   // |ca_cert| is the issuer of |cert|. |  | 
|  1116   CertificateList ca_cert_list = |  | 
|  1117       CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem", |  | 
|  1118                                     X509Certificate::FORMAT_AUTO); |  | 
|  1119   ASSERT_EQ(1U, ca_cert_list.size()); |  | 
|  1120   scoped_refptr<X509Certificate> ca_cert(ca_cert_list[0]); |  | 
|  1121  |  | 
|  1122   CertificateList cert_list = CreateCertificateListFromFile( |  | 
|  1123       GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO); |  | 
|  1124   ASSERT_EQ(1U, cert_list.size()); |  | 
|  1125   scoped_refptr<X509Certificate> cert(cert_list[0]); |  | 
|  1126  |  | 
|  1127   // Verification of |cert| fails when |ca_cert| is not in the trust anchors |  | 
|  1128   // list. |  | 
|  1129   int flags = 0; |  | 
|  1130   CertVerifyResult verify_result; |  | 
|  1131   int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(), |  | 
|  1132                      &verify_result); |  | 
|  1133   EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); |  | 
|  1134   EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); |  | 
|  1135   EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); |  | 
|  1136  |  | 
|  1137   // Now add the |ca_cert| to the |trust_anchors|, and verification should pass. |  | 
|  1138   CertificateList trust_anchors; |  | 
|  1139   trust_anchors.push_back(ca_cert); |  | 
|  1140   error = Verify(cert.get(), "127.0.0.1", flags, NULL, trust_anchors, |  | 
|  1141                  &verify_result); |  | 
|  1142   EXPECT_THAT(error, IsOk()); |  | 
|  1143   EXPECT_EQ(0U, verify_result.cert_status); |  | 
|  1144   EXPECT_TRUE(verify_result.is_issued_by_additional_trust_anchor); |  | 
|  1145  |  | 
|  1146   // Clearing the |trust_anchors| makes verification fail again (the cache |  | 
|  1147   // should be skipped). |  | 
|  1148   error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(), |  | 
|  1149                  &verify_result); |  | 
|  1150   EXPECT_THAT(error, IsError(ERR_CERT_AUTHORITY_INVALID)); |  | 
|  1151   EXPECT_EQ(CERT_STATUS_AUTHORITY_INVALID, verify_result.cert_status); |  | 
|  1152   EXPECT_FALSE(verify_result.is_issued_by_additional_trust_anchor); |  | 
|  1153 } |  | 
|  1154  |  | 
|  1155 // Tests that certificates issued by user-supplied roots are not flagged as |  | 
|  1156 // issued by a known root. This should pass whether or not the platform supports |  | 
|  1157 // detecting known roots. |  | 
|  1158 TEST_P(CertVerifyProcInternalTest, IsIssuedByKnownRootIgnoresTestRoots) { |  | 
|  1159   // Load root_ca_cert.pem into the test root store. |  | 
|  1160   ScopedTestRoot test_root( |  | 
|  1161       ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get()); |  | 
|  1162  |  | 
|  1163   scoped_refptr<X509Certificate> cert( |  | 
|  1164       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  1165  |  | 
|  1166   // Verification should pass. |  | 
|  1167   int flags = 0; |  | 
|  1168   CertVerifyResult verify_result; |  | 
|  1169   int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(), |  | 
|  1170                      &verify_result); |  | 
|  1171   EXPECT_THAT(error, IsOk()); |  | 
|  1172   EXPECT_EQ(0U, verify_result.cert_status); |  | 
|  1173   // But should not be marked as a known root. |  | 
|  1174   EXPECT_FALSE(verify_result.is_issued_by_known_root); |  | 
|  1175 } |  | 
|  1176  |  | 
|  1177 // Test that CRLSets are effective in making a certificate appear to be |  | 
|  1178 // revoked. |  | 
|  1179 TEST_P(CertVerifyProcInternalTest, CRLSet) { |  | 
|  1180   if (!SupportsCRLSet()) { |  | 
|  1181     LOG(INFO) << "Skipping test as verifier doesn't support CRLSet"; |  | 
|  1182     return; |  | 
|  1183   } |  | 
|  1184  |  | 
|  1185   CertificateList ca_cert_list = |  | 
|  1186       CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem", |  | 
|  1187                                     X509Certificate::FORMAT_AUTO); |  | 
|  1188   ASSERT_EQ(1U, ca_cert_list.size()); |  | 
|  1189   ScopedTestRoot test_root(ca_cert_list[0].get()); |  | 
|  1190  |  | 
|  1191   CertificateList cert_list = CreateCertificateListFromFile( |  | 
|  1192       GetTestCertsDirectory(), "ok_cert.pem", X509Certificate::FORMAT_AUTO); |  | 
|  1193   ASSERT_EQ(1U, cert_list.size()); |  | 
|  1194   scoped_refptr<X509Certificate> cert(cert_list[0]); |  | 
|  1195  |  | 
|  1196   int flags = 0; |  | 
|  1197   CertVerifyResult verify_result; |  | 
|  1198   int error = Verify(cert.get(), "127.0.0.1", flags, NULL, CertificateList(), |  | 
|  1199                      &verify_result); |  | 
|  1200   EXPECT_THAT(error, IsOk()); |  | 
|  1201   EXPECT_EQ(0U, verify_result.cert_status); |  | 
|  1202  |  | 
|  1203   scoped_refptr<CRLSet> crl_set; |  | 
|  1204   std::string crl_set_bytes; |  | 
|  1205  |  | 
|  1206   // First test blocking by SPKI. |  | 
|  1207   EXPECT_TRUE(base::ReadFileToString( |  | 
|  1208       GetTestCertsDirectory().AppendASCII("crlset_by_leaf_spki.raw"), |  | 
|  1209       &crl_set_bytes)); |  | 
|  1210   ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); |  | 
|  1211  |  | 
|  1212   error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(), |  | 
|  1213                  CertificateList(), &verify_result); |  | 
|  1214   EXPECT_THAT(error, IsError(ERR_CERT_REVOKED)); |  | 
|  1215  |  | 
|  1216   // Second, test revocation by serial number of a cert directly under the |  | 
|  1217   // root. |  | 
|  1218   crl_set_bytes.clear(); |  | 
|  1219   EXPECT_TRUE(base::ReadFileToString( |  | 
|  1220       GetTestCertsDirectory().AppendASCII("crlset_by_root_serial.raw"), |  | 
|  1221       &crl_set_bytes)); |  | 
|  1222   ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); |  | 
|  1223  |  | 
|  1224   error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(), |  | 
|  1225                  CertificateList(), &verify_result); |  | 
|  1226   EXPECT_THAT(error, IsError(ERR_CERT_REVOKED)); |  | 
|  1227 } |  | 
|  1228  |  | 
|  1229 TEST_P(CertVerifyProcInternalTest, CRLSetLeafSerial) { |  | 
|  1230   if (!SupportsCRLSet()) { |  | 
|  1231     LOG(INFO) << "Skipping test as verifier doesn't support CRLSet"; |  | 
|  1232     return; |  | 
|  1233   } |  | 
|  1234  |  | 
|  1235   CertificateList ca_cert_list = |  | 
|  1236       CreateCertificateListFromFile(GetTestCertsDirectory(), "root_ca_cert.pem", |  | 
|  1237                                     X509Certificate::FORMAT_AUTO); |  | 
|  1238   ASSERT_EQ(1U, ca_cert_list.size()); |  | 
|  1239   ScopedTestRoot test_root(ca_cert_list[0].get()); |  | 
|  1240  |  | 
|  1241   CertificateList intermediate_cert_list = CreateCertificateListFromFile( |  | 
|  1242       GetTestCertsDirectory(), "intermediate_ca_cert.pem", |  | 
|  1243       X509Certificate::FORMAT_AUTO); |  | 
|  1244   ASSERT_EQ(1U, intermediate_cert_list.size()); |  | 
|  1245   X509Certificate::OSCertHandles intermediates; |  | 
|  1246   intermediates.push_back(intermediate_cert_list[0]->os_cert_handle()); |  | 
|  1247  |  | 
|  1248   CertificateList cert_list = CreateCertificateListFromFile( |  | 
|  1249       GetTestCertsDirectory(), "ok_cert_by_intermediate.pem", |  | 
|  1250       X509Certificate::FORMAT_AUTO); |  | 
|  1251   ASSERT_EQ(1U, cert_list.size()); |  | 
|  1252  |  | 
|  1253   scoped_refptr<X509Certificate> leaf = X509Certificate::CreateFromHandle( |  | 
|  1254       cert_list[0]->os_cert_handle(), intermediates); |  | 
|  1255   ASSERT_TRUE(leaf); |  | 
|  1256  |  | 
|  1257   int flags = 0; |  | 
|  1258   CertVerifyResult verify_result; |  | 
|  1259   int error = Verify(leaf.get(), "127.0.0.1", flags, NULL, CertificateList(), |  | 
|  1260                      &verify_result); |  | 
|  1261   EXPECT_THAT(error, IsOk()); |  | 
|  1262  |  | 
|  1263   // Test revocation by serial number of a certificate not under the root. |  | 
|  1264   scoped_refptr<CRLSet> crl_set; |  | 
|  1265   std::string crl_set_bytes; |  | 
|  1266   ASSERT_TRUE(base::ReadFileToString( |  | 
|  1267       GetTestCertsDirectory().AppendASCII("crlset_by_intermediate_serial.raw"), |  | 
|  1268       &crl_set_bytes)); |  | 
|  1269   ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); |  | 
|  1270  |  | 
|  1271   error = Verify(leaf.get(), "127.0.0.1", flags, crl_set.get(), |  | 
|  1272                  CertificateList(), &verify_result); |  | 
|  1273   EXPECT_THAT(error, IsError(ERR_CERT_REVOKED)); |  | 
|  1274 } |  | 
|  1275  |  | 
|  1276 // Tests that CRLSets participate in path building functions, and that as |  | 
|  1277 // long as a valid path exists within the verification graph, verification |  | 
|  1278 // succeeds. |  | 
|  1279 // |  | 
|  1280 // In this test, there are two roots (D and E), and three possible paths |  | 
|  1281 // to validate a leaf (A): |  | 
|  1282 // 1. A(B) -> B(C) -> C(D) -> D(D) |  | 
|  1283 // 2. A(B) -> B(C) -> C(E) -> E(E) |  | 
|  1284 // 3. A(B) -> B(F) -> F(E) -> E(E) |  | 
|  1285 // |  | 
|  1286 // Each permutation of revocation is tried: |  | 
|  1287 // 1. Revoking E by SPKI, so that only Path 1 is valid (as E is in Paths 2 & 3) |  | 
|  1288 // 2. Revoking C(D) and F(E) by serial, so that only Path 2 is valid. |  | 
|  1289 // 3. Revoking C by SPKI, so that only Path 3 is valid (as C is in Paths 1 & 2) |  | 
|  1290 TEST_P(CertVerifyProcInternalTest, CRLSetDuringPathBuilding) { |  | 
|  1291   if (!SupportsCRLSetsInPathBuilding()) { |  | 
|  1292     LOG(INFO) << "Skipping this test on this platform."; |  | 
|  1293     return; |  | 
|  1294   } |  | 
|  1295  |  | 
|  1296   const char* const kPath1Files[] = { |  | 
|  1297       "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-D.pem", |  | 
|  1298       "multi-root-D-by-D.pem"}; |  | 
|  1299   const char* const kPath2Files[] = { |  | 
|  1300       "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem", |  | 
|  1301       "multi-root-E-by-E.pem"}; |  | 
|  1302   const char* const kPath3Files[] = { |  | 
|  1303       "multi-root-A-by-B.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem", |  | 
|  1304       "multi-root-E-by-E.pem"}; |  | 
|  1305  |  | 
|  1306   CertificateList path_1_certs; |  | 
|  1307   ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath1Files, &path_1_certs)); |  | 
|  1308  |  | 
|  1309   CertificateList path_2_certs; |  | 
|  1310   ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath2Files, &path_2_certs)); |  | 
|  1311  |  | 
|  1312   CertificateList path_3_certs; |  | 
|  1313   ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath3Files, &path_3_certs)); |  | 
|  1314  |  | 
|  1315   // Add D and E as trust anchors. |  | 
|  1316   ScopedTestRoot test_root_D(path_1_certs[3].get());  // D-by-D |  | 
|  1317   ScopedTestRoot test_root_E(path_2_certs[3].get());  // E-by-E |  | 
|  1318  |  | 
|  1319   // Create a chain that contains all the certificate paths possible. |  | 
|  1320   // CertVerifyProcInternalTest.VerifyReturnChainFiltersUnrelatedCerts already |  | 
|  1321   // ensures that it's safe to send additional certificates as inputs, and |  | 
|  1322   // that they're ignored if not necessary. |  | 
|  1323   // This is to avoid relying on AIA or internal object caches when |  | 
|  1324   // interacting with the underlying library. |  | 
|  1325   X509Certificate::OSCertHandles intermediates; |  | 
|  1326   intermediates.push_back(path_1_certs[1]->os_cert_handle());  // B-by-C |  | 
|  1327   intermediates.push_back(path_1_certs[2]->os_cert_handle());  // C-by-D |  | 
|  1328   intermediates.push_back(path_2_certs[2]->os_cert_handle());  // C-by-E |  | 
|  1329   intermediates.push_back(path_3_certs[1]->os_cert_handle());  // B-by-F |  | 
|  1330   intermediates.push_back(path_3_certs[2]->os_cert_handle());  // F-by-E |  | 
|  1331   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |  | 
|  1332       path_1_certs[0]->os_cert_handle(), intermediates); |  | 
|  1333   ASSERT_TRUE(cert); |  | 
|  1334  |  | 
|  1335   struct TestPermutations { |  | 
|  1336     const char* crlset; |  | 
|  1337     bool expect_valid; |  | 
|  1338     scoped_refptr<X509Certificate> expected_intermediate; |  | 
|  1339   } kTests[] = { |  | 
|  1340       {"multi-root-crlset-D-and-E.raw", false, nullptr}, |  | 
|  1341       {"multi-root-crlset-E.raw", true, path_1_certs[2].get()}, |  | 
|  1342       {"multi-root-crlset-CD-and-FE.raw", true, path_2_certs[2].get()}, |  | 
|  1343       {"multi-root-crlset-C.raw", true, path_3_certs[2].get()}, |  | 
|  1344       {"multi-root-crlset-unrelated.raw", true, nullptr}}; |  | 
|  1345  |  | 
|  1346   for (const auto& testcase : kTests) { |  | 
|  1347     SCOPED_TRACE(testcase.crlset); |  | 
|  1348     scoped_refptr<CRLSet> crl_set; |  | 
|  1349     std::string crl_set_bytes; |  | 
|  1350     EXPECT_TRUE(base::ReadFileToString( |  | 
|  1351         GetTestCertsDirectory().AppendASCII(testcase.crlset), &crl_set_bytes)); |  | 
|  1352     ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); |  | 
|  1353  |  | 
|  1354     int flags = 0; |  | 
|  1355     CertVerifyResult verify_result; |  | 
|  1356     int error = Verify(cert.get(), "127.0.0.1", flags, crl_set.get(), |  | 
|  1357                        CertificateList(), &verify_result); |  | 
|  1358  |  | 
|  1359     if (!testcase.expect_valid) { |  | 
|  1360       EXPECT_NE(OK, error); |  | 
|  1361       EXPECT_NE(0U, verify_result.cert_status); |  | 
|  1362       continue; |  | 
|  1363     } |  | 
|  1364  |  | 
|  1365     ASSERT_THAT(error, IsOk()); |  | 
|  1366     ASSERT_EQ(0U, verify_result.cert_status); |  | 
|  1367     ASSERT_TRUE(verify_result.verified_cert.get()); |  | 
|  1368  |  | 
|  1369     if (!testcase.expected_intermediate) |  | 
|  1370       continue; |  | 
|  1371  |  | 
|  1372     const X509Certificate::OSCertHandles& verified_intermediates = |  | 
|  1373         verify_result.verified_cert->GetIntermediateCertificates(); |  | 
|  1374     ASSERT_EQ(3U, verified_intermediates.size()); |  | 
|  1375  |  | 
|  1376     scoped_refptr<X509Certificate> intermediate = |  | 
|  1377         X509Certificate::CreateFromHandle(verified_intermediates[1], |  | 
|  1378                                           X509Certificate::OSCertHandles()); |  | 
|  1379     ASSERT_TRUE(intermediate); |  | 
|  1380  |  | 
|  1381     EXPECT_TRUE(testcase.expected_intermediate->Equals(intermediate.get())) |  | 
|  1382         << "Expected: " << testcase.expected_intermediate->subject().common_name |  | 
|  1383         << " issued by " << testcase.expected_intermediate->issuer().common_name |  | 
|  1384         << "; Got: " << intermediate->subject().common_name << " issued by " |  | 
|  1385         << intermediate->issuer().common_name; |  | 
|  1386   } |  | 
|  1387 } |  | 
|  1388  |  | 
|  1389 #if defined(OS_MACOSX) && !defined(OS_IOS) |  | 
|  1390 // Test that a CRLSet blocking one of the intermediates supplied by the server |    34 // Test that a CRLSet blocking one of the intermediates supplied by the server | 
|  1391 // can be worked around by the chopping workaround for path building. (Once the |    35 // can be worked around by the chopping workaround for path building. (Once the | 
|  1392 // supplied chain is chopped back to just the target, a better path can be |    36 // supplied chain is chopped back to just the target, a better path can be | 
|  1393 // found out-of-band. Normally that would be by AIA fetching, for the purposes |    37 // found out-of-band. Normally that would be by AIA fetching, for the purposes | 
|  1394 // of this test the better path is supplied by a test keychain.) |    38 // of this test the better path is supplied by a test keychain.) | 
|  1395 // |    39 // | 
|  1396 // In this test, there are two possible paths to validate a leaf (A): |    40 // In this test, there are two possible paths to validate a leaf (A): | 
|  1397 // 1. A(B) -> B(C) -> C(E) -> E(E) |    41 // 1. A(B) -> B(C) -> C(E) -> E(E) | 
|  1398 // 2. A(B) -> B(F) -> F(E) -> E(E) |    42 // 2. A(B) -> B(F) -> F(E) -> E(E) | 
|  1399 // |    43 // | 
|  1400 // A(B) -> B(C) -> C(E) is supplied to the verifier. |    44 // A(B) -> B(C) -> C(E) is supplied to the verifier. | 
|  1401 // B(F) and F(E) are supplied in a test keychain. |    45 // B(F) and F(E) are supplied in a test keychain. | 
|  1402 // C is blocked by a CRLset. |    46 // C is blocked by a CRLset. | 
|  1403 // |    47 // | 
|  1404 // The verifier should rollback until it just tries A(B) alone, at which point |    48 // The verifier should rollback until it just tries A(B) alone, at which point | 
|  1405 // it will pull B(F) & F(E) from the keychain and succeed. |    49 // it will pull B(F) & F(E) from the keychain and succeed. | 
|  1406 TEST(CertVerifyProcMacTest, MacCRLIntermediate) { |    50 TEST(CertVerifyProcMacTest, MacCRLIntermediate) { | 
|  1407   if (base::mac::IsAtLeastOS10_12()) { |    51   if (base::mac::IsAtLeastOS10_12()) { | 
|  1408     // TODO(crbug.com/671889): Investigate SecTrustSetKeychains issue on Sierra. |    52     // TODO(crbug.com/671889): Investigate SecTrustSetKeychains issue on Sierra. | 
|  1409     LOG(INFO) << "Skipping test, SecTrustSetKeychains does not work on 10.12"; |    53     LOG(INFO) << "Skipping test, SecTrustSetKeychains does not work on 10.12"; | 
|  1410     return; |    54     return; | 
|  1411   } |    55   } | 
|  1412   const char* const kPath2Files[] = { |  | 
|  1413       "multi-root-A-by-B.pem", "multi-root-B-by-C.pem", "multi-root-C-by-E.pem", |  | 
|  1414       "multi-root-E-by-E.pem"}; |  | 
|  1415   CertificateList path_2_certs; |    56   CertificateList path_2_certs; | 
|  1416   ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath2Files, &path_2_certs)); |    57   ASSERT_TRUE( | 
|  1417  |    58       LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-C.pem", | 
|  1418   const char* const kPath3Files[] = { |    59                             "multi-root-C-by-E.pem", "multi-root-E-by-E.pem"}, | 
|  1419       "multi-root-A-by-B.pem", "multi-root-B-by-F.pem", "multi-root-F-by-E.pem", |    60                            &path_2_certs)); | 
|  1420       "multi-root-E-by-E.pem"}; |  | 
|  1421  |    61  | 
|  1422   CertificateList path_3_certs; |    62   CertificateList path_3_certs; | 
|  1423   ASSERT_NO_FATAL_FAILURE(LoadCertificateFiles(kPath3Files, &path_3_certs)); |    63   ASSERT_TRUE( | 
 |    64       LoadCertificateFiles({"multi-root-A-by-B.pem", "multi-root-B-by-F.pem", | 
 |    65                             "multi-root-F-by-E.pem", "multi-root-E-by-E.pem"}, | 
 |    66                            &path_3_certs)); | 
|  1424  |    67  | 
|  1425   // Add E as trust anchor. |    68   // Add E as trust anchor. | 
|  1426   ScopedTestRoot test_root_E(path_3_certs[3].get());  // E-by-E |    69   ScopedTestRoot test_root_E(path_3_certs[3].get());  // E-by-E | 
|  1427  |    70  | 
|  1428   X509Certificate::OSCertHandles intermediates; |    71   X509Certificate::OSCertHandles intermediates; | 
|  1429   intermediates.push_back(path_2_certs[1]->os_cert_handle());  // B-by-C |    72   intermediates.push_back(path_2_certs[1]->os_cert_handle());  // B-by-C | 
|  1430   intermediates.push_back(path_2_certs[2]->os_cert_handle());  // C-by-E |    73   intermediates.push_back(path_2_certs[2]->os_cert_handle());  // C-by-E | 
|  1431   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( |    74   scoped_refptr<X509Certificate> cert = X509Certificate::CreateFromHandle( | 
|  1432       path_3_certs[0]->os_cert_handle(), intermediates); |    75       path_3_certs[0]->os_cert_handle(), intermediates); | 
|  1433   ASSERT_TRUE(cert); |    76   ASSERT_TRUE(cert); | 
| (...skipping 19 matching lines...) Expand all  Loading... | 
|  1453   std::string crl_set_bytes; |    96   std::string crl_set_bytes; | 
|  1454   // CRL which blocks C by SPKI. |    97   // CRL which blocks C by SPKI. | 
|  1455   EXPECT_TRUE(base::ReadFileToString( |    98   EXPECT_TRUE(base::ReadFileToString( | 
|  1456       GetTestCertsDirectory().AppendASCII("multi-root-crlset-C.raw"), |    99       GetTestCertsDirectory().AppendASCII("multi-root-crlset-C.raw"), | 
|  1457       &crl_set_bytes)); |   100       &crl_set_bytes)); | 
|  1458   ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); |   101   ASSERT_TRUE(CRLSetStorage::Parse(crl_set_bytes, &crl_set)); | 
|  1459  |   102  | 
|  1460   int flags = 0; |   103   int flags = 0; | 
|  1461   CertVerifyResult verify_result; |   104   CertVerifyResult verify_result; | 
|  1462  |   105  | 
|  1463   scoped_refptr<CertVerifyProc> verify_proc = CertVerifyProc::CreateDefault(); |   106   scoped_refptr<CertVerifyProc> verify_proc = new CertVerifyProcMac; | 
|  1464   int error = |   107   int error = | 
|  1465       verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |   108       verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, | 
|  1466                           crl_set.get(), CertificateList(), &verify_result); |   109                           crl_set.get(), CertificateList(), &verify_result); | 
|  1467  |   110  | 
|  1468   ASSERT_EQ(OK, error); |   111   ASSERT_EQ(OK, error); | 
|  1469   ASSERT_EQ(0U, verify_result.cert_status); |   112   ASSERT_EQ(0U, verify_result.cert_status); | 
|  1470   ASSERT_TRUE(verify_result.verified_cert.get()); |   113   ASSERT_TRUE(verify_result.verified_cert.get()); | 
|  1471  |   114  | 
|  1472   const X509Certificate::OSCertHandles& verified_intermediates = |   115   const X509Certificate::OSCertHandles& verified_intermediates = | 
|  1473       verify_result.verified_cert->GetIntermediateCertificates(); |   116       verify_result.verified_cert->GetIntermediateCertificates(); | 
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  1510   SecKeychainRef keychain; |   153   SecKeychainRef keychain; | 
|  1511   OSStatus status = |   154   OSStatus status = | 
|  1512       SecKeychainOpen(keychain_path.MaybeAsASCII().c_str(), &keychain); |   155       SecKeychainOpen(keychain_path.MaybeAsASCII().c_str(), &keychain); | 
|  1513   ASSERT_EQ(errSecSuccess, status); |   156   ASSERT_EQ(errSecSuccess, status); | 
|  1514   ASSERT_TRUE(keychain); |   157   ASSERT_TRUE(keychain); | 
|  1515   base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); |   158   base::ScopedCFTypeRef<SecKeychainRef> scoped_keychain(keychain); | 
|  1516   test_keychain_search_list->AddKeychain(keychain); |   159   test_keychain_search_list->AddKeychain(keychain); | 
|  1517  |   160  | 
|  1518   int flags = 0; |   161   int flags = 0; | 
|  1519   CertVerifyResult verify_result; |   162   CertVerifyResult verify_result; | 
|  1520   scoped_refptr<CertVerifyProc> verify_proc = CertVerifyProc::CreateDefault(); |   163   scoped_refptr<CertVerifyProc> verify_proc = new CertVerifyProcMac; | 
|  1521   int error = verify_proc->Verify(cert.get(), "www.tripadvisor.com", |   164   int error = verify_proc->Verify(cert.get(), "www.tripadvisor.com", | 
|  1522                                   std::string(), flags, nullptr /* crl_set */, |   165                                   std::string(), flags, nullptr /* crl_set */, | 
|  1523                                   CertificateList(), &verify_result); |   166                                   CertificateList(), &verify_result); | 
|  1524  |   167  | 
|  1525   ASSERT_EQ(OK, error); |   168   ASSERT_EQ(OK, error); | 
|  1526   EXPECT_EQ(0U, verify_result.cert_status); |   169   EXPECT_EQ(0U, verify_result.cert_status); | 
|  1527   EXPECT_FALSE(verify_result.has_sha1); |   170   EXPECT_FALSE(verify_result.has_sha1); | 
|  1528   ASSERT_TRUE(verify_result.verified_cert.get()); |   171   ASSERT_TRUE(verify_result.verified_cert.get()); | 
|  1529  |   172  | 
|  1530   const X509Certificate::OSCertHandles& verified_intermediates = |   173   const X509Certificate::OSCertHandles& verified_intermediates = | 
|  1531       verify_result.verified_cert->GetIntermediateCertificates(); |   174       verify_result.verified_cert->GetIntermediateCertificates(); | 
|  1532   ASSERT_EQ(2U, verified_intermediates.size()); |   175   ASSERT_EQ(2U, verified_intermediates.size()); | 
|  1533 } |   176 } | 
|  1534  |   177  | 
|  1535 // Test that the system root certificate keychain is in the expected location |   178 // Test that the system root certificate keychain is in the expected location | 
|  1536 // and can be opened. Other tests would fail if this was not true, but this |   179 // and can be opened. Other tests would fail if this was not true, but this | 
|  1537 // test makes the reason for the failure obvious. |   180 // test makes the reason for the failure obvious. | 
|  1538 TEST(CertVerifyProcMacTest, MacSystemRootCertificateKeychainLocation) { |   181 TEST(CertVerifyProcMacTest, MacSystemRootCertificateKeychainLocation) { | 
|  1539   const char* root_keychain_path = |   182   const char* root_keychain_path = | 
|  1540       "/System/Library/Keychains/SystemRootCertificates.keychain"; |   183       "/System/Library/Keychains/SystemRootCertificates.keychain"; | 
|  1541   ASSERT_TRUE(base::PathExists(base::FilePath(root_keychain_path))); |   184   ASSERT_TRUE(base::PathExists(base::FilePath(root_keychain_path))); | 
|  1542  |   185  | 
|  1543   SecKeychainRef keychain; |   186   SecKeychainRef keychain; | 
|  1544   OSStatus status = SecKeychainOpen(root_keychain_path, &keychain); |   187   OSStatus status = SecKeychainOpen(root_keychain_path, &keychain); | 
|  1545   ASSERT_EQ(errSecSuccess, status); |   188   ASSERT_EQ(errSecSuccess, status); | 
|  1546   CFRelease(keychain); |   189   CFRelease(keychain); | 
|  1547 } |   190 } | 
|  1548 #endif  // defined(OS_MACOSX) && !defined(OS_IOS) |  | 
|  1549  |   191  | 
|  1550 // TODO(crbug.com/649017): This is not parameterized by the CertVerifyProc |  | 
|  1551 // because the CertVerifyProc::Verify() does this unconditionally based on the |  | 
|  1552 // platform. |  | 
|  1553 bool AreSHA1IntermediatesAllowed() { |  | 
|  1554 #if defined(OS_WIN) |  | 
|  1555   // TODO(rsleevi): Remove this once https://crbug.com/588789 is resolved |  | 
|  1556   // for Windows 7/2008 users. |  | 
|  1557   // Note: This must be kept in sync with cert_verify_proc.cc |  | 
|  1558   return base::win::GetVersion() < base::win::VERSION_WIN8; |  | 
|  1559 #else |  | 
|  1560   return false; |  | 
|  1561 #endif |  | 
|  1562 } |  | 
|  1563  |  | 
|  1564 TEST(CertVerifyProcTest, RejectsMD2) { |  | 
|  1565   scoped_refptr<X509Certificate> cert( |  | 
|  1566       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  1567   ASSERT_TRUE(cert); |  | 
|  1568  |  | 
|  1569   CertVerifyResult result; |  | 
|  1570   result.has_md2 = true; |  | 
|  1571   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  1572  |  | 
|  1573   int flags = 0; |  | 
|  1574   CertVerifyResult verify_result; |  | 
|  1575   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1576                                   nullptr /* crl_set */, CertificateList(), |  | 
|  1577                                   &verify_result); |  | 
|  1578   EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); |  | 
|  1579   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); |  | 
|  1580 } |  | 
|  1581  |  | 
|  1582 TEST(CertVerifyProcTest, RejectsMD4) { |  | 
|  1583   scoped_refptr<X509Certificate> cert( |  | 
|  1584       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  1585   ASSERT_TRUE(cert); |  | 
|  1586  |  | 
|  1587   CertVerifyResult result; |  | 
|  1588   result.has_md4 = true; |  | 
|  1589   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  1590  |  | 
|  1591   int flags = 0; |  | 
|  1592   CertVerifyResult verify_result; |  | 
|  1593   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1594                                   nullptr /* crl_set */, CertificateList(), |  | 
|  1595                                   &verify_result); |  | 
|  1596   EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); |  | 
|  1597   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); |  | 
|  1598 } |  | 
|  1599  |  | 
|  1600 TEST(CertVerifyProcTest, RejectsMD5) { |  | 
|  1601   scoped_refptr<X509Certificate> cert( |  | 
|  1602       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  1603   ASSERT_TRUE(cert); |  | 
|  1604  |  | 
|  1605   CertVerifyResult result; |  | 
|  1606   result.has_md5 = true; |  | 
|  1607   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  1608  |  | 
|  1609   int flags = 0; |  | 
|  1610   CertVerifyResult verify_result; |  | 
|  1611   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1612                                   nullptr /* crl_set */, CertificateList(), |  | 
|  1613                                   &verify_result); |  | 
|  1614   EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); |  | 
|  1615   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM); |  | 
|  1616 } |  | 
|  1617  |  | 
|  1618 TEST(CertVerifyProcTest, RejectsPublicSHA1Leaves) { |  | 
|  1619   scoped_refptr<X509Certificate> cert( |  | 
|  1620       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  1621   ASSERT_TRUE(cert); |  | 
|  1622  |  | 
|  1623   CertVerifyResult result; |  | 
|  1624   result.has_sha1 = true; |  | 
|  1625   result.has_sha1_leaf = true; |  | 
|  1626   result.is_issued_by_known_root = true; |  | 
|  1627   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  1628  |  | 
|  1629   int flags = 0; |  | 
|  1630   CertVerifyResult verify_result; |  | 
|  1631   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1632                                   nullptr /* crl_set */, CertificateList(), |  | 
|  1633                                   &verify_result); |  | 
|  1634   EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); |  | 
|  1635   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_WEAK_SIGNATURE_ALGORITHM); |  | 
|  1636 } |  | 
|  1637  |  | 
|  1638 TEST(CertVerifyProcTest, RejectsPublicSHA1IntermediatesUnlessAllowed) { |  | 
|  1639   scoped_refptr<X509Certificate> cert(ImportCertFromFile( |  | 
|  1640       GetTestCertsDirectory(), "39_months_after_2015_04.pem")); |  | 
|  1641   ASSERT_TRUE(cert); |  | 
|  1642  |  | 
|  1643   CertVerifyResult result; |  | 
|  1644   result.has_sha1 = true; |  | 
|  1645   result.has_sha1_leaf = false; |  | 
|  1646   result.is_issued_by_known_root = true; |  | 
|  1647   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  1648  |  | 
|  1649   int flags = 0; |  | 
|  1650   CertVerifyResult verify_result; |  | 
|  1651   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1652                                   nullptr /* crl_set */, CertificateList(), |  | 
|  1653                                   &verify_result); |  | 
|  1654   if (AreSHA1IntermediatesAllowed()) { |  | 
|  1655     EXPECT_THAT(error, IsOk()); |  | 
|  1656     EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); |  | 
|  1657   } else { |  | 
|  1658     EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); |  | 
|  1659     EXPECT_TRUE(verify_result.cert_status & |  | 
|  1660                 CERT_STATUS_WEAK_SIGNATURE_ALGORITHM); |  | 
|  1661   } |  | 
|  1662 } |  | 
|  1663  |  | 
|  1664 TEST(CertVerifyProcTest, RejectsPrivateSHA1UnlessFlag) { |  | 
|  1665   scoped_refptr<X509Certificate> cert( |  | 
|  1666       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  1667   ASSERT_TRUE(cert); |  | 
|  1668  |  | 
|  1669   CertVerifyResult result; |  | 
|  1670   result.has_sha1 = true; |  | 
|  1671   result.has_sha1_leaf = true; |  | 
|  1672   result.is_issued_by_known_root = false; |  | 
|  1673   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  1674  |  | 
|  1675   // SHA-1 should be rejected by default for private roots... |  | 
|  1676   int flags = 0; |  | 
|  1677   CertVerifyResult verify_result; |  | 
|  1678   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1679                                   nullptr /* crl_set */, CertificateList(), |  | 
|  1680                                   &verify_result); |  | 
|  1681   EXPECT_THAT(error, IsError(ERR_CERT_WEAK_SIGNATURE_ALGORITHM)); |  | 
|  1682   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); |  | 
|  1683  |  | 
|  1684   // ... unless VERIFY_ENABLE_SHA1_LOCAL_ANCHORS was supplied. |  | 
|  1685   flags = CertVerifier::VERIFY_ENABLE_SHA1_LOCAL_ANCHORS; |  | 
|  1686   verify_result.Reset(); |  | 
|  1687   error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  1688                               nullptr /* crl_set */, CertificateList(), |  | 
|  1689                               &verify_result); |  | 
|  1690   EXPECT_THAT(error, IsOk()); |  | 
|  1691   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_SHA1_SIGNATURE_PRESENT); |  | 
|  1692 } |  | 
|  1693  |  | 
|  1694 enum ExpectedAlgorithms { |  | 
|  1695   EXPECT_MD2 = 1 << 0, |  | 
|  1696   EXPECT_MD4 = 1 << 1, |  | 
|  1697   EXPECT_MD5 = 1 << 2, |  | 
|  1698   EXPECT_SHA1 = 1 << 3, |  | 
|  1699   EXPECT_SHA1_LEAF = 1 << 4, |  | 
|  1700 }; |  | 
|  1701  |  | 
|  1702 struct WeakDigestTestData { |  | 
|  1703   const char* root_cert_filename; |  | 
|  1704   const char* intermediate_cert_filename; |  | 
|  1705   const char* ee_cert_filename; |  | 
|  1706   int expected_algorithms; |  | 
|  1707 }; |  | 
|  1708  |  | 
|  1709 const char* StringOrDefault(const char* str, const char* default_value) { |  | 
|  1710   if (!str) |  | 
|  1711     return default_value; |  | 
|  1712   return str; |  | 
|  1713 } |  | 
|  1714  |  | 
|  1715 // GTest 'magic' pretty-printer, so that if/when a test fails, it knows how |  | 
|  1716 // to output the parameter that was passed. Without this, it will simply |  | 
|  1717 // attempt to print out the first twenty bytes of the object, which depending |  | 
|  1718 // on platform and alignment, may result in an invalid read. |  | 
|  1719 void PrintTo(const WeakDigestTestData& data, std::ostream* os) { |  | 
|  1720   *os << "root: " << StringOrDefault(data.root_cert_filename, "none") |  | 
|  1721       << "; intermediate: " |  | 
|  1722       << StringOrDefault(data.intermediate_cert_filename, "none") |  | 
|  1723       << "; end-entity: " << data.ee_cert_filename; |  | 
|  1724 } |  | 
|  1725  |  | 
|  1726 class CertVerifyProcWeakDigestTest |  | 
|  1727     : public testing::TestWithParam<WeakDigestTestData> { |  | 
|  1728  public: |  | 
|  1729   CertVerifyProcWeakDigestTest() {} |  | 
|  1730   virtual ~CertVerifyProcWeakDigestTest() {} |  | 
|  1731 }; |  | 
|  1732  |  | 
|  1733 // Tests that the CertVerifyProc::Verify() properly surfaces the (weak) hash |  | 
|  1734 // algorithms used in the chain. |  | 
|  1735 TEST_P(CertVerifyProcWeakDigestTest, VerifyDetectsAlgorithm) { |  | 
|  1736   WeakDigestTestData data = GetParam(); |  | 
|  1737   base::FilePath certs_dir = GetTestCertsDirectory(); |  | 
|  1738  |  | 
|  1739   scoped_refptr<X509Certificate> intermediate_cert; |  | 
|  1740   scoped_refptr<X509Certificate> root_cert; |  | 
|  1741  |  | 
|  1742   // Build |intermediates| as the full chain (including trust anchor). |  | 
|  1743   X509Certificate::OSCertHandles intermediates; |  | 
|  1744  |  | 
|  1745   if (data.intermediate_cert_filename) { |  | 
|  1746     intermediate_cert = |  | 
|  1747         ImportCertFromFile(certs_dir, data.intermediate_cert_filename); |  | 
|  1748     ASSERT_TRUE(intermediate_cert); |  | 
|  1749     intermediates.push_back(intermediate_cert->os_cert_handle()); |  | 
|  1750   } |  | 
|  1751  |  | 
|  1752   if (data.root_cert_filename) { |  | 
|  1753     root_cert = ImportCertFromFile(certs_dir, data.root_cert_filename); |  | 
|  1754     ASSERT_TRUE(root_cert); |  | 
|  1755     intermediates.push_back(root_cert->os_cert_handle()); |  | 
|  1756   } |  | 
|  1757  |  | 
|  1758   scoped_refptr<X509Certificate> ee_cert = |  | 
|  1759       ImportCertFromFile(certs_dir, data.ee_cert_filename); |  | 
|  1760   ASSERT_TRUE(ee_cert); |  | 
|  1761  |  | 
|  1762   scoped_refptr<X509Certificate> ee_chain = X509Certificate::CreateFromHandle( |  | 
|  1763       ee_cert->os_cert_handle(), intermediates); |  | 
|  1764   ASSERT_TRUE(ee_chain); |  | 
|  1765  |  | 
|  1766   int flags = 0; |  | 
|  1767   CertVerifyResult verify_result; |  | 
|  1768  |  | 
|  1769   // Use a mock CertVerifyProc that returns success with a verified_cert of |  | 
|  1770   // |ee_chain|. |  | 
|  1771   // |  | 
|  1772   // This is sufficient for the purposes of this test, as the checking for weak |  | 
|  1773   // hash algorithms is done by CertVerifyProc::Verify(). |  | 
|  1774   scoped_refptr<CertVerifyProc> proc = |  | 
|  1775       new MockCertVerifyProc(CertVerifyResult()); |  | 
|  1776   proc->Verify(ee_chain.get(), "127.0.0.1", std::string(), flags, nullptr, |  | 
|  1777                CertificateList(), &verify_result); |  | 
|  1778   EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD2), verify_result.has_md2); |  | 
|  1779   EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD4), verify_result.has_md4); |  | 
|  1780   EXPECT_EQ(!!(data.expected_algorithms & EXPECT_MD5), verify_result.has_md5); |  | 
|  1781   EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1), verify_result.has_sha1); |  | 
|  1782   EXPECT_EQ(!!(data.expected_algorithms & EXPECT_SHA1_LEAF), |  | 
|  1783             verify_result.has_sha1_leaf); |  | 
|  1784 } |  | 
|  1785  |  | 
|  1786 // The signature algorithm of the root CA should not matter. |  | 
|  1787 const WeakDigestTestData kVerifyRootCATestData[] = { |  | 
|  1788     {"weak_digest_md5_root.pem", "weak_digest_sha1_intermediate.pem", |  | 
|  1789      "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1790     {"weak_digest_md4_root.pem", "weak_digest_sha1_intermediate.pem", |  | 
|  1791      "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1792     {"weak_digest_md2_root.pem", "weak_digest_sha1_intermediate.pem", |  | 
|  1793      "weak_digest_sha1_ee.pem", EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1794 }; |  | 
|  1795 INSTANTIATE_TEST_CASE_P(VerifyRoot, |  | 
|  1796                         CertVerifyProcWeakDigestTest, |  | 
|  1797                         testing::ValuesIn(kVerifyRootCATestData)); |  | 
|  1798  |  | 
|  1799 // The signature algorithm of intermediates should be properly detected. |  | 
|  1800 const WeakDigestTestData kVerifyIntermediateCATestData[] = { |  | 
|  1801     {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", |  | 
|  1802      "weak_digest_sha1_ee.pem", EXPECT_MD5 | EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1803     {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", |  | 
|  1804      "weak_digest_sha1_ee.pem", EXPECT_MD4 | EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1805     {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", |  | 
|  1806      "weak_digest_sha1_ee.pem", EXPECT_MD2 | EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1807 }; |  | 
|  1808  |  | 
|  1809 INSTANTIATE_TEST_CASE_P(VerifyIntermediate, |  | 
|  1810                         CertVerifyProcWeakDigestTest, |  | 
|  1811                         testing::ValuesIn(kVerifyIntermediateCATestData)); |  | 
|  1812  |  | 
|  1813 // The signature algorithm of end-entity should be properly detected. |  | 
|  1814 const WeakDigestTestData kVerifyEndEntityTestData[] = { |  | 
|  1815     {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", |  | 
|  1816      "weak_digest_md5_ee.pem", EXPECT_MD5 | EXPECT_SHA1}, |  | 
|  1817     {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", |  | 
|  1818      "weak_digest_md4_ee.pem", EXPECT_MD4 | EXPECT_SHA1}, |  | 
|  1819     {"weak_digest_sha1_root.pem", "weak_digest_sha1_intermediate.pem", |  | 
|  1820      "weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_SHA1}, |  | 
|  1821 }; |  | 
|  1822  |  | 
|  1823 INSTANTIATE_TEST_CASE_P(VerifyEndEntity, |  | 
|  1824                         CertVerifyProcWeakDigestTest, |  | 
|  1825                         testing::ValuesIn(kVerifyEndEntityTestData)); |  | 
|  1826  |  | 
|  1827 // Incomplete chains do not report the status of the intermediate. |  | 
|  1828 // Note: really each of these tests should also expect the digest algorithm of |  | 
|  1829 // the intermediate (included as a comment). However CertVerifyProc::Verify() is |  | 
|  1830 // unable to distinguish that this is an intermediate and not a trust anchor, so |  | 
|  1831 // this intermediate is treated like a trust anchor. |  | 
|  1832 const WeakDigestTestData kVerifyIncompleteIntermediateTestData[] = { |  | 
|  1833     {NULL, "weak_digest_md5_intermediate.pem", "weak_digest_sha1_ee.pem", |  | 
|  1834      /*EXPECT_MD5 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1835     {NULL, "weak_digest_md4_intermediate.pem", "weak_digest_sha1_ee.pem", |  | 
|  1836      /*EXPECT_MD4 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1837     {NULL, "weak_digest_md2_intermediate.pem", "weak_digest_sha1_ee.pem", |  | 
|  1838      /*EXPECT_MD2 |*/ EXPECT_SHA1 | EXPECT_SHA1_LEAF}, |  | 
|  1839 }; |  | 
|  1840  |  | 
|  1841 INSTANTIATE_TEST_CASE_P( |  | 
|  1842     MAYBE_VerifyIncompleteIntermediate, |  | 
|  1843     CertVerifyProcWeakDigestTest, |  | 
|  1844     testing::ValuesIn(kVerifyIncompleteIntermediateTestData)); |  | 
|  1845  |  | 
|  1846 // Incomplete chains should report the status of the end-entity. |  | 
|  1847 // Note: really each of these tests should also expect EXPECT_SHA1 (included as |  | 
|  1848 // a comment). However CertVerifyProc::Verify() is unable to distinguish that |  | 
|  1849 // this is an intermediate and not a trust anchor, so this intermediate is |  | 
|  1850 // treated like a trust anchor. |  | 
|  1851 const WeakDigestTestData kVerifyIncompleteEETestData[] = { |  | 
|  1852     {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md5_ee.pem", |  | 
|  1853      /*EXPECT_SHA1 |*/ EXPECT_MD5}, |  | 
|  1854     {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md4_ee.pem", |  | 
|  1855      /*EXPECT_SHA1 |*/ EXPECT_MD4}, |  | 
|  1856     {NULL, "weak_digest_sha1_intermediate.pem", "weak_digest_md2_ee.pem", |  | 
|  1857      /*EXPECT_SHA1 |*/ EXPECT_MD2}, |  | 
|  1858 }; |  | 
|  1859  |  | 
|  1860 INSTANTIATE_TEST_CASE_P(VerifyIncompleteEndEntity, |  | 
|  1861                         CertVerifyProcWeakDigestTest, |  | 
|  1862                         testing::ValuesIn(kVerifyIncompleteEETestData)); |  | 
|  1863  |  | 
|  1864 // Differing algorithms between the intermediate and the EE should still be |  | 
|  1865 // reported. |  | 
|  1866 const WeakDigestTestData kVerifyMixedTestData[] = { |  | 
|  1867     {"weak_digest_sha1_root.pem", "weak_digest_md5_intermediate.pem", |  | 
|  1868      "weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_MD5}, |  | 
|  1869     {"weak_digest_sha1_root.pem", "weak_digest_md2_intermediate.pem", |  | 
|  1870      "weak_digest_md5_ee.pem", EXPECT_MD2 | EXPECT_MD5}, |  | 
|  1871     {"weak_digest_sha1_root.pem", "weak_digest_md4_intermediate.pem", |  | 
|  1872      "weak_digest_md2_ee.pem", EXPECT_MD2 | EXPECT_MD4}, |  | 
|  1873 }; |  | 
|  1874  |  | 
|  1875 INSTANTIATE_TEST_CASE_P(VerifyMixed, |  | 
|  1876                         CertVerifyProcWeakDigestTest, |  | 
|  1877                         testing::ValuesIn(kVerifyMixedTestData)); |  | 
|  1878  |  | 
|  1879 // The EE is a trusted certificate. Even though it uses weak hashes, these |  | 
|  1880 // should not be reported. |  | 
|  1881 const WeakDigestTestData kVerifyTrustedEETestData[] = { |  | 
|  1882     {NULL, NULL, "weak_digest_md5_ee.pem", 0}, |  | 
|  1883     {NULL, NULL, "weak_digest_md4_ee.pem", 0}, |  | 
|  1884     {NULL, NULL, "weak_digest_md2_ee.pem", 0}, |  | 
|  1885     {NULL, NULL, "weak_digest_sha1_ee.pem", 0}, |  | 
|  1886 }; |  | 
|  1887  |  | 
|  1888 INSTANTIATE_TEST_CASE_P(VerifyTrustedEE, |  | 
|  1889                         CertVerifyProcWeakDigestTest, |  | 
|  1890                         testing::ValuesIn(kVerifyTrustedEETestData)); |  | 
|  1891  |  | 
|  1892 // For the list of valid hostnames, see |  | 
|  1893 // net/cert/data/ssl/certificates/subjectAltName_sanity_check.pem |  | 
|  1894 struct CertVerifyProcNameData { |  | 
|  1895   const char* hostname; |  | 
|  1896   bool valid;  // Whether or not |hostname| matches a subjectAltName. |  | 
|  1897 }; |  | 
|  1898  |  | 
|  1899 // Test fixture for verifying certificate names. These tests are run for each |  | 
|  1900 // of the CertVerify implementations. |  | 
|  1901 class CertVerifyProcNameTest : public CertVerifyProcInternalTest { |  | 
|  1902  public: |  | 
|  1903   CertVerifyProcNameTest() {} |  | 
|  1904   virtual ~CertVerifyProcNameTest() {} |  | 
|  1905  |  | 
|  1906  protected: |  | 
|  1907   void VerifyCertName(const char* hostname, bool valid) { |  | 
|  1908     CertificateList cert_list = CreateCertificateListFromFile( |  | 
|  1909         GetTestCertsDirectory(), "subjectAltName_sanity_check.pem", |  | 
|  1910         X509Certificate::FORMAT_AUTO); |  | 
|  1911     ASSERT_EQ(1U, cert_list.size()); |  | 
|  1912     scoped_refptr<X509Certificate> cert(cert_list[0]); |  | 
|  1913  |  | 
|  1914     ScopedTestRoot scoped_root(cert.get()); |  | 
|  1915  |  | 
|  1916     CertVerifyResult verify_result; |  | 
|  1917     int error = Verify(cert.get(), hostname, 0, NULL, CertificateList(), |  | 
|  1918                        &verify_result); |  | 
|  1919     if (valid) { |  | 
|  1920       EXPECT_THAT(error, IsOk()); |  | 
|  1921       EXPECT_FALSE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID); |  | 
|  1922     } else { |  | 
|  1923       EXPECT_THAT(error, IsError(ERR_CERT_COMMON_NAME_INVALID)); |  | 
|  1924       EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_COMMON_NAME_INVALID); |  | 
|  1925     } |  | 
|  1926   } |  | 
|  1927 }; |  | 
|  1928  |  | 
|  1929 // Don't match the common name |  | 
|  1930 TEST_P(CertVerifyProcNameTest, DontMatchCommonName) { |  | 
|  1931   VerifyCertName("127.0.0.1", false); |  | 
|  1932 } |  | 
|  1933  |  | 
|  1934 // Matches the iPAddress SAN (IPv4) |  | 
|  1935 TEST_P(CertVerifyProcNameTest, MatchesIpSanIpv4) { |  | 
|  1936   VerifyCertName("127.0.0.2", true); |  | 
|  1937 } |  | 
|  1938  |  | 
|  1939 // Matches the iPAddress SAN (IPv6) |  | 
|  1940 TEST_P(CertVerifyProcNameTest, MatchesIpSanIpv6) { |  | 
|  1941   VerifyCertName("FE80:0:0:0:0:0:0:1", true); |  | 
|  1942 } |  | 
|  1943  |  | 
|  1944 // Should not match the iPAddress SAN |  | 
|  1945 TEST_P(CertVerifyProcNameTest, DoesntMatchIpSanIpv6) { |  | 
|  1946   VerifyCertName("[FE80:0:0:0:0:0:0:1]", false); |  | 
|  1947 } |  | 
|  1948  |  | 
|  1949 // Compressed form matches the iPAddress SAN (IPv6) |  | 
|  1950 TEST_P(CertVerifyProcNameTest, MatchesIpSanCompressedIpv6) { |  | 
|  1951   VerifyCertName("FE80::1", true); |  | 
|  1952 } |  | 
|  1953  |  | 
|  1954 // IPv6 mapped form should NOT match iPAddress SAN |  | 
|  1955 TEST_P(CertVerifyProcNameTest, DoesntMatchIpSanIPv6Mapped) { |  | 
|  1956   VerifyCertName("::127.0.0.2", false); |  | 
|  1957 } |  | 
|  1958  |  | 
|  1959 // Matches the dNSName SAN |  | 
|  1960 TEST_P(CertVerifyProcNameTest, MatchesDnsSan) { |  | 
|  1961   VerifyCertName("test.example", true); |  | 
|  1962 } |  | 
|  1963  |  | 
|  1964 // Matches the dNSName SAN (trailing . ignored) |  | 
|  1965 TEST_P(CertVerifyProcNameTest, MatchesDnsSanTrailingDot) { |  | 
|  1966   VerifyCertName("test.example.", true); |  | 
|  1967 } |  | 
|  1968  |  | 
|  1969 // Should not match the dNSName SAN |  | 
|  1970 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSan) { |  | 
|  1971   VerifyCertName("www.test.example", false); |  | 
|  1972 } |  | 
|  1973  |  | 
|  1974 // Should not match the dNSName SAN |  | 
|  1975 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanInvalid) { |  | 
|  1976   VerifyCertName("test..example", false); |  | 
|  1977 } |  | 
|  1978  |  | 
|  1979 // Should not match the dNSName SAN |  | 
|  1980 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanTwoTrailingDots) { |  | 
|  1981   VerifyCertName("test.example..", false); |  | 
|  1982 } |  | 
|  1983  |  | 
|  1984 // Should not match the dNSName SAN |  | 
|  1985 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanLeadingAndTrailingDot) { |  | 
|  1986   VerifyCertName(".test.example.", false); |  | 
|  1987 } |  | 
|  1988  |  | 
|  1989 // Should not match the dNSName SAN |  | 
|  1990 TEST_P(CertVerifyProcNameTest, DoesntMatchDnsSanTrailingDot) { |  | 
|  1991   VerifyCertName(".test.example", false); |  | 
|  1992 } |  | 
|  1993  |  | 
|  1994 INSTANTIATE_TEST_CASE_P(VerifyName, |  | 
|  1995                         CertVerifyProcNameTest, |  | 
|  1996                         testing::ValuesIn(kAllCertVerifiers), |  | 
|  1997                         VerifyProcTypeToName); |  | 
|  1998  |  | 
|  1999 #if defined(OS_MACOSX) && !defined(OS_IOS) |  | 
|  2000 // Test that CertVerifyProcMac reacts appropriately when Apple's certificate |   192 // Test that CertVerifyProcMac reacts appropriately when Apple's certificate | 
|  2001 // verifier rejects a certificate with a fatal error. This is a regression |   193 // verifier rejects a certificate with a fatal error. This is a regression | 
|  2002 // test for https://crbug.com/472291. |   194 // test for https://crbug.com/472291. | 
|  2003 // (Since 10.12, this causes a recoverable error instead of a fatal one.) |   195 // (Since 10.12, this causes a recoverable error instead of a fatal one.) | 
|  2004 // TODO(mattm): Try to find a different way to cause a fatal error that works |   196 // TODO(mattm): Try to find a different way to cause a fatal error that works | 
|  2005 // on 10.12. |   197 // on 10.12. | 
|  2006 TEST(CertVerifyProcMacTest, LargeKey) { |   198 TEST(CertVerifyProcMacTest, LargeKey) { | 
|  2007   // Load root_ca_cert.pem into the test root store. |   199   // Load root_ca_cert.pem into the test root store. | 
|  2008   ScopedTestRoot test_root( |   200   ScopedTestRoot test_root( | 
|  2009       ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get()); |   201       ImportCertFromFile(GetTestCertsDirectory(), "root_ca_cert.pem").get()); | 
|  2010  |   202  | 
|  2011   scoped_refptr<X509Certificate> cert( |   203   scoped_refptr<X509Certificate> cert( | 
|  2012       ImportCertFromFile(GetTestCertsDirectory(), "large_key.pem")); |   204       ImportCertFromFile(GetTestCertsDirectory(), "large_key.pem")); | 
|  2013  |   205  | 
|  2014   // Apple's verifier rejects this certificate as invalid because the |   206   // Apple's verifier rejects this certificate as invalid because the | 
|  2015   // RSA key is too large. If a future version of OS X changes this, |   207   // RSA key is too large. If a future version of OS X changes this, | 
|  2016   // large_key.pem may need to be regenerated with a larger key. |   208   // large_key.pem may need to be regenerated with a larger key. | 
|  2017   int flags = 0; |   209   int flags = 0; | 
|  2018   CertVerifyResult verify_result; |   210   CertVerifyResult verify_result; | 
|  2019   scoped_refptr<CertVerifyProc> verify_proc = CertVerifyProc::CreateDefault(); |   211   scoped_refptr<CertVerifyProc> verify_proc = new CertVerifyProcMac; | 
|  2020   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |   212   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, | 
|  2021                                   NULL, CertificateList(), &verify_result); |   213                                   NULL, CertificateList(), &verify_result); | 
|  2022   EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); |   214   EXPECT_THAT(error, IsError(ERR_CERT_INVALID)); | 
|  2023   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); |   215   EXPECT_TRUE(verify_result.cert_status & CERT_STATUS_INVALID); | 
|  2024 } |   216 } | 
|  2025 #endif  // defined(OS_MACOSX) && !defined(OS_IOS) |  | 
|  2026  |   217  | 
|  2027 // Tests that CertVerifyProc records a histogram correctly when a |   218 }  // namespace | 
|  2028 // certificate chaining to a private root contains the TLS feature |  | 
|  2029 // extension and does not have a stapled OCSP response. |  | 
|  2030 TEST(CertVerifyProcTest, HasTLSFeatureExtensionUMA) { |  | 
|  2031   base::HistogramTester histograms; |  | 
|  2032   scoped_refptr<X509Certificate> cert( |  | 
|  2033       ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem")); |  | 
|  2034   ASSERT_TRUE(cert); |  | 
|  2035   CertVerifyResult result; |  | 
|  2036   result.is_issued_by_known_root = false; |  | 
|  2037   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  2038  |  | 
|  2039   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0); |  | 
|  2040   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0); |  | 
|  2041  |  | 
|  2042   int flags = 0; |  | 
|  2043   CertVerifyResult verify_result; |  | 
|  2044   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  2045                                   NULL, CertificateList(), &verify_result); |  | 
|  2046   EXPECT_EQ(OK, error); |  | 
|  2047   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1); |  | 
|  2048   histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, true, 1); |  | 
|  2049   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 1); |  | 
|  2050   histograms.ExpectBucketCount(kTLSFeatureExtensionOCSPHistogram, false, 1); |  | 
|  2051 } |  | 
|  2052  |  | 
|  2053 // Tests that CertVerifyProc records a histogram correctly when a |  | 
|  2054 // certificate chaining to a private root contains the TLS feature |  | 
|  2055 // extension and does have a stapled OCSP response. |  | 
|  2056 TEST(CertVerifyProcTest, HasTLSFeatureExtensionWithStapleUMA) { |  | 
|  2057   base::HistogramTester histograms; |  | 
|  2058   scoped_refptr<X509Certificate> cert( |  | 
|  2059       ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem")); |  | 
|  2060   ASSERT_TRUE(cert); |  | 
|  2061   CertVerifyResult result; |  | 
|  2062   result.is_issued_by_known_root = false; |  | 
|  2063   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  2064  |  | 
|  2065   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0); |  | 
|  2066   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0); |  | 
|  2067  |  | 
|  2068   int flags = 0; |  | 
|  2069   CertVerifyResult verify_result; |  | 
|  2070   int error = |  | 
|  2071       verify_proc->Verify(cert.get(), "127.0.0.1", "dummy response", flags, |  | 
|  2072                           nullptr, CertificateList(), &verify_result); |  | 
|  2073   EXPECT_EQ(OK, error); |  | 
|  2074   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1); |  | 
|  2075   histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, true, 1); |  | 
|  2076   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 1); |  | 
|  2077   histograms.ExpectBucketCount(kTLSFeatureExtensionOCSPHistogram, true, 1); |  | 
|  2078 } |  | 
|  2079  |  | 
|  2080 // Tests that CertVerifyProc records a histogram correctly when a |  | 
|  2081 // certificate chaining to a private root does not contain the TLS feature |  | 
|  2082 // extension. |  | 
|  2083 TEST(CertVerifyProcTest, DoesNotHaveTLSFeatureExtensionUMA) { |  | 
|  2084   base::HistogramTester histograms; |  | 
|  2085   scoped_refptr<X509Certificate> cert( |  | 
|  2086       ImportCertFromFile(GetTestCertsDirectory(), "ok_cert.pem")); |  | 
|  2087   ASSERT_TRUE(cert); |  | 
|  2088   CertVerifyResult result; |  | 
|  2089   result.is_issued_by_known_root = false; |  | 
|  2090   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  2091  |  | 
|  2092   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0); |  | 
|  2093   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0); |  | 
|  2094  |  | 
|  2095   int flags = 0; |  | 
|  2096   CertVerifyResult verify_result; |  | 
|  2097   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  2098                                   NULL, CertificateList(), &verify_result); |  | 
|  2099   EXPECT_EQ(OK, error); |  | 
|  2100   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 1); |  | 
|  2101   histograms.ExpectBucketCount(kTLSFeatureExtensionHistogram, false, 1); |  | 
|  2102   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0); |  | 
|  2103 } |  | 
|  2104  |  | 
|  2105 // Tests that CertVerifyProc does not record a histogram when a |  | 
|  2106 // certificate contains the TLS feature extension but chains to a public |  | 
|  2107 // root. |  | 
|  2108 TEST(CertVerifyProcTest, HasTLSFeatureExtensionWithPublicRootUMA) { |  | 
|  2109   base::HistogramTester histograms; |  | 
|  2110   scoped_refptr<X509Certificate> cert( |  | 
|  2111       ImportCertFromFile(GetTestCertsDirectory(), "tls_feature_extension.pem")); |  | 
|  2112   ASSERT_TRUE(cert); |  | 
|  2113   CertVerifyResult result; |  | 
|  2114   result.is_issued_by_known_root = true; |  | 
|  2115   scoped_refptr<CertVerifyProc> verify_proc = new MockCertVerifyProc(result); |  | 
|  2116  |  | 
|  2117   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0); |  | 
|  2118  |  | 
|  2119   int flags = 0; |  | 
|  2120   CertVerifyResult verify_result; |  | 
|  2121   int error = verify_proc->Verify(cert.get(), "127.0.0.1", std::string(), flags, |  | 
|  2122                                   NULL, CertificateList(), &verify_result); |  | 
|  2123   EXPECT_EQ(OK, error); |  | 
|  2124   histograms.ExpectTotalCount(kTLSFeatureExtensionHistogram, 0); |  | 
|  2125   histograms.ExpectTotalCount(kTLSFeatureExtensionOCSPHistogram, 0); |  | 
|  2126 } |  | 
|  2127  |   219  | 
|  2128 }  // namespace net |   220 }  // namespace net | 
| OLD | NEW |