Repository: electron/electron
Pull request: fix: fix cookie encryption provider loading on Windows and Linux

#### Description of Change

Fast follow to #49348. 

This PR modifies our existing cookie encryption logic to match an upstream change here: "Port net::CookieCryptoDelegate to os_crypt async" | https://chromium-review.googlesource.com/c/chromium/src/+/6996667 However, the previous PR only fixed the issue properly for MacOS. This PR provides the appropriate platform fixes for both Windows and Linux key providers.

We should try to land this fix before the 40.0.0 stable cut, as missing it breaks applications using cookie encryption.

#### Checklist
<!-- Remove items that do not apply. For completed items, change [ ] to [x]. -->

- [ ] PR description included
- [ ] `npm test` passes
- [ ] tests are [changed or added](https://github.com/electron/electron/blob/main/docs/development/testing.md)
- [ ] relevant API documentation, tutorials, and examples are updated and follow the [documentation style guide](https://github.com/electron/electron/blob/main/docs/development/style-guide.md)
- [ ] [PR release notes](https://github.com/electron/clerk/blob/main/README.md) describe the change in a way relevant to app developers, and are [capitalized, punctuated, and past tense](https://github.com/electron/clerk/blob/main/README.md#examples).

#### Release Notes

Notes: Fixed an issue on Windows and Linux where no cookie encryption key provider was passed into the network service when cookie encryption was enabled.


Changed files:
filename: BUILD.gn
patch: @@ -465,6 +465,8 @@ source_set("electron_lib") {
     "//components/os_crypt/async/browser",
     "//components/os_crypt/async/browser:key_provider_interface",
     "//components/os_crypt/sync",
+    "//components/password_manager/core/browser:password_switches",
+    "//components/password_manager/core/common:features",
     "//components/pref_registry",
     "//components/prefs",
     "//components/security_state/content",
@@ -595,6 +597,7 @@ source_set("electron_lib") {
     use_libcxx_modules = false
 
     deps += [
+      "//components/os_crypt/async/browser:keychain_key_provider",
       "//components/os_crypt/common:keychain_password_mac",
       "//components/remote_cocoa/app_shim",
       "//components/remote_cocoa/browser",
@@ -657,6 +660,8 @@ source_set("electron_lib") {
       ":libnotify_loader",
       "//build/config/linux/gtk",
       "//components/crash/content/browser",
+      "//components/os_crypt/async/browser:freedesktop_secret_key_provider",
+      "//components/os_crypt/async/browser:posix_key_provider",
       "//dbus",
       "//device/bluetooth",
       "//third_party/crashpad/crashpad/client",
@@ -697,6 +702,7 @@ source_set("electron_lib") {
     deps += [
       "//components/app_launch_prefetch",
       "//components/crash/core/app:crash_export_thunks",
+      "//components/os_crypt/async/browser:dpapi_key_provider",
       "//third_party/libxml:xml_writer",
       "//ui/wm",
       "//ui/wm/public",

filename: shell/browser/browser_process_impl.cc
patch: @@ -12,11 +12,27 @@
 #include "base/files/file_path.h"
 #include "base/notimplemented.h"
 #include "base/path_service.h"
+#include "build/build_config.h"
 #include "chrome/browser/browser_process.h"
 #include "chrome/common/chrome_switches.h"
 #include "components/os_crypt/async/browser/key_provider.h"
 #include "components/os_crypt/async/browser/os_crypt_async.h"
 #include "components/os_crypt/sync/os_crypt.h"
+#include "components/password_manager/core/browser/password_manager_switches.h"
+
+#if BUILDFLAG(IS_WIN)
+#include "components/os_crypt/async/browser/dpapi_key_provider.h"
+#endif
+
+#if BUILDFLAG(IS_LINUX)
+#include "components/os_crypt/async/browser/freedesktop_secret_key_provider.h"
+#include "components/os_crypt/async/browser/posix_key_provider.h"
+#endif
+
+#if BUILDFLAG(IS_MAC)
+#include "components/os_crypt/async/browser/keychain_key_provider.h"
+#endif
+
 #include "components/prefs/in_memory_pref_store.h"
 #include "components/prefs/json_pref_store.h"
 #include "components/prefs/overlay_user_pref_store.h"
@@ -406,15 +422,45 @@ void BrowserProcessImpl::CreateNetworkQualityObserver() {
 }
 
 void BrowserProcessImpl::CreateOSCryptAsync() {
-  // source: https://chromium-review.googlesource.com/c/chromium/src/+/4455776
-
-  // For now, initialize OSCryptAsync with no providers. This delegates all
-  // encryption operations to OSCrypt.
-  // TODO(crbug.com/1373092): Add providers behind features, as support for them
-  // is added.
-  os_crypt_async_ = std::make_unique<os_crypt_async::OSCryptAsync>(
-      std::vector<
-          std::pair<size_t, std::unique_ptr<os_crypt_async::KeyProvider>>>());
+  // Initialize OSCryptAsync with platform-specific key providers.
+  // See https://chromium-review.googlesource.com/c/chromium/src/+/6996667
+  std::vector<std::pair<size_t, std::unique_ptr<os_crypt_async::KeyProvider>>>
+      providers;
+
+#if BUILDFLAG(IS_WIN)
+  // On Windows, use DPAPI key provider for cookie encryption.
+  providers.emplace_back(
+      /*precedence=*/10u,
+      std::make_unique<os_crypt_async::DPAPIKeyProvider>(local_state()));
+#endif  // BUILDFLAG(IS_WIN)
+
+#if BUILDFLAG(IS_LINUX)
+  // On Linux, use FreedesktopSecretKeyProvider (for GNOME Keyring, KWallet,
+  // etc.) with PosixKeyProvider as fallback.
+  base::CommandLine* cmd_line = base::CommandLine::ForCurrentProcess();
+  const auto password_store =
+      cmd_line->GetSwitchValueASCII(password_manager::kPasswordStore);
+
+  providers.emplace_back(
+      /*precedence=*/10u,
+      std::make_unique<os_crypt_async::FreedesktopSecretKeyProvider>(
+          password_store, "Electron", nullptr));
+
+  // PosixKeyProvider as fallback with lower precedence.
+  providers.emplace_back(
+      /*precedence=*/5u, std::make_unique<os_crypt_async::PosixKeyProvider>());
+#endif  // BUILDFLAG(IS_LINUX)
+
+#if BUILDFLAG(IS_MAC)
+  // On macOS, use KeychainKeyProvider for cookie encryption.
+  // This is enabled by default in Chrome via features::kUseKeychainKeyProvider.
+  providers.emplace_back(
+      /*precedence=*/10u,
+      std::make_unique<os_crypt_async::KeychainKeyProvider>());
+#endif  // BUILDFLAG(IS_MAC)
+
+  os_crypt_async_ =
+      std::make_unique<os_crypt_async::OSCryptAsync>(std::move(providers));
 
   // Trigger async initialization of OSCrypt key providers.
   os_crypt_async_->GetInstance(base::DoNothing());