network_service_allow_remote_certificate_verification_logic.patch 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241
  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 3bb208bad23cd3247f95305104a856e9d0bbc396..170ba3cf6176e8423b6009a0ac0299bf1e411158 100644
  9. --- a/services/network/network_context.cc
  10. +++ b/services/network/network_context.cc
  11. @@ -114,6 +114,11 @@
  12. #include "services/network/url_loader.h"
  13. #include "services/network/url_request_context_builder_mojo.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. #include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
  21. #include "components/certificate_transparency/chrome_require_ct_delegate.h"
  22. @@ -324,6 +329,79 @@ std::string HashesToBase64String(const net::HashValueVector& hashes) {
  23. } // namespace
  24. +class RemoteCertVerifier : public net::CertVerifier {
  25. + public:
  26. + RemoteCertVerifier(std::unique_ptr<net::CertVerifier> upstream): upstream_(std::move(upstream)) {
  27. + }
  28. + ~RemoteCertVerifier() override = default;
  29. +
  30. + void Bind(
  31. + mojo::PendingRemote<mojom::CertVerifierClient> client_info) {
  32. + client_.reset();
  33. + if (client_info.is_valid()) {
  34. + client_.Bind(std::move(client_info));
  35. + }
  36. + }
  37. +
  38. + // CertVerifier implementation
  39. + int Verify(const RequestParams& params,
  40. + net::CertVerifyResult* verify_result,
  41. + net::CompletionOnceCallback callback,
  42. + std::unique_ptr<Request>* out_req,
  43. + const net::NetLogWithSource& net_log) override {
  44. + out_req->reset();
  45. +
  46. + net::CompletionOnceCallback callback2 = base::BindOnce(
  47. + &RemoteCertVerifier::OnRequestFinished, base::Unretained(this),
  48. + params, std::move(callback), verify_result);
  49. + int result = upstream_->Verify(params, verify_result,
  50. + std::move(callback2), out_req, net_log);
  51. + if (result != net::ERR_IO_PENDING) {
  52. + // Synchronous completion
  53. + }
  54. +
  55. + return result;
  56. + }
  57. +
  58. +
  59. + void SetConfig(const Config& config) override {
  60. + upstream_->SetConfig(config);
  61. + }
  62. +
  63. + void OnRequestFinished(const RequestParams& params, net::CompletionOnceCallback callback, net::CertVerifyResult* verify_result, int error) {
  64. + if (client_.is_bound()) {
  65. + client_->Verify(error, *verify_result, params.certificate(),
  66. + params.hostname(), params.flags(), params.ocsp_response(),
  67. + base::BindOnce(&RemoteCertVerifier::OnRemoteResponse,
  68. + base::Unretained(this), params, verify_result, error,
  69. + std::move(callback)));
  70. + } else {
  71. + std::move(callback).Run(error);
  72. + }
  73. + }
  74. +
  75. + void OnRemoteResponse(
  76. + const RequestParams& params,
  77. + net::CertVerifyResult* verify_result,
  78. + int error,
  79. + net::CompletionOnceCallback callback,
  80. + int error2,
  81. + const net::CertVerifyResult& verify_result2) {
  82. + if (error2 == net::ERR_ABORTED) {
  83. + // use the default
  84. + std::move(callback).Run(error);
  85. + } else {
  86. + // use the override
  87. + verify_result->Reset();
  88. + verify_result->verified_cert = verify_result2.verified_cert;
  89. + std::move(callback).Run(error2);
  90. + }
  91. + }
  92. + private:
  93. + std::unique_ptr<net::CertVerifier> upstream_;
  94. + mojo::Remote<mojom::CertVerifierClient> client_;
  95. +};
  96. +
  97. constexpr uint32_t NetworkContext::kMaxOutstandingRequestsPerProcess;
  98. NetworkContext::PendingCertVerify::PendingCertVerify() = default;
  99. @@ -518,6 +596,13 @@ void NetworkContext::SetClient(
  100. client_.Bind(std::move(client));
  101. }
  102. +void NetworkContext::SetCertVerifierClient(
  103. + mojo::PendingRemote<mojom::CertVerifierClient> client) {
  104. + if (remote_cert_verifier_) {
  105. + remote_cert_verifier_->Bind(std::move(client));
  106. + }
  107. +}
  108. +
  109. void NetworkContext::CreateURLLoaderFactory(
  110. mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
  111. mojom::URLLoaderFactoryParamsPtr params) {
  112. @@ -1723,8 +1808,9 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
  113. "NetworkContext should pass CertVerifierServiceRemoteParams.";
  114. std::unique_ptr<net::CertVerifier> cert_verifier;
  115. + std::unique_ptr<net::CertVerifier> temp_verifier;
  116. if (g_cert_verifier_for_testing) {
  117. - cert_verifier = std::make_unique<WrappedTestingCertVerifier>();
  118. + temp_verifier = std::make_unique<WrappedTestingCertVerifier>();
  119. } else {
  120. if (params_->cert_verifier_params &&
  121. params_->cert_verifier_params->is_remote_params()) {
  122. @@ -1752,14 +1838,14 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
  123. cert_net_fetcher_ =
  124. base::MakeRefCounted<net::CertNetFetcherURLRequest>();
  125. - cert_verifier = CreateCertVerifier(creation_params, cert_net_fetcher_);
  126. + temp_verifier = CreateCertVerifier(creation_params, cert_net_fetcher_);
  127. }
  128. // Whether the cert verifier is remote or in-process, we should wrap it in
  129. // caching and coalescing layers to avoid extra verifications and IPCs.
  130. - cert_verifier = std::make_unique<net::CachingCertVerifier>(
  131. + temp_verifier = std::make_unique<net::CachingCertVerifier>(
  132. std::make_unique<net::CoalescingCertVerifier>(
  133. - std::move(cert_verifier)));
  134. + std::move(temp_verifier)));
  135. #if defined(OS_CHROMEOS)
  136. cert_verifier_with_trust_anchors_ =
  137. @@ -1768,13 +1854,27 @@ URLRequestContextOwner NetworkContext::MakeURLRequestContext(
  138. UpdateAdditionalCertificates(
  139. std::move(params_->initial_additional_certificates));
  140. cert_verifier_with_trust_anchors_->InitializeOnIOThread(
  141. - std::move(cert_verifier));
  142. - cert_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_);
  143. + std::move(temp_verifier));
  144. + temp_verifier = base::WrapUnique(cert_verifier_with_trust_anchors_);
  145. #endif // defined(OS_CHROMEOS)
  146. + if (!temp_verifier) {
  147. +#if !defined(OS_LINUX)
  148. + temp_verifier = std::make_unique<net::MultiThreadedCertVerifier>(
  149. + net::CertVerifyProc::CreateSystemVerifyProc(std::move(cert_net_fetcher_)));
  150. +#else
  151. + temp_verifier = std::make_unique<net::MultiThreadedCertVerifier>(
  152. + net::CertVerifyProc::CreateBuiltinVerifyProc(std::move(cert_net_fetcher_)));
  153. +#endif
  154. + }
  155. + auto remote_cert_verifier = std::make_unique<RemoteCertVerifier>(std::move(temp_verifier));
  156. + remote_cert_verifier_ = remote_cert_verifier.get();
  157. + cert_verifier = std::make_unique<net::CachingCertVerifier>(std::move(remote_cert_verifier));
  158. }
  159. - builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
  160. - *command_line, nullptr, std::move(cert_verifier)));
  161. + cert_verifier = IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
  162. + *command_line, nullptr, std::move(cert_verifier));
  163. +
  164. + builder.SetCertVerifier(std::move(cert_verifier));
  165. std::unique_ptr<NetworkServiceNetworkDelegate> network_delegate =
  166. std::make_unique<NetworkServiceNetworkDelegate>(
  167. diff --git a/services/network/network_context.h b/services/network/network_context.h
  168. index eced38ff04f8d7f3a91079b65f5ad29348bf8813..391a02c108debdd5e5572b4a666d30dc68ece76b 100644
  169. --- a/services/network/network_context.h
  170. +++ b/services/network/network_context.h
  171. @@ -86,6 +86,7 @@ class DomainReliabilityMonitor;
  172. namespace network {
  173. class CertVerifierWithTrustAnchors;
  174. +class RemoteCertVerifier;
  175. class CookieManager;
  176. class ExpectCTReporter;
  177. class HostResolver;
  178. @@ -189,6 +190,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
  179. void CreateURLLoaderFactory(
  180. mojo::PendingReceiver<mojom::URLLoaderFactory> receiver,
  181. mojom::URLLoaderFactoryParamsPtr params) override;
  182. + void SetCertVerifierClient(
  183. + mojo::PendingRemote<mojom::CertVerifierClient> client) override;
  184. void ResetURLLoaderFactories() override;
  185. void GetCookieManager(
  186. mojo::PendingReceiver<mojom::CookieManager> receiver) override;
  187. @@ -653,6 +656,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkContext
  188. CertVerifierWithTrustAnchors* cert_verifier_with_trust_anchors_ = nullptr;
  189. #endif
  190. + RemoteCertVerifier* remote_cert_verifier_ = nullptr;
  191. +
  192. // CertNetFetcher used by the context's CertVerifier. May be nullptr if
  193. // CertNetFetcher is not used by the current platform, or if the actual
  194. // net::CertVerifier is instantiated outside of the network service.
  195. diff --git a/services/network/public/mojom/network_context.mojom b/services/network/public/mojom/network_context.mojom
  196. index 2c696bbb7863f02a93cacef0fd8780a5fa3ac040..73b790fab0f6c6377f8206960a478778ecf6e62c 100644
  197. --- a/services/network/public/mojom/network_context.mojom
  198. +++ b/services/network/public/mojom/network_context.mojom
  199. @@ -214,6 +214,17 @@ struct CTPolicy {
  200. array<string> excluded_legacy_spkis;
  201. };
  202. +interface CertVerifierClient {
  203. + Verify(
  204. + int32 default_error,
  205. + CertVerifyResult default_result,
  206. + X509Certificate certificate,
  207. + string hostname,
  208. + int32 flags,
  209. + string? ocsp_response
  210. + ) => (int32 error_code, CertVerifyResult result);
  211. +};
  212. +
  213. // Parameters for constructing a network context.
  214. struct NetworkContextParams {
  215. // Name used by memory tools to identify the context.
  216. @@ -856,6 +867,9 @@ interface NetworkContext {
  217. // Sets a client for this network context.
  218. SetClient(pending_remote<NetworkContextClient> client);
  219. + // Sets a certificate verifier client for this network context.
  220. + SetCertVerifierClient(pending_remote<CertVerifierClient>? client);
  221. +
  222. // Creates a new URLLoaderFactory with the given |params|.
  223. CreateURLLoaderFactory(pending_receiver<URLLoaderFactory> url_loader_factory,
  224. URLLoaderFactoryParams params);