| Index: mozilla/security/nss/lib/softoken/lgglue.c
|
| ===================================================================
|
| --- mozilla/security/nss/lib/softoken/lgglue.c (revision 191424)
|
| +++ mozilla/security/nss/lib/softoken/lgglue.c (working copy)
|
| @@ -1,458 +0,0 @@
|
| -/* 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/. */
|
| -/*
|
| - * The following code handles the storage of PKCS 11 modules used by the
|
| - * NSS. This file is written to abstract away how the modules are
|
| - * stored so we can deside that later.
|
| - */
|
| -#include "sftkdb.h"
|
| -#include "sftkdbti.h"
|
| -#include "sdb.h"
|
| -#include "prsystem.h"
|
| -#include "prprf.h"
|
| -#include "prenv.h"
|
| -#include "lgglue.h"
|
| -#include "secerr.h"
|
| -#include "softoken.h"
|
| -
|
| -static LGOpenFunc legacy_glue_open = NULL;
|
| -static LGReadSecmodFunc legacy_glue_readSecmod = NULL;
|
| -static LGReleaseSecmodFunc legacy_glue_releaseSecmod = NULL;
|
| -static LGDeleteSecmodFunc legacy_glue_deleteSecmod = NULL;
|
| -static LGAddSecmodFunc legacy_glue_addSecmod = NULL;
|
| -static LGShutdownFunc legacy_glue_shutdown = NULL;
|
| -
|
| -#ifndef NSS_STATIC
|
| -/*
|
| - * The following 3 functions duplicate the work done by bl_LoadLibrary.
|
| - * We should make bl_LoadLibrary a global and replace the call to
|
| - * sftkdb_LoadLibrary(const char *libname) with it.
|
| - */
|
| -#ifdef XP_UNIX
|
| -#include <unistd.h>
|
| -#define LG_MAX_LINKS 20
|
| -static char *
|
| -sftkdb_resolvePath(const char *orig)
|
| -{
|
| - int count = 0;
|
| - int len =0;
|
| - int ret = -1;
|
| - char *resolved = NULL;
|
| - char *source = NULL;
|
| -
|
| - len = 1025; /* MAX PATH +1*/
|
| - if (strlen(orig)+1 > len) {
|
| - /* PATH TOO LONG */
|
| - return NULL;
|
| - }
|
| - resolved = PORT_Alloc(len);
|
| - if (!resolved) {
|
| - return NULL;
|
| - }
|
| - source = PORT_Alloc(len);
|
| - if (!source) {
|
| - goto loser;
|
| - }
|
| - PORT_Strcpy(source, orig);
|
| - /* Walk down all the links */
|
| - while ( count++ < LG_MAX_LINKS) {
|
| - char *tmp;
|
| - /* swap our previous sorce out with resolved */
|
| - /* read it */
|
| - ret = readlink(source, resolved, len-1);
|
| - if (ret < 0) {
|
| - break;
|
| - }
|
| - resolved[ret] = 0;
|
| - tmp = source; source = resolved; resolved = tmp;
|
| - }
|
| - if (count > 1) {
|
| - ret = 0;
|
| - }
|
| -loser:
|
| - if (resolved) {
|
| - PORT_Free(resolved);
|
| - }
|
| - if (ret < 0) {
|
| - if (source) {
|
| - PORT_Free(source);
|
| - source = NULL;
|
| - }
|
| - }
|
| - return source;
|
| -}
|
| -
|
| -#endif
|
| -
|
| -static PRLibrary *
|
| -sftkdb_LoadFromPath(const char *path, const char *libname)
|
| -{
|
| - char *c;
|
| - int pathLen, nameLen, fullPathLen;
|
| - char *fullPathName = NULL;
|
| - PRLibSpec libSpec;
|
| - PRLibrary *lib = NULL;
|
| -
|
| -
|
| - /* strip of our parent's library name */
|
| - c = strrchr(path, PR_GetDirectorySeparator());
|
| - if (!c) {
|
| - return NULL; /* invalid path */
|
| - }
|
| - pathLen = (c-path)+1;
|
| - nameLen = strlen(libname);
|
| - fullPathLen = pathLen + nameLen +1;
|
| - fullPathName = (char *)PORT_Alloc(fullPathLen);
|
| - if (fullPathName == NULL) {
|
| - return NULL; /* memory allocation error */
|
| - }
|
| - PORT_Memcpy(fullPathName, path, pathLen);
|
| - PORT_Memcpy(fullPathName+pathLen, libname, nameLen);
|
| - fullPathName[fullPathLen-1] = 0;
|
| -
|
| - libSpec.type = PR_LibSpec_Pathname;
|
| - libSpec.value.pathname = fullPathName;
|
| - lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
|
| - PORT_Free(fullPathName);
|
| - return lib;
|
| -}
|
| -
|
| -
|
| -static PRLibrary *
|
| -sftkdb_LoadLibrary(const char *libname)
|
| -{
|
| - PRLibrary *lib = NULL;
|
| - PRFuncPtr fn_addr;
|
| - char *parentLibPath = NULL;
|
| -
|
| - fn_addr = (PRFuncPtr) &sftkdb_LoadLibrary;
|
| - parentLibPath = PR_GetLibraryFilePathname(SOFTOKEN_LIB_NAME, fn_addr);
|
| -
|
| - if (!parentLibPath) {
|
| - goto done;
|
| - }
|
| -
|
| - lib = sftkdb_LoadFromPath(parentLibPath, libname);
|
| -#ifdef XP_UNIX
|
| - /* handle symbolic link case */
|
| - if (!lib) {
|
| - char *trueParentLibPath = sftkdb_resolvePath(parentLibPath);
|
| - if (!trueParentLibPath) {
|
| - goto done;
|
| - }
|
| - lib = sftkdb_LoadFromPath(trueParentLibPath, libname);
|
| - PORT_Free(trueParentLibPath);
|
| - }
|
| -#endif
|
| -
|
| -done:
|
| - if (parentLibPath) {
|
| - PORT_Free(parentLibPath);
|
| - }
|
| -
|
| - /* still couldn't load it, try the generic path */
|
| - if (!lib) {
|
| - PRLibSpec libSpec;
|
| - libSpec.type = PR_LibSpec_Pathname;
|
| - libSpec.value.pathname = libname;
|
| - lib = PR_LoadLibraryWithFlags(libSpec, PR_LD_NOW | PR_LD_LOCAL);
|
| - }
|
| -
|
| - return lib;
|
| -}
|
| -#endif /* STATIC LIBRARIES */
|
| -
|
| -/*
|
| - * stub files for legacy db's to be able to encrypt and decrypt
|
| - * various keys and attributes.
|
| - */
|
| -static SECStatus
|
| -sftkdb_encrypt_stub(PRArenaPool *arena, SDB *sdb, SECItem *plainText,
|
| - SECItem **cipherText)
|
| -{
|
| - SFTKDBHandle *handle = sdb->app_private;
|
| - SECStatus rv;
|
| -
|
| - if (handle == NULL) {
|
| - return SECFailure;
|
| - }
|
| -
|
| - /* if we aren't the key handle, try the other handle */
|
| - if (handle->type != SFTK_KEYDB_TYPE) {
|
| - handle = handle->peerDB;
|
| - }
|
| -
|
| - /* not a key handle */
|
| - if (handle == NULL || handle->passwordLock == NULL) {
|
| - return SECFailure;
|
| - }
|
| -
|
| - PZ_Lock(handle->passwordLock);
|
| - if (handle->passwordKey.data == NULL) {
|
| - PZ_Unlock(handle->passwordLock);
|
| - /* PORT_SetError */
|
| - return SECFailure;
|
| - }
|
| -
|
| - rv = sftkdb_EncryptAttribute(arena,
|
| - handle->newKey?handle->newKey:&handle->passwordKey,
|
| - plainText, cipherText);
|
| - PZ_Unlock(handle->passwordLock);
|
| -
|
| - return rv;
|
| -}
|
| -
|
| -/*
|
| - * stub files for legacy db's to be able to encrypt and decrypt
|
| - * various keys and attributes.
|
| - */
|
| -static SECStatus
|
| -sftkdb_decrypt_stub(SDB *sdb, SECItem *cipherText, SECItem **plainText)
|
| -{
|
| - SFTKDBHandle *handle = sdb->app_private;
|
| - SECStatus rv;
|
| - SECItem *oldKey = NULL;
|
| -
|
| - if (handle == NULL) {
|
| - return SECFailure;
|
| - }
|
| -
|
| - /* if we aren't th handle, try the other handle */
|
| - oldKey = handle->oldKey;
|
| - if (handle->type != SFTK_KEYDB_TYPE) {
|
| - handle = handle->peerDB;
|
| - }
|
| -
|
| - /* not a key handle */
|
| - if (handle == NULL || handle->passwordLock == NULL) {
|
| - return SECFailure;
|
| - }
|
| -
|
| - PZ_Lock(handle->passwordLock);
|
| - if (handle->passwordKey.data == NULL) {
|
| - PZ_Unlock(handle->passwordLock);
|
| - /* PORT_SetError */
|
| - return SECFailure;
|
| - }
|
| - rv = sftkdb_DecryptAttribute( oldKey ? oldKey : &handle->passwordKey,
|
| - cipherText, plainText);
|
| - PZ_Unlock(handle->passwordLock);
|
| -
|
| - return rv;
|
| -}
|
| -
|
| -static const char *LEGACY_LIB_NAME =
|
| - SHLIB_PREFIX"nssdbm"SHLIB_VERSION"."SHLIB_SUFFIX;
|
| -/*
|
| - * 2 bools to tell us if we've check the legacy library successfully or
|
| - * not. Initialize on startup to false by the C BSS segment;
|
| - */
|
| -static PRBool legacy_glue_libCheckFailed; /* set if we failed the check */
|
| -static PRBool legacy_glue_libCheckSucceeded; /* set if we passed the check */
|
| -static PRLibrary *legacy_glue_lib = NULL;
|
| -static SECStatus
|
| -sftkdbLoad_Legacy(PRBool isFIPS)
|
| -{
|
| - PRLibrary *lib = NULL;
|
| - LGSetCryptFunc setCryptFunction = NULL;
|
| -
|
| - if (legacy_glue_lib) {
|
| - /* this check is necessary because it's possible we loaded the
|
| - * legacydb to read secmod.db, which told us whether we were in
|
| - * FIPS mode or not. */
|
| - if (isFIPS && !legacy_glue_libCheckSucceeded) {
|
| - if (legacy_glue_libCheckFailed ||
|
| - !BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) {
|
| - legacy_glue_libCheckFailed = PR_TRUE;
|
| - /* don't clobber legacy glue to avoid race. just let it
|
| - * get cleared in shutdown */
|
| - return SECFailure;
|
| - }
|
| - legacy_glue_libCheckSucceeded = PR_TRUE;
|
| - }
|
| - return SECSuccess;
|
| - }
|
| -
|
| -#ifdef NSS_STATIC
|
| -#ifdef NSS_DISABLE_DBM
|
| - return SECFailure;
|
| -#else
|
| - lib = (PRLibrary *) 0x8;
|
| -
|
| - legacy_glue_open = legacy_Open;
|
| - legacy_glue_readSecmod = legacy_ReadSecmodDB;
|
| - legacy_glue_releaseSecmod = legacy_ReleaseSecmodDBData;
|
| - legacy_glue_deleteSecmod = legacy_DeleteSecmodDB;
|
| - legacy_glue_addSecmod = legacy_AddSecmodDB;
|
| - legacy_glue_shutdown = legacy_Shutdown;
|
| - setCryptFunction = legacy_SetCryptFunctions;
|
| -#endif
|
| -#else
|
| - lib = sftkdb_LoadLibrary(LEGACY_LIB_NAME);
|
| - if (lib == NULL) {
|
| - return SECFailure;
|
| - }
|
| -
|
| - legacy_glue_open = (LGOpenFunc)PR_FindFunctionSymbol(lib, "legacy_Open");
|
| - legacy_glue_readSecmod = (LGReadSecmodFunc) PR_FindFunctionSymbol(lib,
|
| - "legacy_ReadSecmodDB");
|
| - legacy_glue_releaseSecmod = (LGReleaseSecmodFunc) PR_FindFunctionSymbol(lib,
|
| - "legacy_ReleaseSecmodDBData");
|
| - legacy_glue_deleteSecmod = (LGDeleteSecmodFunc) PR_FindFunctionSymbol(lib,
|
| - "legacy_DeleteSecmodDB");
|
| - legacy_glue_addSecmod = (LGAddSecmodFunc)PR_FindFunctionSymbol(lib,
|
| - "legacy_AddSecmodDB");
|
| - legacy_glue_shutdown = (LGShutdownFunc) PR_FindFunctionSymbol(lib,
|
| - "legacy_Shutdown");
|
| - setCryptFunction = (LGSetCryptFunc) PR_FindFunctionSymbol(lib,
|
| - "legacy_SetCryptFunctions");
|
| -
|
| - if (!legacy_glue_open || !legacy_glue_readSecmod ||
|
| - !legacy_glue_releaseSecmod || !legacy_glue_deleteSecmod ||
|
| - !legacy_glue_addSecmod || !setCryptFunction) {
|
| - PR_UnloadLibrary(lib);
|
| - return SECFailure;
|
| - }
|
| -#endif /* NSS_STATIC */
|
| -
|
| - /* verify the loaded library if we are in FIPS mode */
|
| - if (isFIPS) {
|
| - if (!BLAPI_SHVerify(LEGACY_LIB_NAME,(PRFuncPtr)legacy_glue_open)) {
|
| -#ifndef NSS_STATIC
|
| - PR_UnloadLibrary(lib);
|
| -#endif
|
| - return SECFailure;
|
| - }
|
| - legacy_glue_libCheckSucceeded = PR_TRUE;
|
| - }
|
| -
|
| - setCryptFunction(sftkdb_encrypt_stub,sftkdb_decrypt_stub);
|
| - legacy_glue_lib = lib;
|
| - return SECSuccess;
|
| -}
|
| -
|
| -CK_RV
|
| -sftkdbCall_open(const char *dir, const char *certPrefix, const char *keyPrefix,
|
| - int certVersion, int keyVersion, int flags, PRBool isFIPS,
|
| - SDB **certDB, SDB **keyDB)
|
| -{
|
| - SECStatus rv;
|
| -
|
| - rv = sftkdbLoad_Legacy(isFIPS);
|
| - if (rv != SECSuccess) {
|
| - return CKR_GENERAL_ERROR;
|
| - }
|
| - if (!legacy_glue_open) {
|
| - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| - return SECFailure;
|
| - }
|
| - return (*legacy_glue_open)(dir, certPrefix, keyPrefix,
|
| - certVersion, keyVersion,
|
| - flags, certDB, keyDB);
|
| -}
|
| -
|
| -char **
|
| -sftkdbCall_ReadSecmodDB(const char *appName, const char *filename,
|
| - const char *dbname, char *params, PRBool rw)
|
| -{
|
| - SECStatus rv;
|
| -
|
| - rv = sftkdbLoad_Legacy(PR_FALSE);
|
| - if (rv != SECSuccess) {
|
| - return NULL;
|
| - }
|
| - if (!legacy_glue_readSecmod) {
|
| - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| - return NULL;
|
| - }
|
| - return (*legacy_glue_readSecmod)(appName, filename, dbname, params, rw);
|
| -}
|
| -
|
| -SECStatus
|
| -sftkdbCall_ReleaseSecmodDBData(const char *appName,
|
| - const char *filename, const char *dbname,
|
| - char **moduleSpecList, PRBool rw)
|
| -{
|
| - SECStatus rv;
|
| -
|
| - rv = sftkdbLoad_Legacy(PR_FALSE);
|
| - if (rv != SECSuccess) {
|
| - return rv;
|
| - }
|
| - if (!legacy_glue_releaseSecmod) {
|
| - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| - return SECFailure;
|
| - }
|
| - return (*legacy_glue_releaseSecmod)(appName, filename, dbname,
|
| - moduleSpecList, rw);
|
| -}
|
| -
|
| -SECStatus
|
| -sftkdbCall_DeleteSecmodDB(const char *appName,
|
| - const char *filename, const char *dbname,
|
| - char *args, PRBool rw)
|
| -{
|
| - SECStatus rv;
|
| -
|
| - rv = sftkdbLoad_Legacy(PR_FALSE);
|
| - if (rv != SECSuccess) {
|
| - return rv;
|
| - }
|
| - if (!legacy_glue_deleteSecmod) {
|
| - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| - return SECFailure;
|
| - }
|
| - return (*legacy_glue_deleteSecmod)(appName, filename, dbname, args, rw);
|
| -}
|
| -
|
| -SECStatus
|
| -sftkdbCall_AddSecmodDB(const char *appName,
|
| - const char *filename, const char *dbname,
|
| - char *module, PRBool rw)
|
| -{
|
| - SECStatus rv;
|
| -
|
| - rv = sftkdbLoad_Legacy(PR_FALSE);
|
| - if (rv != SECSuccess) {
|
| - return rv;
|
| - }
|
| - if (!legacy_glue_addSecmod) {
|
| - PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
|
| - return SECFailure;
|
| - }
|
| - return (*legacy_glue_addSecmod)(appName, filename, dbname, module, rw);
|
| -}
|
| -
|
| -CK_RV
|
| -sftkdbCall_Shutdown(void)
|
| -{
|
| - CK_RV crv = CKR_OK;
|
| - char *disableUnload = NULL;
|
| - if (!legacy_glue_lib) {
|
| - return CKR_OK;
|
| - }
|
| - if (legacy_glue_shutdown) {
|
| -#ifdef NO_FORK_CHECK
|
| - PRBool parentForkedAfterC_Initialize = PR_FALSE;
|
| -#endif
|
| - crv = (*legacy_glue_shutdown)(parentForkedAfterC_Initialize);
|
| - }
|
| -#ifndef NSS_STATIC
|
| - disableUnload = PR_GetEnv("NSS_DISABLE_UNLOAD");
|
| - if (!disableUnload) {
|
| - PR_UnloadLibrary(legacy_glue_lib);
|
| - }
|
| -#endif
|
| - legacy_glue_lib = NULL;
|
| - legacy_glue_open = NULL;
|
| - legacy_glue_readSecmod = NULL;
|
| - legacy_glue_releaseSecmod = NULL;
|
| - legacy_glue_deleteSecmod = NULL;
|
| - legacy_glue_addSecmod = NULL;
|
| - legacy_glue_libCheckFailed = PR_FALSE;
|
| - legacy_glue_libCheckSucceeded = PR_FALSE;
|
| - return crv;
|
| -}
|
| -
|
| -
|
|
|