diff nss/lib/softoken/lgglue.c @ 0:1e5118fa0cb1

This is NSS with a Cmake Buildsyste To compile a static NSS library for Windows we've used the Chromium-NSS fork and added a Cmake buildsystem to compile it statically for Windows. See README.chromium for chromium changes and README.trustbridge for our modifications.
author Andre Heinecke <andre.heinecke@intevation.de>
date Mon, 28 Jul 2014 10:47:06 +0200
parents
children
line wrap: on
line diff
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/nss/lib/softoken/lgglue.c	Mon Jul 28 10:47:06 2014 +0200
@@ -0,0 +1,458 @@
+/* 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(PLArenaPool *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;
+}
+    
+
This site is hosted by Intevation GmbH (Datenschutzerklärung und Impressum | Privacy Policy and Imprint)