Thu, 22 Jan 2015 13:21:57 +0100
Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6
michael@0 | 1 | /* This Source Code Form is subject to the terms of the Mozilla Public |
michael@0 | 2 | * License, v. 2.0. If a copy of the MPL was not distributed with this |
michael@0 | 3 | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
michael@0 | 4 | /* |
michael@0 | 5 | * The following code handles the storage of PKCS 11 modules used by the |
michael@0 | 6 | * NSS. This file is written to abstract away how the modules are |
michael@0 | 7 | * stored so we can decide that later. |
michael@0 | 8 | */ |
michael@0 | 9 | #include "secport.h" |
michael@0 | 10 | #include "prprf.h" |
michael@0 | 11 | #include "prenv.h" |
michael@0 | 12 | #include "utilpars.h" |
michael@0 | 13 | #include "utilmodt.h" |
michael@0 | 14 | |
michael@0 | 15 | /* |
michael@0 | 16 | * return the expected matching quote value for the one specified |
michael@0 | 17 | */ |
michael@0 | 18 | PRBool NSSUTIL_ArgGetPair(char c) { |
michael@0 | 19 | switch (c) { |
michael@0 | 20 | case '\'': return c; |
michael@0 | 21 | case '\"': return c; |
michael@0 | 22 | case '<': return '>'; |
michael@0 | 23 | case '{': return '}'; |
michael@0 | 24 | case '[': return ']'; |
michael@0 | 25 | case '(': return ')'; |
michael@0 | 26 | default: break; |
michael@0 | 27 | } |
michael@0 | 28 | return ' '; |
michael@0 | 29 | } |
michael@0 | 30 | |
michael@0 | 31 | PRBool NSSUTIL_ArgIsBlank(char c) { |
michael@0 | 32 | return isspace((unsigned char )c); |
michael@0 | 33 | } |
michael@0 | 34 | |
michael@0 | 35 | PRBool NSSUTIL_ArgIsEscape(char c) { |
michael@0 | 36 | return c == '\\'; |
michael@0 | 37 | } |
michael@0 | 38 | |
michael@0 | 39 | PRBool NSSUTIL_ArgIsQuote(char c) { |
michael@0 | 40 | switch (c) { |
michael@0 | 41 | case '\'': |
michael@0 | 42 | case '\"': |
michael@0 | 43 | case '<': |
michael@0 | 44 | case '{': /* } end curly to keep vi bracket matching working */ |
michael@0 | 45 | case '(': /* ) */ |
michael@0 | 46 | case '[': /* ] */ return PR_TRUE; |
michael@0 | 47 | default: break; |
michael@0 | 48 | } |
michael@0 | 49 | return PR_FALSE; |
michael@0 | 50 | } |
michael@0 | 51 | |
michael@0 | 52 | char *NSSUTIL_ArgStrip(char *c) { |
michael@0 | 53 | while (*c && NSSUTIL_ArgIsBlank(*c)) c++; |
michael@0 | 54 | return c; |
michael@0 | 55 | } |
michael@0 | 56 | |
michael@0 | 57 | /* |
michael@0 | 58 | * find the end of the current tag/value pair. string should be pointing just |
michael@0 | 59 | * after the equal sign. Handles quoted characters. |
michael@0 | 60 | */ |
michael@0 | 61 | char * |
michael@0 | 62 | NSSUTIL_ArgFindEnd(char *string) { |
michael@0 | 63 | char endChar = ' '; |
michael@0 | 64 | PRBool lastEscape = PR_FALSE; |
michael@0 | 65 | |
michael@0 | 66 | if (NSSUTIL_ArgIsQuote(*string)) { |
michael@0 | 67 | endChar = NSSUTIL_ArgGetPair(*string); |
michael@0 | 68 | string++; |
michael@0 | 69 | } |
michael@0 | 70 | |
michael@0 | 71 | for (;*string; string++) { |
michael@0 | 72 | if (lastEscape) { |
michael@0 | 73 | lastEscape = PR_FALSE; |
michael@0 | 74 | continue; |
michael@0 | 75 | } |
michael@0 | 76 | if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { |
michael@0 | 77 | lastEscape = PR_TRUE; |
michael@0 | 78 | continue; |
michael@0 | 79 | } |
michael@0 | 80 | if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string)) break; |
michael@0 | 81 | if (*string == endChar) { |
michael@0 | 82 | break; |
michael@0 | 83 | } |
michael@0 | 84 | } |
michael@0 | 85 | |
michael@0 | 86 | return string; |
michael@0 | 87 | } |
michael@0 | 88 | |
michael@0 | 89 | /* |
michael@0 | 90 | * get the value pointed to by string. string should be pointing just beyond |
michael@0 | 91 | * the equal sign. |
michael@0 | 92 | */ |
michael@0 | 93 | char * |
michael@0 | 94 | NSSUTIL_ArgFetchValue(char *string, int *pcount) |
michael@0 | 95 | { |
michael@0 | 96 | char *end = NSSUTIL_ArgFindEnd(string); |
michael@0 | 97 | char *retString, *copyString; |
michael@0 | 98 | PRBool lastEscape = PR_FALSE; |
michael@0 | 99 | int len; |
michael@0 | 100 | |
michael@0 | 101 | len = end - string; |
michael@0 | 102 | if (len == 0) { |
michael@0 | 103 | *pcount = 0; |
michael@0 | 104 | return NULL; |
michael@0 | 105 | } |
michael@0 | 106 | |
michael@0 | 107 | copyString = retString = (char *)PORT_Alloc(len+1); |
michael@0 | 108 | |
michael@0 | 109 | if (*end) len++; |
michael@0 | 110 | *pcount = len; |
michael@0 | 111 | if (retString == NULL) return NULL; |
michael@0 | 112 | |
michael@0 | 113 | |
michael@0 | 114 | if (NSSUTIL_ArgIsQuote(*string)) string++; |
michael@0 | 115 | for (; string < end; string++) { |
michael@0 | 116 | if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) { |
michael@0 | 117 | lastEscape = PR_TRUE; |
michael@0 | 118 | continue; |
michael@0 | 119 | } |
michael@0 | 120 | lastEscape = PR_FALSE; |
michael@0 | 121 | *copyString++ = *string; |
michael@0 | 122 | } |
michael@0 | 123 | *copyString = 0; |
michael@0 | 124 | return retString; |
michael@0 | 125 | } |
michael@0 | 126 | |
michael@0 | 127 | /* |
michael@0 | 128 | * point to the next parameter in string |
michael@0 | 129 | */ |
michael@0 | 130 | char * |
michael@0 | 131 | NSSUTIL_ArgSkipParameter(char *string) |
michael@0 | 132 | { |
michael@0 | 133 | char *end; |
michael@0 | 134 | /* look for the end of the <name>= */ |
michael@0 | 135 | for (;*string; string++) { |
michael@0 | 136 | if (*string == '=') { string++; break; } |
michael@0 | 137 | if (NSSUTIL_ArgIsBlank(*string)) return(string); |
michael@0 | 138 | } |
michael@0 | 139 | |
michael@0 | 140 | end = NSSUTIL_ArgFindEnd(string); |
michael@0 | 141 | if (*end) end++; |
michael@0 | 142 | return end; |
michael@0 | 143 | } |
michael@0 | 144 | |
michael@0 | 145 | /* |
michael@0 | 146 | * get the value from that tag value pair. |
michael@0 | 147 | */ |
michael@0 | 148 | char * |
michael@0 | 149 | NSSUTIL_ArgGetParamValue(char *paramName,char *parameters) |
michael@0 | 150 | { |
michael@0 | 151 | char searchValue[256]; |
michael@0 | 152 | int paramLen = strlen(paramName); |
michael@0 | 153 | char *returnValue = NULL; |
michael@0 | 154 | int next; |
michael@0 | 155 | |
michael@0 | 156 | if ((parameters == NULL) || (*parameters == 0)) return NULL; |
michael@0 | 157 | |
michael@0 | 158 | PORT_Assert(paramLen+2 < sizeof(searchValue)); |
michael@0 | 159 | |
michael@0 | 160 | PORT_Strcpy(searchValue,paramName); |
michael@0 | 161 | PORT_Strcat(searchValue,"="); |
michael@0 | 162 | while (*parameters) { |
michael@0 | 163 | if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) { |
michael@0 | 164 | parameters += paramLen+1; |
michael@0 | 165 | returnValue = NSSUTIL_ArgFetchValue(parameters,&next); |
michael@0 | 166 | break; |
michael@0 | 167 | } else { |
michael@0 | 168 | parameters = NSSUTIL_ArgSkipParameter(parameters); |
michael@0 | 169 | } |
michael@0 | 170 | parameters = NSSUTIL_ArgStrip(parameters); |
michael@0 | 171 | } |
michael@0 | 172 | return returnValue; |
michael@0 | 173 | } |
michael@0 | 174 | |
michael@0 | 175 | /* |
michael@0 | 176 | * find the next flag in the parameter list |
michael@0 | 177 | */ |
michael@0 | 178 | char * |
michael@0 | 179 | NSSUTIL_ArgNextFlag(char *flags) |
michael@0 | 180 | { |
michael@0 | 181 | for (; *flags ; flags++) { |
michael@0 | 182 | if (*flags == ',') { |
michael@0 | 183 | flags++; |
michael@0 | 184 | break; |
michael@0 | 185 | } |
michael@0 | 186 | } |
michael@0 | 187 | return flags; |
michael@0 | 188 | } |
michael@0 | 189 | |
michael@0 | 190 | /* |
michael@0 | 191 | * return true if the flag is set in the label parameter. |
michael@0 | 192 | */ |
michael@0 | 193 | PRBool |
michael@0 | 194 | NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters) |
michael@0 | 195 | { |
michael@0 | 196 | char *flags,*index; |
michael@0 | 197 | int len = strlen(flag); |
michael@0 | 198 | PRBool found = PR_FALSE; |
michael@0 | 199 | |
michael@0 | 200 | flags = NSSUTIL_ArgGetParamValue(label,parameters); |
michael@0 | 201 | if (flags == NULL) return PR_FALSE; |
michael@0 | 202 | |
michael@0 | 203 | for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) { |
michael@0 | 204 | if (PORT_Strncasecmp(index,flag,len) == 0) { |
michael@0 | 205 | found=PR_TRUE; |
michael@0 | 206 | break; |
michael@0 | 207 | } |
michael@0 | 208 | } |
michael@0 | 209 | PORT_Free(flags); |
michael@0 | 210 | return found; |
michael@0 | 211 | } |
michael@0 | 212 | |
michael@0 | 213 | /* |
michael@0 | 214 | * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal |
michael@0 | 215 | */ |
michael@0 | 216 | long |
michael@0 | 217 | NSSUTIL_ArgDecodeNumber(char *num) |
michael@0 | 218 | { |
michael@0 | 219 | int radix = 10; |
michael@0 | 220 | unsigned long value = 0; |
michael@0 | 221 | long retValue = 0; |
michael@0 | 222 | int sign = 1; |
michael@0 | 223 | int digit; |
michael@0 | 224 | |
michael@0 | 225 | if (num == NULL) return retValue; |
michael@0 | 226 | |
michael@0 | 227 | num = NSSUTIL_ArgStrip(num); |
michael@0 | 228 | |
michael@0 | 229 | if (*num == '-') { |
michael@0 | 230 | sign = -1; |
michael@0 | 231 | num++; |
michael@0 | 232 | } |
michael@0 | 233 | |
michael@0 | 234 | if (*num == '0') { |
michael@0 | 235 | radix = 8; |
michael@0 | 236 | num++; |
michael@0 | 237 | if ((*num == 'x') || (*num == 'X')) { |
michael@0 | 238 | radix = 16; |
michael@0 | 239 | num++; |
michael@0 | 240 | } |
michael@0 | 241 | } |
michael@0 | 242 | |
michael@0 | 243 | |
michael@0 | 244 | for ( ;*num; num++ ) { |
michael@0 | 245 | if (isdigit(*num)) { |
michael@0 | 246 | digit = *num - '0'; |
michael@0 | 247 | } else if ((*num >= 'a') && (*num <= 'f')) { |
michael@0 | 248 | digit = *num - 'a' + 10; |
michael@0 | 249 | } else if ((*num >= 'A') && (*num <= 'F')) { |
michael@0 | 250 | digit = *num - 'A' + 10; |
michael@0 | 251 | } else { |
michael@0 | 252 | break; |
michael@0 | 253 | } |
michael@0 | 254 | if (digit >= radix) break; |
michael@0 | 255 | value = value*radix + digit; |
michael@0 | 256 | } |
michael@0 | 257 | |
michael@0 | 258 | retValue = ((int) value) * sign; |
michael@0 | 259 | return retValue; |
michael@0 | 260 | } |
michael@0 | 261 | |
michael@0 | 262 | /* |
michael@0 | 263 | * parameters are tag value pairs. This function returns the tag or label (the |
michael@0 | 264 | * value before the equal size. |
michael@0 | 265 | */ |
michael@0 | 266 | char * |
michael@0 | 267 | NSSUTIL_ArgGetLabel(char *inString, int *next) |
michael@0 | 268 | { |
michael@0 | 269 | char *name=NULL; |
michael@0 | 270 | char *string; |
michael@0 | 271 | int len; |
michael@0 | 272 | |
michael@0 | 273 | /* look for the end of the <label>= */ |
michael@0 | 274 | for (string = inString;*string; string++) { |
michael@0 | 275 | if (*string == '=') { break; } |
michael@0 | 276 | if (NSSUTIL_ArgIsBlank(*string)) break; |
michael@0 | 277 | } |
michael@0 | 278 | |
michael@0 | 279 | len = string - inString; |
michael@0 | 280 | |
michael@0 | 281 | *next = len; |
michael@0 | 282 | if (*string == '=') (*next) += 1; |
michael@0 | 283 | if (len > 0) { |
michael@0 | 284 | name = PORT_Alloc(len+1); |
michael@0 | 285 | PORT_Strncpy(name,inString,len); |
michael@0 | 286 | name[len] = 0; |
michael@0 | 287 | } |
michael@0 | 288 | return name; |
michael@0 | 289 | } |
michael@0 | 290 | |
michael@0 | 291 | /* |
michael@0 | 292 | * read an argument at a Long integer |
michael@0 | 293 | */ |
michael@0 | 294 | long |
michael@0 | 295 | NSSUTIL_ArgReadLong(char *label,char *params, long defValue, PRBool *isdefault) |
michael@0 | 296 | { |
michael@0 | 297 | char *value; |
michael@0 | 298 | long retValue; |
michael@0 | 299 | if (isdefault) *isdefault = PR_FALSE; |
michael@0 | 300 | |
michael@0 | 301 | value = NSSUTIL_ArgGetParamValue(label,params); |
michael@0 | 302 | if (value == NULL) { |
michael@0 | 303 | if (isdefault) *isdefault = PR_TRUE; |
michael@0 | 304 | return defValue; |
michael@0 | 305 | } |
michael@0 | 306 | retValue = NSSUTIL_ArgDecodeNumber(value); |
michael@0 | 307 | if (value) PORT_Free(value); |
michael@0 | 308 | |
michael@0 | 309 | return retValue; |
michael@0 | 310 | } |
michael@0 | 311 | |
michael@0 | 312 | |
michael@0 | 313 | /* |
michael@0 | 314 | * prepare a string to be quoted with 'quote' marks. We do that by adding |
michael@0 | 315 | * appropriate escapes. |
michael@0 | 316 | */ |
michael@0 | 317 | static int |
michael@0 | 318 | nssutil_escapeQuotesSize(const char *string, char quote, PRBool addquotes) |
michael@0 | 319 | { |
michael@0 | 320 | int escapes = 0, size = 0; |
michael@0 | 321 | const char *src; |
michael@0 | 322 | |
michael@0 | 323 | size= addquotes ? 2 : 0; |
michael@0 | 324 | for (src=string; *src ; src++) { |
michael@0 | 325 | if ((*src == quote) || (*src == '\\')) escapes++; |
michael@0 | 326 | size++; |
michael@0 | 327 | } |
michael@0 | 328 | return size+escapes+1; |
michael@0 | 329 | |
michael@0 | 330 | } |
michael@0 | 331 | |
michael@0 | 332 | static char * |
michael@0 | 333 | nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes) |
michael@0 | 334 | { |
michael@0 | 335 | char *newString = 0; |
michael@0 | 336 | int size = 0; |
michael@0 | 337 | const char *src; |
michael@0 | 338 | char *dest; |
michael@0 | 339 | |
michael@0 | 340 | size = nssutil_escapeQuotesSize(string, quote, addquotes); |
michael@0 | 341 | |
michael@0 | 342 | dest = newString = PORT_ZAlloc(size); |
michael@0 | 343 | if (newString == NULL) { |
michael@0 | 344 | return NULL; |
michael@0 | 345 | } |
michael@0 | 346 | |
michael@0 | 347 | if (addquotes) *dest++=quote; |
michael@0 | 348 | for (src=string; *src; src++,dest++) { |
michael@0 | 349 | if ((*src == '\\') || (*src == quote)) { |
michael@0 | 350 | *dest++ = '\\'; |
michael@0 | 351 | } |
michael@0 | 352 | *dest = *src; |
michael@0 | 353 | } |
michael@0 | 354 | if (addquotes) *dest=quote; |
michael@0 | 355 | |
michael@0 | 356 | return newString; |
michael@0 | 357 | } |
michael@0 | 358 | |
michael@0 | 359 | int |
michael@0 | 360 | NSSUTIL_EscapeSize(const char *string, char quote) |
michael@0 | 361 | { |
michael@0 | 362 | return nssutil_escapeQuotesSize(string, quote, PR_FALSE); |
michael@0 | 363 | } |
michael@0 | 364 | |
michael@0 | 365 | char * |
michael@0 | 366 | NSSUTIL_Escape(const char *string, char quote) |
michael@0 | 367 | { |
michael@0 | 368 | return nssutil_escapeQuotes(string, quote, PR_FALSE); |
michael@0 | 369 | } |
michael@0 | 370 | |
michael@0 | 371 | |
michael@0 | 372 | int |
michael@0 | 373 | NSSUTIL_QuoteSize(const char *string, char quote) |
michael@0 | 374 | { |
michael@0 | 375 | return nssutil_escapeQuotesSize(string, quote, PR_TRUE); |
michael@0 | 376 | } |
michael@0 | 377 | |
michael@0 | 378 | char * |
michael@0 | 379 | NSSUTIL_Quote(const char *string, char quote) |
michael@0 | 380 | { |
michael@0 | 381 | return nssutil_escapeQuotes(string, quote, PR_TRUE); |
michael@0 | 382 | } |
michael@0 | 383 | |
michael@0 | 384 | int |
michael@0 | 385 | NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2) |
michael@0 | 386 | { |
michael@0 | 387 | int escapes = 0, size = 0; |
michael@0 | 388 | const char *src; |
michael@0 | 389 | for (src=string; *src ; src++) { |
michael@0 | 390 | if (*src == '\\') escapes+=3; /* \\\\ */ |
michael@0 | 391 | if (*src == quote1) escapes+=2; /* \\quote1 */ |
michael@0 | 392 | if (*src == quote2) escapes++; /* \quote2 */ |
michael@0 | 393 | size++; |
michael@0 | 394 | } |
michael@0 | 395 | |
michael@0 | 396 | return escapes+size+1; |
michael@0 | 397 | } |
michael@0 | 398 | |
michael@0 | 399 | char * |
michael@0 | 400 | NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2) |
michael@0 | 401 | { |
michael@0 | 402 | char *round1 = NULL; |
michael@0 | 403 | char *retValue = NULL; |
michael@0 | 404 | if (string == NULL) { |
michael@0 | 405 | goto done; |
michael@0 | 406 | } |
michael@0 | 407 | round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE); |
michael@0 | 408 | if (round1) { |
michael@0 | 409 | retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE); |
michael@0 | 410 | PORT_Free(round1); |
michael@0 | 411 | } |
michael@0 | 412 | |
michael@0 | 413 | done: |
michael@0 | 414 | if (retValue == NULL) { |
michael@0 | 415 | retValue = PORT_Strdup(""); |
michael@0 | 416 | } |
michael@0 | 417 | return retValue; |
michael@0 | 418 | } |
michael@0 | 419 | |
michael@0 | 420 | |
michael@0 | 421 | /************************************************************************ |
michael@0 | 422 | * These functions are used in contructing strings. |
michael@0 | 423 | * NOTE: they will always return a string, but sometimes it will return |
michael@0 | 424 | * a specific NULL string. These strings must be freed with util_freePair. |
michael@0 | 425 | */ |
michael@0 | 426 | |
michael@0 | 427 | /* string to return on error... */ |
michael@0 | 428 | static char *nssutil_nullString = ""; |
michael@0 | 429 | |
michael@0 | 430 | static char * |
michael@0 | 431 | nssutil_formatValue(PLArenaPool *arena, char *value, char quote) |
michael@0 | 432 | { |
michael@0 | 433 | char *vp,*vp2,*retval; |
michael@0 | 434 | int size = 0, escapes = 0; |
michael@0 | 435 | |
michael@0 | 436 | for (vp=value; *vp ;vp++) { |
michael@0 | 437 | if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) escapes++; |
michael@0 | 438 | size++; |
michael@0 | 439 | } |
michael@0 | 440 | if (arena) { |
michael@0 | 441 | retval = PORT_ArenaZAlloc(arena,size+escapes+1); |
michael@0 | 442 | } else { |
michael@0 | 443 | retval = PORT_ZAlloc(size+escapes+1); |
michael@0 | 444 | } |
michael@0 | 445 | if (retval == NULL) return NULL; |
michael@0 | 446 | vp2 = retval; |
michael@0 | 447 | for (vp=value; *vp; vp++) { |
michael@0 | 448 | if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) |
michael@0 | 449 | *vp2++ = NSSUTIL_ARG_ESCAPE; |
michael@0 | 450 | *vp2++ = *vp; |
michael@0 | 451 | } |
michael@0 | 452 | return retval; |
michael@0 | 453 | } |
michael@0 | 454 | |
michael@0 | 455 | |
michael@0 | 456 | static PRBool nssutil_argHasChar(char *v, char c) |
michael@0 | 457 | { |
michael@0 | 458 | for ( ;*v; v++) { |
michael@0 | 459 | if (*v == c) return PR_TRUE; |
michael@0 | 460 | } |
michael@0 | 461 | return PR_FALSE; |
michael@0 | 462 | } |
michael@0 | 463 | |
michael@0 | 464 | static PRBool nssutil_argHasBlanks(char *v) |
michael@0 | 465 | { |
michael@0 | 466 | for ( ;*v; v++) { |
michael@0 | 467 | if (NSSUTIL_ArgIsBlank(*v)) return PR_TRUE; |
michael@0 | 468 | } |
michael@0 | 469 | return PR_FALSE; |
michael@0 | 470 | } |
michael@0 | 471 | |
michael@0 | 472 | static char * |
michael@0 | 473 | nssutil_formatPair(char *name, char *value, char quote) |
michael@0 | 474 | { |
michael@0 | 475 | char openQuote = quote; |
michael@0 | 476 | char closeQuote = NSSUTIL_ArgGetPair(quote); |
michael@0 | 477 | char *newValue = NULL; |
michael@0 | 478 | char *returnValue; |
michael@0 | 479 | PRBool need_quote = PR_FALSE; |
michael@0 | 480 | |
michael@0 | 481 | if (!value || (*value == 0)) return nssutil_nullString; |
michael@0 | 482 | |
michael@0 | 483 | if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0])) |
michael@0 | 484 | need_quote=PR_TRUE; |
michael@0 | 485 | |
michael@0 | 486 | if ((need_quote && nssutil_argHasChar(value,closeQuote)) |
michael@0 | 487 | || nssutil_argHasChar(value,NSSUTIL_ARG_ESCAPE)) { |
michael@0 | 488 | value = newValue = nssutil_formatValue(NULL, value,quote); |
michael@0 | 489 | if (newValue == NULL) return nssutil_nullString; |
michael@0 | 490 | } |
michael@0 | 491 | if (need_quote) { |
michael@0 | 492 | returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote); |
michael@0 | 493 | } else { |
michael@0 | 494 | returnValue = PR_smprintf("%s=%s",name,value); |
michael@0 | 495 | } |
michael@0 | 496 | if (returnValue == NULL) returnValue = nssutil_nullString; |
michael@0 | 497 | |
michael@0 | 498 | if (newValue) PORT_Free(newValue); |
michael@0 | 499 | |
michael@0 | 500 | return returnValue; |
michael@0 | 501 | } |
michael@0 | 502 | |
michael@0 | 503 | static char *nssutil_formatIntPair(char *name, unsigned long value, |
michael@0 | 504 | unsigned long def) |
michael@0 | 505 | { |
michael@0 | 506 | char *returnValue; |
michael@0 | 507 | |
michael@0 | 508 | if (value == def) return nssutil_nullString; |
michael@0 | 509 | |
michael@0 | 510 | returnValue = PR_smprintf("%s=%d",name,value); |
michael@0 | 511 | |
michael@0 | 512 | return returnValue; |
michael@0 | 513 | } |
michael@0 | 514 | |
michael@0 | 515 | static void |
michael@0 | 516 | nssutil_freePair(char *pair) |
michael@0 | 517 | { |
michael@0 | 518 | if (pair && pair != nssutil_nullString) { |
michael@0 | 519 | PR_smprintf_free(pair); |
michael@0 | 520 | } |
michael@0 | 521 | } |
michael@0 | 522 | |
michael@0 | 523 | |
michael@0 | 524 | /************************************************************************ |
michael@0 | 525 | * Parse the Slot specific parameters in the NSS params. |
michael@0 | 526 | */ |
michael@0 | 527 | |
michael@0 | 528 | struct nssutilArgSlotFlagTable { |
michael@0 | 529 | char *name; |
michael@0 | 530 | int len; |
michael@0 | 531 | unsigned long value; |
michael@0 | 532 | }; |
michael@0 | 533 | |
michael@0 | 534 | #define NSSUTIL_ARG_ENTRY(arg,flag) \ |
michael@0 | 535 | { #arg , sizeof(#arg)-1, flag } |
michael@0 | 536 | static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = { |
michael@0 | 537 | NSSUTIL_ARG_ENTRY(RSA,SECMOD_RSA_FLAG), |
michael@0 | 538 | NSSUTIL_ARG_ENTRY(DSA,SECMOD_RSA_FLAG), |
michael@0 | 539 | NSSUTIL_ARG_ENTRY(RC2,SECMOD_RC4_FLAG), |
michael@0 | 540 | NSSUTIL_ARG_ENTRY(RC4,SECMOD_RC2_FLAG), |
michael@0 | 541 | NSSUTIL_ARG_ENTRY(DES,SECMOD_DES_FLAG), |
michael@0 | 542 | NSSUTIL_ARG_ENTRY(DH,SECMOD_DH_FLAG), |
michael@0 | 543 | NSSUTIL_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG), |
michael@0 | 544 | NSSUTIL_ARG_ENTRY(RC5,SECMOD_RC5_FLAG), |
michael@0 | 545 | NSSUTIL_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG), |
michael@0 | 546 | NSSUTIL_ARG_ENTRY(SHA256,SECMOD_SHA256_FLAG), |
michael@0 | 547 | NSSUTIL_ARG_ENTRY(SHA512,SECMOD_SHA512_FLAG), |
michael@0 | 548 | NSSUTIL_ARG_ENTRY(MD5,SECMOD_MD5_FLAG), |
michael@0 | 549 | NSSUTIL_ARG_ENTRY(MD2,SECMOD_MD2_FLAG), |
michael@0 | 550 | NSSUTIL_ARG_ENTRY(SSL,SECMOD_SSL_FLAG), |
michael@0 | 551 | NSSUTIL_ARG_ENTRY(TLS,SECMOD_TLS_FLAG), |
michael@0 | 552 | NSSUTIL_ARG_ENTRY(AES,SECMOD_AES_FLAG), |
michael@0 | 553 | NSSUTIL_ARG_ENTRY(Camellia,SECMOD_CAMELLIA_FLAG), |
michael@0 | 554 | NSSUTIL_ARG_ENTRY(SEED,SECMOD_SEED_FLAG), |
michael@0 | 555 | NSSUTIL_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG), |
michael@0 | 556 | NSSUTIL_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG), |
michael@0 | 557 | NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG), |
michael@0 | 558 | }; |
michael@0 | 559 | |
michael@0 | 560 | static int nssutil_argSlotFlagTableSize = |
michael@0 | 561 | sizeof(nssutil_argSlotFlagTable)/sizeof(nssutil_argSlotFlagTable[0]); |
michael@0 | 562 | |
michael@0 | 563 | |
michael@0 | 564 | /* turn the slot flags into a bit mask */ |
michael@0 | 565 | unsigned long |
michael@0 | 566 | NSSUTIL_ArgParseSlotFlags(char *label,char *params) |
michael@0 | 567 | { |
michael@0 | 568 | char *flags,*index; |
michael@0 | 569 | unsigned long retValue = 0; |
michael@0 | 570 | int i; |
michael@0 | 571 | PRBool all = PR_FALSE; |
michael@0 | 572 | |
michael@0 | 573 | flags = NSSUTIL_ArgGetParamValue(label,params); |
michael@0 | 574 | if (flags == NULL) return 0; |
michael@0 | 575 | |
michael@0 | 576 | if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE; |
michael@0 | 577 | |
michael@0 | 578 | for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) { |
michael@0 | 579 | for (i=0; i < nssutil_argSlotFlagTableSize; i++) { |
michael@0 | 580 | if (all || |
michael@0 | 581 | (PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name, |
michael@0 | 582 | nssutil_argSlotFlagTable[i].len) == 0)) { |
michael@0 | 583 | retValue |= nssutil_argSlotFlagTable[i].value; |
michael@0 | 584 | } |
michael@0 | 585 | } |
michael@0 | 586 | } |
michael@0 | 587 | PORT_Free(flags); |
michael@0 | 588 | return retValue; |
michael@0 | 589 | } |
michael@0 | 590 | |
michael@0 | 591 | |
michael@0 | 592 | /* parse a single slot specific parameter */ |
michael@0 | 593 | static void |
michael@0 | 594 | nssutil_argDecodeSingleSlotInfo(char *name, char *params, |
michael@0 | 595 | struct NSSUTILPreSlotInfoStr *slotInfo) |
michael@0 | 596 | { |
michael@0 | 597 | char *askpw; |
michael@0 | 598 | |
michael@0 | 599 | slotInfo->slotID=NSSUTIL_ArgDecodeNumber(name); |
michael@0 | 600 | slotInfo->defaultFlags=NSSUTIL_ArgParseSlotFlags("slotFlags",params); |
michael@0 | 601 | slotInfo->timeout=NSSUTIL_ArgReadLong("timeout",params, 0, NULL); |
michael@0 | 602 | |
michael@0 | 603 | askpw = NSSUTIL_ArgGetParamValue("askpw",params); |
michael@0 | 604 | slotInfo->askpw = 0; |
michael@0 | 605 | |
michael@0 | 606 | if (askpw) { |
michael@0 | 607 | if (PORT_Strcasecmp(askpw,"every") == 0) { |
michael@0 | 608 | slotInfo->askpw = -1; |
michael@0 | 609 | } else if (PORT_Strcasecmp(askpw,"timeout") == 0) { |
michael@0 | 610 | slotInfo->askpw = 1; |
michael@0 | 611 | } |
michael@0 | 612 | PORT_Free(askpw); |
michael@0 | 613 | slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS; |
michael@0 | 614 | } |
michael@0 | 615 | slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts", |
michael@0 | 616 | params); |
michael@0 | 617 | slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust", |
michael@0 | 618 | params); |
michael@0 | 619 | } |
michael@0 | 620 | |
michael@0 | 621 | /* parse all the slot specific parameters. */ |
michael@0 | 622 | struct NSSUTILPreSlotInfoStr * |
michael@0 | 623 | NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, char *slotParams, int *retCount) |
michael@0 | 624 | { |
michael@0 | 625 | char *slotIndex; |
michael@0 | 626 | struct NSSUTILPreSlotInfoStr *slotInfo = NULL; |
michael@0 | 627 | int i=0,count = 0,next; |
michael@0 | 628 | |
michael@0 | 629 | *retCount = 0; |
michael@0 | 630 | if ((slotParams == NULL) || (*slotParams == 0)) return NULL; |
michael@0 | 631 | |
michael@0 | 632 | /* first count the number of slots */ |
michael@0 | 633 | for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex; |
michael@0 | 634 | slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) { |
michael@0 | 635 | count++; |
michael@0 | 636 | } |
michael@0 | 637 | |
michael@0 | 638 | /* get the data structures */ |
michael@0 | 639 | if (arena) { |
michael@0 | 640 | slotInfo = PORT_ArenaZNewArray(arena, |
michael@0 | 641 | struct NSSUTILPreSlotInfoStr, count); |
michael@0 | 642 | } else { |
michael@0 | 643 | slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count); |
michael@0 | 644 | } |
michael@0 | 645 | if (slotInfo == NULL) return NULL; |
michael@0 | 646 | |
michael@0 | 647 | for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0; |
michael@0 | 648 | *slotIndex && i < count ; ) { |
michael@0 | 649 | char *name; |
michael@0 | 650 | name = NSSUTIL_ArgGetLabel(slotIndex,&next); |
michael@0 | 651 | slotIndex += next; |
michael@0 | 652 | |
michael@0 | 653 | if (!NSSUTIL_ArgIsBlank(*slotIndex)) { |
michael@0 | 654 | char *args = NSSUTIL_ArgFetchValue(slotIndex,&next); |
michael@0 | 655 | slotIndex += next; |
michael@0 | 656 | if (args) { |
michael@0 | 657 | nssutil_argDecodeSingleSlotInfo(name,args,&slotInfo[i]); |
michael@0 | 658 | i++; |
michael@0 | 659 | PORT_Free(args); |
michael@0 | 660 | } |
michael@0 | 661 | } |
michael@0 | 662 | if (name) PORT_Free(name); |
michael@0 | 663 | slotIndex = NSSUTIL_ArgStrip(slotIndex); |
michael@0 | 664 | } |
michael@0 | 665 | *retCount = i; |
michael@0 | 666 | return slotInfo; |
michael@0 | 667 | } |
michael@0 | 668 | |
michael@0 | 669 | /************************************************************************ |
michael@0 | 670 | * make a new slot specific parameter |
michael@0 | 671 | */ |
michael@0 | 672 | /* first make the slot flags */ |
michael@0 | 673 | static char * |
michael@0 | 674 | nssutil_mkSlotFlags(unsigned long defaultFlags) |
michael@0 | 675 | { |
michael@0 | 676 | char *flags=NULL; |
michael@0 | 677 | int i,j; |
michael@0 | 678 | |
michael@0 | 679 | for (i=0; i < sizeof(defaultFlags)*8; i++) { |
michael@0 | 680 | if (defaultFlags & (1UL <<i)) { |
michael@0 | 681 | char *string = NULL; |
michael@0 | 682 | |
michael@0 | 683 | for (j=0; j < nssutil_argSlotFlagTableSize; j++) { |
michael@0 | 684 | if (nssutil_argSlotFlagTable[j].value == ( 1UL << i )) { |
michael@0 | 685 | string = nssutil_argSlotFlagTable[j].name; |
michael@0 | 686 | break; |
michael@0 | 687 | } |
michael@0 | 688 | } |
michael@0 | 689 | if (string) { |
michael@0 | 690 | if (flags) { |
michael@0 | 691 | char *tmp; |
michael@0 | 692 | tmp = PR_smprintf("%s,%s",flags,string); |
michael@0 | 693 | PR_smprintf_free(flags); |
michael@0 | 694 | flags = tmp; |
michael@0 | 695 | } else { |
michael@0 | 696 | flags = PR_smprintf("%s",string); |
michael@0 | 697 | } |
michael@0 | 698 | } |
michael@0 | 699 | } |
michael@0 | 700 | } |
michael@0 | 701 | |
michael@0 | 702 | return flags; |
michael@0 | 703 | } |
michael@0 | 704 | |
michael@0 | 705 | /* now make the root flags */ |
michael@0 | 706 | #define NSSUTIL_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts")+sizeof("hasRootTrust") |
michael@0 | 707 | static char * |
michael@0 | 708 | nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust) |
michael@0 | 709 | { |
michael@0 | 710 | char *flags= (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE); |
michael@0 | 711 | PRBool first = PR_TRUE; |
michael@0 | 712 | |
michael@0 | 713 | PORT_Memset(flags,0,NSSUTIL_MAX_ROOT_FLAG_SIZE); |
michael@0 | 714 | if (hasRootCerts) { |
michael@0 | 715 | PORT_Strcat(flags,"hasRootCerts"); |
michael@0 | 716 | first = PR_FALSE; |
michael@0 | 717 | } |
michael@0 | 718 | if (hasRootTrust) { |
michael@0 | 719 | if (!first) PORT_Strcat(flags,","); |
michael@0 | 720 | PORT_Strcat(flags,"hasRootTrust"); |
michael@0 | 721 | first = PR_FALSE; |
michael@0 | 722 | } |
michael@0 | 723 | return flags; |
michael@0 | 724 | } |
michael@0 | 725 | |
michael@0 | 726 | /* now make a full slot string */ |
michael@0 | 727 | char * |
michael@0 | 728 | NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags, |
michael@0 | 729 | unsigned long timeout, unsigned char askpw_in, |
michael@0 | 730 | PRBool hasRootCerts, PRBool hasRootTrust) { |
michael@0 | 731 | char *askpw,*flags,*rootFlags,*slotString; |
michael@0 | 732 | char *flagPair,*rootFlagsPair; |
michael@0 | 733 | |
michael@0 | 734 | switch (askpw_in) { |
michael@0 | 735 | case 0xff: |
michael@0 | 736 | askpw = "every"; |
michael@0 | 737 | break; |
michael@0 | 738 | case 1: |
michael@0 | 739 | askpw = "timeout"; |
michael@0 | 740 | break; |
michael@0 | 741 | default: |
michael@0 | 742 | askpw = "any"; |
michael@0 | 743 | break; |
michael@0 | 744 | } |
michael@0 | 745 | flags = nssutil_mkSlotFlags(defaultFlags); |
michael@0 | 746 | rootFlags = nssutil_mkRootFlags(hasRootCerts,hasRootTrust); |
michael@0 | 747 | flagPair = nssutil_formatPair("slotFlags",flags,'\''); |
michael@0 | 748 | rootFlagsPair = nssutil_formatPair("rootFlags",rootFlags,'\''); |
michael@0 | 749 | if (flags) PR_smprintf_free(flags); |
michael@0 | 750 | if (rootFlags) PORT_Free(rootFlags); |
michael@0 | 751 | if (defaultFlags & PK11_OWN_PW_DEFAULTS) { |
michael@0 | 752 | slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]", |
michael@0 | 753 | (PRUint32)slotID,flagPair,askpw,timeout, |
michael@0 | 754 | rootFlagsPair); |
michael@0 | 755 | } else { |
michael@0 | 756 | slotString = PR_smprintf("0x%08lx=[%s %s]", |
michael@0 | 757 | (PRUint32)slotID,flagPair,rootFlagsPair); |
michael@0 | 758 | } |
michael@0 | 759 | nssutil_freePair(flagPair); |
michael@0 | 760 | nssutil_freePair(rootFlagsPair); |
michael@0 | 761 | return slotString; |
michael@0 | 762 | } |
michael@0 | 763 | |
michael@0 | 764 | |
michael@0 | 765 | /************************************************************************ |
michael@0 | 766 | * Parse Full module specs into: library, commonName, module parameters, |
michael@0 | 767 | * and NSS specifi parameters. |
michael@0 | 768 | */ |
michael@0 | 769 | SECStatus |
michael@0 | 770 | NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod, |
michael@0 | 771 | char **parameters, char **nss) |
michael@0 | 772 | { |
michael@0 | 773 | int next; |
michael@0 | 774 | modulespec = NSSUTIL_ArgStrip(modulespec); |
michael@0 | 775 | |
michael@0 | 776 | *lib = *mod = *parameters = *nss = 0; |
michael@0 | 777 | |
michael@0 | 778 | while (*modulespec) { |
michael@0 | 779 | NSSUTIL_HANDLE_STRING_ARG(modulespec,*lib,"library=",;) |
michael@0 | 780 | NSSUTIL_HANDLE_STRING_ARG(modulespec,*mod,"name=",;) |
michael@0 | 781 | NSSUTIL_HANDLE_STRING_ARG(modulespec,*parameters,"parameters=",;) |
michael@0 | 782 | NSSUTIL_HANDLE_STRING_ARG(modulespec,*nss,"nss=",;) |
michael@0 | 783 | NSSUTIL_HANDLE_FINAL_ARG(modulespec) |
michael@0 | 784 | } |
michael@0 | 785 | return SECSuccess; |
michael@0 | 786 | } |
michael@0 | 787 | |
michael@0 | 788 | /************************************************************************ |
michael@0 | 789 | * make a new module spec from it's components */ |
michael@0 | 790 | char * |
michael@0 | 791 | NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters, |
michael@0 | 792 | char *NSS) |
michael@0 | 793 | { |
michael@0 | 794 | char *moduleSpec; |
michael@0 | 795 | char *lib,*name,*param,*nss; |
michael@0 | 796 | |
michael@0 | 797 | /* |
michael@0 | 798 | * now the final spec |
michael@0 | 799 | */ |
michael@0 | 800 | lib = nssutil_formatPair("library",dllName,'\"'); |
michael@0 | 801 | name = nssutil_formatPair("name",commonName,'\"'); |
michael@0 | 802 | param = nssutil_formatPair("parameters",parameters,'\"'); |
michael@0 | 803 | nss = nssutil_formatPair("NSS",NSS,'\"'); |
michael@0 | 804 | moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss); |
michael@0 | 805 | nssutil_freePair(lib); |
michael@0 | 806 | nssutil_freePair(name); |
michael@0 | 807 | nssutil_freePair(param); |
michael@0 | 808 | nssutil_freePair(nss); |
michael@0 | 809 | return (moduleSpec); |
michael@0 | 810 | } |
michael@0 | 811 | |
michael@0 | 812 | |
michael@0 | 813 | #define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA" |
michael@0 | 814 | /****************************************************************************** |
michael@0 | 815 | * Parse the cipher flags from the NSS parameter |
michael@0 | 816 | */ |
michael@0 | 817 | void |
michael@0 | 818 | NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,char *cipherList) |
michael@0 | 819 | { |
michael@0 | 820 | newCiphers[0] = newCiphers[1] = 0; |
michael@0 | 821 | if ((cipherList == NULL) || (*cipherList == 0)) return; |
michael@0 | 822 | |
michael@0 | 823 | for (;*cipherList; cipherList=NSSUTIL_ArgNextFlag(cipherList)) { |
michael@0 | 824 | if (PORT_Strncasecmp(cipherList,NSSUTIL_ARG_FORTEZZA_FLAG, |
michael@0 | 825 | sizeof(NSSUTIL_ARG_FORTEZZA_FLAG)-1) == 0) { |
michael@0 | 826 | newCiphers[0] |= SECMOD_FORTEZZA_FLAG; |
michael@0 | 827 | } |
michael@0 | 828 | |
michael@0 | 829 | /* add additional flags here as necessary */ |
michael@0 | 830 | /* direct bit mapping escape */ |
michael@0 | 831 | if (*cipherList == 0) { |
michael@0 | 832 | if (cipherList[1] == 'l') { |
michael@0 | 833 | newCiphers[1] |= atoi(&cipherList[2]); |
michael@0 | 834 | } else { |
michael@0 | 835 | newCiphers[0] |= atoi(&cipherList[2]); |
michael@0 | 836 | } |
michael@0 | 837 | } |
michael@0 | 838 | } |
michael@0 | 839 | } |
michael@0 | 840 | |
michael@0 | 841 | |
michael@0 | 842 | /********************************************************************* |
michael@0 | 843 | * make NSS parameter... |
michael@0 | 844 | */ |
michael@0 | 845 | /* First make NSS specific flags */ |
michael@0 | 846 | #define MAX_FLAG_SIZE sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\ |
michael@0 | 847 | sizeof("moduleDBOnly")+sizeof("critical") |
michael@0 | 848 | static char * |
michael@0 | 849 | nssutil_mkNSSFlags(PRBool internal, PRBool isFIPS, |
michael@0 | 850 | PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical) |
michael@0 | 851 | { |
michael@0 | 852 | char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE); |
michael@0 | 853 | PRBool first = PR_TRUE; |
michael@0 | 854 | |
michael@0 | 855 | PORT_Memset(flags,0,MAX_FLAG_SIZE); |
michael@0 | 856 | if (internal) { |
michael@0 | 857 | PORT_Strcat(flags,"internal"); |
michael@0 | 858 | first = PR_FALSE; |
michael@0 | 859 | } |
michael@0 | 860 | if (isFIPS) { |
michael@0 | 861 | if (!first) PORT_Strcat(flags,","); |
michael@0 | 862 | PORT_Strcat(flags,"FIPS"); |
michael@0 | 863 | first = PR_FALSE; |
michael@0 | 864 | } |
michael@0 | 865 | if (isModuleDB) { |
michael@0 | 866 | if (!first) PORT_Strcat(flags,","); |
michael@0 | 867 | PORT_Strcat(flags,"moduleDB"); |
michael@0 | 868 | first = PR_FALSE; |
michael@0 | 869 | } |
michael@0 | 870 | if (isModuleDBOnly) { |
michael@0 | 871 | if (!first) PORT_Strcat(flags,","); |
michael@0 | 872 | PORT_Strcat(flags,"moduleDBOnly"); |
michael@0 | 873 | first = PR_FALSE; |
michael@0 | 874 | } |
michael@0 | 875 | if (isCritical) { |
michael@0 | 876 | if (!first) PORT_Strcat(flags,","); |
michael@0 | 877 | PORT_Strcat(flags,"critical"); |
michael@0 | 878 | first = PR_FALSE; |
michael@0 | 879 | } |
michael@0 | 880 | return flags; |
michael@0 | 881 | } |
michael@0 | 882 | |
michael@0 | 883 | |
michael@0 | 884 | /* construct the NSS cipher flags */ |
michael@0 | 885 | static char * |
michael@0 | 886 | nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1) |
michael@0 | 887 | { |
michael@0 | 888 | char *cipher = NULL; |
michael@0 | 889 | int i; |
michael@0 | 890 | |
michael@0 | 891 | for (i=0; i < sizeof(ssl0)*8; i++) { |
michael@0 | 892 | if (ssl0 & (1UL <<i)) { |
michael@0 | 893 | char *string; |
michael@0 | 894 | if ((1UL <<i) == SECMOD_FORTEZZA_FLAG) { |
michael@0 | 895 | string = PR_smprintf("%s",NSSUTIL_ARG_FORTEZZA_FLAG); |
michael@0 | 896 | } else { |
michael@0 | 897 | string = PR_smprintf("0h0x%08lx", 1UL <<i); |
michael@0 | 898 | } |
michael@0 | 899 | if (cipher) { |
michael@0 | 900 | char *tmp; |
michael@0 | 901 | tmp = PR_smprintf("%s,%s",cipher,string); |
michael@0 | 902 | PR_smprintf_free(cipher); |
michael@0 | 903 | PR_smprintf_free(string); |
michael@0 | 904 | cipher = tmp; |
michael@0 | 905 | } else { |
michael@0 | 906 | cipher = string; |
michael@0 | 907 | } |
michael@0 | 908 | } |
michael@0 | 909 | } |
michael@0 | 910 | for (i=0; i < sizeof(ssl0)*8; i++) { |
michael@0 | 911 | if (ssl1 & (1UL <<i)) { |
michael@0 | 912 | if (cipher) { |
michael@0 | 913 | char *tmp; |
michael@0 | 914 | tmp = PR_smprintf("%s,0l0x%08lx",cipher, 1UL <<i); |
michael@0 | 915 | PR_smprintf_free(cipher); |
michael@0 | 916 | cipher = tmp; |
michael@0 | 917 | } else { |
michael@0 | 918 | cipher = PR_smprintf("0l0x%08lx", 1UL <<i); |
michael@0 | 919 | } |
michael@0 | 920 | } |
michael@0 | 921 | } |
michael@0 | 922 | |
michael@0 | 923 | return cipher; |
michael@0 | 924 | } |
michael@0 | 925 | |
michael@0 | 926 | /* Assemble a full NSS string. */ |
michael@0 | 927 | char * |
michael@0 | 928 | NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal, |
michael@0 | 929 | PRBool isFIPS, PRBool isModuleDB, PRBool isModuleDBOnly, |
michael@0 | 930 | PRBool isCritical, unsigned long trustOrder, |
michael@0 | 931 | unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1) |
michael@0 | 932 | { |
michael@0 | 933 | int slotLen, i; |
michael@0 | 934 | char *slotParams, *ciphers, *nss, *nssFlags, *tmp; |
michael@0 | 935 | char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair; |
michael@0 | 936 | |
michael@0 | 937 | |
michael@0 | 938 | /* now let's build up the string |
michael@0 | 939 | * first the slot infos |
michael@0 | 940 | */ |
michael@0 | 941 | slotLen=0; |
michael@0 | 942 | for (i=0; i < (int)slotCount; i++) { |
michael@0 | 943 | slotLen += PORT_Strlen(slotStrings[i])+1; |
michael@0 | 944 | } |
michael@0 | 945 | slotLen += 1; /* space for the final NULL */ |
michael@0 | 946 | |
michael@0 | 947 | slotParams = (char *)PORT_ZAlloc(slotLen); |
michael@0 | 948 | PORT_Memset(slotParams,0,slotLen); |
michael@0 | 949 | for (i=0; i < (int)slotCount; i++) { |
michael@0 | 950 | PORT_Strcat(slotParams,slotStrings[i]); |
michael@0 | 951 | PORT_Strcat(slotParams," "); |
michael@0 | 952 | PR_smprintf_free(slotStrings[i]); |
michael@0 | 953 | slotStrings[i]=NULL; |
michael@0 | 954 | } |
michael@0 | 955 | |
michael@0 | 956 | /* |
michael@0 | 957 | * now the NSS structure |
michael@0 | 958 | */ |
michael@0 | 959 | nssFlags = nssutil_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly, |
michael@0 | 960 | isCritical); |
michael@0 | 961 | /* for now only the internal module is critical */ |
michael@0 | 962 | ciphers = nssutil_mkCipherFlags(ssl0, ssl1); |
michael@0 | 963 | |
michael@0 | 964 | trustOrderPair = nssutil_formatIntPair("trustOrder",trustOrder, |
michael@0 | 965 | NSSUTIL_DEFAULT_TRUST_ORDER); |
michael@0 | 966 | cipherOrderPair = nssutil_formatIntPair("cipherOrder",cipherOrder, |
michael@0 | 967 | NSSUTIL_DEFAULT_CIPHER_ORDER); |
michael@0 | 968 | slotPair=nssutil_formatPair("slotParams",slotParams,'{'); /* } */ |
michael@0 | 969 | if (slotParams) PORT_Free(slotParams); |
michael@0 | 970 | cipherPair=nssutil_formatPair("ciphers",ciphers,'\''); |
michael@0 | 971 | if (ciphers) PR_smprintf_free(ciphers); |
michael@0 | 972 | flagPair=nssutil_formatPair("Flags",nssFlags,'\''); |
michael@0 | 973 | if (nssFlags) PORT_Free(nssFlags); |
michael@0 | 974 | nss = PR_smprintf("%s %s %s %s %s",trustOrderPair, |
michael@0 | 975 | cipherOrderPair,slotPair,cipherPair,flagPair); |
michael@0 | 976 | nssutil_freePair(trustOrderPair); |
michael@0 | 977 | nssutil_freePair(cipherOrderPair); |
michael@0 | 978 | nssutil_freePair(slotPair); |
michael@0 | 979 | nssutil_freePair(cipherPair); |
michael@0 | 980 | nssutil_freePair(flagPair); |
michael@0 | 981 | tmp = NSSUTIL_ArgStrip(nss); |
michael@0 | 982 | if (*tmp == '\0') { |
michael@0 | 983 | PR_smprintf_free(nss); |
michael@0 | 984 | nss = NULL; |
michael@0 | 985 | } |
michael@0 | 986 | return nss; |
michael@0 | 987 | } |
michael@0 | 988 | |
michael@0 | 989 | /***************************************************************************** |
michael@0 | 990 | * |
michael@0 | 991 | * Private calls for use by softoken and utilmod.c |
michael@0 | 992 | */ |
michael@0 | 993 | |
michael@0 | 994 | #define SQLDB "sql:" |
michael@0 | 995 | #define EXTERNDB "extern:" |
michael@0 | 996 | #define LEGACY "dbm:" |
michael@0 | 997 | #define MULTIACCESS "multiaccess:" |
michael@0 | 998 | #define SECMOD_DB "secmod.db" |
michael@0 | 999 | const char * |
michael@0 | 1000 | _NSSUTIL_EvaluateConfigDir(const char *configdir, |
michael@0 | 1001 | NSSDBType *pdbType, char **appName) |
michael@0 | 1002 | { |
michael@0 | 1003 | NSSDBType dbType; |
michael@0 | 1004 | *appName = NULL; |
michael@0 | 1005 | /* force the default */ |
michael@0 | 1006 | #ifdef NSS_DISABLE_DBM |
michael@0 | 1007 | dbType = NSS_DB_TYPE_SQL; |
michael@0 | 1008 | #else |
michael@0 | 1009 | dbType = NSS_DB_TYPE_LEGACY; |
michael@0 | 1010 | #endif |
michael@0 | 1011 | if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) { |
michael@0 | 1012 | char *cdir; |
michael@0 | 1013 | dbType = NSS_DB_TYPE_MULTIACCESS; |
michael@0 | 1014 | |
michael@0 | 1015 | *appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1); |
michael@0 | 1016 | if (*appName == NULL) { |
michael@0 | 1017 | return configdir; |
michael@0 | 1018 | } |
michael@0 | 1019 | cdir = *appName; |
michael@0 | 1020 | while (*cdir && *cdir != ':') { |
michael@0 | 1021 | cdir++; |
michael@0 | 1022 | } |
michael@0 | 1023 | if (*cdir == ':') { |
michael@0 | 1024 | *cdir = 0; |
michael@0 | 1025 | cdir++; |
michael@0 | 1026 | } |
michael@0 | 1027 | configdir = cdir; |
michael@0 | 1028 | } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB)-1) == 0) { |
michael@0 | 1029 | dbType = NSS_DB_TYPE_SQL; |
michael@0 | 1030 | configdir = configdir + sizeof(SQLDB) -1; |
michael@0 | 1031 | } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB)-1) == 0) { |
michael@0 | 1032 | dbType = NSS_DB_TYPE_EXTERN; |
michael@0 | 1033 | configdir = configdir + sizeof(EXTERNDB) -1; |
michael@0 | 1034 | } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY)-1) == 0) { |
michael@0 | 1035 | dbType = NSS_DB_TYPE_LEGACY; |
michael@0 | 1036 | configdir = configdir + sizeof(LEGACY) -1; |
michael@0 | 1037 | } else { |
michael@0 | 1038 | /* look up the default from the environment */ |
michael@0 | 1039 | char *defaultType = PR_GetEnv("NSS_DEFAULT_DB_TYPE"); |
michael@0 | 1040 | if (defaultType != NULL) { |
michael@0 | 1041 | if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB)-2) == 0) { |
michael@0 | 1042 | dbType = NSS_DB_TYPE_SQL; |
michael@0 | 1043 | } else if (PORT_Strncmp(defaultType,EXTERNDB,sizeof(EXTERNDB)-2)==0) { |
michael@0 | 1044 | dbType = NSS_DB_TYPE_EXTERN; |
michael@0 | 1045 | } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY)-2) == 0) { |
michael@0 | 1046 | dbType = NSS_DB_TYPE_LEGACY; |
michael@0 | 1047 | } |
michael@0 | 1048 | } |
michael@0 | 1049 | } |
michael@0 | 1050 | /* if the caller has already set a type, don't change it */ |
michael@0 | 1051 | if (*pdbType == NSS_DB_TYPE_NONE) { |
michael@0 | 1052 | *pdbType = dbType; |
michael@0 | 1053 | } |
michael@0 | 1054 | return configdir; |
michael@0 | 1055 | } |
michael@0 | 1056 | |
michael@0 | 1057 | char * |
michael@0 | 1058 | _NSSUTIL_GetSecmodName(char *param, NSSDBType *dbType, char **appName, |
michael@0 | 1059 | char **filename, PRBool *rw) |
michael@0 | 1060 | { |
michael@0 | 1061 | int next; |
michael@0 | 1062 | char *configdir = NULL; |
michael@0 | 1063 | char *secmodName = NULL; |
michael@0 | 1064 | char *value = NULL; |
michael@0 | 1065 | char *save_params = param; |
michael@0 | 1066 | const char *lconfigdir; |
michael@0 | 1067 | PRBool noModDB = PR_FALSE; |
michael@0 | 1068 | param = NSSUTIL_ArgStrip(param); |
michael@0 | 1069 | |
michael@0 | 1070 | |
michael@0 | 1071 | while (*param) { |
michael@0 | 1072 | NSSUTIL_HANDLE_STRING_ARG(param,configdir,"configDir=",;) |
michael@0 | 1073 | NSSUTIL_HANDLE_STRING_ARG(param,secmodName,"secmod=",;) |
michael@0 | 1074 | NSSUTIL_HANDLE_FINAL_ARG(param) |
michael@0 | 1075 | } |
michael@0 | 1076 | |
michael@0 | 1077 | *rw = PR_TRUE; |
michael@0 | 1078 | if (NSSUTIL_ArgHasFlag("flags","readOnly",save_params)) { |
michael@0 | 1079 | *rw = PR_FALSE; |
michael@0 | 1080 | } |
michael@0 | 1081 | |
michael@0 | 1082 | if (!secmodName || *secmodName == '\0') { |
michael@0 | 1083 | if (secmodName) PORT_Free(secmodName); |
michael@0 | 1084 | secmodName = PORT_Strdup(SECMOD_DB); |
michael@0 | 1085 | } |
michael@0 | 1086 | |
michael@0 | 1087 | *filename = secmodName; |
michael@0 | 1088 | lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName); |
michael@0 | 1089 | |
michael@0 | 1090 | if (NSSUTIL_ArgHasFlag("flags","noModDB",save_params)) { |
michael@0 | 1091 | /* there isn't a module db, don't load the legacy support */ |
michael@0 | 1092 | noModDB = PR_TRUE; |
michael@0 | 1093 | *dbType = NSS_DB_TYPE_SQL; |
michael@0 | 1094 | PORT_Free(*filename); |
michael@0 | 1095 | *filename = NULL; |
michael@0 | 1096 | *rw = PR_FALSE; |
michael@0 | 1097 | } |
michael@0 | 1098 | |
michael@0 | 1099 | /* only use the renamed secmod for legacy databases */ |
michael@0 | 1100 | if ((*dbType != NSS_DB_TYPE_LEGACY) && |
michael@0 | 1101 | (*dbType != NSS_DB_TYPE_MULTIACCESS)) { |
michael@0 | 1102 | secmodName="pkcs11.txt"; |
michael@0 | 1103 | } |
michael@0 | 1104 | |
michael@0 | 1105 | if (noModDB) { |
michael@0 | 1106 | value = NULL; |
michael@0 | 1107 | } else if (lconfigdir && lconfigdir[0] != '\0') { |
michael@0 | 1108 | value = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s", |
michael@0 | 1109 | lconfigdir,secmodName); |
michael@0 | 1110 | } else { |
michael@0 | 1111 | value = PR_smprintf("%s",secmodName); |
michael@0 | 1112 | } |
michael@0 | 1113 | if (configdir) PORT_Free(configdir); |
michael@0 | 1114 | return value; |
michael@0 | 1115 | } |
michael@0 | 1116 | |
michael@0 | 1117 |