network_service_allow_remote_certificate_verification_logic.patch 8.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
  2. From: Jeremy Apthorp <[email protected]>
  3. Date: Wed, 8 May 2019 17:25:55 -0700
  4. Subject: network_service_allow_remote_certificate_verification_logic.patch
  5. This adds a callback from the network service that's used to implement
  6. session.setCertificateVerifyCallback.
  7. diff --git a/services/network/network_context.cc b/services/network/network_context.cc
  8. index c8fd97e2bb411d3d7954782310bebac43b20b727..3a898f13c4516db5fbd1ccb5cb4e92c18a75bfd9 100644
  9. --- a/services/network/network_context.cc
  10. +++ b/services/network/network_context.cc
  11. @@ -150,6 +150,11 @@
  12. #include "services/network/web_transport.h"
  13. #include "url/gurl.h"
  14. +// Electron
  15. +#include "net/cert/caching_cert_verifier.h"
  16. +#include "net/cert/cert_verify_proc.h"
  17. +#include "net/cert/multi_threaded_cert_verifier.h"
  18. +
  19. #if BUILDFLAG(IS_CT_SUPPORTED)
  20. // gn check does not account for BUILDFLAG(). So, for iOS builds, it will
  21. // complain about a missing dependency on the target exposing this header. Add a
  22. @@ -513,6 +518,99 @@ bool GetFullDataFilePath(
  23. } // namespace
  24. +class RemoteCertVerifier : public net::CertVerifier {
  25. + public:
  26. + class Request : public net::CertVerifier::Request {
  27. + public:
  28. + Request() {}
  29. + ~Request() override = default;
  30. + void OnRemoteResponse(
  31. + const RequestParams& params,
  32. + net::CertVerifyResult* verify_result,
  33. + int error_from_upstream,
  34. + net::CompletionOnceCallback callback,
  35. + int error_from_client,
  36. + const net::CertVerifyResult& verify_result_from_client) {
  37. + if (error_from_client == net::ERR_ABORTED) {
  38. + // use the default
  39. + std::move(callback).Run(error_from_upstream);
  40. + } else {
  41. + // use the override
  42. + verify_result->Reset();
  43. + verify_result->verified_cert = verify_result_from_client.verified_cert;
  44. + std::move(callback).Run(error_from_client);
  45. + }
  46. + }
  47. + base::WeakPtr<Request> GetWeakPtr() { return weak_factory_.GetWeakPtr(); }
  48. + private:
  49. + base::WeakPtrFactory<Request> weak_factory_{this};
  50. + };
  51. +
  52. + RemoteCertVerifier(std::unique_ptr<net::CertVerifier> upstream): upstream_(std::move(upstream)) {
  53. + }
  54. + ~RemoteCertVerifier() override = default;
  55. +
  56. + void Bind(
  57. + mojo::PendingRemote<mojom::CertVerifierClient> client_info) {
  58. + client_.reset();
  59. + if (client_info.is_valid()) {
  60. + client_.Bind(std::move(client_info));
  61. + }
  62. + }
  63. +
  64. + // CertVerifier implementation
  65. + int Verify(const RequestParams& params,
  66. + net::CertVerifyResult* verify_result,
  67. + net::CompletionOnceCallback callback,
  68. + std::unique_ptr<CertVerifier::Request>* out_req,
  69. + const net::NetLogWithSource& net_log) override {
  70. + out_req->reset();
  71. +
  72. + net::CompletionOnceCallback callback2 = base::BindOnce(
  73. + &RemoteCertVerifier::OnRequestFinished, base::Unretained(this),
  74. + params, std::move(callback), verify_result, out_req);
  75. + return upstream_->Verify(params, verify_result, std::move(callback2), out_req, net_log);
  76. + }
  77. +
  78. +
  79. + void SetConfig(const Config& config) override {
  80. + upstream_->SetConfig(config);
  81. + }
  82. +
  83. + void AddObserver(CertVerifier::Observer* observer) override {
  84. + upstream_->AddObserver(observer);
  85. + }
  86. +
  87. + void RemoveObserver(CertVerifier::Observer* observer) override {
  88. + upstream_->RemoveObserver(observer);
  89. + }
  90. +
  91. + void OnRequestFinished(const RequestParams& params,
  92. + net::CompletionOnceCallback callback,
  93. + net::CertVerifyResult* verify_result,
  94. + std::unique_ptr<CertVerifier::Request>* out_req,
  95. + int error) {
  96. + if (client_.is_bound()) {
  97. + // We take a weak pointer to the request because deletion of the request
  98. + // is what signals cancellation. Thus if the request is cancelled, the
  99. + // callback won't be called, thus avoiding UAF, because |verify_result|
  100. + // is freed when the request is cancelled.
  101. + *out_req = std::make_unique<Request>();
  102. + base::WeakPtr<Request> weak_req = static_cast<Request*>(out_req->get())->GetWeakPtr();
  103. + client_->Verify(error, *verify_result, params.certificate(),
  104. + params.hostname(), params.flags(), params.ocsp_response(),
  105. + base::BindOnce(&Request::OnRemoteResponse,
  106. + weak_req, params, verify_result, error, std::move(callback)));
  107. + } else {
  108. + std::move(callback).Run(error);
  109. + }
  110. + }
  111. +
  112. + private:
  113. + std::unique_ptr<net::CertVerifier> upstream_;
  114. + mojo::Remote<mojom::CertVerifierClient> client_;
  115. +};
  116. +
  117. constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
  118. NetworkContext::NetworkContextHttpAuthPreferences::
  119. @@ -878,6 +976,13 @@ void NetworkContext::SetClient(
  120. client_.Bind(std::move(client));
  121. }
  122. +void NetworkContext::SetCertVerifierClient(
  123. + mojo::PendingRemote<mojom::CertVerifierClient> client) {
  124. + if (remote_cert_verifier_) {
  125. + remote_cert_verifier_->Bind(std::move(client));
  126. + }
  127. +}
  128. +
  129. void NetworkContext::CreateURLLoaderFactory(
  130. mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
  131. mojom::URLLoaderFactoryParamsPtr params) {
  132. @@ -2343,6 +2448,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
  133. std::move(cert_verifier));
  134. cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_.get());
  135. #endif // BUILDFLAG(IS_CHROMEOS)
  136. + auto remote_cert_verifier = std::make_unique<RemoteCertVerifier>(std::move(cert_verifier));
  137. + remote_cert_verifier_ = remote_cert_verifier.get();
  138. + cert_verifier = std::make_unique<net::CachingCertVerifier>(std::move(remote_cert_verifier));
  139. }
  140. builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
  141. diff --git a/services/network/network_context.h b/services/network/network_context.h
  142. index 401fa9c5931479dc2c60f3b3d7c58a4899ae06d2..fdc0899c6ccf8ff23dfad6de24ce0afa2efa4695 100644
  143. --- a/services/network/network_context.h
  144. +++ b/services/network/network_context.h
  145. @@ -113,6 +113,7 @@ class URLMatcher;
  146. namespace network {
  147. class CertVerifierWithTrustAnchors;
  148. +class RemoteCertVerifier;
  149. class CookieManager;
  150. class HostResolver;
  151. class MdnsResponderManager;
  152. @@ -245,6 +246,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
  153. void CreateURLLoaderFactory(
  154. mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
  155. mojom::URLLoaderFactoryParamsPtr params) override;
  156. + void SetCertVerifierClient(
  157. + mojo::PendingRemote<mojom::CertVerifierClient> client) override;
  158. void ResetURLLoaderFactories() override;
  159. void GetViaObliviousHttp(
  160. mojom::ObliviousHttpRequestPtr request,
  161. @@ -880,6 +883,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
  162. std::vector<base::OnceClosure> dismount_closures_;
  163. #endif // BUILDFLAG(IS_DIRECTORY_TRANSFER_REQUIRED)
  164. + raw_ptr<RemoteCertVerifier> remote_cert_verifier_ = nullptr;
  165. +
  166. // Created on-demand. Null if unused.
  167. std::unique_ptr<HostResolver> internal_host_resolver_;
  168. // Map values set to non-null only if that HostResolver has its own private
  169. diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
  170. index 3240e5b9a1a61ef6ccf343d86d6fb61017f2d1de..8d50681d41cd8321036fb14b724661a8398ab510 100644
  171. --- a/services/network/public/mojom/network_context.mojom
  172. +++ b/services/network/public/mojom/network_context.mojom
  173. @@ -298,6 +298,16 @@ struct SocketBrokerRemotes {
  174. pending_remote<SocketBroker> server;
  175. };
  176. +interface CertVerifierClient {
  177. + Verify(
  178. + int32 default_error,
  179. + CertVerifyResult default_result,
  180. + X509Certificate certificate,
  181. + string hostname,
  182. + int32 flags,
  183. + string? ocsp_response
  184. + ) => (int32 error_code, CertVerifyResult result);
  185. +};
  186. // Parameters for constructing a network context.
  187. struct NetworkContextParams {
  188. @@ -953,6 +963,9 @@ interface NetworkContext {
  189. // Sets a client for this network context.
  190. SetClient(pending_remote<NetworkContextClient> client);
  191. + // Sets a certificate verifier client for this network context.
  192. + SetCertVerifierClient(pending_remote<CertVerifierClient>? client);
  193. +
  194. // Creates a new URLLoaderFactory with the given |params|.
  195. CreateURLLoaderFactory(pending_receiver<URLLoaderFactory> url_loader_factory,
  196. URLLoaderFactoryParams params);
  197. diff --git a/services/network/test/test_network_context.h b/services/network/test/test_network_context.h
  198. index 73cfd546a0c5b5119aac6df910be9d925b48ade7..3061938ac5af0f2f1dbe0e0c70457b21ab1cd6c2 100644
  199. --- a/services/network/test/test_network_context.h
  200. +++ b/services/network/test/test_network_context.h
  201. @@ -62,6 +62,8 @@ class TestNetworkContext : public mojom::NetworkContext {
  202. void CreateURLLoaderFactory(
  203. mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
  204. mojom::URLLoaderFactoryParamsPtr params) override {}
  205. + void SetCertVerifierClient(
  206. + mojo::PendingRemote<mojom::CertVerifierClient> client) override {}
  207. void GetCookieManager(
  208. mojo::PendingReceiver<mojom::CookieManager> cookie_manager) override {}
  209. void GetRestrictedCookieManager(