| OLD | NEW |
| (Empty) |
| 1 /* This Source Code Form is subject to the terms of the Mozilla Public | |
| 2 * License, v. 2.0. If a copy of the MPL was not distributed with this | |
| 3 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ | |
| 4 /* | |
| 5 * The following handles the loading, unloading and management of | |
| 6 * various PCKS #11 modules | |
| 7 */ | |
| 8 | |
| 9 | |
| 10 /* | |
| 11 * this header file contains routines for parsing PKCS #11 module spec | |
| 12 * strings. It contains 'C' code and should only be included in one module. | |
| 13 * Currently it is included in both softoken and the wrapper. | |
| 14 */ | |
| 15 #include <ctype.h> | |
| 16 #include "pkcs11.h" | |
| 17 #include "seccomon.h" | |
| 18 #include "prprf.h" | |
| 19 #include "secmodt.h" | |
| 20 #include "pk11init.h" | |
| 21 | |
| 22 #define SECMOD_ARG_LIBRARY_PARAMETER "library=" | |
| 23 #define SECMOD_ARG_NAME_PARAMETER "name=" | |
| 24 #define SECMOD_ARG_MODULE_PARAMETER "parameters=" | |
| 25 #define SECMOD_ARG_NSS_PARAMETER "NSS=" | |
| 26 #define SECMOD_ARG_FORTEZZA_FLAG "FORTEZZA" | |
| 27 #define SECMOD_ARG_ESCAPE '\\' | |
| 28 | |
| 29 struct secmodargSlotFlagTable { | |
| 30 char *name; | |
| 31 int len; | |
| 32 unsigned long value; | |
| 33 }; | |
| 34 | |
| 35 #define SECMOD_DEFAULT_CIPHER_ORDER 0 | |
| 36 #define SECMOD_DEFAULT_TRUST_ORDER 50 | |
| 37 | |
| 38 | |
| 39 #define SECMOD_ARG_ENTRY(arg,flag) \ | |
| 40 { #arg , sizeof(#arg)-1, flag } | |
| 41 static struct secmodargSlotFlagTable secmod_argSlotFlagTable[] = { | |
| 42 SECMOD_ARG_ENTRY(RSA,SECMOD_RSA_FLAG), | |
| 43 SECMOD_ARG_ENTRY(DSA,SECMOD_RSA_FLAG), | |
| 44 SECMOD_ARG_ENTRY(RC2,SECMOD_RC4_FLAG), | |
| 45 SECMOD_ARG_ENTRY(RC4,SECMOD_RC2_FLAG), | |
| 46 SECMOD_ARG_ENTRY(DES,SECMOD_DES_FLAG), | |
| 47 SECMOD_ARG_ENTRY(DH,SECMOD_DH_FLAG), | |
| 48 SECMOD_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG), | |
| 49 SECMOD_ARG_ENTRY(RC5,SECMOD_RC5_FLAG), | |
| 50 SECMOD_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG), | |
| 51 SECMOD_ARG_ENTRY(MD5,SECMOD_MD5_FLAG), | |
| 52 SECMOD_ARG_ENTRY(MD2,SECMOD_MD2_FLAG), | |
| 53 SECMOD_ARG_ENTRY(SSL,SECMOD_SSL_FLAG), | |
| 54 SECMOD_ARG_ENTRY(TLS,SECMOD_TLS_FLAG), | |
| 55 SECMOD_ARG_ENTRY(AES,SECMOD_AES_FLAG), | |
| 56 SECMOD_ARG_ENTRY(Camellia,SECMOD_CAMELLIA_FLAG), | |
| 57 SECMOD_ARG_ENTRY(SEED,SECMOD_SEED_FLAG), | |
| 58 SECMOD_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG), | |
| 59 SECMOD_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG), | |
| 60 SECMOD_ARG_ENTRY(Disable, PK11_DISABLE_FLAG), | |
| 61 }; | |
| 62 | |
| 63 #define SECMOD_HANDLE_STRING_ARG(param,target,value,command) \ | |
| 64 if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \ | |
| 65 param += sizeof(value)-1; \ | |
| 66 if (target) PORT_Free(target); \ | |
| 67 target = secmod_argFetchValue(param,&next); \ | |
| 68 param += next; \ | |
| 69 command ;\ | |
| 70 } else | |
| 71 | |
| 72 #define SECMOD_HANDLE_FINAL_ARG(param) \ | |
| 73 { param = secmod_argSkipParameter(param); } param = secmod_argStrip(param); | |
| 74 | |
| 75 | |
| 76 static int secmod_argSlotFlagTableSize = | |
| 77 sizeof(secmod_argSlotFlagTable)/sizeof(secmod_argSlotFlagTable[0]); | |
| 78 | |
| 79 | |
| 80 static PRBool secmod_argGetPair(char c) { | |
| 81 switch (c) { | |
| 82 case '\'': return c; | |
| 83 case '\"': return c; | |
| 84 case '<': return '>'; | |
| 85 case '{': return '}'; | |
| 86 case '[': return ']'; | |
| 87 case '(': return ')'; | |
| 88 default: break; | |
| 89 } | |
| 90 return ' '; | |
| 91 } | |
| 92 | |
| 93 static PRBool secmod_argIsBlank(char c) { | |
| 94 return isspace((unsigned char )c); | |
| 95 } | |
| 96 | |
| 97 static PRBool secmod_argIsEscape(char c) { | |
| 98 return c == '\\'; | |
| 99 } | |
| 100 | |
| 101 static PRBool secmod_argIsQuote(char c) { | |
| 102 switch (c) { | |
| 103 case '\'': | |
| 104 case '\"': | |
| 105 case '<': | |
| 106 case '{': /* } end curly to keep vi bracket matching working */ | |
| 107 case '(': /* ) */ | |
| 108 case '[': /* ] */ return PR_TRUE; | |
| 109 default: break; | |
| 110 } | |
| 111 return PR_FALSE; | |
| 112 } | |
| 113 | |
| 114 static PRBool secmod_argHasChar(char *v, char c) | |
| 115 { | |
| 116 for ( ;*v; v++) { | |
| 117 if (*v == c) return PR_TRUE; | |
| 118 } | |
| 119 return PR_FALSE; | |
| 120 } | |
| 121 | |
| 122 static PRBool secmod_argHasBlanks(char *v) | |
| 123 { | |
| 124 for ( ;*v; v++) { | |
| 125 if (secmod_argIsBlank(*v)) return PR_TRUE; | |
| 126 } | |
| 127 return PR_FALSE; | |
| 128 } | |
| 129 | |
| 130 static char *secmod_argStrip(char *c) { | |
| 131 while (*c && secmod_argIsBlank(*c)) c++; | |
| 132 return c; | |
| 133 } | |
| 134 | |
| 135 static char * | |
| 136 secmod_argFindEnd(char *string) { | |
| 137 char endChar = ' '; | |
| 138 PRBool lastEscape = PR_FALSE; | |
| 139 | |
| 140 if (secmod_argIsQuote(*string)) { | |
| 141 endChar = secmod_argGetPair(*string); | |
| 142 string++; | |
| 143 } | |
| 144 | |
| 145 for (;*string; string++) { | |
| 146 if (lastEscape) { | |
| 147 lastEscape = PR_FALSE; | |
| 148 continue; | |
| 149 } | |
| 150 if (secmod_argIsEscape(*string) && !lastEscape) { | |
| 151 lastEscape = PR_TRUE; | |
| 152 continue; | |
| 153 } | |
| 154 if ((endChar == ' ') && secmod_argIsBlank(*string)) break; | |
| 155 if (*string == endChar) { | |
| 156 break; | |
| 157 } | |
| 158 } | |
| 159 | |
| 160 return string; | |
| 161 } | |
| 162 | |
| 163 static char * | |
| 164 secmod_argFetchValue(char *string, int *pcount) | |
| 165 { | |
| 166 char *end = secmod_argFindEnd(string); | |
| 167 char *retString, *copyString; | |
| 168 PRBool lastEscape = PR_FALSE; | |
| 169 int len; | |
| 170 | |
| 171 len = end - string; | |
| 172 if (len == 0) { | |
| 173 *pcount = 0; | |
| 174 return NULL; | |
| 175 } | |
| 176 | |
| 177 copyString = retString = (char *)PORT_Alloc(len+1); | |
| 178 | |
| 179 if (*end) len++; | |
| 180 *pcount = len; | |
| 181 if (retString == NULL) return NULL; | |
| 182 | |
| 183 | |
| 184 if (secmod_argIsQuote(*string)) string++; | |
| 185 for (; string < end; string++) { | |
| 186 if (secmod_argIsEscape(*string) && !lastEscape) { | |
| 187 lastEscape = PR_TRUE; | |
| 188 continue; | |
| 189 } | |
| 190 lastEscape = PR_FALSE; | |
| 191 *copyString++ = *string; | |
| 192 } | |
| 193 *copyString = 0; | |
| 194 return retString; | |
| 195 } | |
| 196 | |
| 197 static char * | |
| 198 secmod_argSkipParameter(char *string) | |
| 199 { | |
| 200 char *end; | |
| 201 /* look for the end of the <name>= */ | |
| 202 for (;*string; string++) { | |
| 203 if (*string == '=') { string++; break; } | |
| 204 if (secmod_argIsBlank(*string)) return(string); | |
| 205 } | |
| 206 | |
| 207 end = secmod_argFindEnd(string); | |
| 208 if (*end) end++; | |
| 209 return end; | |
| 210 } | |
| 211 | |
| 212 | |
| 213 static SECStatus | |
| 214 secmod_argParseModuleSpec(char *modulespec, char **lib, char **mod, | |
| 215 char **parameters, char **nss) | |
| 216 { | |
| 217 int next; | |
| 218 modulespec = secmod_argStrip(modulespec); | |
| 219 | |
| 220 *lib = *mod = *parameters = *nss = 0; | |
| 221 | |
| 222 while (*modulespec) { | |
| 223 SECMOD_HANDLE_STRING_ARG(modulespec,*lib,SECMOD_ARG_LIBRARY_PARAMETER,;) | |
| 224 SECMOD_HANDLE_STRING_ARG(modulespec,*mod,SECMOD_ARG_NAME_PARAMETER,;) | |
| 225 SECMOD_HANDLE_STRING_ARG(modulespec,*parameters, | |
| 226 SECMOD_ARG_MODULE_PARAMETER,;) | |
| 227 SECMOD_HANDLE_STRING_ARG(modulespec,*nss,SECMOD_ARG_NSS_PARAMETER,;) | |
| 228 SECMOD_HANDLE_FINAL_ARG(modulespec) | |
| 229 } | |
| 230 return SECSuccess; | |
| 231 } | |
| 232 | |
| 233 | |
| 234 static char * | |
| 235 secmod_argGetParamValue(char *paramName,char *parameters) | |
| 236 { | |
| 237 char searchValue[256]; | |
| 238 int paramLen = strlen(paramName); | |
| 239 char *returnValue = NULL; | |
| 240 int next; | |
| 241 | |
| 242 if ((parameters == NULL) || (*parameters == 0)) return NULL; | |
| 243 | |
| 244 PORT_Assert(paramLen+2 < sizeof(searchValue)); | |
| 245 | |
| 246 PORT_Strcpy(searchValue,paramName); | |
| 247 PORT_Strcat(searchValue,"="); | |
| 248 while (*parameters) { | |
| 249 if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) { | |
| 250 parameters += paramLen+1; | |
| 251 returnValue = secmod_argFetchValue(parameters,&next); | |
| 252 break; | |
| 253 } else { | |
| 254 parameters = secmod_argSkipParameter(parameters); | |
| 255 } | |
| 256 parameters = secmod_argStrip(parameters); | |
| 257 } | |
| 258 return returnValue; | |
| 259 } | |
| 260 | |
| 261 | |
| 262 static char * | |
| 263 secmod_argNextFlag(char *flags) | |
| 264 { | |
| 265 for (; *flags ; flags++) { | |
| 266 if (*flags == ',') { | |
| 267 flags++; | |
| 268 break; | |
| 269 } | |
| 270 } | |
| 271 return flags; | |
| 272 } | |
| 273 | |
| 274 static PRBool | |
| 275 secmod_argHasFlag(char *label, char *flag, char *parameters) | |
| 276 { | |
| 277 char *flags,*index; | |
| 278 int len = strlen(flag); | |
| 279 PRBool found = PR_FALSE; | |
| 280 | |
| 281 flags = secmod_argGetParamValue(label,parameters); | |
| 282 if (flags == NULL) return PR_FALSE; | |
| 283 | |
| 284 for (index=flags; *index; index=secmod_argNextFlag(index)) { | |
| 285 if (PORT_Strncasecmp(index,flag,len) == 0) { | |
| 286 found=PR_TRUE; | |
| 287 break; | |
| 288 } | |
| 289 } | |
| 290 PORT_Free(flags); | |
| 291 return found; | |
| 292 } | |
| 293 | |
| 294 static void | |
| 295 secmod_argSetNewCipherFlags(unsigned long *newCiphers,char *cipherList) | |
| 296 { | |
| 297 newCiphers[0] = newCiphers[1] = 0; | |
| 298 if ((cipherList == NULL) || (*cipherList == 0)) return; | |
| 299 | |
| 300 for (;*cipherList; cipherList=secmod_argNextFlag(cipherList)) { | |
| 301 if (PORT_Strncasecmp(cipherList,SECMOD_ARG_FORTEZZA_FLAG, | |
| 302 sizeof(SECMOD_ARG_FORTEZZA_FLAG)-1) == 0) { | |
| 303 newCiphers[0] |= SECMOD_FORTEZZA_FLAG; | |
| 304 } | |
| 305 | |
| 306 /* add additional flags here as necessary */ | |
| 307 /* direct bit mapping escape */ | |
| 308 if (*cipherList == 0) { | |
| 309 if (cipherList[1] == 'l') { | |
| 310 newCiphers[1] |= atoi(&cipherList[2]); | |
| 311 } else { | |
| 312 newCiphers[0] |= atoi(&cipherList[2]); | |
| 313 } | |
| 314 } | |
| 315 } | |
| 316 } | |
| 317 | |
| 318 | |
| 319 /* | |
| 320 * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal | |
| 321 */ | |
| 322 static long | |
| 323 secmod_argDecodeNumber(char *num) | |
| 324 { | |
| 325 int radix = 10; | |
| 326 unsigned long value = 0; | |
| 327 long retValue = 0; | |
| 328 int sign = 1; | |
| 329 int digit; | |
| 330 | |
| 331 if (num == NULL) return retValue; | |
| 332 | |
| 333 num = secmod_argStrip(num); | |
| 334 | |
| 335 if (*num == '-') { | |
| 336 sign = -1; | |
| 337 num++; | |
| 338 } | |
| 339 | |
| 340 if (*num == '0') { | |
| 341 radix = 8; | |
| 342 num++; | |
| 343 if ((*num == 'x') || (*num == 'X')) { | |
| 344 radix = 16; | |
| 345 num++; | |
| 346 } | |
| 347 } | |
| 348 | |
| 349 | |
| 350 for ( ;*num; num++ ) { | |
| 351 if (isdigit(*num)) { | |
| 352 digit = *num - '0'; | |
| 353 } else if ((*num >= 'a') && (*num <= 'f')) { | |
| 354 digit = *num - 'a' + 10; | |
| 355 } else if ((*num >= 'A') && (*num <= 'F')) { | |
| 356 digit = *num - 'A' + 10; | |
| 357 } else { | |
| 358 break; | |
| 359 } | |
| 360 if (digit >= radix) break; | |
| 361 value = value*radix + digit; | |
| 362 } | |
| 363 | |
| 364 retValue = ((int) value) * sign; | |
| 365 return retValue; | |
| 366 } | |
| 367 | |
| 368 static long | |
| 369 secmod_argReadLong(char *label,char *params, long defValue, PRBool *isdefault) | |
| 370 { | |
| 371 char *value; | |
| 372 long retValue; | |
| 373 if (isdefault) *isdefault = PR_FALSE; | |
| 374 | |
| 375 value = secmod_argGetParamValue(label,params); | |
| 376 if (value == NULL) { | |
| 377 if (isdefault) *isdefault = PR_TRUE; | |
| 378 return defValue; | |
| 379 } | |
| 380 retValue = secmod_argDecodeNumber(value); | |
| 381 if (value) PORT_Free(value); | |
| 382 | |
| 383 return retValue; | |
| 384 } | |
| 385 | |
| 386 | |
| 387 static unsigned long | |
| 388 secmod_argSlotFlags(char *label,char *params) | |
| 389 { | |
| 390 char *flags,*index; | |
| 391 unsigned long retValue = 0; | |
| 392 int i; | |
| 393 PRBool all = PR_FALSE; | |
| 394 | |
| 395 flags = secmod_argGetParamValue(label,params); | |
| 396 if (flags == NULL) return 0; | |
| 397 | |
| 398 if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE; | |
| 399 | |
| 400 for (index=flags; *index; index=secmod_argNextFlag(index)) { | |
| 401 for (i=0; i < secmod_argSlotFlagTableSize; i++) { | |
| 402 if (all || (PORT_Strncasecmp(index, secmod_argSlotFlagTable[i].name, | |
| 403 secmod_argSlotFlagTable[i].len) == 0)) { | |
| 404 retValue |= secmod_argSlotFlagTable[i].value; | |
| 405 } | |
| 406 } | |
| 407 } | |
| 408 PORT_Free(flags); | |
| 409 return retValue; | |
| 410 } | |
| 411 | |
| 412 | |
| 413 static void | |
| 414 secmod_argDecodeSingleSlotInfo(char *name, char *params, | |
| 415 PK11PreSlotInfo *slotInfo) | |
| 416 { | |
| 417 char *askpw; | |
| 418 | |
| 419 slotInfo->slotID=secmod_argDecodeNumber(name); | |
| 420 slotInfo->defaultFlags=secmod_argSlotFlags("slotFlags",params); | |
| 421 slotInfo->timeout=secmod_argReadLong("timeout",params, 0, NULL); | |
| 422 | |
| 423 askpw = secmod_argGetParamValue("askpw",params); | |
| 424 slotInfo->askpw = 0; | |
| 425 | |
| 426 if (askpw) { | |
| 427 if (PORT_Strcasecmp(askpw,"every") == 0) { | |
| 428 slotInfo->askpw = -1; | |
| 429 } else if (PORT_Strcasecmp(askpw,"timeout") == 0) { | |
| 430 slotInfo->askpw = 1; | |
| 431 } | |
| 432 PORT_Free(askpw); | |
| 433 slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS; | |
| 434 } | |
| 435 slotInfo->hasRootCerts = secmod_argHasFlag("rootFlags", "hasRootCerts", | |
| 436 params); | |
| 437 slotInfo->hasRootTrust = secmod_argHasFlag("rootFlags", "hasRootTrust", | |
| 438 params); | |
| 439 } | |
| 440 | |
| 441 static char * | |
| 442 secmod_argGetName(char *inString, int *next) | |
| 443 { | |
| 444 char *name=NULL; | |
| 445 char *string; | |
| 446 int len; | |
| 447 | |
| 448 /* look for the end of the <name>= */ | |
| 449 for (string = inString;*string; string++) { | |
| 450 if (*string == '=') { break; } | |
| 451 if (secmod_argIsBlank(*string)) break; | |
| 452 } | |
| 453 | |
| 454 len = string - inString; | |
| 455 | |
| 456 *next = len; | |
| 457 if (*string == '=') (*next) += 1; | |
| 458 if (len > 0) { | |
| 459 name = PORT_Alloc(len+1); | |
| 460 PORT_Strncpy(name,inString,len); | |
| 461 name[len] = 0; | |
| 462 } | |
| 463 return name; | |
| 464 } | |
| 465 | |
| 466 static PK11PreSlotInfo * | |
| 467 secmod_argParseSlotInfo(PRArenaPool *arena, char *slotParams, int *retCount) | |
| 468 { | |
| 469 char *slotIndex; | |
| 470 PK11PreSlotInfo *slotInfo = NULL; | |
| 471 int i=0,count = 0,next; | |
| 472 | |
| 473 *retCount = 0; | |
| 474 if ((slotParams == NULL) || (*slotParams == 0)) return NULL; | |
| 475 | |
| 476 /* first count the number of slots */ | |
| 477 for (slotIndex = secmod_argStrip(slotParams); *slotIndex; | |
| 478 slotIndex = secmod_argStrip(secmod_argSkipParameter(slotIndex))) { | |
| 479 count++; | |
| 480 } | |
| 481 | |
| 482 /* get the data structures */ | |
| 483 if (arena) { | |
| 484 slotInfo = (PK11PreSlotInfo *) | |
| 485 PORT_ArenaAlloc(arena,count*sizeof(PK11PreSlotInfo)); | |
| 486 PORT_Memset(slotInfo,0,count*sizeof(PK11PreSlotInfo)); | |
| 487 } else { | |
| 488 slotInfo = (PK11PreSlotInfo *) | |
| 489 PORT_ZAlloc(count*sizeof(PK11PreSlotInfo)); | |
| 490 } | |
| 491 if (slotInfo == NULL) return NULL; | |
| 492 | |
| 493 for (slotIndex = secmod_argStrip(slotParams), i = 0; | |
| 494 *slotIndex && i < count ; ) { | |
| 495 char *name; | |
| 496 name = secmod_argGetName(slotIndex,&next); | |
| 497 slotIndex += next; | |
| 498 | |
| 499 if (!secmod_argIsBlank(*slotIndex)) { | |
| 500 char *args = secmod_argFetchValue(slotIndex,&next); | |
| 501 slotIndex += next; | |
| 502 if (args) { | |
| 503 secmod_argDecodeSingleSlotInfo(name,args,&slotInfo[i]); | |
| 504 i++; | |
| 505 PORT_Free(args); | |
| 506 } | |
| 507 } | |
| 508 if (name) PORT_Free(name); | |
| 509 slotIndex = secmod_argStrip(slotIndex); | |
| 510 } | |
| 511 *retCount = i; | |
| 512 return slotInfo; | |
| 513 } | |
| 514 | |
| 515 static char *secmod_nullString = ""; | |
| 516 | |
| 517 static char * | |
| 518 secmod_formatValue(PRArenaPool *arena, char *value, char quote) | |
| 519 { | |
| 520 char *vp,*vp2,*retval; | |
| 521 int size = 0, escapes = 0; | |
| 522 | |
| 523 for (vp=value; *vp ;vp++) { | |
| 524 if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) escapes++; | |
| 525 size++; | |
| 526 } | |
| 527 if (arena) { | |
| 528 retval = PORT_ArenaZAlloc(arena,size+escapes+1); | |
| 529 } else { | |
| 530 retval = PORT_ZAlloc(size+escapes+1); | |
| 531 } | |
| 532 if (retval == NULL) return NULL; | |
| 533 vp2 = retval; | |
| 534 for (vp=value; *vp; vp++) { | |
| 535 if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) | |
| 536 *vp2++ = SECMOD_ARG_ESCAPE; | |
| 537 *vp2++ = *vp; | |
| 538 } | |
| 539 return retval; | |
| 540 } | |
| 541 | |
| 542 static char *secmod_formatPair(char *name,char *value, char quote) | |
| 543 { | |
| 544 char openQuote = quote; | |
| 545 char closeQuote = secmod_argGetPair(quote); | |
| 546 char *newValue = NULL; | |
| 547 char *returnValue; | |
| 548 PRBool need_quote = PR_FALSE; | |
| 549 | |
| 550 if (!value || (*value == 0)) return secmod_nullString; | |
| 551 | |
| 552 if (secmod_argHasBlanks(value) || secmod_argIsQuote(value[0])) | |
| 553 need_quote=PR_TRUE; | |
| 554 | |
| 555 if ((need_quote && secmod_argHasChar(value,closeQuote)) | |
| 556 || secmod_argHasChar(value,SECMOD_ARG_ESCAPE))
{ | |
| 557 value = newValue = secmod_formatValue(NULL, value,quote); | |
| 558 if (newValue == NULL) return secmod_nullString; | |
| 559 } | |
| 560 if (need_quote) { | |
| 561 returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote); | |
| 562 } else { | |
| 563 returnValue = PR_smprintf("%s=%s",name,value); | |
| 564 } | |
| 565 if (returnValue == NULL) returnValue = secmod_nullString; | |
| 566 | |
| 567 if (newValue) PORT_Free(newValue); | |
| 568 | |
| 569 return returnValue; | |
| 570 } | |
| 571 | |
| 572 static char *secmod_formatIntPair(char *name, unsigned long value, | |
| 573 unsigned long def) | |
| 574 { | |
| 575 char *returnValue; | |
| 576 | |
| 577 if (value == def) return secmod_nullString; | |
| 578 | |
| 579 returnValue = PR_smprintf("%s=%d",name,value); | |
| 580 | |
| 581 return returnValue; | |
| 582 } | |
| 583 | |
| 584 static void | |
| 585 secmod_freePair(char *pair) | |
| 586 { | |
| 587 if (pair && pair != secmod_nullString) { | |
| 588 PR_smprintf_free(pair); | |
| 589 } | |
| 590 } | |
| 591 | |
| 592 #define MAX_FLAG_SIZE sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\ | |
| 593 sizeof("moduleDBOnly")+sizeof("critical") | |
| 594 static char * | |
| 595 secmod_mkNSSFlags(PRBool internal, PRBool isFIPS, | |
| 596 PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical) | |
| 597 { | |
| 598 char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE); | |
| 599 PRBool first = PR_TRUE; | |
| 600 | |
| 601 PORT_Memset(flags,0,MAX_FLAG_SIZE); | |
| 602 if (internal) { | |
| 603 PORT_Strcat(flags,"internal"); | |
| 604 first = PR_FALSE; | |
| 605 } | |
| 606 if (isFIPS) { | |
| 607 if (!first) PORT_Strcat(flags,","); | |
| 608 PORT_Strcat(flags,"FIPS"); | |
| 609 first = PR_FALSE; | |
| 610 } | |
| 611 if (isModuleDB) { | |
| 612 if (!first) PORT_Strcat(flags,","); | |
| 613 PORT_Strcat(flags,"moduleDB"); | |
| 614 first = PR_FALSE; | |
| 615 } | |
| 616 if (isModuleDBOnly) { | |
| 617 if (!first) PORT_Strcat(flags,","); | |
| 618 PORT_Strcat(flags,"moduleDBOnly"); | |
| 619 first = PR_FALSE; | |
| 620 } | |
| 621 if (isCritical) { | |
| 622 if (!first) PORT_Strcat(flags,","); | |
| 623 PORT_Strcat(flags,"critical"); | |
| 624 first = PR_FALSE; | |
| 625 } | |
| 626 return flags; | |
| 627 } | |
| 628 | |
| 629 static char * | |
| 630 secmod_mkCipherFlags(unsigned long ssl0, unsigned long ssl1) | |
| 631 { | |
| 632 char *cipher = NULL; | |
| 633 int i; | |
| 634 | |
| 635 for (i=0; i < sizeof(ssl0)*8; i++) { | |
| 636 if (ssl0 & (1<<i)) { | |
| 637 char *string; | |
| 638 if ((1<<i) == SECMOD_FORTEZZA_FLAG) { | |
| 639 string = PR_smprintf("%s","FORTEZZA"); | |
| 640 } else { | |
| 641 string = PR_smprintf("0h0x%08x",1<<i); | |
| 642 } | |
| 643 if (cipher) { | |
| 644 char *tmp; | |
| 645 tmp = PR_smprintf("%s,%s",cipher,string); | |
| 646 PR_smprintf_free(cipher); | |
| 647 PR_smprintf_free(string); | |
| 648 cipher = tmp; | |
| 649 } else { | |
| 650 cipher = string; | |
| 651 } | |
| 652 } | |
| 653 } | |
| 654 for (i=0; i < sizeof(ssl0)*8; i++) { | |
| 655 if (ssl1 & (1<<i)) { | |
| 656 if (cipher) { | |
| 657 char *tmp; | |
| 658 tmp = PR_smprintf("%s,0l0x%08x",cipher,1<<i); | |
| 659 PR_smprintf_free(cipher); | |
| 660 cipher = tmp; | |
| 661 } else { | |
| 662 cipher = PR_smprintf("0l0x%08x",1<<i); | |
| 663 } | |
| 664 } | |
| 665 } | |
| 666 | |
| 667 return cipher; | |
| 668 } | |
| 669 | |
| 670 static char * | |
| 671 secmod_mkSlotFlags(unsigned long defaultFlags) | |
| 672 { | |
| 673 char *flags=NULL; | |
| 674 int i,j; | |
| 675 | |
| 676 for (i=0; i < sizeof(defaultFlags)*8; i++) { | |
| 677 if (defaultFlags & (1<<i)) { | |
| 678 char *string = NULL; | |
| 679 | |
| 680 for (j=0; j < secmod_argSlotFlagTableSize; j++) { | |
| 681 if (secmod_argSlotFlagTable[j].value == ( 1UL << i )) { | |
| 682 string = secmod_argSlotFlagTable[j].name; | |
| 683 break; | |
| 684 } | |
| 685 } | |
| 686 if (string) { | |
| 687 if (flags) { | |
| 688 char *tmp; | |
| 689 tmp = PR_smprintf("%s,%s",flags,string); | |
| 690 PR_smprintf_free(flags); | |
| 691 flags = tmp; | |
| 692 } else { | |
| 693 flags = PR_smprintf("%s",string); | |
| 694 } | |
| 695 } | |
| 696 } | |
| 697 } | |
| 698 | |
| 699 return flags; | |
| 700 } | |
| 701 | |
| 702 #define SECMOD_MAX_ROOT_FLAG_SIZE sizeof("hasRootCerts")+sizeof("hasRootTrust") | |
| 703 | |
| 704 static char * | |
| 705 secmod_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust) | |
| 706 { | |
| 707 char *flags= (char *)PORT_ZAlloc(SECMOD_MAX_ROOT_FLAG_SIZE); | |
| 708 PRBool first = PR_TRUE; | |
| 709 | |
| 710 PORT_Memset(flags,0,SECMOD_MAX_ROOT_FLAG_SIZE); | |
| 711 if (hasRootCerts) { | |
| 712 PORT_Strcat(flags,"hasRootCerts"); | |
| 713 first = PR_FALSE; | |
| 714 } | |
| 715 if (hasRootTrust) { | |
| 716 if (!first) PORT_Strcat(flags,","); | |
| 717 PORT_Strcat(flags,"hasRootTrust"); | |
| 718 first = PR_FALSE; | |
| 719 } | |
| 720 return flags; | |
| 721 } | |
| 722 | |
| 723 static char * | |
| 724 secmod_mkSlotString(unsigned long slotID, unsigned long defaultFlags, | |
| 725 unsigned long timeout, unsigned char askpw_in, | |
| 726 PRBool hasRootCerts, PRBool hasRootTrust) { | |
| 727 char *askpw,*flags,*rootFlags,*slotString; | |
| 728 char *flagPair,*rootFlagsPair; | |
| 729 | |
| 730 switch (askpw_in) { | |
| 731 case 0xff: | |
| 732 askpw = "every"; | |
| 733 break; | |
| 734 case 1: | |
| 735 askpw = "timeout"; | |
| 736 break; | |
| 737 default: | |
| 738 askpw = "any"; | |
| 739 break; | |
| 740 } | |
| 741 flags = secmod_mkSlotFlags(defaultFlags); | |
| 742 rootFlags = secmod_mkRootFlags(hasRootCerts,hasRootTrust); | |
| 743 flagPair=secmod_formatPair("slotFlags",flags,'\''); | |
| 744 rootFlagsPair=secmod_formatPair("rootFlags",rootFlags,'\''); | |
| 745 if (flags) PR_smprintf_free(flags); | |
| 746 if (rootFlags) PORT_Free(rootFlags); | |
| 747 if (defaultFlags & PK11_OWN_PW_DEFAULTS) { | |
| 748 slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]", | |
| 749 (PRUint32)slotID,flagPair,askpw,timeout, | |
| 750 rootFlagsPair); | |
| 751 } else { | |
| 752 slotString = PR_smprintf("0x%08lx=[%s %s]", | |
| 753 (PRUint32)slotID,flagPair,rootFlagsPair); | |
| 754 } | |
| 755 secmod_freePair(flagPair); | |
| 756 secmod_freePair(rootFlagsPair); | |
| 757 return slotString; | |
| 758 } | |
| 759 | |
| 760 static char * | |
| 761 secmod_mkNSS(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS, | |
| 762 PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical, | |
| 763 unsigned long trustOrder, unsigned long cipherOrder, | |
| 764 unsigned long ssl0, unsigned long ssl1) { | |
| 765 int slotLen, i; | |
| 766 char *slotParams, *ciphers, *nss, *nssFlags, *tmp; | |
| 767 char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair; | |
| 768 | |
| 769 | |
| 770 /* now let's build up the string | |
| 771 * first the slot infos | |
| 772 */ | |
| 773 slotLen=0; | |
| 774 for (i=0; i < (int)slotCount; i++) { | |
| 775 slotLen += PORT_Strlen(slotStrings[i])+1; | |
| 776 } | |
| 777 slotLen += 1; /* space for the final NULL */ | |
| 778 | |
| 779 slotParams = (char *)PORT_ZAlloc(slotLen); | |
| 780 PORT_Memset(slotParams,0,slotLen); | |
| 781 for (i=0; i < (int)slotCount; i++) { | |
| 782 PORT_Strcat(slotParams,slotStrings[i]); | |
| 783 PORT_Strcat(slotParams," "); | |
| 784 PR_smprintf_free(slotStrings[i]); | |
| 785 slotStrings[i]=NULL; | |
| 786 } | |
| 787 | |
| 788 /* | |
| 789 * now the NSS structure | |
| 790 */ | |
| 791 nssFlags = secmod_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly, | |
| 792 isCritical); | |
| 793 /* for now only the internal module is critical */ | |
| 794 ciphers = secmod_mkCipherFlags(ssl0, ssl1); | |
| 795 | |
| 796 trustOrderPair=secmod_formatIntPair("trustOrder",trustOrder, | |
| 797 SECMOD_DEFAULT_TRUST_ORDER); | |
| 798 cipherOrderPair=secmod_formatIntPair("cipherOrder",cipherOrder, | |
| 799 SECMOD_DEFAULT_CIPHER_ORDER); | |
| 800 slotPair=secmod_formatPair("slotParams",slotParams,'{'); /* } */ | |
| 801 if (slotParams) PORT_Free(slotParams); | |
| 802 cipherPair=secmod_formatPair("ciphers",ciphers,'\''); | |
| 803 if (ciphers) PR_smprintf_free(ciphers); | |
| 804 flagPair=secmod_formatPair("Flags",nssFlags,'\''); | |
| 805 if (nssFlags) PORT_Free(nssFlags); | |
| 806 nss = PR_smprintf("%s %s %s %s %s",trustOrderPair, | |
| 807 cipherOrderPair,slotPair,cipherPair,flagPair); | |
| 808 secmod_freePair(trustOrderPair); | |
| 809 secmod_freePair(cipherOrderPair); | |
| 810 secmod_freePair(slotPair); | |
| 811 secmod_freePair(cipherPair); | |
| 812 secmod_freePair(flagPair); | |
| 813 tmp = secmod_argStrip(nss); | |
| 814 if (*tmp == '\0') { | |
| 815 PR_smprintf_free(nss); | |
| 816 nss = NULL; | |
| 817 } | |
| 818 return nss; | |
| 819 } | |
| 820 | |
| 821 static char * | |
| 822 secmod_mkNewModuleSpec(char *dllName, char *commonName, char *parameters, | |
| 823 char *NSS) { | |
| 824 char *moduleSpec; | |
| 825 char *lib,*name,*param,*nss; | |
| 826 | |
| 827 /* | |
| 828 * now the final spec | |
| 829 */ | |
| 830 lib = secmod_formatPair("library",dllName,'\"'); | |
| 831 name = secmod_formatPair("name",commonName,'\"'); | |
| 832 param = secmod_formatPair("parameters",parameters,'\"'); | |
| 833 nss = secmod_formatPair("NSS",NSS,'\"'); | |
| 834 moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss); | |
| 835 secmod_freePair(lib); | |
| 836 secmod_freePair(name); | |
| 837 secmod_freePair(param); | |
| 838 secmod_freePair(nss); | |
| 839 return (moduleSpec); | |
| 840 } | |
| 841 | |
| OLD | NEW |