Commit 4912926d authored by Tsuyoshi Horo's avatar Tsuyoshi Horo Committed by Commit Bot

Support data URL for cert-url of Signed HTTP Exchange.

Data URL for cert-url had been supported.
But after crrev.com/c/1577483 which landed in 76.0.3774.0, Chrome failes
to load the data URL when NetworkService is enabled.

To fix this issue, this CL change SignedExchangeCertFetcher to use
DataURLLoaderFactory when the cert-url's scheme is "data:".

Bug: 966736,939871
Change-Id: I352caf29e54f288371f18266597f5374ab7ca2bf
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1628488Reviewed-by: default avatarKunihiko Sakamoto <ksakamoto@chromium.org>
Reviewed-by: default avatarKinuko Yasuda <kinuko@chromium.org>
Commit-Queue: Tsuyoshi Horo <horo@chromium.org>
Cr-Commit-Position: refs/heads/master@{#662980}
parent 5c925bda
...@@ -5,17 +5,20 @@ ...@@ -5,17 +5,20 @@
#include "content/browser/web_package/signed_exchange_cert_fetcher.h" #include "content/browser/web_package/signed_exchange_cert_fetcher.h"
#include "base/bind.h" #include "base/bind.h"
#include "base/feature_list.h"
#include "base/format_macros.h" #include "base/format_macros.h"
#include "base/metrics/histogram_macros.h" #include "base/metrics/histogram_macros.h"
#include "base/numerics/safe_conversions.h" #include "base/numerics/safe_conversions.h"
#include "base/strings/string_piece.h" #include "base/strings/string_piece.h"
#include "base/strings/stringprintf.h" #include "base/strings/stringprintf.h"
#include "base/trace_event/trace_event.h" #include "base/trace_event/trace_event.h"
#include "content/browser/data_url_loader_factory.h"
#include "content/browser/loader/resource_dispatcher_host_impl.h" #include "content/browser/loader/resource_dispatcher_host_impl.h"
#include "content/browser/web_package/signed_exchange_consts.h" #include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_devtools_proxy.h" #include "content/browser/web_package/signed_exchange_devtools_proxy.h"
#include "content/browser/web_package/signed_exchange_reporter.h" #include "content/browser/web_package/signed_exchange_reporter.h"
#include "content/browser/web_package/signed_exchange_utils.h" #include "content/browser/web_package/signed_exchange_utils.h"
#include "content/common/single_request_url_loader_factory.h"
#include "content/common/throttling_url_loader.h" #include "content/common/throttling_url_loader.h"
#include "content/public/common/resource_type.h" #include "content/public/common/resource_type.h"
#include "content/public/common/url_loader_throttle.h" #include "content/public/common/url_loader_throttle.h"
...@@ -25,6 +28,7 @@ ...@@ -25,6 +28,7 @@
#include "net/base/load_flags.h" #include "net/base/load_flags.h"
#include "net/http/http_status_code.h" #include "net/http/http_status_code.h"
#include "services/network/loader_util.h" #include "services/network/loader_util.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/shared_url_loader_factory.h" #include "services/network/public/cpp/shared_url_loader_factory.h"
namespace content { namespace content {
...@@ -139,6 +143,15 @@ void SignedExchangeCertFetcher::Start() { ...@@ -139,6 +143,15 @@ void SignedExchangeCertFetcher::Start() {
devtools_proxy_->CertificateRequestSent(*cert_request_id_, devtools_proxy_->CertificateRequestSent(*cert_request_id_,
*resource_request_); *resource_request_);
} }
// When NetworkService enabled, data URL is not handled by the passed
// URLRequestContext's SharedURLLoaderFactory.
if (base::FeatureList::IsEnabled(network::features::kNetworkService) &&
resource_request_->url.SchemeIs(url::kDataScheme)) {
shared_url_loader_factory_ =
base::MakeRefCounted<SingleRequestURLLoaderFactory>(
base::BindOnce(&SignedExchangeCertFetcher::OnDataURLRequest,
base::Unretained(this)));
}
url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart( url_loader_ = ThrottlingURLLoader::CreateLoaderAndStart(
std::move(shared_url_loader_factory_), std::move(throttles_), std::move(shared_url_loader_factory_), std::move(throttles_),
0 /* routing_id */, 0 /* routing_id */,
...@@ -318,6 +331,17 @@ void SignedExchangeCertFetcher::OnComplete( ...@@ -318,6 +331,17 @@ void SignedExchangeCertFetcher::OnComplete(
Abort(); Abort();
} }
void SignedExchangeCertFetcher::OnDataURLRequest(
const network::ResourceRequest& resource_request,
network::mojom::URLLoaderRequest url_loader_request,
network::mojom::URLLoaderClientPtr url_loader_client_ptr) {
data_url_loader_factory_ = std::make_unique<DataURLLoaderFactory>();
data_url_loader_factory_->CreateLoaderAndStart(
std::move(url_loader_request), 0, 0, 0, resource_request,
std::move(url_loader_client_ptr),
net::MutableNetworkTrafficAnnotationTag(kCertFetcherTrafficAnnotation));
}
void SignedExchangeCertFetcher::MaybeNotifyCompletionToDevtools( void SignedExchangeCertFetcher::MaybeNotifyCompletionToDevtools(
const network::URLLoaderCompletionStatus& status) { const network::URLLoaderCompletionStatus& status) {
if (!devtools_proxy_ || has_notified_completion_to_devtools_) if (!devtools_proxy_ || has_notified_completion_to_devtools_)
......
...@@ -20,6 +20,9 @@ ...@@ -20,6 +20,9 @@
namespace network { namespace network {
class SharedURLLoaderFactory; class SharedURLLoaderFactory;
namespace mojom {
class URLLoaderFactory;
} // namespace mojom
} // namespace network } // namespace network
namespace mojo { namespace mojo {
...@@ -100,6 +103,10 @@ class CONTENT_EXPORT SignedExchangeCertFetcher ...@@ -100,6 +103,10 @@ class CONTENT_EXPORT SignedExchangeCertFetcher
mojo::ScopedDataPipeConsumerHandle body) override; mojo::ScopedDataPipeConsumerHandle body) override;
void OnComplete(const network::URLLoaderCompletionStatus& status) override; void OnComplete(const network::URLLoaderCompletionStatus& status) override;
void OnDataURLRequest(const network::ResourceRequest& resource_request,
network::mojom::URLLoaderRequest,
network::mojom::URLLoaderClientPtr);
scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_; scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
std::vector<std::unique_ptr<URLLoaderThrottle>> throttles_; std::vector<std::unique_ptr<URLLoaderThrottle>> throttles_;
std::unique_ptr<network::ResourceRequest> resource_request_; std::unique_ptr<network::ResourceRequest> resource_request_;
...@@ -118,6 +125,8 @@ class CONTENT_EXPORT SignedExchangeCertFetcher ...@@ -118,6 +125,8 @@ class CONTENT_EXPORT SignedExchangeCertFetcher
SignedExchangeReporter* reporter_; SignedExchangeReporter* reporter_;
base::Optional<base::UnguessableToken> cert_request_id_; base::Optional<base::UnguessableToken> cert_request_id_;
std::unique_ptr<network::mojom::URLLoaderFactory> data_url_loader_factory_;
DISALLOW_COPY_AND_ASSIGN(SignedExchangeCertFetcher); DISALLOW_COPY_AND_ASSIGN(SignedExchangeCertFetcher);
}; };
......
...@@ -28,6 +28,10 @@ tmpdir=$(mktemp -d) ...@@ -28,6 +28,10 @@ tmpdir=$(mktemp -d)
echo -n OCSP >$tmpdir/ocsp echo -n OCSP >$tmpdir/ocsp
gen-certurl -pem $certfile -ocsp $tmpdir/ocsp > $certfile.cbor gen-certurl -pem $certfile -ocsp $tmpdir/ocsp > $certfile.cbor
cert_base64=$(base64 -w 0 $certfile.cbor)
data_cert_url="data:application/cert-chain+cbor;base64,$cert_base64"
# A valid Signed Exchange. # A valid Signed Exchange.
gen-signedexchange \ gen-signedexchange \
-version $sxg_version \ -version $sxg_version \
...@@ -516,4 +520,19 @@ gen-signedexchange \ ...@@ -516,4 +520,19 @@ gen-signedexchange \
-o sxg/register-sw-after-fallback.sxg \ -o sxg/register-sw-after-fallback.sxg \
-miRecordSize 100 -miRecordSize 100
# A valid Signed Exchange using data URL for cert-url.
gen-signedexchange \
-version $sxg_version \
-uri $inner_url_origin/signed-exchange/resources/inner-url.html \
-status 200 \
-content sxg-location.html \
-certificate $certfile \
-certUrl $data_cert_url \
-validityUrl $inner_url_origin/signed-exchange/resources/resource.validity.msg \
-privateKey $keyfile \
-date 2018-04-01T00:00:00Z \
-expire 168h \
-o sxg/sxg-data-cert-url.sxg \
-miRecordSize 100
rm -fr $tmpdir rm -fr $tmpdir
<!DOCTYPE html>
<title>SignedHTTPExchange using data URL for cert-url</title>
<script src="/resources/testharness.js"></script>
<script src="/resources/testharnessreport.js"></script>
<script src="/common/get-host-info.sub.js"></script>
<script src="./resources/sxg-util.js"></script>
<body>
<script>
promise_test(async (t) => {
const sxgUrl = get_host_info().HTTPS_ORIGIN + '/signed-exchange/resources/sxg/sxg-data-cert-url.sxg';
const message = await openSXGInIframeAndWaitForMessage(t, sxgUrl);
assert_equals(message.location, innerURLOrigin() + '/signed-exchange/resources/inner-url.html');
assert_false(message.is_fallback);
}, 'SignedHTTPExchange using data URL for cert-url');
</script>
</body>
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment