electron_crypto_module_delegate_nss.cc 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. // Copyright (c) 2024 Switchboard
  2. // Use of this source code is governed by the MIT license that can be
  3. // found in the LICENSE file.
  4. #include "shell/browser/electron_crypto_module_delegate_nss.h"
  5. #include "content/public/browser/browser_thread.h"
  6. #include "crypto/nss_crypto_module_delegate.h"
  7. #include "shell/browser/api/electron_api_app.h"
  8. #include "shell/browser/javascript_environment.h"
  9. #include "shell/common/gin_converters/callback_converter.h"
  10. #include "shell/common/gin_helper/callback.h"
  11. #include "shell/common/gin_helper/dictionary.h"
  12. #include "shell/common/v8_util.h"
  13. ElectronNSSCryptoModuleDelegate::ElectronNSSCryptoModuleDelegate(
  14. const net::HostPortPair& server)
  15. : server_(server),
  16. event_(base::WaitableEvent::ResetPolicy::AUTOMATIC,
  17. base::WaitableEvent::InitialState::NOT_SIGNALED) {}
  18. ElectronNSSCryptoModuleDelegate::~ElectronNSSCryptoModuleDelegate() = default;
  19. std::string ElectronNSSCryptoModuleDelegate::RequestPassword(
  20. const std::string& token_name,
  21. bool retry,
  22. bool* cancelled) {
  23. DCHECK(!event_.IsSignaled());
  24. event_.Reset();
  25. if (content::GetUIThreadTaskRunner({})->PostTask(
  26. FROM_HERE,
  27. base::BindOnce(
  28. &ElectronNSSCryptoModuleDelegate::RequestPasswordOnUIThread, this,
  29. token_name, retry))) {
  30. base::ScopedAllowBaseSyncPrimitivesForTesting allow_wait;
  31. event_.Wait();
  32. }
  33. *cancelled = cancelled_;
  34. return password_;
  35. }
  36. void ElectronNSSCryptoModuleDelegate::RequestPasswordOnUIThread(
  37. const std::string& token_name,
  38. bool retry) {
  39. DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
  40. v8::Isolate* isolate = electron::JavascriptEnvironment::GetIsolate();
  41. v8::HandleScope handle_scope(isolate);
  42. gin::Handle<gin_helper::internal::Event> event =
  43. gin_helper::internal::Event::New(isolate);
  44. v8::Local<v8::Object> event_object = event.ToV8().As<v8::Object>();
  45. gin_helper::Dictionary dict(isolate, event_object);
  46. dict.Set("hostname", server_.host());
  47. dict.Set("tokenName", token_name);
  48. dict.Set("isRetry", retry);
  49. electron::api::App::Get()->EmitWithoutEvent(
  50. "-client-certificate-request-password", event_object,
  51. base::BindOnce(&ElectronNSSCryptoModuleDelegate::OnPassword, this));
  52. if (!event->GetDefaultPrevented()) {
  53. password_ = "";
  54. cancelled_ = true;
  55. event_.Signal();
  56. }
  57. }
  58. void ElectronNSSCryptoModuleDelegate::OnPassword(gin::Arguments* args) {
  59. args->GetNext(&password_);
  60. cancelled_ = password_.empty();
  61. event_.Signal();
  62. }