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 #ifndef _nsNSSComponent_h_
8 #define _nsNSSComponent_h_
9 
10 #include "nsINSSComponent.h"
11 
12 #include "EnterpriseRoots.h"
13 #include "ScopedNSSTypes.h"
14 #include "SharedCertVerifier.h"
15 #include "mozilla/Attributes.h"
16 #include "mozilla/Monitor.h"
17 #include "mozilla/Mutex.h"
18 #include "mozilla/RefPtr.h"
19 #include "nsCOMPtr.h"
20 #include "nsIObserver.h"
21 #include "nsNSSCallbacks.h"
22 #include "prerror.h"
23 #include "sslt.h"
24 
25 #ifdef XP_WIN
26 #  include "windows.h"  // this needs to be before the following includes
27 #  include "wincrypt.h"
28 #endif  // XP_WIN
29 
30 class nsIDOMWindow;
31 class nsIPrompt;
32 class SmartCardThreadList;
33 
34 namespace mozilla {
35 namespace psm {
36 
37 MOZ_MUST_USE
38 ::already_AddRefed<mozilla::psm::SharedCertVerifier> GetDefaultCertVerifier();
39 UniqueCERTCertList FindClientCertificatesWithPrivateKeys();
40 
41 }  // namespace psm
42 }  // namespace mozilla
43 
44 #define NS_NSSCOMPONENT_CID                          \
45   {                                                  \
46     0x4cb64dfd, 0xca98, 0x4e24, {                    \
47       0xbe, 0xfd, 0x0d, 0x92, 0x85, 0xa3, 0x3b, 0xcb \
48     }                                                \
49   }
50 
51 extern bool EnsureNSSInitializedChromeOrContent();
52 extern bool HandleTLSPrefChange(const nsCString& aPref);
53 extern void SetValidationOptionsCommon();
54 extern void NSSShutdownForSocketProcess();
55 
56 // Implementation of the PSM component interface.
57 class nsNSSComponent final : public nsINSSComponent, public nsIObserver {
58  public:
59   // LoadLoadableCertsTask updates mLoadableCertsLoaded and
60   // mLoadableCertsLoadedResult and then signals mLoadableCertsLoadedMonitor.
61   friend class LoadLoadableCertsTask;
62   // BackgroundImportEnterpriseCertsTask calls ImportEnterpriseRoots and
63   // UpdateCertVerifierWithEnterpriseRoots.
64   friend class BackgroundImportEnterpriseCertsTask;
65 
66   nsNSSComponent();
67 
68   NS_DECL_THREADSAFE_ISUPPORTS
69   NS_DECL_NSINSSCOMPONENT
70   NS_DECL_NSIOBSERVER
71 
72   nsresult Init();
73 
74   static nsresult GetNewPrompter(nsIPrompt** result);
75 
76   static void FillTLSVersionRange(SSLVersionRange& rangeOut,
77                                   uint32_t minFromPrefs, uint32_t maxFromPrefs,
78                                   SSLVersionRange defaults);
79 
80   static nsresult SetEnabledTLSVersions();
81 
82   // This function should be only called on parent process.
83   // When socket process is enabled, this function sends an IPC to clear the
84   // SSLTokensCache in socket process. If not,
85   // DoClearSSLExternalAndInternalSessionCache() will be called.
86   static void ClearSSLExternalAndInternalSessionCacheNative();
87   // This function does the actual work of clearing the session cache.
88   static void DoClearSSLExternalAndInternalSessionCache();
89 
90  protected:
91   virtual ~nsNSSComponent();
92 
93  private:
94   nsresult InitializeNSS();
95   void ShutdownNSS();
96 
97   void setValidationOptions(bool isInitialSetting,
98                             const mozilla::MutexAutoLock& proofOfLock);
99   void UpdateCertVerifierWithEnterpriseRoots();
100   nsresult RegisterObservers();
101 
102   void MaybeImportEnterpriseRoots();
103   void ImportEnterpriseRoots();
104   void UnloadEnterpriseRoots();
105   nsresult CommonGetEnterpriseCerts(
106       nsTArray<nsTArray<uint8_t>>& enterpriseCerts, bool getRoots);
107 
108   bool ShouldEnableEnterpriseRootsForFamilySafety(uint32_t familySafetyMode);
109 
110   // mLoadableCertsLoadedMonitor protects mLoadableCertsLoaded.
111   mozilla::Monitor mLoadableCertsLoadedMonitor;
112   bool mLoadableCertsLoaded;
113   nsresult mLoadableCertsLoadedResult;
114 
115   // mMutex protects all members that are accessed from more than one thread.
116   mozilla::Mutex mMutex;
117 
118   // The following members are accessed from more than one thread:
119 
120 #ifdef DEBUG
121   nsString mTestBuiltInRootHash;
122 #endif
123   nsString mContentSigningRootHash;
124   RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier;
125   nsString mMitmCanaryIssuer;
126   bool mMitmDetecionEnabled;
127   mozilla::Vector<EnterpriseCert> mEnterpriseCerts;
128 
129   // The following members are accessed only on the main thread:
130   static int mInstanceCount;
131   // If InitializeNSS succeeds, then we have dispatched an event to load the
132   // loadable roots module, enterprise certificates (if enabled), and the os
133   // client certs module (if enabled) on a background thread. We must wait for
134   // it to complete before attempting to unload the modules again in
135   // ShutdownNSS. If we never dispatched the event, then we can't wait for it
136   // to complete (because it will never complete) so we use this boolean to keep
137   // track of if we should wait.
138   bool mLoadLoadableCertsTaskDispatched;
139 };
140 
BlockUntilLoadableCertsLoaded()141 inline nsresult BlockUntilLoadableCertsLoaded() {
142   nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
143   if (!component) {
144     return NS_ERROR_FAILURE;
145   }
146   return component->BlockUntilLoadableCertsLoaded();
147 }
148 
CheckForSmartCardChanges()149 inline nsresult CheckForSmartCardChanges() {
150 #ifndef MOZ_NO_SMART_CARDS
151   nsCOMPtr<nsINSSComponent> component(do_GetService(PSM_COMPONENT_CONTRACTID));
152   if (!component) {
153     return NS_ERROR_FAILURE;
154   }
155   return component->CheckForSmartCardChanges();
156 #else
157   return NS_OK;
158 #endif
159 }
160 
161 #endif  // _nsNSSComponent_h_
162