nsNSSComponent.cpp (79724B)
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 "BinaryPath.h" 10 #include "CryptoTask.h" 11 #include "EnterpriseRoots.h" 12 #include "ExtendedValidation.h" 13 #include "NSSCertDBTrustDomain.h" 14 #include "PKCS11ModuleDB.h" 15 #include "SSLTokensCache.h" 16 #include "ScopedNSSTypes.h" 17 #include "cert.h" 18 #include "cert_storage/src/cert_storage.h" 19 #include "certdb.h" 20 #include "mozilla/AppShutdown.h" 21 #include "mozilla/Atomics.h" 22 #include "mozilla/Assertions.h" 23 #include "mozilla/Base64.h" 24 #include "mozilla/EndianUtils.h" 25 #include "mozilla/FilePreferences.h" 26 #include "mozilla/Preferences.h" 27 #include "mozilla/ProfilerLabels.h" 28 #include "mozilla/ProfilerMarkers.h" 29 #include "mozilla/PublicSSL.h" 30 #include "mozilla/Services.h" 31 #include "mozilla/StaticMutex.h" 32 #include "mozilla/StaticPrefs_security.h" 33 #include "mozilla/StaticPtr.h" 34 #include "mozilla/SyncRunnable.h" 35 #include "mozilla/TimeStamp.h" 36 #include "mozilla/Vector.h" 37 #include "mozilla/dom/Promise.h" 38 #include "mozilla/glean/SecurityManagerSslMetrics.h" 39 #include "mozilla/net/SocketProcessParent.h" 40 #include "mozpkix/pkixnss.h" 41 #include "nsAppDirectoryServiceDefs.h" 42 #include "nsCRT.h" 43 #include "nsClientAuthRemember.h" 44 #include "nsComponentManagerUtils.h" 45 #include "nsDirectoryServiceDefs.h" 46 #include "nsICertOverrideService.h" 47 #include "nsIFile.h" 48 #include "nsIOService.h" 49 #include "nsIObserverService.h" 50 #include "nsIPrompt.h" 51 #include "nsIProperties.h" 52 #include "nsISerialEventTarget.h" 53 #include "nsISiteSecurityService.h" 54 #include "nsITimer.h" 55 #include "nsITokenPasswordDialogs.h" 56 #include "nsIWindowWatcher.h" 57 #include "nsIXULRuntime.h" 58 #include "nsLiteralString.h" 59 #include "nsNSSHelper.h" 60 #include "nsNSSIOLayer.h" 61 #include "nsNetCID.h" 62 #include "nsPK11TokenDB.h" 63 #include "nsPrintfCString.h" 64 #include "nsServiceManagerUtils.h" 65 #include "nsThreadUtils.h" 66 #include "nsXULAppAPI.h" 67 #include "nss.h" 68 #include "p12plcy.h" 69 #include "pk11pub.h" 70 #include "prmem.h" 71 #include "secerr.h" 72 #include "secmod.h" 73 #include "ssl.h" 74 #include "sslerr.h" 75 #include "sslproto.h" 76 77 #if defined(XP_LINUX) && !defined(ANDROID) 78 # include <linux/magic.h> 79 # include <sys/vfs.h> 80 #endif 81 82 using namespace mozilla; 83 using namespace mozilla::psm; 84 85 LazyLogModule gPIPNSSLog("pipnss"); 86 87 int nsNSSComponent::mInstanceCount = 0; 88 89 // Forward declaration. 90 nsresult CommonInit(); 91 92 template <const glean::impl::QuantityMetric* metric> 93 class MOZ_RAII AutoGleanTimer { 94 public: 95 explicit AutoGleanTimer(TimeStamp aStart = TimeStamp::Now()) 96 : mStart(aStart) {} 97 98 ~AutoGleanTimer() { 99 TimeStamp end = TimeStamp::Now(); 100 uint32_t delta = static_cast<uint32_t>((end - mStart).ToMilliseconds()); 101 metric->Set(delta); 102 } 103 104 private: 105 const TimeStamp mStart; 106 }; 107 108 // Take an nsIFile and get a UTF-8-encoded c-string representation of the 109 // location of that file (encapsulated in an nsACString). 110 // This operation is generally to be avoided, except when interacting with 111 // third-party or legacy libraries that cannot handle `nsIFile`s (such as NSS). 112 // |result| is encoded in UTF-8. 113 nsresult FileToCString(const nsCOMPtr<nsIFile>& file, nsACString& result) { 114 #ifdef XP_WIN 115 nsAutoString path; 116 nsresult rv = file->GetPath(path); 117 if (NS_SUCCEEDED(rv)) { 118 CopyUTF16toUTF8(path, result); 119 } 120 return rv; 121 #else 122 return file->GetNativePath(result); 123 #endif 124 } 125 126 void TruncateFromLastDirectorySeparator(nsCString& path) { 127 static const nsAutoCString kSeparatorString( 128 mozilla::FilePreferences::kPathSeparator); 129 int32_t index = path.RFind(kSeparatorString); 130 if (index == kNotFound) { 131 return; 132 } 133 path.Truncate(index); 134 } 135 136 bool LoadIPCClientCerts() { 137 if (!LoadIPCClientCertsModule()) { 138 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to load ipcclientcerts")); 139 return false; 140 } 141 return true; 142 } 143 144 // This function can be called from chrome or content or socket processes 145 // to ensure that NSS is initialized. 146 bool EnsureNSSInitializedChromeOrContent() { 147 static Atomic<bool> initialized(false); 148 149 if (initialized) { 150 return true; 151 } 152 153 // If this is not the main thread (i.e. probably a worker) then forward this 154 // call to the main thread. 155 if (!NS_IsMainThread()) { 156 nsCOMPtr<nsIThread> mainThread; 157 nsresult rv = NS_GetMainThread(getter_AddRefs(mainThread)); 158 if (NS_FAILED(rv)) { 159 return false; 160 } 161 162 // Forward to the main thread synchronously. 163 mozilla::SyncRunnable::DispatchToThread( 164 mainThread, 165 NS_NewRunnableFunction("EnsureNSSInitializedChromeOrContent", []() { 166 EnsureNSSInitializedChromeOrContent(); 167 })); 168 169 return initialized; 170 } 171 172 if (XRE_IsParentProcess()) { 173 nsCOMPtr<nsISupports> nss = do_GetService(PSM_COMPONENT_CONTRACTID); 174 if (!nss) { 175 return false; 176 } 177 initialized = true; 178 return true; 179 } 180 181 if (NSS_IsInitialized()) { 182 initialized = true; 183 return true; 184 } 185 186 if (NSS_NoDB_Init(nullptr) != SECSuccess) { 187 return false; 188 } 189 190 if (XRE_IsSocketProcess()) { 191 if (NS_FAILED(CommonInit())) { 192 return false; 193 } 194 // If ipcclientcerts fails to load, client certificate authentication won't 195 // work (if networking is done on the socket process). This is preferable 196 // to stopping the program entirely, so treat this as best-effort. 197 (void)NS_WARN_IF(!LoadIPCClientCerts()); 198 initialized = true; 199 return true; 200 } 201 202 if (NS_FAILED(mozilla::psm::InitializeCipherSuite())) { 203 return false; 204 } 205 206 mozilla::psm::DisableMD5(); 207 mozilla::pkix::RegisterErrorTable(); 208 initialized = true; 209 return true; 210 } 211 212 static const uint32_t OCSP_TIMEOUT_MILLISECONDS_SOFT_MAX = 5000; 213 static const uint32_t OCSP_TIMEOUT_MILLISECONDS_HARD_MAX = 20000; 214 215 void nsNSSComponent::GetRevocationBehaviorFromPrefs( 216 /*out*/ CertVerifier::OcspDownloadConfig* odc, 217 /*out*/ CertVerifier::OcspStrictConfig* osc, 218 /*out*/ uint32_t* certShortLifetimeInDays, 219 /*out*/ TimeDuration& softTimeout, 220 /*out*/ TimeDuration& hardTimeout) { 221 MOZ_ASSERT(NS_IsMainThread()); 222 MOZ_ASSERT(odc); 223 MOZ_ASSERT(osc); 224 MOZ_ASSERT(certShortLifetimeInDays); 225 226 // 0 = disabled 227 // 1 = enabled for everything (default) 228 // 2 = enabled for EV certificates only 229 uint32_t ocspLevel = StaticPrefs::security_OCSP_enabled(); 230 switch (ocspLevel) { 231 case 0: 232 *odc = CertVerifier::ocspOff; 233 break; 234 case 2: 235 *odc = CertVerifier::ocspEVOnly; 236 break; 237 default: 238 *odc = CertVerifier::ocspOn; 239 break; 240 } 241 242 *osc = StaticPrefs::security_OCSP_require() ? CertVerifier::ocspStrict 243 : CertVerifier::ocspRelaxed; 244 245 *certShortLifetimeInDays = 246 StaticPrefs::security_pki_cert_short_lifetime_in_days(); 247 248 uint32_t softTimeoutMillis = 249 StaticPrefs::security_OCSP_timeoutMilliseconds_soft(); 250 softTimeoutMillis = 251 std::min(softTimeoutMillis, OCSP_TIMEOUT_MILLISECONDS_SOFT_MAX); 252 softTimeout = TimeDuration::FromMilliseconds(softTimeoutMillis); 253 254 uint32_t hardTimeoutMillis = 255 StaticPrefs::security_OCSP_timeoutMilliseconds_hard(); 256 hardTimeoutMillis = 257 std::min(hardTimeoutMillis, OCSP_TIMEOUT_MILLISECONDS_HARD_MAX); 258 hardTimeout = TimeDuration::FromMilliseconds(hardTimeoutMillis); 259 } 260 261 nsNSSComponent::nsNSSComponent() 262 : mLoadableCertsLoadedMonitor("nsNSSComponent.mLoadableCertsLoadedMonitor"), 263 mLoadableCertsLoaded(false), 264 mLoadableCertsLoadedResult(NS_ERROR_FAILURE), 265 mMutex("nsNSSComponent.mMutex"), 266 mMitmDetecionEnabled(false) { 267 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::ctor\n")); 268 MOZ_RELEASE_ASSERT(NS_IsMainThread()); 269 270 MOZ_ASSERT(mInstanceCount == 0, 271 "nsNSSComponent is a singleton, but instantiated multiple times!"); 272 ++mInstanceCount; 273 } 274 275 nsNSSComponent::~nsNSSComponent() { 276 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor\n")); 277 MOZ_RELEASE_ASSERT(NS_IsMainThread()); 278 279 // All cleanup code requiring services needs to happen in xpcom_shutdown 280 281 PrepareForShutdown(); 282 nsSSLIOLayerHelpers::GlobalCleanup(); 283 --mInstanceCount; 284 285 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::dtor finished\n")); 286 } 287 288 void nsNSSComponent::UnloadEnterpriseRoots() { 289 MOZ_ASSERT(NS_IsMainThread()); 290 if (!NS_IsMainThread()) { 291 return; 292 } 293 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("UnloadEnterpriseRoots")); 294 MutexAutoLock lock(mMutex); 295 mEnterpriseCerts.Clear(); 296 setValidationOptions(lock); 297 ClearSSLExternalAndInternalSessionCache(); 298 } 299 300 class BackgroundImportEnterpriseCertsTask final : public CryptoTask { 301 public: 302 explicit BackgroundImportEnterpriseCertsTask(nsNSSComponent* nssComponent) 303 : mNSSComponent(nssComponent) {} 304 305 private: 306 virtual nsresult CalculateResult() override { 307 mNSSComponent->ImportEnterpriseRoots(); 308 mNSSComponent->UpdateCertVerifierWithEnterpriseRoots(); 309 return NS_OK; 310 } 311 312 virtual void CallCallback(nsresult rv) override { 313 nsCOMPtr<nsIObserverService> observerService = 314 mozilla::services::GetObserverService(); 315 if (observerService) { 316 observerService->NotifyObservers(nullptr, "psm:enterprise-certs-imported", 317 nullptr); 318 } 319 } 320 321 RefPtr<nsNSSComponent> mNSSComponent; 322 }; 323 324 void nsNSSComponent::MaybeImportEnterpriseRoots() { 325 MOZ_ASSERT(NS_IsMainThread()); 326 if (!NS_IsMainThread()) { 327 return; 328 } 329 bool importEnterpriseRoots = StaticPrefs::security_enterprise_roots_enabled(); 330 if (importEnterpriseRoots) { 331 RefPtr<BackgroundImportEnterpriseCertsTask> task = 332 new BackgroundImportEnterpriseCertsTask(this); 333 (void)task->Dispatch(); 334 } 335 } 336 337 void nsNSSComponent::ImportEnterpriseRoots() { 338 MOZ_ASSERT(!NS_IsMainThread()); 339 if (NS_IsMainThread()) { 340 return; 341 } 342 343 nsTArray<EnterpriseCert> enterpriseCerts; 344 nsresult rv = GatherEnterpriseCerts(enterpriseCerts); 345 if (NS_SUCCEEDED(rv)) { 346 MutexAutoLock lock(mMutex); 347 mEnterpriseCerts = std::move(enterpriseCerts); 348 } else { 349 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed gathering enterprise roots")); 350 } 351 } 352 353 nsresult nsNSSComponent::CommonGetEnterpriseCerts( 354 nsTArray<nsTArray<uint8_t>>& enterpriseCerts, bool getRoots) { 355 nsresult rv = BlockUntilLoadableCertsLoaded(); 356 if (NS_FAILED(rv)) { 357 return rv; 358 } 359 360 enterpriseCerts.Clear(); 361 MutexAutoLock nsNSSComponentLock(mMutex); 362 for (const auto& cert : mEnterpriseCerts) { 363 nsTArray<uint8_t> certCopy; 364 // mEnterpriseCerts includes both roots and intermediates. 365 if (cert.GetIsRoot() == getRoots) { 366 cert.CopyBytes(certCopy); 367 enterpriseCerts.AppendElement(std::move(certCopy)); 368 } 369 } 370 return NS_OK; 371 } 372 373 NS_IMETHODIMP 374 nsNSSComponent::GetEnterpriseRoots( 375 nsTArray<nsTArray<uint8_t>>& enterpriseRoots) { 376 return CommonGetEnterpriseCerts(enterpriseRoots, true); 377 } 378 379 nsresult BytesArrayToPEM(const nsTArray<nsTArray<uint8_t>>& bytesArray, 380 nsACString& pemArray) { 381 for (const auto& bytes : bytesArray) { 382 nsAutoCString base64; 383 nsresult rv = Base64Encode(reinterpret_cast<const char*>(bytes.Elements()), 384 bytes.Length(), base64); 385 if (NS_FAILED(rv)) { 386 return rv; 387 } 388 if (!pemArray.IsEmpty()) { 389 pemArray.AppendLiteral("\n"); 390 } 391 pemArray.AppendLiteral("-----BEGIN CERTIFICATE-----\n"); 392 for (size_t i = 0; i < base64.Length() / 64; i++) { 393 pemArray.Append(Substring(base64, i * 64, 64)); 394 pemArray.AppendLiteral("\n"); 395 } 396 if (base64.Length() % 64 != 0) { 397 size_t chunks = base64.Length() / 64; 398 pemArray.Append(Substring(base64, chunks * 64)); 399 pemArray.AppendLiteral("\n"); 400 } 401 pemArray.AppendLiteral("-----END CERTIFICATE-----"); 402 } 403 return NS_OK; 404 } 405 406 NS_IMETHODIMP 407 nsNSSComponent::GetEnterpriseRootsPEM(nsACString& enterpriseRootsPEM) { 408 nsTArray<nsTArray<uint8_t>> enterpriseRoots; 409 nsresult rv = GetEnterpriseRoots(enterpriseRoots); 410 if (NS_FAILED(rv)) { 411 return rv; 412 } 413 return BytesArrayToPEM(enterpriseRoots, enterpriseRootsPEM); 414 } 415 416 NS_IMETHODIMP 417 nsNSSComponent::GetEnterpriseIntermediates( 418 nsTArray<nsTArray<uint8_t>>& enterpriseIntermediates) { 419 return CommonGetEnterpriseCerts(enterpriseIntermediates, false); 420 } 421 422 NS_IMETHODIMP 423 nsNSSComponent::GetEnterpriseIntermediatesPEM( 424 nsACString& enterpriseIntermediatesPEM) { 425 nsTArray<nsTArray<uint8_t>> enterpriseIntermediates; 426 nsresult rv = GetEnterpriseIntermediates(enterpriseIntermediates); 427 if (NS_FAILED(rv)) { 428 return rv; 429 } 430 return BytesArrayToPEM(enterpriseIntermediates, enterpriseIntermediatesPEM); 431 } 432 433 NS_IMETHODIMP 434 nsNSSComponent::AddEnterpriseIntermediate( 435 const nsTArray<uint8_t>& intermediateBytes) { 436 nsresult rv = BlockUntilLoadableCertsLoaded(); 437 if (NS_FAILED(rv)) { 438 return rv; 439 } 440 EnterpriseCert intermediate(intermediateBytes.Elements(), 441 intermediateBytes.Length(), false); 442 { 443 MutexAutoLock nsNSSComponentLock(mMutex); 444 mEnterpriseCerts.AppendElement(std::move(intermediate)); 445 } 446 447 UpdateCertVerifierWithEnterpriseRoots(); 448 return NS_OK; 449 } 450 451 class LoadLoadableCertsTask final : public Runnable { 452 public: 453 LoadLoadableCertsTask(nsNSSComponent* nssComponent, 454 bool importEnterpriseRoots, nsAutoCString&& greBinDir) 455 : Runnable("LoadLoadableCertsTask"), 456 mNSSComponent(nssComponent), 457 mImportEnterpriseRoots(importEnterpriseRoots), 458 mGreBinDir(std::move(greBinDir)) { 459 MOZ_ASSERT(nssComponent); 460 } 461 462 ~LoadLoadableCertsTask() = default; 463 464 nsresult Dispatch(); 465 466 private: 467 NS_IMETHOD Run() override; 468 nsresult LoadLoadableRoots(); 469 RefPtr<nsNSSComponent> mNSSComponent; 470 bool mImportEnterpriseRoots; 471 nsAutoCString mGreBinDir; 472 }; 473 474 nsresult LoadLoadableCertsTask::Dispatch() { 475 // The stream transport service (note: not the socket transport service) can 476 // be used to perform background tasks or I/O that would otherwise block the 477 // main thread. 478 nsCOMPtr<nsIEventTarget> target( 479 do_GetService(NS_STREAMTRANSPORTSERVICE_CONTRACTID)); 480 if (!target) { 481 return NS_ERROR_FAILURE; 482 } 483 return target->Dispatch(this, NS_DISPATCH_NORMAL); 484 } 485 486 NS_IMETHODIMP 487 LoadLoadableCertsTask::Run() { 488 AutoGleanTimer<&glean::networking::loading_certs_task> timer; 489 490 nsresult loadLoadableRootsResult = LoadLoadableRoots(); 491 if (NS_WARN_IF(NS_FAILED(loadLoadableRootsResult))) { 492 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("LoadLoadableRoots failed")); 493 // We don't return loadLoadableRootsResult here because then 494 // BlockUntilLoadableCertsLoaded will just wait forever. Instead we'll save 495 // its value (below) so we can inform code that relies on the roots module 496 // being present that loading it failed. 497 } 498 499 // Loading EV information will only succeed if we've successfully loaded the 500 // loadable roots module. 501 if (NS_SUCCEEDED(loadLoadableRootsResult)) { 502 if (NS_FAILED(LoadExtendedValidationInfo())) { 503 // This isn't a show-stopper in the same way that failing to load the 504 // roots module is. 505 MOZ_LOG(gPIPNSSLog, LogLevel::Error, ("failed to load EV info")); 506 } 507 } 508 509 if (mImportEnterpriseRoots) { 510 mNSSComponent->ImportEnterpriseRoots(); 511 mNSSComponent->UpdateCertVerifierWithEnterpriseRoots(); 512 } 513 514 if (StaticPrefs::security_osclientcerts_autoload()) { 515 bool success = LoadOSClientCertsModule(); 516 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 517 ("loading OS client certs module %s", 518 success ? "succeeded" : "failed")); 519 } 520 521 { 522 MonitorAutoLock rootsLoadedLock(mNSSComponent->mLoadableCertsLoadedMonitor); 523 mNSSComponent->mLoadableCertsLoaded = true; 524 // Cache the result of LoadLoadableRoots so BlockUntilLoadableCertsLoaded 525 // can return it to all callers later (we use that particular result because 526 // if that operation fails, it's unlikely that any TLS connection will 527 // succeed whereas the browser may still be able to operate if the other 528 // tasks fail). 529 mNSSComponent->mLoadableCertsLoadedResult = loadLoadableRootsResult; 530 mNSSComponent->mLoadableCertsLoadedMonitor.NotifyAll(); 531 } 532 return NS_OK; 533 } 534 535 class BackgroundLoadOSClientCertsModuleTask final : public CryptoTask { 536 public: 537 explicit BackgroundLoadOSClientCertsModuleTask() {} 538 539 private: 540 virtual nsresult CalculateResult() override { 541 bool success = LoadOSClientCertsModule(); 542 return success ? NS_OK : NS_ERROR_FAILURE; 543 } 544 545 virtual void CallCallback(nsresult rv) override { 546 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 547 ("loading OS client certs module %s", 548 NS_SUCCEEDED(rv) ? "succeeded" : "failed")); 549 nsCOMPtr<nsIObserverService> observerService = 550 mozilla::services::GetObserverService(); 551 if (observerService) { 552 observerService->NotifyObservers( 553 nullptr, "psm:load-os-client-certs-module-task-ran", nullptr); 554 } 555 } 556 }; 557 558 void AsyncLoadOrUnloadOSClientCertsModule(bool load) { 559 if (load) { 560 RefPtr<BackgroundLoadOSClientCertsModuleTask> task = 561 new BackgroundLoadOSClientCertsModuleTask(); 562 (void)task->Dispatch(); 563 } else { 564 UniqueSECMODModule osClientCertsModule( 565 SECMOD_FindModule(kOSClientCertsModuleName.get())); 566 if (osClientCertsModule) { 567 SECMOD_UnloadUserModule(osClientCertsModule.get()); 568 } 569 } 570 } 571 572 nsresult nsNSSComponent::BlockUntilLoadableCertsLoaded() { 573 MonitorAutoLock rootsLoadedLock(mLoadableCertsLoadedMonitor); 574 while (!mLoadableCertsLoaded) { 575 rootsLoadedLock.Wait(); 576 } 577 MOZ_ASSERT(mLoadableCertsLoaded); 578 579 return mLoadableCertsLoadedResult; 580 } 581 582 #ifndef MOZ_NO_SMART_CARDS 583 static StaticMutex sCheckForSmartCardChangesMutex MOZ_UNANNOTATED; 584 MOZ_RUNINIT static TimeStamp sLastCheckedForSmartCardChanges = TimeStamp::Now(); 585 #endif 586 587 nsresult nsNSSComponent::CheckForSmartCardChanges() { 588 #ifndef MOZ_NO_SMART_CARDS 589 { 590 StaticMutexAutoLock lock(sCheckForSmartCardChangesMutex); 591 // Do this at most once every 3 seconds. 592 TimeStamp now = TimeStamp::Now(); 593 if (now - sLastCheckedForSmartCardChanges < 594 TimeDuration::FromSeconds(3.0)) { 595 return NS_OK; 596 } 597 sLastCheckedForSmartCardChanges = now; 598 } 599 600 // SECMOD_UpdateSlotList attempts to acquire the list lock as well, so we 601 // have to do this in three steps. 602 Vector<UniqueSECMODModule> modulesWithRemovableSlots; 603 { 604 AutoSECMODListReadLock secmodLock; 605 SECMODModuleList* list = SECMOD_GetDefaultModuleList(); 606 while (list) { 607 if (SECMOD_LockedModuleHasRemovableSlots(list->module)) { 608 UniqueSECMODModule module(SECMOD_ReferenceModule(list->module)); 609 if (!modulesWithRemovableSlots.append(std::move(module))) { 610 return NS_ERROR_OUT_OF_MEMORY; 611 } 612 } 613 list = list->next; 614 } 615 } 616 for (auto& module : modulesWithRemovableSlots) { 617 // Best-effort. 618 (void)SECMOD_UpdateSlotList(module.get()); 619 } 620 AutoSECMODListReadLock secmodLock; 621 for (auto& module : modulesWithRemovableSlots) { 622 for (int i = 0; i < module->slotCount; i++) { 623 // We actually don't care about the return value here - we just need to 624 // call this to get NSS to update its view of this slot. 625 (void)PK11_IsPresent(module->slots[i]); 626 } 627 } 628 #endif 629 630 return NS_OK; 631 } 632 633 #ifdef MOZ_SYSTEM_NSS 634 // Returns by reference the path to the directory containing the file that has 635 // been loaded as MOZ_DLL_PREFIX nss3 MOZ_DLL_SUFFIX. 636 // |result| is encoded in UTF-8. 637 static nsresult GetNSS3Directory(nsCString& result) { 638 MOZ_ASSERT(NS_IsMainThread()); 639 640 UniquePRString nss3Path( 641 PR_GetLibraryFilePathname(MOZ_DLL_PREFIX "nss3" MOZ_DLL_SUFFIX, 642 reinterpret_cast<PRFuncPtr>(NSS_Initialize))); 643 if (!nss3Path) { 644 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nss not loaded?")); 645 return NS_ERROR_FAILURE; 646 } 647 nsCOMPtr<nsIFile> nss3File; 648 nsresult rv = NS_NewNativeLocalFile(nsDependentCString(nss3Path.get()), 649 getter_AddRefs(nss3File)); 650 if (NS_FAILED(rv)) { 651 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 652 ("couldn't initialize file with path '%s'", nss3Path.get())); 653 return rv; 654 } 655 nsCOMPtr<nsIFile> nss3Directory; 656 rv = nss3File->GetParent(getter_AddRefs(nss3Directory)); 657 if (NS_FAILED(rv)) { 658 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("couldn't get parent directory?")); 659 return rv; 660 } 661 return FileToCString(nss3Directory, result); 662 } 663 #endif // MOZ_SYSTEM_NSS 664 665 // Returns by reference the path to the desired directory, based on the current 666 // settings in the directory service. 667 // |result| is encoded in UTF-8. 668 static nsresult GetDirectoryPath(const char* directoryKey, nsCString& result) { 669 MOZ_ASSERT(NS_IsMainThread()); 670 671 nsCOMPtr<nsIProperties> directoryService( 672 do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID)); 673 if (!directoryService) { 674 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not get directory service")); 675 return NS_ERROR_FAILURE; 676 } 677 nsCOMPtr<nsIFile> directory; 678 nsresult rv = directoryService->Get(directoryKey, NS_GET_IID(nsIFile), 679 getter_AddRefs(directory)); 680 if (NS_FAILED(rv)) { 681 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 682 ("could not get '%s' from directory service", directoryKey)); 683 return rv; 684 } 685 return FileToCString(directory, result); 686 } 687 688 nsresult LoadLoadableCertsTask::LoadLoadableRoots() { 689 // We first start checking if the MOZ_SYSTEM_NSS is used 690 // If it's not - we check if there is nssckbi library in bin directory 691 // If not found again - we finally load the library from XUL 692 #ifdef MOZ_SYSTEM_NSS 693 694 // First try checking the OS' default library search path. 695 nsAutoCString emptyString; 696 if (mozilla::psm::LoadLoadableRoots(emptyString)) { 697 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 698 ("loaded CKBI from from OS default library path")); 699 return NS_OK; 700 } 701 702 // Trying the library provided by NSS 703 nsAutoCString nss3Dir; 704 nsresult rv = GetNSS3Directory(nss3Dir); 705 706 if (NS_SUCCEEDED(rv)) { 707 if (mozilla::psm::LoadLoadableRoots(nss3Dir)) { 708 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 709 ("loaded CKBI from %s", nss3Dir.get())); 710 return NS_OK; 711 } 712 } else { 713 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 714 ("could not determine where nss was loaded from")); 715 } 716 717 #endif // MOZ_SYSTEM_NSS 718 719 if (mozilla::psm::LoadLoadableRoots(mGreBinDir)) { 720 mozilla::glean::pkcs11::external_trust_anchor_module_loaded.Set(true); 721 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 722 ("loaded external CKBI from gre directory")); 723 return NS_OK; 724 } 725 726 mozilla::glean::pkcs11::external_trust_anchor_module_loaded.Set(false); 727 728 if (LoadLoadableRootsFromXul()) { 729 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("loaded CKBI from xul")); 730 return NS_OK; 731 } 732 733 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("could not load loadable roots")); 734 return NS_ERROR_FAILURE; 735 } 736 737 // Table of pref names and SSL cipher ID 738 typedef struct { 739 const char* pref; 740 int32_t id; 741 bool (*prefGetter)(); 742 } CipherPref; 743 744 // Update the switch statement in AccumulateCipherSuite in nsNSSCallbacks.cpp 745 // when you add/remove cipher suites here. 746 static const CipherPref sCipherPrefs[] = { 747 {"security.ssl3.ecdhe_rsa_aes_128_gcm_sha256", 748 TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, 749 StaticPrefs::security_ssl3_ecdhe_rsa_aes_128_gcm_sha256}, 750 {"security.ssl3.ecdhe_ecdsa_aes_128_gcm_sha256", 751 TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, 752 StaticPrefs::security_ssl3_ecdhe_ecdsa_aes_128_gcm_sha256}, 753 {"security.ssl3.ecdhe_ecdsa_chacha20_poly1305_sha256", 754 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, 755 StaticPrefs::security_ssl3_ecdhe_ecdsa_chacha20_poly1305_sha256}, 756 {"security.ssl3.ecdhe_rsa_chacha20_poly1305_sha256", 757 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256, 758 StaticPrefs::security_ssl3_ecdhe_rsa_chacha20_poly1305_sha256}, 759 {"security.ssl3.ecdhe_ecdsa_aes_256_gcm_sha384", 760 TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, 761 StaticPrefs::security_ssl3_ecdhe_ecdsa_aes_256_gcm_sha384}, 762 {"security.ssl3.ecdhe_rsa_aes_256_gcm_sha384", 763 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, 764 StaticPrefs::security_ssl3_ecdhe_rsa_aes_256_gcm_sha384}, 765 {"security.ssl3.ecdhe_rsa_aes_128_sha", TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA, 766 StaticPrefs::security_ssl3_ecdhe_rsa_aes_128_sha}, 767 {"security.ssl3.ecdhe_ecdsa_aes_128_sha", 768 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA, 769 StaticPrefs::security_ssl3_ecdhe_ecdsa_aes_128_sha}, 770 {"security.ssl3.ecdhe_rsa_aes_256_sha", TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA, 771 StaticPrefs::security_ssl3_ecdhe_rsa_aes_256_sha}, 772 {"security.ssl3.ecdhe_ecdsa_aes_256_sha", 773 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA, 774 StaticPrefs::security_ssl3_ecdhe_ecdsa_aes_256_sha}, 775 {"security.ssl3.dhe_rsa_aes_128_sha", TLS_DHE_RSA_WITH_AES_128_CBC_SHA, 776 StaticPrefs::security_ssl3_dhe_rsa_aes_128_sha}, 777 {"security.ssl3.dhe_rsa_aes_256_sha", TLS_DHE_RSA_WITH_AES_256_CBC_SHA, 778 StaticPrefs::security_ssl3_dhe_rsa_aes_256_sha}, 779 {"security.tls13.aes_128_gcm_sha256", TLS_AES_128_GCM_SHA256, 780 StaticPrefs::security_tls13_aes_128_gcm_sha256}, 781 {"security.tls13.chacha20_poly1305_sha256", TLS_CHACHA20_POLY1305_SHA256, 782 StaticPrefs::security_tls13_chacha20_poly1305_sha256}, 783 {"security.tls13.aes_256_gcm_sha384", TLS_AES_256_GCM_SHA384, 784 StaticPrefs::security_tls13_aes_256_gcm_sha384}, 785 {"security.ssl3.rsa_aes_128_gcm_sha256", TLS_RSA_WITH_AES_128_GCM_SHA256, 786 StaticPrefs::security_ssl3_rsa_aes_128_gcm_sha256}, 787 {"security.ssl3.rsa_aes_256_gcm_sha384", TLS_RSA_WITH_AES_256_GCM_SHA384, 788 StaticPrefs::security_ssl3_rsa_aes_256_gcm_sha384}, 789 {"security.ssl3.rsa_aes_128_sha", TLS_RSA_WITH_AES_128_CBC_SHA, 790 StaticPrefs::security_ssl3_rsa_aes_128_sha}, 791 {"security.ssl3.rsa_aes_256_sha", TLS_RSA_WITH_AES_256_CBC_SHA, 792 StaticPrefs::security_ssl3_rsa_aes_256_sha}, 793 }; 794 795 // These ciphersuites can only be enabled if deprecated versions of TLS are 796 // also enabled (via the preference "security.tls.version.enable-deprecated"). 797 static const CipherPref sDeprecatedTLS1CipherPrefs[] = { 798 {"security.ssl3.deprecated.rsa_des_ede3_sha", TLS_RSA_WITH_3DES_EDE_CBC_SHA, 799 StaticPrefs::security_ssl3_deprecated_rsa_des_ede3_sha}, 800 }; 801 802 // This function will convert from pref values like 1, 2, ... 803 // to the internal values of SSL_LIBRARY_VERSION_TLS_1_0, 804 // SSL_LIBRARY_VERSION_TLS_1_1, ... 805 /*static*/ 806 void nsNSSComponent::FillTLSVersionRange(SSLVersionRange& rangeOut, 807 uint32_t minFromPrefs, 808 uint32_t maxFromPrefs, 809 SSLVersionRange defaults) { 810 rangeOut = defaults; 811 // determine what versions are supported 812 SSLVersionRange supported; 813 if (SSL_VersionRangeGetSupported(ssl_variant_stream, &supported) != 814 SECSuccess) { 815 return; 816 } 817 818 // Clip the defaults by what NSS actually supports to enable 819 // working with a system NSS with different ranges. 820 rangeOut.min = std::max(rangeOut.min, supported.min); 821 rangeOut.max = std::min(rangeOut.max, supported.max); 822 823 // convert min/maxFromPrefs to the internal representation 824 minFromPrefs += SSL_LIBRARY_VERSION_3_0; 825 maxFromPrefs += SSL_LIBRARY_VERSION_3_0; 826 // if min/maxFromPrefs are invalid, use defaults 827 if (minFromPrefs > maxFromPrefs || minFromPrefs < supported.min || 828 maxFromPrefs > supported.max || 829 minFromPrefs < SSL_LIBRARY_VERSION_TLS_1_0) { 830 return; 831 } 832 833 // fill out rangeOut 834 rangeOut.min = (uint16_t)minFromPrefs; 835 rangeOut.max = (uint16_t)maxFromPrefs; 836 } 837 838 static void ConfigureTLSSessionIdentifiers() { 839 bool disableSessionIdentifiers = 840 StaticPrefs::security_ssl_disable_session_identifiers(); 841 SSL_OptionSetDefault(SSL_ENABLE_SESSION_TICKETS, !disableSessionIdentifiers); 842 SSL_OptionSetDefault(SSL_NO_CACHE, disableSessionIdentifiers); 843 } 844 845 nsresult CommonInit() { 846 SSL_OptionSetDefault(SSL_ENABLE_SSL2, false); 847 SSL_OptionSetDefault(SSL_V2_COMPATIBLE_HELLO, false); 848 849 nsresult rv = nsNSSComponent::SetEnabledTLSVersions(); 850 if (NS_FAILED(rv)) { 851 return rv; 852 } 853 854 ConfigureTLSSessionIdentifiers(); 855 856 SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, 857 StaticPrefs::security_ssl_require_safe_negotiation()); 858 SSL_OptionSetDefault(SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_REQUIRES_XTN); 859 SSL_OptionSetDefault(SSL_ENABLE_EXTENDED_MASTER_SECRET, true); 860 SSL_OptionSetDefault(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, 861 StaticPrefs::security_tls_hello_downgrade_check()); 862 SSL_OptionSetDefault(SSL_ENABLE_FALSE_START, 863 StaticPrefs::security_ssl_enable_false_start()); 864 // SSL_ENABLE_ALPN also requires calling SSL_SetNextProtoNego in order for 865 // the extensions to be negotiated. 866 // WebRTC does not do that so it will not use ALPN even when this preference 867 // is true. 868 SSL_OptionSetDefault(SSL_ENABLE_ALPN, 869 StaticPrefs::security_ssl_enable_alpn()); 870 SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA, 871 StaticPrefs::security_tls_enable_0rtt_data()); 872 SSL_OptionSetDefault(SSL_ENABLE_POST_HANDSHAKE_AUTH, 873 StaticPrefs::security_tls_enable_post_handshake_auth()); 874 SSL_OptionSetDefault( 875 SSL_ENABLE_DELEGATED_CREDENTIALS, 876 StaticPrefs::security_tls_enable_delegated_credentials()); 877 SSL_OptionSetDefault(SSL_DB_LOAD_CERTIFICATE_CHAIN, false); 878 879 rv = InitializeCipherSuite(); 880 if (NS_FAILED(rv)) { 881 MOZ_LOG(gPIPNSSLog, LogLevel::Error, 882 ("Unable to initialize cipher suite settings\n")); 883 return rv; 884 } 885 886 DisableMD5(); 887 888 mozilla::pkix::RegisterErrorTable(); 889 nsSSLIOLayerHelpers::GlobalInit(); 890 891 return NS_OK; 892 } 893 894 void PrepareForShutdownInSocketProcess() { 895 MOZ_ASSERT(XRE_IsSocketProcess()); 896 nsSSLIOLayerHelpers::GlobalCleanup(); 897 } 898 899 bool HandleTLSPrefChange(const nsCString& prefName) { 900 // Note that the code in this function should be kept in sync with 901 // gCallbackSecurityPrefs in nsIOService.cpp. 902 bool prefFound = true; 903 if (prefName.EqualsLiteral("security.tls.version.min") || 904 prefName.EqualsLiteral("security.tls.version.max") || 905 prefName.EqualsLiteral("security.tls.version.enable-deprecated")) { 906 (void)nsNSSComponent::SetEnabledTLSVersions(); 907 } else if (prefName.EqualsLiteral("security.tls.hello_downgrade_check")) { 908 SSL_OptionSetDefault(SSL_ENABLE_HELLO_DOWNGRADE_CHECK, 909 StaticPrefs::security_tls_hello_downgrade_check()); 910 } else if (prefName.EqualsLiteral("security.ssl.require_safe_negotiation")) { 911 SSL_OptionSetDefault(SSL_REQUIRE_SAFE_NEGOTIATION, 912 StaticPrefs::security_ssl_require_safe_negotiation()); 913 } else if (prefName.EqualsLiteral("security.ssl.enable_false_start")) { 914 SSL_OptionSetDefault(SSL_ENABLE_FALSE_START, 915 StaticPrefs::security_ssl_enable_false_start()); 916 } else if (prefName.EqualsLiteral("security.ssl.enable_alpn")) { 917 SSL_OptionSetDefault(SSL_ENABLE_ALPN, 918 StaticPrefs::security_ssl_enable_alpn()); 919 } else if (prefName.EqualsLiteral("security.tls.enable_0rtt_data")) { 920 SSL_OptionSetDefault(SSL_ENABLE_0RTT_DATA, 921 StaticPrefs::security_tls_enable_0rtt_data()); 922 } else if (prefName.EqualsLiteral( 923 "security.tls.enable_post_handshake_auth")) { 924 SSL_OptionSetDefault( 925 SSL_ENABLE_POST_HANDSHAKE_AUTH, 926 StaticPrefs::security_tls_enable_post_handshake_auth()); 927 } else if (prefName.EqualsLiteral( 928 "security.tls.enable_delegated_credentials")) { 929 SSL_OptionSetDefault( 930 SSL_ENABLE_DELEGATED_CREDENTIALS, 931 StaticPrefs::security_tls_enable_delegated_credentials()); 932 } else if (prefName.EqualsLiteral( 933 "security.ssl.disable_session_identifiers")) { 934 ConfigureTLSSessionIdentifiers(); 935 } else { 936 prefFound = false; 937 } 938 return prefFound; 939 } 940 941 namespace { 942 943 class CipherSuiteChangeObserver : public nsIObserver { 944 public: 945 NS_DECL_ISUPPORTS 946 NS_DECL_NSIOBSERVER 947 948 static nsresult StartObserve(); 949 950 protected: 951 virtual ~CipherSuiteChangeObserver() = default; 952 953 private: 954 static StaticRefPtr<CipherSuiteChangeObserver> sObserver; 955 CipherSuiteChangeObserver() = default; 956 }; 957 958 NS_IMPL_ISUPPORTS(CipherSuiteChangeObserver, nsIObserver) 959 960 // static 961 StaticRefPtr<CipherSuiteChangeObserver> CipherSuiteChangeObserver::sObserver; 962 963 // static 964 nsresult CipherSuiteChangeObserver::StartObserve() { 965 MOZ_ASSERT(NS_IsMainThread(), 966 "CipherSuiteChangeObserver::StartObserve() can only be accessed " 967 "on the main thread"); 968 if (!sObserver) { 969 RefPtr<CipherSuiteChangeObserver> observer = 970 new CipherSuiteChangeObserver(); 971 nsresult rv = Preferences::AddStrongObserver(observer.get(), "security."); 972 if (NS_FAILED(rv)) { 973 sObserver = nullptr; 974 return rv; 975 } 976 977 nsCOMPtr<nsIObserverService> observerService = 978 mozilla::services::GetObserverService(); 979 observerService->AddObserver(observer, NS_XPCOM_SHUTDOWN_OBSERVER_ID, 980 false); 981 982 sObserver = observer; 983 } 984 return NS_OK; 985 } 986 987 // Enables or disabled ciphersuites from deprecated versions of TLS as 988 // appropriate. If security.tls.version.enable-deprecated is true, these 989 // ciphersuites may be enabled, if the corresponding preference is true. 990 // Otherwise, these ciphersuites will be disabled. 991 void SetDeprecatedTLS1CipherPrefs() { 992 if (StaticPrefs::security_tls_version_enable_deprecated()) { 993 for (const auto& deprecatedTLS1CipherPref : sDeprecatedTLS1CipherPrefs) { 994 SSL_CipherPrefSetDefault(deprecatedTLS1CipherPref.id, 995 deprecatedTLS1CipherPref.prefGetter()); 996 } 997 } else { 998 for (const auto& deprecatedTLS1CipherPref : sDeprecatedTLS1CipherPrefs) { 999 SSL_CipherPrefSetDefault(deprecatedTLS1CipherPref.id, false); 1000 } 1001 } 1002 } 1003 1004 // static 1005 void SetKyberPolicy() { 1006 if (StaticPrefs::security_tls_enable_kyber()) { 1007 NSS_SetAlgorithmPolicy(SEC_OID_MLKEM768X25519, NSS_USE_ALG_IN_SSL_KX, 0); 1008 } else { 1009 NSS_SetAlgorithmPolicy(SEC_OID_MLKEM768X25519, 0, NSS_USE_ALG_IN_SSL_KX); 1010 } 1011 } 1012 1013 nsresult CipherSuiteChangeObserver::Observe(nsISupports* /*aSubject*/, 1014 const char* aTopic, 1015 const char16_t* someData) { 1016 MOZ_ASSERT(NS_IsMainThread(), 1017 "CipherSuiteChangeObserver::Observe can only be accessed on main " 1018 "thread"); 1019 if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { 1020 NS_ConvertUTF16toUTF8 prefName(someData); 1021 // Look through the cipher table and set according to pref setting 1022 for (const auto& cipherPref : sCipherPrefs) { 1023 if (prefName.Equals(cipherPref.pref)) { 1024 SSL_CipherPrefSetDefault(cipherPref.id, cipherPref.prefGetter()); 1025 break; 1026 } 1027 } 1028 SetDeprecatedTLS1CipherPrefs(); 1029 SetKyberPolicy(); 1030 nsNSSComponent::DoClearSSLExternalAndInternalSessionCache(); 1031 } else if (nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { 1032 Preferences::RemoveObserver(this, "security."); 1033 MOZ_ASSERT(sObserver.get() == this); 1034 sObserver = nullptr; 1035 nsCOMPtr<nsIObserverService> observerService = 1036 mozilla::services::GetObserverService(); 1037 observerService->RemoveObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID); 1038 } 1039 return NS_OK; 1040 } 1041 1042 } // namespace 1043 1044 void nsNSSComponent::setValidationOptions( 1045 const mozilla::MutexAutoLock& proofOfLock) { 1046 // We access prefs so this must be done on the main thread. 1047 mMutex.AssertCurrentThreadOwns(); 1048 MOZ_ASSERT(NS_IsMainThread()); 1049 if (NS_WARN_IF(!NS_IsMainThread())) { 1050 return; 1051 } 1052 1053 CertVerifier::CertificateTransparencyMode ctMode = 1054 GetCertificateTransparencyMode(); 1055 nsCString skipCTForHosts; 1056 Preferences::GetCString( 1057 "security.pki.certificate_transparency.disable_for_hosts", 1058 skipCTForHosts); 1059 nsAutoCString skipCTForSPKIHashesBase64; 1060 Preferences::GetCString( 1061 "security.pki.certificate_transparency.disable_for_spki_hashes", 1062 skipCTForSPKIHashesBase64); 1063 nsTArray<CopyableTArray<uint8_t>> skipCTForSPKIHashes; 1064 for (const auto& spkiHashBase64 : skipCTForSPKIHashesBase64.Split(',')) { 1065 nsAutoCString spkiHashString; 1066 if (NS_SUCCEEDED(Base64Decode(spkiHashBase64, spkiHashString))) { 1067 nsTArray<uint8_t> spkiHash(spkiHashString.Data(), 1068 spkiHashString.Length()); 1069 skipCTForSPKIHashes.AppendElement(std::move(spkiHash)); 1070 } 1071 } 1072 CertVerifier::CertificateTransparencyConfig ctConfig( 1073 ctMode, std::move(skipCTForHosts), std::move(skipCTForSPKIHashes)); 1074 1075 CRLiteMode defaultCRLiteMode = CRLiteMode::Enforce; 1076 CRLiteMode crliteMode = 1077 static_cast<CRLiteMode>(StaticPrefs::security_pki_crlite_mode()); 1078 switch (crliteMode) { 1079 case CRLiteMode::Disabled: 1080 case CRLiteMode::TelemetryOnly: 1081 case CRLiteMode::Enforce: 1082 break; 1083 default: 1084 crliteMode = defaultCRLiteMode; 1085 break; 1086 } 1087 1088 CertVerifier::OcspDownloadConfig odc; 1089 CertVerifier::OcspStrictConfig osc; 1090 uint32_t certShortLifetimeInDays; 1091 TimeDuration softTimeout; 1092 TimeDuration hardTimeout; 1093 1094 GetRevocationBehaviorFromPrefs(&odc, &osc, &certShortLifetimeInDays, 1095 softTimeout, hardTimeout); 1096 1097 mDefaultCertVerifier = new SharedCertVerifier( 1098 odc, osc, softTimeout, hardTimeout, certShortLifetimeInDays, 1099 std::move(ctConfig), crliteMode, mEnterpriseCerts); 1100 } 1101 1102 void nsNSSComponent::UpdateCertVerifierWithEnterpriseRoots() { 1103 MutexAutoLock lock(mMutex); 1104 if (!mDefaultCertVerifier) { 1105 return; 1106 } 1107 1108 RefPtr<SharedCertVerifier> oldCertVerifier = mDefaultCertVerifier; 1109 nsCString skipCTForHosts(oldCertVerifier->mCTConfig.mSkipForHosts); 1110 CertVerifier::CertificateTransparencyConfig ctConfig( 1111 oldCertVerifier->mCTConfig.mMode, std::move(skipCTForHosts), 1112 oldCertVerifier->mCTConfig.mSkipForSPKIHashes.Clone()); 1113 mDefaultCertVerifier = new SharedCertVerifier( 1114 oldCertVerifier->mOCSPDownloadConfig, 1115 oldCertVerifier->mOCSPStrict ? CertVerifier::ocspStrict 1116 : CertVerifier::ocspRelaxed, 1117 oldCertVerifier->mOCSPTimeoutSoft, oldCertVerifier->mOCSPTimeoutHard, 1118 oldCertVerifier->mCertShortLifetimeInDays, std::move(ctConfig), 1119 oldCertVerifier->mCRLiteMode, mEnterpriseCerts); 1120 } 1121 1122 // Enable the TLS versions given in the prefs, defaulting to TLS 1.0 (min) and 1123 // TLS 1.2 (max) when the prefs aren't set or set to invalid values. 1124 nsresult nsNSSComponent::SetEnabledTLSVersions() { 1125 // Keep these values in sync with all.js. 1126 // 1 means TLS 1.0, 2 means TLS 1.1, etc. 1127 static const uint32_t PSM_DEFAULT_MIN_TLS_VERSION = 3; 1128 static const uint32_t PSM_DEFAULT_MAX_TLS_VERSION = 4; 1129 static const uint32_t PSM_DEPRECATED_TLS_VERSION = 1; 1130 1131 uint32_t minFromPrefs = StaticPrefs::security_tls_version_min(); 1132 uint32_t maxFromPrefs = StaticPrefs::security_tls_version_max(); 1133 1134 // This override should be removed some time after 1135 // PSM_DEFAULT_MIN_TLS_VERSION is increased to 3. 1136 bool enableDeprecated = StaticPrefs::security_tls_version_enable_deprecated(); 1137 if (enableDeprecated) { 1138 minFromPrefs = std::min(minFromPrefs, PSM_DEPRECATED_TLS_VERSION); 1139 } 1140 1141 SSLVersionRange defaults = { 1142 SSL_LIBRARY_VERSION_3_0 + PSM_DEFAULT_MIN_TLS_VERSION, 1143 SSL_LIBRARY_VERSION_3_0 + PSM_DEFAULT_MAX_TLS_VERSION}; 1144 SSLVersionRange filledInRange; 1145 FillTLSVersionRange(filledInRange, minFromPrefs, maxFromPrefs, defaults); 1146 1147 SECStatus srv = 1148 SSL_VersionRangeSetDefault(ssl_variant_stream, &filledInRange); 1149 if (srv != SECSuccess) { 1150 return NS_ERROR_FAILURE; 1151 } 1152 1153 return NS_OK; 1154 } 1155 1156 #if defined(XP_WIN) || (defined(XP_LINUX) && !defined(ANDROID)) 1157 // If the profile directory is on a networked drive, we want to set the 1158 // environment variable NSS_SDB_USE_CACHE to yes (as long as it hasn't been set 1159 // before). 1160 static void SetNSSDatabaseCacheModeAsAppropriate() { 1161 MOZ_ASSERT(NS_IsMainThread()); 1162 1163 nsCOMPtr<nsIFile> profileFile; 1164 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, 1165 getter_AddRefs(profileFile)); 1166 if (NS_FAILED(rv)) { 1167 // We're probably running without a profile directory, so this is 1168 // irrelevant. 1169 return; 1170 } 1171 1172 static const char sNSS_SDB_USE_CACHE[] = "NSS_SDB_USE_CACHE"; 1173 static const char sNSS_SDB_USE_CACHE_WITH_VALUE[] = "NSS_SDB_USE_CACHE=yes"; 1174 auto profilePath = profileFile->NativePath(); 1175 1176 # if defined(XP_LINUX) && !defined(ANDROID) 1177 struct statfs statfs_s; 1178 if (statfs(profilePath.get(), &statfs_s) == 0 && 1179 statfs_s.f_type == NFS_SUPER_MAGIC && !PR_GetEnv(sNSS_SDB_USE_CACHE)) { 1180 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1181 ("profile is remote (and NSS_SDB_USE_CACHE wasn't set): " 1182 "setting NSS_SDB_USE_CACHE")); 1183 PR_SetEnv(sNSS_SDB_USE_CACHE_WITH_VALUE); 1184 } else { 1185 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("not setting NSS_SDB_USE_CACHE")); 1186 } 1187 # endif // defined(XP_LINUX) && !defined(ANDROID) 1188 1189 # ifdef XP_WIN 1190 wchar_t volPath[MAX_PATH]; 1191 if (::GetVolumePathNameW(profilePath.get(), volPath, MAX_PATH) && 1192 ::GetDriveTypeW(volPath) == DRIVE_REMOTE && 1193 !PR_GetEnv(sNSS_SDB_USE_CACHE)) { 1194 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1195 ("profile is remote (and NSS_SDB_USE_CACHE wasn't set): " 1196 "setting NSS_SDB_USE_CACHE")); 1197 PR_SetEnv(sNSS_SDB_USE_CACHE_WITH_VALUE); 1198 } else { 1199 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("not setting NSS_SDB_USE_CACHE")); 1200 } 1201 # endif // XP_WIN 1202 } 1203 #endif // defined(XP_WIN) || (defined(XP_LINUX) && !defined(ANDROID)) 1204 1205 static nsresult GetNSSProfilePath(nsAutoCString& aProfilePath) { 1206 aProfilePath.Truncate(); 1207 nsCOMPtr<nsIFile> profileFile; 1208 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, 1209 getter_AddRefs(profileFile)); 1210 if (NS_FAILED(rv)) { 1211 NS_WARNING( 1212 "NSS will be initialized without a profile directory. " 1213 "Some things may not work as expected."); 1214 return NS_OK; 1215 } 1216 1217 #if defined(XP_WIN) 1218 // SQLite always takes UTF-8 file paths regardless of the current system 1219 // code page. 1220 nsAutoString u16ProfilePath; 1221 rv = profileFile->GetPath(u16ProfilePath); 1222 CopyUTF16toUTF8(u16ProfilePath, aProfilePath); 1223 #else 1224 rv = profileFile->GetNativePath(aProfilePath); 1225 #endif 1226 if (NS_FAILED(rv)) { 1227 MOZ_LOG(gPIPNSSLog, LogLevel::Error, 1228 ("Could not get native path for profile directory.\n")); 1229 return rv; 1230 } 1231 1232 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1233 ("NSS profile at '%s'\n", aProfilePath.get())); 1234 return NS_OK; 1235 } 1236 1237 #ifndef ANDROID 1238 // Given a profile path, attempt to rename the PKCS#11 module DB to 1239 // "pkcs11.txt.fips". In the case of a catastrophic failure (e.g. out of 1240 // memory), returns a failing nsresult. If execution could conceivably proceed, 1241 // returns NS_OK even if renaming the file didn't work. This simplifies the 1242 // logic of the calling code. 1243 // |profilePath| is encoded in UTF-8. 1244 static nsresult AttemptToRenamePKCS11ModuleDB(const nsACString& profilePath) { 1245 nsCOMPtr<nsIFile> profileDir; 1246 // |profilePath| is encoded in UTF-8 because SQLite always takes UTF-8 file 1247 // paths regardless of the current system code page. 1248 MOZ_TRY(NS_NewUTF8LocalFile(profilePath, getter_AddRefs(profileDir))); 1249 const char* moduleDBFilename = "pkcs11.txt"; 1250 nsAutoCString destModuleDBFilename(moduleDBFilename); 1251 destModuleDBFilename.Append(".fips"); 1252 nsCOMPtr<nsIFile> dbFile; 1253 nsresult rv = profileDir->Clone(getter_AddRefs(dbFile)); 1254 if (NS_FAILED(rv) || !dbFile) { 1255 return NS_ERROR_FAILURE; 1256 } 1257 rv = dbFile->AppendNative(nsAutoCString(moduleDBFilename)); 1258 if (NS_FAILED(rv)) { 1259 return rv; 1260 } 1261 // If the PKCS#11 module DB doesn't exist, renaming it won't help. 1262 bool exists; 1263 rv = dbFile->Exists(&exists); 1264 if (NS_FAILED(rv)) { 1265 return rv; 1266 } 1267 // This is strange, but not a catastrophic failure. 1268 if (!exists) { 1269 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1270 ("%s doesn't exist?", moduleDBFilename)); 1271 return NS_OK; 1272 } 1273 nsCOMPtr<nsIFile> destDBFile; 1274 rv = profileDir->Clone(getter_AddRefs(destDBFile)); 1275 if (NS_FAILED(rv) || !destDBFile) { 1276 return NS_ERROR_FAILURE; 1277 } 1278 rv = destDBFile->AppendNative(destModuleDBFilename); 1279 if (NS_FAILED(rv)) { 1280 return rv; 1281 } 1282 // If the destination exists, presumably we've already tried this. Doing it 1283 // again won't help. 1284 rv = destDBFile->Exists(&exists); 1285 if (NS_FAILED(rv)) { 1286 return rv; 1287 } 1288 // Unfortunate, but not a catastrophic failure. 1289 if (exists) { 1290 MOZ_LOG( 1291 gPIPNSSLog, LogLevel::Debug, 1292 ("%s already exists - not overwriting", destModuleDBFilename.get())); 1293 return NS_OK; 1294 } 1295 // Now do the actual move. 1296 // This may fail on, e.g., a read-only file system. This would be unfortunate, 1297 // but again it isn't catastropic and we would want to fall back to 1298 // initializing NSS in no-DB mode. 1299 (void)dbFile->MoveToNative(profileDir, destModuleDBFilename); 1300 return NS_OK; 1301 } 1302 #endif // ifndef ANDROID 1303 1304 // Given a profile directory, attempt to initialize NSS. If nocertdb is true, 1305 // (or if we don't have a profile directory) simply initialize NSS in no DB mode 1306 // and return. Otherwise, first attempt to initialize in read/write mode, and 1307 // then read-only mode if that fails. If both attempts fail, we may be failing 1308 // to initialize an NSS DB collection that has FIPS mode enabled. Attempt to 1309 // ascertain if this is the case, and if so, rename the offending PKCS#11 module 1310 // DB so we can (hopefully) initialize NSS in read-write mode. Again attempt 1311 // read-only mode if that fails. Finally, fall back to no DB mode. On Android 1312 // we can skip the FIPS workaround since it was never possible to enable FIPS 1313 // there anyway. 1314 // |profilePath| is encoded in UTF-8. 1315 static nsresult InitializeNSSWithFallbacks(const nsACString& profilePath, 1316 bool nocertdb, bool safeMode) { 1317 if (nocertdb || profilePath.IsEmpty()) { 1318 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1319 ("nocertdb mode or empty profile path -> NSS_NoDB_Init")); 1320 SECStatus srv = NSS_NoDB_Init(nullptr); 1321 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 1322 if (srv != SECSuccess) { 1323 MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %d", 1324 PR_GetError()); 1325 } 1326 #endif 1327 return srv == SECSuccess ? NS_OK : NS_ERROR_FAILURE; 1328 } 1329 1330 // Try read/write mode. If we're in safeMode, we won't load PKCS#11 modules. 1331 #ifndef ANDROID 1332 PRErrorCode savedPRErrorCode1; 1333 #endif // ifndef ANDROID 1334 PKCS11DBConfig safeModeDBConfig = 1335 safeMode ? PKCS11DBConfig::DoNotLoadModules : PKCS11DBConfig::LoadModules; 1336 SECStatus srv = ::mozilla::psm::InitializeNSS( 1337 profilePath, NSSDBConfig::ReadWrite, safeModeDBConfig); 1338 if (srv == SECSuccess) { 1339 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r/w mode")); 1340 return NS_OK; 1341 } 1342 #ifndef ANDROID 1343 savedPRErrorCode1 = PR_GetError(); 1344 PRErrorCode savedPRErrorCode2; 1345 #endif // ifndef ANDROID 1346 // That failed. Try read-only mode. 1347 srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadOnly, 1348 safeModeDBConfig); 1349 if (srv == SECSuccess) { 1350 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized NSS in r-o mode")); 1351 return NS_OK; 1352 } 1353 #ifndef ANDROID 1354 savedPRErrorCode2 = PR_GetError(); 1355 1356 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1357 ("failed to initialize NSS with codes %d %d", savedPRErrorCode1, 1358 savedPRErrorCode2)); 1359 #endif // ifndef ANDROID 1360 1361 #ifndef ANDROID 1362 // That failed as well. Maybe we're trying to load a PKCS#11 module DB that is 1363 // in FIPS mode, but we don't support FIPS? Test load NSS without PKCS#11 1364 // modules. If that succeeds, that's probably what's going on. 1365 if (!safeMode && (savedPRErrorCode1 == SEC_ERROR_LEGACY_DATABASE || 1366 savedPRErrorCode2 == SEC_ERROR_LEGACY_DATABASE || 1367 savedPRErrorCode1 == SEC_ERROR_PKCS11_DEVICE_ERROR || 1368 savedPRErrorCode2 == SEC_ERROR_PKCS11_DEVICE_ERROR)) { 1369 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("attempting no-module db init")); 1370 // It would make sense to initialize NSS in read-only mode here since this 1371 // is just a test to see if the PKCS#11 module DB being in FIPS mode is the 1372 // problem, but for some reason the combination of read-only and no-moddb 1373 // flags causes NSS initialization to fail, so unfortunately we have to use 1374 // read-write mode. 1375 srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadWrite, 1376 PKCS11DBConfig::DoNotLoadModules); 1377 if (srv == SECSuccess) { 1378 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("FIPS may be the problem")); 1379 // Unload NSS so we can attempt to fix this situation for the user. 1380 srv = NSS_Shutdown(); 1381 if (srv != SECSuccess) { 1382 # ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 1383 MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %d", 1384 PR_GetError()); 1385 # endif 1386 return NS_ERROR_FAILURE; 1387 } 1388 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("trying to rename module db")); 1389 // If this fails non-catastrophically, we'll attempt to initialize NSS 1390 // again in r/w then r-o mode (both of which will fail), and then we'll 1391 // fall back to NSS_NoDB_Init, which is the behavior we want. 1392 nsresult rv = AttemptToRenamePKCS11ModuleDB(profilePath); 1393 if (NS_FAILED(rv)) { 1394 # ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 1395 // An nsresult is a uint32_t, but at least one of our compilers doesn't 1396 // like this format string unless we include the cast. <shruggie emoji> 1397 MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %u", 1398 (uint32_t)rv); 1399 # endif 1400 return rv; 1401 } 1402 srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadWrite, 1403 PKCS11DBConfig::LoadModules); 1404 if (srv == SECSuccess) { 1405 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized in r/w mode")); 1406 return NS_OK; 1407 } 1408 srv = ::mozilla::psm::InitializeNSS(profilePath, NSSDBConfig::ReadOnly, 1409 PKCS11DBConfig::LoadModules); 1410 if (srv == SECSuccess) { 1411 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("initialized in r-o mode")); 1412 return NS_OK; 1413 } 1414 } 1415 } 1416 #endif 1417 1418 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("last-resort NSS_NoDB_Init")); 1419 srv = NSS_NoDB_Init(nullptr); 1420 #ifdef MOZ_DIAGNOSTIC_ASSERT_ENABLED 1421 if (srv != SECSuccess) { 1422 MOZ_CRASH_UNSAFE_PRINTF("InitializeNSSWithFallbacks failed: %d", 1423 PR_GetError()); 1424 } 1425 #endif 1426 return srv == SECSuccess ? NS_OK : NS_ERROR_FAILURE; 1427 } 1428 1429 #if defined(NIGHTLY_BUILD) && !defined(ANDROID) 1430 // dbType is either "cert9.db" or "key4.db" 1431 void UnmigrateOneCertDB(const nsCOMPtr<nsIFile>& profileDirectory, 1432 const nsACString& dbType) { 1433 nsCOMPtr<nsIFile> dbFile; 1434 nsresult rv = profileDirectory->Clone(getter_AddRefs(dbFile)); 1435 if (NS_FAILED(rv)) { 1436 return; 1437 } 1438 rv = dbFile->AppendNative(dbType); 1439 if (NS_FAILED(rv)) { 1440 return; 1441 } 1442 bool exists; 1443 rv = dbFile->Exists(&exists); 1444 if (NS_FAILED(rv)) { 1445 return; 1446 } 1447 // If the unprefixed DB already exists, don't overwrite it. 1448 if (exists) { 1449 return; 1450 } 1451 nsCOMPtr<nsIFile> prefixedDBFile; 1452 rv = profileDirectory->Clone(getter_AddRefs(prefixedDBFile)); 1453 if (NS_FAILED(rv)) { 1454 return; 1455 } 1456 nsAutoCString prefixedDBName("gecko-no-share-"); 1457 prefixedDBName.Append(dbType); 1458 rv = prefixedDBFile->AppendNative(prefixedDBName); 1459 if (NS_FAILED(rv)) { 1460 return; 1461 } 1462 (void)prefixedDBFile->MoveToNative(nullptr, dbType); 1463 } 1464 1465 void UnmigrateFromPrefixedCertDBs() { 1466 nsCOMPtr<nsIFile> profileDirectory; 1467 nsresult rv = NS_GetSpecialDirectory(NS_APP_USER_PROFILE_50_DIR, 1468 getter_AddRefs(profileDirectory)); 1469 if (NS_FAILED(rv)) { 1470 return; 1471 } 1472 UnmigrateOneCertDB(profileDirectory, "cert9.db"_ns); 1473 UnmigrateOneCertDB(profileDirectory, "key4.db"_ns); 1474 } 1475 #endif // defined(NIGHTLY_BUILD) && !defined(ANDROID) 1476 1477 nsresult nsNSSComponent::InitializeNSS() { 1478 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::InitializeNSS\n")); 1479 AUTO_PROFILER_LABEL("nsNSSComponent::InitializeNSS", OTHER); 1480 AUTO_PROFILER_MARKER("nsNSSComponent::InitializeNSS", OTHER); 1481 1482 static_assert( 1483 nsINSSErrorsService::NSS_SEC_ERROR_BASE == SEC_ERROR_BASE && 1484 nsINSSErrorsService::NSS_SEC_ERROR_LIMIT == SEC_ERROR_LIMIT && 1485 nsINSSErrorsService::NSS_SSL_ERROR_BASE == SSL_ERROR_BASE && 1486 nsINSSErrorsService::NSS_SSL_ERROR_LIMIT == SSL_ERROR_LIMIT, 1487 "You must update the values in nsINSSErrorsService.idl"); 1488 1489 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization beginning\n")); 1490 1491 nsAutoCString profileStr; 1492 nsresult rv = GetNSSProfilePath(profileStr); 1493 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); 1494 if (NS_FAILED(rv)) { 1495 return NS_ERROR_NOT_AVAILABLE; 1496 } 1497 1498 #if defined(NIGHTLY_BUILD) && !defined(ANDROID) 1499 if (!profileStr.IsEmpty()) { 1500 UnmigrateFromPrefixedCertDBs(); 1501 } 1502 #endif 1503 1504 #if defined(XP_WIN) || (defined(XP_LINUX) && !defined(ANDROID)) 1505 SetNSSDatabaseCacheModeAsAppropriate(); 1506 #endif 1507 1508 bool nocertdb = StaticPrefs::security_nocertdb_AtStartup(); 1509 bool inSafeMode = true; 1510 nsCOMPtr<nsIXULRuntime> runtime(do_GetService("@mozilla.org/xre/runtime;1")); 1511 // There might not be an nsIXULRuntime in embedded situations. This will 1512 // default to assuming we are in safe mode (as a result, no external PKCS11 1513 // modules will be loaded). 1514 if (runtime) { 1515 rv = runtime->GetInSafeMode(&inSafeMode); 1516 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); 1517 if (NS_FAILED(rv)) { 1518 return rv; 1519 } 1520 } 1521 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("inSafeMode: %u\n", inSafeMode)); 1522 1523 rv = InitializeNSSWithFallbacks(profileStr, nocertdb, inSafeMode); 1524 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); 1525 if (NS_FAILED(rv)) { 1526 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("failed to initialize NSS")); 1527 return rv; 1528 } 1529 1530 PK11_SetPasswordFunc(PK11PasswordPrompt); 1531 1532 // Register an observer so we can inform NSS when these prefs change 1533 Preferences::AddStrongObserver(this, "security."); 1534 1535 rv = CommonInit(); 1536 1537 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); 1538 if (NS_FAILED(rv)) { 1539 return NS_ERROR_UNEXPECTED; 1540 } 1541 1542 nsCOMPtr<nsICertOverrideService> certOverrideService( 1543 do_GetService(NS_CERTOVERRIDE_CONTRACTID)); 1544 nsCOMPtr<nsIClientAuthRememberService> clientAuthRememberService( 1545 do_GetService(NS_CLIENTAUTHREMEMBERSERVICE_CONTRACTID)); 1546 nsCOMPtr<nsISiteSecurityService> siteSecurityService( 1547 do_GetService(NS_SSSERVICE_CONTRACTID)); 1548 nsCOMPtr<nsICertStorage> certStorage(do_GetService(NS_CERT_STORAGE_CID)); 1549 1550 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("NSS Initialization done\n")); 1551 1552 { 1553 MutexAutoLock lock(mMutex); 1554 1555 // ensure we have initial values for various root hashes 1556 #ifdef DEBUG 1557 mTestBuiltInRootHash.Truncate(); 1558 Preferences::GetCString("security.test.built_in_root_hash", 1559 mTestBuiltInRootHash); 1560 #endif 1561 mMitmCanaryIssuer.Truncate(); 1562 Preferences::GetString("security.pki.mitm_canary_issuer", 1563 mMitmCanaryIssuer); 1564 mMitmDetecionEnabled = 1565 Preferences::GetBool("security.pki.mitm_canary_issuer.enabled", true); 1566 1567 // Set dynamic options from prefs. 1568 setValidationOptions(lock); 1569 1570 bool importEnterpriseRoots = 1571 StaticPrefs::security_enterprise_roots_enabled(); 1572 1573 nsAutoCString greBinDir; 1574 rv = GetDirectoryPath(NS_GRE_BIN_DIR, greBinDir); 1575 if (NS_FAILED(rv)) { 1576 return rv; 1577 } 1578 1579 RefPtr<LoadLoadableCertsTask> loadLoadableCertsTask( 1580 new LoadLoadableCertsTask(this, importEnterpriseRoots, 1581 std::move(greBinDir))); 1582 rv = loadLoadableCertsTask->Dispatch(); 1583 MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv)); 1584 if (NS_FAILED(rv)) { 1585 return rv; 1586 } 1587 1588 return NS_OK; 1589 } 1590 } 1591 1592 void nsNSSComponent::PrepareForShutdown() { 1593 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent::PrepareForShutdown")); 1594 MOZ_RELEASE_ASSERT(NS_IsMainThread()); 1595 1596 PK11_SetPasswordFunc((PK11PasswordFunc) nullptr); 1597 1598 Preferences::RemoveObserver(this, "security."); 1599 1600 // Release the default CertVerifier. This will cause any held NSS resources 1601 // to be released. 1602 { 1603 MutexAutoLock lock(mMutex); 1604 mDefaultCertVerifier = nullptr; 1605 } 1606 1607 // Unload osclientcerts so it drops any held resources and stops its 1608 // background thread. 1609 AsyncLoadOrUnloadOSClientCertsModule(false); 1610 1611 // We don't actually shut down NSS - XPCOM does, after all threads have been 1612 // joined and the component manager has been shut down (and so there shouldn't 1613 // be any XPCOM objects holding NSS resources). 1614 } 1615 1616 nsresult nsNSSComponent::Init() { 1617 MOZ_RELEASE_ASSERT(NS_IsMainThread()); 1618 if (!NS_IsMainThread()) { 1619 return NS_ERROR_NOT_SAME_THREAD; 1620 } 1621 1622 MOZ_ASSERT(XRE_IsParentProcess()); 1623 if (!XRE_IsParentProcess()) { 1624 return NS_ERROR_NOT_AVAILABLE; 1625 } 1626 1627 AutoGleanTimer<&glean::networking::nss_initialization> timer; 1628 1629 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("Beginning NSS initialization\n")); 1630 1631 nsresult rv = InitializeNSS(); 1632 if (NS_FAILED(rv)) { 1633 MOZ_LOG(gPIPNSSLog, LogLevel::Error, 1634 ("nsNSSComponent::InitializeNSS() failed\n")); 1635 return rv; 1636 } 1637 1638 rv = RegisterObservers(); 1639 if (NS_FAILED(rv)) { 1640 return rv; 1641 } 1642 1643 return NS_OK; 1644 } 1645 1646 // nsISupports Implementation for the class 1647 NS_IMPL_ISUPPORTS(nsNSSComponent, nsINSSComponent, nsIObserver) 1648 1649 static const char* const PROFILE_BEFORE_CHANGE_TOPIC = "profile-before-change"; 1650 1651 NS_IMETHODIMP 1652 nsNSSComponent::Observe(nsISupports* aSubject, const char* aTopic, 1653 const char16_t* someData) { 1654 // In some tests, we don't receive a "profile-before-change" topic. However, 1655 // we still have to shut down before the storage service shuts down, because 1656 // closing the sql-backed softoken requires sqlite still be available. Thus, 1657 // we observe "xpcom-shutdown" just in case. 1658 if (nsCRT::strcmp(aTopic, PROFILE_BEFORE_CHANGE_TOPIC) == 0 || 1659 nsCRT::strcmp(aTopic, NS_XPCOM_SHUTDOWN_OBSERVER_ID) == 0) { 1660 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1661 ("receiving profile change or XPCOM shutdown notification")); 1662 PrepareForShutdown(); 1663 } else if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) { 1664 bool clearSessionCache = true; 1665 NS_ConvertUTF16toUTF8 prefName(someData); 1666 1667 if (HandleTLSPrefChange(prefName)) { 1668 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("HandleTLSPrefChange done")); 1669 } else if ( 1670 prefName.EqualsLiteral("security.OCSP.enabled") || 1671 prefName.EqualsLiteral("security.OCSP.require") || 1672 prefName.EqualsLiteral("security.pki.cert_short_lifetime_in_days") || 1673 prefName.EqualsLiteral("security.ssl.enable_ocsp_stapling") || 1674 prefName.EqualsLiteral("security.ssl.enable_ocsp_must_staple") || 1675 prefName.EqualsLiteral("security.pki.certificate_transparency.mode") || 1676 prefName.EqualsLiteral( 1677 "security.pki.certificate_transparency.disable_for_hosts") || 1678 prefName.EqualsLiteral( 1679 "security.pki.certificate_transparency.disable_for_spki_hashes") || 1680 prefName.EqualsLiteral("security.OCSP.timeoutMilliseconds.soft") || 1681 prefName.EqualsLiteral("security.OCSP.timeoutMilliseconds.hard") || 1682 prefName.EqualsLiteral("security.pki.crlite_mode")) { 1683 MutexAutoLock lock(mMutex); 1684 setValidationOptions(lock); 1685 #ifdef DEBUG 1686 } else if (prefName.EqualsLiteral("security.test.built_in_root_hash")) { 1687 MutexAutoLock lock(mMutex); 1688 mTestBuiltInRootHash.Truncate(); 1689 Preferences::GetCString("security.test.built_in_root_hash", 1690 mTestBuiltInRootHash); 1691 #endif // DEBUG 1692 } else if (prefName.Equals("security.enterprise_roots.enabled")) { 1693 UnloadEnterpriseRoots(); 1694 MaybeImportEnterpriseRoots(); 1695 } else if (prefName.Equals("security.osclientcerts.autoload")) { 1696 bool loadOSClientCertsModule = 1697 StaticPrefs::security_osclientcerts_autoload(); 1698 AsyncLoadOrUnloadOSClientCertsModule(loadOSClientCertsModule); 1699 } else if (prefName.EqualsLiteral("security.pki.mitm_canary_issuer")) { 1700 MutexAutoLock lock(mMutex); 1701 mMitmCanaryIssuer.Truncate(); 1702 Preferences::GetString("security.pki.mitm_canary_issuer", 1703 mMitmCanaryIssuer); 1704 } else if (prefName.EqualsLiteral( 1705 "security.pki.mitm_canary_issuer.enabled")) { 1706 MutexAutoLock lock(mMutex); 1707 mMitmDetecionEnabled = 1708 Preferences::GetBool("security.pki.mitm_canary_issuer.enabled", true); 1709 } else { 1710 clearSessionCache = false; 1711 } 1712 if (clearSessionCache) { 1713 ClearSSLExternalAndInternalSessionCache(); 1714 } 1715 } else if (!nsCRT::strcmp(aTopic, "last-pb-context-exited")) { 1716 nsNSSComponent::DoClearSSLExternalAndInternalSessionCache(); 1717 } 1718 1719 return NS_OK; 1720 } 1721 1722 /*static*/ 1723 nsresult nsNSSComponent::GetNewPrompter(nsIPrompt** result) { 1724 NS_ENSURE_ARG_POINTER(result); 1725 *result = nullptr; 1726 1727 if (!NS_IsMainThread()) { 1728 NS_ERROR("nsSDRContext::GetNewPrompter called off the main thread"); 1729 return NS_ERROR_NOT_SAME_THREAD; 1730 } 1731 1732 nsresult rv; 1733 nsCOMPtr<nsIWindowWatcher> wwatch( 1734 do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv)); 1735 NS_ENSURE_SUCCESS(rv, rv); 1736 1737 rv = wwatch->GetNewPrompter(0, result); 1738 NS_ENSURE_SUCCESS(rv, rv); 1739 1740 return rv; 1741 } 1742 1743 nsresult nsNSSComponent::LogoutAuthenticatedPK11() { 1744 ClearSSLExternalAndInternalSessionCache(); 1745 1746 nsCOMPtr<nsIObserverService> os = mozilla::services::GetObserverService(); 1747 if (os) { 1748 os->NotifyObservers(nullptr, "net:cancel-all-connections", nullptr); 1749 } 1750 1751 return NS_OK; 1752 } 1753 1754 nsresult nsNSSComponent::RegisterObservers() { 1755 nsCOMPtr<nsIObserverService> observerService( 1756 do_GetService("@mozilla.org/observer-service;1")); 1757 if (!observerService) { 1758 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1759 ("nsNSSComponent: couldn't get observer service\n")); 1760 return NS_ERROR_FAILURE; 1761 } 1762 1763 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, ("nsNSSComponent: adding observers\n")); 1764 // Using false for the ownsweak parameter means the observer service will 1765 // keep a strong reference to this component. As a result, this will live at 1766 // least as long as the observer service. 1767 observerService->AddObserver(this, PROFILE_BEFORE_CHANGE_TOPIC, false); 1768 observerService->AddObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false); 1769 observerService->AddObserver(this, "last-pb-context-exited", false); 1770 1771 return NS_OK; 1772 } 1773 1774 nsresult DoesCertMatchFingerprint(const nsTArray<uint8_t>& cert, 1775 const nsCString& fingerprint, bool& result) { 1776 result = false; 1777 1778 if (cert.Length() > std::numeric_limits<uint32_t>::max()) { 1779 return NS_ERROR_INVALID_ARG; 1780 } 1781 nsTArray<uint8_t> digestArray; 1782 nsresult rv = Digest::DigestBuf(SEC_OID_SHA256, cert.Elements(), 1783 cert.Length(), digestArray); 1784 if (NS_FAILED(rv)) { 1785 return rv; 1786 } 1787 SECItem digestItem = {siBuffer, digestArray.Elements(), 1788 static_cast<unsigned int>(digestArray.Length())}; 1789 UniquePORTString certFingerprint( 1790 CERT_Hexify(&digestItem, true /* use colon delimiters */)); 1791 if (!certFingerprint) { 1792 return NS_ERROR_FAILURE; 1793 } 1794 1795 result = fingerprint.Equals(certFingerprint.get()); 1796 return NS_OK; 1797 } 1798 1799 NS_IMETHODIMP 1800 nsNSSComponent::IsCertTestBuiltInRoot(const nsTArray<uint8_t>& cert, 1801 bool* result) { 1802 NS_ENSURE_ARG_POINTER(result); 1803 *result = false; 1804 1805 #ifdef DEBUG 1806 MutexAutoLock lock(mMutex); 1807 nsresult rv = DoesCertMatchFingerprint(cert, mTestBuiltInRootHash, *result); 1808 if (NS_FAILED(rv)) { 1809 return rv; 1810 } 1811 #endif // DEBUG 1812 1813 return NS_OK; 1814 } 1815 1816 NS_IMETHODIMP 1817 nsNSSComponent::IssuerMatchesMitmCanary(const char* aCertIssuer) { 1818 MutexAutoLock lock(mMutex); 1819 if (mMitmDetecionEnabled && !mMitmCanaryIssuer.IsEmpty()) { 1820 nsString certIssuer = NS_ConvertUTF8toUTF16(aCertIssuer); 1821 if (mMitmCanaryIssuer.Equals(certIssuer)) { 1822 return NS_OK; 1823 } 1824 } 1825 1826 return NS_ERROR_FAILURE; 1827 } 1828 1829 SharedCertVerifier::~SharedCertVerifier() = default; 1830 1831 NS_IMETHODIMP 1832 nsNSSComponent::GetDefaultCertVerifier(SharedCertVerifier** result) { 1833 MutexAutoLock lock(mMutex); 1834 NS_ENSURE_ARG_POINTER(result); 1835 RefPtr<SharedCertVerifier> certVerifier(mDefaultCertVerifier); 1836 certVerifier.forget(result); 1837 return NS_OK; 1838 } 1839 1840 // static 1841 void nsNSSComponent::DoClearSSLExternalAndInternalSessionCache() { 1842 SSL_ClearSessionCache(); 1843 mozilla::net::SSLTokensCache::Clear(); 1844 } 1845 1846 NS_IMETHODIMP 1847 nsNSSComponent::ClearSSLExternalAndInternalSessionCache() { 1848 MOZ_ASSERT(XRE_IsParentProcess()); 1849 if (!XRE_IsParentProcess()) { 1850 return NS_ERROR_NOT_AVAILABLE; 1851 } 1852 1853 if (mozilla::net::nsIOService::UseSocketProcess()) { 1854 if (mozilla::net::gIOService) { 1855 mozilla::net::gIOService->CallOrWaitForSocketProcess([]() { 1856 RefPtr<mozilla::net::SocketProcessParent> socketParent = 1857 mozilla::net::SocketProcessParent::GetSingleton(); 1858 (void)socketParent->SendClearSessionCache(); 1859 }); 1860 } 1861 } 1862 DoClearSSLExternalAndInternalSessionCache(); 1863 return NS_OK; 1864 } 1865 1866 NS_IMETHODIMP 1867 nsNSSComponent::AsyncClearSSLExternalAndInternalSessionCache( 1868 JSContext* aCx, ::mozilla::dom::Promise** aPromise) { 1869 MOZ_ASSERT(XRE_IsParentProcess()); 1870 if (!XRE_IsParentProcess()) { 1871 return NS_ERROR_NOT_AVAILABLE; 1872 } 1873 1874 nsIGlobalObject* globalObject = xpc::CurrentNativeGlobal(aCx); 1875 if (NS_WARN_IF(!globalObject)) { 1876 return NS_ERROR_FAILURE; 1877 } 1878 1879 ErrorResult result; 1880 RefPtr<mozilla::dom::Promise> promise = 1881 mozilla::dom::Promise::Create(globalObject, result); 1882 if (NS_WARN_IF(result.Failed())) { 1883 return result.StealNSResult(); 1884 } 1885 1886 if (mozilla::net::nsIOService::UseSocketProcess() && 1887 mozilla::net::gIOService) { 1888 mozilla::net::gIOService->CallOrWaitForSocketProcess([p = RefPtr{ 1889 promise}]() { 1890 RefPtr<mozilla::net::SocketProcessParent> socketParent = 1891 mozilla::net::SocketProcessParent::GetSingleton(); 1892 (void)socketParent->SendClearSessionCache()->Then( 1893 GetCurrentSerialEventTarget(), __func__, 1894 [promise = RefPtr{p}] { promise->MaybeResolveWithUndefined(); }, 1895 [promise = RefPtr{p}] { promise->MaybeReject(NS_ERROR_UNEXPECTED); }); 1896 }); 1897 } else { 1898 promise->MaybeResolveWithUndefined(); 1899 } 1900 DoClearSSLExternalAndInternalSessionCache(); 1901 promise.forget(aPromise); 1902 return NS_OK; 1903 } 1904 1905 Atomic<bool> sSearchingForClientAuthCertificates{false}; 1906 1907 extern "C" { 1908 // Returns true once if gecko is searching for client authentication 1909 // certificates (i.e., if some thread has an 1910 // AutoSearchingForClientAuthCertificates on the stack). 1911 // The idea is when gecko instantiates an 1912 // AutoSearchingForClientAuthCertificates, sSearchingForClientAuthCertificates 1913 // will get set to true. Some thread running some NSS code will result in a 1914 // call to IsGeckoSearchingForClientAuthCertificates(), which will essentially 1915 // claim the search by swapping the value for false. The search will happen, 1916 // but for the rest of the lifetime of the 1917 // AutoSearchingForClientAuthCertificates, this function will return false, 1918 // meaning no other threads will also cause searches to happen. 1919 bool IsGeckoSearchingForClientAuthCertificates() { 1920 return sSearchingForClientAuthCertificates.exchange(false); 1921 } 1922 } 1923 1924 AutoSearchingForClientAuthCertificates:: 1925 AutoSearchingForClientAuthCertificates() { 1926 sSearchingForClientAuthCertificates = true; 1927 } 1928 1929 AutoSearchingForClientAuthCertificates:: 1930 ~AutoSearchingForClientAuthCertificates() { 1931 sSearchingForClientAuthCertificates = false; 1932 } 1933 1934 namespace mozilla { 1935 namespace psm { 1936 1937 already_AddRefed<SharedCertVerifier> GetDefaultCertVerifier() { 1938 static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID); 1939 1940 nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID)); 1941 if (!nssComponent) { 1942 return nullptr; 1943 } 1944 nsresult rv = nssComponent->BlockUntilLoadableCertsLoaded(); 1945 if (NS_FAILED(rv)) { 1946 return nullptr; 1947 } 1948 RefPtr<SharedCertVerifier> result; 1949 rv = nssComponent->GetDefaultCertVerifier(getter_AddRefs(result)); 1950 if (NS_FAILED(rv)) { 1951 return nullptr; 1952 } 1953 return result.forget(); 1954 } 1955 1956 // Helper for FindClientCertificatesWithPrivateKeys. Copies all 1957 // CERTCertificates from `from` to `to`. 1958 static inline void CopyCertificatesTo(UniqueCERTCertList& from, 1959 UniqueCERTCertList& to) { 1960 MOZ_ASSERT(from); 1961 MOZ_ASSERT(to); 1962 for (CERTCertListNode* n = CERT_LIST_HEAD(from.get()); 1963 !CERT_LIST_END(n, from.get()); n = CERT_LIST_NEXT(n)) { 1964 UniqueCERTCertificate cert(CERT_DupCertificate(n->cert)); 1965 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1966 (" provisionally adding '%s'", n->cert->subjectName)); 1967 if (CERT_AddCertToListTail(to.get(), cert.get()) == SECSuccess) { 1968 (void)cert.release(); 1969 } 1970 } 1971 } 1972 1973 // Lists all private keys on all modules and returns a list of any corresponding 1974 // client certificates. Returns an empty list if no such certificates can be 1975 // found. Returns null if an error is encountered. 1976 UniqueCERTCertList FindClientCertificatesWithPrivateKeys() { 1977 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1978 ("FindClientCertificatesWithPrivateKeys")); 1979 AutoSearchingForClientAuthCertificates _; 1980 1981 (void)BlockUntilLoadableCertsLoaded(); 1982 (void)CheckForSmartCardChanges(); 1983 1984 UniqueCERTCertList certsWithPrivateKeys(CERT_NewCertList()); 1985 if (!certsWithPrivateKeys) { 1986 return nullptr; 1987 } 1988 1989 UniquePK11SlotInfo internalSlot(PK11_GetInternalKeySlot()); 1990 1991 AutoSECMODListReadLock secmodLock; 1992 SECMODModuleList* list = SECMOD_GetDefaultModuleList(); 1993 while (list) { 1994 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1995 (" module '%s'", list->module->commonName)); 1996 for (int i = 0; i < list->module->slotCount; i++) { 1997 PK11SlotInfo* slot = list->module->slots[i]; 1998 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 1999 (" slot '%s'", PK11_GetSlotName(slot))); 2000 // If this is the internal certificate/key slot or the slot on the 2001 // builtin roots module, there may be many more certificates than private 2002 // keys, so search by private keys (PK11_HasRootCerts will be true if the 2003 // slot contains an object with the vendor-specific CK_CLASS 2004 // CKO_NSS_BUILTIN_ROOT_LIST, which should only be the case for the NSS 2005 // builtin roots module). 2006 if (internalSlot.get() == slot || PK11_HasRootCerts(slot)) { 2007 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 2008 (" (looking at internal/builtin slot)")); 2009 if (PK11_Authenticate(slot, true, nullptr) != SECSuccess) { 2010 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (couldn't authenticate)")); 2011 continue; 2012 } 2013 UniqueSECKEYPrivateKeyList privateKeys( 2014 PK11_ListPrivKeysInSlot(slot, nullptr, nullptr)); 2015 if (!privateKeys) { 2016 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (no private keys)")); 2017 continue; 2018 } 2019 for (SECKEYPrivateKeyListNode* node = PRIVKEY_LIST_HEAD(privateKeys); 2020 !PRIVKEY_LIST_END(node, privateKeys); 2021 node = PRIVKEY_LIST_NEXT(node)) { 2022 UniqueCERTCertList certs(PK11_GetCertsMatchingPrivateKey(node->key)); 2023 if (!certs) { 2024 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 2025 (" PK11_GetCertsMatchingPrivateKey encountered an " 2026 "error ")); 2027 continue; 2028 } 2029 if (CERT_LIST_EMPTY(certs)) { 2030 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (no certs for key)")); 2031 continue; 2032 } 2033 CopyCertificatesTo(certs, certsWithPrivateKeys); 2034 } 2035 } else { 2036 // ... otherwise, optimistically assume that searching by certificate 2037 // won't take too much time. Since "friendly" slots expose certificates 2038 // without needing to be authenticated to, this results in fewer PIN 2039 // dialogs shown to the user. 2040 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 2041 (" (looking at non-internal slot)")); 2042 2043 if (!PK11_IsPresent(slot)) { 2044 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (not present)")); 2045 continue; 2046 } 2047 // If this isn't a "friendly" slot, authenticate to expose certificates. 2048 if (!PK11_IsFriendly(slot) && 2049 PK11_Authenticate(slot, true, nullptr) != SECSuccess) { 2050 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" (couldn't authenticate)")); 2051 continue; 2052 } 2053 UniqueCERTCertList certsInSlot(PK11_ListCertsInSlot(slot)); 2054 if (!certsInSlot) { 2055 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 2056 (" (couldn't list certs in slot)")); 2057 continue; 2058 } 2059 // When NSS decodes a certificate, if that certificate has a 2060 // corresponding private key (or public key, if the slot it's on hasn't 2061 // been logged into), it notes it as a "user cert". 2062 if (CERT_FilterCertListForUserCerts(certsInSlot.get()) != SECSuccess) { 2063 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 2064 (" (couldn't filter certs)")); 2065 continue; 2066 } 2067 CopyCertificatesTo(certsInSlot, certsWithPrivateKeys); 2068 } 2069 } 2070 list = list->next; 2071 } 2072 2073 if (CERT_FilterCertListByUsage(certsWithPrivateKeys.get(), certUsageSSLClient, 2074 false) != SECSuccess) { 2075 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, 2076 (" CERT_FilterCertListByUsage encountered an error - returning")); 2077 return nullptr; 2078 } 2079 2080 if (MOZ_UNLIKELY(MOZ_LOG_TEST(gPIPNSSLog, LogLevel::Debug))) { 2081 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" returning:")); 2082 for (CERTCertListNode* n = CERT_LIST_HEAD(certsWithPrivateKeys); 2083 !CERT_LIST_END(n, certsWithPrivateKeys); n = CERT_LIST_NEXT(n)) { 2084 MOZ_LOG(gPIPNSSLog, LogLevel::Debug, (" %s", n->cert->subjectName)); 2085 } 2086 } 2087 2088 return certsWithPrivateKeys; 2089 } 2090 2091 CertVerifier::CertificateTransparencyMode GetCertificateTransparencyMode() { 2092 const CertVerifier::CertificateTransparencyMode defaultCTMode = 2093 CertVerifier::CertificateTransparencyMode::TelemetryOnly; 2094 CertVerifier::CertificateTransparencyMode ctMode = 2095 static_cast<CertVerifier::CertificateTransparencyMode>( 2096 StaticPrefs::security_pki_certificate_transparency_mode()); 2097 switch (ctMode) { 2098 case CertVerifier::CertificateTransparencyMode::Disabled: 2099 case CertVerifier::CertificateTransparencyMode::TelemetryOnly: 2100 case CertVerifier::CertificateTransparencyMode::Enforce: 2101 break; 2102 default: 2103 ctMode = defaultCTMode; 2104 break; 2105 } 2106 return ctMode; 2107 } 2108 2109 } // namespace psm 2110 } // namespace mozilla 2111 2112 NS_IMPL_ISUPPORTS(PipUIContext, nsIInterfaceRequestor) 2113 2114 PipUIContext::PipUIContext() = default; 2115 2116 PipUIContext::~PipUIContext() = default; 2117 2118 NS_IMETHODIMP 2119 PipUIContext::GetInterface(const nsIID& uuid, void** result) { 2120 NS_ENSURE_ARG_POINTER(result); 2121 *result = nullptr; 2122 2123 if (!NS_IsMainThread()) { 2124 NS_ERROR("PipUIContext::GetInterface called off the main thread"); 2125 return NS_ERROR_NOT_SAME_THREAD; 2126 } 2127 2128 if (!uuid.Equals(NS_GET_IID(nsIPrompt))) return NS_ERROR_NO_INTERFACE; 2129 2130 nsIPrompt* prompt = nullptr; 2131 nsresult rv = nsNSSComponent::GetNewPrompter(&prompt); 2132 *result = prompt; 2133 return rv; 2134 } 2135 2136 nsresult getNSSDialogs(void** _result, REFNSIID aIID, const char* contract) { 2137 if (!NS_IsMainThread()) { 2138 NS_ERROR("getNSSDialogs called off the main thread"); 2139 return NS_ERROR_NOT_SAME_THREAD; 2140 } 2141 2142 nsresult rv; 2143 2144 nsCOMPtr<nsISupports> svc = do_GetService(contract, &rv); 2145 if (NS_FAILED(rv)) { 2146 return rv; 2147 } 2148 2149 rv = svc->QueryInterface(aIID, _result); 2150 2151 return rv; 2152 } 2153 2154 nsresult setPassword(PK11SlotInfo* slot, nsIInterfaceRequestor* ctx) { 2155 MOZ_ASSERT(slot); 2156 MOZ_ASSERT(ctx); 2157 NS_ENSURE_ARG_POINTER(slot); 2158 NS_ENSURE_ARG_POINTER(ctx); 2159 2160 if (PK11_NeedUserInit(slot)) { 2161 nsCOMPtr<nsITokenPasswordDialogs> dialogs; 2162 nsresult rv = getNSSDialogs(getter_AddRefs(dialogs), 2163 NS_GET_IID(nsITokenPasswordDialogs), 2164 NS_TOKENPASSWORDSDIALOG_CONTRACTID); 2165 if (NS_FAILED(rv)) { 2166 return rv; 2167 } 2168 2169 bool canceled; 2170 nsCOMPtr<nsIPK11Token> token = new nsPK11Token(slot); 2171 rv = dialogs->SetPassword(ctx, token, &canceled); 2172 if (NS_FAILED(rv)) { 2173 return rv; 2174 } 2175 2176 if (canceled) { 2177 return NS_ERROR_NOT_AVAILABLE; 2178 } 2179 } 2180 2181 return NS_OK; 2182 } 2183 2184 static PRBool ConvertBetweenUCS2andASCII(PRBool toUnicode, unsigned char* inBuf, 2185 unsigned int inBufLen, 2186 unsigned char* outBuf, 2187 unsigned int maxOutBufLen, 2188 unsigned int* outBufLen, 2189 PRBool swapBytes) { 2190 std::unique_ptr<unsigned char[]> inBufDup(new unsigned char[inBufLen]); 2191 if (!inBufDup) { 2192 return PR_FALSE; 2193 } 2194 std::memcpy(inBufDup.get(), inBuf, inBufLen * sizeof(unsigned char)); 2195 2196 // If converting Unicode to ASCII, swap bytes before conversion as neccessary. 2197 if (!toUnicode && swapBytes) { 2198 if (inBufLen % 2 != 0) { 2199 return PR_FALSE; 2200 } 2201 mozilla::NativeEndian::swapFromLittleEndianInPlace( 2202 reinterpret_cast<char16_t*>(inBufDup.get()), inBufLen / 2); 2203 } 2204 return PORT_UCS2_UTF8Conversion(toUnicode, inBufDup.get(), inBufLen, outBuf, 2205 maxOutBufLen, outBufLen); 2206 } 2207 2208 namespace mozilla { 2209 namespace psm { 2210 2211 nsresult InitializeCipherSuite() { 2212 MOZ_ASSERT(NS_IsMainThread(), 2213 "InitializeCipherSuite() can only be accessed on the main thread"); 2214 2215 if (NSS_SetDomesticPolicy() != SECSuccess) { 2216 return NS_ERROR_FAILURE; 2217 } 2218 2219 // Disable any ciphers that NSS might have enabled by default 2220 for (uint16_t i = 0; i < SSL_NumImplementedCiphers; ++i) { 2221 uint16_t cipher_id = SSL_ImplementedCiphers[i]; 2222 SSL_CipherPrefSetDefault(cipher_id, false); 2223 } 2224 2225 // Now only set SSL/TLS ciphers we knew about at compile time 2226 for (const auto& cipherPref : sCipherPrefs) { 2227 SSL_CipherPrefSetDefault(cipherPref.id, cipherPref.prefGetter()); 2228 } 2229 2230 SetDeprecatedTLS1CipherPrefs(); 2231 2232 // Enable ciphers for PKCS#12 2233 SEC_PKCS12EnableCipher(PKCS12_RC4_40, 1); 2234 SEC_PKCS12EnableCipher(PKCS12_RC4_128, 1); 2235 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_40, 1); 2236 SEC_PKCS12EnableCipher(PKCS12_RC2_CBC_128, 1); 2237 SEC_PKCS12EnableCipher(PKCS12_DES_56, 1); 2238 SEC_PKCS12EnableCipher(PKCS12_DES_EDE3_168, 1); 2239 SEC_PKCS12EnableCipher(PKCS12_AES_CBC_128, 1); 2240 SEC_PKCS12EnableCipher(PKCS12_AES_CBC_192, 1); 2241 SEC_PKCS12EnableCipher(PKCS12_AES_CBC_256, 1); 2242 SEC_PKCS12SetPreferredCipher(PKCS12_DES_EDE3_168, 1); 2243 PORT_SetUCS2_ASCIIConversionFunction(ConvertBetweenUCS2andASCII); 2244 2245 // PSM enforces a minimum RSA key size of 1024 bits, which is overridable. 2246 // NSS has its own minimum, which is not overridable (the default is 1023 2247 // bits). This sets the NSS minimum to 512 bits so users can still connect to 2248 // devices like wifi routers with woefully small keys (they would have to add 2249 // an override to do so, but they already do for such devices). 2250 NSS_OptionSet(NSS_RSA_MIN_KEY_SIZE, 512); 2251 2252 SetKyberPolicy(); 2253 2254 // Observe preference change around cipher suite setting. 2255 return CipherSuiteChangeObserver::StartObserve(); 2256 } 2257 2258 } // namespace psm 2259 } // namespace mozilla