diff --git a/security/manager/ssl/src/CryptoTask.cpp b/security/manager/ssl/src/CryptoTask.cpp deleted file mode 100644 index 02000f0fffba..000000000000 --- a/security/manager/ssl/src/CryptoTask.cpp +++ /dev/null @@ -1,71 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#include "CryptoTask.h" - -namespace mozilla { - -CryptoTask::~CryptoTask() -{ - MOZ_ASSERT(mReleasedNSSResources); - - nsNSSShutDownPreventionLock lock; - if (!isAlreadyShutDown()) { - shutdown(calledFromObject); - } -} - -nsresult -CryptoTask::Dispatch(const nsACString & taskThreadName) -{ - nsCOMPtr thread; - nsresult rv = NS_NewThread(getter_AddRefs(thread), this); - if (thread) { - NS_SetThreadName(thread, taskThreadName); - } - return rv; -} - -NS_IMETHODIMP -CryptoTask::Run() -{ - if (!NS_IsMainThread()) { - nsNSSShutDownPreventionLock locker; - if (isAlreadyShutDown()) { - mRv = NS_ERROR_NOT_AVAILABLE; - } else { - mRv = CalculateResult(); - } - NS_DispatchToMainThread(this); - } else { - // back on the main thread - - // call ReleaseNSSResources now, before calling CallCallback, so that - // CryptoTasks have consistent behavior regardless of whether NSS is shut - // down between CalculateResult being called and CallCallback being called. - if (!mReleasedNSSResources) { - mReleasedNSSResources = true; - ReleaseNSSResources(); - } - - CallCallback(mRv); - } - - return NS_OK; -} - -void -CryptoTask::virtualDestroyNSSReference() -{ - NS_ABORT_IF_FALSE(NS_IsMainThread(), - "virtualDestroyNSSReference called off the main thread"); - if (!mReleasedNSSResources) { - mReleasedNSSResources = true; - ReleaseNSSResources(); - } -} - -} // namespace mozilla diff --git a/security/manager/ssl/src/CryptoTask.h b/security/manager/ssl/src/CryptoTask.h deleted file mode 100644 index 465b88f7cdd1..000000000000 --- a/security/manager/ssl/src/CryptoTask.h +++ /dev/null @@ -1,87 +0,0 @@ -/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* vim: set ts=2 et sw=2 tw=80: */ -/* This Source Code Form is subject to the terms of the Mozilla Public - * License, v. 2.0. If a copy of the MPL was not distributed with this file, - * You can obtain one at http://mozilla.org/MPL/2.0/. */ - -#ifndef mozilla__CryptoTask_h -#define mozilla__CryptoTask_h - -#include "mozilla/Attributes.h" -#include "nsThreadUtils.h" -#include "nsNSSShutDown.h" - -namespace mozilla { - -/** - * Frequently we need to run a task on a background thread without blocking - * the main thread, and then call a callback on the main thread with the - * result. This class provides the framework for that. Subclasses must: - * - * (1) Override CalculateResult for the off-the-main-thread computation. - * NSS functionality may only be accessed within CalculateResult. - * (2) Override ReleaseNSSResources to release references to all NSS - * resources (that do implement nsNSSShutDownObject themselves). - * (3) Override CallCallback() for the on-the-main-thread call of the - * callback. - * - * CalculateResult, ReleaseNSSResources, and CallCallback are called in order, - * except CalculateResult might be skipped if NSS is shut down before it can - * be called; in that case ReleaseNSSResources will be called and then - * CallCallback will be called with an error code. - */ -class CryptoTask : public nsRunnable, - public nsNSSShutDownObject -{ -public: - template - nsresult Dispatch(const char (&taskThreadName)[LEN]) - { - MOZ_STATIC_ASSERT(LEN <= 15, - "Thread name must be no more than 15 characters"); - return Dispatch(nsDependentCString(taskThreadName)); - } - -protected: - CryptoTask() - : mRv(NS_ERROR_NOT_INITIALIZED), - mReleasedNSSResources(false) - { - } - - virtual ~CryptoTask(); - - /** - * Called on a background thread (never the main thread). If CalculateResult - * is called, then its result will be passed to CallCallback on the main - * thread. - */ - virtual nsresult CalculateResult() = 0; - - /** - * Called on the main thread during NSS shutdown or just before CallCallback - * has been called. All NSS resources must be released. Usually, this just - * means assigning nullptr to the ScopedNSSType-based memory variables. - */ - virtual void ReleaseNSSResources() = 0; - - /** - * Called on the main thread with the result from CalculateResult() or - * with an error code if NSS was shut down before CalculateResult could - * be called. - */ - virtual void CallCallback(nsresult rv) = 0; - -private: - NS_IMETHOD Run() MOZ_OVERRIDE MOZ_FINAL; - virtual void virtualDestroyNSSReference() MOZ_OVERRIDE MOZ_FINAL; - - nsresult Dispatch(const nsACString & taskThreadName); - - nsresult mRv; - bool mReleasedNSSResources; -}; - -} // namespace mozilla - -#endif // mozilla__CryptoTask_h diff --git a/security/manager/ssl/src/Makefile.in b/security/manager/ssl/src/Makefile.in index 8bc4a34c17fa..99e9acf381bb 100644 --- a/security/manager/ssl/src/Makefile.in +++ b/security/manager/ssl/src/Makefile.in @@ -20,7 +20,6 @@ GRE_MODULE = 1 LIBXUL_LIBRARY = 1 CPPSRCS = \ - CryptoTask.cpp \ nsCERTValInParamWrapper.cpp \ nsNSSCleaner.cpp \ nsCertOverrideService.cpp \ @@ -91,7 +90,6 @@ DEFINES += \ $(NULL) EXPORTS += \ - CryptoTask.h \ nsNSSShutDown.h \ ScopedNSSTypes.h \ $(NULL) diff --git a/security/manager/ssl/src/ScopedNSSTypes.h b/security/manager/ssl/src/ScopedNSSTypes.h index 4a560f0e4a48..d5077b283785 100644 --- a/security/manager/ssl/src/ScopedNSSTypes.h +++ b/security/manager/ssl/src/ScopedNSSTypes.h @@ -7,8 +7,6 @@ #ifndef mozilla_ScopedNSSTypes_h #define mozilla_ScopedNSSTypes_h -#include "mozilla/Likely.h" -#include "mozilla/mozalloc_oom.h" #include "mozilla/Scoped.h" #include "prio.h" @@ -17,62 +15,9 @@ #include "keyhi.h" #include "pk11pub.h" #include "sechash.h" -#include "secpkcs7.h" -#include "prerror.h" namespace mozilla { -// It is very common to cast between char* and uint8_t* when doing crypto stuff. -// Here, we provide more type-safe wrappers around reinterpret_cast so you don't -// shoot yourself in the foot by reinterpret_casting completely unrelated types. - -inline char * -char_ptr_cast(uint8_t * p) { return reinterpret_cast(p); } - -inline const char * -char_ptr_cast(const uint8_t * p) { return reinterpret_cast(p); } - -inline uint8_t * -uint8_t_ptr_cast(char * p) { return reinterpret_cast(p); } - -inline const uint8_t * -uint8_t_ptr_cast(const char * p) { return reinterpret_cast(p); } - -// NSPR APIs use PRStatus/PR_GetError and NSS APIs use SECStatus/PR_GetError to -// report success/failure. These funtions make it more convenient and *safer* -// to translate NSPR/NSS results to nsresult. They are safer because they -// refuse to traslate any bad PRStatus/SECStatus into an NS_OK, even when the -// NSPR/NSS function forgot to call PR_SetError. - -// IMPORTANT: This must be called immediately after the function that set the -// error code. Prefer using MapSECStatus to this. -inline nsresult -PRErrorCode_to_nsresult(PRErrorCode error) -{ - if (!error) { - MOZ_NOT_REACHED("Function failed without calling PR_GetError"); - return NS_ERROR_UNEXPECTED; - } - - // From NSSErrorsService::GetXPCOMFromNSSError - // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113) - return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY, - -1 * error); -} - -// IMPORTANT: This must be called immediately after the function returning the -// SECStatus result. The recommended usage is: -// nsresult rv = MapSECStatus(f(x, y, z)); -inline nsresult -MapSECStatus(SECStatus rv) -{ - if (rv == SECSuccess) - return NS_OK; - - PRErrorCode error = PR_GetError(); - return PRErrorCode_to_nsresult(error); -} - // Alphabetical order by NSS type MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPRFileDesc, PRFileDesc, @@ -102,6 +47,10 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedCERTValidity, CERTValidity, CERT_DestroyValidity) +MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedHASHContext, + HASHContext, + HASH_Destroy) + MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSMessage, NSSCMSMessage, NSS_CMSMessage_Destroy) @@ -109,93 +58,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedNSSCMSSignedData, NSSCMSSignedData, NSS_CMSSignedData_Destroy) -namespace psm { - -inline void -PK11_DestroyContext_true(PK11Context * ctx) { - PK11_DestroyContext(ctx, true); -} - -} // namespace mozilla::psm - -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11Context, - PK11Context, - mozilla::psm::PK11_DestroyContext_true) - -/** A more convenient way of dealing with digests calculated into - * stack-allocated buffers. - * - * Typical usage, for digesting a buffer in memory: - * - * Digest digest; - * nsresult rv = digest.DigestBuf(SEC_OID_SHA256, mybuffer, myBufferLen); - * NS_ENSURE_SUCCESS(rv, rv); - * rv = MapSECStatus(SomeNSSFunction(..., digest.get(), ...)); - * - * Less typical usage, for digesting while doing streaming I/O and similar: - * - * Digest digest; - * ScopedPK11Context digestContext(PK11_CreateDigestContext(SEC_OID_SHA1)); - * NS_ENSURE_TRUE(digestContext, NS_ERROR_OUT_OF_MEMORY); - * rv = MapSECStatus(PK11_DigestBegin(digestContext)); - * NS_ENSURE_SUCCESS(rv, rv); - * for (...) { - * rv = MapSECStatus(PK11_DigestOp(digestContext, ...)); - * NS_ENSURE_SUCCESS(rv, rv); - * } - * rv = digestContext.End(SEC_OID_SHA1, digestContext); - * NS_ENSURE_SUCCESS(rv, rv) - */ -class Digest -{ -public: - Digest() - { - item.type = siBuffer; - item.data = buf; - item.len = 0; - } - - nsresult DigestBuf(SECOidTag hashAlg, const uint8_t * buf, uint32_t len) - { - nsresult rv = SetLength(hashAlg); - NS_ENSURE_SUCCESS(rv, rv); - return MapSECStatus(PK11_HashBuf(hashAlg, item.data, buf, len)); - } - - nsresult End(SECOidTag hashAlg, ScopedPK11Context & context) - { - nsresult rv = SetLength(hashAlg); - NS_ENSURE_SUCCESS(rv, rv); - uint32_t len; - rv = MapSECStatus(PK11_DigestFinal(context, item.data, &len, item.len)); - NS_ENSURE_SUCCESS(rv, rv); - context = nullptr; - NS_ENSURE_TRUE(len == item.len, NS_ERROR_UNEXPECTED); - return NS_OK; - } - - const SECItem & get() const { return item; } - -private: - nsresult SetLength(SECOidTag hashType) - { - switch (hashType) - { - case SEC_OID_SHA1: item.len = SHA1_LENGTH; break; - case SEC_OID_SHA256: item.len = SHA256_LENGTH; break; - case SEC_OID_SHA384: item.len = SHA384_LENGTH; break; - case SEC_OID_SHA512: item.len = SHA512_LENGTH; break; - default: - return NS_ERROR_INVALID_ARG; - } - - return NS_OK; - } - - uint8_t buf[HASH_LENGTH_MAX]; - SECItem item; -}; MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SlotInfo, PK11SlotInfo, @@ -207,59 +69,6 @@ MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedPK11SymKey, PK11SymKey, PK11_FreeSymKey) -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSEC_PKCS7ContentInfo, - SEC_PKCS7ContentInfo, - SEC_PKCS7DestroyContentInfo) - -// Wrapper around NSS's SECItem_AllocItem that handles OOM the same way as -// other allocators. -inline void -SECITEM_AllocItem(SECItem & item, uint32_t len) -{ - if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) { - mozalloc_handle_oom(len); - if (MOZ_UNLIKELY(!SECITEM_AllocItem(nullptr, &item, len))) { - MOZ_CRASH(); - } - } -} - -class ScopedAutoSECItem MOZ_FINAL : public SECItem -{ -public: - ScopedAutoSECItem(uint32_t initialAllocatedLen = 0) - { - data = NULL; - len = 0; - if (initialAllocatedLen > 0) { - SECITEM_AllocItem(*this, initialAllocatedLen); - } - } - - void reset() - { - SECITEM_FreeItem(this, false); - } - - ~ScopedAutoSECItem() - { - reset(); - } -}; - -namespace psm { - -inline void SECITEM_FreeItem_true(SECItem * s) -{ - return SECITEM_FreeItem(s, true); -} - -} // namespace impl - -MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECItem, - ::SECItem, - ::mozilla::psm::SECITEM_FreeItem_true) - MOZ_TYPE_SPECIFIC_SCOPED_POINTER_TEMPLATE(ScopedSECKEYPrivateKey, SECKEYPrivateKey, SECKEY_DestroyPrivateKey) diff --git a/security/manager/ssl/src/nsNSSComponent.cpp b/security/manager/ssl/src/nsNSSComponent.cpp index 3a93e8c482a6..a9d703f95ee2 100644 --- a/security/manager/ssl/src/nsNSSComponent.cpp +++ b/security/manager/ssl/src/nsNSSComponent.cpp @@ -55,7 +55,6 @@ #include "nsNSSShutDown.h" #include "nsSmartCardEvent.h" #include "nsIKeyModule.h" -#include "ScopedNSSTypes.h" #include "nss.h" #include "pk11func.h" @@ -2029,7 +2028,7 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen, *aPrincipal = nullptr; nsNSSShutDownPreventionLock locker; - ScopedSEC_PKCS7ContentInfo p7_info; + SEC_PKCS7ContentInfo * p7_info = nullptr; unsigned char hash[SHA1_LENGTH]; SECItem item; @@ -2128,6 +2127,8 @@ nsNSSComponent::VerifySignature(const char* aRSABuf, uint32_t aRSABufLen, } while (0); } + SEC_PKCS7DestroyContentInfo(p7_info); + return rv2; } diff --git a/toolkit/identity/IdentityCryptoService.cpp b/toolkit/identity/IdentityCryptoService.cpp index d476103ce658..707636ced19d 100644 --- a/toolkit/identity/IdentityCryptoService.cpp +++ b/toolkit/identity/IdentityCryptoService.cpp @@ -13,7 +13,6 @@ #include "nsCOMPtr.h" #include "nsStringGlue.h" #include "mozilla/Base64.h" -#include "ScopedNSSTypes.h" #include "nss.h" #include "pk11pub.h" @@ -61,6 +60,34 @@ Base64UrlEncodeImpl(const nsACString & utf8Input, nsACString & result) return NS_OK; } + +nsresult +PRErrorCode_to_nsresult(PRErrorCode error) +{ + if (!error) { + MOZ_NOT_REACHED("Function failed without calling PR_GetError"); + return NS_ERROR_UNEXPECTED; + } + + // From NSSErrorsService::GetXPCOMFromNSSError + // XXX Don't make up nsresults, it's supposed to be an enum (bug 778113) + return (nsresult)NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_SECURITY, + -1 * error); +} + +// IMPORTANT: This must be called immediately after the function returning the +// SECStatus result. The recommended usage is: +// nsresult rv = MapSECStatus(f(x, y, z)); +nsresult +MapSECStatus(SECStatus rv) +{ + if (rv == SECSuccess) + return NS_OK; + + PRErrorCode error = PR_GetError(); + return PRErrorCode_to_nsresult(error); +} + #define DSA_KEY_TYPE_STRING (NS_LITERAL_CSTRING("DS160")) #define RSA_KEY_TYPE_STRING (NS_LITERAL_CSTRING("RS256"))