1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* 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 "nsNSSModule.h"
#include "ContentSignatureVerifier.h"
#include "NSSErrorsService.h"
#include "OSKeyStore.h"
#include "OSReauthenticator.h"
#include "PKCS11ModuleDB.h"
#include "SecretDecoderRing.h"
#include "TransportSecurityInfo.h"
#include "mozilla/MacroArgs.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/SyncRunnable.h"
#include "nsCURILoader.h"
#include "nsCryptoHash.h"
#include "nsKeyModule.h"
#include "nsNSSCertificate.h"
#include "nsNSSCertificateDB.h"
#include "nsNSSComponent.h"
#include "nsNSSVersion.h"
#include "nsNetCID.h"
#include "nsPK11TokenDB.h"
#include "nsPKCS11Slot.h"
#include "nsRandomGenerator.h"
#include "nsSecureBrowserUI.h"
#include "nsXULAppAPI.h"
#ifdef MOZ_XUL
# include "nsCertTree.h"
#endif
namespace mozilla {
namespace psm {
// Many of the implementations in this module call NSS functions and as a result
// require that PSM has successfully initialized NSS before being used.
// Additionally, some of the implementations have various restrictions on which
// process and threads they can be used on (e.g. some can only be used in the
// parent process and some must be initialized only on the main thread).
// The following initialization framework allows these requirements to be
// succinctly expressed and implemented.
template <class InstanceClass, nsresult (InstanceClass::*InitMethod)()>
MOZ_ALWAYS_INLINE static nsresult Instantiate(REFNSIID aIID, void** aResult) {
InstanceClass* inst = new InstanceClass();
NS_ADDREF(inst);
nsresult rv = InitMethod != nullptr ? (inst->*InitMethod)() : NS_OK;
if (NS_SUCCEEDED(rv)) {
rv = inst->QueryInterface(aIID, aResult);
}
NS_RELEASE(inst);
return rv;
}
enum class ThreadRestriction {
// must be initialized on the main thread (but can be used on any thread)
MainThreadOnly,
// can be initialized and used on any thread
AnyThread,
};
enum class ProcessRestriction {
ParentProcessOnly,
AnyProcess,
};
template <class InstanceClass,
nsresult (InstanceClass::*InitMethod)() = nullptr,
ProcessRestriction processRestriction =
ProcessRestriction::ParentProcessOnly,
ThreadRestriction threadRestriction = ThreadRestriction::AnyThread>
static nsresult Constructor(nsISupports* aOuter, REFNSIID aIID,
void** aResult) {
*aResult = nullptr;
if (aOuter != nullptr) {
return NS_ERROR_NO_AGGREGATION;
}
if (processRestriction == ProcessRestriction::ParentProcessOnly &&
!XRE_IsParentProcess()) {
return NS_ERROR_NOT_AVAILABLE;
}
if (!EnsureNSSInitializedChromeOrContent()) {
return NS_ERROR_FAILURE;
}
if (threadRestriction == ThreadRestriction::MainThreadOnly &&
!NS_IsMainThread()) {
return NS_ERROR_NOT_SAME_THREAD;
}
return Instantiate<InstanceClass, InitMethod>(aIID, aResult);
}
#define IMPL(type, ...) \
template <> \
nsresult NSSConstructor<type>(nsISupports * aOuter, const nsIID& aIID, \
void** aResult) { \
return Constructor<type, __VA_ARGS__>(aOuter, aIID, aResult); \
}
// Components that require main thread initialization could cause a deadlock
// in necko code (bug 1418752). To prevent it we initialize all such components
// on main thread in advance in net_EnsurePSMInit(). Update that function when
// new component with ThreadRestriction::MainThreadOnly is added.
IMPL(SecretDecoderRing, nullptr)
IMPL(nsPK11TokenDB, nullptr)
IMPL(PKCS11ModuleDB, nullptr)
IMPL(nsNSSCertificate, nullptr, ProcessRestriction::AnyProcess)
IMPL(nsNSSCertificateDB, nullptr)
#ifdef MOZ_XUL
IMPL(nsCertTree, nullptr)
#endif
IMPL(nsCryptoHash, nullptr, ProcessRestriction::AnyProcess)
IMPL(nsCryptoHMAC, nullptr, ProcessRestriction::AnyProcess)
IMPL(nsKeyObject, nullptr, ProcessRestriction::AnyProcess)
IMPL(nsKeyObjectFactory, nullptr, ProcessRestriction::AnyProcess)
IMPL(ContentSignatureVerifier, nullptr)
IMPL(nsRandomGenerator, nullptr, ProcessRestriction::AnyProcess)
IMPL(TransportSecurityInfo, nullptr, ProcessRestriction::AnyProcess)
IMPL(OSKeyStore, nullptr, ProcessRestriction::ParentProcessOnly,
ThreadRestriction::MainThreadOnly)
IMPL(OSReauthenticator, nullptr, ProcessRestriction::ParentProcessOnly,
ThreadRestriction::MainThreadOnly)
#undef IMPL
} // namespace psm
} // namespace mozilla
|