Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(7)

Unified Diff: mozilla/security/nss/lib/softoken/sftkmod.c

Issue 11362174: Update NSS to NSS 3.14 pre-release snapshot 2012-06-28 01:00:00 PDT. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/deps/third_party/nss/
Patch Set: Update the snapshot timestamp in README.chromium Created 8 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: mozilla/security/nss/lib/softoken/sftkmod.c
===================================================================
--- mozilla/security/nss/lib/softoken/sftkmod.c (revision 166571)
+++ mozilla/security/nss/lib/softoken/sftkmod.c (working copy)
@@ -1,731 +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. 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 "secerr.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 _WIN32
- if (!sep) {
- /* pkcs11i.h defines PATH_SEPARATOR as "/" for all platforms. */
- sep = PORT_Strrchr(dirPath,'\\');
- }
-#endif
- if (sep) {
- *sep = 0;
- file = PR_smprintf("%s"PATH_SEPARATOR"%s", dirPath, filename);
- } else {
- file = PR_smprintf("%s", 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 ((dbname != NULL) &&
- ((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;
-
- if (dbname == NULL) {
- goto return_default;
- }
-
- /* 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 collapses
- * 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.
- * This is necessary to maintain the semantics of the transition from
- * old to new DB's. If there is an old DB and not new DB, we will
- * automatically use the old DB. If the DB was opened read/write, we
- * create a new db and upgrade it from 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);
- }
- }
-
-return_default:
-
- 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 ((dbname != NULL) &&
- ((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 (dbname == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- if ((dbType == SDB_LEGACY) || (dbType == SDB_MULTIACCESS)) {
- return sftkdbCall_DeleteSecmodDB(appName, filename, dbname, args, rw);
- }
-
- if (!rw) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- 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 collapses
- * 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);
- if (found) {
- /* rename dbname2 to dbname */
- PR_Delete(dbname);
- PR_Rename(dbname2,dbname);
- } else {
- PR_Delete(dbname2);
- }
- PORT_Free(dbname2);
- PORT_Free(lib);
- PORT_Free(name);
- PORT_Free(block);
- return SECSuccess;
-
-loser:
- if (fd != NULL) {
- fclose(fd);
- }
- if (fd2 != NULL) {
- fclose(fd2);
- }
- if (dbname2) {
- PR_Delete(dbname2);
- PORT_Free(dbname2);
- }
- PORT_Free(lib);
- PORT_Free(name);
- 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 (dbname == NULL) {
- PORT_SetError(SEC_ERROR_INVALID_ARGS);
- return SECFailure;
- }
-
- 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) {
- PORT_SetError(SEC_ERROR_READ_ONLY);
- 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;
- }
- block = sftkdb_DupnCat(block, module, keyEnd-module+1);
- if (block == NULL) { goto loser; }
- value = sftk_argFetchValue(&keyEnd[1], &count);
- 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;
-}
-
-

Powered by Google App Engine
This is Rietveld 408576698