diff options
Diffstat (limited to 'security/nss/lib/pk11wrap/pk11load.c')
-rw-r--r-- | security/nss/lib/pk11wrap/pk11load.c | 71 |
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; |