1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/util/utilpars.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,1117 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * The following code handles the storage of PKCS 11 modules used by the 1.9 + * NSS. This file is written to abstract away how the modules are 1.10 + * stored so we can decide that later. 1.11 + */ 1.12 +#include "secport.h" 1.13 +#include "prprf.h" 1.14 +#include "prenv.h" 1.15 +#include "utilpars.h" 1.16 +#include "utilmodt.h" 1.17 + 1.18 +/* 1.19 + * return the expected matching quote value for the one specified 1.20 + */ 1.21 +PRBool NSSUTIL_ArgGetPair(char c) { 1.22 + switch (c) { 1.23 + case '\'': return c; 1.24 + case '\"': return c; 1.25 + case '<': return '>'; 1.26 + case '{': return '}'; 1.27 + case '[': return ']'; 1.28 + case '(': return ')'; 1.29 + default: break; 1.30 + } 1.31 + return ' '; 1.32 +} 1.33 + 1.34 +PRBool NSSUTIL_ArgIsBlank(char c) { 1.35 + return isspace((unsigned char )c); 1.36 +} 1.37 + 1.38 +PRBool NSSUTIL_ArgIsEscape(char c) { 1.39 + return c == '\\'; 1.40 +} 1.41 + 1.42 +PRBool NSSUTIL_ArgIsQuote(char c) { 1.43 + switch (c) { 1.44 + case '\'': 1.45 + case '\"': 1.46 + case '<': 1.47 + case '{': /* } end curly to keep vi bracket matching working */ 1.48 + case '(': /* ) */ 1.49 + case '[': /* ] */ return PR_TRUE; 1.50 + default: break; 1.51 + } 1.52 + return PR_FALSE; 1.53 +} 1.54 + 1.55 +char *NSSUTIL_ArgStrip(char *c) { 1.56 + while (*c && NSSUTIL_ArgIsBlank(*c)) c++; 1.57 + return c; 1.58 +} 1.59 + 1.60 +/* 1.61 + * find the end of the current tag/value pair. string should be pointing just 1.62 + * after the equal sign. Handles quoted characters. 1.63 + */ 1.64 +char * 1.65 +NSSUTIL_ArgFindEnd(char *string) { 1.66 + char endChar = ' '; 1.67 + PRBool lastEscape = PR_FALSE; 1.68 + 1.69 + if (NSSUTIL_ArgIsQuote(*string)) { 1.70 + endChar = NSSUTIL_ArgGetPair(*string); 1.71 + string++; 1.72 + } 1.73 + 1.74 + for (;*string; string++) { 1.75 + if (lastEscape) { 1.76 + lastEscape = PR_FALSE; 1.77 + continue; 1.78 + } 1.79 + if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { 1.80 + lastEscape = PR_TRUE; 1.81 + continue; 1.82 + } 1.83 + if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string)) break; 1.84 + if (*string == endChar) { 1.85 + break; 1.86 + } 1.87 + } 1.88 + 1.89 + return string; 1.90 +} 1.91 + 1.92 +/* 1.93 + * get the value pointed to by string. string should be pointing just beyond 1.94 + * the equal sign. 1.95 + */ 1.96 +char * 1.97 +NSSUTIL_ArgFetchValue(char *string, int *pcount) 1.98 +{ 1.99 + char *end = NSSUTIL_ArgFindEnd(string); 1.100 + char *retString, *copyString; 1.101 + PRBool lastEscape = PR_FALSE; 1.102 + int len; 1.103 + 1.104 + len = end - string; 1.105 + if (len == 0) { 1.106 + *pcount = 0; 1.107 + return NULL; 1.108 + } 1.109 + 1.110 + copyString = retString = (char *)PORT_Alloc(len+1); 1.111 + 1.112 + if (*end) len++; 1.113 + *pcount = len; 1.114 + if (retString == NULL) return NULL; 1.115 + 1.116 + 1.117 + if (NSSUTIL_ArgIsQuote(*string)) string++; 1.118 + for (; string < end; string++) { 1.119 + if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { 1.120 + lastEscape = PR_TRUE; 1.121 + continue; 1.122 + } 1.123 + lastEscape = PR_FALSE; 1.124 + *copyString++ = *string; 1.125 + } 1.126 + *copyString = 0; 1.127 + return retString; 1.128 +} 1.129 + 1.130 +/* 1.131 + * point to the next parameter in string 1.132 + */ 1.133 +char * 1.134 +NSSUTIL_ArgSkipParameter(char *string) 1.135 +{ 1.136 + char *end; 1.137 + /* look for the end of the <name>= */ 1.138 + for (;*string; string++) { 1.139 + if (*string == '=') { string++; break; } 1.140 + if (NSSUTIL_ArgIsBlank(*string)) return(string); 1.141 + } 1.142 + 1.143 + end = NSSUTIL_ArgFindEnd(string); 1.144 + if (*end) end++; 1.145 + return end; 1.146 +} 1.147 + 1.148 +/* 1.149 + * get the value from that tag value pair. 1.150 + */ 1.151 +char * 1.152 +NSSUTIL_ArgGetParamValue(char *paramName,char *parameters) 1.153 +{ 1.154 + char searchValue[256]; 1.155 + int paramLen = strlen(paramName); 1.156 + char *returnValue = NULL; 1.157 + int next; 1.158 + 1.159 + if ((parameters == NULL) || (*parameters == 0)) return NULL; 1.160 + 1.161 + PORT_Assert(paramLen+2 < sizeof(searchValue)); 1.162 + 1.163 + PORT_Strcpy(searchValue,paramName); 1.164 + PORT_Strcat(searchValue,"="); 1.165 + while (*parameters) { 1.166 + if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) { 1.167 + parameters += paramLen+1; 1.168 + returnValue = NSSUTIL_ArgFetchValue(parameters,&next); 1.169 + break; 1.170 + } else { 1.171 + parameters = NSSUTIL_ArgSkipParameter(parameters); 1.172 + } 1.173 + parameters = NSSUTIL_ArgStrip(parameters); 1.174 + } 1.175 + return returnValue; 1.176 +} 1.177 + 1.178 +/* 1.179 + * find the next flag in the parameter list 1.180 + */ 1.181 +char * 1.182 +NSSUTIL_ArgNextFlag(char *flags) 1.183 +{ 1.184 + for (; *flags ; flags++) { 1.185 + if (*flags == ',') { 1.186 + flags++; 1.187 + break; 1.188 + } 1.189 + } 1.190 + return flags; 1.191 +} 1.192 + 1.193 +/* 1.194 + * return true if the flag is set in the label parameter. 1.195 + */ 1.196 +PRBool 1.197 +NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters) 1.198 +{ 1.199 + char *flags,*index; 1.200 + int len = strlen(flag); 1.201 + PRBool found = PR_FALSE; 1.202 + 1.203 + flags = NSSUTIL_ArgGetParamValue(label,parameters); 1.204 + if (flags == NULL) return PR_FALSE; 1.205 + 1.206 + for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) { 1.207 + if (PORT_Strncasecmp(index,flag,len) == 0) { 1.208 + found=PR_TRUE; 1.209 + break; 1.210 + } 1.211 + } 1.212 + PORT_Free(flags); 1.213 + return found; 1.214 +} 1.215 + 1.216 +/* 1.217 + * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal 1.218 + */ 1.219 +long 1.220 +NSSUTIL_ArgDecodeNumber(char *num) 1.221 +{ 1.222 + int radix = 10; 1.223 + unsigned long value = 0; 1.224 + long retValue = 0; 1.225 + int sign = 1; 1.226 + int digit; 1.227 + 1.228 + if (num == NULL) return retValue; 1.229 + 1.230 + num = NSSUTIL_ArgStrip(num); 1.231 + 1.232 + if (*num == '-') { 1.233 + sign = -1; 1.234 + num++; 1.235 + } 1.236 + 1.237 + if (*num == '0') { 1.238 + radix = 8; 1.239 + num++; 1.240 + if ((*num == 'x') || (*num == 'X')) { 1.241 + radix = 16; 1.242 + num++; 1.243 + } 1.244 + } 1.245 + 1.246 + 1.247 + for ( ;*num; num++ ) { 1.248 + if (isdigit(*num)) { 1.249 + digit = *num - '0'; 1.250 + } else if ((*num >= 'a') && (*num <= 'f')) { 1.251 + digit = *num - 'a' + 10; 1.252 + } else if ((*num >= 'A') && (*num <= 'F')) { 1.253 + digit = *num - 'A' + 10; 1.254 + } else { 1.255 + break; 1.256 + } 1.257 + if (digit >= radix) break; 1.258 + value = value*radix + digit; 1.259 + } 1.260 + 1.261 + retValue = ((int) value) * sign; 1.262 + return retValue; 1.263 +} 1.264 + 1.265 +/* 1.266 + * parameters are tag value pairs. This function returns the tag or label (the 1.267 + * value before the equal size. 1.268 + */ 1.269 +char * 1.270 +NSSUTIL_ArgGetLabel(char *inString, int *next) 1.271 +{ 1.272 + char *name=NULL; 1.273 + char *string; 1.274 + int len; 1.275 + 1.276 + /* look for the end of the <label>= */ 1.277 + for (string = inString;*string; string++) { 1.278 + if (*string == '=') { break; } 1.279 + if (NSSUTIL_ArgIsBlank(*string)) break; 1.280 + } 1.281 + 1.282 + len = string - inString; 1.283 + 1.284 + *next = len; 1.285 + if (*string == '=') (*next) += 1; 1.286 + if (len > 0) { 1.287 + name = PORT_Alloc(len+1); 1.288 + PORT_Strncpy(name,inString,len); 1.289 + name[len] = 0; 1.290 + } 1.291 + return name; 1.292 +} 1.293 + 1.294 +/* 1.295 + * read an argument at a Long integer 1.296 + */ 1.297 +long 1.298 +NSSUTIL_ArgReadLong(char *label,char *params, long defValue, PRBool *isdefault) 1.299 +{ 1.300 + char *value; 1.301 + long retValue; 1.302 + if (isdefault) *isdefault = PR_FALSE; 1.303 + 1.304 + value = NSSUTIL_ArgGetParamValue(label,params); 1.305 + if (value == NULL) { 1.306 + if (isdefault) *isdefault = PR_TRUE; 1.307 + return defValue; 1.308 + } 1.309 + retValue = NSSUTIL_ArgDecodeNumber(value); 1.310 + if (value) PORT_Free(value); 1.311 + 1.312 + return retValue; 1.313 +} 1.314 + 1.315 + 1.316 +/* 1.317 + * prepare a string to be quoted with 'quote' marks. We do that by adding 1.318 + * appropriate escapes. 1.319 + */ 1.320 +static int 1.321 +nssutil_escapeQuotesSize(const char *string, char quote, PRBool addquotes) 1.322 +{ 1.323 + int escapes = 0, size = 0; 1.324 + const char *src; 1.325 + 1.326 + size= addquotes ? 2 : 0; 1.327 + for (src=string; *src ; src++) { 1.328 + if ((*src == quote) || (*src == '\\')) escapes++; 1.329 + size++; 1.330 + } 1.331 + return size+escapes+1; 1.332 + 1.333 +} 1.334 + 1.335 +static char * 1.336 +nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes) 1.337 +{ 1.338 + char *newString = 0; 1.339 + int size = 0; 1.340 + const char *src; 1.341 + char *dest; 1.342 + 1.343 + size = nssutil_escapeQuotesSize(string, quote, addquotes); 1.344 + 1.345 + dest = newString = PORT_ZAlloc(size); 1.346 + if (newString == NULL) { 1.347 + return NULL; 1.348 + } 1.349 + 1.350 + if (addquotes) *dest++=quote; 1.351 + for (src=string; *src; src++,dest++) { 1.352 + if ((*src == '\\') || (*src == quote)) { 1.353 + *dest++ = '\\'; 1.354 + } 1.355 + *dest = *src; 1.356 + } 1.357 + if (addquotes) *dest=quote; 1.358 + 1.359 + return newString; 1.360 +} 1.361 + 1.362 +int 1.363 +NSSUTIL_EscapeSize(const char *string, char quote) 1.364 +{ 1.365 + return nssutil_escapeQuotesSize(string, quote, PR_FALSE); 1.366 +} 1.367 + 1.368 +char * 1.369 +NSSUTIL_Escape(const char *string, char quote) 1.370 +{ 1.371 + return nssutil_escapeQuotes(string, quote, PR_FALSE); 1.372 +} 1.373 + 1.374 + 1.375 +int 1.376 +NSSUTIL_QuoteSize(const char *string, char quote) 1.377 +{ 1.378 + return nssutil_escapeQuotesSize(string, quote, PR_TRUE); 1.379 +} 1.380 + 1.381 +char * 1.382 +NSSUTIL_Quote(const char *string, char quote) 1.383 +{ 1.384 + return nssutil_escapeQuotes(string, quote, PR_TRUE); 1.385 +} 1.386 + 1.387 +int 1.388 +NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2) 1.389 +{ 1.390 + int escapes = 0, size = 0; 1.391 + const char *src; 1.392 + for (src=string; *src ; src++) { 1.393 + if (*src == '\\') escapes+=3; /* \\\\ */ 1.394 + if (*src == quote1) escapes+=2; /* \\quote1 */ 1.395 + if (*src == quote2) escapes++; /* \quote2 */ 1.396 + size++; 1.397 + } 1.398 + 1.399 + return escapes+size+1; 1.400 +} 1.401 + 1.402 +char * 1.403 +NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2) 1.404 +{ 1.405 + char *round1 = NULL; 1.406 + char *retValue = NULL; 1.407 + if (string == NULL) { 1.408 + goto done; 1.409 + } 1.410 + round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE); 1.411 + if (round1) { 1.412 + retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE); 1.413 + PORT_Free(round1); 1.414 + } 1.415 + 1.416 +done: 1.417 + if (retValue == NULL) { 1.418 + retValue = PORT_Strdup(""); 1.419 + } 1.420 + return retValue; 1.421 +} 1.422 + 1.423 + 1.424 +/************************************************************************ 1.425 + * These functions are used in contructing strings. 1.426 + * NOTE: they will always return a string, but sometimes it will return 1.427 + * a specific NULL string. These strings must be freed with util_freePair. 1.428 + */ 1.429 + 1.430 +/* string to return on error... */ 1.431 +static char *nssutil_nullString = ""; 1.432 + 1.433 +static char * 1.434 +nssutil_formatValue(PLArenaPool *arena, char *value, char quote) 1.435 +{ 1.436 + char *vp,*vp2,*retval; 1.437 + int size = 0, escapes = 0; 1.438 + 1.439 + for (vp=value; *vp ;vp++) { 1.440 + if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) escapes++; 1.441 + size++; 1.442 + } 1.443 + if (arena) { 1.444 + retval = PORT_ArenaZAlloc(arena,size+escapes+1); 1.445 + } else { 1.446 + retval = PORT_ZAlloc(size+escapes+1); 1.447 + } 1.448 + if (retval == NULL) return NULL; 1.449 + vp2 = retval; 1.450 + for (vp=value; *vp; vp++) { 1.451 + if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) 1.452 + *vp2++ = NSSUTIL_ARG_ESCAPE; 1.453 + *vp2++ = *vp; 1.454 + } 1.455 + return retval; 1.456 +} 1.457 + 1.458 + 1.459 +static PRBool nssutil_argHasChar(char *v, char c) 1.460 +{ 1.461 + for ( ;*v; v++) { 1.462 + if (*v == c) return PR_TRUE; 1.463 + } 1.464 + return PR_FALSE; 1.465 +} 1.466 + 1.467 +static PRBool nssutil_argHasBlanks(char *v) 1.468 +{ 1.469 + for ( ;*v; v++) { 1.470 + if (NSSUTIL_ArgIsBlank(*v)) return PR_TRUE; 1.471 + } 1.472 + return PR_FALSE; 1.473 +} 1.474 + 1.475 +static char * 1.476 +nssutil_formatPair(char *name, char *value, char quote) 1.477 +{ 1.478 + char openQuote = quote; 1.479 + char closeQuote = NSSUTIL_ArgGetPair(quote); 1.480 + char *newValue = NULL; 1.481 + char *returnValue; 1.482 + PRBool need_quote = PR_FALSE; 1.483 + 1.484 + if (!value || (*value == 0)) return nssutil_nullString; 1.485 + 1.486 + if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0])) 1.487 + need_quote=PR_TRUE; 1.488 + 1.489 + if ((need_quote && nssutil_argHasChar(value,closeQuote)) 1.490 + || nssutil_argHasChar(value,NSSUTIL_ARG_ESCAPE)) { 1.491 + value = newValue = nssutil_formatValue(NULL, value,quote); 1.492 + if (newValue == NULL) return nssutil_nullString; 1.493 + } 1.494 + if (need_quote) { 1.495 + returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote); 1.496 + } else { 1.497 + returnValue = PR_smprintf("%s=%s",name,value); 1.498 + } 1.499 + if (returnValue == NULL) returnValue = nssutil_nullString; 1.500 + 1.501 + if (newValue) PORT_Free(newValue); 1.502 + 1.503 + return returnValue; 1.504 +} 1.505 + 1.506 +static char *nssutil_formatIntPair(char *name, unsigned long value, 1.507 + unsigned long def) 1.508 +{ 1.509 + char *returnValue; 1.510 + 1.511 + if (value == def) return nssutil_nullString; 1.512 + 1.513 + returnValue = PR_smprintf("%s=%d",name,value); 1.514 + 1.515 + return returnValue; 1.516 +} 1.517 + 1.518 +static void 1.519 +nssutil_freePair(char *pair) 1.520 +{ 1.521 + if (pair && pair != nssutil_nullString) { 1.522 + PR_smprintf_free(pair); 1.523 + } 1.524 +} 1.525 + 1.526 + 1.527 +/************************************************************************ 1.528 + * Parse the Slot specific parameters in the NSS params. 1.529 + */ 1.530 + 1.531 +struct nssutilArgSlotFlagTable { 1.532 + char *name; 1.533 + int len; 1.534 + unsigned long value; 1.535 +}; 1.536 + 1.537 +#define NSSUTIL_ARG_ENTRY(arg,flag) \ 1.538 +{ #arg , sizeof(#arg)-1, flag } 1.539 +static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = { 1.540 + NSSUTIL_ARG_ENTRY(RSA,SECMOD_RSA_FLAG), 1.541 + NSSUTIL_ARG_ENTRY(DSA,SECMOD_RSA_FLAG), 1.542 + NSSUTIL_ARG_ENTRY(RC2,SECMOD_RC4_FLAG), 1.543 + NSSUTIL_ARG_ENTRY(RC4,SECMOD_RC2_FLAG), 1.544 + NSSUTIL_ARG_ENTRY(DES,SECMOD_DES_FLAG), 1.545 + NSSUTIL_ARG_ENTRY(DH,SECMOD_DH_FLAG), 1.546 + NSSUTIL_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG), 1.547 + NSSUTIL_ARG_ENTRY(RC5,SECMOD_RC5_FLAG), 1.548 + NSSUTIL_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG), 1.549 + NSSUTIL_ARG_ENTRY(SHA256,SECMOD_SHA256_FLAG), 1.550 + NSSUTIL_ARG_ENTRY(SHA512,SECMOD_SHA512_FLAG), 1.551 + NSSUTIL_ARG_ENTRY(MD5,SECMOD_MD5_FLAG), 1.552 + NSSUTIL_ARG_ENTRY(MD2,SECMOD_MD2_FLAG), 1.553 + NSSUTIL_ARG_ENTRY(SSL,SECMOD_SSL_FLAG), 1.554 + NSSUTIL_ARG_ENTRY(TLS,SECMOD_TLS_FLAG), 1.555 + NSSUTIL_ARG_ENTRY(AES,SECMOD_AES_FLAG), 1.556 + NSSUTIL_ARG_ENTRY(Camellia,SECMOD_CAMELLIA_FLAG), 1.557 + NSSUTIL_ARG_ENTRY(SEED,SECMOD_SEED_FLAG), 1.558 + NSSUTIL_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG), 1.559 + NSSUTIL_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG), 1.560 + NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG), 1.561 +}; 1.562 + 1.563 +static int nssutil_argSlotFlagTableSize = 1.564 + sizeof(nssutil_argSlotFlagTable)/sizeof(nssutil_argSlotFlagTable[0]); 1.565 + 1.566 + 1.567 +/* turn the slot flags into a bit mask */ 1.568 +unsigned long 1.569 +NSSUTIL_ArgParseSlotFlags(char *label,char *params) 1.570 +{ 1.571 + char *flags,*index; 1.572 + unsigned long retValue = 0; 1.573 + int i; 1.574 + PRBool all = PR_FALSE; 1.575 + 1.576 + flags = NSSUTIL_ArgGetParamValue(label,params); 1.577 + if (flags == NULL) return 0; 1.578 + 1.579 + if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE; 1.580 + 1.581 + for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) { 1.582 + for (i=0; i < nssutil_argSlotFlagTableSize; i++) { 1.583 + if (all || 1.584 + (PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name, 1.585 + nssutil_argSlotFlagTable[i].len) == 0)) { 1.586 + retValue |= nssutil_argSlotFlagTable[i].value; 1.587 + } 1.588 + } 1.589 + } 1.590 + PORT_Free(flags); 1.591 + return retValue; 1.592 +} 1.593 + 1.594 + 1.595 +/* parse a single slot specific parameter */ 1.596 +static void 1.597 +nssutil_argDecodeSingleSlotInfo(char *name, char *params, 1.598 + struct NSSUTILPreSlotInfoStr *slotInfo) 1.599 +{ 1.600 + char *askpw; 1.601 + 1.602 + slotInfo->slotID=NSSUTIL_ArgDecodeNumber(name); 1.603 + slotInfo->defaultFlags=NSSUTIL_ArgParseSlotFlags("slotFlags",params); 1.604 + slotInfo->timeout=NSSUTIL_ArgReadLong("timeout",params, 0, NULL); 1.605 + 1.606 + askpw = NSSUTIL_ArgGetParamValue("askpw",params); 1.607 + slotInfo->askpw = 0; 1.608 + 1.609 + if (askpw) { 1.610 + if (PORT_Strcasecmp(askpw,"every") == 0) { 1.611 + slotInfo->askpw = -1; 1.612 + } else if (PORT_Strcasecmp(askpw,"timeout") == 0) { 1.613 + slotInfo->askpw = 1; 1.614 + } 1.615 + PORT_Free(askpw); 1.616 + slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS; 1.617 + } 1.618 + slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts", 1.619 + params); 1.620 + slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust", 1.621 + params); 1.622 +} 1.623 + 1.624 +/* parse all the slot specific parameters. */ 1.625 +struct NSSUTILPreSlotInfoStr * 1.626 +NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, char *slotParams, int *retCount) 1.627 +{ 1.628 + char *slotIndex; 1.629 + struct NSSUTILPreSlotInfoStr *slotInfo = NULL; 1.630 + int i=0,count = 0,next; 1.631 + 1.632 + *retCount = 0; 1.633 + if ((slotParams == NULL) || (*slotParams == 0)) return NULL; 1.634 + 1.635 + /* first count the number of slots */ 1.636 + for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex; 1.637 + slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) { 1.638 + count++; 1.639 + } 1.640 + 1.641 + /* get the data structures */ 1.642 + if (arena) { 1.643 + slotInfo = PORT_ArenaZNewArray(arena, 1.644 + struct NSSUTILPreSlotInfoStr, count); 1.645 + } else { 1.646 + slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count); 1.647 + } 1.648 + if (slotInfo == NULL) return NULL; 1.649 + 1.650 + for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0; 1.651 + *slotIndex && i < count ; ) { 1.652 + char *name; 1.653 + name = NSSUTIL_ArgGetLabel(slotIndex,&next); 1.654 + slotIndex += next; 1.655 + 1.656 + if (!NSSUTIL_ArgIsBlank(*slotIndex)) { 1.657 + char *args = NSSUTIL_ArgFetchValue(slotIndex,&next); 1.658 + slotIndex += next; 1.659 + if (args) { 1.660 + nssutil_argDecodeSingleSlotInfo(name,args,&slotInfo[i]); 1.661 + i++; 1.662 + PORT_Free(args); 1.663 + } 1.664 + } 1.665 + if (name) PORT_Free(name); 1.666 + slotIndex = NSSUTIL_ArgStrip(slotIndex); 1.667 + } 1.668 + *retCount = i; 1.669 + return slotInfo; 1.670 +} 1.671 + 1.672 +/************************************************************************ 1.673 + * make a new slot specific parameter 1.674 + */ 1.675 +/* first make the slot flags */ 1.676 +static char * 1.677 +nssutil_mkSlotFlags(unsigned long defaultFlags) 1.678 +{ 1.679 + char *flags=NULL; 1.680 + int i,j; 1.681 + 1.682 + for (i=0; i < sizeof(defaultFlags)*8; i++) { 1.683 + if (defaultFlags & (1UL <<i)) { 1.684 + char *string = NULL; 1.685 + 1.686 + for (j=0; j < nssutil_argSlotFlagTableSize; j++) { 1.687 + if (nssutil_argSlotFlagTable[j].value == ( 1UL << i )) { 1.688 + string = nssutil_argSlotFlagTable[j].name; 1.689 + break; 1.690 + } 1.691 + } 1.692 + if (string) { 1.693 + if (flags) { 1.694 + char *tmp; 1.695 + tmp = PR_smprintf("%s,%s",flags,string); 1.696 + PR_smprintf_free(flags); 1.697 + flags = tmp; 1.698 + } else { 1.699 + flags = PR_smprintf("%s",string); 1.700 + } 1.701 + } 1.702 + } 1.703 + } 1.704 + 1.705 + return flags; 1.706 +} 1.707 + 1.708 +/* now make the root flags */ 1.709 +#define NSSUTIL_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts")+sizeof("hasRootTrust") 1.710 +static char * 1.711 +nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust) 1.712 +{ 1.713 + char *flags= (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE); 1.714 + PRBool first = PR_TRUE; 1.715 + 1.716 + PORT_Memset(flags,0,NSSUTIL_MAX_ROOT_FLAG_SIZE); 1.717 + if (hasRootCerts) { 1.718 + PORT_Strcat(flags,"hasRootCerts"); 1.719 + first = PR_FALSE; 1.720 + } 1.721 + if (hasRootTrust) { 1.722 + if (!first) PORT_Strcat(flags,","); 1.723 + PORT_Strcat(flags,"hasRootTrust"); 1.724 + first = PR_FALSE; 1.725 + } 1.726 + return flags; 1.727 +} 1.728 + 1.729 +/* now make a full slot string */ 1.730 +char * 1.731 +NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags, 1.732 + unsigned long timeout, unsigned char askpw_in, 1.733 + PRBool hasRootCerts, PRBool hasRootTrust) { 1.734 + char *askpw,*flags,*rootFlags,*slotString; 1.735 + char *flagPair,*rootFlagsPair; 1.736 + 1.737 + switch (askpw_in) { 1.738 + case 0xff: 1.739 + askpw = "every"; 1.740 + break; 1.741 + case 1: 1.742 + askpw = "timeout"; 1.743 + break; 1.744 + default: 1.745 + askpw = "any"; 1.746 + break; 1.747 + } 1.748 + flags = nssutil_mkSlotFlags(defaultFlags); 1.749 + rootFlags = nssutil_mkRootFlags(hasRootCerts,hasRootTrust); 1.750 + flagPair = nssutil_formatPair("slotFlags",flags,'\''); 1.751 + rootFlagsPair = nssutil_formatPair("rootFlags",rootFlags,'\''); 1.752 + if (flags) PR_smprintf_free(flags); 1.753 + if (rootFlags) PORT_Free(rootFlags); 1.754 + if (defaultFlags & PK11_OWN_PW_DEFAULTS) { 1.755 + slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]", 1.756 + (PRUint32)slotID,flagPair,askpw,timeout, 1.757 + rootFlagsPair); 1.758 + } else { 1.759 + slotString = PR_smprintf("0x%08lx=[%s %s]", 1.760 + (PRUint32)slotID,flagPair,rootFlagsPair); 1.761 + } 1.762 + nssutil_freePair(flagPair); 1.763 + nssutil_freePair(rootFlagsPair); 1.764 + return slotString; 1.765 +} 1.766 + 1.767 + 1.768 +/************************************************************************ 1.769 + * Parse Full module specs into: library, commonName, module parameters, 1.770 + * and NSS specifi parameters. 1.771 + */ 1.772 +SECStatus 1.773 +NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod, 1.774 + char **parameters, char **nss) 1.775 +{ 1.776 + int next; 1.777 + modulespec = NSSUTIL_ArgStrip(modulespec); 1.778 + 1.779 + *lib = *mod = *parameters = *nss = 0; 1.780 + 1.781 + while (*modulespec) { 1.782 + NSSUTIL_HANDLE_STRING_ARG(modulespec,*lib,"library=",;) 1.783 + NSSUTIL_HANDLE_STRING_ARG(modulespec,*mod,"name=",;) 1.784 + NSSUTIL_HANDLE_STRING_ARG(modulespec,*parameters,"parameters=",;) 1.785 + NSSUTIL_HANDLE_STRING_ARG(modulespec,*nss,"nss=",;) 1.786 + NSSUTIL_HANDLE_FINAL_ARG(modulespec) 1.787 + } 1.788 + return SECSuccess; 1.789 +} 1.790 + 1.791 +/************************************************************************ 1.792 + * make a new module spec from it's components */ 1.793 +char * 1.794 +NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters, 1.795 + char *NSS) 1.796 +{ 1.797 + char *moduleSpec; 1.798 + char *lib,*name,*param,*nss; 1.799 + 1.800 + /* 1.801 + * now the final spec 1.802 + */ 1.803 + lib = nssutil_formatPair("library",dllName,'\"'); 1.804 + name = nssutil_formatPair("name",commonName,'\"'); 1.805 + param = nssutil_formatPair("parameters",parameters,'\"'); 1.806 + nss = nssutil_formatPair("NSS",NSS,'\"'); 1.807 + moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss); 1.808 + nssutil_freePair(lib); 1.809 + nssutil_freePair(name); 1.810 + nssutil_freePair(param); 1.811 + nssutil_freePair(nss); 1.812 + return (moduleSpec); 1.813 +} 1.814 + 1.815 + 1.816 +#define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA" 1.817 +/****************************************************************************** 1.818 + * Parse the cipher flags from the NSS parameter 1.819 + */ 1.820 +void 1.821 +NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,char *cipherList) 1.822 +{ 1.823 + newCiphers[0] = newCiphers[1] = 0; 1.824 + if ((cipherList == NULL) || (*cipherList == 0)) return; 1.825 + 1.826 + for (;*cipherList; cipherList=NSSUTIL_ArgNextFlag(cipherList)) { 1.827 + if (PORT_Strncasecmp(cipherList,NSSUTIL_ARG_FORTEZZA_FLAG, 1.828 + sizeof(NSSUTIL_ARG_FORTEZZA_FLAG)-1) == 0) { 1.829 + newCiphers[0] |= SECMOD_FORTEZZA_FLAG; 1.830 + } 1.831 + 1.832 + /* add additional flags here as necessary */ 1.833 + /* direct bit mapping escape */ 1.834 + if (*cipherList == 0) { 1.835 + if (cipherList[1] == 'l') { 1.836 + newCiphers[1] |= atoi(&cipherList[2]); 1.837 + } else { 1.838 + newCiphers[0] |= atoi(&cipherList[2]); 1.839 + } 1.840 + } 1.841 + } 1.842 +} 1.843 + 1.844 + 1.845 +/********************************************************************* 1.846 + * make NSS parameter... 1.847 + */ 1.848 +/* First make NSS specific flags */ 1.849 +#define MAX_FLAG_SIZE sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\ 1.850 + sizeof("moduleDBOnly")+sizeof("critical") 1.851 +static char * 1.852 +nssutil_mkNSSFlags(PRBool internal, PRBool isFIPS, 1.853 + PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical) 1.854 +{ 1.855 + char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE); 1.856 + PRBool first = PR_TRUE; 1.857 + 1.858 + PORT_Memset(flags,0,MAX_FLAG_SIZE); 1.859 + if (internal) { 1.860 + PORT_Strcat(flags,"internal"); 1.861 + first = PR_FALSE; 1.862 + } 1.863 + if (isFIPS) { 1.864 + if (!first) PORT_Strcat(flags,","); 1.865 + PORT_Strcat(flags,"FIPS"); 1.866 + first = PR_FALSE; 1.867 + } 1.868 + if (isModuleDB) { 1.869 + if (!first) PORT_Strcat(flags,","); 1.870 + PORT_Strcat(flags,"moduleDB"); 1.871 + first = PR_FALSE; 1.872 + } 1.873 + if (isModuleDBOnly) { 1.874 + if (!first) PORT_Strcat(flags,","); 1.875 + PORT_Strcat(flags,"moduleDBOnly"); 1.876 + first = PR_FALSE; 1.877 + } 1.878 + if (isCritical) { 1.879 + if (!first) PORT_Strcat(flags,","); 1.880 + PORT_Strcat(flags,"critical"); 1.881 + first = PR_FALSE; 1.882 + } 1.883 + return flags; 1.884 +} 1.885 + 1.886 + 1.887 +/* construct the NSS cipher flags */ 1.888 +static char * 1.889 +nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1) 1.890 +{ 1.891 + char *cipher = NULL; 1.892 + int i; 1.893 + 1.894 + for (i=0; i < sizeof(ssl0)*8; i++) { 1.895 + if (ssl0 & (1UL <<i)) { 1.896 + char *string; 1.897 + if ((1UL <<i) == SECMOD_FORTEZZA_FLAG) { 1.898 + string = PR_smprintf("%s",NSSUTIL_ARG_FORTEZZA_FLAG); 1.899 + } else { 1.900 + string = PR_smprintf("0h0x%08lx", 1UL <<i); 1.901 + } 1.902 + if (cipher) { 1.903 + char *tmp; 1.904 + tmp = PR_smprintf("%s,%s",cipher,string); 1.905 + PR_smprintf_free(cipher); 1.906 + PR_smprintf_free(string); 1.907 + cipher = tmp; 1.908 + } else { 1.909 + cipher = string; 1.910 + } 1.911 + } 1.912 + } 1.913 + for (i=0; i < sizeof(ssl0)*8; i++) { 1.914 + if (ssl1 & (1UL <<i)) { 1.915 + if (cipher) { 1.916 + char *tmp; 1.917 + tmp = PR_smprintf("%s,0l0x%08lx",cipher, 1UL <<i); 1.918 + PR_smprintf_free(cipher); 1.919 + cipher = tmp; 1.920 + } else { 1.921 + cipher = PR_smprintf("0l0x%08lx", 1UL <<i); 1.922 + } 1.923 + } 1.924 + } 1.925 + 1.926 + return cipher; 1.927 +} 1.928 + 1.929 +/* Assemble a full NSS string. */ 1.930 +char * 1.931 +NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal, 1.932 + PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly, 1.933 + PRBool isCritical, unsigned long trustOrder, 1.934 + unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1) 1.935 +{ 1.936 + int slotLen, i; 1.937 + char *slotParams, *ciphers, *nss, *nssFlags, *tmp; 1.938 + char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair; 1.939 + 1.940 + 1.941 + /* now let's build up the string 1.942 + * first the slot infos 1.943 + */ 1.944 + slotLen=0; 1.945 + for (i=0; i < (int)slotCount; i++) { 1.946 + slotLen += PORT_Strlen(slotStrings[i])+1; 1.947 + } 1.948 + slotLen += 1; /* space for the final NULL */ 1.949 + 1.950 + slotParams = (char *)PORT_ZAlloc(slotLen); 1.951 + PORT_Memset(slotParams,0,slotLen); 1.952 + for (i=0; i < (int)slotCount; i++) { 1.953 + PORT_Strcat(slotParams,slotStrings[i]); 1.954 + PORT_Strcat(slotParams," "); 1.955 + PR_smprintf_free(slotStrings[i]); 1.956 + slotStrings[i]=NULL; 1.957 + } 1.958 + 1.959 + /* 1.960 + * now the NSS structure 1.961 + */ 1.962 + nssFlags = nssutil_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly, 1.963 + isCritical); 1.964 + /* for now only the internal module is critical */ 1.965 + ciphers = nssutil_mkCipherFlags(ssl0, ssl1); 1.966 + 1.967 + trustOrderPair = nssutil_formatIntPair("trustOrder",trustOrder, 1.968 + NSSUTIL_DEFAULT_TRUST_ORDER); 1.969 + cipherOrderPair = nssutil_formatIntPair("cipherOrder",cipherOrder, 1.970 + NSSUTIL_DEFAULT_CIPHER_ORDER); 1.971 + slotPair=nssutil_formatPair("slotParams",slotParams,'{'); /* } */ 1.972 + if (slotParams) PORT_Free(slotParams); 1.973 + cipherPair=nssutil_formatPair("ciphers",ciphers,'\''); 1.974 + if (ciphers) PR_smprintf_free(ciphers); 1.975 + flagPair=nssutil_formatPair("Flags",nssFlags,'\''); 1.976 + if (nssFlags) PORT_Free(nssFlags); 1.977 + nss = PR_smprintf("%s %s %s %s %s",trustOrderPair, 1.978 + cipherOrderPair,slotPair,cipherPair,flagPair); 1.979 + nssutil_freePair(trustOrderPair); 1.980 + nssutil_freePair(cipherOrderPair); 1.981 + nssutil_freePair(slotPair); 1.982 + nssutil_freePair(cipherPair); 1.983 + nssutil_freePair(flagPair); 1.984 + tmp = NSSUTIL_ArgStrip(nss); 1.985 + if (*tmp == '\0') { 1.986 + PR_smprintf_free(nss); 1.987 + nss = NULL; 1.988 + } 1.989 + return nss; 1.990 +} 1.991 + 1.992 +/***************************************************************************** 1.993 + * 1.994 + * Private calls for use by softoken and utilmod.c 1.995 + */ 1.996 + 1.997 +#define SQLDB "sql:" 1.998 +#define EXTERNDB "extern:" 1.999 +#define LEGACY "dbm:" 1.1000 +#define MULTIACCESS "multiaccess:" 1.1001 +#define SECMOD_DB "secmod.db" 1.1002 +const char * 1.1003 +_NSSUTIL_EvaluateConfigDir(const char *configdir, 1.1004 + NSSDBType *pdbType, char **appName) 1.1005 +{ 1.1006 + NSSDBType dbType; 1.1007 + *appName = NULL; 1.1008 +/* force the default */ 1.1009 +#ifdef NSS_DISABLE_DBM 1.1010 + dbType = NSS_DB_TYPE_SQL; 1.1011 +#else 1.1012 + dbType = NSS_DB_TYPE_LEGACY; 1.1013 +#endif 1.1014 + if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) { 1.1015 + char *cdir; 1.1016 + dbType = NSS_DB_TYPE_MULTIACCESS; 1.1017 + 1.1018 + *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1); 1.1019 + if (*appName == NULL) { 1.1020 + return configdir; 1.1021 + } 1.1022 + cdir = *appName; 1.1023 + while (*cdir && *cdir != ':') { 1.1024 + cdir++; 1.1025 + } 1.1026 + if (*cdir == ':') { 1.1027 + *cdir = 0; 1.1028 + cdir++; 1.1029 + } 1.1030 + configdir = cdir; 1.1031 + } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB)-1) == 0) { 1.1032 + dbType = NSS_DB_TYPE_SQL; 1.1033 + configdir = configdir + sizeof(SQLDB) -1; 1.1034 + } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB)-1) == 0) { 1.1035 + dbType = NSS_DB_TYPE_EXTERN; 1.1036 + configdir = configdir + sizeof(EXTERNDB) -1; 1.1037 + } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY)-1) == 0) { 1.1038 + dbType = NSS_DB_TYPE_LEGACY; 1.1039 + configdir = configdir + sizeof(LEGACY) -1; 1.1040 + } else { 1.1041 + /* look up the default from the environment */ 1.1042 + char *defaultType = PR_GetEnv("NSS_DEFAULT_DB_TYPE"); 1.1043 + if (defaultType != NULL) { 1.1044 + if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB)-2) == 0) { 1.1045 + dbType = NSS_DB_TYPE_SQL; 1.1046 + } else if (PORT_Strncmp(defaultType,EXTERNDB,sizeof(EXTERNDB)-2)==0) { 1.1047 + dbType = NSS_DB_TYPE_EXTERN; 1.1048 + } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY)-2) == 0) { 1.1049 + dbType = NSS_DB_TYPE_LEGACY; 1.1050 + } 1.1051 + } 1.1052 + } 1.1053 + /* if the caller has already set a type, don't change it */ 1.1054 + if (*pdbType == NSS_DB_TYPE_NONE) { 1.1055 + *pdbType = dbType; 1.1056 + } 1.1057 + return configdir; 1.1058 +} 1.1059 + 1.1060 +char * 1.1061 +_NSSUTIL_GetSecmodName(char *param, NSSDBType *dbType, char **appName, 1.1062 + char **filename, PRBool *rw) 1.1063 +{ 1.1064 + int next; 1.1065 + char *configdir = NULL; 1.1066 + char *secmodName = NULL; 1.1067 + char *value = NULL; 1.1068 + char *save_params = param; 1.1069 + const char *lconfigdir; 1.1070 + PRBool noModDB = PR_FALSE; 1.1071 + param = NSSUTIL_ArgStrip(param); 1.1072 + 1.1073 + 1.1074 + while (*param) { 1.1075 + NSSUTIL_HANDLE_STRING_ARG(param,configdir,"configDir=",;) 1.1076 + NSSUTIL_HANDLE_STRING_ARG(param,secmodName,"secmod=",;) 1.1077 + NSSUTIL_HANDLE_FINAL_ARG(param) 1.1078 + } 1.1079 + 1.1080 + *rw = PR_TRUE; 1.1081 + if (NSSUTIL_ArgHasFlag("flags","readOnly",save_params)) { 1.1082 + *rw = PR_FALSE; 1.1083 + } 1.1084 + 1.1085 + if (!secmodName || *secmodName == '\0') { 1.1086 + if (secmodName) PORT_Free(secmodName); 1.1087 + secmodName = PORT_Strdup(SECMOD_DB); 1.1088 + } 1.1089 + 1.1090 + *filename = secmodName; 1.1091 + lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName); 1.1092 + 1.1093 + if (NSSUTIL_ArgHasFlag("flags","noModDB",save_params)) { 1.1094 + /* there isn't a module db, don't load the legacy support */ 1.1095 + noModDB = PR_TRUE; 1.1096 + *dbType = NSS_DB_TYPE_SQL; 1.1097 + PORT_Free(*filename); 1.1098 + *filename = NULL; 1.1099 + *rw = PR_FALSE; 1.1100 + } 1.1101 + 1.1102 + /* only use the renamed secmod for legacy databases */ 1.1103 + if ((*dbType != NSS_DB_TYPE_LEGACY) && 1.1104 + (*dbType != NSS_DB_TYPE_MULTIACCESS)) { 1.1105 + secmodName="pkcs11.txt"; 1.1106 + } 1.1107 + 1.1108 + if (noModDB) { 1.1109 + value = NULL; 1.1110 + } else if (lconfigdir && lconfigdir[0] != '\0') { 1.1111 + value = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s", 1.1112 + lconfigdir,secmodName); 1.1113 + } else { 1.1114 + value = PR_smprintf("%s",secmodName); 1.1115 + } 1.1116 + if (configdir) PORT_Free(configdir); 1.1117 + return value; 1.1118 +} 1.1119 + 1.1120 +