summaryrefslogtreecommitdiffstats
path: root/security/nss/lib/pk11wrap/pk11load.c
diff options
context:
space:
mode:
Diffstat (limited to 'security/nss/lib/pk11wrap/pk11load.c')
-rw-r--r--security/nss/lib/pk11wrap/pk11load.c71
1 files changed, 52 insertions, 19 deletions
diff --git a/security/nss/lib/pk11wrap/pk11load.c b/security/nss/lib/pk11wrap/pk11load.c
index a84070103..9b941f963 100644
--- a/security/nss/lib/pk11wrap/pk11load.c
+++ b/security/nss/lib/pk11wrap/pk11load.c
@@ -275,8 +275,8 @@ secmod_ModuleInit(SECMODModule *mod, SECMODModule **reload,
}
if (crv != CKR_OK) {
if (!mod->isThreadSafe ||
- crv == CKR_NETSCAPE_CERTDB_FAILED ||
- crv == CKR_NETSCAPE_KEYDB_FAILED) {
+ crv == CKR_NSS_CERTDB_FAILED ||
+ crv == CKR_NSS_KEYDB_FAILED) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
}
@@ -380,7 +380,9 @@ softoken_LoadDSO(void)
return PR_FAILURE;
}
#else
-CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList);
+CK_RV NSC_GetInterface(CK_UTF8CHAR_PTR pInterfaceName,
+ CK_VERSION_PTR pVersion,
+ CK_INTERFACE_PTR_PTR *ppInterface, CK_FLAGS flags);
char **NSC_ModuleDBFunc(unsigned long function, char *parameters, void *args);
#endif
@@ -391,12 +393,18 @@ SECStatus
secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
{
PRLibrary *library = NULL;
- CK_C_GetFunctionList entry = NULL;
+ CK_C_GetInterface ientry = NULL;
+ CK_C_GetFunctionList fentry = NULL;
CK_INFO info;
CK_ULONG slotCount = 0;
SECStatus rv;
PRBool alreadyLoaded = PR_FALSE;
char *disableUnload = NULL;
+#ifndef NSS_STATIC_SOFTOKEN
+ const char *nss_interface;
+ const char *nss_function;
+#endif
+ CK_INTERFACE_PTR interface;
if (mod->loaded)
return SECSuccess;
@@ -404,7 +412,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/* internal modules get loaded from their internal list */
if (mod->internal && (mod->dllName == NULL)) {
#ifdef NSS_STATIC_SOFTOKEN
- entry = (CK_C_GetFunctionList)NSC_GetFunctionList;
+ ientry = (CK_C_GetInterface)NSC_GetInterface;
#else
/*
* Loads softoken as a dynamic library,
@@ -417,15 +425,22 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
PR_ATOMIC_INCREMENT(&softokenLoadCount);
if (mod->isFIPS) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "FC_GetFunctionList");
+ nss_interface = "FC_GetInterface";
+ nss_function = "FC_GetFunctionList";
} else {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(softokenLib, "NSC_GetFunctionList");
+ nss_interface = "NSC_GetInterface";
+ nss_function = "NSC_GetFunctionList";
}
- if (!entry)
- return SECFailure;
+ ientry = (CK_C_GetInterface)
+ PR_FindSymbol(softokenLib, nss_interface);
+ if (!ientry) {
+ fentry = (CK_C_GetFunctionList)
+ PR_FindSymbol(softokenLib, nss_function);
+ if (!fentry) {
+ return SECFailure;
+ }
+ }
#endif
if (mod->isModuleDB) {
@@ -461,8 +476,12 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
* now we need to get the entry point to find the function pointers
*/
if (!mod->moduleDBOnly) {
- entry = (CK_C_GetFunctionList)
- PR_FindSymbol(library, "C_GetFunctionList");
+ ientry = (CK_C_GetInterface)
+ PR_FindSymbol(library, "C_GetInterface");
+ if (!ientry) {
+ fentry = (CK_C_GetFunctionList)
+ PR_FindSymbol(library, "C_GetFunctionList");
+ }
}
if (mod->isModuleDB) {
mod->moduleDBFunc = (void *)
@@ -470,7 +489,7 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
}
if (mod->moduleDBFunc == NULL)
mod->isModuleDB = PR_FALSE;
- if (entry == NULL) {
+ if ((ientry == NULL) && (fentry == NULL)) {
if (mod->isModuleDB) {
mod->loaded = PR_TRUE;
mod->moduleDBOnly = PR_TRUE;
@@ -484,14 +503,28 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/*
* We need to get the function list
*/
- if ((*entry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
- goto fail;
+ if (ientry) {
+ /* we first try to get a FORK_SAFE interface */
+ if ((*ientry)((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface,
+ CKF_INTERFACE_FORK_SAFE) != CKR_OK) {
+ /* one is not appearantly available, get a non-fork safe version */
+ if ((*ientry)((CK_UTF8CHAR_PTR) "PKCS 11", NULL, &interface, 0) != CKR_OK) {
+ goto fail;
+ }
+ }
+ mod->functionList = interface->pFunctionList;
+ mod->flags = interface->flags;
+ } else {
+ if ((*fentry)((CK_FUNCTION_LIST_PTR *)&mod->functionList) != CKR_OK)
+ goto fail;
+ mod->flags = 0;
+ }
#ifdef DEBUG_MODULE
modToDBG = PR_GetEnvSecure("NSS_DEBUG_PKCS11_MODULE");
if (modToDBG && strcmp(mod->commonName, modToDBG) == 0) {
mod->functionList = (void *)nss_InsertDeviceLog(
- (CK_FUNCTION_LIST_PTR)mod->functionList);
+ (CK_FUNCTION_LIST_3_0_PTR)mod->functionList);
}
#endif
@@ -513,10 +546,10 @@ secmod_LoadPKCS11Module(SECMODModule *mod, SECMODModule **oldModule)
/* check the version number */
if (PK11_GETTAB(mod)->C_GetInfo(&info) != CKR_OK)
goto fail2;
- if (info.cryptokiVersion.major != 2)
+ if (info.cryptokiVersion.major < 2)
goto fail2;
/* all 2.0 are a priori *not* thread safe */
- if (info.cryptokiVersion.minor < 1) {
+ if ((info.cryptokiVersion.major == 2) && (info.cryptokiVersion.minor < 1)) {
if (!loadSingleThreadedModules) {
PORT_SetError(SEC_ERROR_INCOMPATIBLE_PKCS11);
goto fail2;