1 // Copyright 2019 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "content/public/test/signed_exchange_browser_test_helper.h"
6 
7 #include <memory>
8 
9 #include "base/files/file_path.h"
10 #include "base/path_service.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/task/post_task.h"
13 #include "base/threading/thread_restrictions.h"
14 #include "content/browser/web_package/signed_exchange_utils.h"
15 #include "content/public/browser/browser_task_traits.h"
16 #include "content/public/browser/browser_thread.h"
17 #include "content/public/common/content_features.h"
18 #include "content/public/common/content_paths.h"
19 #include "content/public/test/browser_test_utils.h"
20 #include "net/cert/cert_verify_result.h"
21 #include "net/cert/mock_cert_verifier.h"
22 #include "net/dns/mock_host_resolver.h"
23 #include "net/test/cert_test_util.h"
24 
25 namespace content {
26 
27 constexpr uint64_t SignedExchangeBrowserTestHelper::kSignatureHeaderDate =
28     1564272000;  // 2019-07-28T00:00:00Z
29 constexpr uint64_t SignedExchangeBrowserTestHelper::kSignatureHeaderExpires =
30     1564876800;  // 2019-08-04T00:00:00Z
31 
32 SignedExchangeBrowserTestHelper::SignedExchangeBrowserTestHelper() = default;
33 
34 SignedExchangeBrowserTestHelper::~SignedExchangeBrowserTestHelper() = default;
35 
SetUp()36 void SignedExchangeBrowserTestHelper::SetUp() {
37   signed_exchange_utils::SetVerificationTimeForTesting(
38       base::Time::UnixEpoch() +
39       base::TimeDelta::FromSeconds(kSignatureHeaderDate));
40 }
41 
TearDownOnMainThread()42 void SignedExchangeBrowserTestHelper::TearDownOnMainThread() {
43   interceptor_.reset();
44   signed_exchange_utils::SetVerificationTimeForTesting(
45       base::Optional<base::Time>());
46 }
47 
48 scoped_refptr<net::X509Certificate>
LoadCertificate()49 SignedExchangeBrowserTestHelper::LoadCertificate() {
50   constexpr char kCertFileName[] = "prime256v1-sha256.public.pem";
51 
52   base::ScopedAllowBlockingForTesting allow_io;
53   base::FilePath dir_path;
54   base::PathService::Get(content::DIR_TEST_DATA, &dir_path);
55   dir_path = dir_path.Append(FILE_PATH_LITERAL("sxg"));
56 
57   return net::CreateCertificateChainFromFile(
58       dir_path, kCertFileName, net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
59 }
60 
InstallUrlInterceptor(const GURL & url,const std::string & data_path)61 void SignedExchangeBrowserTestHelper::InstallUrlInterceptor(
62     const GURL& url,
63     const std::string& data_path) {
64   if (!interceptor_) {
65     interceptor_ = std::make_unique<URLLoaderInterceptor>(base::BindRepeating(
66         &SignedExchangeBrowserTestHelper::OnInterceptCallback,
67         base::Unretained(this)));
68   }
69   interceptor_data_path_map_[url] = data_path;
70 }
71 
InstallMockCert(content::ContentMockCertVerifier::CertVerifier * cert_verifier)72 void SignedExchangeBrowserTestHelper::InstallMockCert(
73     content::ContentMockCertVerifier::CertVerifier* cert_verifier) {
74   // Make the MockCertVerifier treat the certificate
75   // "prime256v1-sha256.public.pem" as valid for "test.example.org".
76   scoped_refptr<net::X509Certificate> original_cert = LoadCertificate();
77   net::CertVerifyResult dummy_result;
78   dummy_result.verified_cert = original_cert;
79   dummy_result.cert_status = net::OK;
80   dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
81   dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
82   cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
83                                          dummy_result, net::OK);
84 }
85 
InstallMockCertChainInterceptor()86 void SignedExchangeBrowserTestHelper::InstallMockCertChainInterceptor() {
87   InstallUrlInterceptor(
88       GURL("https://cert.example.org/cert.msg"),
89       "content/test/data/sxg/test.example.org.public.pem.cbor");
90 }
91 
OnInterceptCallback(URLLoaderInterceptor::RequestParams * params)92 bool SignedExchangeBrowserTestHelper::OnInterceptCallback(
93     URLLoaderInterceptor::RequestParams* params) {
94   const auto it = interceptor_data_path_map_.find(params->url_request.url);
95   if (it == interceptor_data_path_map_.end())
96     return false;
97   URLLoaderInterceptor::WriteResponse(it->second, params->client.get());
98   return true;
99 }
100 
101 }  // namespace content
102