blob: 4cd4619a3355da9126cb148ee2175bcbddc8ba76 [file] [log] [blame]
// Copyright 2019 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "content/public/test/signed_exchange_browser_test_helper.h"
#include <memory>
#include "base/files/file_path.h"
#include "base/path_service.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/thread_restrictions.h"
#include "content/browser/web_package/signed_exchange_handler.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_paths.h"
#include "content/public/test/browser_test_utils.h"
#include "net/cert/cert_verify_result.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/test/cert_test_util.h"
#include "net/test/url_request/url_request_mock_http_job.h"
#include "net/url_request/url_request_filter.h"
#include "services/network/public/cpp/features.h"
namespace content {
constexpr uint64_t SignedExchangeBrowserTestHelper::kSignatureHeaderDate =
1520834000; // 2018-03-12T05:53:20Z
constexpr uint64_t SignedExchangeBrowserTestHelper::kSignatureHeaderExpires =
1520837600; // 2018-03-12T06:53:20Z
SignedExchangeBrowserTestHelper::SignedExchangeBrowserTestHelper() = default;
SignedExchangeBrowserTestHelper::~SignedExchangeBrowserTestHelper() = default;
void SignedExchangeBrowserTestHelper::SetUp() {
SignedExchangeHandler::SetVerificationTimeForTesting(
base::Time::UnixEpoch() +
base::TimeDelta::FromSeconds(kSignatureHeaderDate));
}
void SignedExchangeBrowserTestHelper::TearDownOnMainThread() {
interceptor_.reset();
SignedExchangeHandler::SetVerificationTimeForTesting(
base::Optional<base::Time>());
}
scoped_refptr<net::X509Certificate>
SignedExchangeBrowserTestHelper::LoadCertificate() {
constexpr char kCertFileName[] = "prime256v1-sha256.public.pem";
base::ScopedAllowBlockingForTesting allow_io;
base::FilePath dir_path;
base::PathService::Get(content::DIR_TEST_DATA, &dir_path);
dir_path = dir_path.Append(FILE_PATH_LITERAL("sxg"));
return net::CreateCertificateChainFromFile(
dir_path, kCertFileName, net::X509Certificate::FORMAT_PEM_CERT_SEQUENCE);
}
void SignedExchangeBrowserTestHelper::InstallUrlInterceptor(
const GURL& url,
const std::string& data_path) {
if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
if (!interceptor_) {
interceptor_ = std::make_unique<URLLoaderInterceptor>(base::BindRepeating(
&SignedExchangeBrowserTestHelper::OnInterceptCallback,
base::Unretained(this)));
}
interceptor_data_path_map_[url] = data_path;
} else {
base::PostTaskWithTraits(
FROM_HERE, {BrowserThread::IO},
base::BindOnce(&InstallMockInterceptors, url, data_path));
}
}
void SignedExchangeBrowserTestHelper::InstallMockCert(
content::ContentMockCertVerifier::CertVerifier* cert_verifier) {
// Make the MockCertVerifier treat the certificate
// "prime256v1-sha256.public.pem" as valid for "test.example.org".
scoped_refptr<net::X509Certificate> original_cert = LoadCertificate();
net::CertVerifyResult dummy_result;
dummy_result.verified_cert = original_cert;
dummy_result.cert_status = net::OK;
dummy_result.ocsp_result.response_status = net::OCSPVerifyResult::PROVIDED;
dummy_result.ocsp_result.revocation_status = net::OCSPRevocationStatus::GOOD;
cert_verifier->AddResultForCertAndHost(original_cert, "test.example.org",
dummy_result, net::OK);
}
void SignedExchangeBrowserTestHelper::InstallMockCertChainInterceptor() {
InstallUrlInterceptor(
GURL("https://cert.example.org/cert.msg"),
"content/test/data/sxg/test.example.org.public.pem.cbor");
}
void SignedExchangeBrowserTestHelper::InstallMockInterceptors(
const GURL& url,
const std::string& data_path) {
base::FilePath root_path;
CHECK(base::PathService::Get(base::DIR_SOURCE_ROOT, &root_path));
net::URLRequestFilter::GetInstance()->AddUrlInterceptor(
url, net::URLRequestMockHTTPJob::CreateInterceptorForSingleFile(
root_path.AppendASCII(data_path)));
}
bool SignedExchangeBrowserTestHelper::OnInterceptCallback(
URLLoaderInterceptor::RequestParams* params) {
const auto it = interceptor_data_path_map_.find(params->url_request.url);
if (it == interceptor_data_path_map_.end())
return false;
URLLoaderInterceptor::WriteResponse(it->second, params->client.get());
return true;
}
} // namespace content