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 |