tor-browser

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

nsNSSModule.cpp (3769B)


      1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
      2 *
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include "nsNSSModule.h"
      8 
      9 #include "ContentSignatureVerifier.h"
     10 #include "OSKeyStore.h"
     11 #include "OSReauthenticator.h"
     12 #include "PKCS11ModuleDB.h"
     13 #include "SecretDecoderRing.h"
     14 #include "mozilla/ModuleUtils.h"
     15 #include "mozilla/SyncRunnable.h"
     16 #include "nsCertTree.h"
     17 #include "nsNSSCertificateDB.h"
     18 #include "nsPK11TokenDB.h"
     19 #include "nsRandomGenerator.h"
     20 #include "nsXULAppAPI.h"
     21 
     22 namespace mozilla {
     23 namespace psm {
     24 
     25 // Many of the implementations in this module call NSS functions and as a result
     26 // require that PSM has successfully initialized NSS before being used.
     27 // Additionally, some of the implementations have various restrictions on which
     28 // process and threads they can be used on (e.g. some can only be used in the
     29 // parent process and some must be initialized only on the main thread).
     30 // The following initialization framework allows these requirements to be
     31 // succinctly expressed and implemented.
     32 
     33 template <class InstanceClass, nsresult (InstanceClass::*InitMethod)()>
     34 MOZ_ALWAYS_INLINE static nsresult Instantiate(REFNSIID aIID, void** aResult) {
     35  InstanceClass* inst = new InstanceClass();
     36  NS_ADDREF(inst);
     37  nsresult rv = InitMethod != nullptr ? (inst->*InitMethod)() : NS_OK;
     38  if (NS_SUCCEEDED(rv)) {
     39    rv = inst->QueryInterface(aIID, aResult);
     40  }
     41  NS_RELEASE(inst);
     42  return rv;
     43 }
     44 
     45 enum class ThreadRestriction {
     46  // must be initialized on the main thread (but can be used on any thread)
     47  MainThreadOnly,
     48  // can be initialized and used on any thread
     49  AnyThread,
     50 };
     51 
     52 enum class ProcessRestriction {
     53  ParentProcessOnly,
     54  AnyProcess,
     55 };
     56 
     57 template <class InstanceClass,
     58          nsresult (InstanceClass::*InitMethod)() = nullptr,
     59          ProcessRestriction processRestriction =
     60              ProcessRestriction::ParentProcessOnly,
     61          ThreadRestriction threadRestriction = ThreadRestriction::AnyThread>
     62 static nsresult Constructor(REFNSIID aIID, void** aResult) {
     63  *aResult = nullptr;
     64 
     65  if (processRestriction == ProcessRestriction::ParentProcessOnly &&
     66      !XRE_IsParentProcess()) {
     67    return NS_ERROR_NOT_AVAILABLE;
     68  }
     69 
     70  if (!EnsureNSSInitializedChromeOrContent()) {
     71    return NS_ERROR_FAILURE;
     72  }
     73 
     74  if (threadRestriction == ThreadRestriction::MainThreadOnly &&
     75      !NS_IsMainThread()) {
     76    return NS_ERROR_NOT_SAME_THREAD;
     77  }
     78 
     79  return Instantiate<InstanceClass, InitMethod>(aIID, aResult);
     80 }
     81 
     82 #define IMPL(type, ...)                                              \
     83  template <>                                                        \
     84  nsresult NSSConstructor<type>(const nsIID& aIID, void** aResult) { \
     85    return Constructor<type, __VA_ARGS__>(aIID, aResult);            \
     86  }
     87 
     88 // Components that require main thread initialization could cause a deadlock
     89 // in necko code (bug 1418752). To prevent it we initialize all such components
     90 // on main thread in advance in net_EnsurePSMInit(). Update that function when
     91 // new component with ThreadRestriction::MainThreadOnly is added.
     92 IMPL(SecretDecoderRing, nullptr)
     93 IMPL(nsPK11TokenDB, nullptr)
     94 IMPL(PKCS11ModuleDB, nullptr)
     95 IMPL(nsNSSCertificateDB, nullptr)
     96 IMPL(nsCertTree, nullptr)
     97 IMPL(ContentSignatureVerifier, nullptr)
     98 IMPL(nsRandomGenerator, nullptr, ProcessRestriction::AnyProcess)
     99 IMPL(OSKeyStore, nullptr, ProcessRestriction::ParentProcessOnly,
    100     ThreadRestriction::MainThreadOnly)
    101 IMPL(OSReauthenticator, nullptr, ProcessRestriction::ParentProcessOnly,
    102     ThreadRestriction::MainThreadOnly)
    103 #undef IMPL
    104 
    105 }  // namespace psm
    106 }  // namespace mozilla