michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: /* michael@0: * The following code handles the storage of PKCS 11 modules used by the michael@0: * NSS. This file is written to abstract away how the modules are michael@0: * stored so we can deside that later. michael@0: */ michael@0: #include "pkcs11i.h" michael@0: #include "sdb.h" michael@0: #include "prprf.h" michael@0: #include "prenv.h" michael@0: #include "utilpars.h" michael@0: michael@0: #define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; } michael@0: michael@0: static void michael@0: sftk_parseTokenFlags(char *tmp, sftk_token_parameters *parsed) { michael@0: parsed->readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",tmp); michael@0: parsed->noCertDB = NSSUTIL_ArgHasFlag("flags","noCertDB",tmp); michael@0: parsed->noKeyDB = NSSUTIL_ArgHasFlag("flags","noKeyDB",tmp); michael@0: parsed->forceOpen = NSSUTIL_ArgHasFlag("flags","forceOpen",tmp); michael@0: parsed->pwRequired = NSSUTIL_ArgHasFlag("flags","passwordRequired",tmp); michael@0: parsed->optimizeSpace = NSSUTIL_ArgHasFlag("flags","optimizeSpace",tmp); michael@0: return; michael@0: } michael@0: michael@0: static void michael@0: sftk_parseFlags(char *tmp, sftk_parameters *parsed) { michael@0: parsed->noModDB = NSSUTIL_ArgHasFlag("flags","noModDB",tmp); michael@0: parsed->readOnly = NSSUTIL_ArgHasFlag("flags","readOnly",tmp); michael@0: /* keep legacy interface working */ michael@0: parsed->noCertDB = NSSUTIL_ArgHasFlag("flags","noCertDB",tmp); michael@0: parsed->forceOpen = NSSUTIL_ArgHasFlag("flags","forceOpen",tmp); michael@0: parsed->pwRequired = NSSUTIL_ArgHasFlag("flags","passwordRequired",tmp); michael@0: parsed->optimizeSpace = NSSUTIL_ArgHasFlag("flags","optimizeSpace",tmp); michael@0: return; michael@0: } michael@0: michael@0: static CK_RV michael@0: sftk_parseTokenParameters(char *param, sftk_token_parameters *parsed) michael@0: { michael@0: int next; michael@0: char *tmp = NULL; michael@0: char *index; michael@0: index = NSSUTIL_ArgStrip(param); michael@0: michael@0: while (*index) { michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updCertPrefix, michael@0: "updateCertPrefix=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updKeyPrefix, michael@0: "updateKeyPrefix=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->certPrefix,"certPrefix=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyPrefix=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updtokdes, michael@0: "updateTokenDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,tmp,"minPWLen=", michael@0: if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); tmp = NULL; }) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,tmp,"flags=", michael@0: if(tmp) { sftk_parseTokenFlags(param,parsed); PORT_Free(tmp); michael@0: tmp = NULL; }) michael@0: NSSUTIL_HANDLE_FINAL_ARG(index) michael@0: } michael@0: return CKR_OK; michael@0: } michael@0: michael@0: static void michael@0: sftk_parseTokens(char *tokenParams, sftk_parameters *parsed) michael@0: { michael@0: char *tokenIndex; michael@0: sftk_token_parameters *tokens = NULL; michael@0: int i=0,count = 0,next; michael@0: michael@0: if ((tokenParams == NULL) || (*tokenParams == 0)) return; michael@0: michael@0: /* first count the number of slots */ michael@0: for (tokenIndex = NSSUTIL_ArgStrip(tokenParams); *tokenIndex; michael@0: tokenIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(tokenIndex))) { michael@0: count++; michael@0: } michael@0: michael@0: /* get the data structures */ michael@0: tokens = (sftk_token_parameters *) michael@0: PORT_ZAlloc(count*sizeof(sftk_token_parameters)); michael@0: if (tokens == NULL) return; michael@0: michael@0: for (tokenIndex = NSSUTIL_ArgStrip(tokenParams), i = 0; michael@0: *tokenIndex && i < count ; i++ ) { michael@0: char *name; michael@0: name = NSSUTIL_ArgGetLabel(tokenIndex,&next); michael@0: tokenIndex += next; michael@0: michael@0: tokens[i].slotID = NSSUTIL_ArgDecodeNumber(name); michael@0: tokens[i].readOnly = PR_FALSE; michael@0: tokens[i].noCertDB = PR_FALSE; michael@0: tokens[i].noKeyDB = PR_FALSE; michael@0: if (!NSSUTIL_ArgIsBlank(*tokenIndex)) { michael@0: char *args = NSSUTIL_ArgFetchValue(tokenIndex,&next); michael@0: tokenIndex += next; michael@0: if (args) { michael@0: sftk_parseTokenParameters(args,&tokens[i]); michael@0: PORT_Free(args); michael@0: } michael@0: } michael@0: if (name) PORT_Free(name); michael@0: tokenIndex = NSSUTIL_ArgStrip(tokenIndex); michael@0: } michael@0: parsed->token_count = i; michael@0: parsed->tokens = tokens; michael@0: return; michael@0: } michael@0: michael@0: CK_RV michael@0: sftk_parseParameters(char *param, sftk_parameters *parsed, PRBool isFIPS) michael@0: { michael@0: int next; michael@0: char *tmp = NULL; michael@0: char *index; michael@0: char *certPrefix = NULL, *keyPrefix = NULL; michael@0: char *tokdes = NULL, *ptokdes = NULL, *pupdtokdes = NULL; michael@0: char *slotdes = NULL, *pslotdes = NULL; michael@0: char *fslotdes = NULL, *ftokdes = NULL; michael@0: char *minPW = NULL; michael@0: index = NSSUTIL_ArgStrip(param); michael@0: michael@0: PORT_Memset(parsed, 0, sizeof(sftk_parameters)); michael@0: michael@0: while (*index) { michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->configdir,"configDir=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updatedir,"updateDir=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->updateID,"updateID=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->man,"manufacturerID=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;) michael@0: /* constructed values, used so legacy interfaces still work */ michael@0: NSSUTIL_HANDLE_STRING_ARG(index,certPrefix,"certPrefix=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,keyPrefix,"keyPrefix=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,tokdes,"cryptoTokenDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,ptokdes,"dbTokenDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,ftokdes,"FIPSTokenDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,pupdtokdes, "updateTokenDescription=",;) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,minPW,"minPWLen=",;) michael@0: michael@0: NSSUTIL_HANDLE_STRING_ARG(index,tmp,"flags=", michael@0: if(tmp) { sftk_parseFlags(param,parsed); PORT_Free(tmp); michael@0: tmp = NULL; }) michael@0: NSSUTIL_HANDLE_STRING_ARG(index,tmp,"tokens=", michael@0: if(tmp) { sftk_parseTokens(tmp,parsed); PORT_Free(tmp); tmp = NULL; }) michael@0: NSSUTIL_HANDLE_FINAL_ARG(index) michael@0: } michael@0: if (parsed->tokens == NULL) { michael@0: int count = isFIPS ? 1 : 2; michael@0: int index = count-1; michael@0: sftk_token_parameters *tokens = NULL; michael@0: michael@0: tokens = (sftk_token_parameters *) michael@0: PORT_ZAlloc(count*sizeof(sftk_token_parameters)); michael@0: if (tokens == NULL) { michael@0: goto loser; michael@0: } michael@0: parsed->tokens = tokens; michael@0: parsed->token_count = count; michael@0: tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID; michael@0: tokens[index].certPrefix = certPrefix; michael@0: tokens[index].keyPrefix = keyPrefix; michael@0: tokens[index].minPW = minPW ? atoi(minPW) : 0; michael@0: tokens[index].readOnly = parsed->readOnly; michael@0: tokens[index].noCertDB = parsed->noCertDB; michael@0: tokens[index].noKeyDB = parsed->noCertDB; michael@0: tokens[index].forceOpen = parsed->forceOpen; michael@0: tokens[index].pwRequired = parsed->pwRequired; michael@0: tokens[index].optimizeSpace = parsed->optimizeSpace; michael@0: tokens[0].optimizeSpace = parsed->optimizeSpace; michael@0: certPrefix = NULL; michael@0: keyPrefix = NULL; michael@0: if (isFIPS) { michael@0: tokens[index].tokdes = ftokdes; michael@0: tokens[index].updtokdes = pupdtokdes; michael@0: tokens[index].slotdes = fslotdes; michael@0: fslotdes = NULL; michael@0: ftokdes = NULL; michael@0: pupdtokdes = NULL; michael@0: } else { michael@0: tokens[index].tokdes = ptokdes; michael@0: tokens[index].updtokdes = pupdtokdes; michael@0: tokens[index].slotdes = pslotdes; michael@0: tokens[0].slotID = NETSCAPE_SLOT_ID; michael@0: tokens[0].tokdes = tokdes; michael@0: tokens[0].slotdes = slotdes; michael@0: tokens[0].noCertDB = PR_TRUE; michael@0: tokens[0].noKeyDB = PR_TRUE; michael@0: pupdtokdes = NULL; michael@0: ptokdes = NULL; michael@0: pslotdes = NULL; michael@0: tokdes = NULL; michael@0: slotdes = NULL; michael@0: } michael@0: } michael@0: michael@0: loser: michael@0: FREE_CLEAR(certPrefix); michael@0: FREE_CLEAR(keyPrefix); michael@0: FREE_CLEAR(tokdes); michael@0: FREE_CLEAR(ptokdes); michael@0: FREE_CLEAR(pupdtokdes); michael@0: FREE_CLEAR(slotdes); michael@0: FREE_CLEAR(pslotdes); michael@0: FREE_CLEAR(fslotdes); michael@0: FREE_CLEAR(ftokdes); michael@0: FREE_CLEAR(minPW); michael@0: return CKR_OK; michael@0: } michael@0: michael@0: void michael@0: sftk_freeParams(sftk_parameters *params) michael@0: { michael@0: int i; michael@0: michael@0: for (i=0; i < params->token_count; i++) { michael@0: FREE_CLEAR(params->tokens[i].configdir); michael@0: FREE_CLEAR(params->tokens[i].certPrefix); michael@0: FREE_CLEAR(params->tokens[i].keyPrefix); michael@0: FREE_CLEAR(params->tokens[i].tokdes); michael@0: FREE_CLEAR(params->tokens[i].slotdes); michael@0: FREE_CLEAR(params->tokens[i].updatedir); michael@0: FREE_CLEAR(params->tokens[i].updCertPrefix); michael@0: FREE_CLEAR(params->tokens[i].updKeyPrefix); michael@0: FREE_CLEAR(params->tokens[i].updateID); michael@0: FREE_CLEAR(params->tokens[i].updtokdes); michael@0: } michael@0: michael@0: FREE_CLEAR(params->configdir); michael@0: FREE_CLEAR(params->secmodName); michael@0: FREE_CLEAR(params->man); michael@0: FREE_CLEAR(params->libdes); michael@0: FREE_CLEAR(params->tokens); michael@0: FREE_CLEAR(params->updatedir); michael@0: FREE_CLEAR(params->updateID); michael@0: } michael@0: