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 "nsNSSComponent.h"
8
9 #include "ExtendedValidation.h"
10 #include "NSSCertDBTrustDomain.h"
11 #include "ScopedNSSTypes.h"
12 #include "SharedSSLState.h"
13 #include "cert.h"
14 #include "certdb.h"
15 #include "mozStorageCID.h"
16 #include "mozilla/ArrayUtils.h"
17 #include "mozilla/Casting.h"
18 #include "mozilla/Preferences.h"
19 #include "mozilla/PublicSSL.h"
20 #include "mozilla/Services.h"
21 #include "mozilla/StaticPtr.h"
22 #include "mozilla/SyncRunnable.h"
23 #include "mozilla/Telemetry.h"
24 #include "mozilla/Unused.h"
25 #include "nsAppDirectoryServiceDefs.h"
26 #include "nsCRT.h"
27 #include "nsClientAuthRemember.h"
28 #include "nsComponentManagerUtils.h"
29 #include "nsDirectoryServiceDefs.h"
30 #include "nsICertOverrideService.h"
31 #include "nsIFile.h"
32 #include "nsIObserverService.h"
33 #include "nsIPrompt.h"
34 #include "nsIProperties.h"
35 #include "nsISiteSecurityService.h"
36 #include "nsITokenPasswordDialogs.h"
37 #include "nsIWindowWatcher.h"
38 #include "nsIXULRuntime.h"
39 #include "nsNSSCertificateDB.h"
40 #include "nsNSSHelper.h"
41 #include "nsNSSShutDown.h"
42 #include "nsServiceManagerUtils.h"
43 #include "nsThreadUtils.h"
44 #include "nsXULAppAPI.h"
45 #include "nss.h"
46 #include "p12plcy.h"
47 #include "pkix/pkixnss.h"
48 #include "secerr.h"
49 #include "secmod.h"
50 #include "ssl.h"
51 #include "sslerr.h"
52 #include "sslproto.h"
53
54 #ifndef MOZ_NO_SMART_CARDS
55 #include "nsSmartCardMonitor.h"
56 #endif
57
58 #ifdef XP_WIN
59 #include "mozilla/WindowsVersion.h"
60 #include "nsILocalFileWin.h"
61
62 #include "windows.h" // this needs to be before the following includes
63 #include "lmcons.h"
64 #include "sddl.h"
65 #include "wincrypt.h"
66 #include "nsIWindowsRegKey.h"
67 #endif
68
69 using namespace mozilla;
70 using namespace mozilla::psm;
71
72 LazyLogModule gPIPNSSLog("pipnss");
73
74 int nsNSSComponent::mInstanceCount = 0;
75
76 // This function can be called from chrome or content processes
77 // to ensure that NSS is initialized.
EnsureNSSInitializedChromeOrContent()78 bool EnsureNSSInitializedChromeOrContent()
79 {
80 nsresult rv;
81 if (XRE_IsParentProcess()) {
82 nsCOMPtr<nsISupports> nss = do_GetService(PSM_COMPONENT_CONTRACTID, &rv);
83 if (NS_FAILED(rv)) {
84 return false;
85 }
86
87 return true;
88 }
89
90 // If this is a content process and not the main thread (i.e. probably a
91 // worker) then forward this call to the main thread.
92 if (!NS_IsMainThread()) {
93 static Atomic<bool> initialized(false);
94
95 // Cache the result to dispatch to the main thread only once per worker.
96 if (initialized) {
97 return true;
98 }
99
100 nsCOMPtr<nsIThread> mainThread;
101 nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread));
102 if (NS_FAILED(rv)) {
103 return false;
104 }
105
106 // Forward to the main thread synchronously.
107 mozilla::SyncRunnable::DispatchToThread(mainThread,
108 new SyncRunnable(NS_NewRunnableFunction([]() {
109 initialized = EnsureNSSInitializedChromeOrContent();
110 }))
111 );
112
113 return initialized;
114 }
115
116 if (NSS_IsInitialized()) {
117 return true;
118 }
119
120 if (NSS_NoDB_Init(nullptr) != SECSuccess) {
121 return false;
122 }
123
124 if (NS_FAILED(mozilla::psm::InitializeCipherSuite())) {
125 return false;
126 }
127
128 mozilla::psm::DisableMD5();
129 return true;
130 }
131
132 // We must ensure that the nsNSSComponent has been loaded before
133 // creating any other components.
EnsureNSSInitialized(EnsureNSSOperator op)134 bool EnsureNSSInitialized(EnsureNSSOperator op)
135 {
136 if (GeckoProcessType_Default != XRE_GetProcessType())
137 {
138 if (op == nssEnsureOnChromeOnly)
139 {
140 // If the component needs PSM/NSS initialized only on the chrome process,
141 // pretend we successfully initiated it but in reality we bypass it.
142 // It's up to the programmer to check for process type in such components
143 // and take care not to call anything that needs NSS/PSM initiated.
144 return true;
145 }
146
147 NS_ERROR("Trying to initialize PSM/NSS in a non-chrome process!");
148 return false;
149 }
150
151 static bool loading = false;
152 static int32_t haveLoaded = 0;
153
154 switch (op)
155 {
156 // In following 4 cases we are protected by monitor of XPCOM component
157 // manager - we are inside of do_GetService call for nss component, so it is
158 // safe to move with the flags here.
159 case nssLoadingComponent:
160 if (loading)
161 return false; // We are reentered during nss component creation
162 loading = true;
163 return true;
164
165 case nssInitSucceeded:
166 NS_ASSERTION(loading, "Bad call to EnsureNSSInitialized(nssInitSucceeded)");
167 loading = false;
168 PR_AtomicSet(&haveLoaded, 1);
169 return true;
170
171 case nssInitFailed:
172 NS_ASSERTION(loading, "Bad call to EnsureNSSInitialized(nssInitFailed)");
173 loading = false;
174 MOZ_FALLTHROUGH;
175
176 case nssShutdown:
177 PR_AtomicSet(&haveLoaded, 0);
178 return false;
179
180 // In this case we are called from a component to ensure nss initilization.
181 // If the component has not yet been loaded and is not currently loading
182 // call do_GetService for nss component to ensure it.
183 case nssEnsure:
184 case nssEnsureOnChromeOnly:
185 case nssEnsureChromeOrContent:
186 // We are reentered during nss component creation or nss component is already up
187 if (PR_AtomicAdd(&haveLoaded, 0) || loading)
188 return true;
189
190 {
191 nsCOMPtr<nsINSSComponent> nssComponent
192 = do_GetService(PSM_COMPONENT_CONTRACTID);
193
194 // Nss component failed to initialize, inform the caller of that fact.
195 // Flags are appropriately set by component constructor itself.
196 if (!nssComponent)
197 return false;
198
199 bool isInitialized;
200 nsresult rv = nssComponent->IsNSSInitialized(&isInitialized);
201 return NS_SUCCEEDED(rv) && isInitialized;
202 }
203
204 default:
205 NS_ASSERTION(false, "Bad operator to EnsureNSSInitialized");
206 return false;
207 }
208 }
209
210 static void
GetRevocationBehaviorFromPrefs(CertVerifier::OcspDownloadConfig * odc,CertVerifier::OcspStrictConfig * osc,CertVerifier::OcspGetConfig * ogc,uint32_t * certShortLifetimeInDays,const MutexAutoLock &)211 GetRevocationBehaviorFromPrefs(/*out*/ CertVerifier::OcspDownloadConfig* odc,
212 /*out*/ CertVerifier::OcspStrictConfig* osc,
213 /*out*/ CertVerifier::OcspGetConfig* ogc,
214 /*out*/ uint32_t* certShortLifetimeInDays,
215 const MutexAutoLock& /*proofOfLock*/)
216 {
217 MOZ_ASSERT(NS_IsMainThread());
218 MOZ_ASSERT(odc);
219 MOZ_ASSERT(osc);
220 MOZ_ASSERT(ogc);
221 MOZ_ASSERT(certShortLifetimeInDays);
222
223 // 0 = disabled
224 // 1 = enabled for everything (default)
225 // 2 = enabled for EV certificates only
226 int32_t ocspLevel = Preferences::GetInt("security.OCSP.enabled", 1);
227 switch (ocspLevel) {
228 case 0: *odc = CertVerifier::ocspOff; break;
229 case 2: *odc = CertVerifier::ocspEVOnly; break;
230 default: *odc = CertVerifier::ocspOn; break;
231 }
232
233 *osc = Preferences::GetBool("security.OCSP.require", false)
234 ? CertVerifier::ocspStrict
235 : CertVerifier::ocspRelaxed;
236
237 // XXX: Always use POST for OCSP; see bug 871954 for undoing this.
238 *ogc = Preferences::GetBool("security.OCSP.GET.enabled", false)
239 ? CertVerifier::ocspGetEnabled
240 : CertVerifier::ocspGetDisabled;
241
242 // If we pass in just 0 as the second argument to Preferences::GetUint, there
243 // are two function signatures that match (given that 0 can be intepreted as
244 // a null pointer). Thus the compiler will complain without the cast.
245 *certShortLifetimeInDays =
246 Preferences::GetUint("security.pki.cert_short_lifetime_in_days",
247 static_cast<uint32_t>(0));
248
249 SSL_ClearSessionCache();
250 }
251
nsNSSComponent()252 nsNSSComponent::nsNSSComponent()
253 : mutex("nsNSSComponent.mutex")
254 , mNSSInitialized(false)
255 #ifndef MOZ_NO_SMART_CARDS
256 , mThreadList(nullptr)
257 #endif
258 {
259 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ctor\n"));
260 MOZ_RELEASE_ASSERT(NS_IsMainThread());
261
262 NS_ASSERTION( (0 == mInstanceCount), "nsNSSComponent is a singleton, but instantiated multiple times!");
263 ++mInstanceCount;
264 }
265
~nsNSSComponent()266 nsNSSComponent::~nsNSSComponent()
267 {
268 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor\n"));
269 MOZ_RELEASE_ASSERT(NS_IsMainThread());
270
271 // All cleanup code requiring services needs to happen in xpcom_shutdown
272
273 ShutdownNSS();
274 SharedSSLState::GlobalCleanup();
275 RememberCertErrorsTable::Cleanup();
276 --mInstanceCount;
277 nsNSSShutDownList::shutdown();
278
279 // We are being freed, drop the haveLoaded flag to re-enable
280 // potential nss initialization later.
281 EnsureNSSInitialized(nssShutdown);
282
283 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor finished\n"));
284 }
285
286 NS_IMETHODIMP
PIPBundleFormatStringFromName(const char * name,const char16_t ** params,uint32_t numParams,nsAString & outString)287 nsNSSComponent::PIPBundleFormatStringFromName(const char* name,
288 const char16_t** params,
289 uint32_t numParams,
290 nsAString& outString)
291 {
292 nsresult rv = NS_ERROR_FAILURE;
293
294 if (mPIPNSSBundle && name) {
295 nsXPIDLString result;
296 rv = mPIPNSSBundle->FormatStringFromName(NS_ConvertASCIItoUTF16(name).get(),
297 params, numParams,
298 getter_Copies(result));
299 if (NS_SUCCEEDED(rv)) {
300 outString = result;
301 }
302 }
303 return rv;
304 }
305
306 NS_IMETHODIMP
GetPIPNSSBundleString(const char * name,nsAString & outString)307 nsNSSComponent::GetPIPNSSBundleString(const char* name, nsAString& outString)
308 {
309 nsresult rv = NS_ERROR_FAILURE;
310
311 outString.SetLength(0);
312 if (mPIPNSSBundle && name) {
313 nsXPIDLString result;
314 rv = mPIPNSSBundle->GetStringFromName(NS_ConvertASCIItoUTF16(name).get(),
315 getter_Copies(result));
316 if (NS_SUCCEEDED(rv)) {
317 outString = result;
318 rv = NS_OK;
319 }
320 }
321
322 return rv;
323 }
324
325 NS_IMETHODIMP
GetNSSBundleString(const char * name,nsAString & outString)326 nsNSSComponent::GetNSSBundleString(const char* name, nsAString& outString)
327 {
328 nsresult rv = NS_ERROR_FAILURE;
329
330 outString.SetLength(0);
331 if (mNSSErrorsBundle && name) {
332 nsXPIDLString result;
333 rv = mNSSErrorsBundle->GetStringFromName(NS_ConvertASCIItoUTF16(name).get(),
334 getter_Copies(result));
335 if (NS_SUCCEEDED(rv)) {
336 outString = result;
337 rv = NS_OK;
338 }
339 }
340
341 return rv;
342 }
343
344 #ifndef MOZ_NO_SMART_CARDS
345 void
LaunchSmartCardThreads()346 nsNSSComponent::LaunchSmartCardThreads()
347 {
348 nsNSSShutDownPreventionLock locker;
349 {
350 SECMODModuleList* list;
351 SECMODListLock* lock = SECMOD_GetDefaultModuleListLock();
352 if (!lock) {
353 MOZ_LOG(gPIPNSSLog, LogLevel::Error,
354 ("Couldn't get the module list lock, can't launch smart card threads\n"));
355 return;
356 }
357 SECMOD_GetReadLock(lock);
358 list = SECMOD_GetDefaultModuleList();
359
360 while (list) {
361 SECMODModule* module = list->module;
362 LaunchSmartCardThread(module);
363 list = list->next;
364 }
365 SECMOD_ReleaseReadLock(lock);
366 }
367 }
368
369 NS_IMETHODIMP
LaunchSmartCardThread(SECMODModule * module)370 nsNSSComponent::LaunchSmartCardThread(SECMODModule* module)
371 {
372 SmartCardMonitoringThread* newThread;
373 if (SECMOD_HasRemovableSlots(module)) {
374 if (!mThreadList) {
375 mThreadList = new SmartCardThreadList();
376 }
377 newThread = new SmartCardMonitoringThread(module);
378 // newThread is adopted by the add.
379 return mThreadList->Add(newThread);
380 }
381 return NS_OK;
382 }
383
384 NS_IMETHODIMP
ShutdownSmartCardThread(SECMODModule * module)385 nsNSSComponent::ShutdownSmartCardThread(SECMODModule* module)
386 {
387 if (!mThreadList) {
388 return NS_OK;
389 }
390 mThreadList->Remove(module);
391 return NS_OK;
392 }
393
394 void
ShutdownSmartCardThreads()395 nsNSSComponent::ShutdownSmartCardThreads()
396 {
397 delete mThreadList;
398 mThreadList = nullptr;
399 }
400 #endif // MOZ_NO_SMART_CARDS
401
402 #ifdef XP_WIN
403 static bool
GetUserSid(nsAString & sidString)404 GetUserSid(nsAString& sidString)
405 {
406 // UNLEN is the maximum user name length (see Lmcons.h). +1 for the null
407 // terminator.
408 WCHAR lpAccountName[UNLEN + 1];
409 DWORD lcAccountName = sizeof(lpAccountName) / sizeof(lpAccountName[0]);
410 BOOL success = GetUserName(lpAccountName, &lcAccountName);
411 if (!success) {
412 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("GetUserName failed"));
413 return false;
414 }
415 char sid_buffer[SECURITY_MAX_SID_SIZE];
416 SID* sid = BitwiseCast<SID*, char*>(sid_buffer);
417 DWORD cbSid = ArrayLength(sid_buffer);
418 SID_NAME_USE eUse;
419 // There doesn't appear to be a defined maximum length for the domain name
420 // here. To deal with this, we start with a reasonable buffer length and
421 // see if that works. If it fails and the error indicates insufficient length,
422 // we use the indicated required length and try again.
423 DWORD cchReferencedDomainName = 128;
424 auto ReferencedDomainName(MakeUnique<WCHAR[]>(cchReferencedDomainName));
425 success = LookupAccountName(nullptr, lpAccountName, sid, &cbSid,
426 ReferencedDomainName.get(),
427 &cchReferencedDomainName, &eUse);
428 if (!success && GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
429 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("LookupAccountName failed"));
430 return false;
431 }
432 if (!success) {
433 ReferencedDomainName = MakeUnique<WCHAR[]>(cchReferencedDomainName);
434 success = LookupAccountName(nullptr, lpAccountName, sid, &cbSid,
435 ReferencedDomainName.get(),
436 &cchReferencedDomainName, &eUse);
437 }
438 if (!success) {
439 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("LookupAccountName failed"));
440 return false;
441 }
442 LPTSTR StringSid;
443 success = ConvertSidToStringSid(sid, &StringSid);
444 if (!success) {
445 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("ConvertSidToStringSid failed"));
446 return false;
447 }
448 sidString.Assign(StringSid);
449 LocalFree(StringSid);
450 return true;
451 }
452
453 // This is a specialized helper function to read the value of a registry key
454 // that might not be present. If it is present, returns (via the output
455 // parameter) its value. Otherwise, returns the given default value.
456 // This function handles one level of nesting. That is, if the desired value
457 // is actually in a direct child of the given registry key (where the child
458 // and/or the value being sought may not actually be present), this function
459 // will handle that. In the normal case, though, optionalChildName will be
460 // null.
461 static nsresult
ReadRegKeyValueWithDefault(nsCOMPtr<nsIWindowsRegKey> regKey,uint32_t flags,wchar_t * optionalChildName,wchar_t * valueName,uint32_t defaultValue,uint32_t & valueOut)462 ReadRegKeyValueWithDefault(nsCOMPtr<nsIWindowsRegKey> regKey,
463 uint32_t flags,
464 wchar_t* optionalChildName,
465 wchar_t* valueName,
466 uint32_t defaultValue,
467 uint32_t& valueOut)
468 {
469 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("ReadRegKeyValueWithDefault"));
470 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
471 ("attempting to read '%S%s%S' with default '%u'",
472 optionalChildName ? optionalChildName : L"",
473 optionalChildName ? "\\" : "", valueName, defaultValue));
474 if (optionalChildName) {
475 nsDependentString childNameString(optionalChildName);
476 bool hasChild;
477 nsresult rv = regKey->HasChild(childNameString, &hasChild);
478 if (NS_FAILED(rv)) {
479 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
480 ("failed to determine if child key is present"));
481 return rv;
482 }
483 if (!hasChild) {
484 valueOut = defaultValue;
485 return NS_OK;
486 }
487 nsCOMPtr<nsIWindowsRegKey> childRegKey;
488 rv = regKey->OpenChild(childNameString, flags,
489 getter_AddRefs(childRegKey));
490 if (NS_FAILED(rv)) {
491 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't open child key"));
492 return rv;
493 }
494 return ReadRegKeyValueWithDefault(childRegKey, flags, nullptr, valueName,
495 defaultValue, valueOut);
496 }
497 nsDependentString valueNameString(valueName);
498 bool hasValue;
499 nsresult rv = regKey->HasValue(valueNameString, &hasValue);
500 if (NS_FAILED(rv)) {
501 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
502 ("failed to determine if value is present"));
503 return rv;
504 }
505 if (!hasValue) {
506 valueOut = defaultValue;
507 return NS_OK;
508 }
509 rv = regKey->ReadIntValue(valueNameString, &valueOut);
510 if (NS_FAILED(rv)) {
511 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to read value"));
512 return rv;
513 }
514 return NS_OK;
515 }
516
517 static nsresult
AccountHasFamilySafetyEnabled(bool & enabled)518 AccountHasFamilySafetyEnabled(bool& enabled)
519 {
520 enabled = false;
521 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("AccountHasFamilySafetyEnabled?"));
522 nsCOMPtr<nsIWindowsRegKey> parentalControlsKey(
523 do_CreateInstance("@mozilla.org/windows-registry-key;1"));
524 if (!parentalControlsKey) {
525 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't create nsIWindowsRegKey"));
526 return NS_ERROR_FAILURE;
527 }
528 uint32_t flags = nsIWindowsRegKey::ACCESS_READ | nsIWindowsRegKey::WOW64_64;
529 NS_NAMED_LITERAL_STRING(familySafetyPath,
530 "SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Parental Controls");
531 nsresult rv = parentalControlsKey->Open(
532 nsIWindowsRegKey::ROOT_KEY_LOCAL_MACHINE, familySafetyPath, flags);
533 if (NS_FAILED(rv)) {
534 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't open parentalControlsKey"));
535 return rv;
536 }
537 NS_NAMED_LITERAL_STRING(usersString, "Users");
538 bool hasUsers;
539 rv = parentalControlsKey->HasChild(usersString, &hasUsers);
540 if (NS_FAILED(rv)) {
541 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("HasChild(Users) failed"));
542 return rv;
543 }
544 if (!hasUsers) {
545 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
546 ("Users subkey not present - Parental Controls not enabled"));
547 return NS_OK;
548 }
549 nsCOMPtr<nsIWindowsRegKey> usersKey;
550 rv = parentalControlsKey->OpenChild(usersString, flags,
551 getter_AddRefs(usersKey));
552 if (NS_FAILED(rv)) {
553 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to open Users subkey"));
554 return rv;
555 }
556 nsAutoString sid;
557 if (!GetUserSid(sid)) {
558 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get sid"));
559 return NS_ERROR_FAILURE;
560 }
561 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("our sid is '%S'", sid.get()));
562 bool hasSid;
563 rv = usersKey->HasChild(sid, &hasSid);
564 if (NS_FAILED(rv)) {
565 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("HasChild(sid) failed"));
566 return rv;
567 }
568 if (!hasSid) {
569 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
570 ("sid not present in Family Safety Users"));
571 return NS_OK;
572 }
573 nsCOMPtr<nsIWindowsRegKey> sidKey;
574 rv = usersKey->OpenChild(sid, flags, getter_AddRefs(sidKey));
575 if (NS_FAILED(rv)) {
576 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't open sid key"));
577 return rv;
578 }
579 // There are three keys we're interested in: "Parental Controls On",
580 // "Logging Required", and "Web\\Filter On". These keys will have value 0
581 // or 1, indicating a particular feature is disabled or enabled,
582 // respectively. So, if "Parental Controls On" is not 1, Family Safety is
583 // disabled and we don't care about anything else. If both "Logging
584 // Required" and "Web\\Filter On" are 0, the proxy will not be running,
585 // so for our purposes we can consider Family Safety disabled in that
586 // case.
587 // By default, "Logging Required" is 1 and "Web\\Filter On" is 0,
588 // reflecting the initial settings when Family Safety is enabled for an
589 // account for the first time, However, these sub-keys are not created
590 // unless they are switched away from the default value.
591 uint32_t parentalControlsOn;
592 rv = sidKey->ReadIntValue(NS_LITERAL_STRING("Parental Controls On"),
593 &parentalControlsOn);
594 if (NS_FAILED(rv)) {
595 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
596 ("couldn't read Parental Controls On"));
597 return rv;
598 }
599 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
600 ("Parental Controls On: %u", parentalControlsOn));
601 if (parentalControlsOn != 1) {
602 return NS_OK;
603 }
604 uint32_t loggingRequired;
605 rv = ReadRegKeyValueWithDefault(sidKey, flags, nullptr, L"Logging Required",
606 1, loggingRequired);
607 if (NS_FAILED(rv)) {
608 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
609 ("failed to read value of Logging Required"));
610 return rv;
611 }
612 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
613 ("Logging Required: %u", loggingRequired));
614 uint32_t webFilterOn;
615 rv = ReadRegKeyValueWithDefault(sidKey, flags, L"Web", L"Filter On", 0,
616 webFilterOn);
617 if (NS_FAILED(rv)) {
618 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
619 ("failed to read value of Web\\Filter On"));
620 return rv;
621 }
622 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Web\\Filter On: %u", webFilterOn));
623 enabled = loggingRequired == 1 || webFilterOn == 1;
624 return NS_OK;
625 }
626
627 // It would be convenient to just use nsIX509CertDB in the following code.
628 // However, since nsIX509CertDB depends on nsNSSComponent initialization (and
629 // since this code runs during that initialization), we can't use it. Instead,
630 // we can use NSS APIs directly (as long as we're called late enough in
631 // nsNSSComponent initialization such that those APIs are safe to use).
632
633 // Helper function to convert a PCCERT_CONTEXT (i.e. a certificate obtained via
634 // a Windows API) to a temporary CERTCertificate (i.e. a certificate for use
635 // with NSS APIs).
636 static UniqueCERTCertificate
PCCERT_CONTEXTToCERTCertificate(PCCERT_CONTEXT pccert)637 PCCERT_CONTEXTToCERTCertificate(PCCERT_CONTEXT pccert)
638 {
639 MOZ_ASSERT(pccert);
640 if (!pccert) {
641 return nullptr;
642 }
643
644 SECItem derCert = {
645 siBuffer,
646 pccert->pbCertEncoded,
647 pccert->cbCertEncoded
648 };
649 return UniqueCERTCertificate(
650 CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCert,
651 nullptr, // nickname unnecessary
652 false, // not permanent
653 true)); // copy DER
654 }
655
656 static const char* kMicrosoftFamilySafetyCN = "Microsoft Family Safety";
657
658 nsresult
MaybeImportFamilySafetyRoot(PCCERT_CONTEXT certificate,bool & wasFamilySafetyRoot)659 nsNSSComponent::MaybeImportFamilySafetyRoot(PCCERT_CONTEXT certificate,
660 bool& wasFamilySafetyRoot)
661 {
662 MOZ_ASSERT(NS_IsMainThread());
663 if (!NS_IsMainThread()) {
664 return NS_ERROR_NOT_SAME_THREAD;
665 }
666 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("MaybeImportFamilySafetyRoot"));
667 wasFamilySafetyRoot = false;
668
669 UniqueCERTCertificate nssCertificate(
670 PCCERT_CONTEXTToCERTCertificate(certificate));
671 if (!nssCertificate) {
672 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't decode certificate"));
673 return NS_ERROR_FAILURE;
674 }
675 // Looking for a certificate with the common name 'Microsoft Family Safety'
676 UniquePORTString subjectName(CERT_GetCommonName(&nssCertificate->subject));
677 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
678 ("subject name is '%s'", subjectName.get()));
679 if (nsCRT::strcmp(subjectName.get(), kMicrosoftFamilySafetyCN) == 0) {
680 wasFamilySafetyRoot = true;
681 CERTCertTrust trust = {
682 CERTDB_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_USER,
683 0,
684 0
685 };
686 if (CERT_ChangeCertTrust(nullptr, nssCertificate.get(), &trust)
687 != SECSuccess) {
688 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
689 ("couldn't trust certificate for TLS server auth"));
690 return NS_ERROR_FAILURE;
691 }
692 MOZ_ASSERT(!mFamilySafetyRoot);
693 mFamilySafetyRoot = Move(nssCertificate);
694 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("added Family Safety root"));
695 }
696 return NS_OK;
697 }
698
699 // Because HCERTSTORE is just a typedef void*, we can't use any of the nice
700 // scoped or unique pointer templates. To elaborate, any attempt would
701 // instantiate those templates with T = void. When T gets used in the context
702 // of T&, this results in void&, which isn't legal.
703 class ScopedCertStore final
704 {
705 public:
ScopedCertStore(HCERTSTORE certstore)706 explicit ScopedCertStore(HCERTSTORE certstore) : certstore(certstore) {}
707
~ScopedCertStore()708 ~ScopedCertStore()
709 {
710 CertCloseStore(certstore, 0);
711 }
712
get()713 HCERTSTORE get()
714 {
715 return certstore;
716 }
717
718 private:
719 ScopedCertStore(const ScopedCertStore&) = delete;
720 ScopedCertStore& operator=(const ScopedCertStore&) = delete;
721 HCERTSTORE certstore;
722 };
723
724 static const wchar_t* kWindowsDefaultRootStoreName = L"ROOT";
725
726 nsresult
LoadFamilySafetyRoot()727 nsNSSComponent::LoadFamilySafetyRoot()
728 {
729 ScopedCertStore certstore(
730 CertOpenSystemStore(0, kWindowsDefaultRootStoreName));
731 if (!certstore.get()) {
732 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
733 ("couldn't get certstore '%S'", kWindowsDefaultRootStoreName));
734 return NS_ERROR_FAILURE;
735 }
736 // Any resources held by the certificate are released by the next call to
737 // CertFindCertificateInStore.
738 PCCERT_CONTEXT certificate = nullptr;
739 while ((certificate = CertFindCertificateInStore(certstore.get(),
740 X509_ASN_ENCODING, 0,
741 CERT_FIND_ANY, nullptr,
742 certificate))) {
743 bool wasFamilySafetyRoot = false;
744 nsresult rv = MaybeImportFamilySafetyRoot(certificate,
745 wasFamilySafetyRoot);
746 if (NS_SUCCEEDED(rv) && wasFamilySafetyRoot) {
747 return NS_OK; // We're done (we're only expecting one root).
748 }
749 }
750 return NS_ERROR_FAILURE;
751 }
752
753 void
UnloadFamilySafetyRoot()754 nsNSSComponent::UnloadFamilySafetyRoot()
755 {
756 MOZ_ASSERT(NS_IsMainThread());
757 if (!NS_IsMainThread()) {
758 return;
759 }
760 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("UnloadFamilySafetyRoot"));
761 if (!mFamilySafetyRoot) {
762 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Family Safety Root wasn't present"));
763 return;
764 }
765 // It would be intuitive to set the trust to { 0, 0, 0 } here. However, this
766 // doesn't work for temporary certificates because CERT_ChangeCertTrust first
767 // looks up the current trust settings in the permanent cert database, finds
768 // that such trust doesn't exist, considers the current trust to be
769 // { 0, 0, 0 }, and decides that it doesn't need to update the trust since
770 // they're the same. To work around this, we set a non-zero flag to ensure
771 // that the trust will get updated.
772 CERTCertTrust trust = { CERTDB_USER, 0, 0 };
773 if (CERT_ChangeCertTrust(nullptr, mFamilySafetyRoot.get(), &trust)
774 != SECSuccess) {
775 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
776 ("couldn't untrust certificate for TLS server auth"));
777 }
778 mFamilySafetyRoot = nullptr;
779 }
780
781 #endif // XP_WIN
782
783 // The supported values of this pref are:
784 // 0: disable detecting Family Safety mode and importing the root
785 // 1: only attempt to detect Family Safety mode (don't import the root)
786 // 2: detect Family Safety mode and import the root
787 const char* kFamilySafetyModePref = "security.family_safety.mode";
788
789 // The telemetry gathered by this function is as follows:
790 // 0-2: the value of the Family Safety mode pref
791 // 3: detecting Family Safety mode failed
792 // 4: Family Safety was not enabled
793 // 5: Family Safety was enabled
794 // 6: failed to import the Family Safety root
795 // 7: successfully imported the root
796 void
MaybeEnableFamilySafetyCompatibility()797 nsNSSComponent::MaybeEnableFamilySafetyCompatibility()
798 {
799 #ifdef XP_WIN
800 UnloadFamilySafetyRoot();
801 if (!(IsWin8Point1OrLater() && !IsWin10OrLater())) {
802 return;
803 }
804 // Detect but don't import by default.
805 uint32_t familySafetyMode = Preferences::GetUint(kFamilySafetyModePref, 1);
806 if (familySafetyMode > 2) {
807 familySafetyMode = 0;
808 }
809 Telemetry::Accumulate(Telemetry::FAMILY_SAFETY, familySafetyMode);
810 if (familySafetyMode == 0) {
811 return;
812 }
813 bool familySafetyEnabled;
814 nsresult rv = AccountHasFamilySafetyEnabled(familySafetyEnabled);
815 if (NS_FAILED(rv)) {
816 Telemetry::Accumulate(Telemetry::FAMILY_SAFETY, 3);
817 return;
818 }
819 if (!familySafetyEnabled) {
820 Telemetry::Accumulate(Telemetry::FAMILY_SAFETY, 4);
821 return;
822 }
823 Telemetry::Accumulate(Telemetry::FAMILY_SAFETY, 5);
824 if (familySafetyMode == 2) {
825 rv = LoadFamilySafetyRoot();
826 if (NS_FAILED(rv)) {
827 Telemetry::Accumulate(Telemetry::FAMILY_SAFETY, 6);
828 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
829 ("failed to load Family Safety root"));
830 } else {
831 Telemetry::Accumulate(Telemetry::FAMILY_SAFETY, 7);
832 }
833 }
834 #endif // XP_WIN
835 }
836
837 #ifdef XP_WIN
838 // Helper function to determine if the OS considers the given certificate to be
839 // a trust anchor for TLS server auth certificates. This is to be used in the
840 // context of importing what are presumed to be root certificates from the OS.
841 // If this function returns true but it turns out that the given certificate is
842 // in some way unsuitable to issue certificates, mozilla::pkix will never build
843 // a valid chain that includes the certificate, so importing it even if it
844 // isn't a valid CA poses no risk.
845 static bool
CertIsTrustAnchorForTLSServerAuth(PCCERT_CONTEXT certificate)846 CertIsTrustAnchorForTLSServerAuth(PCCERT_CONTEXT certificate)
847 {
848 MOZ_ASSERT(certificate);
849 if (!certificate) {
850 return false;
851 }
852
853 PCCERT_CHAIN_CONTEXT pChainContext = nullptr;
854 CERT_ENHKEY_USAGE enhkeyUsage;
855 memset(&enhkeyUsage, 0, sizeof(CERT_ENHKEY_USAGE));
856 LPSTR identifiers[] = {
857 "1.3.6.1.5.5.7.3.1", // id-kp-serverAuth
858 };
859 enhkeyUsage.cUsageIdentifier = ArrayLength(identifiers);
860 enhkeyUsage.rgpszUsageIdentifier = identifiers;
861 CERT_USAGE_MATCH certUsage;
862 memset(&certUsage, 0, sizeof(CERT_USAGE_MATCH));
863 certUsage.dwType = USAGE_MATCH_TYPE_AND;
864 certUsage.Usage = enhkeyUsage;
865 CERT_CHAIN_PARA chainPara;
866 memset(&chainPara, 0, sizeof(CERT_CHAIN_PARA));
867 chainPara.cbSize = sizeof(CERT_CHAIN_PARA);
868 chainPara.RequestedUsage = certUsage;
869
870 if (!CertGetCertificateChain(nullptr, certificate, nullptr, nullptr,
871 &chainPara, 0, nullptr, &pChainContext)) {
872 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("CertGetCertificateChain failed"));
873 return false;
874 }
875 bool trusted = pChainContext->TrustStatus.dwErrorStatus ==
876 CERT_TRUST_NO_ERROR;
877 bool isRoot = pChainContext->cChain == 1;
878 CertFreeCertificateChain(pChainContext);
879 if (trusted && isRoot) {
880 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
881 ("certificate is trust anchor for TLS server auth"));
882 return true;
883 }
884 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
885 ("certificate not trust anchor for TLS server auth"));
886 return false;
887 }
888
889 void
UnloadEnterpriseRoots()890 nsNSSComponent::UnloadEnterpriseRoots()
891 {
892 MOZ_ASSERT(NS_IsMainThread());
893 if (!NS_IsMainThread()) {
894 return;
895 }
896 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("UnloadEnterpriseRoots"));
897 if (!mEnterpriseRoots) {
898 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("no enterprise roots were present"));
899 return;
900 }
901 // It would be intuitive to set the trust to { 0, 0, 0 } here. However, this
902 // doesn't work for temporary certificates because CERT_ChangeCertTrust first
903 // looks up the current trust settings in the permanent cert database, finds
904 // that such trust doesn't exist, considers the current trust to be
905 // { 0, 0, 0 }, and decides that it doesn't need to update the trust since
906 // they're the same. To work around this, we set a non-zero flag to ensure
907 // that the trust will get updated.
908 CERTCertTrust trust = { CERTDB_USER, 0, 0 };
909 for (CERTCertListNode* n = CERT_LIST_HEAD(mEnterpriseRoots.get());
910 !CERT_LIST_END(n, mEnterpriseRoots.get()); n = CERT_LIST_NEXT(n)) {
911 if (!n || !n->cert) {
912 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
913 ("library failure: CERTCertListNode null or lacks cert"));
914 continue;
915 }
916 if (CERT_ChangeCertTrust(nullptr, n->cert, &trust) != SECSuccess) {
917 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
918 ("couldn't untrust certificate for TLS server auth"));
919 }
920 }
921 mEnterpriseRoots = nullptr;
922 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("unloaded enterprise roots"));
923 }
924
925 NS_IMETHODIMP
GetEnterpriseRoots(nsIX509CertList ** enterpriseRoots)926 nsNSSComponent::GetEnterpriseRoots(nsIX509CertList** enterpriseRoots)
927 {
928 MOZ_ASSERT(NS_IsMainThread());
929 if (!NS_IsMainThread()) {
930 return NS_ERROR_NOT_SAME_THREAD;
931 }
932 NS_ENSURE_ARG_POINTER(enterpriseRoots);
933
934 nsNSSShutDownPreventionLock lock;
935 // nsNSSComponent isn't a nsNSSShutDownObject, so we can't check
936 // isAlreadyShutDown(). However, since mEnterpriseRoots is cleared when NSS
937 // shuts down, we can use that as a proxy for checking for NSS shutdown.
938 // (Of course, it may also be the case that no enterprise roots were imported,
939 // so we should just return a null list and NS_OK in this case.)
940 if (!mEnterpriseRoots) {
941 *enterpriseRoots = nullptr;
942 return NS_OK;
943 }
944 UniqueCERTCertList enterpriseRootsCopy(
945 nsNSSCertList::DupCertList(mEnterpriseRoots, lock));
946 if (!enterpriseRootsCopy) {
947 return NS_ERROR_FAILURE;
948 }
949 nsCOMPtr<nsIX509CertList> enterpriseRootsCertList(
950 new nsNSSCertList(Move(enterpriseRootsCopy), lock));
951 if (!enterpriseRootsCertList) {
952 return NS_ERROR_FAILURE;
953 }
954 enterpriseRootsCertList.forget(enterpriseRoots);
955 return NS_OK;
956 }
957 #endif // XP_WIN
958
959 static const char* kEnterpriseRootModePref = "security.enterprise_roots.enabled";
960
961 void
MaybeImportEnterpriseRoots()962 nsNSSComponent::MaybeImportEnterpriseRoots()
963 {
964 #ifdef XP_WIN
965 MOZ_ASSERT(NS_IsMainThread());
966 if (!NS_IsMainThread()) {
967 return;
968 }
969 UnloadEnterpriseRoots();
970 bool importEnterpriseRoots = Preferences::GetBool(kEnterpriseRootModePref,
971 false);
972 if (!importEnterpriseRoots) {
973 return;
974 }
975
976 MOZ_ASSERT(!mEnterpriseRoots);
977 mEnterpriseRoots.reset(CERT_NewCertList());
978 if (!mEnterpriseRoots) {
979 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
980 ("failed to allocate a new CERTCertList for mEnterpriseRoots"));
981 return;
982 }
983
984 ImportEnterpriseRootsForLocation(CERT_SYSTEM_STORE_LOCAL_MACHINE);
985 ImportEnterpriseRootsForLocation(CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY);
986 ImportEnterpriseRootsForLocation(CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE);
987 #endif // XP_WIN
988 }
989
990 #ifdef XP_WIN
991 // Loads the enterprise roots at the registry location corresponding to the
992 // given location flag.
993 // Supported flags are:
994 // CERT_SYSTEM_STORE_LOCAL_MACHINE
995 // (for HKLM\SOFTWARE\Microsoft\SystemCertificates)
996 // CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY
997 // (for HKLM\SOFTWARE\Policies\Microsoft\SystemCertificates\Root\Certificates)
998 // CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE
999 // (for HKLM\SOFTWARE\Microsoft\EnterpriseCertificates\Root\Certificates)
1000 void
ImportEnterpriseRootsForLocation(DWORD locationFlag)1001 nsNSSComponent::ImportEnterpriseRootsForLocation(DWORD locationFlag)
1002 {
1003 MOZ_ASSERT(NS_IsMainThread());
1004 if (!NS_IsMainThread()) {
1005 return;
1006 }
1007 MOZ_ASSERT(locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE ||
1008 locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY ||
1009 locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE,
1010 "unexpected locationFlag for ImportEnterpriseRootsForLocation");
1011 if (!(locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE ||
1012 locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_GROUP_POLICY ||
1013 locationFlag == CERT_SYSTEM_STORE_LOCAL_MACHINE_ENTERPRISE)) {
1014 return;
1015 }
1016
1017 DWORD flags = locationFlag |
1018 CERT_STORE_OPEN_EXISTING_FLAG |
1019 CERT_STORE_READONLY_FLAG;
1020 // The certificate store being opened should consist only of certificates
1021 // added by a user or administrator and not any certificates that are part
1022 // of Microsoft's root store program.
1023 // The 3rd parameter to CertOpenStore should be NULL according to
1024 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa376559%28v=vs.85%29.aspx
1025 ScopedCertStore enterpriseRootStore(CertOpenStore(
1026 CERT_STORE_PROV_SYSTEM_REGISTRY_W, 0, NULL, flags,
1027 kWindowsDefaultRootStoreName));
1028 if (!enterpriseRootStore.get()) {
1029 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to open enterprise root store"));
1030 return;
1031 }
1032 CERTCertTrust trust = {
1033 CERTDB_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_USER,
1034 0,
1035 0
1036 };
1037 PCCERT_CONTEXT certificate = nullptr;
1038 uint32_t numImported = 0;
1039 while ((certificate = CertFindCertificateInStore(enterpriseRootStore.get(),
1040 X509_ASN_ENCODING, 0,
1041 CERT_FIND_ANY, nullptr,
1042 certificate))) {
1043 if (!CertIsTrustAnchorForTLSServerAuth(certificate)) {
1044 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
1045 ("skipping cert not trust anchor for TLS server auth"));
1046 continue;
1047 }
1048 UniqueCERTCertificate nssCertificate(
1049 PCCERT_CONTEXTToCERTCertificate(certificate));
1050 if (!nssCertificate) {
1051 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't decode certificate"));
1052 continue;
1053 }
1054 // Don't import the Microsoft Family Safety root (this prevents the
1055 // Enterprise Roots feature from interacting poorly with the Family
1056 // Safety support).
1057 UniquePORTString subjectName(
1058 CERT_GetCommonName(&nssCertificate->subject));
1059 if (nsCRT::strcmp(subjectName.get(), kMicrosoftFamilySafetyCN) == 0) {
1060 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("skipping Family Safety Root"));
1061 continue;
1062 }
1063 MOZ_ASSERT(mEnterpriseRoots, "mEnterpriseRoots unexpectedly NULL?");
1064 if (!mEnterpriseRoots) {
1065 return;
1066 }
1067 if (CERT_AddCertToListTail(mEnterpriseRoots.get(), nssCertificate.get())
1068 != SECSuccess) {
1069 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't add cert to list"));
1070 continue;
1071 }
1072 if (CERT_ChangeCertTrust(nullptr, nssCertificate.get(), &trust)
1073 != SECSuccess) {
1074 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
1075 ("couldn't trust certificate for TLS server auth"));
1076 }
1077 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Imported '%s'", subjectName.get()));
1078 numImported++;
1079 // now owned by mEnterpriseRoots
1080 Unused << nssCertificate.release();
1081 }
1082 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("imported %u roots", numImported));
1083 }
1084 #endif // XP_WIN
1085
1086 void
LoadLoadableRoots()1087 nsNSSComponent::LoadLoadableRoots()
1088 {
1089 nsNSSShutDownPreventionLock locker;
1090 SECMODModule* RootsModule = nullptr;
1091
1092 // In the past we used SECMOD_AddNewModule to load our module containing
1093 // root CA certificates. This caused problems, refer to bug 176501.
1094 // On startup, we fix our database and clean any stored module reference,
1095 // and will use SECMOD_LoadUserModule to temporarily load it
1096 // for the session. (This approach requires to clean up
1097 // using SECMOD_UnloadUserModule at the end of the session.)
1098
1099 {
1100 // Find module containing root certs
1101
1102 SECMODModuleList* list;
1103 SECMODListLock* lock = SECMOD_GetDefaultModuleListLock();
1104 if (!lock) {
1105 MOZ_LOG(gPIPNSSLog, LogLevel::Error,
1106 ("Couldn't get the module list lock, can't install loadable roots\n"));
1107 return;
1108 }
1109 SECMOD_GetReadLock(lock);
1110 list = SECMOD_GetDefaultModuleList();
1111
1112 while (!RootsModule && list) {
1113 SECMODModule* module = list->module;
1114
1115 for (int i=0; i < module->slotCount; i++) {
1116 PK11SlotInfo* slot = module->slots[i];
1117 if (PK11_IsPresent(slot)) {
1118 if (PK11_HasRootCerts(slot)) {
1119 RootsModule = SECMOD_ReferenceModule(module);
1120 break;
1121 }
1122 }
1123 }
1124
1125 list = list->next;
1126 }
1127 SECMOD_ReleaseReadLock(lock);
1128 }
1129
1130 if (RootsModule) {
1131 int32_t modType;
1132 SECMOD_DeleteModule(RootsModule->commonName, &modType);
1133 SECMOD_DestroyModule(RootsModule);
1134 RootsModule = nullptr;
1135 }
1136
1137 // Find the best Roots module for our purposes.
1138 // Prefer the application's installation directory,
1139 // but also ensure the library is at least the version we expect.
1140
1141 nsAutoString modName;
1142 nsresult rv = GetPIPNSSBundleString("RootCertModuleName", modName);
1143 if (NS_FAILED(rv)) {
1144 // When running Cpp unit tests on Android, this will fail because string
1145 // bundles aren't available (see bug 1311077, bug 1228175 comment 12, and
1146 // bug 929655). Because the module name is really only for display purposes,
1147 // we can just hard-code the value here. Furthermore, if we want to be able
1148 // to stop using string bundles in PSM in this way, we'll have to hard-code
1149 // the string and only use the localized version when displaying it to the
1150 // user, so this is a step in that direction anyway.
1151 modName.AssignLiteral("Builtin Roots Module");
1152 }
1153
1154 nsCOMPtr<nsIProperties> directoryService(do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID));
1155 if (!directoryService)
1156 return;
1157
1158 static const char nss_lib[] = "nss3";
1159 const char* possible_ckbi_locations[] = {
1160 nss_lib, // This special value means: search for ckbi in the directory
1161 // where nss3 is.
1162 NS_XPCOM_CURRENT_PROCESS_DIR,
1163 NS_GRE_DIR,
1164 0 // This special value means:
1165 // search for ckbi in the directories on the shared
1166 // library/DLL search path
1167 };
1168
1169 for (size_t il = 0; il < sizeof(possible_ckbi_locations)/sizeof(const char*); ++il) {
1170 nsAutoCString libDir;
1171
1172 if (possible_ckbi_locations[il]) {
1173 nsCOMPtr<nsIFile> mozFile;
1174 if (possible_ckbi_locations[il] == nss_lib) {
1175 // Get the location of the nss3 library.
1176 char* nss_path = PR_GetLibraryFilePathname(DLL_PREFIX "nss3" DLL_SUFFIX,
1177 (PRFuncPtr) NSS_Initialize);
1178 if (!nss_path) {
1179 continue;
1180 }
1181 // Get the directory containing the nss3 library.
1182 nsCOMPtr<nsIFile> nssLib(do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv));
1183 if (NS_SUCCEEDED(rv)) {
1184 rv = nssLib->InitWithNativePath(nsDependentCString(nss_path));
1185 }
1186 PR_Free(nss_path);
1187 if (NS_SUCCEEDED(rv)) {
1188 nsCOMPtr<nsIFile> file;
1189 if (NS_SUCCEEDED(nssLib->GetParent(getter_AddRefs(file)))) {
1190 mozFile = do_QueryInterface(file);
1191 }
1192 }
1193 } else {
1194 directoryService->Get( possible_ckbi_locations[il],
1195 NS_GET_IID(nsIFile),
1196 getter_AddRefs(mozFile));
1197 }
1198
1199 if (!mozFile) {
1200 continue;
1201 }
1202
1203 if (NS_FAILED(mozFile->GetNativePath(libDir))) {
1204 continue;
1205 }
1206 }
1207
1208 NS_ConvertUTF16toUTF8 modNameUTF8(modName);
1209 if (mozilla::psm::LoadLoadableRoots(
1210 libDir.Length() > 0 ? libDir.get() : nullptr,
1211 modNameUTF8.get()) == SECSuccess) {
1212 break;
1213 }
1214 }
1215 }
1216
1217 void
UnloadLoadableRoots()1218 nsNSSComponent::UnloadLoadableRoots()
1219 {
1220 nsresult rv;
1221 nsAutoString modName;
1222 rv = GetPIPNSSBundleString("RootCertModuleName", modName);
1223 if (NS_FAILED(rv)) return;
1224
1225 NS_ConvertUTF16toUTF8 modNameUTF8(modName);
1226 ::mozilla::psm::UnloadLoadableRoots(modNameUTF8.get());
1227 }
1228
1229 nsresult
ConfigureInternalPKCS11Token()1230 nsNSSComponent::ConfigureInternalPKCS11Token()
1231 {
1232 nsNSSShutDownPreventionLock locker;
1233 nsAutoString manufacturerID;
1234 nsAutoString libraryDescription;
1235 nsAutoString tokenDescription;
1236 nsAutoString privateTokenDescription;
1237 nsAutoString slotDescription;
1238 nsAutoString privateSlotDescription;
1239 nsAutoString fips140SlotDescription;
1240 nsAutoString fips140TokenDescription;
1241
1242 nsresult rv;
1243 rv = GetPIPNSSBundleString("ManufacturerID", manufacturerID);
1244 if (NS_FAILED(rv)) return rv;
1245
1246 rv = GetPIPNSSBundleString("LibraryDescription", libraryDescription);
1247 if (NS_FAILED(rv)) return rv;
1248
1249 rv = GetPIPNSSBundleString("TokenDescription", tokenDescription);
1250 if (NS_FAILED(rv)) return rv;
1251
1252 rv = GetPIPNSSBundleString("PrivateTokenDescription", privateTokenDescription);
1253 if (NS_FAILED(rv)) return rv;
1254
1255 rv = GetPIPNSSBundleString("SlotDescription", slotDescription);
1256 if (NS_FAILED(rv)) return rv;
1257
1258 rv = GetPIPNSSBundleString("PrivateSlotDescription", privateSlotDescription);
1259 if (NS_FAILED(rv)) return rv;
1260
1261 rv = GetPIPNSSBundleString("Fips140SlotDescription", fips140SlotDescription);
1262 if (NS_FAILED(rv)) return rv;
1263
1264 rv = GetPIPNSSBundleString("Fips140TokenDescription", fips140TokenDescription);
1265 if (NS_FAILED(rv)) return rv;
1266
1267 PK11_ConfigurePKCS11(NS_ConvertUTF16toUTF8(manufacturerID).get(),
1268 NS_ConvertUTF16toUTF8(libraryDescription).get(),
1269 NS_ConvertUTF16toUTF8(tokenDescription).get(),
1270 NS_ConvertUTF16toUTF8(privateTokenDescription).get(),
1271 NS_ConvertUTF16toUTF8(slotDescription).get(),
1272 NS_ConvertUTF16toUTF8(privateSlotDescription).get(),
1273 NS_ConvertUTF16toUTF8(fips140SlotDescription).get(),
1274 NS_ConvertUTF16toUTF8(fips140TokenDescription).get(),
1275 0, 0);
1276 return NS_OK;
1277 }
1278
1279 nsresult
InitializePIPNSSBundle()1280 nsNSSComponent::InitializePIPNSSBundle()
1281 {
1282 // Called during init only, no mutex required.
1283
1284 nsresult rv;
1285 nsCOMPtr<nsIStringBundleService> bundleService(do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv));
1286 #ifdef ANDROID
1287 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1288 MOZ_RELEASE_ASSERT(bundleService);
1289 #endif
1290 if (NS_FAILED(rv) || !bundleService)
1291 return NS_ERROR_FAILURE;
1292
1293 bundleService->CreateBundle("chrome://pipnss/locale/pipnss.properties",
1294 getter_AddRefs(mPIPNSSBundle));
1295 #ifdef ANDROID
1296 MOZ_RELEASE_ASSERT(mPIPNSSBundle);
1297 #endif
1298 if (!mPIPNSSBundle)
1299 rv = NS_ERROR_FAILURE;
1300
1301 bundleService->CreateBundle("chrome://pipnss/locale/nsserrors.properties",
1302 getter_AddRefs(mNSSErrorsBundle));
1303 #ifdef ANDROID
1304 MOZ_RELEASE_ASSERT(mNSSErrorsBundle);
1305 #endif
1306 if (!mNSSErrorsBundle)
1307 rv = NS_ERROR_FAILURE;
1308
1309 return rv;
1310 }
1311
1312 // Table of pref names and SSL cipher ID
1313 typedef struct {
1314 const char* pref;
1315 long id;
1316 bool enabledByDefault;
1317 bool weak;
1318 } CipherPref;
1319
1320 // Update the switch statement in AccumulateCipherSuite in nsNSSCallbacks.cpp
1321 // when you add/remove cipher suites here.
1322 static const CipherPref sCipherPrefs[] = {
1323 { "security.ssl3.ecdhe_rsa_aes_128_gcm_sha256",
1324 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, true },
1325 { "security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256",
1326 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, true },
1327
1328 { "security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256",
1329 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, true },
1330 { "security.ssl3.ecdhe_rsa_chacha20_poly1305_sha256",
1331 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, true },
1332
1333 { "security.ssl3.ecdhe_ecdsa_aes_256_gcm_sha384",
1334 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, true },
1335 { "security.ssl3.ecdhe_rsa_aes_256_gcm_sha384",
1336 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, true },
1337
1338 { "security.ssl3.ecdhe_rsa_aes_128_sha",
1339 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, true },
1340 { "security.ssl3.ecdhe_ecdsa_aes_128_sha",
1341 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, true },
1342
1343 { "security.ssl3.ecdhe_rsa_aes_256_sha",
1344 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, true },
1345 { "security.ssl3.ecdhe_ecdsa_aes_256_sha",
1346 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, true },
1347
1348 { "security.ssl3.dhe_rsa_aes_128_sha",
1349 TLS_DHE_RSA_WITH_AES_128_CBC_SHA, true },
1350
1351 { "security.ssl3.dhe_rsa_aes_256_sha",
1352 TLS_DHE_RSA_WITH_AES_256_CBC_SHA, true },
1353
1354 { "security.tls13.aes_128_gcm_sha256",
1355 TLS_AES_128_GCM_SHA256, true },
1356 { "security.tls13.chacha20_poly1305_sha256",
1357 TLS_CHACHA20_POLY1305_SHA256, true },
1358 { "security.tls13.aes_256_gcm_sha384",
1359 TLS_AES_256_GCM_SHA384, true },
1360
1361 { "security.ssl3.rsa_aes_128_sha",
1362 TLS_RSA_WITH_AES_128_CBC_SHA, true }, // deprecated (RSA key exchange)
1363 { "security.ssl3.rsa_aes_256_sha",
1364 TLS_RSA_WITH_AES_256_CBC_SHA, true }, // deprecated (RSA key exchange)
1365 { "security.ssl3.rsa_des_ede3_sha",
1366 TLS_RSA_WITH_3DES_EDE_CBC_SHA, true }, // deprecated (RSA key exchange, 3DES)
1367
1368 // All the rest are disabled
1369
1370 { nullptr, 0 } // end marker
1371 };
1372
1373 // Bit flags indicating what weak ciphers are enabled.
1374 // The bit index will correspond to the index in sCipherPrefs.
1375 // Wrtten by the main thread, read from any threads.
1376 static Atomic<uint32_t> sEnabledWeakCiphers;
1377 static_assert(MOZ_ARRAY_LENGTH(sCipherPrefs) - 1 <= sizeof(uint32_t) * CHAR_BIT,
1378 "too many cipher suites");
1379
1380 /*static*/ bool
AreAnyWeakCiphersEnabled()1381 nsNSSComponent::AreAnyWeakCiphersEnabled()
1382 {
1383 return !!sEnabledWeakCiphers;
1384 }
1385
1386 /*static*/ void
UseWeakCiphersOnSocket(PRFileDesc * fd)1387 nsNSSComponent::UseWeakCiphersOnSocket(PRFileDesc* fd)
1388 {
1389 const uint32_t enabledWeakCiphers = sEnabledWeakCiphers;
1390 const CipherPref* const cp = sCipherPrefs;
1391 for (size_t i = 0; cp[i].pref; ++i) {
1392 if (enabledWeakCiphers & ((uint32_t)1 << i)) {
1393 SSL_CipherPrefSet(fd, cp[i].id, true);
1394 }
1395 }
1396 }
1397
1398 // This function will convert from pref values like 1, 2, ...
1399 // to the internal values of SSL_LIBRARY_VERSION_TLS_1_0,
1400 // SSL_LIBRARY_VERSION_TLS_1_1, ...
1401 /*static*/ void
FillTLSVersionRange(SSLVersionRange & rangeOut,uint32_t minFromPrefs,uint32_t maxFromPrefs,SSLVersionRange defaults)1402 nsNSSComponent::FillTLSVersionRange(SSLVersionRange& rangeOut,
1403 uint32_t minFromPrefs,
1404 uint32_t maxFromPrefs,
1405 SSLVersionRange defaults)
1406 {
1407 rangeOut = defaults;
1408 // determine what versions are supported
1409 SSLVersionRange supported;
1410 if (SSL_VersionRangeGetSupported(ssl_variant_stream, &supported)
1411 != SECSuccess) {
1412 return;
1413 }
1414
1415 // Clip the defaults by what NSS actually supports to enable
1416 // working with a system NSS with different ranges.
1417 rangeOut.min = std::max(rangeOut.min, supported.min);
1418 rangeOut.max = std::min(rangeOut.max, supported.max);
1419
1420 // convert min/maxFromPrefs to the internal representation
1421 minFromPrefs += SSL_LIBRARY_VERSION_3_0;
1422 maxFromPrefs += SSL_LIBRARY_VERSION_3_0;
1423 // if min/maxFromPrefs are invalid, use defaults
1424 if (minFromPrefs > maxFromPrefs ||
1425 minFromPrefs < supported.min || maxFromPrefs > supported.max ||
1426 minFromPrefs < SSL_LIBRARY_VERSION_TLS_1_0) {
1427 return;
1428 }
1429
1430 // fill out rangeOut
1431 rangeOut.min = (uint16_t) minFromPrefs;
1432 rangeOut.max = (uint16_t) maxFromPrefs;
1433 }
1434
1435 static const int32_t OCSP_ENABLED_DEFAULT = 1;
1436 static const bool REQUIRE_SAFE_NEGOTIATION_DEFAULT = false;
1437 static const bool FALSE_START_ENABLED_DEFAULT = true;
1438 static const bool NPN_ENABLED_DEFAULT = true;
1439 static const bool ALPN_ENABLED_DEFAULT = false;
1440 static const bool ENABLED_0RTT_DATA_DEFAULT = false;
1441
1442 static void
ConfigureTLSSessionIdentifiers()1443 ConfigureTLSSessionIdentifiers()
1444 {
1445 bool disableSessionIdentifiers =
1446 Preferences::GetBool("security.ssl.disable_session_identifiers", false);
1447 SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, !disableSessionIdentifiers);
1448 SSL_OptionSetDefault(SSL_NO_CACHE, disableSessionIdentifiers);
1449 }
1450
1451 namespace {
1452
1453 class CipherSuiteChangeObserver : public nsIObserver
1454 {
1455 public:
1456 NS_DECL_ISUPPORTS
1457 NS_DECL_NSIOBSERVER
1458
1459 static nsresult StartObserve();
1460
1461 protected:
~CipherSuiteChangeObserver()1462 virtual ~CipherSuiteChangeObserver() {}
1463
1464 private:
1465 static StaticRefPtr<CipherSuiteChangeObserver> sObserver;
CipherSuiteChangeObserver()1466 CipherSuiteChangeObserver() {}
1467 };
1468
1469 NS_IMPL_ISUPPORTS(CipherSuiteChangeObserver, nsIObserver)
1470
1471 // static
1472 StaticRefPtr<CipherSuiteChangeObserver> CipherSuiteChangeObserver::sObserver;
1473
1474 // static
1475 nsresult
StartObserve()1476 CipherSuiteChangeObserver::StartObserve()
1477 {
1478 NS_ASSERTION(NS_IsMainThread(), "CipherSuiteChangeObserver::StartObserve() can only be accessed in main thread");
1479 if (!sObserver) {
1480 RefPtr<CipherSuiteChangeObserver> observer = new CipherSuiteChangeObserver();
1481 nsresult rv = Preferences::AddStrongObserver(observer.get(), "security.");
1482 #ifdef ANDROID
1483 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1484 #endif
1485 if (NS_FAILED(rv)) {
1486 sObserver = nullptr;
1487 return rv;
1488 }
1489
1490 nsCOMPtr<nsIObserverService> observerService =
1491 mozilla::services::GetObserverService();
1492 observerService->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID,
1493 false);
1494
1495 sObserver = observer;
1496 }
1497 return NS_OK;
1498 }
1499
1500 nsresult
Observe(nsISupports * aSubject,const char * aTopic,const char16_t * someData)1501 CipherSuiteChangeObserver::Observe(nsISupports* aSubject,
1502 const char* aTopic,
1503 const char16_t* someData)
1504 {
1505 NS_ASSERTION(NS_IsMainThread(), "CipherSuiteChangeObserver::Observe can only be accessed in main thread");
1506 if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
1507 NS_ConvertUTF16toUTF8 prefName(someData);
1508 // Look through the cipher table and set according to pref setting
1509 const CipherPref* const cp = sCipherPrefs;
1510 for (size_t i = 0; cp[i].pref; ++i) {
1511 if (prefName.Equals(cp[i].pref)) {
1512 bool cipherEnabled = Preferences::GetBool(cp[i].pref,
1513 cp[i].enabledByDefault);
1514 if (cp[i].weak) {
1515 // Weak ciphers will not be used by default even if they
1516 // are enabled in prefs. They are only used on specific
1517 // sockets as a part of a fallback mechanism.
1518 // Only the main thread will change sEnabledWeakCiphers.
1519 uint32_t enabledWeakCiphers = sEnabledWeakCiphers;
1520 if (cipherEnabled) {
1521 enabledWeakCiphers |= ((uint32_t)1 << i);
1522 } else {
1523 enabledWeakCiphers &= ~((uint32_t)1 << i);
1524 }
1525 sEnabledWeakCiphers = enabledWeakCiphers;
1526 } else {
1527 SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled);
1528 SSL_ClearSessionCache();
1529 }
1530 break;
1531 }
1532 }
1533 } else if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) {
1534 Preferences::RemoveObserver(this, "security.");
1535 MOZ_ASSERT(sObserver.get() == this);
1536 sObserver = nullptr;
1537 nsCOMPtr<nsIObserverService> observerService =
1538 mozilla::services::GetObserverService();
1539 observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID);
1540 }
1541 return NS_OK;
1542 }
1543
1544 } // namespace
1545
1546 // Caller must hold a lock on nsNSSComponent::mutex when calling this function
setValidationOptions(bool isInitialSetting,const MutexAutoLock & lock)1547 void nsNSSComponent::setValidationOptions(bool isInitialSetting,
1548 const MutexAutoLock& lock)
1549 {
1550 // This preference controls whether we do OCSP fetching and does not affect
1551 // OCSP stapling.
1552 // 0 = disabled, 1 = enabled
1553 int32_t ocspEnabled = Preferences::GetInt("security.OCSP.enabled",
1554 OCSP_ENABLED_DEFAULT);
1555
1556 bool ocspRequired = ocspEnabled &&
1557 Preferences::GetBool("security.OCSP.require", false);
1558
1559 // We measure the setting of the pref at startup only to minimize noise by
1560 // addons that may muck with the settings, though it probably doesn't matter.
1561 if (isInitialSetting) {
1562 Telemetry::Accumulate(Telemetry::CERT_OCSP_ENABLED, ocspEnabled);
1563 Telemetry::Accumulate(Telemetry::CERT_OCSP_REQUIRED, ocspRequired);
1564 }
1565
1566 bool ocspStaplingEnabled = Preferences::GetBool("security.ssl.enable_ocsp_stapling",
1567 true);
1568 PublicSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
1569 PrivateSSLState()->SetOCSPStaplingEnabled(ocspStaplingEnabled);
1570
1571 bool ocspMustStapleEnabled = Preferences::GetBool("security.ssl.enable_ocsp_must_staple",
1572 true);
1573 PublicSSLState()->SetOCSPMustStapleEnabled(ocspMustStapleEnabled);
1574 PrivateSSLState()->SetOCSPMustStapleEnabled(ocspMustStapleEnabled);
1575
1576 const CertVerifier::CertificateTransparencyMode defaultCTMode =
1577 CertVerifier::CertificateTransparencyMode::TelemetryOnly;
1578 CertVerifier::CertificateTransparencyMode ctMode =
1579 static_cast<CertVerifier::CertificateTransparencyMode>
1580 (Preferences::GetInt("security.pki.certificate_transparency.mode",
1581 static_cast<int32_t>(defaultCTMode)));
1582 switch (ctMode) {
1583 case CertVerifier::CertificateTransparencyMode::Disabled:
1584 case CertVerifier::CertificateTransparencyMode::TelemetryOnly:
1585 break;
1586 default:
1587 ctMode = defaultCTMode;
1588 break;
1589 }
1590 bool sctsEnabled =
1591 ctMode != CertVerifier::CertificateTransparencyMode::Disabled;
1592 PublicSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled);
1593 PrivateSSLState()->SetSignedCertTimestampsEnabled(sctsEnabled);
1594
1595 CertVerifier::PinningMode pinningMode =
1596 static_cast<CertVerifier::PinningMode>
1597 (Preferences::GetInt("security.cert_pinning.enforcement_level",
1598 CertVerifier::pinningDisabled));
1599 if (pinningMode > CertVerifier::pinningEnforceTestMode) {
1600 pinningMode = CertVerifier::pinningDisabled;
1601 }
1602
1603 CertVerifier::SHA1Mode sha1Mode = static_cast<CertVerifier::SHA1Mode>
1604 (Preferences::GetInt("security.pki.sha1_enforcement_level",
1605 static_cast<int32_t>(CertVerifier::SHA1Mode::Allowed)));
1606 switch (sha1Mode) {
1607 case CertVerifier::SHA1Mode::Allowed:
1608 case CertVerifier::SHA1Mode::Forbidden:
1609 case CertVerifier::SHA1Mode::UsedToBeBefore2016ButNowIsForbidden:
1610 case CertVerifier::SHA1Mode::ImportedRoot:
1611 case CertVerifier::SHA1Mode::ImportedRootOrBefore2016:
1612 break;
1613 default:
1614 sha1Mode = CertVerifier::SHA1Mode::Allowed;
1615 break;
1616 }
1617
1618 // Convert a previously-available setting to a safe one.
1619 if (sha1Mode == CertVerifier::SHA1Mode::UsedToBeBefore2016ButNowIsForbidden) {
1620 sha1Mode = CertVerifier::SHA1Mode::Forbidden;
1621 }
1622
1623 BRNameMatchingPolicy::Mode nameMatchingMode =
1624 static_cast<BRNameMatchingPolicy::Mode>
1625 (Preferences::GetInt("security.pki.name_matching_mode",
1626 static_cast<int32_t>(BRNameMatchingPolicy::Mode::DoNotEnforce)));
1627 switch (nameMatchingMode) {
1628 case BRNameMatchingPolicy::Mode::Enforce:
1629 case BRNameMatchingPolicy::Mode::EnforceAfter23August2015:
1630 case BRNameMatchingPolicy::Mode::EnforceAfter23August2016:
1631 case BRNameMatchingPolicy::Mode::DoNotEnforce:
1632 break;
1633 default:
1634 nameMatchingMode = BRNameMatchingPolicy::Mode::DoNotEnforce;
1635 break;
1636 }
1637
1638 NetscapeStepUpPolicy netscapeStepUpPolicy =
1639 static_cast<NetscapeStepUpPolicy>
1640 (Preferences::GetUint("security.pki.netscape_step_up_policy",
1641 static_cast<uint32_t>(NetscapeStepUpPolicy::AlwaysMatch)));
1642 switch (netscapeStepUpPolicy) {
1643 case NetscapeStepUpPolicy::AlwaysMatch:
1644 case NetscapeStepUpPolicy::MatchBefore23August2016:
1645 case NetscapeStepUpPolicy::MatchBefore23August2015:
1646 case NetscapeStepUpPolicy::NeverMatch:
1647 break;
1648 default:
1649 netscapeStepUpPolicy = NetscapeStepUpPolicy::AlwaysMatch;
1650 break;
1651 }
1652
1653 CertVerifier::OcspDownloadConfig odc;
1654 CertVerifier::OcspStrictConfig osc;
1655 CertVerifier::OcspGetConfig ogc;
1656 uint32_t certShortLifetimeInDays;
1657
1658 GetRevocationBehaviorFromPrefs(&odc, &osc, &ogc, &certShortLifetimeInDays,
1659 lock);
1660 mDefaultCertVerifier = new SharedCertVerifier(odc, osc, ogc,
1661 certShortLifetimeInDays,
1662 pinningMode, sha1Mode,
1663 nameMatchingMode,
1664 netscapeStepUpPolicy,
1665 ctMode);
1666 }
1667
1668 // Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and
1669 // TLS 1.2 (max) when the prefs aren't set or set to invalid values.
1670 nsresult
setEnabledTLSVersions()1671 nsNSSComponent::setEnabledTLSVersions()
1672 {
1673 // keep these values in sync with security-prefs.js
1674 // 1 means TLS 1.0, 2 means TLS 1.1, etc.
1675 static const uint32_t PSM_DEFAULT_MIN_TLS_VERSION = 1;
1676 static const uint32_t PSM_DEFAULT_MAX_TLS_VERSION = 3;
1677
1678 uint32_t minFromPrefs = Preferences::GetUint("security.tls.version.min",
1679 PSM_DEFAULT_MIN_TLS_VERSION);
1680 uint32_t maxFromPrefs = Preferences::GetUint("security.tls.version.max",
1681 PSM_DEFAULT_MAX_TLS_VERSION);
1682
1683 SSLVersionRange defaults = {
1684 SSL_LIBRARY_VERSION_3_0 + PSM_DEFAULT_MIN_TLS_VERSION,
1685 SSL_LIBRARY_VERSION_3_0 + PSM_DEFAULT_MAX_TLS_VERSION
1686 };
1687 SSLVersionRange filledInRange;
1688 FillTLSVersionRange(filledInRange, minFromPrefs, maxFromPrefs, defaults);
1689
1690 SECStatus srv =
1691 SSL_VersionRangeSetDefault(ssl_variant_stream, &filledInRange);
1692 if (srv != SECSuccess) {
1693 return NS_ERROR_FAILURE;
1694 }
1695
1696 return NS_OK;
1697 }
1698
1699 static nsresult
GetNSSProfilePath(nsAutoCString & aProfilePath)1700 GetNSSProfilePath(nsAutoCString& aProfilePath)
1701 {
1702 aProfilePath.Truncate();
1703 const char* dbDirOverride = getenv("MOZPSM_NSSDBDIR_OVERRIDE");
1704 if (dbDirOverride && strlen(dbDirOverride) > 0) {
1705 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
1706 ("Using specified MOZPSM_NSSDBDIR_OVERRIDE as NSS DB dir: %s\n",
1707 dbDirOverride));
1708 aProfilePath.Assign(dbDirOverride);
1709 return NS_OK;
1710 }
1711
1712 nsCOMPtr<nsIFile> profileFile;
1713 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR,
1714 getter_AddRefs(profileFile));
1715 if (NS_FAILED(rv)) {
1716 NS_WARNING("NSS will be initialized without a profile directory. "
1717 "Some things may not work as expected.");
1718 return NS_OK;
1719 }
1720
1721 #if defined(XP_WIN)
1722 // Native path will drop Unicode characters that cannot be mapped to system's
1723 // codepage, using short (canonical) path as workaround.
1724 nsCOMPtr<nsILocalFileWin> profileFileWin(do_QueryInterface(profileFile));
1725 if (!profileFileWin) {
1726 MOZ_LOG(gPIPNSSLog, LogLevel::Error,
1727 ("Could not get nsILocalFileWin for profile directory.\n"));
1728 return NS_ERROR_FAILURE;
1729 }
1730 rv = profileFileWin->GetNativeCanonicalPath(aProfilePath);
1731 #else
1732 rv = profileFile->GetNativePath(aProfilePath);
1733 #endif
1734 #ifdef ANDROID
1735 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1736 #endif
1737 if (NS_FAILED(rv)) {
1738 MOZ_LOG(gPIPNSSLog, LogLevel::Error,
1739 ("Could not get native path for profile directory.\n"));
1740 return rv;
1741 }
1742
1743 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
1744 ("NSS profile at '%s'\n", aProfilePath.get()));
1745 return NS_OK;
1746 }
1747
1748 nsresult
InitializeNSS()1749 nsNSSComponent::InitializeNSS()
1750 {
1751 // Can be called both during init and profile change.
1752 // Needs mutex protection.
1753
1754 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::InitializeNSS\n"));
1755
1756 static_assert(nsINSSErrorsService::NSS_SEC_ERROR_BASE == SEC_ERROR_BASE &&
1757 nsINSSErrorsService::NSS_SEC_ERROR_LIMIT == SEC_ERROR_LIMIT &&
1758 nsINSSErrorsService::NSS_SSL_ERROR_BASE == SSL_ERROR_BASE &&
1759 nsINSSErrorsService::NSS_SSL_ERROR_LIMIT == SSL_ERROR_LIMIT,
1760 "You must update the values in nsINSSErrorsService.idl");
1761
1762 MutexAutoLock lock(mutex);
1763
1764 #ifdef ANDROID
1765 MOZ_RELEASE_ASSERT(!mNSSInitialized);
1766 #endif
1767 if (mNSSInitialized) {
1768 // We should never try to initialize NSS more than once in a process.
1769 MOZ_ASSERT_UNREACHABLE("Trying to initialize NSS twice");
1770 return NS_ERROR_FAILURE;
1771 }
1772
1773 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization beginning\n"));
1774
1775 // The call to ConfigureInternalPKCS11Token needs to be done before NSS is initialized,
1776 // but affects only static data.
1777 // If we could assume i18n will not change between profiles, one call per application
1778 // run were sufficient. As I can't predict what happens in the future, let's repeat
1779 // this call for every re-init of NSS.
1780
1781 ConfigureInternalPKCS11Token();
1782
1783 nsAutoCString profileStr;
1784 nsresult rv = GetNSSProfilePath(profileStr);
1785 #ifdef ANDROID
1786 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1787 #endif
1788 if (NS_FAILED(rv)) {
1789 return NS_ERROR_NOT_AVAILABLE;
1790 }
1791
1792 SECStatus init_rv = SECFailure;
1793 bool nocertdb = Preferences::GetBool("security.nocertdb", false);
1794 bool inSafeMode = true;
1795 nsCOMPtr<nsIXULRuntime> runtime(do_GetService("@mozilla.org/xre/runtime;1"));
1796 // There might not be an nsIXULRuntime in embedded situations. This will
1797 // default to assuming we are in safe mode (as a result, no external PKCS11
1798 // modules will be loaded).
1799 if (runtime) {
1800 rv = runtime->GetInSafeMode(&inSafeMode);
1801 #ifdef ANDROID
1802 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1803 #endif
1804 if (NS_FAILED(rv)) {
1805 return rv;
1806 }
1807 }
1808 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("inSafeMode: %u\n", inSafeMode));
1809
1810 if (!nocertdb && !profileStr.IsEmpty()) {
1811 // First try to initialize the NSS DB in read/write mode.
1812 // Only load PKCS11 modules if we're not in safe mode.
1813 init_rv = ::mozilla::psm::InitializeNSS(profileStr.get(), false, !inSafeMode);
1814 // If that fails, attempt read-only mode.
1815 if (init_rv != SECSuccess) {
1816 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not init NSS r/w in %s\n", profileStr.get()));
1817 init_rv = ::mozilla::psm::InitializeNSS(profileStr.get(), true, !inSafeMode);
1818 }
1819 if (init_rv != SECSuccess) {
1820 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not init in r/o either\n"));
1821 }
1822 }
1823 // If we haven't succeeded in initializing the DB in our profile
1824 // directory or we don't have a profile at all, or the "security.nocertdb"
1825 // pref has been set to "true", attempt to initialize with no DB.
1826 if (nocertdb || init_rv != SECSuccess) {
1827 init_rv = NSS_NoDB_Init(nullptr);
1828 #ifdef ANDROID
1829 MOZ_RELEASE_ASSERT(init_rv == SECSuccess);
1830 #endif
1831 }
1832 if (init_rv != SECSuccess) {
1833 #ifdef ANDROID
1834 MOZ_RELEASE_ASSERT(false);
1835 #endif
1836 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("could not initialize NSS - panicking\n"));
1837 return NS_ERROR_NOT_AVAILABLE;
1838 }
1839
1840 // ensure we have an initial value for the content signer root
1841 mContentSigningRootHash =
1842 Preferences::GetString("security.content.signature.root_hash");
1843
1844 mNSSInitialized = true;
1845
1846 PK11_SetPasswordFunc(PK11PasswordPrompt);
1847
1848 SharedSSLState::GlobalInit();
1849
1850 // Register an observer so we can inform NSS when these prefs change
1851 Preferences::AddStrongObserver(this, "security.");
1852
1853 SSL_OptionSetDefault(SSL_ENABLE_SSL2, false);
1854 SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, false);
1855
1856 rv = setEnabledTLSVersions();
1857 #ifdef ANDROID
1858 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1859 #endif
1860 if (NS_FAILED(rv)) {
1861 return NS_ERROR_UNEXPECTED;
1862 }
1863
1864 DisableMD5();
1865 LoadLoadableRoots();
1866
1867 rv = LoadExtendedValidationInfo();
1868 #ifdef ANDROID
1869 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
1870 #endif
1871 if (NS_FAILED(rv)) {
1872 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to load EV info"));
1873 return rv;
1874 }
1875
1876 MaybeEnableFamilySafetyCompatibility();
1877 MaybeImportEnterpriseRoots();
1878
1879 ConfigureTLSSessionIdentifiers();
1880
1881 bool requireSafeNegotiation =
1882 Preferences::GetBool("security.ssl.require_safe_negotiation",
1883 REQUIRE_SAFE_NEGOTIATION_DEFAULT);
1884 SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
1885
1886 SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_REQUIRES_XTN);
1887
1888 SSL_OptionSetDefault(SSL_ENABLE_EXTENDED_MASTER_SECRET, true);
1889
1890 SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
1891 Preferences::GetBool("security.ssl.enable_false_start",
1892 FALSE_START_ENABLED_DEFAULT));
1893
1894 // SSL_ENABLE_NPN and SSL_ENABLE_ALPN also require calling
1895 // SSL_SetNextProtoNego in order for the extensions to be negotiated.
1896 // WebRTC does not do that so it will not use NPN or ALPN even when these
1897 // preferences are true.
1898 SSL_OptionSetDefault(SSL_ENABLE_NPN,
1899 Preferences::GetBool("security.ssl.enable_npn",
1900 NPN_ENABLED_DEFAULT));
1901 SSL_OptionSetDefault(SSL_ENABLE_ALPN,
1902 Preferences::GetBool("security.ssl.enable_alpn",
1903 ALPN_ENABLED_DEFAULT));
1904
1905 SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
1906 Preferences::GetBool("security.tls.enable_0rtt_data",
1907 ENABLED_0RTT_DATA_DEFAULT));
1908
1909 if (NS_FAILED(InitializeCipherSuite())) {
1910 #ifdef ANDROID
1911 MOZ_RELEASE_ASSERT(false);
1912 #endif
1913 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to initialize cipher suite settings\n"));
1914 return NS_ERROR_FAILURE;
1915 }
1916
1917 // TLSServerSocket may be run with the session cache enabled. It is necessary
1918 // to call this once before that can happen. This specifies a maximum of 1000
1919 // cache entries (the default number of cache entries is 10000, which seems a
1920 // little excessive as there probably won't be that many clients connecting to
1921 // any TLSServerSockets the browser runs.)
1922 // Note that this must occur before any calls to SSL_ClearSessionCache
1923 // (otherwise memory will leak).
1924 if (SSL_ConfigServerSessionIDCache(1000, 0, 0, nullptr) != SECSuccess) {
1925 #ifdef ANDROID
1926 MOZ_RELEASE_ASSERT(false);
1927 #endif
1928 return NS_ERROR_FAILURE;
1929 }
1930
1931 // ensure the CertBlocklist is initialised
1932 nsCOMPtr<nsICertBlocklist> certList = do_GetService(NS_CERTBLOCKLIST_CONTRACTID);
1933 #ifdef ANDROID
1934 MOZ_RELEASE_ASSERT(certList);
1935 #endif
1936 if (!certList) {
1937 return NS_ERROR_FAILURE;
1938 }
1939
1940 // dynamic options from prefs
1941 setValidationOptions(true, lock);
1942
1943 #ifndef MOZ_NO_SMART_CARDS
1944 LaunchSmartCardThreads();
1945 #endif
1946
1947 mozilla::pkix::RegisterErrorTable();
1948
1949 // Initialize the site security service
1950 nsCOMPtr<nsISiteSecurityService> sssService =
1951 do_GetService(NS_SSSERVICE_CONTRACTID);
1952 #ifdef ANDROID
1953 MOZ_RELEASE_ASSERT(sssService);
1954 #endif
1955 if (!sssService) {
1956 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Cannot initialize site security service\n"));
1957 return NS_ERROR_FAILURE;
1958 }
1959
1960 // Initialize the cert override service
1961 nsCOMPtr<nsICertOverrideService> coService =
1962 do_GetService(NS_CERTOVERRIDE_CONTRACTID);
1963 #ifdef ANDROID
1964 MOZ_RELEASE_ASSERT(coService);
1965 #endif
1966 if (!coService) {
1967 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Cannot initialize cert override service\n"));
1968 return NS_ERROR_FAILURE;
1969 }
1970
1971 if (PK11_IsFIPS()) {
1972 Telemetry::Accumulate(Telemetry::FIPS_ENABLED, true);
1973 }
1974 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization done\n"));
1975 return NS_OK;
1976 }
1977
1978 void
ShutdownNSS()1979 nsNSSComponent::ShutdownNSS()
1980 {
1981 // Can be called both during init and profile change,
1982 // needs mutex protection.
1983
1984 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ShutdownNSS\n"));
1985 MOZ_RELEASE_ASSERT(NS_IsMainThread());
1986
1987 MutexAutoLock lock(mutex);
1988
1989 if (mNSSInitialized) {
1990 mNSSInitialized = false;
1991
1992 PK11_SetPasswordFunc((PK11PasswordFunc)nullptr);
1993
1994 Preferences::RemoveObserver(this, "security.");
1995
1996 #ifdef XP_WIN
1997 mFamilySafetyRoot = nullptr;
1998 mEnterpriseRoots = nullptr;
1999 #endif
2000
2001 #ifndef MOZ_NO_SMART_CARDS
2002 ShutdownSmartCardThreads();
2003 #endif
2004 SSL_ClearSessionCache();
2005 // TLSServerSocket may be run with the session cache enabled. This ensures
2006 // those resources are cleaned up.
2007 Unused << SSL_ShutdownServerSessionIDCache();
2008
2009 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("evaporating psm resources"));
2010 if (NS_FAILED(nsNSSShutDownList::evaporateAllNSSResources())) {
2011 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to evaporate resources"));
2012 return;
2013 }
2014 UnloadLoadableRoots();
2015 EnsureNSSInitialized(nssShutdown);
2016 if (SECSuccess != ::NSS_Shutdown()) {
2017 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("NSS SHUTDOWN FAILURE"));
2018 } else {
2019 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS shutdown =====>> OK <<====="));
2020 }
2021 }
2022 }
2023
2024 nsresult
Init()2025 nsNSSComponent::Init()
2026 {
2027 MOZ_RELEASE_ASSERT(NS_IsMainThread());
2028 if (!NS_IsMainThread()) {
2029 return NS_ERROR_NOT_SAME_THREAD;
2030 }
2031
2032 nsresult rv = NS_OK;
2033
2034 // To avoid a sqlite3_config race in NSS init, as a workaround for
2035 // bug 730495, we require the storage service to get initialized first.
2036 nsCOMPtr<nsISupports> storageService =
2037 do_GetService(MOZ_STORAGE_SERVICE_CONTRACTID);
2038 if (!storageService) {
2039 return NS_ERROR_NOT_AVAILABLE;
2040 }
2041
2042 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Beginning NSS initialization\n"));
2043
2044 rv = InitializePIPNSSBundle();
2045 #ifdef ANDROID
2046 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
2047 #endif
2048 if (NS_FAILED(rv)) {
2049 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("Unable to create pipnss bundle.\n"));
2050 return rv;
2051 }
2052
2053 // Access our string bundles now, this prevents assertions from I/O
2054 // - nsStandardURL not thread-safe
2055 // - wrong thread: 'NS_IsMainThread()' in nsIOService.cpp
2056 // when loading error strings on the SSL threads.
2057 {
2058 NS_NAMED_LITERAL_STRING(dummy_name, "dummy");
2059 nsXPIDLString result;
2060 mPIPNSSBundle->GetStringFromName(dummy_name.get(),
2061 getter_Copies(result));
2062 mNSSErrorsBundle->GetStringFromName(dummy_name.get(),
2063 getter_Copies(result));
2064 }
2065
2066
2067 rv = InitializeNSS();
2068 #ifdef ANDROID
2069 MOZ_RELEASE_ASSERT(NS_SUCCEEDED(rv));
2070 #endif
2071 if (NS_FAILED(rv)) {
2072 MOZ_LOG(gPIPNSSLog, LogLevel::Error,
2073 ("nsNSSComponent::InitializeNSS() failed\n"));
2074 return rv;
2075 }
2076
2077 RememberCertErrorsTable::Init();
2078
2079 return RegisterObservers();
2080 }
2081
2082 // nsISupports Implementation for the class
2083 NS_IMPL_ISUPPORTS(nsNSSComponent,
2084 nsINSSComponent,
2085 nsIObserver)
2086
2087 static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change";
2088
2089 NS_IMETHODIMP
Observe(nsISupports * aSubject,const char * aTopic,const char16_t * someData)2090 nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic,
2091 const char16_t* someData)
2092 {
2093 if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0) {
2094 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("receiving profile change topic\n"));
2095 DoProfileBeforeChange();
2096 } else if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
2097 nsNSSShutDownPreventionLock locker;
2098 bool clearSessionCache = true;
2099 NS_ConvertUTF16toUTF8 prefName(someData);
2100
2101 if (prefName.EqualsLiteral("security.tls.version.min") ||
2102 prefName.EqualsLiteral("security.tls.version.max")) {
2103 (void) setEnabledTLSVersions();
2104 } else if (prefName.EqualsLiteral("security.ssl.require_safe_negotiation")) {
2105 bool requireSafeNegotiation =
2106 Preferences::GetBool("security.ssl.require_safe_negotiation",
2107 REQUIRE_SAFE_NEGOTIATION_DEFAULT);
2108 SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, requireSafeNegotiation);
2109 } else if (prefName.EqualsLiteral("security.ssl.enable_false_start")) {
2110 SSL_OptionSetDefault(SSL_ENABLE_FALSE_START,
2111 Preferences::GetBool("security.ssl.enable_false_start",
2112 FALSE_START_ENABLED_DEFAULT));
2113 } else if (prefName.EqualsLiteral("security.ssl.enable_npn")) {
2114 SSL_OptionSetDefault(SSL_ENABLE_NPN,
2115 Preferences::GetBool("security.ssl.enable_npn",
2116 NPN_ENABLED_DEFAULT));
2117 } else if (prefName.EqualsLiteral("security.ssl.enable_alpn")) {
2118 SSL_OptionSetDefault(SSL_ENABLE_ALPN,
2119 Preferences::GetBool("security.ssl.enable_alpn",
2120 ALPN_ENABLED_DEFAULT));
2121 } else if (prefName.EqualsLiteral("security.tls.enable_0rtt_data")) {
2122 SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA,
2123 Preferences::GetBool("security.tls.enable_0rtt_data",
2124 ENABLED_0RTT_DATA_DEFAULT));
2125 } else if (prefName.Equals("security.ssl.disable_session_identifiers")) {
2126 ConfigureTLSSessionIdentifiers();
2127 } else if (prefName.EqualsLiteral("security.OCSP.enabled") ||
2128 prefName.EqualsLiteral("security.OCSP.require") ||
2129 prefName.EqualsLiteral("security.OCSP.GET.enabled") ||
2130 prefName.EqualsLiteral("security.pki.cert_short_lifetime_in_days") ||
2131 prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") ||
2132 prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") ||
2133 prefName.EqualsLiteral("security.pki.certificate_transparency.mode") ||
2134 prefName.EqualsLiteral("security.cert_pinning.enforcement_level") ||
2135 prefName.EqualsLiteral("security.pki.sha1_enforcement_level") ||
2136 prefName.EqualsLiteral("security.pki.name_matching_mode") ||
2137 prefName.EqualsLiteral("security.pki.netscape_step_up_policy")) {
2138 MutexAutoLock lock(mutex);
2139 setValidationOptions(false, lock);
2140 #ifdef DEBUG
2141 } else if (prefName.EqualsLiteral("security.test.built_in_root_hash")) {
2142 MutexAutoLock lock(mutex);
2143 mTestBuiltInRootHash = Preferences::GetString("security.test.built_in_root_hash");
2144 #endif // DEBUG
2145 } else if (prefName.Equals(kFamilySafetyModePref)) {
2146 MaybeEnableFamilySafetyCompatibility();
2147 } else if (prefName.EqualsLiteral("security.content.signature.root_hash")) {
2148 MutexAutoLock lock(mutex);
2149 mContentSigningRootHash =
2150 Preferences::GetString("security.content.signature.root_hash");
2151 } else if (prefName.Equals(kEnterpriseRootModePref)) {
2152 MaybeImportEnterpriseRoots();
2153 } else {
2154 clearSessionCache = false;
2155 }
2156 if (clearSessionCache)
2157 SSL_ClearSessionCache();
2158 }
2159
2160 return NS_OK;
2161 }
2162
2163 /*static*/ nsresult
GetNewPrompter(nsIPrompt ** result)2164 nsNSSComponent::GetNewPrompter(nsIPrompt** result)
2165 {
2166 NS_ENSURE_ARG_POINTER(result);
2167 *result = nullptr;
2168
2169 if (!NS_IsMainThread()) {
2170 NS_ERROR("nsSDRContext::GetNewPrompter called off the main thread");
2171 return NS_ERROR_NOT_SAME_THREAD;
2172 }
2173
2174 nsresult rv;
2175 nsCOMPtr<nsIWindowWatcher> wwatch(do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv));
2176 NS_ENSURE_SUCCESS(rv, rv);
2177
2178 rv = wwatch->GetNewPrompter(0, result);
2179 NS_ENSURE_SUCCESS(rv, rv);
2180
2181 return rv;
2182 }
2183
2184 /*static*/ nsresult
ShowAlertWithConstructedString(const nsString & message)2185 nsNSSComponent::ShowAlertWithConstructedString(const nsString& message)
2186 {
2187 nsCOMPtr<nsIPrompt> prompter;
2188 nsresult rv = GetNewPrompter(getter_AddRefs(prompter));
2189 if (prompter) {
2190 rv = prompter->Alert(nullptr, message.get());
2191 }
2192 return rv;
2193 }
2194
2195 NS_IMETHODIMP
ShowAlertFromStringBundle(const char * messageID)2196 nsNSSComponent::ShowAlertFromStringBundle(const char* messageID)
2197 {
2198 nsString message;
2199 nsresult rv;
2200
2201 rv = GetPIPNSSBundleString(messageID, message);
2202 if (NS_FAILED(rv)) {
2203 NS_ERROR("GetPIPNSSBundleString failed");
2204 return rv;
2205 }
2206
2207 return ShowAlertWithConstructedString(message);
2208 }
2209
LogoutAuthenticatedPK11()2210 nsresult nsNSSComponent::LogoutAuthenticatedPK11()
2211 {
2212 nsCOMPtr<nsICertOverrideService> icos =
2213 do_GetService("@mozilla.org/security/certoverride;1");
2214 if (icos) {
2215 icos->ClearValidityOverride(
2216 NS_LITERAL_CSTRING("all:temporary-certificates"),
2217 0);
2218 }
2219
2220 nsClientAuthRememberService::ClearAllRememberedDecisions();
2221
2222 return nsNSSShutDownList::doPK11Logout();
2223 }
2224
2225 nsresult
RegisterObservers()2226 nsNSSComponent::RegisterObservers()
2227 {
2228 // Happens once during init only, no mutex protection.
2229
2230 nsCOMPtr<nsIObserverService> observerService(
2231 do_GetService("@mozilla.org/observer-service;1"));
2232 #ifdef ANDROID
2233 MOZ_RELEASE_ASSERT(observerService);
2234 #endif
2235 if (!observerService) {
2236 MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
2237 ("nsNSSComponent: couldn't get observer service\n"));
2238 return NS_ERROR_FAILURE;
2239 }
2240
2241 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent: adding observers\n"));
2242 // Using false for the ownsweak parameter means the observer service will
2243 // keep a strong reference to this component. As a result, this will live at
2244 // least as long as the observer service.
2245 observerService->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false);
2246
2247 return NS_OK;
2248 }
2249
2250 void
DoProfileBeforeChange()2251 nsNSSComponent::DoProfileBeforeChange()
2252 {
2253 bool needsCleanup = true;
2254
2255 {
2256 MutexAutoLock lock(mutex);
2257
2258 if (!mNSSInitialized) {
2259 // Make sure we don't try to cleanup if we have already done so.
2260 // This makes sure we behave safely, in case we are notified
2261 // multiple times.
2262 needsCleanup = false;
2263 }
2264 }
2265
2266 if (needsCleanup) {
2267 ShutdownNSS();
2268 }
2269 }
2270
2271 NS_IMETHODIMP
IsNSSInitialized(bool * initialized)2272 nsNSSComponent::IsNSSInitialized(bool* initialized)
2273 {
2274 MutexAutoLock lock(mutex);
2275 *initialized = mNSSInitialized;
2276 return NS_OK;
2277 }
2278
2279 #ifdef DEBUG
2280 NS_IMETHODIMP
IsCertTestBuiltInRoot(CERTCertificate * cert,bool & result)2281 nsNSSComponent::IsCertTestBuiltInRoot(CERTCertificate* cert, bool& result)
2282 {
2283 MutexAutoLock lock(mutex);
2284 MOZ_ASSERT(mNSSInitialized);
2285
2286 result = false;
2287
2288 if (mTestBuiltInRootHash.IsEmpty()) {
2289 return NS_OK;
2290 }
2291
2292 RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(cert);
2293 if (!nsc) {
2294 return NS_ERROR_FAILURE;
2295 }
2296 nsAutoString certHash;
2297 nsresult rv = nsc->GetSha256Fingerprint(certHash);
2298 if (NS_FAILED(rv)) {
2299 return rv;
2300 }
2301
2302 result = mTestBuiltInRootHash.Equals(certHash);
2303 return NS_OK;
2304 }
2305 #endif // DEBUG
2306
2307 NS_IMETHODIMP
IsCertContentSigningRoot(CERTCertificate * cert,bool & result)2308 nsNSSComponent::IsCertContentSigningRoot(CERTCertificate* cert, bool& result)
2309 {
2310 MutexAutoLock lock(mutex);
2311 MOZ_ASSERT(mNSSInitialized);
2312
2313 result = false;
2314
2315 if (mContentSigningRootHash.IsEmpty()) {
2316 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("mContentSigningRootHash is empty"));
2317 return NS_ERROR_FAILURE;
2318 }
2319
2320 RefPtr<nsNSSCertificate> nsc = nsNSSCertificate::Create(cert);
2321 if (!nsc) {
2322 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("creating nsNSSCertificate failed"));
2323 return NS_ERROR_FAILURE;
2324 }
2325 nsAutoString certHash;
2326 nsresult rv = nsc->GetSha256Fingerprint(certHash);
2327 if (NS_FAILED(rv)) {
2328 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("getting cert fingerprint failed"));
2329 return rv;
2330 }
2331
2332 result = mContentSigningRootHash.Equals(certHash);
2333 return NS_OK;
2334 }
2335
~SharedCertVerifier()2336 SharedCertVerifier::~SharedCertVerifier() { }
2337
2338 already_AddRefed<SharedCertVerifier>
GetDefaultCertVerifier()2339 nsNSSComponent::GetDefaultCertVerifier()
2340 {
2341 MutexAutoLock lock(mutex);
2342 MOZ_ASSERT(mNSSInitialized);
2343 RefPtr<SharedCertVerifier> certVerifier(mDefaultCertVerifier);
2344 return certVerifier.forget();
2345 }
2346
2347 namespace mozilla { namespace psm {
2348
2349 already_AddRefed<SharedCertVerifier>
GetDefaultCertVerifier()2350 GetDefaultCertVerifier()
2351 {
2352 static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
2353
2354 nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID));
2355 if (nssComponent) {
2356 return nssComponent->GetDefaultCertVerifier();
2357 }
2358
2359 return nullptr;
2360 }
2361
2362 } } // namespace mozilla::psm
2363
NS_IMPL_ISUPPORTS(PipUIContext,nsIInterfaceRequestor)2364 NS_IMPL_ISUPPORTS(PipUIContext, nsIInterfaceRequestor)
2365
2366 PipUIContext::PipUIContext()
2367 {
2368 }
2369
~PipUIContext()2370 PipUIContext::~PipUIContext()
2371 {
2372 }
2373
2374 NS_IMETHODIMP
GetInterface(const nsIID & uuid,void ** result)2375 PipUIContext::GetInterface(const nsIID& uuid, void** result)
2376 {
2377 NS_ENSURE_ARG_POINTER(result);
2378 *result = nullptr;
2379
2380 if (!NS_IsMainThread()) {
2381 NS_ERROR("PipUIContext::GetInterface called off the main thread");
2382 return NS_ERROR_NOT_SAME_THREAD;
2383 }
2384
2385 if (!uuid.Equals(NS_GET_IID(nsIPrompt)))
2386 return NS_ERROR_NO_INTERFACE;
2387
2388 nsIPrompt* prompt = nullptr;
2389 nsresult rv = nsNSSComponent::GetNewPrompter(&prompt);
2390 *result = prompt;
2391 return rv;
2392 }
2393
2394 nsresult
getNSSDialogs(void ** _result,REFNSIID aIID,const char * contract)2395 getNSSDialogs(void** _result, REFNSIID aIID, const char* contract)
2396 {
2397 if (!NS_IsMainThread()) {
2398 NS_ERROR("getNSSDialogs called off the main thread");
2399 return NS_ERROR_NOT_SAME_THREAD;
2400 }
2401
2402 nsresult rv;
2403
2404 nsCOMPtr<nsISupports> svc = do_GetService(contract, &rv);
2405 if (NS_FAILED(rv)) {
2406 return rv;
2407 }
2408
2409 rv = svc->QueryInterface(aIID, _result);
2410
2411 return rv;
2412 }
2413
2414 nsresult
setPassword(PK11SlotInfo * slot,nsIInterfaceRequestor * ctx,nsNSSShutDownPreventionLock &)2415 setPassword(PK11SlotInfo* slot, nsIInterfaceRequestor* ctx,
2416 nsNSSShutDownPreventionLock& /*proofOfLock*/)
2417 {
2418 MOZ_ASSERT(slot);
2419 MOZ_ASSERT(ctx);
2420 NS_ENSURE_ARG_POINTER(slot);
2421 NS_ENSURE_ARG_POINTER(ctx);
2422
2423 if (PK11_NeedUserInit(slot)) {
2424 nsCOMPtr<nsITokenPasswordDialogs> dialogs;
2425 nsresult rv = getNSSDialogs(getter_AddRefs(dialogs),
2426 NS_GET_IID(nsITokenPasswordDialogs),
2427 NS_TOKENPASSWORDSDIALOG_CONTRACTID);
2428 if (NS_FAILED(rv)) {
2429 return rv;
2430 }
2431
2432 bool canceled;
2433 NS_ConvertUTF8toUTF16 tokenName(PK11_GetTokenName(slot));
2434 rv = dialogs->SetPassword(ctx, tokenName.get(), &canceled);
2435 if (NS_FAILED(rv)) {
2436 return rv;
2437 }
2438
2439 if (canceled) {
2440 return NS_ERROR_NOT_AVAILABLE;
2441 }
2442 }
2443
2444 return NS_OK;
2445 }
2446
2447 namespace mozilla {
2448 namespace psm {
2449
2450 nsresult
InitializeCipherSuite()2451 InitializeCipherSuite()
2452 {
2453 NS_ASSERTION(NS_IsMainThread(), "InitializeCipherSuite() can only be accessed in main thread");
2454
2455 if (NSS_SetDomesticPolicy() != SECSuccess) {
2456 #ifdef ANDROID
2457 MOZ_RELEASE_ASSERT(false);
2458 #endif
2459 return NS_ERROR_FAILURE;
2460 }
2461
2462 // Disable any ciphers that NSS might have enabled by default
2463 for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) {
2464 uint16_t cipher_id = SSL_ImplementedCiphers[i];
2465 SSL_CipherPrefSetDefault(cipher_id, false);
2466 }
2467
2468 // Now only set SSL/TLS ciphers we knew about at compile time
2469 uint32_t enabledWeakCiphers = 0;
2470 const CipherPref* const cp = sCipherPrefs;
2471 for (size_t i = 0; cp[i].pref; ++i) {
2472 bool cipherEnabled = Preferences::GetBool(cp[i].pref,
2473 cp[i].enabledByDefault);
2474 if (cp[i].weak) {
2475 // Weak ciphers are not used by default. See the comment
2476 // in CipherSuiteChangeObserver::Observe for details.
2477 if (cipherEnabled) {
2478 enabledWeakCiphers |= ((uint32_t)1 << i);
2479 }
2480 } else {
2481 SSL_CipherPrefSetDefault(cp[i].id, cipherEnabled);
2482 }
2483 }
2484 sEnabledWeakCiphers = enabledWeakCiphers;
2485
2486 // Enable ciphers for PKCS#12
2487 SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1);
2488 SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1);
2489 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1);
2490 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1);
2491 SEC_PKCS12EnableCipher(PKCS12_DES_56, 1);
2492 SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1);
2493 SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1);
2494 PORT_SetUCS2_ASCIIConversionFunction(pip_ucs2_ascii_conversion_fn);
2495
2496 // PSM enforces a minimum RSA key size of 1024 bits, which is overridable.
2497 // NSS has its own minimum, which is not overridable (the default is 1023
2498 // bits). This sets the NSS minimum to 512 bits so users can still connect to
2499 // devices like wifi routers with woefully small keys (they would have to add
2500 // an override to do so, but they already do for such devices).
2501 NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 512);
2502
2503 // Observe preference change around cipher suite setting.
2504 return CipherSuiteChangeObserver::StartObserve();
2505 }
2506
2507 } // namespace psm
2508 } // namespace mozilla
2509