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