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, &param, &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