mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 12:51:06 +00:00
Bug 1905453 - collect telemetry on the prevalence of third-party pkcs#11 modules r=jschanck
Differential Revision: https://phabricator.services.mozilla.com/D215563
This commit is contained in:
parent
1777874bea
commit
5291778fb1
@ -13,6 +13,7 @@
|
||||
#include "ExtendedValidation.h"
|
||||
#include "MultiLogCTVerifier.h"
|
||||
#include "NSSErrorsService.h"
|
||||
#include "PKCS11ModuleDB.h"
|
||||
#include "PublicKeyPinningService.h"
|
||||
#include "cert.h"
|
||||
#include "cert_storage/src/cert_storage.h"
|
||||
@ -37,7 +38,6 @@
|
||||
#include "nsCRTGlue.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsNSSCallbacks.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsNSSCertificate.h"
|
||||
#include "nsNSSCertificateDB.h"
|
||||
#include "nsNSSIOLayer.h"
|
||||
@ -102,7 +102,7 @@ NSSCertDBTrustDomain::NSSCertDBTrustDomain(
|
||||
mHostname(hostname),
|
||||
mCertStorage(do_GetService(NS_CERT_STORAGE_CID)),
|
||||
mOCSPStaplingStatus(CertVerifier::OCSP_STAPLING_NEVER_CHECKED),
|
||||
mBuiltInRootsModule(SECMOD_FindModule(kRootModuleName)),
|
||||
mBuiltInRootsModule(SECMOD_FindModule(kRootModuleName.get())),
|
||||
mOCSPFetchStatus(OCSPFetchStatus::NotFetched) {}
|
||||
|
||||
static void FindRootsWithSubject(UniqueSECMODModule& rootsModule,
|
||||
@ -1686,6 +1686,8 @@ SECStatus InitializeNSS(const nsACString& dir, NSSDBConfig nssDbConfig,
|
||||
}
|
||||
}
|
||||
|
||||
CollectThirdPartyPKCS11ModuleTelemetry();
|
||||
|
||||
return SECSuccess;
|
||||
}
|
||||
|
||||
@ -1750,8 +1752,6 @@ bool LoadUserModuleAt(const char* moduleName, const char* libraryName,
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* kIPCClientCertsModuleName = "IPC Client Cert Module";
|
||||
|
||||
bool LoadIPCClientCertsModule(const nsCString& dir) {
|
||||
// The IPC client certs module needs to be able to call back into gecko to be
|
||||
// able to communicate with the parent process over IPC. This is achieved by
|
||||
@ -1759,14 +1759,14 @@ bool LoadIPCClientCertsModule(const nsCString& dir) {
|
||||
// extra string parameter that will be available when C_Initialize is called
|
||||
// on IPC client certs.
|
||||
nsPrintfCString addrs("%p,%p", DoFindObjects, DoSign);
|
||||
if (!LoadUserModuleAt(kIPCClientCertsModuleName, "ipcclientcerts", dir,
|
||||
if (!LoadUserModuleAt(kIPCClientCertsModuleName.get(), "ipcclientcerts", dir,
|
||||
addrs.get())) {
|
||||
return false;
|
||||
}
|
||||
RunOnShutdown(
|
||||
[]() {
|
||||
UniqueSECMODModule ipcClientCertsModule(
|
||||
SECMOD_FindModule(kIPCClientCertsModuleName));
|
||||
SECMOD_FindModule(kIPCClientCertsModuleName.get()));
|
||||
if (ipcClientCertsModule) {
|
||||
SECMOD_UnloadUserModule(ipcClientCertsModule.get());
|
||||
}
|
||||
@ -1775,14 +1775,12 @@ bool LoadIPCClientCertsModule(const nsCString& dir) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const char* kOSClientCertsModuleName = "OS Client Cert Module";
|
||||
|
||||
bool LoadOSClientCertsModule(const nsCString& dir) {
|
||||
nsLiteralCString params =
|
||||
StaticPrefs::security_osclientcerts_assume_rsa_pss_support()
|
||||
? "RSA-PSS"_ns
|
||||
: ""_ns;
|
||||
return LoadUserModuleAt(kOSClientCertsModuleName, "osclientcerts", dir,
|
||||
return LoadUserModuleAt(kOSClientCertsModuleName.get(), "osclientcerts", dir,
|
||||
params.get());
|
||||
}
|
||||
|
||||
@ -1794,7 +1792,7 @@ bool LoadLoadableRoots(const nsCString& dir) {
|
||||
// "Root Certs" module allows us to load the correct one. See bug 1406396.
|
||||
int unusedModType;
|
||||
Unused << SECMOD_DeleteModule("Root Certs", &unusedModType);
|
||||
return LoadUserModuleAt(kRootModuleName, "nssckbi", dir, nullptr);
|
||||
return LoadUserModuleAt(kRootModuleName.get(), "nssckbi", dir, nullptr);
|
||||
}
|
||||
|
||||
nsresult DefaultServerNicknameForCert(const CERTCertificate* cert,
|
||||
|
@ -87,8 +87,6 @@ bool LoadLoadableRoots(const nsCString& dir);
|
||||
*/
|
||||
bool LoadOSClientCertsModule(const nsCString& dir);
|
||||
|
||||
extern const char* kOSClientCertsModuleName;
|
||||
|
||||
/**
|
||||
* Loads the IPC client certs module.
|
||||
*
|
||||
@ -99,8 +97,6 @@ extern const char* kOSClientCertsModuleName;
|
||||
*/
|
||||
bool LoadIPCClientCertsModule(const nsCString& dir);
|
||||
|
||||
extern const char* kIPCClientCertsModuleName;
|
||||
|
||||
/**
|
||||
* Unloads the loadable roots module and os client certs module, if loaded.
|
||||
*/
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include "EnterpriseRoots.h"
|
||||
|
||||
#include "PKCS11ModuleDB.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/IntegerPrintfMacros.h"
|
||||
#include "mozilla/Casting.h"
|
||||
@ -13,7 +14,6 @@
|
||||
#include "mozilla/Unused.h"
|
||||
#include "mozpkix/Result.h"
|
||||
#include "nsCRT.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsThreadUtils.h"
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
@ -33,6 +33,7 @@
|
||||
extern mozilla::LazyLogModule gPIPNSSLog;
|
||||
|
||||
using namespace mozilla;
|
||||
using namespace psm;
|
||||
|
||||
void EnterpriseCert::CopyBytes(nsTArray<uint8_t>& dest) const {
|
||||
dest.Assign(mDER);
|
||||
@ -498,7 +499,7 @@ nsresult GatherEnterpriseCerts(nsTArray<EnterpriseCert>& certs) {
|
||||
}
|
||||
|
||||
certs.Clear();
|
||||
UniqueSECMODModule rootsModule(SECMOD_FindModule(kRootModuleName));
|
||||
UniqueSECMODModule rootsModule(SECMOD_FindModule(kRootModuleName.get()));
|
||||
#ifdef XP_WIN
|
||||
GatherEnterpriseCertsWindows(certs, rootsModule);
|
||||
#endif // XP_WIN
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "PKCS11ModuleDB.h"
|
||||
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "mozilla/glean/GleanMetrics.h"
|
||||
#include "nsComponentManagerUtils.h"
|
||||
#include "nsIMutableArray.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
@ -33,7 +34,7 @@ static nsresult NormalizeModuleNameIn(const nsAString& moduleNameIn,
|
||||
return rv;
|
||||
}
|
||||
if (moduleNameIn.Equals(localizedRootModuleName)) {
|
||||
moduleNameOut.Assign(kRootModuleName);
|
||||
moduleNameOut.Assign(kRootModuleName.get());
|
||||
return NS_OK;
|
||||
}
|
||||
moduleNameOut.Assign(NS_ConvertUTF16toUTF8(moduleNameIn));
|
||||
@ -59,6 +60,8 @@ PKCS11ModuleDB::DeleteModule(const nsAString& aModuleName) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CollectThirdPartyPKCS11ModuleTelemetry();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -103,6 +106,9 @@ PKCS11ModuleDB::AddModule(const nsAString& aModuleName,
|
||||
if (srv != SECSuccess) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
CollectThirdPartyPKCS11ModuleTelemetry();
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
@ -180,5 +186,32 @@ PKCS11ModuleDB::GetIsFIPSEnabled(bool* aIsFIPSEnabled) {
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
const nsLiteralCString kBuiltInModuleNames[] = {
|
||||
kNSSInternalModuleName,
|
||||
kRootModuleName,
|
||||
kOSClientCertsModuleName,
|
||||
kIPCClientCertsModuleName,
|
||||
};
|
||||
|
||||
void CollectThirdPartyPKCS11ModuleTelemetry() {
|
||||
size_t thirdPartyModulesLoaded = 0;
|
||||
AutoSECMODListReadLock lock;
|
||||
for (SECMODModuleList* list = SECMOD_GetDefaultModuleList(); list;
|
||||
list = list->next) {
|
||||
bool isThirdParty = true;
|
||||
for (const auto& builtInModuleName : kBuiltInModuleNames) {
|
||||
if (builtInModuleName.Equals(list->module->commonName)) {
|
||||
isThirdParty = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isThirdParty) {
|
||||
thirdPartyModulesLoaded++;
|
||||
}
|
||||
}
|
||||
mozilla::glean::pkcs11::third_party_modules_loaded.Set(
|
||||
thirdPartyModulesLoaded);
|
||||
}
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
@ -7,6 +7,7 @@
|
||||
#define PKCS11ModuleDB_h
|
||||
|
||||
#include "nsIPKCS11ModuleDB.h"
|
||||
#include "nsTLiteralString.h"
|
||||
|
||||
namespace mozilla {
|
||||
namespace psm {
|
||||
@ -29,6 +30,13 @@ class PKCS11ModuleDB : public nsIPKCS11ModuleDB {
|
||||
virtual ~PKCS11ModuleDB() = default;
|
||||
};
|
||||
|
||||
const nsLiteralCString kIPCClientCertsModuleName("IPC Client Cert Module");
|
||||
const nsLiteralCString kNSSInternalModuleName("NSS Internal PKCS #11 Module");
|
||||
const nsLiteralCString kOSClientCertsModuleName("OS Client Cert Module");
|
||||
const nsLiteralCString kRootModuleName("Builtin Roots Module");
|
||||
|
||||
void CollectThirdPartyPKCS11ModuleTelemetry();
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
||||
|
||||
|
@ -6,12 +6,12 @@
|
||||
|
||||
#include "RootCertificateTelemetryUtils.h"
|
||||
|
||||
#include "PKCS11ModuleDB.h"
|
||||
#include "RootHashes.inc" // Note: Generated by genRootCAHashes.js
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "mozilla/ArrayUtils.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "nsINSSComponent.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsServiceManagerUtils.h"
|
||||
#include "pk11pub.h"
|
||||
|
||||
@ -109,7 +109,7 @@ int32_t RootCABinNumber(Span<const uint8_t> cert) {
|
||||
// because then it should have already matched our built-in list. This is
|
||||
// here as a backstop to catch situations where a built-in root was added but
|
||||
// the built-in telemetry information was not updated.
|
||||
UniqueSECMODModule rootsModule(SECMOD_FindModule(kRootModuleName));
|
||||
UniqueSECMODModule rootsModule(SECMOD_FindModule(kRootModuleName.get()));
|
||||
AutoSECMODListReadLock secmodLock;
|
||||
if (!rootsModule || rootsModule->slotCount != 1) {
|
||||
return ROOT_CERTIFICATE_UNKNOWN;
|
||||
|
@ -246,3 +246,19 @@ verification_used_cert_from:
|
||||
- dkeeler@mozilla.com
|
||||
expires: never
|
||||
denominator_metric: tls.certificate_verifications
|
||||
|
||||
pkcs11:
|
||||
third_party_modules_loaded:
|
||||
type: quantity
|
||||
description:
|
||||
The number of third-party PKCS#11 modules loaded.
|
||||
bugs:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1905453
|
||||
data_reviews:
|
||||
- https://bugzilla.mozilla.org/show_bug.cgi?id=1905453
|
||||
data_sensitivity:
|
||||
- interaction
|
||||
notification_emails:
|
||||
- dkeeler@mozilla.com
|
||||
expires: never
|
||||
unit: modules
|
||||
|
@ -26,12 +26,6 @@
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
// To avoid relying on localized strings in PSM, we hard-code the root module
|
||||
// name internally. When we display it to the user in the list of modules in the
|
||||
// front-end, we look up the localized value and display that instead of this.
|
||||
const char* kRootModuleName = "Builtin Roots Module";
|
||||
const size_t kRootModuleNameLen = strlen(kRootModuleName);
|
||||
|
||||
static nsresult GetPIPNSSBundle(nsIStringBundle** pipnssBundle) {
|
||||
nsCOMPtr<nsIStringBundleService> bundleService(
|
||||
do_GetService(NS_STRINGBUNDLE_CONTRACTID));
|
||||
|
@ -5,18 +5,8 @@
|
||||
#ifndef nsNSSCertHelper_h
|
||||
#define nsNSSCertHelper_h
|
||||
|
||||
#ifndef INET6_ADDRSTRLEN
|
||||
# define INET6_ADDRSTRLEN 46
|
||||
#endif
|
||||
|
||||
#include "certt.h"
|
||||
#include "nsString.h"
|
||||
|
||||
extern const char* kRootModuleName;
|
||||
extern const size_t kRootModuleNameLen;
|
||||
|
||||
class nsIX509Cert;
|
||||
|
||||
// If input is valid UTF-8, converts from UTF-8 to UTF-16. Otherwise,
|
||||
// converts from Latin1 to UTF-16.
|
||||
void LossyUTF8ToUTF16(const char* str, uint32_t len, /*out*/ nsAString& result);
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "EnterpriseRoots.h"
|
||||
#include "ExtendedValidation.h"
|
||||
#include "NSSCertDBTrustDomain.h"
|
||||
#include "PKCS11ModuleDB.h"
|
||||
#include "SSLTokensCache.h"
|
||||
#include "ScopedNSSTypes.h"
|
||||
#include "SharedSSLState.h"
|
||||
@ -610,7 +611,7 @@ void AsyncLoadOrUnloadOSClientCertsModule(bool load) {
|
||||
Unused << task->Dispatch();
|
||||
} else {
|
||||
UniqueSECMODModule osClientCertsModule(
|
||||
SECMOD_FindModule(kOSClientCertsModuleName));
|
||||
SECMOD_FindModule(kOSClientCertsModuleName.get()));
|
||||
if (osClientCertsModule) {
|
||||
SECMOD_UnloadUserModule(osClientCertsModule.get());
|
||||
}
|
||||
|
@ -44,7 +44,6 @@
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsISocketProvider.h"
|
||||
#include "nsIWebProgressListener.h"
|
||||
#include "nsNSSCertHelper.h"
|
||||
#include "nsNSSComponent.h"
|
||||
#include "nsNSSHelper.h"
|
||||
#include "nsPrintfCString.h"
|
||||
|
@ -6,6 +6,7 @@
|
||||
|
||||
#include <string.h>
|
||||
|
||||
#include "PKCS11ModuleDB.h"
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/Logging.h"
|
||||
#include "mozilla/Telemetry.h"
|
||||
@ -20,6 +21,7 @@
|
||||
#include "secmod.h"
|
||||
|
||||
using mozilla::LogLevel;
|
||||
using namespace mozilla::psm;
|
||||
|
||||
extern mozilla::LazyLogModule gPIPNSSLog;
|
||||
|
||||
@ -213,8 +215,10 @@ nsPKCS11Module::nsPKCS11Module(SECMODModule* module) {
|
||||
static nsresult NormalizeModuleNameOut(const char* moduleNameIn,
|
||||
nsACString& moduleNameOut) {
|
||||
// Easy case: this isn't the builtin roots module.
|
||||
if (strnlen(moduleNameIn, kRootModuleNameLen + 1) != kRootModuleNameLen ||
|
||||
strncmp(kRootModuleName, moduleNameIn, kRootModuleNameLen) != 0) {
|
||||
if (strnlen(moduleNameIn, kRootModuleName.Length() + 1) !=
|
||||
kRootModuleName.Length() ||
|
||||
strncmp(kRootModuleName.get(), moduleNameIn, kRootModuleName.Length()) !=
|
||||
0) {
|
||||
moduleNameOut.Assign(moduleNameIn);
|
||||
return NS_OK;
|
||||
}
|
||||
|
@ -13,7 +13,15 @@ const gModuleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(
|
||||
Ci.nsIPKCS11ModuleDB
|
||||
);
|
||||
|
||||
function run_test() {
|
||||
add_task(async function test_pkcs11_module() {
|
||||
Services.fog.initializeFOG();
|
||||
|
||||
equal(
|
||||
0,
|
||||
await Glean.pkcs11.thirdPartyModulesLoaded.testGetValue(),
|
||||
"should have no third-party modules to begin with"
|
||||
);
|
||||
|
||||
// Check that if we have never added the test module, that we don't find it
|
||||
// in the module list.
|
||||
checkPKCS11ModuleNotPresent("PKCS11 Test Module", "pkcs11testmodule");
|
||||
@ -23,6 +31,11 @@ function run_test() {
|
||||
libraryFile.append("pkcs11testmodule");
|
||||
libraryFile.append(ctypes.libraryName("pkcs11testmodule"));
|
||||
loadPKCS11Module(libraryFile, "PKCS11 Test Module", true);
|
||||
equal(
|
||||
1,
|
||||
await Glean.pkcs11.thirdPartyModulesLoaded.testGetValue(),
|
||||
"should have one third-party module after loading it"
|
||||
);
|
||||
let testModule = checkPKCS11ModuleExists(
|
||||
"PKCS11 Test Module",
|
||||
"pkcs11testmodule"
|
||||
@ -50,9 +63,14 @@ function run_test() {
|
||||
Ci.nsIPKCS11ModuleDB
|
||||
);
|
||||
pkcs11ModuleDB.deleteModule("PKCS11 Test Module");
|
||||
equal(
|
||||
0,
|
||||
await Glean.pkcs11.thirdPartyModulesLoaded.testGetValue(),
|
||||
"should have no third-party modules after unloading it"
|
||||
);
|
||||
checkPKCS11ModuleNotPresent("PKCS11 Test Module", "pkcs11testmodule");
|
||||
|
||||
// Check miscellaneous module DB methods and attributes.
|
||||
ok(!gModuleDB.canToggleFIPS, "It should NOT be possible to toggle FIPS");
|
||||
ok(!gModuleDB.isFIPSEnabled, "FIPS should not be enabled");
|
||||
}
|
||||
});
|
||||
|
Loading…
Reference in New Issue
Block a user