cert_verifier_creation.cc 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. // Copyright 2020 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. #include "services/cert_verifier/cert_verifier_creation.h"
  5. #include "build/build_config.h"
  6. #include "build/chromeos_buildflags.h"
  7. #include "net/base/features.h"
  8. #include "net/cert/cert_verify_proc.h"
  9. #include "net/cert/multi_threaded_cert_verifier.h"
  10. #include "net/cert_net/cert_net_fetcher_url_request.h"
  11. #include "net/net_buildflags.h"
  12. #if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) || \
  13. BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX) || BUILDFLAG(IS_CHROMEOS)
  14. #include "net/cert/cert_verify_proc_builtin.h"
  15. #include "net/cert/internal/system_trust_store.h"
  16. #endif
  17. #if BUILDFLAG(IS_CHROMEOS)
  18. #include "crypto/nss_util_internal.h"
  19. #include "net/cert/internal/system_trust_store_nss.h"
  20. #endif
  21. #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  22. #include "net/cert/cert_verify_proc_builtin.h"
  23. #include "net/cert/internal/system_trust_store.h"
  24. #include "net/cert/internal/trust_store_chrome.h"
  25. #endif
  26. #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
  27. #include "services/cert_verifier/trial_comparison_cert_verifier_mojo.h"
  28. #endif
  29. namespace cert_verifier {
  30. namespace {
  31. #if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
  32. bool UsingBuiltinCertVerifier(
  33. mojom::CertVerifierCreationParams::CertVerifierImpl mode) {
  34. switch (mode) {
  35. case mojom::CertVerifierCreationParams::CertVerifierImpl::kDefault:
  36. return base::FeatureList::IsEnabled(
  37. net::features::kCertVerifierBuiltinFeature);
  38. case mojom::CertVerifierCreationParams::CertVerifierImpl::kBuiltin:
  39. return true;
  40. case mojom::CertVerifierCreationParams::CertVerifierImpl::kSystem:
  41. return false;
  42. }
  43. }
  44. #endif
  45. #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  46. bool UsingChromeRootStore(
  47. mojom::CertVerifierCreationParams::ChromeRootImpl mode) {
  48. switch (mode) {
  49. case mojom::CertVerifierCreationParams::ChromeRootImpl::kRootDefault:
  50. return base::FeatureList::IsEnabled(net::features::kChromeRootStoreUsed);
  51. case mojom::CertVerifierCreationParams::ChromeRootImpl::kRootChrome:
  52. return true;
  53. case mojom::CertVerifierCreationParams::ChromeRootImpl::kRootSystem:
  54. return false;
  55. }
  56. }
  57. #endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  58. #if BUILDFLAG(IS_CHROMEOS)
  59. crypto::ScopedPK11Slot GetUserSlotRestrictionForChromeOSParams(
  60. mojom::CertVerifierCreationParams* creation_params) {
  61. crypto::ScopedPK11Slot public_slot;
  62. #if BUILDFLAG(IS_CHROMEOS_LACROS)
  63. if (creation_params && creation_params->nss_full_path.has_value()) {
  64. public_slot =
  65. crypto::OpenSoftwareNSSDB(creation_params->nss_full_path.value(),
  66. /*description=*/"cert_db");
  67. // `public_slot` can contain important security related settings. Crash if
  68. // failed to load it.
  69. CHECK(public_slot);
  70. }
  71. #elif BUILDFLAG(IS_CHROMEOS_ASH)
  72. if (creation_params && !creation_params->username_hash.empty()) {
  73. // Make sure NSS is initialized for the user.
  74. crypto::InitializeNSSForChromeOSUser(creation_params->username_hash,
  75. creation_params->nss_path.value());
  76. public_slot =
  77. crypto::GetPublicSlotForChromeOSUser(creation_params->username_hash);
  78. }
  79. #else
  80. #error IS_CHROMEOS set without IS_CHROMEOS_LACROS or IS_CHROMEOS_ASH
  81. #endif
  82. return public_slot;
  83. }
  84. #endif // BUILDFLAG(IS_CHROMEOS)
  85. // CertVerifyProcFactory that returns a CertVerifyProc that supports the old
  86. // configuration for platforms where we are transitioning from one cert
  87. // configuration to another. If the platform only supports one configuration,
  88. // return a CertVerifyProc that supports that configuration.
  89. class OldDefaultCertVerifyProcFactory : public net::CertVerifyProcFactory {
  90. public:
  91. explicit OldDefaultCertVerifyProcFactory(
  92. mojom::CertVerifierCreationParams* creation_params) {
  93. #if BUILDFLAG(IS_CHROMEOS)
  94. user_slot_restriction_ =
  95. GetUserSlotRestrictionForChromeOSParams(creation_params);
  96. #endif
  97. }
  98. scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc(
  99. scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
  100. const net::ChromeRootStoreData* root_store_data) override {
  101. scoped_refptr<net::CertVerifyProc> verify_proc;
  102. #if BUILDFLAG(IS_CHROMEOS)
  103. verify_proc = net::CreateCertVerifyProcBuiltin(
  104. std::move(cert_net_fetcher),
  105. net::CreateSslSystemTrustStoreNSSWithUserSlotRestriction(
  106. user_slot_restriction_ ? crypto::ScopedPK11Slot(PK11_ReferenceSlot(
  107. user_slot_restriction_.get()))
  108. : nullptr));
  109. #elif BUILDFLAG(IS_FUCHSIA) || BUILDFLAG(IS_LINUX)
  110. verify_proc = net::CreateCertVerifyProcBuiltin(
  111. std::move(cert_net_fetcher), net::CreateSslSystemTrustStore());
  112. #else
  113. verify_proc = net::CertVerifyProc::CreateSystemVerifyProc(
  114. std::move(cert_net_fetcher));
  115. #endif
  116. return verify_proc;
  117. }
  118. protected:
  119. ~OldDefaultCertVerifyProcFactory() override = default;
  120. #if BUILDFLAG(IS_CHROMEOS)
  121. crypto::ScopedPK11Slot user_slot_restriction_;
  122. #endif
  123. };
  124. #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  125. // CertVerifyProcFactory that returns a CertVerifyProc that uses the
  126. // Chrome Cert Verifier with the Chrome Root Store.
  127. class NewCertVerifyProcChromeRootStoreFactory
  128. : public net::CertVerifyProcFactory {
  129. public:
  130. explicit NewCertVerifyProcChromeRootStoreFactory(
  131. mojom::CertVerifierCreationParams* creation_params) {
  132. #if BUILDFLAG(IS_CHROMEOS)
  133. user_slot_restriction_ =
  134. GetUserSlotRestrictionForChromeOSParams(creation_params);
  135. #endif
  136. }
  137. scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc(
  138. scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
  139. const net::ChromeRootStoreData* root_store_data) override {
  140. std::unique_ptr<net::TrustStoreChrome> chrome_root;
  141. if (!root_store_data) {
  142. chrome_root = std::make_unique<net::TrustStoreChrome>();
  143. } else {
  144. chrome_root = std::make_unique<net::TrustStoreChrome>(*root_store_data);
  145. }
  146. std::unique_ptr<net::SystemTrustStore> trust_store;
  147. #if BUILDFLAG(IS_CHROMEOS)
  148. trust_store =
  149. net::CreateSslSystemTrustStoreChromeRootWithUserSlotRestriction(
  150. std::move(chrome_root),
  151. user_slot_restriction_ ? crypto::ScopedPK11Slot(PK11_ReferenceSlot(
  152. user_slot_restriction_.get()))
  153. : nullptr);
  154. #else
  155. trust_store =
  156. net::CreateSslSystemTrustStoreChromeRoot(std::move(chrome_root));
  157. #endif
  158. return net::CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher),
  159. std::move(trust_store));
  160. }
  161. protected:
  162. ~NewCertVerifyProcChromeRootStoreFactory() override = default;
  163. #if BUILDFLAG(IS_CHROMEOS)
  164. crypto::ScopedPK11Slot user_slot_restriction_;
  165. #endif
  166. };
  167. #endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  168. #if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
  169. // CertVerifyProcFactory that returns a CertVerifyProc that uses the
  170. // Chrome Cert Verifier without the Chrome Root Store.
  171. class NewCertVerifyProcBuiltinFactory : public net::CertVerifyProcFactory {
  172. public:
  173. scoped_refptr<net::CertVerifyProc> CreateCertVerifyProc(
  174. scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
  175. const net::ChromeRootStoreData* root_store_data) override {
  176. return net::CreateCertVerifyProcBuiltin(std::move(cert_net_fetcher),
  177. net::CreateSslSystemTrustStore());
  178. }
  179. protected:
  180. ~NewCertVerifyProcBuiltinFactory() override = default;
  181. };
  182. // Returns true if creation_params are requesting the creation of a
  183. // Builtin Verifier using system roots (as opposed to Chrome Root Store).
  184. bool IsUsingBuiltinWithSystemRoots(
  185. const mojom::CertVerifierCreationParams* creation_params) {
  186. return creation_params
  187. ? UsingBuiltinCertVerifier(
  188. creation_params->use_builtin_cert_verifier)
  189. : UsingBuiltinCertVerifier(mojom::CertVerifierCreationParams::
  190. CertVerifierImpl::kDefault);
  191. }
  192. #endif // BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
  193. #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
  194. // Returns true if creation_params are requesting the creation of a
  195. // TrialComparisonCertVerifier.
  196. bool IsTrialVerificationOn(
  197. const mojom::CertVerifierCreationParams* creation_params) {
  198. #if BUILDFLAG(IS_CHROMEOS)
  199. #error "Trial comparisons not supported on ChromeOS yet. Code changes needed."
  200. #endif
  201. // Check to see if we have trial comparison cert verifier params.
  202. return creation_params &&
  203. creation_params->trial_comparison_cert_verifier_params;
  204. }
  205. // Should only be called if IsTrialVerificationOn(creation_params) == true.
  206. std::unique_ptr<net::CertVerifierWithUpdatableProc> CreateTrialCertVerifier(
  207. mojom::CertVerifierCreationParams* creation_params,
  208. scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
  209. const net::ChromeRootStoreData* root_store_data) {
  210. DCHECK(IsTrialVerificationOn(creation_params));
  211. // If we're doing trial verification, we always do it between the old
  212. // default and the proposed new default, giving the user the value computed
  213. // by the old default.
  214. auto primary_proc_factory =
  215. base::MakeRefCounted<OldDefaultCertVerifyProcFactory>(creation_params);
  216. scoped_refptr<net::CertVerifyProc> primary_proc =
  217. primary_proc_factory->CreateCertVerifyProc(cert_net_fetcher,
  218. root_store_data);
  219. #if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) && \
  220. BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  221. scoped_refptr<net::CertVerifyProcFactory> trial_proc_factory;
  222. if (net::features::kCertDualVerificationTrialUseCrs.Get()) {
  223. trial_proc_factory =
  224. base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>(
  225. creation_params);
  226. } else {
  227. trial_proc_factory =
  228. base::MakeRefCounted<NewCertVerifyProcBuiltinFactory>();
  229. }
  230. #elif BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  231. auto trial_proc_factory =
  232. base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>(
  233. creation_params);
  234. #else
  235. auto trial_proc_factory =
  236. base::MakeRefCounted<NewCertVerifyProcBuiltinFactory>();
  237. #endif
  238. scoped_refptr<net::CertVerifyProc> trial_proc =
  239. trial_proc_factory->CreateCertVerifyProc(cert_net_fetcher,
  240. root_store_data);
  241. return std::make_unique<TrialComparisonCertVerifierMojo>(
  242. creation_params->trial_comparison_cert_verifier_params->initial_allowed,
  243. std::move(creation_params->trial_comparison_cert_verifier_params
  244. ->config_client_receiver),
  245. std::move(creation_params->trial_comparison_cert_verifier_params
  246. ->report_client),
  247. std::move(primary_proc), std::move(primary_proc_factory),
  248. std::move(trial_proc), std::move(trial_proc_factory));
  249. }
  250. #endif // BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
  251. #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  252. // Check to see if we're using the Chrome Root Store for this verifier.
  253. // Returns true if Chrome Root Store is on in creation_params.
  254. bool IsUsingChromeRootStore(
  255. const mojom::CertVerifierCreationParams* creation_params) {
  256. return creation_params
  257. ? UsingChromeRootStore(creation_params->use_chrome_root_store)
  258. : UsingChromeRootStore(mojom::CertVerifierCreationParams::
  259. ChromeRootImpl::kRootDefault);
  260. }
  261. #endif // BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  262. } // namespace
  263. bool IsUsingCertNetFetcher() {
  264. #if BUILDFLAG(IS_ANDROID) || BUILDFLAG(IS_FUCHSIA) || \
  265. BUILDFLAG(IS_CHROMEOS) || BUILDFLAG(IS_LINUX) || \
  266. BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED) || \
  267. BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED) || \
  268. BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  269. return true;
  270. #else
  271. return false;
  272. #endif
  273. }
  274. std::unique_ptr<net::CertVerifierWithUpdatableProc> CreateCertVerifier(
  275. mojom::CertVerifierCreationParams* creation_params,
  276. scoped_refptr<net::CertNetFetcher> cert_net_fetcher,
  277. const net::ChromeRootStoreData* root_store_data) {
  278. DCHECK(cert_net_fetcher || !IsUsingCertNetFetcher());
  279. std::unique_ptr<net::CertVerifierWithUpdatableProc> cert_verifier;
  280. #if BUILDFLAG(TRIAL_COMPARISON_CERT_VERIFIER_SUPPORTED)
  281. if (!cert_verifier && IsTrialVerificationOn(creation_params)) {
  282. cert_verifier = CreateTrialCertVerifier(creation_params, cert_net_fetcher,
  283. root_store_data);
  284. }
  285. #endif
  286. // We check for CRS support here first. In the case where we are on a
  287. // platform that has both the CHROME_ROOT_STORE_SUPPORTED and the
  288. // BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED build flags on and has both
  289. // enabled in creation_params, that should be interpreted as wanting CRS with
  290. // Builtin.
  291. #if BUILDFLAG(CHROME_ROOT_STORE_SUPPORTED)
  292. if (!cert_verifier && IsUsingChromeRootStore(creation_params)) {
  293. scoped_refptr<NewCertVerifyProcChromeRootStoreFactory> proc_factory =
  294. base::MakeRefCounted<NewCertVerifyProcChromeRootStoreFactory>(
  295. creation_params);
  296. cert_verifier = std::make_unique<net::MultiThreadedCertVerifier>(
  297. proc_factory->CreateCertVerifyProc(cert_net_fetcher, root_store_data),
  298. proc_factory);
  299. }
  300. #endif
  301. #if BUILDFLAG(BUILTIN_CERT_VERIFIER_FEATURE_SUPPORTED)
  302. if (!cert_verifier && IsUsingBuiltinWithSystemRoots(creation_params)) {
  303. scoped_refptr<NewCertVerifyProcBuiltinFactory> proc_factory =
  304. base::MakeRefCounted<NewCertVerifyProcBuiltinFactory>();
  305. cert_verifier = std::make_unique<net::MultiThreadedCertVerifier>(
  306. proc_factory->CreateCertVerifyProc(cert_net_fetcher, root_store_data),
  307. proc_factory);
  308. }
  309. #endif
  310. if (!cert_verifier) {
  311. scoped_refptr<OldDefaultCertVerifyProcFactory> proc_factory =
  312. base::MakeRefCounted<OldDefaultCertVerifyProcFactory>(creation_params);
  313. cert_verifier = std::make_unique<net::MultiThreadedCertVerifier>(
  314. proc_factory->CreateCertVerifyProc(cert_net_fetcher, root_store_data),
  315. proc_factory);
  316. }
  317. return cert_verifier;
  318. }
  319. } // namespace cert_verifier