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