/* 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 decide that later. */ #include "secport.h" #include "prprf.h" #include "prenv.h" #include "utilpars.h" #include "utilmodt.h" /* * return the expected matching quote value for the one specified */ PRBool NSSUTIL_ArgGetPair(char c) { switch (c) { case '\'': return c; case '\"': return c; case '<': return '>'; case '{': return '}'; case '[': return ']'; case '(': return ')'; default: break; } return ' '; } PRBool NSSUTIL_ArgIsBlank(char c) { return isspace((unsigned char)c); } PRBool NSSUTIL_ArgIsEscape(char c) { return c == '\\'; } PRBool NSSUTIL_ArgIsQuote(char c) { switch (c) { case '\'': case '\"': case '<': case '{': /* } end curly to keep vi bracket matching working */ case '(': /* ) */ case '[': /* ] */ return PR_TRUE; default: break; } return PR_FALSE; } const char * NSSUTIL_ArgStrip(const char *c) { while (*c && NSSUTIL_ArgIsBlank(*c)) c++; return c; } /* * find the end of the current tag/value pair. string should be pointing just * after the equal sign. Handles quoted characters. */ const char * NSSUTIL_ArgFindEnd(const char *string) { char endChar = ' '; PRBool lastEscape = PR_FALSE; if (NSSUTIL_ArgIsQuote(*string)) { endChar = NSSUTIL_ArgGetPair(*string); string++; } for (; *string; string++) { if (lastEscape) { lastEscape = PR_FALSE; continue; } if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { lastEscape = PR_TRUE; continue; } if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string)) break; if (*string == endChar) { break; } } return string; } /* * get the value pointed to by string. string should be pointing just beyond * the equal sign. */ char * NSSUTIL_ArgFetchValue(const char *string, int *pcount) { const char *end = NSSUTIL_ArgFindEnd(string); char *retString, *copyString; PRBool lastEscape = PR_FALSE; int len; len = end - string; if (len == 0) { *pcount = 0; return NULL; } copyString = retString = (char *)PORT_Alloc(len + 1); if (*end) len++; *pcount = len; if (retString == NULL) return NULL; if (NSSUTIL_ArgIsQuote(*string)) string++; for (; string < end; string++) { if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { lastEscape = PR_TRUE; continue; } lastEscape = PR_FALSE; *copyString++ = *string; } *copyString = 0; return retString; } /* * point to the next parameter in string */ const char * NSSUTIL_ArgSkipParameter(const char *string) { const char *end; /* look for the end of the <name>= */ for (; *string; string++) { if (*string == '=') { string++; break; } if (NSSUTIL_ArgIsBlank(*string)) return (string); } end = NSSUTIL_ArgFindEnd(string); if (*end) end++; return end; } /* * get the value from that tag value pair. */ char * NSSUTIL_ArgGetParamValue(const char *paramName, const char *parameters) { char searchValue[256]; int paramLen = strlen(paramName); char *returnValue = NULL; int next; if ((parameters == NULL) || (*parameters == 0)) return NULL; PORT_Assert(paramLen + 2 < sizeof(searchValue)); PORT_Strcpy(searchValue, paramName); PORT_Strcat(searchValue, "="); while (*parameters) { if (PORT_Strncasecmp(parameters, searchValue, paramLen + 1) == 0) { parameters += paramLen + 1; returnValue = NSSUTIL_ArgFetchValue(parameters, &next); break; } else { parameters = NSSUTIL_ArgSkipParameter(parameters); } parameters = NSSUTIL_ArgStrip(parameters); } return returnValue; } /* * find the next flag in the parameter list */ const char * NSSUTIL_ArgNextFlag(const char *flags) { for (; *flags; flags++) { if (*flags == ',') { flags++; break; } } return flags; } /* * return true if the flag is set in the label parameter. */ PRBool NSSUTIL_ArgHasFlag(const char *label, const char *flag, const char *parameters) { char *flags; const char *index; int len = strlen(flag); PRBool found = PR_FALSE; flags = NSSUTIL_ArgGetParamValue(label, parameters); if (flags == NULL) return PR_FALSE; for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) { if (PORT_Strncasecmp(index, flag, len) == 0) { found = PR_TRUE; break; } } PORT_Free(flags); return found; } /* * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal */ long NSSUTIL_ArgDecodeNumber(const char *num) { int radix = 10; unsigned long value = 0; long retValue = 0; int sign = 1; int digit; if (num == NULL) return retValue; num = NSSUTIL_ArgStrip(num); if (*num == '-') { sign = -1; num++; } if (*num == '0') { radix = 8; num++; if ((*num == 'x') || (*num == 'X')) { radix = 16; num++; } } for (; *num; num++) { if (isdigit(*num)) { digit = *num - '0'; } else if ((*num >= 'a') && (*num <= 'f')) { digit = *num - 'a' + 10; } else if ((*num >= 'A') && (*num <= 'F')) { digit = *num - 'A' + 10; } else { break; } if (digit >= radix) break; value = value * radix + digit; } retValue = ((int)value) * sign; return retValue; } /* * parameters are tag value pairs. This function returns the tag or label (the * value before the equal size. */ char * NSSUTIL_ArgGetLabel(const char *inString, int *next) { char *name = NULL; const char *string; int len; /* look for the end of the <label>= */ for (string = inString; *string; string++) { if (*string == '=') { break; } if (NSSUTIL_ArgIsBlank(*string)) break; } len = string - inString; *next = len; if (*string == '=') (*next) += 1; if (len > 0) { name = PORT_Alloc(len + 1); PORT_Strncpy(name, inString, len); name[len] = 0; } return name; } /* * read an argument at a Long integer */ long NSSUTIL_ArgReadLong(const char *label, const char *params, long defValue, PRBool *isdefault) { char *value; long retValue; if (isdefault) *isdefault = PR_FALSE; value = NSSUTIL_ArgGetParamValue(label, params); if (value == NULL) { if (isdefault) *isdefault = PR_TRUE; return defValue; } retValue = NSSUTIL_ArgDecodeNumber(value); if (value) PORT_Free(value); return retValue; } /* * prepare a string to be quoted with 'quote' marks. We do that by adding * appropriate escapes. */ static int nssutil_escapeQuotesSize(const char *string, char quote, PRBool addquotes) { int escapes = 0, size = 0; const char *src; size = addquotes ? 2 : 0; for (src = string; *src; src++) { if ((*src == quote) || (*src == '\\')) escapes++; size++; } return size + escapes + 1; } static char * nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes) { char *newString = 0; int size = 0; const char *src; char *dest; size = nssutil_escapeQuotesSize(string, quote, addquotes); dest = newString = PORT_ZAlloc(size); if (newString == NULL) { return NULL; } if (addquotes) *dest++ = quote; for (src = string; *src; src++, dest++) { if ((*src == '\\') || (*src == quote)) { *dest++ = '\\'; } *dest = *src; } if (addquotes) *dest = quote; return newString; } int NSSUTIL_EscapeSize(const char *string, char quote) { return nssutil_escapeQuotesSize(string, quote, PR_FALSE); } char * NSSUTIL_Escape(const char *string, char quote) { return nssutil_escapeQuotes(string, quote, PR_FALSE); } int NSSUTIL_QuoteSize(const char *string, char quote) { return nssutil_escapeQuotesSize(string, quote, PR_TRUE); } char * NSSUTIL_Quote(const char *string, char quote) { return nssutil_escapeQuotes(string, quote, PR_TRUE); } int NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2) { int escapes = 0, size = 0; const char *src; for (src = string; *src; src++) { if (*src == '\\') escapes += 3; /* \\\\ */ if (*src == quote1) escapes += 2; /* \\quote1 */ if (*src == quote2) escapes++; /* \quote2 */ size++; } return escapes + size + 1; } char * NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2) { char *round1 = NULL; char *retValue = NULL; if (string == NULL) { goto done; } round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE); if (round1) { retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE); PORT_Free(round1); } done: if (retValue == NULL) { retValue = PORT_Strdup(""); } return retValue; } /************************************************************************ * These functions are used in contructing strings. * NOTE: they will always return a string, but sometimes it will return * a specific NULL string. These strings must be freed with util_freePair. */ /* string to return on error... */ static char *nssutil_nullString = ""; static char * nssutil_formatValue(PLArenaPool *arena, char *value, char quote) { char *vp, *vp2, *retval; int size = 0, escapes = 0; for (vp = value; *vp; vp++) { if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) escapes++; size++; } if (arena) { retval = PORT_ArenaZAlloc(arena, size + escapes + 1); } else { retval = PORT_ZAlloc(size + escapes + 1); } if (retval == NULL) return NULL; vp2 = retval; for (vp = value; *vp; vp++) { if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) *vp2++ = NSSUTIL_ARG_ESCAPE; *vp2++ = *vp; } return retval; } static PRBool nssutil_argHasChar(char *v, char c) { for (; *v; v++) { if (*v == c) return PR_TRUE; } return PR_FALSE; } static PRBool nssutil_argHasBlanks(char *v) { for (; *v; v++) { if (NSSUTIL_ArgIsBlank(*v)) return PR_TRUE; } return PR_FALSE; } static char * nssutil_formatPair(char *name, char *value, char quote) { char openQuote = quote; char closeQuote = NSSUTIL_ArgGetPair(quote); char *newValue = NULL; char *returnValue; PRBool need_quote = PR_FALSE; if (!value || (*value == 0)) return nssutil_nullString; if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0])) need_quote = PR_TRUE; if ((need_quote && nssutil_argHasChar(value, closeQuote)) || nssutil_argHasChar(value, NSSUTIL_ARG_ESCAPE)) { value = newValue = nssutil_formatValue(NULL, value, quote); if (newValue == NULL) return nssutil_nullString; } if (need_quote) { returnValue = PR_smprintf("%s=%c%s%c", name, openQuote, value, closeQuote); } else { returnValue = PR_smprintf("%s=%s", name, value); } if (returnValue == NULL) returnValue = nssutil_nullString; if (newValue) PORT_Free(newValue); return returnValue; } static char * nssutil_formatIntPair(char *name, unsigned long value, unsigned long def) { char *returnValue; if (value == def) return nssutil_nullString; returnValue = PR_smprintf("%s=%d", name, value); return returnValue; } static void nssutil_freePair(char *pair) { if (pair && pair != nssutil_nullString) { PR_smprintf_free(pair); } } /************************************************************************ * Parse the Slot specific parameters in the NSS params. */ struct nssutilArgSlotFlagTable { char *name; int len; unsigned long value; }; #define NSSUTIL_ARG_ENTRY(arg, flag) \ { \ #arg, sizeof(#arg) - 1, flag \ } static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = { NSSUTIL_ARG_ENTRY(RSA, SECMOD_RSA_FLAG), NSSUTIL_ARG_ENTRY(DSA, SECMOD_RSA_FLAG), NSSUTIL_ARG_ENTRY(RC2, SECMOD_RC4_FLAG), NSSUTIL_ARG_ENTRY(RC4, SECMOD_RC2_FLAG), NSSUTIL_ARG_ENTRY(DES, SECMOD_DES_FLAG), NSSUTIL_ARG_ENTRY(DH, SECMOD_DH_FLAG), NSSUTIL_ARG_ENTRY(FORTEZZA, SECMOD_FORTEZZA_FLAG), NSSUTIL_ARG_ENTRY(RC5, SECMOD_RC5_FLAG), NSSUTIL_ARG_ENTRY(SHA1, SECMOD_SHA1_FLAG), NSSUTIL_ARG_ENTRY(SHA256, SECMOD_SHA256_FLAG), NSSUTIL_ARG_ENTRY(SHA512, SECMOD_SHA512_FLAG), NSSUTIL_ARG_ENTRY(MD5, SECMOD_MD5_FLAG), NSSUTIL_ARG_ENTRY(MD2, SECMOD_MD2_FLAG), NSSUTIL_ARG_ENTRY(SSL, SECMOD_SSL_FLAG), NSSUTIL_ARG_ENTRY(TLS, SECMOD_TLS_FLAG), NSSUTIL_ARG_ENTRY(AES, SECMOD_AES_FLAG), NSSUTIL_ARG_ENTRY(Camellia, SECMOD_CAMELLIA_FLAG), NSSUTIL_ARG_ENTRY(SEED, SECMOD_SEED_FLAG), NSSUTIL_ARG_ENTRY(PublicCerts, SECMOD_FRIENDLY_FLAG), NSSUTIL_ARG_ENTRY(RANDOM, SECMOD_RANDOM_FLAG), NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG), }; static int nssutil_argSlotFlagTableSize = sizeof(nssutil_argSlotFlagTable) / sizeof(nssutil_argSlotFlagTable[0]); /* turn the slot flags into a bit mask */ unsigned long NSSUTIL_ArgParseSlotFlags(const char *label, const char *params) { char *flags; const char *index; unsigned long retValue = 0; int i; PRBool all = PR_FALSE; flags = NSSUTIL_ArgGetParamValue(label, params); if (flags == NULL) return 0; if (PORT_Strcasecmp(flags, "all") == 0) all = PR_TRUE; for (index = flags; *index; index = NSSUTIL_ArgNextFlag(index)) { for (i = 0; i < nssutil_argSlotFlagTableSize; i++) { if (all || (PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name, nssutil_argSlotFlagTable[i].len) == 0)) { retValue |= nssutil_argSlotFlagTable[i].value; } } } PORT_Free(flags); return retValue; } /* parse a single slot specific parameter */ static void nssutil_argDecodeSingleSlotInfo(char *name, char *params, struct NSSUTILPreSlotInfoStr *slotInfo) { char *askpw; slotInfo->slotID = NSSUTIL_ArgDecodeNumber(name); slotInfo->defaultFlags = NSSUTIL_ArgParseSlotFlags("slotFlags", params); slotInfo->timeout = NSSUTIL_ArgReadLong("timeout", params, 0, NULL); askpw = NSSUTIL_ArgGetParamValue("askpw", params); slotInfo->askpw = 0; if (askpw) { if (PORT_Strcasecmp(askpw, "every") == 0) { slotInfo->askpw = -1; } else if (PORT_Strcasecmp(askpw, "timeout") == 0) { slotInfo->askpw = 1; } PORT_Free(askpw); slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS; } slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts", params); slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust", params); } /* parse all the slot specific parameters. */ struct NSSUTILPreSlotInfoStr * NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, const char *slotParams, int *retCount) { const char *slotIndex; struct NSSUTILPreSlotInfoStr *slotInfo = NULL; int i = 0, count = 0, next; *retCount = 0; if ((slotParams == NULL) || (*slotParams == 0)) return NULL; /* first count the number of slots */ for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex; slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) { count++; } /* get the data structures */ if (arena) { slotInfo = PORT_ArenaZNewArray(arena, struct NSSUTILPreSlotInfoStr, count); } else { slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count); } if (slotInfo == NULL) return NULL; for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0; *slotIndex && i < count;) { char *name; name = NSSUTIL_ArgGetLabel(slotIndex, &next); slotIndex += next; if (!NSSUTIL_ArgIsBlank(*slotIndex)) { char *args = NSSUTIL_ArgFetchValue(slotIndex, &next); slotIndex += next; if (args) { nssutil_argDecodeSingleSlotInfo(name, args, &slotInfo[i]); i++; PORT_Free(args); } } if (name) PORT_Free(name); slotIndex = NSSUTIL_ArgStrip(slotIndex); } *retCount = i; return slotInfo; } /************************************************************************ * make a new slot specific parameter */ /* first make the slot flags */ static char * nssutil_mkSlotFlags(unsigned long defaultFlags) { char *flags = NULL; unsigned int i; int j; for (i = 0; i < sizeof(defaultFlags) * 8; i++) { if (defaultFlags & (1UL << i)) { char *string = NULL; for (j = 0; j < nssutil_argSlotFlagTableSize; j++) { if (nssutil_argSlotFlagTable[j].value == (1UL << i)) { string = nssutil_argSlotFlagTable[j].name; break; } } if (string) { if (flags) { char *tmp; tmp = PR_smprintf("%s,%s", flags, string); PR_smprintf_free(flags); flags = tmp; } else { flags = PR_smprintf("%s", string); } } } } return flags; } /* now make the root flags */ #define NSSUTIL_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts") + sizeof("hasRootTrust") static char * nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust) { char *flags = (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE); PRBool first = PR_TRUE; PORT_Memset(flags, 0, NSSUTIL_MAX_ROOT_FLAG_SIZE); if (hasRootCerts) { PORT_Strcat(flags, "hasRootCerts"); first = PR_FALSE; } if (hasRootTrust) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "hasRootTrust"); } return flags; } /* now make a full slot string */ char * NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags, unsigned long timeout, unsigned char askpw_in, PRBool hasRootCerts, PRBool hasRootTrust) { char *askpw, *flags, *rootFlags, *slotString; char *flagPair, *rootFlagsPair; switch (askpw_in) { case 0xff: askpw = "every"; break; case 1: askpw = "timeout"; break; default: askpw = "any"; break; } flags = nssutil_mkSlotFlags(defaultFlags); rootFlags = nssutil_mkRootFlags(hasRootCerts, hasRootTrust); flagPair = nssutil_formatPair("slotFlags", flags, '\''); rootFlagsPair = nssutil_formatPair("rootFlags", rootFlags, '\''); if (flags) PR_smprintf_free(flags); if (rootFlags) PORT_Free(rootFlags); if (defaultFlags & PK11_OWN_PW_DEFAULTS) { slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]", (PRUint32)slotID, flagPair, askpw, timeout, rootFlagsPair); } else { slotString = PR_smprintf("0x%08lx=[%s %s]", (PRUint32)slotID, flagPair, rootFlagsPair); } nssutil_freePair(flagPair); nssutil_freePair(rootFlagsPair); return slotString; } /************************************************************************ * Parse Full module specs into: library, commonName, module parameters, * and NSS specifi parameters. */ SECStatus NSSUTIL_ArgParseModuleSpecEx(const char *modulespec, char **lib, char **mod, char **parameters, char **nss, char **config) { int next; modulespec = NSSUTIL_ArgStrip(modulespec); *lib = *mod = *parameters = *nss = *config = 0; while (*modulespec) { NSSUTIL_HANDLE_STRING_ARG(modulespec, *lib, "library=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *mod, "name=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *parameters, "parameters=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *nss, "nss=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *config, "config=", ;) NSSUTIL_HANDLE_FINAL_ARG(modulespec) } return SECSuccess; } /************************************************************************ * Parse Full module specs into: library, commonName, module parameters, * and NSS specifi parameters. */ SECStatus NSSUTIL_ArgParseModuleSpec(const char *modulespec, char **lib, char **mod, char **parameters, char **nss) { int next; modulespec = NSSUTIL_ArgStrip(modulespec); *lib = *mod = *parameters = *nss = 0; while (*modulespec) { NSSUTIL_HANDLE_STRING_ARG(modulespec, *lib, "library=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *mod, "name=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *parameters, "parameters=", ;) NSSUTIL_HANDLE_STRING_ARG(modulespec, *nss, "nss=", ;) NSSUTIL_HANDLE_FINAL_ARG(modulespec) } return SECSuccess; } /************************************************************************ * make a new module spec from it's components */ char * NSSUTIL_MkModuleSpecEx(char *dllName, char *commonName, char *parameters, char *NSS, char *config) { char *moduleSpec; char *lib, *name, *param, *nss, *conf; /* * now the final spec */ lib = nssutil_formatPair("library", dllName, '\"'); name = nssutil_formatPair("name", commonName, '\"'); param = nssutil_formatPair("parameters", parameters, '\"'); nss = nssutil_formatPair("NSS", NSS, '\"'); if (config) { conf = nssutil_formatPair("config", config, '\"'); moduleSpec = PR_smprintf("%s %s %s %s %s", lib, name, param, nss, conf); nssutil_freePair(conf); } else { moduleSpec = PR_smprintf("%s %s %s %s", lib, name, param, nss); } nssutil_freePair(lib); nssutil_freePair(name); nssutil_freePair(param); nssutil_freePair(nss); return (moduleSpec); } /************************************************************************ * make a new module spec from it's components */ char * NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters, char *NSS) { return NSSUTIL_MkModuleSpecEx(dllName, commonName, parameters, NSS, NULL); } #define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA" /****************************************************************************** * Parse the cipher flags from the NSS parameter */ void NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers, const char *cipherList) { newCiphers[0] = newCiphers[1] = 0; if ((cipherList == NULL) || (*cipherList == 0)) return; for (; *cipherList; cipherList = NSSUTIL_ArgNextFlag(cipherList)) { if (PORT_Strncasecmp(cipherList, NSSUTIL_ARG_FORTEZZA_FLAG, sizeof(NSSUTIL_ARG_FORTEZZA_FLAG) - 1) == 0) { newCiphers[0] |= SECMOD_FORTEZZA_FLAG; } /* add additional flags here as necessary */ /* direct bit mapping escape */ if (*cipherList == 0) { if (cipherList[1] == 'l') { newCiphers[1] |= atoi(&cipherList[2]); } else { newCiphers[0] |= atoi(&cipherList[2]); } } } } /********************************************************************* * make NSS parameter... */ /* First make NSS specific flags */ #define MAX_FLAG_SIZE sizeof("internal") + sizeof("FIPS") + sizeof("moduleDB") + \ sizeof("moduleDBOnly") + sizeof("critical") static char * nssutil_mkNSSFlags(PRBool internal, PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical) { char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE); PRBool first = PR_TRUE; PORT_Memset(flags, 0, MAX_FLAG_SIZE); if (internal) { PORT_Strcat(flags, "internal"); first = PR_FALSE; } if (isFIPS) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "FIPS"); first = PR_FALSE; } if (isModuleDB) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "moduleDB"); first = PR_FALSE; } if (isModuleDBOnly) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "moduleDBOnly"); first = PR_FALSE; } if (isCritical) { if (!first) PORT_Strcat(flags, ","); PORT_Strcat(flags, "critical"); } return flags; } /* construct the NSS cipher flags */ static char * nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1) { char *cipher = NULL; unsigned int i; for (i = 0; i < sizeof(ssl0) * 8; i++) { if (ssl0 & (1UL << i)) { char *string; if ((1UL << i) == SECMOD_FORTEZZA_FLAG) { string = PR_smprintf("%s", NSSUTIL_ARG_FORTEZZA_FLAG); } else { string = PR_smprintf("0h0x%08lx", 1UL << i); } if (cipher) { char *tmp; tmp = PR_smprintf("%s,%s", cipher, string); PR_smprintf_free(cipher); PR_smprintf_free(string); cipher = tmp; } else { cipher = string; } } } for (i = 0; i < sizeof(ssl0) * 8; i++) { if (ssl1 & (1UL << i)) { if (cipher) { char *tmp; tmp = PR_smprintf("%s,0l0x%08lx", cipher, 1UL << i); PR_smprintf_free(cipher); cipher = tmp; } else { cipher = PR_smprintf("0l0x%08lx", 1UL << i); } } } return cipher; } /* Assemble a full NSS string. */ char * NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical, unsigned long trustOrder, unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1) { int slotLen, i; char *slotParams, *ciphers, *nss, *nssFlags; const char *tmp; char *trustOrderPair, *cipherOrderPair, *slotPair, *cipherPair, *flagPair; /* now let's build up the string * first the slot infos */ slotLen = 0; for (i = 0; i < (int)slotCount; i++) { slotLen += PORT_Strlen(slotStrings[i]) + 1; } slotLen += 1; /* space for the final NULL */ slotParams = (char *)PORT_ZAlloc(slotLen); PORT_Memset(slotParams, 0, slotLen); for (i = 0; i < (int)slotCount; i++) { PORT_Strcat(slotParams, slotStrings[i]); PORT_Strcat(slotParams, " "); PR_smprintf_free(slotStrings[i]); slotStrings[i] = NULL; } /* * now the NSS structure */ nssFlags = nssutil_mkNSSFlags(internal, isFIPS, isModuleDB, isModuleDBOnly, isCritical); /* for now only the internal module is critical */ ciphers = nssutil_mkCipherFlags(ssl0, ssl1); trustOrderPair = nssutil_formatIntPair("trustOrder", trustOrder, NSSUTIL_DEFAULT_TRUST_ORDER); cipherOrderPair = nssutil_formatIntPair("cipherOrder", cipherOrder, NSSUTIL_DEFAULT_CIPHER_ORDER); slotPair = nssutil_formatPair("slotParams", slotParams, '{'); /* } */ if (slotParams) PORT_Free(slotParams); cipherPair = nssutil_formatPair("ciphers", ciphers, '\''); if (ciphers) PR_smprintf_free(ciphers); flagPair = nssutil_formatPair("Flags", nssFlags, '\''); if (nssFlags) PORT_Free(nssFlags); nss = PR_smprintf("%s %s %s %s %s", trustOrderPair, cipherOrderPair, slotPair, cipherPair, flagPair); nssutil_freePair(trustOrderPair); nssutil_freePair(cipherOrderPair); nssutil_freePair(slotPair); nssutil_freePair(cipherPair); nssutil_freePair(flagPair); tmp = NSSUTIL_ArgStrip(nss); if (*tmp == '\0') { PR_smprintf_free(nss); nss = NULL; } return nss; } /***************************************************************************** * * Private calls for use by softoken and utilmod.c */ #define SQLDB "sql:" #define EXTERNDB "extern:" #define LEGACY "dbm:" #define MULTIACCESS "multiaccess:" #define SECMOD_DB "secmod.db" const char * _NSSUTIL_EvaluateConfigDir(const char *configdir, NSSDBType *pdbType, char **appName) { NSSDBType dbType; PRBool checkEnvDefaultDB = PR_FALSE; *appName = NULL; /* force the default */ #ifdef NSS_DISABLE_DBM dbType = NSS_DB_TYPE_SQL; #else dbType = NSS_DB_TYPE_LEGACY; #endif if (configdir == NULL) { checkEnvDefaultDB = PR_TRUE; } else if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS) - 1) == 0) { char *cdir; dbType = NSS_DB_TYPE_MULTIACCESS; *appName = PORT_Strdup(configdir + sizeof(MULTIACCESS) - 1); if (*appName == NULL) { return configdir; } cdir = *appName; while (*cdir && *cdir != ':') { cdir++; } if (*cdir == ':') { *cdir = 0; cdir++; } configdir = cdir; } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB) - 1) == 0) { dbType = NSS_DB_TYPE_SQL; configdir = configdir + sizeof(SQLDB) - 1; } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB) - 1) == 0) { dbType = NSS_DB_TYPE_EXTERN; configdir = configdir + sizeof(EXTERNDB) - 1; } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY) - 1) == 0) { dbType = NSS_DB_TYPE_LEGACY; configdir = configdir + sizeof(LEGACY) - 1; } else { checkEnvDefaultDB = PR_TRUE; } /* look up the default from the environment */ if (checkEnvDefaultDB) { char *defaultType = PR_GetEnvSecure("NSS_DEFAULT_DB_TYPE"); if (defaultType != NULL) { if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB) - 2) == 0) { dbType = NSS_DB_TYPE_SQL; } else if (PORT_Strncmp(defaultType, EXTERNDB, sizeof(EXTERNDB) - 2) == 0) { dbType = NSS_DB_TYPE_EXTERN; } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY) - 2) == 0) { dbType = NSS_DB_TYPE_LEGACY; } } } /* if the caller has already set a type, don't change it */ if (*pdbType == NSS_DB_TYPE_NONE) { *pdbType = dbType; } return configdir; } char * _NSSUTIL_GetSecmodName(const char *param, NSSDBType *dbType, char **appName, char **filename, PRBool *rw) { int next; char *configdir = NULL; char *secmodName = NULL; char *value = NULL; const char *save_params = param; const char *lconfigdir; PRBool noModDB = PR_FALSE; param = NSSUTIL_ArgStrip(param); while (*param) { NSSUTIL_HANDLE_STRING_ARG(param, configdir, "configDir=", ;) NSSUTIL_HANDLE_STRING_ARG(param, secmodName, "secmod=", ;) NSSUTIL_HANDLE_FINAL_ARG(param) } *rw = PR_TRUE; if (NSSUTIL_ArgHasFlag("flags", "readOnly", save_params)) { *rw = PR_FALSE; } if (!secmodName || *secmodName == '\0') { if (secmodName) PORT_Free(secmodName); secmodName = PORT_Strdup(SECMOD_DB); } *filename = secmodName; lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName); if (NSSUTIL_ArgHasFlag("flags", "noModDB", save_params)) { /* there isn't a module db, don't load the legacy support */ noModDB = PR_TRUE; *dbType = NSS_DB_TYPE_SQL; PORT_Free(*filename); *filename = NULL; *rw = PR_FALSE; } /* only use the renamed secmod for legacy databases */ if ((*dbType != NSS_DB_TYPE_LEGACY) && (*dbType != NSS_DB_TYPE_MULTIACCESS) && !NSSUTIL_ArgHasFlag("flags", "forceSecmodChoice", save_params)) { secmodName = "pkcs11.txt"; } if (noModDB) { value = NULL; } else if (lconfigdir && lconfigdir[0] != '\0') { value = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s", lconfigdir, secmodName); } else { value = PR_smprintf("%s", secmodName); } if (configdir) PORT_Free(configdir); return value; }