diff --git a/security/manager/ssl/src/CryptoTask.cpp b/security/manager/ssl/src/CryptoTask.cpp index ba34d7398e2..016d997b2a7 100644 --- a/security/manager/ssl/src/CryptoTask.cpp +++ b/security/manager/ssl/src/CryptoTask.cpp @@ -5,6 +5,7 @@ * You can obtain one at http://mozilla.org/MPL/2.0/. */ #include "CryptoTask.h" +#include "nsNSSComponent.h" namespace mozilla { @@ -18,6 +19,29 @@ CryptoTask::~CryptoTask() } } +nsresult +CryptoTask::Dispatch(const nsACString& taskThreadName) +{ + MOZ_ASSERT(taskThreadName.Length() <= 15); + + // Ensure that NSS is initialized, since presumably CalculateResult + // will use NSS functions + if (!EnsureNSSInitializedChromeOrContent()) { + return NS_ERROR_FAILURE; + } + + // Can't add 'this' as the event to run, since mThread may not be set yet + nsresult rv = NS_NewThread(getter_AddRefs(mThread), nullptr, + nsIThreadManager::DEFAULT_STACK_SIZE); + if (NS_FAILED(rv)) { + return rv; + } + + NS_SetThreadName(mThread, taskThreadName); + // Note: event must not null out mThread! + return mThread->Dispatch(this, NS_DISPATCH_NORMAL); +} + NS_IMETHODIMP CryptoTask::Run() { diff --git a/security/manager/ssl/src/CryptoTask.h b/security/manager/ssl/src/CryptoTask.h index ec7a35b626f..d2f78084786 100644 --- a/security/manager/ssl/src/CryptoTask.h +++ b/security/manager/ssl/src/CryptoTask.h @@ -50,15 +50,11 @@ public: { static_assert(LEN <= 15, "Thread name must be no more than 15 characters"); - // Can't add 'this' as the event to run, since mThread may not be set yet - nsresult rv = NS_NewNamedThread(taskThreadName, getter_AddRefs(mThread)); - if (NS_SUCCEEDED(rv)) { - // Note: event must not null out mThread! - rv = mThread->Dispatch(this, NS_DISPATCH_NORMAL); - } - return rv; + return Dispatch(NS_LITERAL_CSTRING(taskThreadName)); } + nsresult Dispatch(const nsACString& taskThreadName); + void Skip() { virtualDestroyNSSReference(); diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 4bacbe60398..47a7f05ffcb 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -127,6 +127,40 @@ nsTokenEventRunnable::Run() bool nsPSMInitPanic::isPanic = false; +// This function can be called from chrome or content processes +// to ensure that NSS is initialized. +bool EnsureNSSInitializedChromeOrContent() +{ + nsresult rv; + if (XRE_GetProcessType() == GeckoProcessType_Default) { + nsCOMPtr nss = do_GetService(PSM_COMPONENT_CONTRACTID, &rv); + if (NS_FAILED(rv)) { + return false; + } + + return true; + } + + if (!NS_IsMainThread()) { + return false; + } + + if (NSS_IsInitialized()) { + return true; + } + + if (NSS_NoDB_Init(nullptr) != SECSuccess) { + return false; + } + + if (NS_FAILED(mozilla::psm::InitializeCipherSuite())) { + return false; + } + + mozilla::psm::DisableMD5(); + return true; +} + // We must ensure that the nsNSSComponent has been loaded before // creating any other components. bool EnsureNSSInitialized(EnsureNSSOperator op) diff --git a/security/manager/ssl/src/nsNSSComponent.h b/security/manager/ssl/src/nsNSSComponent.h index a5a0e2912c9..79937ca389e 100644 --- a/security/manager/ssl/src/nsNSSComponent.h +++ b/security/manager/ssl/src/nsNSSComponent.h @@ -61,6 +61,8 @@ enum EnsureNSSOperator nssEnsureOnChromeOnly = 101 }; +extern bool EnsureNSSInitializedChromeOrContent(); + extern bool EnsureNSSInitialized(EnsureNSSOperator op); class nsNSSComponent;