diff options
Diffstat (limited to 'security/nss/lib/softoken/sftkmod.c')
-rw-r--r-- | security/nss/lib/softoken/sftkmod.c | 728 |
1 files changed, 0 insertions, 728 deletions
diff --git a/security/nss/lib/softoken/sftkmod.c b/security/nss/lib/softoken/sftkmod.c deleted file mode 100644 index 73c7dbb64..000000000 --- a/security/nss/lib/softoken/sftkmod.c +++ /dev/null @@ -1,728 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Netscape security libraries. - * - * The Initial Developer of the Original Code is - * Netscape Communications Corporation. - * Portions created by the Initial Developer are Copyright (C) 1994-2007 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ -/* - * The following code handles the storage of PKCS 11 modules used by the - * NSS. For the rest of NSS, only one kind of database handle exists: - * - * SFTKDBHandle - * - * There is one SFTKDBHandle for the each key database and one for each cert - * database. These databases are opened as associated pairs, one pair per - * slot. SFTKDBHandles are reference counted objects. - * - * Each SFTKDBHandle points to a low level database handle (SDB). This handle - * represents the underlying physical database. These objects are not - * reference counted, an are 'owned' by their respective SFTKDBHandles. - * - * - */ -#include "sftkdb.h" -#include "sftkpars.h" -#include "prprf.h" -#include "prsystem.h" -#include "lgglue.h" -#include "secmodt.h" -#if defined (_WIN32) -#include <io.h> -#endif - -/**************************************************************** - * - * Secmod database. - * - * The new secmod database is simply a text file with each of the module - * entries. in the following form: - * - * # - * # This is a comment The next line is the library to load - * library=libmypkcs11.so - * name="My PKCS#11 module" - * params="my library's param string" - * nss="NSS parameters" - * other="parameters for other libraries and applications" - * - * library=libmynextpk11.so - * name="My other PKCS#11 module" - */ - -static char * -sftkdb_quote(const char *string, char quote) -{ - char *newString = 0; - int escapes = 0, size = 0; - const char *src; - char *dest; - - size=2; - for (src=string; *src ; src++) { - if ((*src == quote) || (*src == '\\')) escapes++; - size++; - } - - dest = newString = PORT_ZAlloc(escapes+size+1); - if (newString == NULL) { - return NULL; - } - - *dest++=quote; - for (src=string; *src; src++,dest++) { - if ((*src == '\\') || (*src == quote)) { - *dest++ = '\\'; - } - *dest = *src; - } - *dest=quote; - - return newString; -} - -/* - * Smart string cat functions. Automatically manage the memory. - * The first parameter is the source string. If it's null, we - * allocate memory for it. If it's not, we reallocate memory - * so the the concanenated string fits. - */ -static char * -sftkdb_DupnCat(char *baseString, const char *str, int str_len) -{ - int len = (baseString ? PORT_Strlen(baseString) : 0) + 1; - char *newString; - - len += str_len; - newString = (char *) PORT_Realloc(baseString,len); - if (newString == NULL) { - PORT_Free(baseString); - return NULL; - } - if (baseString == NULL) *newString = 0; - return PORT_Strncat(newString,str, str_len); -} - -/* Same as sftkdb_DupnCat except it concatenates the full string, not a - * partial one */ -static char * -sftkdb_DupCat(char *baseString, const char *str) -{ - return sftkdb_DupnCat(baseString, str, PORT_Strlen(str)); -} - -/* function to free up all the memory associated with a null terminated - * array of module specs */ -static SECStatus -sftkdb_releaseSpecList(char **moduleSpecList) -{ - if (moduleSpecList) { - char **index; - for(index = moduleSpecList; *index; index++) { - PORT_Free(*index); - } - PORT_Free(moduleSpecList); - } - return SECSuccess; -} - -#define SECMOD_STEP 10 -static SECStatus -sftkdb_growList(char ***pModuleList, int *useCount, int last) -{ - char **newModuleList; - - *useCount += SECMOD_STEP; - newModuleList = (char **)PORT_Realloc(*pModuleList, - *useCount*sizeof(char *)); - if (newModuleList == NULL) { - return SECFailure; - } - PORT_Memset(&newModuleList[last],0, sizeof(char *)*SECMOD_STEP); - *pModuleList = newModuleList; - return SECSuccess; -} - -static -char *sftk_getOldSecmodName(const char *dbname,const char *filename) -{ - char *file = NULL; - char *dirPath = PORT_Strdup(dbname); - char *sep; - - sep = PORT_Strrchr(dirPath,*PATH_SEPARATOR); -#ifdef WINDOWS - if (!sep) { - sep = PORT_Strrchr(dirPath,'/'); - } -#endif - if (sep) { - *(sep)=0; - } - file= PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename); - PORT_Free(dirPath); - return file; -} - -#ifdef XP_UNIX -#include <unistd.h> -#endif -#include <fcntl.h> - -#ifndef WINCE -/* same as fopen, except it doesn't use umask, but explicit */ -FILE * -lfopen(const char *name, const char *mode, int flags) -{ - int fd; - FILE *file; - - fd = open(name, flags, 0600); - if (fd < 0) { - return NULL; - } - file = fdopen(fd, mode); - if (!file) { - close(fd); - } - /* file inherits fd */ - return file; -} -#endif - -#define MAX_LINE_LENGTH 2048 -#define SFTK_DEFAULT_INTERNAL_INIT1 "library= name=\"NSS Internal PKCS #11 Module\" parameters=" -#define SFTK_DEFAULT_INTERNAL_INIT2 " NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={" -#define SFTK_DEFAULT_INTERNAL_INIT3 " askpw=any timeout=30})\"" - -/* - * Read all the existing modules in out of the file. - */ -char ** -sftkdb_ReadSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *params, PRBool rw) -{ - FILE *fd = NULL; - char **moduleList = NULL; - int moduleCount = 1; - int useCount = SECMOD_STEP; - char line[MAX_LINE_LENGTH]; - PRBool internal = PR_FALSE; - PRBool skipParams = PR_FALSE; - char *moduleString = NULL; - char *paramsValue=NULL; - PRBool failed = PR_TRUE; - - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_ReadSecmodDB(appName, filename, dbname, params, rw); - } - - moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **)); - if (moduleList == NULL) return NULL; - - /* do we really want to use streams here */ - fd = fopen(dbname, "r"); - if (fd == NULL) goto done; - - /* - * the following loop takes line separated config lines and colapses - * the lines to a single string, escaping and quoting as necessary. - */ - /* loop state variables */ - moduleString = NULL; /* current concatenated string */ - internal = PR_FALSE; /* is this an internal module */ - skipParams = PR_FALSE; /* did we find an override parameter block*/ - paramsValue = NULL; /* the current parameter block value */ - while (fgets(line, sizeof(line), fd) != NULL) { - int len = PORT_Strlen(line); - - /* remove the ending newline */ - if (len && line[len-1] == '\n') { - len--; - line[len] = 0; - } - if (*line == '#') { - continue; - } - if (*line != 0) { - /* - * The PKCS #11 group standard assumes blocks of strings - * separated by new lines, clumped by new lines. Internally - * we take strings separated by spaces, so we may need to escape - * certain spaces. - */ - char *value = PORT_Strchr(line,'='); - - /* there is no value, write out the stanza as is */ - if (value == NULL || value[1] == 0) { - if (moduleString) { - moduleString = sftkdb_DupnCat(moduleString," ", 1); - if (moduleString == NULL) goto loser; - } - moduleString = sftkdb_DupCat(moduleString, line); - if (moduleString == NULL) goto loser; - /* value is already quoted, just write it out */ - } else if (value[1] == '"') { - if (moduleString) { - moduleString = sftkdb_DupnCat(moduleString," ", 1); - if (moduleString == NULL) goto loser; - } - moduleString = sftkdb_DupCat(moduleString, line); - if (moduleString == NULL) goto loser; - /* we have an override parameter section, remember that - * we found this (see following comment about why this - * is necessary). */ - if (PORT_Strncasecmp(line, "parameters", 10) == 0) { - skipParams = PR_TRUE; - } - /* - * The internal token always overrides it's parameter block - * from the passed in parameters, so wait until then end - * before we include the parameter block in case we need to - * override it. NOTE: if the parameter block is quoted with ("), - * this override does not happen. This allows you to override - * the application's parameter configuration. - * - * parameter block state is controlled by the following variables: - * skipParams - Bool : set to true of we have an override param - * block (all other blocks, either implicit or explicit are - * ignored). - * paramsValue - char * : pointer to the current param block. In - * the absence of overrides, paramsValue is set to the first - * parameter block we find. All subsequent blocks are ignored. - * When we find an internal token, the application passed - * parameters take precident. - */ - } else if (PORT_Strncasecmp(line, "parameters", 10) == 0) { - /* already have parameters */ - if (paramsValue) { - continue; - } - paramsValue = sftkdb_quote(&value[1], '"'); - if (paramsValue == NULL) goto loser; - continue; - } else { - /* may need to quote */ - char *newLine; - if (moduleString) { - moduleString = sftkdb_DupnCat(moduleString," ", 1); - if (moduleString == NULL) goto loser; - } - moduleString = sftkdb_DupnCat(moduleString,line,value-line+1); - if (moduleString == NULL) goto loser; - newLine = sftkdb_quote(&value[1],'"'); - if (newLine == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString,newLine); - PORT_Free(newLine); - if (moduleString == NULL) goto loser; - } - - /* check to see if it's internal? */ - if (PORT_Strncasecmp(line, "NSS=", 4) == 0) { - /* This should be case insensitive! reviewers make - * me fix it if it's not */ - if (PORT_Strstr(line,"internal")) { - internal = PR_TRUE; - /* override the parameters */ - if (paramsValue) { - PORT_Free(paramsValue); - } - paramsValue = sftkdb_quote(params, '"'); - } - } - continue; - } - if ((moduleString == NULL) || (*moduleString == 0)) { - continue; - } - - /* - * if we are here, we have found a complete stanza. Now write out - * any param section we may have found. - */ - if (paramsValue) { - /* we had an override */ - if (!skipParams) { - moduleString = sftkdb_DupnCat(moduleString," parameters=", 12); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, paramsValue); - if (moduleString == NULL) goto loser; - } - PORT_Free(paramsValue); - paramsValue = NULL; - } - - if ((moduleCount+1) >= useCount) { - SECStatus rv; - rv = sftkdb_growList(&moduleList, &useCount, moduleCount+1); - if (rv != SECSuccess) { - goto loser; - } - } - - if (internal) { - moduleList[0] = moduleString; - } else { - moduleList[moduleCount] = moduleString; - moduleCount++; - } - moduleString = NULL; - internal = PR_FALSE; - skipParams = PR_FALSE; - } - - if (moduleString) { - PORT_Free(moduleString); - moduleString = NULL; - } -done: - /* if we couldn't open a pkcs11 database, look for the old one */ - if (fd == NULL) { - char *olddbname = sftk_getOldSecmodName(dbname,filename); - PRStatus status; - char **oldModuleList; - int i; - - /* couldn't get the old name */ - if (!olddbname) { - goto bail; - } - - /* old one doesn't exist */ - status = PR_Access(olddbname, PR_ACCESS_EXISTS); - if (status != PR_SUCCESS) { - goto bail; - } - - oldModuleList = sftkdbCall_ReadSecmodDB(appName, filename, - olddbname, params, rw); - /* old one had no modules */ - if (!oldModuleList) { - goto bail; - } - - /* count the modules */ - for (i=0; oldModuleList[i]; i++) { } - - /* grow the moduleList if necessary */ - if (i >= useCount) { - SECStatus rv; - rv = sftkdb_growList(&moduleList,&useCount,moduleCount+1); - if (rv != SECSuccess) { - goto loser; - } - } - - /* write each module out, and copy it */ - for (i=0; oldModuleList[i]; i++) { - if (rw) { - sftkdb_AddSecmodDB(dbType,appName,filename,dbname, - oldModuleList[i],rw); - } - if (moduleList[i]) { - PORT_Free(moduleList[i]); - } - moduleList[i] = PORT_Strdup(oldModuleList[i]); - } - - /* done with the old module list */ - sftkdbCall_ReleaseSecmodDBData(appName, filename, olddbname, - oldModuleList, rw); -bail: - if (olddbname) { - PR_smprintf_free(olddbname); - } - } - - if (!moduleList[0]) { - char * newParams; - moduleString = PORT_Strdup(SFTK_DEFAULT_INTERNAL_INIT1); - newParams = sftkdb_quote(params,'"'); - if (newParams == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, newParams); - PORT_Free(newParams); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, SFTK_DEFAULT_INTERNAL_INIT2); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, SECMOD_SLOT_FLAGS); - if (moduleString == NULL) goto loser; - moduleString = sftkdb_DupCat(moduleString, SFTK_DEFAULT_INTERNAL_INIT3); - if (moduleString == NULL) goto loser; - moduleList[0] = moduleString; - moduleString = NULL; - } - failed = PR_FALSE; - -loser: - /* - * cleanup - */ - /* deal with trust cert db here */ - if (moduleString) { - PORT_Free(moduleString); - moduleString = NULL; - } - if (paramsValue) { - PORT_Free(paramsValue); - paramsValue = NULL; - } - if (failed || (moduleList[0] == NULL)) { - /* This is wrong! FIXME */ - sftkdb_releaseSpecList(moduleList); - moduleList = NULL; - failed = PR_TRUE; - } - if (fd != NULL) { - fclose(fd); - } else if (!failed && rw) { - /* update our internal module */ - sftkdb_AddSecmodDB(dbType,appName,filename,dbname,moduleList[0],rw); - } - return moduleList; -} - -SECStatus -sftkdb_ReleaseSecmodDBData(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char **moduleSpecList, PRBool rw) -{ - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_ReleaseSecmodDBData(appName, filename, dbname, - moduleSpecList, rw); - } - if (moduleSpecList) { - sftkdb_releaseSpecList(moduleSpecList); - } - return SECSuccess; -} - - -/* - * Delete a module from the Data Base - */ -SECStatus -sftkdb_DeleteSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *args, PRBool rw) -{ - /* SHDB_FIXME implement */ - FILE *fd = NULL; - FILE *fd2 = NULL; - char line[MAX_LINE_LENGTH]; - char *dbname2 = NULL; - char *block = NULL; - char *name = NULL; - char *lib = NULL; - int name_len, lib_len; - PRBool skip = PR_FALSE; - PRBool found = PR_FALSE; - - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw); - } - - if (!rw) { - return SECFailure; - } - - dbname2 = strdup(dbname); - if (dbname2 == NULL) goto loser; - dbname2[strlen(dbname)-1]++; - - /* do we really want to use streams here */ - fd = fopen(dbname, "r"); - if (fd == NULL) goto loser; -#ifdef WINCE - fd2 = fopen(dbname2, "w+"); -#else - fd2 = lfopen(dbname2, "w+", O_CREAT|O_RDWR|O_TRUNC); -#endif - if (fd2 == NULL) goto loser; - - name = sftk_argGetParamValue("name",args); - if (name) { - name_len = PORT_Strlen(name); - } - lib = sftk_argGetParamValue("library",args); - if (lib) { - lib_len = PORT_Strlen(lib); - } - - - /* - * the following loop takes line separated config files and colapses - * the lines to a single string, escaping and quoting as necessary. - */ - /* loop state variables */ - block = NULL; - skip = PR_FALSE; - while (fgets(line, sizeof(line), fd) != NULL) { - /* If we are processing a block (we haven't hit a blank line yet */ - if (*line != '\n') { - /* skip means we are in the middle of a block we are deleting */ - if (skip) { - continue; - } - /* if we haven't found the block yet, check to see if this block - * matches our requirements */ - if (!found && ((name && (PORT_Strncasecmp(line,"name=",5) == 0) && - (PORT_Strncmp(line+5,name,name_len) == 0)) || - (lib && (PORT_Strncasecmp(line,"library=",8) == 0) && - (PORT_Strncmp(line+8,lib,lib_len) == 0)))) { - - /* yup, we don't need to save any more data, */ - PORT_Free(block); - block=NULL; - /* we don't need to collect more of this block */ - skip = PR_TRUE; - /* we don't need to continue searching for the block */ - found =PR_TRUE; - continue; - } - /* not our match, continue to collect data in this block */ - block = sftkdb_DupCat(block,line); - continue; - } - /* we've collected a block of data that wasn't the module we were - * looking for, write it out */ - if (block) { - fwrite(block, PORT_Strlen(block), 1, fd2); - PORT_Free(block); - block = NULL; - } - /* If we didn't just delete the this block, keep the blank line */ - if (!skip) { - fputs(line,fd2); - } - /* we are definately not in a deleted block anymore */ - skip = PR_FALSE; - } - fclose(fd); - fclose(fd2); - /* rename dbname2 to dbname */ - if (found) { - PR_Delete(dbname); - PR_Rename(dbname2,dbname); - } - PORT_Free(dbname2); - return SECSuccess; - -loser: - if (fd != NULL) { - fclose(fd); - } - if (fd2 != NULL) { - fclose(fd2); - } - if (dbname2) { - PR_Delete(dbname2); - PORT_Free(dbname2); - } - return SECFailure; -} - -/* - * Add a module to the Data base - */ -SECStatus -sftkdb_AddSecmodDB(SDBType dbType, const char *appName, - const char *filename, const char *dbname, - char *module, PRBool rw) -{ - FILE *fd = NULL; - char *block = NULL; - PRBool libFound = PR_FALSE; - - if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) { - return sftkdbCall_AddSecmodDB(appName, filename, dbname, module, rw); - } - - /* can't write to a read only module */ - if (!rw) { - return SECFailure; - } - - /* remove the previous version if it exists */ - (void) sftkdb_DeleteSecmodDB(dbType, appName, filename, dbname, module, rw); - -#ifdef WINCE - fd = fopen(dbname, "a+"); -#else - fd = lfopen(dbname, "a+", O_CREAT|O_RDWR|O_APPEND); -#endif - if (fd == NULL) { - return SECFailure; - } - module = sftk_argStrip(module); - while (*module) { - int count; - char *keyEnd = PORT_Strchr(module,'='); - char *value; - - if (PORT_Strncmp(module, "library=", 8) == 0) { - libFound=PR_TRUE; - } - if (keyEnd == NULL) { - block = sftkdb_DupCat(block, module); - break; - } - value = sftk_argFetchValue(&keyEnd[1], &count); - block = sftkdb_DupnCat(block, module, keyEnd-module+1); - if (block == NULL) { goto loser; } - if (value) { - block = sftkdb_DupCat(block, sftk_argStrip(value)); - PORT_Free(value); - } - if (block == NULL) { goto loser; } - block = sftkdb_DupnCat(block, "\n", 1); - module = keyEnd + 1 + count; - module = sftk_argStrip(module); - } - if (block) { - if (!libFound) { - fprintf(fd,"library=\n"); - } - fwrite(block, PORT_Strlen(block), 1, fd); - fprintf(fd,"\n"); - PORT_Free(block); - block = NULL; - } - fclose(fd); - return SECSuccess; - -loser: - PORT_Free(block); - fclose(fd); - return SECFailure; -} - - |