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