Bug 1937808 - Export OSClientCerts in libxul instead of shared library r=keeler,glandium
Differential Revision: https://phabricator.services.mozilla.com/D230412
This commit is contained in:
5
Cargo.lock
generated
5
Cargo.lock
generated
@@ -2457,6 +2457,7 @@ dependencies = [
|
|||||||
"nsstring",
|
"nsstring",
|
||||||
"oblivious_http",
|
"oblivious_http",
|
||||||
"origin-trials-ffi",
|
"origin-trials-ffi",
|
||||||
|
"osclientcerts",
|
||||||
"oxilangtag",
|
"oxilangtag",
|
||||||
"oxilangtag-ffi",
|
"oxilangtag-ffi",
|
||||||
"prefs_parser",
|
"prefs_parser",
|
||||||
@@ -4839,7 +4840,7 @@ dependencies = [
|
|||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "osclientcerts-static"
|
name = "osclientcerts"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"byteorder",
|
"byteorder",
|
||||||
@@ -4848,10 +4849,10 @@ dependencies = [
|
|||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libloading",
|
"libloading",
|
||||||
"log",
|
"log",
|
||||||
"mozilla-central-workspace-hack",
|
|
||||||
"pkcs11-bindings",
|
"pkcs11-bindings",
|
||||||
"rsclientcerts",
|
"rsclientcerts",
|
||||||
"sha2",
|
"sha2",
|
||||||
|
"static_prefs",
|
||||||
"winapi",
|
"winapi",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|||||||
@@ -359,14 +359,6 @@ bin/libfreebl_64int_3.so
|
|||||||
@RESPATH@/chrome/pippki@JAREXT@
|
@RESPATH@/chrome/pippki@JAREXT@
|
||||||
@RESPATH@/chrome/pippki.manifest
|
@RESPATH@/chrome/pippki.manifest
|
||||||
|
|
||||||
; preprocessor.py doesn't handle parentheses, so while the following could be
|
|
||||||
; expressed in a single line, it's more clear to break them up.
|
|
||||||
#if defined(XP_WIN) || defined(XP_MACOSX)
|
|
||||||
#if !defined(_ARM64_)
|
|
||||||
@BINPATH@/@DLL_PREFIX@osclientcerts@DLL_SUFFIX@
|
|
||||||
#endif
|
|
||||||
#endif
|
|
||||||
|
|
||||||
@BINPATH@/@DLL_PREFIX@ipcclientcerts@DLL_SUFFIX@
|
@BINPATH@/@DLL_PREFIX@ipcclientcerts@DLL_SUFFIX@
|
||||||
|
|
||||||
; For process sandboxing
|
; For process sandboxing
|
||||||
|
|||||||
@@ -274,5 +274,4 @@ jsrust = ["dep:allocator-api2", "dep:arrayvec", "dep:byteorder", "dep:cc", "dep:
|
|||||||
minidump-analyzer-export = ["dep:allocator-api2", "dep:arrayvec", "dep:bitflags", "dep:byteorder", "dep:clap", "dep:env_logger", "dep:futures-channel", "dep:futures-core", "dep:futures-executor", "dep:futures-sink", "dep:futures-util", "dep:getrandom", "dep:hashbrown", "dep:hex", "dep:indexmap", "dep:log", "dep:memchr", "dep:nom", "dep:num-traits", "dep:object", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:time", "dep:time-macros", "dep:tracing", "dep:uuid", "dep:windows-sys", "dep:zerocopy"]
|
minidump-analyzer-export = ["dep:allocator-api2", "dep:arrayvec", "dep:bitflags", "dep:byteorder", "dep:clap", "dep:env_logger", "dep:futures-channel", "dep:futures-core", "dep:futures-executor", "dep:futures-sink", "dep:futures-util", "dep:getrandom", "dep:hashbrown", "dep:hex", "dep:indexmap", "dep:log", "dep:memchr", "dep:nom", "dep:num-traits", "dep:object", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:time", "dep:time-macros", "dep:tracing", "dep:uuid", "dep:windows-sys", "dep:zerocopy"]
|
||||||
mozwer_s = ["dep:allocator-api2", "dep:byteorder", "dep:getrandom", "dep:hashbrown", "dep:indexmap", "dep:log", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:uuid", "dep:windows-sys", "dep:zerocopy"]
|
mozwer_s = ["dep:allocator-api2", "dep:byteorder", "dep:getrandom", "dep:hashbrown", "dep:indexmap", "dep:log", "dep:once_cell", "dep:scroll", "dep:serde_json", "dep:uuid", "dep:windows-sys", "dep:zerocopy"]
|
||||||
nmhproxy = ["dep:allocator-api2", "dep:bitflags", "dep:byteorder", "dep:form_urlencoded", "dep:hashbrown", "dep:icu_locid", "dep:icu_properties", "dep:idna", "dep:indexmap", "dep:once_cell", "dep:percent-encoding", "dep:serde_json", "dep:smallvec", "dep:stable_deref_trait", "dep:tinystr", "dep:unicode-bidi", "dep:url", "dep:windows-sys", "dep:yoke", "dep:zerocopy", "dep:zerofrom", "dep:zerovec"]
|
nmhproxy = ["dep:allocator-api2", "dep:bitflags", "dep:byteorder", "dep:form_urlencoded", "dep:hashbrown", "dep:icu_locid", "dep:icu_properties", "dep:idna", "dep:indexmap", "dep:once_cell", "dep:percent-encoding", "dep:serde_json", "dep:smallvec", "dep:stable_deref_trait", "dep:tinystr", "dep:unicode-bidi", "dep:url", "dep:windows-sys", "dep:yoke", "dep:zerocopy", "dep:zerofrom", "dep:zerovec"]
|
||||||
osclientcerts-static = ["dep:bindgen", "dep:bitflags", "dep:byteorder", "dep:core-foundation-sys", "dep:env_logger", "dep:itertools", "dep:log", "dep:memchr", "dep:nom", "dep:regex"]
|
|
||||||
test-builtins-static = ["dep:bindgen", "dep:bitflags", "dep:itertools", "dep:memchr", "dep:nom", "dep:regex", "dep:smallvec"]
|
test-builtins-static = ["dep:bindgen", "dep:bitflags", "dep:itertools", "dep:memchr", "dep:nom", "dep:regex", "dep:smallvec"]
|
||||||
|
|||||||
@@ -16094,6 +16094,7 @@
|
|||||||
type: RelaxedAtomicBool
|
type: RelaxedAtomicBool
|
||||||
value: true
|
value: true
|
||||||
mirror: always
|
mirror: always
|
||||||
|
rust: true
|
||||||
|
|
||||||
- name: security.pki.cert_short_lifetime_in_days
|
- name: security.pki.cert_short_lifetime_in_days
|
||||||
type: RelaxedAtomicUint32
|
type: RelaxedAtomicUint32
|
||||||
|
|||||||
@@ -1789,6 +1789,27 @@ bool LoadUserModuleAt(const char* moduleName, const char* libraryName,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool LoadUserModuleFromXul(const char* moduleName,
|
||||||
|
CK_C_GetFunctionList fentry) {
|
||||||
|
// If a module exists with the same name, make a best effort attempt to delete
|
||||||
|
// it. Note that it isn't possible to delete the internal module, so checking
|
||||||
|
// the return value would be detrimental in that case.
|
||||||
|
int unusedModType;
|
||||||
|
Unused << SECMOD_DeleteModule(moduleName, &unusedModType);
|
||||||
|
|
||||||
|
UniqueSECMODModule userModule(
|
||||||
|
SECMOD_LoadUserModuleWithFunction(moduleName, fentry));
|
||||||
|
if (!userModule) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!userModule->loaded) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool LoadIPCClientCertsModule(const nsCString& dir) {
|
bool LoadIPCClientCertsModule(const nsCString& dir) {
|
||||||
// The IPC client certs module needs to be able to call back into gecko to be
|
// 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
|
// able to communicate with the parent process over IPC. This is achieved by
|
||||||
@@ -1812,13 +1833,24 @@ bool LoadIPCClientCertsModule(const nsCString& dir) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadOSClientCertsModule(const nsCString& dir) {
|
extern "C" {
|
||||||
nsLiteralCString params =
|
// Extern function to call osclientcerts module C_GetFunctionList.
|
||||||
StaticPrefs::security_osclientcerts_assume_rsa_pss_support()
|
// NSS calls it to obtain the list of functions comprising this module.
|
||||||
? "RSA-PSS"_ns
|
// ppFunctionList must be a valid pointer.
|
||||||
: ""_ns;
|
CK_RV OSClientCerts_C_GetFunctionList(CK_FUNCTION_LIST_PTR_PTR ppFunctionList);
|
||||||
return LoadUserModuleAt(kOSClientCertsModuleName.get(), "osclientcerts", dir,
|
} // extern "C"
|
||||||
params.get());
|
|
||||||
|
bool LoadOSClientCertsModule() {
|
||||||
|
// Corresponds to Rust cfg(any(
|
||||||
|
// target_os = "macos",
|
||||||
|
// target_os = "ios",
|
||||||
|
// all(target_os = "windows", not(target_arch = "aarch64"))))]
|
||||||
|
#if defined(__APPLE__) || (defined WIN32 && !defined(__aarch64__))
|
||||||
|
return LoadUserModuleFromXul(kOSClientCertsModuleName.get(),
|
||||||
|
OSClientCerts_C_GetFunctionList);
|
||||||
|
#else
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
bool LoadLoadableRoots(const nsCString& dir) {
|
bool LoadLoadableRoots(const nsCString& dir) {
|
||||||
|
|||||||
@@ -80,12 +80,9 @@ bool LoadLoadableRoots(const nsCString& dir);
|
|||||||
/**
|
/**
|
||||||
* Loads the OS client certs module.
|
* Loads the OS client certs module.
|
||||||
*
|
*
|
||||||
* @param dir
|
|
||||||
* The path to the directory containing the module. This should be the
|
|
||||||
* same as where all of the other gecko libraries live.
|
|
||||||
* @return true if the module was successfully loaded, false otherwise.
|
* @return true if the module was successfully loaded, false otherwise.
|
||||||
*/
|
*/
|
||||||
bool LoadOSClientCertsModule(const nsCString& dir);
|
bool LoadOSClientCertsModule();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Loads the IPC client certs module.
|
* Loads the IPC client certs module.
|
||||||
|
|||||||
@@ -4,14 +4,6 @@
|
|||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
||||||
|
|
||||||
# osclientcerts is currently only implemented for Windows
|
|
||||||
# osclientcerts transitively depends on winapi 0.2.8, which doesn't work with
|
|
||||||
# AArch64
|
|
||||||
if (CONFIG["OS_ARCH"] == "WINNT" and CONFIG["TARGET_CPU"] != "aarch64") or CONFIG[
|
|
||||||
"OS_ARCH"
|
|
||||||
] == "Darwin":
|
|
||||||
DIRS += ["osclientcerts"]
|
|
||||||
|
|
||||||
DIRS += ["ipcclientcerts"]
|
DIRS += ["ipcclientcerts"]
|
||||||
DIRS += ["builtins"]
|
DIRS += ["builtins"]
|
||||||
|
|
||||||
@@ -177,16 +169,11 @@ if CONFIG["TARGET_KERNEL"] == "Darwin":
|
|||||||
"OSReauthenticatorDarwin.mm",
|
"OSReauthenticatorDarwin.mm",
|
||||||
]
|
]
|
||||||
OS_LIBS += [
|
OS_LIBS += [
|
||||||
|
"-framework CoreFoundation",
|
||||||
"-framework LocalAuthentication",
|
"-framework LocalAuthentication",
|
||||||
"-framework Security",
|
"-framework Security",
|
||||||
]
|
]
|
||||||
|
|
||||||
if CONFIG["OS_ARCH"] == "WINNT":
|
|
||||||
OS_LIBS += ["credui"]
|
|
||||||
UNIFIED_SOURCES += [
|
|
||||||
"CredentialManagerSecret.cpp",
|
|
||||||
]
|
|
||||||
|
|
||||||
IPDL_SOURCES += [
|
IPDL_SOURCES += [
|
||||||
"PIPCClientCerts.ipdl",
|
"PIPCClientCerts.ipdl",
|
||||||
"PSelectTLSClientAuthCert.ipdl",
|
"PSelectTLSClientAuthCert.ipdl",
|
||||||
@@ -194,6 +181,31 @@ IPDL_SOURCES += [
|
|||||||
"PVerifySSLServerCert.ipdl",
|
"PVerifySSLServerCert.ipdl",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
# Required by OSClientCerts and CredentialManagerSecret.
|
||||||
|
if CONFIG["OS_ARCH"] == "WINNT":
|
||||||
|
OS_LIBS += [
|
||||||
|
"advapi32",
|
||||||
|
"credui",
|
||||||
|
"crypt32",
|
||||||
|
"kernel32",
|
||||||
|
"ncrypt",
|
||||||
|
"userenv",
|
||||||
|
"ws2_32",
|
||||||
|
"ntdll",
|
||||||
|
]
|
||||||
|
|
||||||
|
UNIFIED_SOURCES += [
|
||||||
|
"CredentialManagerSecret.cpp",
|
||||||
|
]
|
||||||
|
# Version string comparison is generally wrong, but by the time it would
|
||||||
|
# actually matter, either bug 1489995 would be fixed, or the build would
|
||||||
|
# require version >= 1.78.
|
||||||
|
if CONFIG["RUSTC_VERSION"] and CONFIG["RUSTC_VERSION"] >= "1.78.0":
|
||||||
|
OS_LIBS += [
|
||||||
|
"synchronization",
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
FINAL_LIBRARY = "xul"
|
FINAL_LIBRARY = "xul"
|
||||||
|
|
||||||
LOCAL_INCLUDES += [
|
LOCAL_INCLUDES += [
|
||||||
|
|||||||
@@ -482,14 +482,12 @@ class LoadLoadableCertsTask final : public Runnable {
|
|||||||
public:
|
public:
|
||||||
LoadLoadableCertsTask(nsNSSComponent* nssComponent,
|
LoadLoadableCertsTask(nsNSSComponent* nssComponent,
|
||||||
bool importEnterpriseRoots,
|
bool importEnterpriseRoots,
|
||||||
Vector<nsCString>&& possibleLoadableRootsLocations,
|
Vector<nsCString>&& possibleLoadableRootsLocations)
|
||||||
Maybe<nsCString>&& osClientCertsModuleLocation)
|
|
||||||
: Runnable("LoadLoadableCertsTask"),
|
: Runnable("LoadLoadableCertsTask"),
|
||||||
mNSSComponent(nssComponent),
|
mNSSComponent(nssComponent),
|
||||||
mImportEnterpriseRoots(importEnterpriseRoots),
|
mImportEnterpriseRoots(importEnterpriseRoots),
|
||||||
mPossibleLoadableRootsLocations(
|
mPossibleLoadableRootsLocations(
|
||||||
std::move(possibleLoadableRootsLocations)),
|
std::move(possibleLoadableRootsLocations)) {
|
||||||
mOSClientCertsModuleLocation(std::move(osClientCertsModuleLocation)) {
|
|
||||||
MOZ_ASSERT(nssComponent);
|
MOZ_ASSERT(nssComponent);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -503,7 +501,6 @@ class LoadLoadableCertsTask final : public Runnable {
|
|||||||
RefPtr<nsNSSComponent> mNSSComponent;
|
RefPtr<nsNSSComponent> mNSSComponent;
|
||||||
bool mImportEnterpriseRoots;
|
bool mImportEnterpriseRoots;
|
||||||
Vector<nsCString> mPossibleLoadableRootsLocations; // encoded in UTF-8
|
Vector<nsCString> mPossibleLoadableRootsLocations; // encoded in UTF-8
|
||||||
Maybe<nsCString> mOSClientCertsModuleLocation; // encoded in UTF-8
|
|
||||||
};
|
};
|
||||||
|
|
||||||
nsresult LoadLoadableCertsTask::Dispatch() {
|
nsresult LoadLoadableCertsTask::Dispatch() {
|
||||||
@@ -545,12 +542,14 @@ LoadLoadableCertsTask::Run() {
|
|||||||
mNSSComponent->ImportEnterpriseRoots();
|
mNSSComponent->ImportEnterpriseRoots();
|
||||||
mNSSComponent->UpdateCertVerifierWithEnterpriseRoots();
|
mNSSComponent->UpdateCertVerifierWithEnterpriseRoots();
|
||||||
}
|
}
|
||||||
if (mOSClientCertsModuleLocation.isSome()) {
|
|
||||||
bool success = LoadOSClientCertsModule(*mOSClientCertsModuleLocation);
|
if (StaticPrefs::security_osclientcerts_autoload()) {
|
||||||
|
bool success = LoadOSClientCertsModule();
|
||||||
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
MOZ_LOG(gPIPNSSLog, LogLevel::Debug,
|
||||||
("loading OS client certs module %s",
|
("loading OS client certs module %s",
|
||||||
success ? "succeeded" : "failed"));
|
success ? "succeeded" : "failed"));
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
MonitorAutoLock rootsLoadedLock(mNSSComponent->mLoadableCertsLoadedMonitor);
|
MonitorAutoLock rootsLoadedLock(mNSSComponent->mLoadableCertsLoadedMonitor);
|
||||||
mNSSComponent->mLoadableCertsLoaded = true;
|
mNSSComponent->mLoadableCertsLoaded = true;
|
||||||
@@ -590,12 +589,11 @@ static nsresult GetDirectoryPath(const char* directoryKey, nsCString& result) {
|
|||||||
|
|
||||||
class BackgroundLoadOSClientCertsModuleTask final : public CryptoTask {
|
class BackgroundLoadOSClientCertsModuleTask final : public CryptoTask {
|
||||||
public:
|
public:
|
||||||
explicit BackgroundLoadOSClientCertsModuleTask(const nsCString&& libraryDir)
|
explicit BackgroundLoadOSClientCertsModuleTask() {}
|
||||||
: mLibraryDir(std::move(libraryDir)) {}
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
virtual nsresult CalculateResult() override {
|
virtual nsresult CalculateResult() override {
|
||||||
bool success = LoadOSClientCertsModule(mLibraryDir);
|
bool success = LoadOSClientCertsModule();
|
||||||
return success ? NS_OK : NS_ERROR_FAILURE;
|
return success ? NS_OK : NS_ERROR_FAILURE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -610,19 +608,12 @@ class BackgroundLoadOSClientCertsModuleTask final : public CryptoTask {
|
|||||||
nullptr, "psm:load-os-client-certs-module-task-ran", nullptr);
|
nullptr, "psm:load-os-client-certs-module-task-ran", nullptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsCString mLibraryDir;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
void AsyncLoadOrUnloadOSClientCertsModule(bool load) {
|
void AsyncLoadOrUnloadOSClientCertsModule(bool load) {
|
||||||
if (load) {
|
if (load) {
|
||||||
nsCString libraryDir;
|
|
||||||
nsresult rv = GetDirectoryPath(NS_GRE_BIN_DIR, libraryDir);
|
|
||||||
if (NS_FAILED(rv)) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
RefPtr<BackgroundLoadOSClientCertsModuleTask> task =
|
RefPtr<BackgroundLoadOSClientCertsModuleTask> task =
|
||||||
new BackgroundLoadOSClientCertsModuleTask(std::move(libraryDir));
|
new BackgroundLoadOSClientCertsModuleTask();
|
||||||
Unused << task->Dispatch();
|
Unused << task->Dispatch();
|
||||||
} else {
|
} else {
|
||||||
UniqueSECMODModule osClientCertsModule(
|
UniqueSECMODModule osClientCertsModule(
|
||||||
@@ -1660,19 +1651,9 @@ nsresult nsNSSComponent::InitializeNSS() {
|
|||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool loadOSClientCertsModule =
|
|
||||||
StaticPrefs::security_osclientcerts_autoload();
|
|
||||||
Maybe<nsCString> maybeOSClientCertsModuleLocation;
|
|
||||||
if (loadOSClientCertsModule) {
|
|
||||||
nsAutoCString libraryDir;
|
|
||||||
if (NS_SUCCEEDED(GetDirectoryPath(NS_GRE_BIN_DIR, libraryDir))) {
|
|
||||||
maybeOSClientCertsModuleLocation.emplace(libraryDir);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
RefPtr<LoadLoadableCertsTask> loadLoadableCertsTask(
|
RefPtr<LoadLoadableCertsTask> loadLoadableCertsTask(
|
||||||
new LoadLoadableCertsTask(this, importEnterpriseRoots,
|
new LoadLoadableCertsTask(this, importEnterpriseRoots,
|
||||||
std::move(possibleLoadableRootsLocations),
|
std::move(possibleLoadableRootsLocations)));
|
||||||
std::move(maybeOSClientCertsModuleLocation)));
|
|
||||||
rv = loadLoadableCertsTask->Dispatch();
|
rv = loadLoadableCertsTask->Dispatch();
|
||||||
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
MOZ_DIAGNOSTIC_ASSERT(NS_SUCCEEDED(rv));
|
||||||
if (NS_FAILED(rv)) {
|
if (NS_FAILED(rv)) {
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "osclientcerts-static"
|
name = "osclientcerts"
|
||||||
version = "0.1.4"
|
version = "0.1.4"
|
||||||
authors = ["Dana Keeler <dkeeler@mozilla.com>"]
|
authors = ["Dana Keeler <dkeeler@mozilla.com>"]
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
description = "Platform-specific support for client authentication certificates in Firefox"
|
description = "Platform-specific support for client authentication certificates in Firefox"
|
||||||
repository = "https://github.com/mozkeeler/osclientcerts"
|
|
||||||
license = "MPL-2.0"
|
license = "MPL-2.0"
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
@@ -12,11 +11,11 @@ byteorder = "1.3"
|
|||||||
env_logger = {version = "0.10", default-features = false } # disable `regex` to reduce code size
|
env_logger = {version = "0.10", default-features = false } # disable `regex` to reduce code size
|
||||||
lazy_static = "1"
|
lazy_static = "1"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mozilla-central-workspace-hack = { version = "0.1", features = ["osclientcerts-static"], optional = true }
|
|
||||||
|
|
||||||
pkcs11-bindings = "0.1"
|
pkcs11-bindings = "0.1"
|
||||||
rsclientcerts = { path = "../rsclientcerts" }
|
rsclientcerts = { path = "../rsclientcerts" }
|
||||||
sha2 = "0.10.2"
|
sha2 = "0.10.2"
|
||||||
|
static_prefs = { path = "../../../../modules/libpref/init/static_prefs"}
|
||||||
|
|
||||||
[target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies.core-foundation]
|
[target."cfg(any(target_os = \"macos\", target_os = \"ios\"))".dependencies.core-foundation]
|
||||||
version = "0.9"
|
version = "0.9"
|
||||||
@@ -27,6 +26,3 @@ version = "0.8"
|
|||||||
[target."cfg(target_os = \"windows\")".dependencies.winapi]
|
[target."cfg(target_os = \"windows\")".dependencies.winapi]
|
||||||
version = "0.3"
|
version = "0.3"
|
||||||
features = ["errhandlingapi", "wincrypt"]
|
features = ["errhandlingapi", "wincrypt"]
|
||||||
|
|
||||||
[lib]
|
|
||||||
crate-type = ["staticlib"]
|
|
||||||
|
|||||||
@@ -1,40 +0,0 @@
|
|||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
USE_LIBS += ["osclientcerts-static"]
|
|
||||||
|
|
||||||
UNIFIED_SOURCES += [
|
|
||||||
"stub.cpp",
|
|
||||||
]
|
|
||||||
|
|
||||||
if CONFIG["OS_ARCH"] == "WINNT":
|
|
||||||
OS_LIBS += [
|
|
||||||
"advapi32",
|
|
||||||
"crypt32",
|
|
||||||
"kernel32",
|
|
||||||
"ncrypt",
|
|
||||||
"userenv",
|
|
||||||
"ws2_32",
|
|
||||||
"ntdll",
|
|
||||||
]
|
|
||||||
# Version string comparison is generally wrong, but by the time it would
|
|
||||||
# actually matter, either bug 1489995 would be fixed, or the build would
|
|
||||||
# require version >= 1.78.
|
|
||||||
if CONFIG["RUSTC_VERSION"] and CONFIG["RUSTC_VERSION"] >= "1.78.0":
|
|
||||||
OS_LIBS += [
|
|
||||||
"synchronization",
|
|
||||||
]
|
|
||||||
|
|
||||||
if CONFIG["OS_ARCH"] == "Darwin":
|
|
||||||
OS_LIBS += [
|
|
||||||
"-framework CoreFoundation",
|
|
||||||
"-framework Security",
|
|
||||||
]
|
|
||||||
|
|
||||||
SharedLibrary("osclientcerts")
|
|
||||||
|
|
||||||
NoVisibilityFlags()
|
|
||||||
SYMBOLS_FILE = "osclientcerts.symbols"
|
|
||||||
@@ -1 +0,0 @@
|
|||||||
C_GetFunctionList
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
||||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
||||||
|
|
||||||
// This is an intentionally empty file. It is necessary for the build system to
|
|
||||||
// successfully convert a static rust library into a dynamic library on
|
|
||||||
// Windows.
|
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
|
|
||||||
# vim: set filetype=python:
|
|
||||||
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
||||||
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
||||||
# file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
||||||
|
|
||||||
DIRS += ["dynamic-library"]
|
|
||||||
|
|
||||||
RustLibrary("osclientcerts-static")
|
|
||||||
@@ -21,23 +21,22 @@ extern crate pkcs11_bindings;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate rsclientcerts;
|
extern crate rsclientcerts;
|
||||||
extern crate sha2;
|
extern crate sha2;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(all(target_os = "windows", not(target_arch = "aarch64")))]
|
||||||
extern crate winapi;
|
extern crate winapi;
|
||||||
|
|
||||||
use pkcs11_bindings::*;
|
use pkcs11_bindings::*;
|
||||||
use rsclientcerts::manager::{ManagerProxy, SlotType};
|
use rsclientcerts::manager::{ManagerProxy, SlotType};
|
||||||
use std::ffi::CStr;
|
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
mod backend_macos;
|
mod backend_macos;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(all(target_os = "windows", not(target_arch = "aarch64")))]
|
||||||
mod backend_windows;
|
mod backend_windows;
|
||||||
|
|
||||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
||||||
use crate::backend_macos::Backend;
|
use crate::backend_macos::Backend;
|
||||||
#[cfg(target_os = "windows")]
|
#[cfg(all(target_os = "windows", not(target_arch = "aarch64")))]
|
||||||
use crate::backend_windows::Backend;
|
use crate::backend_windows::Backend;
|
||||||
|
|
||||||
struct ModuleState {
|
struct ModuleState {
|
||||||
@@ -108,24 +107,12 @@ macro_rules! log_with_thread_id {
|
|||||||
|
|
||||||
/// This gets called to initialize the module. For this implementation, this consists of
|
/// This gets called to initialize the module. For this implementation, this consists of
|
||||||
/// instantiating the `ManagerProxy`.
|
/// instantiating the `ManagerProxy`.
|
||||||
extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV {
|
extern "C" fn C_Initialize(_pInitArgs: CK_VOID_PTR) -> CK_RV {
|
||||||
// This will fail if this has already been called, but this isn't a problem because either way,
|
// This will fail if this has already been called, but this isn't a problem because either way,
|
||||||
// logging has been initialized.
|
// logging has been initialized.
|
||||||
let _ = env_logger::try_init();
|
let _ = env_logger::try_init();
|
||||||
|
|
||||||
if pInitArgs.is_null() {
|
let mechanisms = if static_prefs::pref!("security.osclientcerts.assume_rsa_pss_support") {
|
||||||
return CKR_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
let init_args_ptr = unsafe { (*(pInitArgs as CK_C_INITIALIZE_ARGS_PTR)).pReserved };
|
|
||||||
if init_args_ptr.is_null() {
|
|
||||||
return CKR_DEVICE_ERROR;
|
|
||||||
}
|
|
||||||
let init_args_cstr = unsafe { CStr::from_ptr(init_args_ptr as *mut std::os::raw::c_char) };
|
|
||||||
let init_args = match init_args_cstr.to_str() {
|
|
||||||
Ok(init_args) => init_args,
|
|
||||||
Err(_) => return CKR_DEVICE_ERROR,
|
|
||||||
};
|
|
||||||
let mechanisms = if init_args == "RSA-PSS" {
|
|
||||||
vec![CKM_ECDSA, CKM_RSA_PKCS, CKM_RSA_PKCS_PSS]
|
vec![CKM_ECDSA, CKM_RSA_PKCS, CKM_RSA_PKCS_PSS]
|
||||||
} else {
|
} else {
|
||||||
vec![CKM_ECDSA, CKM_RSA_PKCS]
|
vec![CKM_ECDSA, CKM_RSA_PKCS]
|
||||||
@@ -143,17 +130,10 @@ extern "C" fn C_Initialize(pInitArgs: CK_VOID_PTR) -> CK_RV {
|
|||||||
mechanisms,
|
mechanisms,
|
||||||
}) {
|
}) {
|
||||||
Some(_unexpected_previous_module_state) => {
|
Some(_unexpected_previous_module_state) => {
|
||||||
#[cfg(any(target_os = "macos", target_os = "ios"))]
|
log_with_thread_id!(
|
||||||
{
|
warn,
|
||||||
log_with_thread_id!(info, "C_Initialize: module state previously set (this is expected on macOS - replacing it)");
|
"C_Initialize: replacing previously set module state (this is expected on macOS but not on Windows)"
|
||||||
}
|
);
|
||||||
#[cfg(target_os = "windows")]
|
|
||||||
{
|
|
||||||
log_with_thread_id!(
|
|
||||||
warn,
|
|
||||||
"C_Initialize: module state unexpectedly previously set (replacing it)"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => {}
|
None => {}
|
||||||
}
|
}
|
||||||
@@ -1247,7 +1227,9 @@ static FUNCTION_LIST: CK_FUNCTION_LIST = CK_FUNCTION_LIST {
|
|||||||
/// comprising this module.
|
/// comprising this module.
|
||||||
/// ppFunctionList must be a valid pointer.
|
/// ppFunctionList must be a valid pointer.
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub unsafe extern "C" fn C_GetFunctionList(ppFunctionList: CK_FUNCTION_LIST_PTR_PTR) -> CK_RV {
|
pub unsafe extern "C" fn OSClientCerts_C_GetFunctionList(
|
||||||
|
ppFunctionList: CK_FUNCTION_LIST_PTR_PTR,
|
||||||
|
) -> CK_RV {
|
||||||
if ppFunctionList.is_null() {
|
if ppFunctionList.is_null() {
|
||||||
return CKR_ARGUMENTS_BAD;
|
return CKR_ARGUMENTS_BAD;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1108,7 +1108,7 @@ function writeLinesAndClose(lines, outputStream) {
|
|||||||
* A unique substring of name of the dynamic library file of the module
|
* A unique substring of name of the dynamic library file of the module
|
||||||
* that should not be loaded.
|
* that should not be loaded.
|
||||||
*/
|
*/
|
||||||
function checkPKCS11ModuleNotPresent(moduleName, libraryName) {
|
function checkPKCS11ModuleNotPresent(moduleName, libraryName = "undefined") {
|
||||||
let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(
|
let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(
|
||||||
Ci.nsIPKCS11ModuleDB
|
Ci.nsIPKCS11ModuleDB
|
||||||
);
|
);
|
||||||
@@ -1123,10 +1123,12 @@ function checkPKCS11ModuleNotPresent(moduleName, libraryName) {
|
|||||||
moduleName,
|
moduleName,
|
||||||
`Non-test module name shouldn't equal '${moduleName}'`
|
`Non-test module name shouldn't equal '${moduleName}'`
|
||||||
);
|
);
|
||||||
ok(
|
if (libraryName != "undefined") {
|
||||||
!(module.libName && module.libName.includes(libraryName)),
|
ok(
|
||||||
`Non-test module lib name should not include '${libraryName}'`
|
!(module.libName && module.libName.includes(libraryName)),
|
||||||
);
|
`Non-test module lib name should not include '${libraryName}'`
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1142,7 +1144,7 @@ function checkPKCS11ModuleNotPresent(moduleName, libraryName) {
|
|||||||
* @returns {nsIPKCS11Module}
|
* @returns {nsIPKCS11Module}
|
||||||
* The test module.
|
* The test module.
|
||||||
*/
|
*/
|
||||||
function checkPKCS11ModuleExists(moduleName, libraryName) {
|
function checkPKCS11ModuleExists(moduleName, libraryName = "undefined") {
|
||||||
let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(
|
let moduleDB = Cc["@mozilla.org/security/pkcs11moduledb;1"].getService(
|
||||||
Ci.nsIPKCS11ModuleDB
|
Ci.nsIPKCS11ModuleDB
|
||||||
);
|
);
|
||||||
@@ -1159,11 +1161,17 @@ function checkPKCS11ModuleExists(moduleName, libraryName) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
notEqual(testModule, null, "Test module should have been found");
|
notEqual(testModule, null, "Test module should have been found");
|
||||||
notEqual(testModule.libName, null, "Test module lib name should not be null");
|
if (libraryName != "undefined") {
|
||||||
ok(
|
notEqual(
|
||||||
testModule.libName.includes(ctypes.libraryName(libraryName)),
|
testModule.libName,
|
||||||
`Test module lib name should include lib name of '${libraryName}'`
|
null,
|
||||||
);
|
"Test module lib name should not be null"
|
||||||
|
);
|
||||||
|
ok(
|
||||||
|
testModule.libName.includes(ctypes.libraryName(libraryName)),
|
||||||
|
`Test module lib name should include lib name of '${libraryName}'`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return testModule;
|
return testModule;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,10 +16,7 @@ const { TestUtils } = ChromeUtils.importESModule(
|
|||||||
async function check_osclientcerts_module_loaded() {
|
async function check_osclientcerts_module_loaded() {
|
||||||
// Loading happens asynchronously, so we have to wait for the notification.
|
// Loading happens asynchronously, so we have to wait for the notification.
|
||||||
await TestUtils.topicObserved("psm:load-os-client-certs-module-task-ran");
|
await TestUtils.topicObserved("psm:load-os-client-certs-module-task-ran");
|
||||||
let testModule = checkPKCS11ModuleExists(
|
let testModule = checkPKCS11ModuleExists("OS Client Cert Module");
|
||||||
"OS Client Cert Module",
|
|
||||||
"osclientcerts"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Check that listing the slots for the osclientcerts module works.
|
// Check that listing the slots for the osclientcerts module works.
|
||||||
let testModuleSlotNames = Array.from(
|
let testModuleSlotNames = Array.from(
|
||||||
@@ -38,7 +35,7 @@ async function check_osclientcerts_module_loaded() {
|
|||||||
add_task(async function run_test() {
|
add_task(async function run_test() {
|
||||||
// Check that if we haven't loaded the osclientcerts module, we don't find it
|
// Check that if we haven't loaded the osclientcerts module, we don't find it
|
||||||
// in the module list.
|
// in the module list.
|
||||||
checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts");
|
checkPKCS11ModuleNotPresent("OS Client Cert Module");
|
||||||
|
|
||||||
// Check that enabling the pref that loads the osclientcerts module makes it
|
// Check that enabling the pref that loads the osclientcerts module makes it
|
||||||
// appear in the module list.
|
// appear in the module list.
|
||||||
@@ -48,7 +45,7 @@ add_task(async function run_test() {
|
|||||||
// Check that disabling the pref that loads the osclientcerts module (thus
|
// Check that disabling the pref that loads the osclientcerts module (thus
|
||||||
// unloading the module) makes it disappear from the module list.
|
// unloading the module) makes it disappear from the module list.
|
||||||
Services.prefs.setBoolPref("security.osclientcerts.autoload", false);
|
Services.prefs.setBoolPref("security.osclientcerts.autoload", false);
|
||||||
checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts");
|
checkPKCS11ModuleNotPresent("OS Client Cert Module");
|
||||||
|
|
||||||
// Check that loading the module again succeeds.
|
// Check that loading the module again succeeds.
|
||||||
Services.prefs.setBoolPref("security.osclientcerts.autoload", true);
|
Services.prefs.setBoolPref("security.osclientcerts.autoload", true);
|
||||||
@@ -56,5 +53,5 @@ add_task(async function run_test() {
|
|||||||
|
|
||||||
// And once more check that unloading succeeds.
|
// And once more check that unloading succeeds.
|
||||||
Services.prefs.setBoolPref("security.osclientcerts.autoload", false);
|
Services.prefs.setBoolPref("security.osclientcerts.autoload", false);
|
||||||
checkPKCS11ModuleNotPresent("OS Client Cert Module", "osclientcerts");
|
checkPKCS11ModuleNotPresent("OS Client Cert Module");
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ skip-if = ["os == 'android'"]
|
|||||||
["test_osclientcerts_module.js"]
|
["test_osclientcerts_module.js"]
|
||||||
skip-if = [
|
skip-if = [
|
||||||
"os == 'linux'",
|
"os == 'linux'",
|
||||||
"os == 'android'",
|
"os == 'android'"
|
||||||
]
|
]
|
||||||
|
|
||||||
["test_pkcs11_module.js"]
|
["test_pkcs11_module.js"]
|
||||||
|
|||||||
@@ -582,6 +582,7 @@ SECMOD_GetReadLock
|
|||||||
SECMOD_InternaltoPubMechFlags
|
SECMOD_InternaltoPubMechFlags
|
||||||
SECMOD_LoadModule
|
SECMOD_LoadModule
|
||||||
SECMOD_LoadUserModule
|
SECMOD_LoadUserModule
|
||||||
|
SECMOD_LoadUserModuleWithFunction
|
||||||
SECMOD_LockedModuleHasRemovableSlots
|
SECMOD_LockedModuleHasRemovableSlots
|
||||||
SECMOD_OpenUserDB
|
SECMOD_OpenUserDB
|
||||||
SECMOD_PubCipherFlagstoInternal
|
SECMOD_PubCipherFlagstoInternal
|
||||||
|
|||||||
@@ -109,6 +109,9 @@ fallible_collections = { version = "0.4", features = ["rust_1_57"] }
|
|||||||
|
|
||||||
libz-rs-sys = { git = "https://github.com/memorysafety/zlib-rs", rev = "4aa430ccb77537d0d60dab8db993ca51bb1194c5", features = ["custom-prefix"], optional = true }
|
libz-rs-sys = { git = "https://github.com/memorysafety/zlib-rs", rev = "4aa430ccb77537d0d60dab8db993ca51bb1194c5", features = ["custom-prefix"], optional = true }
|
||||||
|
|
||||||
|
[target.'cfg(any(target_os = "macos",target_os = "ios", all(target_os = "windows", not(target_arch = "aarch64"))))'.dependencies]
|
||||||
|
osclientcerts = { path = "../../../../security/manager/ssl/osclientcerts" }
|
||||||
|
|
||||||
[target.'cfg(not(target_os = "android"))'.dependencies]
|
[target.'cfg(not(target_os = "android"))'.dependencies]
|
||||||
gkrust-uniffi-components = { path = "../../../components/uniffi-bindgen-gecko-js/components/", features = ["xpcom"] }
|
gkrust-uniffi-components = { path = "../../../components/uniffi-bindgen-gecko-js/components/", features = ["xpcom"] }
|
||||||
gkrust-uniffi-fixtures = { path = "../../../components/uniffi-bindgen-gecko-js/fixtures/", features = ["xpcom"], optional = true }
|
gkrust-uniffi-fixtures = { path = "../../../components/uniffi-bindgen-gecko-js/fixtures/", features = ["xpcom"], optional = true }
|
||||||
|
|||||||
@@ -85,6 +85,12 @@ extern crate fluent_fallback;
|
|||||||
extern crate l10nregistry_ffi;
|
extern crate l10nregistry_ffi;
|
||||||
extern crate localization_ffi;
|
extern crate localization_ffi;
|
||||||
|
|
||||||
|
#[cfg(any(
|
||||||
|
target_os = "macos",
|
||||||
|
target_os = "ios",
|
||||||
|
all(target_os = "windows", not(target_arch = "aarch64"))))]
|
||||||
|
extern crate osclientcerts;
|
||||||
|
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
extern crate gkrust_uniffi_components;
|
extern crate gkrust_uniffi_components;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user