1314 lines
36 KiB
C
1314 lines
36 KiB
C
/* 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];
|
|
size_t 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((unsigned char)*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(ECC, SECMOD_ECC_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);
|
|
}
|
|
|
|
/************************************************************************
|
|
* add a single flag to the Flags= section inside the spec's NSS= section */
|
|
char *
|
|
NSSUTIL_AddNSSFlagToModuleSpec(char *spec, char *addFlag)
|
|
{
|
|
const char *prefix = "flags=";
|
|
const size_t prefixLen = strlen(prefix);
|
|
char *lib = NULL, *name = NULL, *param = NULL, *nss = NULL, *conf = NULL;
|
|
char *nss2 = NULL, *result = NULL;
|
|
SECStatus rv;
|
|
|
|
rv = NSSUTIL_ArgParseModuleSpecEx(spec, &lib, &name, ¶m, &nss, &conf);
|
|
if (rv != SECSuccess) {
|
|
return NULL;
|
|
}
|
|
|
|
if (nss && NSSUTIL_ArgHasFlag("flags", addFlag, nss)) {
|
|
/* It's already there, nothing to do! */
|
|
PORT_Free(lib);
|
|
PORT_Free(name);
|
|
PORT_Free(param);
|
|
PORT_Free(nss);
|
|
PORT_Free(conf);
|
|
return PORT_Strdup(spec);
|
|
}
|
|
|
|
if (!nss || !strlen(nss)) {
|
|
nss2 = PORT_Alloc(prefixLen + strlen(addFlag) + 1);
|
|
PORT_Strcpy(nss2, prefix);
|
|
PORT_Strcat(nss2, addFlag);
|
|
} else {
|
|
const char *iNss = nss;
|
|
PRBool alreadyAdded = PR_FALSE;
|
|
size_t maxSize = strlen(nss) + strlen(addFlag) + prefixLen + 2; /* space and null terminator */
|
|
nss2 = PORT_Alloc(maxSize);
|
|
*nss2 = 0;
|
|
while (*iNss) {
|
|
iNss = NSSUTIL_ArgStrip(iNss);
|
|
if (PORT_Strncasecmp(iNss, prefix, prefixLen) == 0) {
|
|
/* We found an existing Flags= section. */
|
|
char *oldFlags;
|
|
const char *valPtr;
|
|
int valSize;
|
|
valPtr = iNss + prefixLen;
|
|
oldFlags = NSSUTIL_ArgFetchValue(valPtr, &valSize);
|
|
iNss = valPtr + valSize;
|
|
PORT_Strcat(nss2, prefix);
|
|
PORT_Strcat(nss2, oldFlags);
|
|
PORT_Strcat(nss2, ",");
|
|
PORT_Strcat(nss2, addFlag);
|
|
PORT_Strcat(nss2, " ");
|
|
PORT_Free(oldFlags);
|
|
alreadyAdded = PR_TRUE;
|
|
iNss = NSSUTIL_ArgStrip(iNss);
|
|
PORT_Strcat(nss2, iNss); /* remainder of input */
|
|
break;
|
|
} else {
|
|
/* Append this other name=value pair and continue. */
|
|
const char *startOfNext = NSSUTIL_ArgSkipParameter(iNss);
|
|
PORT_Strncat(nss2, iNss, (startOfNext - iNss));
|
|
if (nss2[strlen(nss2) - 1] != ' ') {
|
|
PORT_Strcat(nss2, " ");
|
|
}
|
|
iNss = startOfNext;
|
|
}
|
|
iNss = NSSUTIL_ArgStrip(iNss);
|
|
}
|
|
if (!alreadyAdded) {
|
|
/* nss wasn't empty, and it didn't contain a Flags section. We can
|
|
* assume that other content from nss has already been added to
|
|
* nss2, which means we already have a trailing space separator. */
|
|
PORT_Strcat(nss2, prefix);
|
|
PORT_Strcat(nss2, addFlag);
|
|
}
|
|
}
|
|
|
|
result = NSSUTIL_MkModuleSpecEx(lib, name, param, nss2, conf);
|
|
PORT_Free(lib);
|
|
PORT_Free(name);
|
|
PORT_Free(param);
|
|
PORT_Free(nss);
|
|
PORT_Free(nss2);
|
|
PORT_Free(conf);
|
|
return result;
|
|
}
|
|
|
|
#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 */
|
|
dbType = NSS_DB_TYPE_SQL;
|
|
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;
|
|
}
|