Back to index

lightning-sunbird  0.9+nobinonly
pk11pars.h
Go to the documentation of this file.
00001 /* ***** BEGIN LICENSE BLOCK *****
00002  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00003  *
00004  * The contents of this file are subject to the Mozilla Public License Version
00005  * 1.1 (the "License"); you may not use this file except in compliance with
00006  * the License. You may obtain a copy of the License at
00007  * http://www.mozilla.org/MPL/
00008  *
00009  * Software distributed under the License is distributed on an "AS IS" basis,
00010  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00011  * for the specific language governing rights and limitations under the
00012  * License.
00013  *
00014  * The Original Code is the Netscape security libraries.
00015  *
00016  * The Initial Developer of the Original Code is
00017  * Netscape Communications Corporation.
00018  * Portions created by the Initial Developer are Copyright (C) 2001
00019  * the Initial Developer. All Rights Reserved.
00020  *
00021  * Contributor(s):
00022  *
00023  * Alternatively, the contents of this file may be used under the terms of
00024  * either the GNU General Public License Version 2 or later (the "GPL"), or
00025  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00026  * in which case the provisions of the GPL or the LGPL are applicable instead
00027  * of those above. If you wish to allow use of your version of this file only
00028  * under the terms of either the GPL or the LGPL, and not to allow others to
00029  * use your version of this file under the terms of the MPL, indicate your
00030  * decision by deleting the provisions above and replace them with the notice
00031  * and other provisions required by the GPL or the LGPL. If you do not delete
00032  * the provisions above, a recipient may use your version of this file under
00033  * the terms of any one of the MPL, the GPL or the LGPL.
00034  *
00035  * ***** END LICENSE BLOCK ***** */
00036 /*
00037  * The following handles the loading, unloading and management of
00038  * various PCKS #11 modules
00039  */
00040 
00041 
00042 /*
00043  * this header file contains routines for parsing PKCS #11 module spec
00044  * strings. It contains 'C' code and should only be included in one module.
00045  * Currently it is included in both softoken and the wrapper.
00046  */
00047 #include <ctype.h>
00048 #include "pkcs11.h"
00049 #include "seccomon.h"
00050 #include "prprf.h"
00051 #include "secmodt.h"
00052 #include "pk11init.h"
00053 
00054 #define SECMOD_ARG_LIBRARY_PARAMETER "library="
00055 #define SECMOD_ARG_NAME_PARAMETER "name="
00056 #define SECMOD_ARG_MODULE_PARAMETER "parameters="
00057 #define SECMOD_ARG_NSS_PARAMETER "NSS="
00058 #define SECMOD_ARG_FORTEZZA_FLAG "FORTEZZA"
00059 #define SECMOD_ARG_ESCAPE '\\'
00060 
00061 struct secmodargSlotFlagTable {
00062     char *name;
00063     int len;
00064     unsigned long value;
00065 };
00066 
00067 #define SECMOD_DEFAULT_CIPHER_ORDER 0
00068 #define SECMOD_DEFAULT_TRUST_ORDER 50
00069 
00070 
00071 #define SECMOD_ARG_ENTRY(arg,flag) \
00072 { #arg , sizeof(#arg)-1, flag }
00073 static struct secmodargSlotFlagTable secmod_argSlotFlagTable[] = {
00074        SECMOD_ARG_ENTRY(RSA,SECMOD_RSA_FLAG),
00075        SECMOD_ARG_ENTRY(DSA,SECMOD_RSA_FLAG),
00076        SECMOD_ARG_ENTRY(RC2,SECMOD_RC4_FLAG),
00077        SECMOD_ARG_ENTRY(RC4,SECMOD_RC2_FLAG),
00078        SECMOD_ARG_ENTRY(DES,SECMOD_DES_FLAG),
00079        SECMOD_ARG_ENTRY(DH,SECMOD_DH_FLAG),
00080        SECMOD_ARG_ENTRY(FORTEZZA,SECMOD_FORTEZZA_FLAG),
00081        SECMOD_ARG_ENTRY(RC5,SECMOD_RC5_FLAG),
00082        SECMOD_ARG_ENTRY(SHA1,SECMOD_SHA1_FLAG),
00083        SECMOD_ARG_ENTRY(MD5,SECMOD_MD5_FLAG),
00084        SECMOD_ARG_ENTRY(MD2,SECMOD_MD2_FLAG),
00085        SECMOD_ARG_ENTRY(SSL,SECMOD_SSL_FLAG),
00086        SECMOD_ARG_ENTRY(TLS,SECMOD_TLS_FLAG),
00087        SECMOD_ARG_ENTRY(AES,SECMOD_AES_FLAG),
00088        SECMOD_ARG_ENTRY(PublicCerts,SECMOD_FRIENDLY_FLAG),
00089        SECMOD_ARG_ENTRY(RANDOM,SECMOD_RANDOM_FLAG),
00090 };
00091 
00092 #define SECMOD_HANDLE_STRING_ARG(param,target,value,command) \
00093     if (PORT_Strncasecmp(param,value,sizeof(value)-1) == 0) { \
00094        param += sizeof(value)-1; \
00095        target = secmod_argFetchValue(param,&next); \
00096        param += next; \
00097        command ;\
00098     } else  
00099 
00100 #define SECMOD_HANDLE_FINAL_ARG(param) \
00101     { param = secmod_argSkipParameter(param); } param = secmod_argStrip(param);
00102        
00103 
00104 static int secmod_argSlotFlagTableSize = 
00105        sizeof(secmod_argSlotFlagTable)/sizeof(secmod_argSlotFlagTable[0]);
00106 
00107 
00108 static PRBool secmod_argGetPair(char c) {
00109     switch (c) {
00110     case '\'': return c;
00111     case '\"': return c;
00112     case '<': return '>';
00113     case '{': return '}';
00114     case '[': return ']';
00115     case '(': return ')';
00116     default: break;
00117     }
00118     return ' ';
00119 }
00120 
00121 static PRBool secmod_argIsBlank(char c) {
00122    return isspace(c);
00123 }
00124 
00125 static PRBool secmod_argIsEscape(char c) {
00126     return c == '\\';
00127 }
00128 
00129 static PRBool secmod_argIsQuote(char c) {
00130     switch (c) {
00131     case '\'':
00132     case '\"':
00133     case '<':
00134     case '{': /* } end curly to keep vi bracket matching working */
00135     case '(': /* ) */
00136     case '[': /* ] */ return PR_TRUE;
00137     default: break;
00138     }
00139     return PR_FALSE;
00140 }
00141 
00142 static PRBool secmod_argHasChar(char *v, char c)
00143 {
00144    for ( ;*v; v++) {
00145        if (*v == c) return PR_TRUE;
00146    }
00147    return PR_FALSE;
00148 }
00149 
00150 static PRBool secmod_argHasBlanks(char *v)
00151 {
00152    for ( ;*v; v++) {
00153        if (secmod_argIsBlank(*v)) return PR_TRUE;
00154    }
00155    return PR_FALSE;
00156 }
00157 
00158 static char *secmod_argStrip(char *c) {
00159    while (*c && secmod_argIsBlank(*c)) c++;
00160    return c;
00161 }
00162 
00163 static char *
00164 secmod_argFindEnd(char *string) {
00165     char endChar = ' ';
00166     PRBool lastEscape = PR_FALSE;
00167 
00168     if (secmod_argIsQuote(*string)) {
00169        endChar = secmod_argGetPair(*string);
00170        string++;
00171     }
00172 
00173     for (;*string; string++) {
00174        if (lastEscape) {
00175            lastEscape = PR_FALSE;
00176            continue;
00177        }
00178        if (secmod_argIsEscape(*string) && !lastEscape) {
00179            lastEscape = PR_TRUE;
00180            continue;
00181        } 
00182        if ((endChar == ' ') && secmod_argIsBlank(*string)) break;
00183        if (*string == endChar) {
00184            break;
00185        }
00186     }
00187 
00188     return string;
00189 }
00190 
00191 static char *
00192 secmod_argFetchValue(char *string, int *pcount)
00193 {
00194     char *end = secmod_argFindEnd(string);
00195     char *retString, *copyString;
00196     PRBool lastEscape = PR_FALSE;
00197     int len;
00198 
00199     len = end - string;
00200     if (len == 0) {
00201        *pcount = 0;
00202        return NULL;
00203     }
00204 
00205     copyString = retString = (char *)PORT_Alloc(len+1);
00206 
00207     if (*end) len++;
00208     *pcount = len;
00209     if (retString == NULL) return NULL;
00210 
00211 
00212     if (secmod_argIsQuote(*string)) string++;
00213     for (; string < end; string++) {
00214        if (secmod_argIsEscape(*string) && !lastEscape) {
00215            lastEscape = PR_TRUE;
00216            continue;
00217        }
00218        lastEscape = PR_FALSE;
00219        *copyString++ = *string;
00220     }
00221     *copyString = 0;
00222     return retString;
00223 }
00224 
00225 static char *
00226 secmod_argSkipParameter(char *string) 
00227 {
00228      char *end;
00229      /* look for the end of the <name>= */
00230      for (;*string; string++) {
00231        if (*string == '=') { string++; break; }
00232        if (secmod_argIsBlank(*string)) return(string); 
00233      }
00234 
00235      end = secmod_argFindEnd(string);
00236      if (*end) end++;
00237      return end;
00238 }
00239 
00240 
00241 static SECStatus
00242 secmod_argParseModuleSpec(char *modulespec, char **lib, char **mod, 
00243                                    char **parameters, char **nss)
00244 {
00245     int next;
00246     modulespec = secmod_argStrip(modulespec);
00247 
00248     *lib = *mod = *parameters = *nss = 0;
00249 
00250     while (*modulespec) {
00251        SECMOD_HANDLE_STRING_ARG(modulespec,*lib,SECMOD_ARG_LIBRARY_PARAMETER,;)
00252        SECMOD_HANDLE_STRING_ARG(modulespec,*mod,SECMOD_ARG_NAME_PARAMETER,;)
00253        SECMOD_HANDLE_STRING_ARG(modulespec,*parameters,
00254                                           SECMOD_ARG_MODULE_PARAMETER,;)
00255        SECMOD_HANDLE_STRING_ARG(modulespec,*nss,SECMOD_ARG_NSS_PARAMETER,;)
00256        SECMOD_HANDLE_FINAL_ARG(modulespec)
00257    }
00258    return SECSuccess;
00259 }
00260 
00261 
00262 static char *
00263 secmod_argGetParamValue(char *paramName,char *parameters)
00264 {
00265     char searchValue[256];
00266     int paramLen = strlen(paramName);
00267     char *returnValue = NULL;
00268     int next;
00269 
00270     if ((parameters == NULL) || (*parameters == 0)) return NULL;
00271 
00272     PORT_Assert(paramLen+2 < sizeof(searchValue));
00273 
00274     PORT_Strcpy(searchValue,paramName);
00275     PORT_Strcat(searchValue,"=");
00276     while (*parameters) {
00277        if (PORT_Strncasecmp(parameters,searchValue,paramLen+1) == 0) {
00278            parameters += paramLen+1;
00279            returnValue = secmod_argFetchValue(parameters,&next);
00280            break;
00281        } else {
00282            parameters = secmod_argSkipParameter(parameters);
00283        }
00284        parameters = secmod_argStrip(parameters);
00285    }
00286    return returnValue;
00287 }
00288     
00289 
00290 static char *
00291 secmod_argNextFlag(char *flags)
00292 {
00293     for (; *flags ; flags++) {
00294        if (*flags == ',') {
00295            flags++;
00296            break;
00297        }
00298     }
00299     return flags;
00300 }
00301 
00302 static PRBool
00303 secmod_argHasFlag(char *label, char *flag, char *parameters)
00304 {
00305     char *flags,*index;
00306     int len = strlen(flag);
00307     PRBool found = PR_FALSE;
00308 
00309     flags = secmod_argGetParamValue(label,parameters);
00310     if (flags == NULL) return PR_FALSE;
00311 
00312     for (index=flags; *index; index=secmod_argNextFlag(index)) {
00313        if (PORT_Strncasecmp(index,flag,len) == 0) {
00314            found=PR_TRUE;
00315            break;
00316        }
00317     }
00318     PORT_Free(flags);
00319     return found;
00320 }
00321 
00322 static void
00323 secmod_argSetNewCipherFlags(unsigned long *newCiphers,char *cipherList)
00324 {
00325     newCiphers[0] = newCiphers[1] = 0;
00326     if ((cipherList == NULL) || (*cipherList == 0)) return;
00327 
00328     for (;*cipherList; cipherList=secmod_argNextFlag(cipherList)) {
00329        if (PORT_Strncasecmp(cipherList,SECMOD_ARG_FORTEZZA_FLAG,
00330                             sizeof(SECMOD_ARG_FORTEZZA_FLAG)-1) == 0) {
00331            newCiphers[0] |= SECMOD_FORTEZZA_FLAG;
00332        } 
00333 
00334        /* add additional flags here as necessary */
00335        /* direct bit mapping escape */
00336        if (*cipherList == 0) {
00337           if (cipherList[1] == 'l') {
00338               newCiphers[1] |= atoi(&cipherList[2]);
00339           } else {
00340               newCiphers[0] |= atoi(&cipherList[2]);
00341           }
00342        }
00343     }
00344 }
00345 
00346 
00347 /*
00348  * decode a number. handle octal (leading '0'), hex (leading '0x') or decimal
00349  */
00350 static long
00351 secmod_argDecodeNumber(char *num)
00352 {
00353     int       radix = 10;
00354     unsigned long value = 0;
00355     long retValue = 0;
00356     int sign = 1;
00357     int digit;
00358 
00359     if (num == NULL) return retValue;
00360 
00361     num = secmod_argStrip(num);
00362 
00363     if (*num == '-') {
00364        sign = -1;
00365        num++;
00366     }
00367 
00368     if (*num == '0') {
00369        radix = 8;
00370        num++;
00371        if ((*num == 'x') || (*num == 'X')) {
00372            radix = 16;
00373            num++;
00374        }
00375     }
00376 
00377    
00378     for ( ;*num; num++ ) {
00379        if (isdigit(*num)) {
00380            digit = *num - '0';
00381        } else if ((*num >= 'a') && (*num <= 'f'))  {
00382            digit = *num - 'a' + 10;
00383        } else if ((*num >= 'A') && (*num <= 'F'))  {
00384            digit = *num - 'A' + 10;
00385        } else {
00386            break;
00387        }
00388        if (digit >= radix) break;
00389        value = value*radix + digit;
00390     }
00391 
00392     retValue = ((int) value) * sign;
00393     return retValue;
00394 }
00395 
00396 static long
00397 secmod_argReadLong(char *label,char *params, long defValue, PRBool *isdefault)
00398 {
00399     char *value;
00400     long retValue;
00401     if (isdefault) *isdefault = PR_FALSE; 
00402 
00403     value = secmod_argGetParamValue(label,params);
00404     if (value == NULL) {
00405        if (isdefault) *isdefault = PR_TRUE;
00406        return defValue;
00407     }
00408     retValue = secmod_argDecodeNumber(value);
00409     if (value) PORT_Free(value);
00410 
00411     return retValue;
00412 }
00413 
00414 
00415 static unsigned long
00416 secmod_argSlotFlags(char *label,char *params)
00417 {
00418     char *flags,*index;
00419     unsigned long retValue = 0;
00420     int i;
00421     PRBool all = PR_FALSE;
00422 
00423     flags = secmod_argGetParamValue(label,params);
00424     if (flags == NULL) return 0;
00425 
00426     if (PORT_Strcasecmp(flags,"all") == 0) all = PR_TRUE;
00427 
00428     for (index=flags; *index; index=secmod_argNextFlag(index)) {
00429        for (i=0; i < secmod_argSlotFlagTableSize; i++) {
00430            if (all || (PORT_Strncasecmp(index, secmod_argSlotFlagTable[i].name,
00431                             secmod_argSlotFlagTable[i].len) == 0)) {
00432               retValue |= secmod_argSlotFlagTable[i].value;
00433            }
00434        }
00435     }
00436     PORT_Free(flags);
00437     return retValue;
00438 }
00439 
00440 
00441 static void
00442 secmod_argDecodeSingleSlotInfo(char *name, char *params, 
00443                                PK11PreSlotInfo *slotInfo)
00444 {
00445     char *askpw;
00446 
00447     slotInfo->slotID=secmod_argDecodeNumber(name);
00448     slotInfo->defaultFlags=secmod_argSlotFlags("slotFlags",params);
00449     slotInfo->timeout=secmod_argReadLong("timeout",params, 0, NULL);
00450 
00451     askpw = secmod_argGetParamValue("askpw",params);
00452     slotInfo->askpw = 0;
00453 
00454     if (askpw) {
00455        if (PORT_Strcasecmp(askpw,"every") == 0) {
00456            slotInfo->askpw = -1;
00457        } else if (PORT_Strcasecmp(askpw,"timeout") == 0) {
00458            slotInfo->askpw = 1;
00459        } 
00460        PORT_Free(askpw);
00461        slotInfo->defaultFlags |= PK11_OWN_PW_DEFAULTS;
00462     }
00463     slotInfo->hasRootCerts = secmod_argHasFlag("rootFlags", "hasRootCerts", 
00464                                                params);
00465     slotInfo->hasRootTrust = secmod_argHasFlag("rootFlags", "hasRootTrust", 
00466                                                params);
00467 }
00468 
00469 static char *
00470 secmod_argGetName(char *inString, int *next) 
00471 {
00472     char *name=NULL;
00473     char *string;
00474     int len;
00475 
00476     /* look for the end of the <name>= */
00477     for (string = inString;*string; string++) {
00478        if (*string == '=') { break; }
00479        if (secmod_argIsBlank(*string)) break;
00480     }
00481 
00482     len = string - inString;
00483 
00484     *next = len; 
00485     if (*string == '=') (*next) += 1;
00486     if (len > 0) {
00487        name = PORT_Alloc(len+1);
00488        PORT_Strncpy(name,inString,len);
00489        name[len] = 0;
00490     }
00491     return name;
00492 }
00493 
00494 static PK11PreSlotInfo *
00495 secmod_argParseSlotInfo(PRArenaPool *arena, char *slotParams, int *retCount)
00496 {
00497     char *slotIndex;
00498     PK11PreSlotInfo *slotInfo = NULL;
00499     int i=0,count = 0,next;
00500 
00501     *retCount = 0;
00502     if ((slotParams == NULL) || (*slotParams == 0))  return NULL;
00503 
00504     /* first count the number of slots */
00505     for (slotIndex = secmod_argStrip(slotParams); *slotIndex; 
00506         slotIndex = secmod_argStrip(secmod_argSkipParameter(slotIndex))) {
00507        count++;
00508     }
00509 
00510     /* get the data structures */
00511     if (arena) {
00512        slotInfo = (PK11PreSlotInfo *) 
00513                      PORT_ArenaAlloc(arena,count*sizeof(PK11PreSlotInfo));
00514        PORT_Memset(slotInfo,0,count*sizeof(PK11PreSlotInfo));
00515     } else {
00516        slotInfo = (PK11PreSlotInfo *) 
00517                      PORT_ZAlloc(count*sizeof(PK11PreSlotInfo));
00518     }
00519     if (slotInfo == NULL) return NULL;
00520 
00521     for (slotIndex = secmod_argStrip(slotParams), i = 0; 
00522                                    *slotIndex && i < count ; ) {
00523        char *name;
00524        name = secmod_argGetName(slotIndex,&next);
00525        slotIndex += next;
00526 
00527        if (!secmod_argIsBlank(*slotIndex)) {
00528            char *args = secmod_argFetchValue(slotIndex,&next);
00529            slotIndex += next;
00530            if (args) {
00531               secmod_argDecodeSingleSlotInfo(name,args,&slotInfo[i]);
00532               i++;
00533               PORT_Free(args);
00534            }
00535        }
00536        if (name) PORT_Free(name);
00537        slotIndex = secmod_argStrip(slotIndex);
00538     }
00539     *retCount = i;
00540     return slotInfo;
00541 }
00542 
00543 static char *secmod_nullString = "";
00544 
00545 static char *
00546 secmod_formatValue(PRArenaPool *arena, char *value, char quote)
00547 {
00548     char *vp,*vp2,*retval;
00549     int size = 0, escapes = 0;
00550 
00551     for (vp=value; *vp ;vp++) {
00552        if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) escapes++;
00553        size++;
00554     }
00555     if (arena) {
00556        retval = PORT_ArenaZAlloc(arena,size+escapes+1);
00557     } else {
00558        retval = PORT_ZAlloc(size+escapes+1);
00559     }
00560     if (retval == NULL) return NULL;
00561     vp2 = retval;
00562     for (vp=value; *vp; vp++) {
00563        if ((*vp == quote) || (*vp == SECMOD_ARG_ESCAPE)) 
00564                             *vp2++ = SECMOD_ARG_ESCAPE;
00565        *vp2++ = *vp;
00566     }
00567     return retval;
00568 }
00569     
00570 static char *secmod_formatPair(char *name,char *value, char quote)
00571 {
00572     char openQuote = quote;
00573     char closeQuote = secmod_argGetPair(quote);
00574     char *newValue = NULL;
00575     char *returnValue;
00576     PRBool need_quote = PR_FALSE;
00577 
00578     if (!value || (*value == 0)) return secmod_nullString;
00579 
00580     if (secmod_argHasBlanks(value) || secmod_argIsQuote(value[0]))
00581                                                   need_quote=PR_TRUE;
00582 
00583     if ((need_quote && secmod_argHasChar(value,closeQuote))
00584                              || secmod_argHasChar(value,SECMOD_ARG_ESCAPE)) {
00585        value = newValue = secmod_formatValue(NULL, value,quote);
00586        if (newValue == NULL) return secmod_nullString;
00587     }
00588     if (need_quote) {
00589        returnValue = PR_smprintf("%s=%c%s%c",name,openQuote,value,closeQuote);
00590     } else {
00591        returnValue = PR_smprintf("%s=%s",name,value);
00592     }
00593     if (returnValue == NULL) returnValue = secmod_nullString;
00594 
00595     if (newValue) PORT_Free(newValue);
00596 
00597     return returnValue;
00598 }
00599 
00600 static char *secmod_formatIntPair(char *name, unsigned long value, 
00601                                   unsigned long def)
00602 {
00603     char *returnValue;
00604 
00605     if (value == def) return secmod_nullString;
00606 
00607     returnValue = PR_smprintf("%s=%d",name,value);
00608 
00609     return returnValue;
00610 }
00611 
00612 static void
00613 secmod_freePair(char *pair)
00614 {
00615     if (pair && pair != secmod_nullString) {
00616        PR_smprintf_free(pair);
00617     }
00618 }
00619 
00620 #define MAX_FLAG_SIZE  sizeof("internal")+sizeof("FIPS")+sizeof("moduleDB")+\
00621                             sizeof("moduleDBOnly")+sizeof("critical")
00622 static char *
00623 secmod_mkNSSFlags(PRBool internal, PRBool isFIPS,
00624               PRBool isModuleDB, PRBool isModuleDBOnly, PRBool isCritical)
00625 {
00626     char *flags = (char *)PORT_ZAlloc(MAX_FLAG_SIZE);
00627     PRBool first = PR_TRUE;
00628 
00629     PORT_Memset(flags,0,MAX_FLAG_SIZE);
00630     if (internal) {
00631        PORT_Strcat(flags,"internal");
00632        first = PR_FALSE;
00633     }
00634     if (isFIPS) {
00635        if (!first) PORT_Strcat(flags,",");
00636        PORT_Strcat(flags,"FIPS");
00637        first = PR_FALSE;
00638     }
00639     if (isModuleDB) {
00640        if (!first) PORT_Strcat(flags,",");
00641        PORT_Strcat(flags,"moduleDB");
00642        first = PR_FALSE;
00643     }
00644     if (isModuleDBOnly) {
00645        if (!first) PORT_Strcat(flags,",");
00646        PORT_Strcat(flags,"moduleDBOnly");
00647        first = PR_FALSE;
00648     }
00649     if (isCritical) {
00650        if (!first) PORT_Strcat(flags,",");
00651        PORT_Strcat(flags,"critical");
00652        first = PR_FALSE;
00653     }
00654     return flags;
00655 }
00656 
00657 static char *
00658 secmod_mkCipherFlags(unsigned long ssl0, unsigned long ssl1)
00659 {
00660     char *cipher = NULL;
00661     int i;
00662 
00663     for (i=0; i < sizeof(ssl0)*8; i++) {
00664        if (ssl0 & (1<<i)) {
00665            char *string;
00666            if ((1<<i) == SECMOD_FORTEZZA_FLAG) {
00667               string = PR_smprintf("%s","FORTEZZA");
00668            } else {
00669               string = PR_smprintf("0h0x%08x",1<<i);
00670            }
00671            if (cipher) {
00672               char *tmp;
00673               tmp = PR_smprintf("%s,%s",cipher,string);
00674               PR_smprintf_free(cipher);
00675               PR_smprintf_free(string);
00676               cipher = tmp;
00677            } else {
00678               cipher = string;
00679            }
00680        }
00681     }
00682     for (i=0; i < sizeof(ssl0)*8; i++) {
00683        if (ssl1 & (1<<i)) {
00684            if (cipher) {
00685               char *tmp;
00686               tmp = PR_smprintf("%s,0l0x%08x",cipher,1<<i);
00687               PR_smprintf_free(cipher);
00688               cipher = tmp;
00689            } else {
00690               cipher = PR_smprintf("0l0x%08x",1<<i);
00691            }
00692        }
00693     }
00694 
00695     return cipher;
00696 }
00697 
00698 static char *
00699 secmod_mkSlotFlags(unsigned long defaultFlags)
00700 {
00701     char *flags=NULL;
00702     int i,j;
00703 
00704     for (i=0; i < sizeof(defaultFlags)*8; i++) {
00705        if (defaultFlags & (1<<i)) {
00706            char *string = NULL;
00707 
00708            for (j=0; j < secmod_argSlotFlagTableSize; j++) {
00709               if (secmod_argSlotFlagTable[j].value == ( 1UL << i )) {
00710                   string = secmod_argSlotFlagTable[j].name;
00711                   break;
00712               }
00713            }
00714            if (string) {
00715               if (flags) {
00716                   char *tmp;
00717                   tmp = PR_smprintf("%s,%s",flags,string);
00718                   PR_smprintf_free(flags);
00719                   flags = tmp;
00720               } else {
00721                   flags = PR_smprintf("%s",string);
00722               }
00723            }
00724        }
00725     }
00726 
00727     return flags;
00728 }
00729 
00730 #define SECMOD_MAX_ROOT_FLAG_SIZE  sizeof("hasRootCerts")+sizeof("hasRootTrust")
00731 
00732 static char *
00733 secmod_mkRootFlags(PRBool hasRootCerts, PRBool hasRootTrust)
00734 {
00735     char *flags= (char *)PORT_ZAlloc(SECMOD_MAX_ROOT_FLAG_SIZE);
00736     PRBool first = PR_TRUE;
00737 
00738     PORT_Memset(flags,0,SECMOD_MAX_ROOT_FLAG_SIZE);
00739     if (hasRootCerts) {
00740        PORT_Strcat(flags,"hasRootCerts");
00741        first = PR_FALSE;
00742     }
00743     if (hasRootTrust) {
00744        if (!first) PORT_Strcat(flags,",");
00745        PORT_Strcat(flags,"hasRootTrust");
00746        first = PR_FALSE;
00747     }
00748     return flags;
00749 }
00750 
00751 static char *
00752 secmod_mkSlotString(unsigned long slotID, unsigned long defaultFlags,
00753                 unsigned long timeout, unsigned char askpw_in,
00754                 PRBool hasRootCerts, PRBool hasRootTrust) {
00755     char *askpw,*flags,*rootFlags,*slotString;
00756     char *flagPair,*rootFlagsPair;
00757        
00758     switch (askpw_in) {
00759     case 0xff:
00760        askpw = "every";
00761        break;
00762     case 1:
00763        askpw = "timeout";
00764        break;
00765     default:
00766        askpw = "any";
00767        break;
00768     }
00769     flags = secmod_mkSlotFlags(defaultFlags);
00770     rootFlags = secmod_mkRootFlags(hasRootCerts,hasRootTrust);
00771     flagPair=secmod_formatPair("slotFlags",flags,'\'');
00772     rootFlagsPair=secmod_formatPair("rootFlags",rootFlags,'\'');
00773     if (flags) PR_smprintf_free(flags);
00774     if (rootFlags) PORT_Free(rootFlags);
00775     if (defaultFlags & PK11_OWN_PW_DEFAULTS) {
00776        slotString = PR_smprintf("0x%08lx=[%s askpw=%s timeout=%d %s]",
00777                             (PRUint32)slotID,flagPair,askpw,timeout,
00778                             rootFlagsPair);
00779     } else {
00780        slotString = PR_smprintf("0x%08lx=[%s %s]",
00781                             (PRUint32)slotID,flagPair,rootFlagsPair);
00782     }
00783     secmod_freePair(flagPair);
00784     secmod_freePair(rootFlagsPair);
00785     return slotString;
00786 }
00787 
00788 static char *
00789 secmod_mkNSS(char **slotStrings, int slotCount, PRBool internal, PRBool isFIPS,
00790          PRBool isModuleDB,  PRBool isModuleDBOnly, PRBool isCritical, 
00791          unsigned long trustOrder, unsigned long cipherOrder,
00792                             unsigned long ssl0, unsigned long ssl1) {
00793     int slotLen, i;
00794     char *slotParams, *ciphers, *nss, *nssFlags, *tmp;
00795     char *trustOrderPair,*cipherOrderPair,*slotPair,*cipherPair,*flagPair;
00796 
00797 
00798     /* now let's build up the string
00799      * first the slot infos
00800      */
00801     slotLen=0;
00802     for (i=0; i < (int)slotCount; i++) {
00803        slotLen += PORT_Strlen(slotStrings[i])+1;
00804     }
00805     slotLen += 1; /* space for the final NULL */
00806 
00807     slotParams = (char *)PORT_ZAlloc(slotLen);
00808     PORT_Memset(slotParams,0,slotLen);
00809     for (i=0; i < (int)slotCount; i++) {
00810        PORT_Strcat(slotParams,slotStrings[i]);
00811        PORT_Strcat(slotParams," ");
00812        PR_smprintf_free(slotStrings[i]);
00813        slotStrings[i]=NULL;
00814     }
00815     
00816     /*
00817      * now the NSS structure
00818      */
00819     nssFlags = secmod_mkNSSFlags(internal,isFIPS,isModuleDB,isModuleDBOnly,
00820                                                  isCritical); 
00821        /* for now only the internal module is critical */
00822     ciphers = secmod_mkCipherFlags(ssl0, ssl1);
00823 
00824     trustOrderPair=secmod_formatIntPair("trustOrder",trustOrder,
00825                                    SECMOD_DEFAULT_TRUST_ORDER);
00826     cipherOrderPair=secmod_formatIntPair("cipherOrder",cipherOrder,
00827                                    SECMOD_DEFAULT_CIPHER_ORDER);
00828     slotPair=secmod_formatPair("slotParams",slotParams,'{'); /* } */
00829     if (slotParams) PORT_Free(slotParams);
00830     cipherPair=secmod_formatPair("ciphers",ciphers,'\'');
00831     if (ciphers) PR_smprintf_free(ciphers);
00832     flagPair=secmod_formatPair("Flags",nssFlags,'\'');
00833     if (nssFlags) PORT_Free(nssFlags);
00834     nss = PR_smprintf("%s %s %s %s %s",trustOrderPair,
00835                      cipherOrderPair,slotPair,cipherPair,flagPair);
00836     secmod_freePair(trustOrderPair);
00837     secmod_freePair(cipherOrderPair);
00838     secmod_freePair(slotPair);
00839     secmod_freePair(cipherPair);
00840     secmod_freePair(flagPair);
00841     tmp = secmod_argStrip(nss);
00842     if (*tmp == '\0') {
00843        PR_smprintf_free(nss);
00844        nss = NULL;
00845     }
00846     return nss;
00847 }
00848 
00849 static char *
00850 secmod_mkNewModuleSpec(char *dllName, char *commonName, char *parameters, 
00851                                                         char *NSS) {
00852     char *moduleSpec;
00853     char *lib,*name,*param,*nss;
00854 
00855     /*
00856      * now the final spec
00857      */
00858     lib = secmod_formatPair("library",dllName,'\"');
00859     name = secmod_formatPair("name",commonName,'\"');
00860     param = secmod_formatPair("parameters",parameters,'\"');
00861     nss = secmod_formatPair("NSS",NSS,'\"');
00862     moduleSpec = PR_smprintf("%s %s %s %s", lib,name,param,nss);
00863     secmod_freePair(lib);
00864     secmod_freePair(name);
00865     secmod_freePair(param);
00866     secmod_freePair(nss);
00867     return (moduleSpec);
00868 }
00869