tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

commit 5626a548d0b71d6ddfb136249264b7a739500c17
parent 17d106ca7c233a3ad709b3e599557560a8a929bd
Author: Yannis Juglaret <yjuglaret@mozilla.com>
Date:   Wed, 17 Dec 2025 15:21:20 +0000

Bug 1957156 - Define a LoadModule IPDL message in the PKCS#11 utility process. r=keeler,ipc-reviewers,nika

This patch defines a placeholder LoadModule IPDL message for
cross-process interaction between the main process and the PKCS#11
utility process. The correct implementation will come in future patches.

This is preliminary work guarded by a Nightly-only pref. It is intended
as a helpful basis for future work by Security Engineering. We don't
actually load the modules within the utility process for the moment.

Differential Revision: https://phabricator.services.mozilla.com/D271624

Diffstat:
Msecurity/manager/ssl/PKCS11ModuleChild.cpp | 17+++++++++++++++++
Msecurity/manager/ssl/PKCS11ModuleChild.h | 3+++
Msecurity/manager/ssl/PPKCS11Module.ipdl | 2++
Msecurity/manager/ssl/nsNSSComponent.cpp | 14++++++++++++++
Msecurity/manager/ssl/tests/gtest/UtilityPKCS11ModuleTest.cpp | 38++++++++++++++++++++++++++++++++++++++
5 files changed, 74 insertions(+), 0 deletions(-)

diff --git a/security/manager/ssl/PKCS11ModuleChild.cpp b/security/manager/ssl/PKCS11ModuleChild.cpp @@ -12,6 +12,9 @@ #include "mozilla/ipc/Endpoint.h" #include "nsDebugImpl.h" +#include <chrono> +#include <thread> + namespace mozilla::psm { nsresult PKCS11ModuleChild::Start(Endpoint<PPKCS11ModuleChild>&& aEndpoint) { @@ -34,4 +37,18 @@ nsresult PKCS11ModuleChild::Start(Endpoint<PPKCS11ModuleChild>&& aEndpoint) { return rv; } +ipc::IPCResult PKCS11ModuleChild::RecvLoadModule( + nsString&& aModule, LoadModuleResolver&& aResolver) { + if (aModule != u"MySecretModule"_ns) { + aResolver(NS_ERROR_NOT_IMPLEMENTED); + return IPC_OK(); + } + + // Simulate a long but successful load + std::this_thread::sleep_for(std::chrono::seconds(1)); + aResolver(NS_OK); + + return IPC_OK(); +} + } // namespace mozilla::psm diff --git a/security/manager/ssl/PKCS11ModuleChild.h b/security/manager/ssl/PKCS11ModuleChild.h @@ -24,6 +24,9 @@ class PKCS11ModuleChild final : public PPKCS11ModuleChild { nsresult Start(Endpoint<PPKCS11ModuleChild>&& aEndpoint); + ipc::IPCResult RecvLoadModule(nsString&& aModule, + LoadModuleResolver&& aResolver); + private: nsCOMPtr<nsISerialEventTarget> mTaskQueue; diff --git a/security/manager/ssl/PPKCS11Module.ipdl b/security/manager/ssl/PPKCS11Module.ipdl @@ -10,6 +10,8 @@ namespace psm { [ChildProc=Utility] protocol PPKCS11Module { + child: + async LoadModule(nsString aModule) returns (nsresult rv); }; } // namespace psm diff --git a/security/manager/ssl/nsNSSComponent.cpp b/security/manager/ssl/nsNSSComponent.cpp @@ -1537,6 +1537,20 @@ nsresult nsNSSComponent::InitializeNSS() { GetCurrentSerialEventTarget(), __func__, [](RefPtr<PKCS11ModuleParent>&& parent) { MOZ_RELEASE_ASSERT(parent); + parent->SendLoadModule(u"MySecretModule"_ns) + ->Then( + GetCurrentSerialEventTarget(), __func__, + [](nsresult res) { + // We have a result from the utility process! + // Check that we successfully loaded MySecretModule. + MOZ_RELEASE_ASSERT(NS_SUCCEEDED(res)); + }, + [](ipc::ResponseRejectReason reason) { + // We ran into an IPC Error. + MOZ_LOG(gPIPNSSLog, LogLevel::Debug, + ("Loading MySecretModule failed: %d", + static_cast<int>(reason))); + }); }, [](base::LaunchError&& aError) { // We ran into a launch error. diff --git a/security/manager/ssl/tests/gtest/UtilityPKCS11ModuleTest.cpp b/security/manager/ssl/tests/gtest/UtilityPKCS11ModuleTest.cpp @@ -14,6 +14,8 @@ #include "mozilla/psm/PKCS11ModuleParent.h" #include "nsThreadUtils.h" +#include <vector> + using namespace mozilla; using namespace mozilla::gtest::ipc; using namespace mozilla::ipc; @@ -46,3 +48,39 @@ TEST_F(psm_UtilityPKCS11Module, Launch) { // Drain the event queue. NS_ProcessPendingEvents(nullptr); } + +TEST_F(psm_UtilityPKCS11Module, LoadModule) { + auto manager = UtilityProcessManager::GetSingleton(); + ASSERT_TRUE(manager); + + auto res = WaitFor(manager->StartPKCS11Module()); + ASSERT_TRUE(res.isOk()) + << "LaunchError: " << res.inspectErr().FunctionName() << ", " + << res.inspectErr().ErrorCode(); + + auto parent = res.unwrap(); + ASSERT_TRUE(parent); + ASSERT_TRUE(parent->CanSend()); + + std::vector<std::pair<nsString, nsresult>> expectedResultValues{ + std::make_pair(u"MySecretModule"_ns, NS_OK), + std::make_pair(u"AnyOtherModule"_ns, NS_ERROR_NOT_IMPLEMENTED)}; + for (const auto& [module, expected] : expectedResultValues) { + NS_ConvertUTF16toUTF8 utf8Module(module); + printf_stderr("Loading module %s\n", utf8Module.get()); + + auto ipcResult = WaitFor(parent->SendLoadModule(module)); + ASSERT_TRUE(ipcResult.isOk()) + << "ResponseRejectReason: " + << static_cast<std::underlying_type<ResponseRejectReason>::type>( + ipcResult.inspectErr()); + + auto result = ipcResult.inspect(); + ASSERT_EQ(result, expected); + } + + manager->CleanShutdown(SandboxingKind::PKCS11_MODULE); + + // Drain the event queue. + NS_ProcessPendingEvents(nullptr); +}