security/nss/lib/util/utilpars.c

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     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"
    15 /*
    16  * return the expected matching quote value for the one specified
    17  */
    18 PRBool NSSUTIL_ArgGetPair(char c) {
    19     switch (c) {
    20     case '\'': return c;
    21     case '\"': return c;
    22     case '<': return '>';
    23     case '{': return '}';
    24     case '[': return ']';
    25     case '(': return ')';
    26     default: break;
    27     }
    28     return ' ';
    29 }
    31 PRBool NSSUTIL_ArgIsBlank(char c) {
    32    return isspace((unsigned char )c);
    33 }
    35 PRBool NSSUTIL_ArgIsEscape(char c) {
    36     return c == '\\';
    37 }
    39 PRBool NSSUTIL_ArgIsQuote(char c) {
    40     switch (c) {
    41     case '\'':
    42     case '\"':
    43     case '<':
    44     case '{': /* } end curly to keep vi bracket matching working */
    45     case '(': /* ) */
    46     case '[': /* ] */ return PR_TRUE;
    47     default: break;
    48     }
    49     return PR_FALSE;
    50 }
    52 char *NSSUTIL_ArgStrip(char *c) {
    53    while (*c && NSSUTIL_ArgIsBlank(*c)) c++;
    54    return c;
    55 }
    57 /*
    58  * find the end of the current tag/value pair. string should be pointing just
    59  * after the equal sign. Handles quoted characters.
    60  */
    61 char *
    62 NSSUTIL_ArgFindEnd(char *string) {
    63     char endChar = ' ';
    64     PRBool lastEscape = PR_FALSE;
    66     if (NSSUTIL_ArgIsQuote(*string)) {
    67 	endChar = NSSUTIL_ArgGetPair(*string);
    68 	string++;
    69     }
    71     for (;*string; string++) {
    72 	if (lastEscape) {
    73 	    lastEscape = PR_FALSE;
    74 	    continue;
    75 	}
    76 	if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
    77 	    lastEscape = PR_TRUE;
    78 	    continue;
    79 	} 
    80 	if ((endChar == ' ') && NSSUTIL_ArgIsBlank(*string)) break;
    81 	if (*string == endChar) {
    82 	    break;
    83 	}
    84     }
    86     return string;
    87 }
    89 /*
    90  * get the value pointed to by string. string should be pointing just beyond
    91  * the equal sign.
    92  */
    93 char *
    94 NSSUTIL_ArgFetchValue(char *string, int *pcount)
    95 {
    96     char *end = NSSUTIL_ArgFindEnd(string);
    97     char *retString, *copyString;
    98     PRBool lastEscape = PR_FALSE;
    99     int len;
   101     len = end - string;
   102     if (len == 0) {
   103 	*pcount = 0;
   104 	return NULL;
   105     }
   107     copyString = retString = (char *)PORT_Alloc(len+1);
   109     if (*end) len++;
   110     *pcount = len;
   111     if (retString == NULL) return NULL;
   114     if (NSSUTIL_ArgIsQuote(*string)) string++;
   115     for (; string < end; string++) {
   116 	if (NSSUTIL_ArgIsEscape(*string) && !lastEscape) {
   117 	    lastEscape = PR_TRUE;
   118 	    continue;
   119 	}
   120 	lastEscape = PR_FALSE;
   121 	*copyString++ = *string;
   122     }
   123     *copyString = 0;
   124     return retString;
   125 }
   127 /*
   128  * point to the next parameter in string
   129  */
   130 char *
   131 NSSUTIL_ArgSkipParameter(char *string) 
   132 {
   133      char *end;
   134      /* look for the end of the <name>= */
   135      for (;*string; string++) {
   136 	if (*string == '=') { string++; break; }
   137 	if (NSSUTIL_ArgIsBlank(*string)) return(string); 
   138      }
   140      end = NSSUTIL_ArgFindEnd(string);
   141      if (*end) end++;
   142      return end;
   143 }
   145 /*
   146  * get the value from that tag value pair.
   147  */
   148 char *
   149 NSSUTIL_ArgGetParamValue(char *paramName,char *parameters)
   150 {
   151     char searchValue[256];
   152     int paramLen = strlen(paramName);
   153     char *returnValue = NULL;
   154     int next;
   156     if ((parameters == NULL) || (*parameters == 0)) return NULL;
   158     PORT_Assert(paramLen+2 < sizeof(searchValue));
   160     PORT_Strcpy(searchValue,paramName);
   161     PORT_Strcat(searchValue,"=");
   162     while (*parameters) {
   163 	if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) {
   164 	    parameters += paramLen+1;
   165 	    returnValue = NSSUTIL_ArgFetchValue(parameters,&next);
   166 	    break;
   167 	} else {
   168 	    parameters = NSSUTIL_ArgSkipParameter(parameters);
   169 	}
   170 	parameters = NSSUTIL_ArgStrip(parameters);
   171    }
   172    return returnValue;
   173 }
   175 /*
   176  * find the next flag in the parameter list
   177  */  
   178 char *
   179 NSSUTIL_ArgNextFlag(char *flags)
   180 {
   181     for (; *flags ; flags++) {
   182 	if (*flags == ',') {
   183 	    flags++;
   184 	    break;
   185 	}
   186     }
   187     return flags;
   188 }
   190 /*
   191  * return true if the flag is set in the label parameter.
   192  */
   193 PRBool
   194 NSSUTIL_ArgHasFlag(char *label, char *flag, char *parameters)
   195 {
   196     char *flags,*index;
   197     int len = strlen(flag);
   198     PRBool found = PR_FALSE;
   200     flags = NSSUTIL_ArgGetParamValue(label,parameters);
   201     if (flags == NULL) return PR_FALSE;
   203     for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) {
   204 	if (PORT_Strncasecmp(index,flag,len) == 0) {
   205 	    found=PR_TRUE;
   206 	    break;
   207 	}
   208     }
   209     PORT_Free(flags);
   210     return found;
   211 }
   213 /*
   214  * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
   215  */
   216 long
   217 NSSUTIL_ArgDecodeNumber(char *num)
   218 {
   219     int	radix = 10;
   220     unsigned long value = 0;
   221     long retValue = 0;
   222     int sign = 1;
   223     int digit;
   225     if (num == NULL) return retValue;
   227     num = NSSUTIL_ArgStrip(num);
   229     if (*num == '-') {
   230 	sign = -1;
   231 	num++;
   232     }
   234     if (*num == '0') {
   235 	radix = 8;
   236 	num++;
   237 	if ((*num == 'x') || (*num == 'X')) {
   238 	    radix = 16;
   239 	    num++;
   240 	}
   241     }
   244     for ( ;*num; num++ ) {
   245 	if (isdigit(*num)) {
   246 	    digit = *num - '0';
   247 	} else if ((*num >= 'a') && (*num <= 'f'))  {
   248 	    digit = *num - 'a' + 10;
   249 	} else if ((*num >= 'A') && (*num <= 'F'))  {
   250 	    digit = *num - 'A' + 10;
   251 	} else {
   252 	    break;
   253 	}
   254 	if (digit >= radix) break;
   255 	value = value*radix + digit;
   256     }
   258     retValue = ((int) value) * sign;
   259     return retValue;
   260 }
   262 /*
   263  * parameters are tag value pairs. This function returns the tag or label (the
   264  * value before the equal size.
   265  */
   266 char *
   267 NSSUTIL_ArgGetLabel(char *inString, int *next) 
   268 {
   269     char *name=NULL;
   270     char *string;
   271     int len;
   273     /* look for the end of the <label>= */
   274     for (string = inString;*string; string++) {
   275 	if (*string == '=') { break; }
   276 	if (NSSUTIL_ArgIsBlank(*string)) break;
   277     }
   279     len = string - inString;
   281     *next = len; 
   282     if (*string == '=') (*next) += 1;
   283     if (len > 0) {
   284 	name = PORT_Alloc(len+1);
   285 	PORT_Strncpy(name,inString,len);
   286 	name[len] = 0;
   287     }
   288     return name;
   289 }
   291 /*
   292  * read an argument at a Long integer
   293  */
   294 long
   295 NSSUTIL_ArgReadLong(char *label,char *params, long defValue, PRBool *isdefault)
   296 {
   297     char *value;
   298     long retValue;
   299     if (isdefault) *isdefault = PR_FALSE; 
   301     value = NSSUTIL_ArgGetParamValue(label,params);
   302     if (value == NULL) {
   303 	if (isdefault) *isdefault = PR_TRUE;
   304 	return defValue;
   305     }
   306     retValue = NSSUTIL_ArgDecodeNumber(value);
   307     if (value) PORT_Free(value);
   309     return retValue;
   310 }
   313 /*
   314  * prepare a string to be quoted with 'quote' marks. We do that by adding
   315  * appropriate escapes.
   316  */
   317 static int
   318 nssutil_escapeQuotesSize(const char *string, char quote, PRBool addquotes)
   319 {
   320     int escapes = 0, size = 0;
   321     const char *src;
   323     size= addquotes ? 2 : 0;
   324     for (src=string; *src ; src++) {
   325 	if ((*src == quote) || (*src == '\\')) escapes++;
   326 	size++;
   327     }
   328     return size+escapes+1;
   330 }
   332 static char *
   333 nssutil_escapeQuotes(const char *string, char quote, PRBool addquotes)
   334 {
   335     char *newString = 0;
   336     int size = 0;
   337     const char *src;
   338     char *dest;
   340     size = nssutil_escapeQuotesSize(string, quote, addquotes);
   342     dest = newString = PORT_ZAlloc(size); 
   343     if (newString == NULL) {
   344 	return NULL;
   345     }
   347     if (addquotes) *dest++=quote;
   348     for (src=string; *src; src++,dest++) {
   349 	if ((*src == '\\') || (*src == quote)) {
   350 	    *dest++ = '\\';
   351 	}
   352 	*dest = *src;
   353     }
   354     if (addquotes) *dest=quote;
   356     return newString;
   357 }
   359 int
   360 NSSUTIL_EscapeSize(const char *string, char quote)
   361 {
   362      return nssutil_escapeQuotesSize(string, quote, PR_FALSE);
   363 }
   365 char *
   366 NSSUTIL_Escape(const char *string, char quote)
   367 {
   368     return nssutil_escapeQuotes(string, quote, PR_FALSE);
   369 }
   372 int
   373 NSSUTIL_QuoteSize(const char *string, char quote)
   374 {
   375      return nssutil_escapeQuotesSize(string, quote, PR_TRUE);
   376 }
   378 char *
   379 NSSUTIL_Quote(const char *string, char quote)
   380 {
   381     return nssutil_escapeQuotes(string, quote, PR_TRUE);
   382 }
   384 int
   385 NSSUTIL_DoubleEscapeSize(const char *string, char quote1, char quote2)
   386 {
   387     int escapes = 0, size = 0;
   388     const char *src;
   389     for (src=string; *src ; src++) {
   390         if (*src == '\\')   escapes+=3; /* \\\\ */
   391         if (*src == quote1) escapes+=2; /* \\quote1 */
   392         if (*src == quote2) escapes++;   /* \quote2 */
   393         size++;
   394     }
   396     return escapes+size+1;
   397 }
   399 char *
   400 NSSUTIL_DoubleEscape(const char *string, char quote1, char quote2)
   401 {
   402     char *round1 = NULL;
   403     char *retValue = NULL;
   404     if (string == NULL) {
   405         goto done;
   406     }
   407     round1 = nssutil_escapeQuotes(string, quote1, PR_FALSE);
   408     if (round1) {
   409         retValue = nssutil_escapeQuotes(round1, quote2, PR_FALSE);
   410         PORT_Free(round1);
   411     }
   413 done:
   414     if (retValue == NULL) {
   415         retValue = PORT_Strdup("");
   416     }
   417     return retValue;
   418 }
   421 /************************************************************************
   422  * These functions are used in contructing strings.
   423  * NOTE: they will always return a string, but sometimes it will return
   424  * a specific NULL string. These strings must be freed with util_freePair.
   425  */
   427 /* string to return on error... */
   428 static char *nssutil_nullString = "";
   430 static char *
   431 nssutil_formatValue(PLArenaPool *arena, char *value, char quote)
   432 {
   433     char *vp,*vp2,*retval;
   434     int size = 0, escapes = 0;
   436     for (vp=value; *vp ;vp++) {
   437 	if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) escapes++;
   438 	size++;
   439     }
   440     if (arena) {
   441 	retval = PORT_ArenaZAlloc(arena,size+escapes+1);
   442     } else {
   443 	retval = PORT_ZAlloc(size+escapes+1);
   444     }
   445     if (retval == NULL) return NULL;
   446     vp2 = retval;
   447     for (vp=value; *vp; vp++) {
   448 	if ((*vp == quote) || (*vp == NSSUTIL_ARG_ESCAPE)) 
   449 				*vp2++ = NSSUTIL_ARG_ESCAPE;
   450 	*vp2++ = *vp;
   451     }
   452     return retval;
   453 }
   456 static PRBool nssutil_argHasChar(char *v, char c)
   457 {
   458    for ( ;*v; v++) {
   459         if (*v == c) return PR_TRUE;
   460    }
   461    return PR_FALSE;
   462 }
   464 static PRBool nssutil_argHasBlanks(char *v)
   465 {
   466    for ( ;*v; v++) {
   467         if (NSSUTIL_ArgIsBlank(*v)) return PR_TRUE;
   468    }
   469    return PR_FALSE;
   470 }
   472 static char *
   473 nssutil_formatPair(char *name, char *value, char quote)
   474 {
   475     char openQuote = quote;
   476     char closeQuote = NSSUTIL_ArgGetPair(quote);
   477     char *newValue = NULL;
   478     char *returnValue;
   479     PRBool need_quote = PR_FALSE;
   481     if (!value || (*value == 0)) return nssutil_nullString;
   483     if (nssutil_argHasBlanks(value) || NSSUTIL_ArgIsQuote(value[0]))
   484 							 need_quote=PR_TRUE;
   486     if ((need_quote && nssutil_argHasChar(value,closeQuote))
   487 			|| nssutil_argHasChar(value,NSSUTIL_ARG_ESCAPE)) {
   488 	value = newValue = nssutil_formatValue(NULL, value,quote);
   489 	if (newValue == NULL) return nssutil_nullString;
   490     }
   491     if (need_quote) {
   492     	returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote);
   493     } else {
   494     	returnValue = PR_smprintf("%s=%s",name,value);
   495     }
   496     if (returnValue == NULL) returnValue = nssutil_nullString;
   498     if (newValue) PORT_Free(newValue);
   500     return returnValue;
   501 }
   503 static char *nssutil_formatIntPair(char *name, unsigned long value, 
   504                                   unsigned long def)
   505 {
   506     char *returnValue;
   508     if (value == def) return nssutil_nullString;
   510     returnValue = PR_smprintf("%s=%d",name,value);
   512     return returnValue;
   513 }
   515 static void
   516 nssutil_freePair(char *pair)
   517 {
   518     if (pair && pair != nssutil_nullString) {
   519 	PR_smprintf_free(pair);
   520     }
   521 }
   524 /************************************************************************
   525  * Parse the Slot specific parameters in the NSS params.
   526  */
   528 struct nssutilArgSlotFlagTable {
   529     char *name;
   530     int len;
   531     unsigned long value;
   532 };
   534 #define NSSUTIL_ARG_ENTRY(arg,flag) \
   535 { #arg , sizeof(#arg)-1, flag }
   536 static struct nssutilArgSlotFlagTable nssutil_argSlotFlagTable[] = {
   537 	NSSUTIL_ARG_ENTRY(RSA,SECMOD_RSA_FLAG),
   538 	NSSUTIL_ARG_ENTRY(DSA,SECMOD_RSA_FLAG),
   539 	NSSUTIL_ARG_ENTRY(RC2,SECMOD_RC4_FLAG),
   540 	NSSUTIL_ARG_ENTRY(RC4,SECMOD_RC2_FLAG),
   541 	NSSUTIL_ARG_ENTRY(DES,SECMOD_DES_FLAG),
   542 	NSSUTIL_ARG_ENTRY(DH,SECMOD_DH_FLAG),
   543 	NSSUTIL_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG),
   544 	NSSUTIL_ARG_ENTRY(RC5,SECMOD_RC5_FLAG),
   545 	NSSUTIL_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG),
   546 	NSSUTIL_ARG_ENTRY(SHA256,SECMOD_SHA256_FLAG),
   547 	NSSUTIL_ARG_ENTRY(SHA512,SECMOD_SHA512_FLAG),
   548 	NSSUTIL_ARG_ENTRY(MD5,SECMOD_MD5_FLAG),
   549 	NSSUTIL_ARG_ENTRY(MD2,SECMOD_MD2_FLAG),
   550 	NSSUTIL_ARG_ENTRY(SSL,SECMOD_SSL_FLAG),
   551 	NSSUTIL_ARG_ENTRY(TLS,SECMOD_TLS_FLAG),
   552 	NSSUTIL_ARG_ENTRY(AES,SECMOD_AES_FLAG),
   553 	NSSUTIL_ARG_ENTRY(Camellia,SECMOD_CAMELLIA_FLAG),
   554 	NSSUTIL_ARG_ENTRY(SEED,SECMOD_SEED_FLAG),
   555 	NSSUTIL_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG),
   556 	NSSUTIL_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG),
   557 	NSSUTIL_ARG_ENTRY(Disable, SECMOD_DISABLE_FLAG),
   558 };
   560 static int nssutil_argSlotFlagTableSize = 
   561 	sizeof(nssutil_argSlotFlagTable)/sizeof(nssutil_argSlotFlagTable[0]);
   564 /* turn the slot flags into a bit mask */
   565 unsigned long
   566 NSSUTIL_ArgParseSlotFlags(char *label,char *params)
   567 {
   568     char *flags,*index;
   569     unsigned long retValue = 0;
   570     int i;
   571     PRBool all = PR_FALSE;
   573     flags = NSSUTIL_ArgGetParamValue(label,params);
   574     if (flags == NULL) return 0;
   576     if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE;
   578     for (index=flags; *index; index=NSSUTIL_ArgNextFlag(index)) {
   579 	for (i=0; i < nssutil_argSlotFlagTableSize; i++) {
   580 	    if (all || 
   581 		(PORT_Strncasecmp(index, nssutil_argSlotFlagTable[i].name,
   582 				nssutil_argSlotFlagTable[i].len) == 0)) {
   583 		retValue |= nssutil_argSlotFlagTable[i].value;
   584 	    }
   585 	}
   586     }
   587     PORT_Free(flags);
   588     return retValue;
   589 }
   592 /* parse a single slot specific parameter */
   593 static void
   594 nssutil_argDecodeSingleSlotInfo(char *name, char *params, 
   595                                struct NSSUTILPreSlotInfoStr *slotInfo)
   596 {
   597     char *askpw;
   599     slotInfo->slotID=NSSUTIL_ArgDecodeNumber(name);
   600     slotInfo->defaultFlags=NSSUTIL_ArgParseSlotFlags("slotFlags",params);
   601     slotInfo->timeout=NSSUTIL_ArgReadLong("timeout",params, 0, NULL);
   603     askpw = NSSUTIL_ArgGetParamValue("askpw",params);
   604     slotInfo->askpw = 0;
   606     if (askpw) {
   607 	if (PORT_Strcasecmp(askpw,"every") == 0) {
   608     	    slotInfo->askpw = -1;
   609 	} else if (PORT_Strcasecmp(askpw,"timeout") == 0) {
   610     	    slotInfo->askpw = 1;
   611 	} 
   612 	PORT_Free(askpw);
   613 	slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
   614     }
   615     slotInfo->hasRootCerts = NSSUTIL_ArgHasFlag("rootFlags", "hasRootCerts", 
   616                                                params);
   617     slotInfo->hasRootTrust = NSSUTIL_ArgHasFlag("rootFlags", "hasRootTrust", 
   618                                                params);
   619 }
   621 /* parse all the slot specific parameters. */
   622 struct NSSUTILPreSlotInfoStr *
   623 NSSUTIL_ArgParseSlotInfo(PLArenaPool *arena, char *slotParams, int *retCount)
   624 {
   625     char *slotIndex;
   626     struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
   627     int i=0,count = 0,next;
   629     *retCount = 0;
   630     if ((slotParams == NULL) || (*slotParams == 0))  return NULL;
   632     /* first count the number of slots */
   633     for (slotIndex = NSSUTIL_ArgStrip(slotParams); *slotIndex; 
   634 	 slotIndex = NSSUTIL_ArgStrip(NSSUTIL_ArgSkipParameter(slotIndex))) {
   635 	count++;
   636     }
   638     /* get the data structures */
   639     if (arena) {
   640 	slotInfo = PORT_ArenaZNewArray(arena,
   641 				struct NSSUTILPreSlotInfoStr, count); 
   642     } else {
   643 	slotInfo = PORT_ZNewArray(struct NSSUTILPreSlotInfoStr, count);
   644     }
   645     if (slotInfo == NULL) return NULL;
   647     for (slotIndex = NSSUTIL_ArgStrip(slotParams), i = 0; 
   648 					*slotIndex && i < count ; ) {
   649 	char *name;
   650 	name = NSSUTIL_ArgGetLabel(slotIndex,&next);
   651 	slotIndex += next;
   653 	if (!NSSUTIL_ArgIsBlank(*slotIndex)) {
   654 	    char *args = NSSUTIL_ArgFetchValue(slotIndex,&next);
   655 	    slotIndex += next;
   656 	    if (args) {
   657 		nssutil_argDecodeSingleSlotInfo(name,args,&slotInfo[i]);
   658 		i++;
   659 		PORT_Free(args);
   660 	    }
   661 	}
   662 	if (name) PORT_Free(name);
   663 	slotIndex = NSSUTIL_ArgStrip(slotIndex);
   664     }
   665     *retCount = i;
   666     return slotInfo;
   667 }
   669 /************************************************************************
   670  * make a new slot specific parameter 
   671  */
   672 /* first make the slot flags */
   673 static char *
   674 nssutil_mkSlotFlags(unsigned long defaultFlags)
   675 {
   676     char *flags=NULL;
   677     int i,j;
   679     for (i=0; i < sizeof(defaultFlags)*8; i++) {
   680 	if (defaultFlags & (1UL <<i)) {
   681 	    char *string = NULL;
   683 	    for (j=0; j < nssutil_argSlotFlagTableSize; j++) {
   684 		if (nssutil_argSlotFlagTable[j].value == ( 1UL << i )) {
   685 		    string = nssutil_argSlotFlagTable[j].name;
   686 		    break;
   687 		}
   688 	    }
   689 	    if (string) {
   690 		if (flags) {
   691 		    char *tmp;
   692 		    tmp = PR_smprintf("%s,%s",flags,string);
   693 		    PR_smprintf_free(flags);
   694 		    flags = tmp;
   695 		} else {
   696 		    flags = PR_smprintf("%s",string);
   697 		}
   698 	    }
   699 	}
   700     }
   702     return flags;
   703 }
   705 /* now make the root flags */
   706 #define NSSUTIL_MAX_ROOT_FLAG_SIZE  sizeof("hasRootCerts")+sizeof("hasRootTrust")
   707 static char *
   708 nssutil_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
   709 {
   710     char *flags= (char *)PORT_ZAlloc(NSSUTIL_MAX_ROOT_FLAG_SIZE);
   711     PRBool first = PR_TRUE;
   713     PORT_Memset(flags,0,NSSUTIL_MAX_ROOT_FLAG_SIZE);
   714     if (hasRootCerts) {
   715 	PORT_Strcat(flags,"hasRootCerts");
   716 	first = PR_FALSE;
   717     }
   718     if (hasRootTrust) {
   719 	if (!first) PORT_Strcat(flags,",");
   720 	PORT_Strcat(flags,"hasRootTrust");
   721 	first = PR_FALSE;
   722     }
   723     return flags;
   724 }
   726 /* now make a full slot string */
   727 char *
   728 NSSUTIL_MkSlotString(unsigned long slotID, unsigned long defaultFlags,
   729 		  unsigned long timeout, unsigned char askpw_in,
   730 		  PRBool hasRootCerts, PRBool hasRootTrust) {
   731     char *askpw,*flags,*rootFlags,*slotString;
   732     char *flagPair,*rootFlagsPair;
   734     switch (askpw_in) {
   735     case 0xff:
   736 	askpw = "every";
   737 	break;
   738     case 1:
   739 	askpw = "timeout";
   740 	break;
   741     default:
   742 	askpw = "any";
   743 	break;
   744     }
   745     flags = nssutil_mkSlotFlags(defaultFlags);
   746     rootFlags = nssutil_mkRootFlags(hasRootCerts,hasRootTrust);
   747     flagPair = nssutil_formatPair("slotFlags",flags,'\'');
   748     rootFlagsPair = nssutil_formatPair("rootFlags",rootFlags,'\'');
   749     if (flags) PR_smprintf_free(flags);
   750     if (rootFlags) PORT_Free(rootFlags);
   751     if (defaultFlags & PK11_OWN_PW_DEFAULTS) {
   752     	slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]",
   753 				(PRUint32)slotID,flagPair,askpw,timeout,
   754 				rootFlagsPair);
   755     } else {
   756     	slotString = PR_smprintf("0x%08lx=[%s %s]",
   757 				(PRUint32)slotID,flagPair,rootFlagsPair);
   758     }
   759     nssutil_freePair(flagPair);
   760     nssutil_freePair(rootFlagsPair);
   761     return slotString;
   762 }
   765 /************************************************************************
   766  * Parse Full module specs into: library, commonName, module parameters,
   767  * and NSS specifi parameters.
   768  */
   769 SECStatus
   770 NSSUTIL_ArgParseModuleSpec(char *modulespec, char **lib, char **mod, 
   771 					char **parameters, char **nss)
   772 {
   773     int next;
   774     modulespec = NSSUTIL_ArgStrip(modulespec);
   776     *lib = *mod = *parameters = *nss = 0;
   778     while (*modulespec) {
   779 	NSSUTIL_HANDLE_STRING_ARG(modulespec,*lib,"library=",;)
   780 	NSSUTIL_HANDLE_STRING_ARG(modulespec,*mod,"name=",;)
   781 	NSSUTIL_HANDLE_STRING_ARG(modulespec,*parameters,"parameters=",;)
   782 	NSSUTIL_HANDLE_STRING_ARG(modulespec,*nss,"nss=",;)
   783 	NSSUTIL_HANDLE_FINAL_ARG(modulespec)
   784    }
   785    return SECSuccess;
   786 }
   788 /************************************************************************
   789  * make a new module spec from it's components */
   790 char *
   791 NSSUTIL_MkModuleSpec(char *dllName, char *commonName, char *parameters, 
   792 								char *NSS)
   793 {
   794     char *moduleSpec;
   795     char *lib,*name,*param,*nss;
   797     /*
   798      * now the final spec
   799      */
   800     lib = nssutil_formatPair("library",dllName,'\"');
   801     name = nssutil_formatPair("name",commonName,'\"');
   802     param = nssutil_formatPair("parameters",parameters,'\"');
   803     nss = nssutil_formatPair("NSS",NSS,'\"');
   804     moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss);
   805     nssutil_freePair(lib);
   806     nssutil_freePair(name);
   807     nssutil_freePair(param);
   808     nssutil_freePair(nss);
   809     return (moduleSpec);
   810 }
   813 #define NSSUTIL_ARG_FORTEZZA_FLAG "FORTEZZA"
   814 /******************************************************************************
   815  * Parse the cipher flags from the NSS parameter
   816  */
   817 void
   818 NSSUTIL_ArgParseCipherFlags(unsigned long *newCiphers,char *cipherList)
   819 {
   820     newCiphers[0] = newCiphers[1] = 0;
   821     if ((cipherList == NULL) || (*cipherList == 0)) return;
   823     for (;*cipherList; cipherList=NSSUTIL_ArgNextFlag(cipherList)) {
   824 	if (PORT_Strncasecmp(cipherList,NSSUTIL_ARG_FORTEZZA_FLAG,
   825 				sizeof(NSSUTIL_ARG_FORTEZZA_FLAG)-1) == 0) {
   826 	    newCiphers[0] |= SECMOD_FORTEZZA_FLAG;
   827 	} 
   829 	/* add additional flags here as necessary */
   830 	/* direct bit mapping escape */
   831 	if (*cipherList == 0) {
   832 	   if (cipherList[1] == 'l') {
   833 		newCiphers[1] |= atoi(&cipherList[2]);
   834 	   } else {
   835 		newCiphers[0] |= atoi(&cipherList[2]);
   836 	   }
   837 	}
   838     }
   839 }
   842 /*********************************************************************
   843  * make NSS parameter...
   844  */
   845 /* First make NSS specific flags */
   846 #define MAX_FLAG_SIZE  sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\
   847 				sizeof("moduleDBOnly")+sizeof("critical")
   848 static char *
   849 nssutil_mkNSSFlags(PRBool internal, PRBool isFIPS,
   850 		PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical)
   851 {
   852     char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE);
   853     PRBool first = PR_TRUE;
   855     PORT_Memset(flags,0,MAX_FLAG_SIZE);
   856     if (internal) {
   857 	PORT_Strcat(flags,"internal");
   858 	first = PR_FALSE;
   859     }
   860     if (isFIPS) {
   861 	if (!first) PORT_Strcat(flags,",");
   862 	PORT_Strcat(flags,"FIPS");
   863 	first = PR_FALSE;
   864     }
   865     if (isModuleDB) {
   866 	if (!first) PORT_Strcat(flags,",");
   867 	PORT_Strcat(flags,"moduleDB");
   868 	first = PR_FALSE;
   869     }
   870     if (isModuleDBOnly) {
   871 	if (!first) PORT_Strcat(flags,",");
   872 	PORT_Strcat(flags,"moduleDBOnly");
   873 	first = PR_FALSE;
   874     }
   875     if (isCritical) {
   876 	if (!first) PORT_Strcat(flags,",");
   877 	PORT_Strcat(flags,"critical");
   878 	first = PR_FALSE;
   879     }
   880     return flags;
   881 }
   884 /* construct the NSS cipher flags */
   885 static char *
   886 nssutil_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
   887 {
   888     char *cipher = NULL;
   889     int i;
   891     for (i=0; i < sizeof(ssl0)*8; i++) {
   892 	if (ssl0 & (1UL <<i)) {
   893 	    char *string;
   894 	    if ((1UL <<i) == SECMOD_FORTEZZA_FLAG) {
   895 		string = PR_smprintf("%s",NSSUTIL_ARG_FORTEZZA_FLAG);
   896 	    } else {
   897 		string = PR_smprintf("0h0x%08lx", 1UL <<i);
   898 	    }
   899 	    if (cipher) {
   900 		char *tmp;
   901 		tmp = PR_smprintf("%s,%s",cipher,string);
   902 		PR_smprintf_free(cipher);
   903 		PR_smprintf_free(string);
   904 		cipher = tmp;
   905 	    } else {
   906 		cipher = string;
   907 	    }
   908 	}
   909     }
   910     for (i=0; i < sizeof(ssl0)*8; i++) {
   911 	if (ssl1 & (1UL <<i)) {
   912 	    if (cipher) {
   913 		char *tmp;
   914 		tmp = PR_smprintf("%s,0l0x%08lx",cipher, 1UL <<i);
   915 		PR_smprintf_free(cipher);
   916 		cipher = tmp;
   917 	    } else {
   918 		cipher = PR_smprintf("0l0x%08lx", 1UL <<i);
   919 	    }
   920 	}
   921     }
   923     return cipher;
   924 }
   926 /* Assemble a full NSS string. */
   927 char *
   928 NSSUTIL_MkNSSString(char **slotStrings, int slotCount, PRBool internal, 
   929 	  PRBool isFIPS, PRBool isModuleDB,  PRBool isModuleDBOnly, 
   930 	  PRBool isCritical, unsigned long trustOrder, 
   931 	  unsigned long cipherOrder, unsigned long ssl0, unsigned long ssl1)
   932 {
   933     int slotLen, i;
   934     char *slotParams, *ciphers, *nss, *nssFlags, *tmp;
   935     char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair;
   938     /* now let's build up the string
   939      * first the slot infos
   940      */
   941     slotLen=0;
   942     for (i=0; i < (int)slotCount; i++) {
   943 	slotLen += PORT_Strlen(slotStrings[i])+1;
   944     }
   945     slotLen += 1; /* space for the final NULL */
   947     slotParams = (char *)PORT_ZAlloc(slotLen);
   948     PORT_Memset(slotParams,0,slotLen);
   949     for (i=0; i < (int)slotCount; i++) {
   950 	PORT_Strcat(slotParams,slotStrings[i]);
   951 	PORT_Strcat(slotParams," ");
   952 	PR_smprintf_free(slotStrings[i]);
   953 	slotStrings[i]=NULL;
   954     }
   956     /*
   957      * now the NSS structure
   958      */
   959     nssFlags = nssutil_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly,
   960 							isCritical); 
   961 	/* for now only the internal module is critical */
   962     ciphers = nssutil_mkCipherFlags(ssl0, ssl1);
   964     trustOrderPair = nssutil_formatIntPair("trustOrder",trustOrder,
   965 					NSSUTIL_DEFAULT_TRUST_ORDER);
   966     cipherOrderPair = nssutil_formatIntPair("cipherOrder",cipherOrder,
   967 					NSSUTIL_DEFAULT_CIPHER_ORDER);
   968     slotPair=nssutil_formatPair("slotParams",slotParams,'{'); /* } */
   969     if (slotParams) PORT_Free(slotParams);
   970     cipherPair=nssutil_formatPair("ciphers",ciphers,'\'');
   971     if (ciphers) PR_smprintf_free(ciphers);
   972     flagPair=nssutil_formatPair("Flags",nssFlags,'\'');
   973     if (nssFlags) PORT_Free(nssFlags);
   974     nss = PR_smprintf("%s %s %s %s %s",trustOrderPair,
   975 			cipherOrderPair,slotPair,cipherPair,flagPair);
   976     nssutil_freePair(trustOrderPair);
   977     nssutil_freePair(cipherOrderPair);
   978     nssutil_freePair(slotPair);
   979     nssutil_freePair(cipherPair);
   980     nssutil_freePair(flagPair);
   981     tmp = NSSUTIL_ArgStrip(nss);
   982     if (*tmp == '\0') {
   983 	PR_smprintf_free(nss);
   984 	nss = NULL;
   985     }
   986     return nss;
   987 }
   989 /*****************************************************************************
   990  *
   991  * Private calls for use by softoken and utilmod.c
   992  */
   994 #define SQLDB "sql:"
   995 #define EXTERNDB "extern:"
   996 #define LEGACY "dbm:"
   997 #define MULTIACCESS "multiaccess:"
   998 #define SECMOD_DB "secmod.db"
   999 const char *
  1000 _NSSUTIL_EvaluateConfigDir(const char *configdir, 
  1001 			   NSSDBType *pdbType, char **appName)
  1003     NSSDBType dbType;
  1004     *appName = NULL;
  1005 /* force the default */
  1006 #ifdef NSS_DISABLE_DBM
  1007     dbType = NSS_DB_TYPE_SQL;
  1008 #else
  1009     dbType = NSS_DB_TYPE_LEGACY;
  1010 #endif
  1011     if (PORT_Strncmp(configdir, MULTIACCESS, sizeof(MULTIACCESS)-1) == 0) {
  1012 	char *cdir;
  1013 	dbType = NSS_DB_TYPE_MULTIACCESS;
  1015 	*appName = PORT_Strdup(configdir+sizeof(MULTIACCESS)-1);
  1016 	if (*appName == NULL) {
  1017 	    return configdir;
  1019 	cdir = *appName;
  1020 	while (*cdir && *cdir != ':') {
  1021 	    cdir++;
  1023 	if (*cdir == ':') {
  1024 	   *cdir = 0;
  1025 	   cdir++;
  1027 	configdir = cdir;
  1028     } else if (PORT_Strncmp(configdir, SQLDB, sizeof(SQLDB)-1) == 0) {
  1029 	dbType = NSS_DB_TYPE_SQL;
  1030 	configdir = configdir + sizeof(SQLDB) -1;
  1031     } else if (PORT_Strncmp(configdir, EXTERNDB, sizeof(EXTERNDB)-1) == 0) {
  1032 	dbType = NSS_DB_TYPE_EXTERN;
  1033 	configdir = configdir + sizeof(EXTERNDB) -1;
  1034     } else if (PORT_Strncmp(configdir, LEGACY, sizeof(LEGACY)-1) == 0) {
  1035 	dbType = NSS_DB_TYPE_LEGACY;
  1036 	configdir = configdir + sizeof(LEGACY) -1;
  1037     } else {
  1038 	/* look up the default from the environment */
  1039 	char *defaultType = PR_GetEnv("NSS_DEFAULT_DB_TYPE");
  1040 	if (defaultType != NULL) {
  1041 	    if (PORT_Strncmp(defaultType, SQLDB, sizeof(SQLDB)-2) == 0) {
  1042 		dbType = NSS_DB_TYPE_SQL;
  1043 	    } else if (PORT_Strncmp(defaultType,EXTERNDB,sizeof(EXTERNDB)-2)==0) {
  1044 		dbType = NSS_DB_TYPE_EXTERN;
  1045 	    } else if (PORT_Strncmp(defaultType, LEGACY, sizeof(LEGACY)-2) == 0) {
  1046 		dbType = NSS_DB_TYPE_LEGACY;
  1050     /* if the caller has already set a type, don't change it */
  1051     if (*pdbType == NSS_DB_TYPE_NONE) {
  1052 	*pdbType = dbType;
  1054     return configdir;
  1057 char *
  1058 _NSSUTIL_GetSecmodName(char *param, NSSDBType *dbType, char **appName,
  1059 		   char **filename, PRBool *rw)
  1061     int next;
  1062     char *configdir = NULL;
  1063     char *secmodName = NULL;
  1064     char *value = NULL;
  1065     char *save_params = param;
  1066     const char *lconfigdir;
  1067     PRBool noModDB = PR_FALSE;
  1068     param = NSSUTIL_ArgStrip(param);
  1071     while (*param) {
  1072 	NSSUTIL_HANDLE_STRING_ARG(param,configdir,"configDir=",;)
  1073 	NSSUTIL_HANDLE_STRING_ARG(param,secmodName,"secmod=",;)
  1074 	NSSUTIL_HANDLE_FINAL_ARG(param)
  1077    *rw = PR_TRUE;
  1078    if (NSSUTIL_ArgHasFlag("flags","readOnly",save_params)) {
  1079 	*rw = PR_FALSE;
  1082    if (!secmodName || *secmodName == '\0') {
  1083 	if (secmodName) PORT_Free(secmodName);
  1084 	secmodName = PORT_Strdup(SECMOD_DB);
  1087    *filename = secmodName;
  1088    lconfigdir = _NSSUTIL_EvaluateConfigDir(configdir, dbType, appName);
  1090    if (NSSUTIL_ArgHasFlag("flags","noModDB",save_params)) {
  1091 	/* there isn't a module db, don't load the legacy support */
  1092 	noModDB = PR_TRUE;
  1093 	*dbType = NSS_DB_TYPE_SQL;
  1094 	PORT_Free(*filename);
  1095 	*filename = NULL;
  1096         *rw = PR_FALSE;
  1099    /* only use the renamed secmod for legacy databases */
  1100    if ((*dbType != NSS_DB_TYPE_LEGACY) && 
  1101 	(*dbType != NSS_DB_TYPE_MULTIACCESS)) {
  1102 	secmodName="pkcs11.txt";
  1105    if (noModDB) {
  1106 	value = NULL;
  1107    } else if (lconfigdir && lconfigdir[0] != '\0') {
  1108 	value = PR_smprintf("%s" NSSUTIL_PATH_SEPARATOR "%s",
  1109 			lconfigdir,secmodName);
  1110    } else {
  1111 	value = PR_smprintf("%s",secmodName);
  1113    if (configdir) PORT_Free(configdir);
  1114    return value;

mercurial