security/nss/cmd/modutil/pk11.c

Wed, 31 Dec 2014 06:55:50 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:55:50 +0100
changeset 2
7e26c7da4463
permissions
-rw-r--r--

Added tag UPSTREAM_283F7C6 for changeset ca08bd8f51b2

     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/. */
     5 /* To edit this file, set TABSTOPS to 4 spaces.
     6  * This is not the normal NSS convention.
     7  */
     9 #include "modutil.h"
    10 #include "pk11func.h"
    12 /*************************************************************************
    13  *
    14  * F i p s M o d e
    15  * If arg=="true", enable FIPS mode on the internal module.  If arg=="false",
    16  * disable FIPS mode on the internal module.
    17  */
    18 Error
    19 FipsMode(char *arg)
    20 {
    21     char *internal_name;
    23     if(!PORT_Strcasecmp(arg, "true")) {
    24 	if(!PK11_IsFIPS()) {
    25 	    internal_name = PR_smprintf("%s",
    26 		SECMOD_GetInternalModule()->commonName);
    27 	    if(SECMOD_DeleteInternalModule(internal_name) != SECSuccess) {
    28 		PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError()));
    29 		PR_smprintf_free(internal_name);
    30 		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    31 		return FIPS_SWITCH_FAILED_ERR;
    32 	    }
    33 	    PR_smprintf_free(internal_name);
    34 	    if (!PK11_IsFIPS()) {
    35 		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    36 		return FIPS_SWITCH_FAILED_ERR;
    37 	    }
    38 	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
    39 	} else {
    40 	    PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_ON_ERR]);
    41 	    return FIPS_ALREADY_ON_ERR;
    42 	}
    43     } else if(!PORT_Strcasecmp(arg, "false")) {
    44 	if(PK11_IsFIPS()) {
    45 	    internal_name = PR_smprintf("%s",
    46 		SECMOD_GetInternalModule()->commonName);
    47 	    if(SECMOD_DeleteInternalModule(internal_name) != SECSuccess) {
    48 		PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError()));
    49 		PR_smprintf_free(internal_name);
    50 		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    51 		return FIPS_SWITCH_FAILED_ERR;
    52 	    }
    53 	    PR_smprintf_free(internal_name);
    54 	    if (PK11_IsFIPS()) {
    55 		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    56 		return FIPS_SWITCH_FAILED_ERR;
    57 	    }
    58 	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
    59 	} else {
    60 	    PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_OFF_ERR]);
    61 	    return FIPS_ALREADY_OFF_ERR;
    62 	}
    63     } else {
    64 	PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
    65 	return INVALID_FIPS_ARG;
    66     }
    68     return SUCCESS;
    69 }
    71 /*************************************************************************
    72  *
    73  * C h k F i p s M o d e
    74  * If arg=="true", verify FIPS mode is enabled on the internal module.  
    75  * If arg=="false", verify FIPS mode is disabled on the internal module.
    76  */
    77 Error
    78 ChkFipsMode(char *arg)
    79 {
    80     if(!PORT_Strcasecmp(arg, "true")) {
    81 	if (PK11_IsFIPS()) {
    82 	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
    83 	} else {
    84 	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
    85 	    return FIPS_SWITCH_FAILED_ERR;
    86 	}
    88     } else if(!PORT_Strcasecmp(arg, "false")) {
    89 	if(!PK11_IsFIPS()) {
    90 	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
    91 	} else {
    92 	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
    93 	    return FIPS_SWITCH_FAILED_ERR;
    94 	}
    95     } else {
    96 	PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
    97 	return INVALID_FIPS_ARG;
    98     }
   100     return SUCCESS;
   101 }
   103 /************************************************************************
   104  * Cipher and Mechanism name-bitmask translation tables
   105  */
   107 typedef struct {
   108     const char *name;
   109     unsigned long mask;
   110 } MaskString;
   113 static const MaskString cipherStrings[] = {
   114     {"FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG}
   115 };
   116 static const int numCipherStrings =
   117     sizeof(cipherStrings) / sizeof(cipherStrings[0]);
   119 /* Initialized by LoadMechanismList */
   120 static MaskString *mechanismStrings =  NULL;
   121 static int numMechanismStrings = 0;
   122 const static PK11DefaultArrayEntry *pk11_DefaultArray = NULL;
   123 static int pk11_DefaultArraySize = 0;
   125 /* Maximum length of a colon-separated list of all the strings in an
   126  * array. */
   127 #define MAX_STRING_LIST_LEN 240    /* or less */
   130 Error
   131 LoadMechanismList(void)
   132 {
   133     int i;
   135     if (pk11_DefaultArray == NULL) {
   136         pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
   137         if (pk11_DefaultArray == NULL) {
   138             /* should assert. This shouldn't happen */
   139             return UNSPECIFIED_ERR;
   140         }
   141     }
   142     if (mechanismStrings != NULL) {
   143 	return SUCCESS;
   144     }
   146     /* build the mechanismStrings array */
   147     mechanismStrings = PORT_NewArray(MaskString, pk11_DefaultArraySize);
   148     if (mechanismStrings == NULL) {
   149 	return OUT_OF_MEM_ERR;
   150     }
   151     numMechanismStrings = pk11_DefaultArraySize;
   152     for (i = 0; i < numMechanismStrings; i++) {
   153 	const char *name = pk11_DefaultArray[i].name;
   154 	unsigned long flag = pk11_DefaultArray[i].flag;
   155 	/* map new name to old */
   156 	switch (flag) {
   157 	case SECMOD_FORTEZZA_FLAG:
   158 	    name = "FORTEZZA";
   159 	    break;
   160 	case SECMOD_SHA1_FLAG:
   161 	    name = "SHA1";
   162 	    break;
   163 	case SECMOD_CAMELLIA_FLAG:
   164 	    name = "CAMELLIA";
   165 	    break;
   166 	case SECMOD_RANDOM_FLAG:
   167 	    name = "RANDOM";
   168 	    break;
   169 	case SECMOD_FRIENDLY_FLAG:
   170 	    name = "FRIENDLY";
   171 	    break;
   172 	default:
   173 	    break;
   174 	}
   175 	mechanismStrings[i].name = name;
   176 	mechanismStrings[i].mask = SECMOD_InternaltoPubMechFlags(flag);
   177     }
   178     return SUCCESS;
   179 }
   181 /************************************************************************
   182  * 
   183  * g e t F l a g s F r o m S t r i n g
   184  *
   185  * Parses a mechanism list passed on the command line and converts it
   186  * to an unsigned long bitmask.
   187  * string is a colon-separated string of constants
   188  * array is an array of MaskStrings.
   189  * elements is the number of elements in array.
   190  */
   191 static unsigned long
   192 getFlagsFromString(char *string, const MaskString array[], int elements)
   193 {
   194     unsigned long ret = 0;
   195     short i = 0;
   196     char *cp;
   197     char *buf;
   198     char *end;
   200     if(!string || !string[0]) {
   201 	return ret;
   202     }
   204     /* Make a temporary copy of the string */
   205     buf = PR_Malloc(strlen(string)+1);
   206     if(!buf) {
   207 	out_of_memory();
   208     }
   209     strcpy(buf, string);
   211     /* Look at each element of the list passed in */
   212     for(cp=buf; cp && *cp; cp = (end ? end+1 : NULL) ) {
   213 	/* Look at the string up to the next colon */
   214 	end = strchr(cp, ':');
   215 	if(end) {
   216 	    *end = '\0';
   217 	}
   219 	/* Find which element this is */
   220 	for(i=0; i < elements; i++) {
   221 	    if( !PORT_Strcasecmp(cp, array[i].name) ) {
   222 		break;
   223 	    }
   224 	}
   225 	if(i == elements) {
   226 	    /* Skip a bogus string, but print a warning message */
   227 	    PR_fprintf(PR_STDERR, errStrings[INVALID_CONSTANT_ERR], cp);
   228 	    continue;
   229 	}
   230 	ret |= array[i].mask;
   231     }
   233     PR_Free(buf);
   234     return ret;
   235 }
   237 /**********************************************************************
   238  *
   239  * g e t S t r i n g F r o m F l a g s
   240  * 
   241  * The return string's memory is owned by this function.  Copy it
   242  * if you need it permanently or you want to change it.
   243  */
   244 static char *
   245 getStringFromFlags(unsigned long flags, const MaskString array[], int elements)
   246 {
   247     static char buf[MAX_STRING_LIST_LEN];
   248     int i;
   249     int count=0;
   251     buf[0] = '\0';
   252     for(i=0; i<elements; i++) {
   253 	if( flags & array[i].mask ) {
   254 	    ++count;
   255 	    if(count!=1) {
   256 		strcat(buf, ":");
   257 	    }
   258 	    strcat(buf, array[i].name);
   259 	}
   260     }
   261     return buf;
   262 }
   264 /**********************************************************************
   265  *
   266  * A d d M o d u l e
   267  *
   268  * Add the named module, with the given library file, ciphers, and
   269  * default mechanism flags
   270  */
   271 Error
   272 AddModule(char *moduleName, char *libFile, char *cipherString,
   273     char *mechanismString, char* modparms)
   274 {
   275     unsigned long ciphers;
   276     unsigned long mechanisms;
   277     SECStatus status;
   279     mechanisms =
   280 	getFlagsFromString(mechanismString, mechanismStrings,
   281 			   numMechanismStrings);
   282     ciphers =
   283 	getFlagsFromString(cipherString, cipherStrings, numCipherStrings);
   285     status =
   286 	SECMOD_AddNewModuleEx(moduleName, libFile,
   287 		  SECMOD_PubMechFlagstoInternal(mechanisms),
   288 		  SECMOD_PubCipherFlagstoInternal(ciphers),
   289 		  modparms, NULL );
   291     if(status != SECSuccess) {
   292 	char* errtxt=NULL;
   293 	PRInt32 copied = 0;
   294 	if (PR_GetErrorTextLength()) {
   295 	    errtxt = PR_Malloc(PR_GetErrorTextLength() + 1);
   296 	    copied = PR_GetErrorText(errtxt);
   297 	}
   298 	if (copied && errtxt) {
   299 	    PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR], 
   300 		       moduleName, errtxt);
   301 	    PR_Free(errtxt);
   302 	} else {
   303 	    PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR], 
   304 		       moduleName, SECU_Strerror(PORT_GetError()));
   305 	}
   306 	return ADD_MODULE_FAILED_ERR;
   307     } else {
   308 	PR_fprintf(PR_STDOUT, msgStrings[ADD_MODULE_SUCCESS_MSG], moduleName);
   309 	return SUCCESS;
   310     }
   311 }
   313 /***********************************************************************
   314  *
   315  * D e l e t e M o d u l e
   316  *
   317  * Deletes the named module from the database.
   318  */
   319 Error
   320 DeleteModule(char *moduleName)
   321 {
   322     SECStatus status;
   323     int type;
   325     status = SECMOD_DeleteModule(moduleName, &type);
   327     if(status != SECSuccess) {
   328 	if(type == SECMOD_FIPS || type == SECMOD_INTERNAL) {
   329 	    PR_fprintf(PR_STDERR, errStrings[DELETE_INTERNAL_ERR]);
   330 	    return DELETE_INTERNAL_ERR;
   331 	} else {
   332 	    PR_fprintf(PR_STDERR, errStrings[DELETE_FAILED_ERR], moduleName);
   333 	    return DELETE_FAILED_ERR;
   334 	}
   335     }
   337     PR_fprintf(PR_STDOUT, msgStrings[DELETE_SUCCESS_MSG], moduleName);
   338     return SUCCESS;
   339 }
   341 /************************************************************************
   342  *
   343  * R a w L i s t M o d u l e s
   344  *
   345  * Lists all the modules in the database, along with their slots and tokens.
   346  */
   347 Error
   348 RawListModule(char *modulespec)
   349 {
   350     SECMODModule *module;
   351     char **moduleSpecList;
   353     module = SECMOD_LoadModule(modulespec,NULL,PR_FALSE);
   354     if (module == NULL) {
   355 	/* handle error */
   356 	return NO_SUCH_MODULE_ERR;
   357     }
   359     moduleSpecList = SECMOD_GetModuleSpecList(module);
   360     if (!moduleSpecList || !moduleSpecList[0]) {
   361 	SECU_PrintError("modutil",
   362 			    "no specs in secmod DB");
   363 	return NO_SUCH_MODULE_ERR;
   364     }
   366     for ( ;*moduleSpecList; moduleSpecList++) {
   367 	printf("%s\n\n",*moduleSpecList);
   368     }
   370     return SUCCESS;
   371 }
   373 Error
   374 RawAddModule(char *dbmodulespec, char *modulespec)
   375 {
   376     SECMODModule *module;
   377     SECMODModule *dbmodule;
   380     dbmodule = SECMOD_LoadModule(dbmodulespec,NULL,PR_TRUE);
   381     if (dbmodule == NULL) {
   382 	/* handle error */
   383 	return NO_SUCH_MODULE_ERR;
   384     }
   386     module = SECMOD_LoadModule(modulespec,dbmodule,PR_FALSE);
   387     if (module == NULL) {
   388 	/* handle error */
   389 	return NO_SUCH_MODULE_ERR;
   390     }
   392     if( SECMOD_UpdateModule(module) != SECSuccess ) {
   393 	PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec);
   394 	return UPDATE_MOD_FAILED_ERR;
   395     }
   396     return SUCCESS;
   397 }
   399 static void
   400 printModule(SECMODModule *module, int *count) 
   401 {
   402     int slotCount = module->loaded ? module->slotCount : 0;
   403     int i;
   405     if ((*count)++) {
   406         PR_fprintf(PR_STDOUT,"\n");
   407     }
   408         PR_fprintf(PR_STDOUT, "%3d. %s\n", *count, module->commonName);
   410     if (module->dllName) {
   411         PR_fprintf(PR_STDOUT, "\tlibrary name: %s\n", module->dllName);
   412     }
   414     if (slotCount == 0) {
   415         PR_fprintf(PR_STDOUT,
   416 	"\t slots: There are no slots attached to this module\n");
   417     } else {
   418         PR_fprintf(PR_STDOUT, "\t slots: %d slot%s attached\n",
   419 		slotCount, (slotCount==1 ? "" : "s") );
   420     }
   422     if (module->loaded == 0) {
   423         PR_fprintf(PR_STDOUT, "\tstatus: Not loaded\n");
   424     } else {
   425         PR_fprintf(PR_STDOUT, "\tstatus: loaded\n");
   426     }
   428     /* Print slot and token names */
   429     for (i = 0; i < slotCount; i++) {
   430         PK11SlotInfo *slot = module->slots[i];
   432         PR_fprintf(PR_STDOUT, "\n");
   433         PR_fprintf(PR_STDOUT, "\t slot: %s\n", PK11_GetSlotName(slot));
   434         PR_fprintf(PR_STDOUT, "\ttoken: %s\n", PK11_GetTokenName(slot));
   435     }
   436     return;
   437 }
   439 /************************************************************************
   440  *
   441  * L i s t M o d u l e s
   442  *
   443  * Lists all the modules in the database, along with their slots and tokens.
   444  */
   445 Error
   446 ListModules()
   447 {
   448     SECMODListLock *lock;
   449     SECMODModuleList *list;
   450     SECMODModuleList *deadlist;
   451     SECMODModuleList *mlp;
   452     Error ret=UNSPECIFIED_ERR;
   453     int count = 0;
   455     lock = SECMOD_GetDefaultModuleListLock();
   456     if(!lock) {
   457 	PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]);
   458 	return NO_LIST_LOCK_ERR;
   459     }
   461     SECMOD_GetReadLock(lock);
   463     list = SECMOD_GetDefaultModuleList();
   464     deadlist = SECMOD_GetDeadModuleList();
   465     if (!list && !deadlist) {
   466 	PR_fprintf(PR_STDERR, errStrings[NO_MODULE_LIST_ERR]);
   467 	ret = NO_MODULE_LIST_ERR;
   468 	goto loser;
   469     }
   471     PR_fprintf(PR_STDOUT,
   472 	"\nListing of PKCS #11 Modules\n"
   473 	"-----------------------------------------------------------\n");
   475     for(mlp=list; mlp != NULL; mlp = mlp->next) {
   476 	printModule(mlp->module, &count);
   477     }
   478     for (mlp=deadlist; mlp != NULL; mlp = mlp->next) {
   479 	printModule(mlp->module, &count);
   480     }
   483     PR_fprintf(PR_STDOUT,
   484 	"-----------------------------------------------------------\n");
   486     ret = SUCCESS;
   488 loser:
   489     SECMOD_ReleaseReadLock(lock);
   490     return ret;
   491 }
   493 /* Strings describing PK11DisableReasons */
   494 static char *disableReasonStr[] = {
   495     "no reason",
   496     "user disabled",
   497     "could not initialize token",
   498     "could not verify token",
   499     "token not present"
   500 };
   501 static int numDisableReasonStr =
   502     sizeof(disableReasonStr) / sizeof(disableReasonStr[0]);
   504 /***********************************************************************
   505  *
   506  * L i s t M o d u l e
   507  *
   508  * Lists detailed information about the named module.
   509  */
   510 Error
   511 ListModule(char *moduleName)
   512 {
   513     SECMODModule *module = NULL;
   514     PK11SlotInfo *slot;
   515     int slotnum;
   516     CK_INFO modinfo;
   517     CK_SLOT_INFO slotinfo;
   518     CK_TOKEN_INFO tokeninfo;
   519     char *ciphers, *mechanisms;
   520     PK11DisableReasons reason;
   521     Error  rv = SUCCESS;
   523     if(!moduleName) {
   524 	return SUCCESS;
   525     }
   527     module = SECMOD_FindModule(moduleName);
   528     if(!module) {
   529 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   530 	rv = NO_SUCH_MODULE_ERR;
   531         goto loser;
   532     }
   534     if ((module->loaded) && 
   535 			(PK11_GetModInfo(module, &modinfo) != SECSuccess)) {
   536 	PR_fprintf(PR_STDERR, errStrings[MOD_INFO_ERR], moduleName);
   537 	rv = MOD_INFO_ERR;
   538         goto loser;
   539     }
   541     /* Module info */
   542     PR_fprintf(PR_STDOUT, 
   543 	"\n-----------------------------------------------------------\n");
   544     PR_fprintf(PR_STDOUT, "Name: %s\n", module->commonName);
   545     if(module->internal || !module->dllName) {
   546 	PR_fprintf(PR_STDOUT, "Library file: **Internal ONLY module**\n");
   547     } else {
   548 	PR_fprintf(PR_STDOUT, "Library file: %s\n", module->dllName);
   549     }
   551     if (module->loaded) {
   552 	PR_fprintf(PR_STDOUT, "Manufacturer: %.32s\n", modinfo.manufacturerID);
   553 	PR_fprintf(PR_STDOUT, "Description: %.32s\n", modinfo.libraryDescription);
   554 	PR_fprintf(PR_STDOUT, "PKCS #11 Version %d.%d\n",
   555 	modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor);
   556 	PR_fprintf(PR_STDOUT, "Library Version: %d.%d\n",
   557 	modinfo.libraryVersion.major, modinfo.libraryVersion.minor);
   558     } else {
   559 	PR_fprintf(PR_STDOUT, "* Module not loaded\n");
   560     }
   561     /* Get cipher and mechanism flags */
   562     ciphers = getStringFromFlags(module->ssl[0], cipherStrings,
   563       numCipherStrings);
   564     if(ciphers[0] == '\0') {
   565 	ciphers = "None";
   566     }
   567     PR_fprintf(PR_STDOUT, "Cipher Enable Flags: %s\n", ciphers);
   568     mechanisms = NULL;
   569     if (module->slotCount > 0) {
   570 	mechanisms = getStringFromFlags(
   571 	    PK11_GetDefaultFlags(module->slots[0]),
   572 	    mechanismStrings, numMechanismStrings);
   573     }
   574     if ((mechanisms==NULL) || (mechanisms[0] =='\0')) {
   575 	mechanisms = "None";
   576     }
   577     PR_fprintf(PR_STDOUT, "Default Mechanism Flags: %s\n", mechanisms);
   579 #define PAD "  "
   581     /* Loop over each slot */
   582     for (slotnum=0; slotnum < module->slotCount; slotnum++) {
   583 	slot = module->slots[slotnum];
   584 	if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) {
   585 	    PR_fprintf(PR_STDERR, errStrings[SLOT_INFO_ERR],
   586 		PK11_GetSlotName(slot));
   587 	    rv = SLOT_INFO_ERR;
   588 	    continue;
   589 	}
   591 	/* Slot Info */
   592 	PR_fprintf(PR_STDOUT, "\n"PAD"Slot: %s\n", PK11_GetSlotName(slot));
   593 	mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot),
   594 	    mechanismStrings, numMechanismStrings);
   595 	if(mechanisms[0] =='\0') {
   596 	     mechanisms = "None";
   597 	}
   598 	PR_fprintf(PR_STDOUT, PAD"Slot Mechanism Flags: %s\n", mechanisms);
   599 	PR_fprintf(PR_STDOUT, PAD"Manufacturer: %.32s\n",
   600 	    slotinfo.manufacturerID);
   601 	if (PK11_IsHW(slot)) {
   602 	    PR_fprintf(PR_STDOUT, PAD"Type: Hardware\n");
   603 	} else {
   604 	    PR_fprintf(PR_STDOUT, PAD"Type: Software\n");
   605 	}
   606 	PR_fprintf(PR_STDOUT, PAD"Version Number: %d.%d\n",
   607 	    slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor);
   608 	PR_fprintf(PR_STDOUT, PAD"Firmware Version: %d.%d\n",
   609 	    slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor);
   610 	if (PK11_IsDisabled(slot)) {
   611 	    reason  = PK11_GetDisabledReason(slot);
   612 	    if(reason < numDisableReasonStr) {
   613 		PR_fprintf(PR_STDOUT, PAD"Status: DISABLED (%s)\n",
   614 		  disableReasonStr[reason]);
   615 	    } else {
   616 		PR_fprintf(PR_STDOUT, PAD"Status: DISABLED\n");
   617 	    }
   618 	} else {
   619 	    PR_fprintf(PR_STDOUT, PAD"Status: Enabled\n");
   620 	}
   622 	if(PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) {
   623 	    PR_fprintf(PR_STDERR, errStrings[TOKEN_INFO_ERR],
   624 	      PK11_GetTokenName(slot));
   625 	    rv = TOKEN_INFO_ERR;
   626 	    continue;
   627 	}
   629 	/* Token Info */
   630 	PR_fprintf(PR_STDOUT, PAD"Token Name: %.32s\n",
   631 	    tokeninfo.label);
   632 	PR_fprintf(PR_STDOUT, PAD"Token Manufacturer: %.32s\n",
   633 	    tokeninfo.manufacturerID);
   634 	PR_fprintf(PR_STDOUT, PAD"Token Model: %.16s\n", tokeninfo.model);
   635 	PR_fprintf(PR_STDOUT, PAD"Token Serial Number: %.16s\n",
   636 	    tokeninfo.serialNumber);
   637 	PR_fprintf(PR_STDOUT, PAD"Token Version: %d.%d\n",
   638 	    tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor);
   639 	PR_fprintf(PR_STDOUT, PAD"Token Firmware Version: %d.%d\n",
   640 	    tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor);
   641 	if(tokeninfo.flags & CKF_WRITE_PROTECTED) {
   642 	    PR_fprintf(PR_STDOUT, PAD"Access: Write Protected\n");
   643 	} else {
   644 	    PR_fprintf(PR_STDOUT, PAD"Access: NOT Write Protected\n");
   645 	}
   646 	if(tokeninfo.flags & CKF_LOGIN_REQUIRED) {
   647 	    PR_fprintf(PR_STDOUT, PAD"Login Type: Login required\n");
   648 	} else {
   649 	    PR_fprintf(PR_STDOUT, PAD
   650 	      "Login Type: Public (no login required)\n");
   651 	}
   652 	if(tokeninfo.flags & CKF_USER_PIN_INITIALIZED) {
   653 	    PR_fprintf(PR_STDOUT, PAD"User Pin: Initialized\n");
   654 	} else {
   655 	    PR_fprintf(PR_STDOUT, PAD"User Pin: NOT Initialized\n");
   656 	}
   657     }
   658     PR_fprintf(PR_STDOUT, 
   659 	"\n-----------------------------------------------------------\n");
   660 loser:
   661     if (module) {
   662         SECMOD_DestroyModule(module);
   663     }
   664     return rv;
   665 }
   667 /************************************************************************
   668  *
   669  * C h a n g e P W
   670  */
   671 Error
   672 ChangePW(char *tokenName, char *pwFile, char *newpwFile)
   673 {
   674     char *oldpw=NULL, *newpw=NULL, *newpw2=NULL;
   675     PK11SlotInfo *slot;
   676     Error ret=UNSPECIFIED_ERR;
   677     PRBool matching;
   679     slot = PK11_FindSlotByName(tokenName);
   680     if(!slot) {
   681 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], tokenName);
   682 	return NO_SUCH_TOKEN_ERR;
   683     }
   685     /* Get old password */
   686     if(! PK11_NeedUserInit(slot)) {
   687 	if(pwFile) {
   688 	    oldpw = SECU_FilePasswd(NULL, PR_FALSE, pwFile);
   689 	    if(PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
   690 		PR_fprintf(PR_STDERR, errStrings[BAD_PW_ERR]);
   691 		ret=BAD_PW_ERR;
   692 		goto loser;
   693 	    }
   694 	} else {
   695 	    for(matching=PR_FALSE; !matching; ) {
   696 		oldpw = SECU_GetPasswordString(NULL, "Enter old password: ");
   697 		if(PK11_CheckUserPassword(slot, oldpw) == SECSuccess) {
   698 		    matching = PR_TRUE;
   699 		} else {
   700 		    PR_fprintf(PR_STDOUT, msgStrings[BAD_PW_MSG]);
   701 		}
   702 	    }
   703 	}
   704     }
   706     /* Get new password */
   707     if(newpwFile) {
   708 	newpw = SECU_FilePasswd(NULL, PR_FALSE, newpwFile);
   709     } else {
   710 	for(matching=PR_FALSE; !matching; ) {
   711 	    newpw = SECU_GetPasswordString(NULL, "Enter new password: ");
   712 	    newpw2 = SECU_GetPasswordString(NULL, "Re-enter new password: ");
   713 	    if(strcmp(newpw, newpw2)) {
   714 		PR_fprintf(PR_STDOUT, msgStrings[PW_MATCH_MSG]);
   715 	    } else {
   716 		matching = PR_TRUE;
   717 	    }
   718 	}
   719     }
   721     /* Change the password */
   722     if(PK11_NeedUserInit(slot)) {
   723 	if(PK11_InitPin(slot, NULL /*ssopw*/, newpw) != SECSuccess) {
   724 	    PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName);
   725 	    ret = CHANGEPW_FAILED_ERR;
   726 	    goto loser;
   727 	}
   728     } else {
   729 	if(PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
   730 	    PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName);
   731 	    ret = CHANGEPW_FAILED_ERR;
   732 	    goto loser;
   733 	}
   734     }
   736     PR_fprintf(PR_STDOUT, msgStrings[CHANGEPW_SUCCESS_MSG], tokenName);
   737     ret = SUCCESS;
   739 loser:
   740     if(oldpw) {
   741 	memset(oldpw, 0, strlen(oldpw));
   742 	PORT_Free(oldpw);
   743     }
   744     if(newpw) {
   745 	memset(newpw, 0, strlen(newpw));
   746 	PORT_Free(newpw);
   747     }
   748     if(newpw2) {
   749 	memset(newpw2, 0, strlen(newpw2));
   750 	PORT_Free(newpw2);
   751     }
   752     PK11_FreeSlot(slot);
   754     return ret;
   755 }
   757 /***********************************************************************
   758  *
   759  * E n a b l e M o d u l e
   760  *
   761  * If enable==PR_TRUE, enables the module or slot.
   762  * If enable==PR_FALSE, disables the module or slot.
   763  * moduleName is the name of the module.
   764  * slotName is the name of the slot.  It is optional.
   765  */
   766 Error
   767 EnableModule(char *moduleName, char *slotName, PRBool enable)
   768 {
   769     int i;
   770     SECMODModule *module = NULL;
   771     PK11SlotInfo *slot = NULL;
   772     PRBool found = PR_FALSE;
   773     Error rv;
   775     module = SECMOD_FindModule(moduleName);
   776     if(!module) {
   777 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   778 	rv = NO_SUCH_MODULE_ERR;
   779         goto loser;
   780     }
   782     for(i=0; i < module->slotCount; i++) {
   783 	slot = module->slots[i];
   784 	if(slotName && strcmp(PK11_GetSlotName(slot), slotName)) {
   785 		/* Not the right slot */
   786 		continue;
   787 	}
   788 	if(enable) {
   789 	    if(! PK11_UserEnableSlot(slot)) {
   790 		PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR],
   791 		    "enable", PK11_GetSlotName(slot));
   792 		rv = ENABLE_FAILED_ERR;
   793                 goto loser;
   794 	    } else {
   795 		found = PR_TRUE;
   796 		PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG],
   797 		    PK11_GetSlotName(slot), "enabled");
   798 	    }
   799 	} else {
   800 	    if(! PK11_UserDisableSlot(slot)) {
   801 		PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR],
   802 		    "disable", PK11_GetSlotName(slot));
   803 		rv = ENABLE_FAILED_ERR;
   804                 goto loser;
   805 	    } else {
   806 		found = PR_TRUE;
   807 		PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG],
   808 		    PK11_GetSlotName(slot), "disabled");
   809 	    }
   810 	}
   811     }
   813     if(slotName && !found) {
   814 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
   815 	rv = NO_SUCH_SLOT_ERR;
   816         goto loser;
   817     }
   819     /* Delete and re-add module to save changes */
   820     if( SECMOD_UpdateModule(module) != SECSuccess ) {
   821 	PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], moduleName);
   822 	rv = UPDATE_MOD_FAILED_ERR;
   823         goto loser;
   824     }
   826     rv = SUCCESS;
   827 loser:
   828     if (module) {
   829         SECMOD_DestroyModule(module);
   830     }
   831     return rv;
   832 }
   834 /*************************************************************************
   835  *
   836  * S e t D e f a u l t M o d u l e
   837  *
   838  */
   839 Error
   840 SetDefaultModule(char *moduleName, char *slotName, char *mechanisms)
   841 {
   842     SECMODModule *module = NULL;
   843     PK11SlotInfo *slot;
   844     int s, i;
   845     unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings,
   846 	numMechanismStrings);
   847     PRBool found = PR_FALSE;
   848     Error errcode = UNSPECIFIED_ERR;
   850     mechFlags =  SECMOD_PubMechFlagstoInternal(mechFlags);
   852     module = SECMOD_FindModule(moduleName);
   853     if(!module) {
   854 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   855 	errcode = NO_SUCH_MODULE_ERR;
   856 	goto loser;
   857     }
   859     /* Go through each slot */
   860     for(s=0; s < module->slotCount; s++) {
   861 	slot = module->slots[s];
   863 	if ((slotName != NULL) &&
   864 	    !((strcmp(PK11_GetSlotName(slot),slotName) == 0) ||
   865 	    (strcmp(PK11_GetTokenName(slot),slotName) == 0)) ) {
   866 	    /* we are only interested in changing the one slot */
   867 	    continue;
   868 	}
   870 	found = PR_TRUE;
   872 	/* Go through each mechanism */
   873 	for(i=0; i < pk11_DefaultArraySize; i++) {
   874 	    if(pk11_DefaultArray[i].flag & mechFlags) {
   875 		/* Enable this default mechanism */
   876 		PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]),
   877 		    PR_TRUE);
   878 	    }
   879 	}
   880     }
   881     if (slotName && !found) {
   882 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
   883 	errcode = NO_SUCH_SLOT_ERR;
   884 	goto loser;
   885     }
   887     /* Delete and re-add module to save changes */
   888     if( SECMOD_UpdateModule(module) != SECSuccess ) {
   889 	PR_fprintf(PR_STDERR, errStrings[DEFAULT_FAILED_ERR],
   890 	  moduleName);
   891 	errcode = DEFAULT_FAILED_ERR;
   892 	goto loser;
   893     }
   895     PR_fprintf(PR_STDOUT, msgStrings[DEFAULT_SUCCESS_MSG]);
   897     errcode = SUCCESS;
   898 loser:
   899     if (module) {
   900         SECMOD_DestroyModule(module);
   901     }
   902     return errcode;
   903 }
   905 /************************************************************************
   906  *
   907  * U n s e t D e f a u l t M o d u l e
   908  */
   909 Error
   910 UnsetDefaultModule(char *moduleName, char *slotName, char *mechanisms)
   911 {
   912     SECMODModule * module = NULL;
   913     PK11SlotInfo *slot;
   914     int s, i;
   915     unsigned long mechFlags = getFlagsFromString(mechanisms,
   916 	mechanismStrings, numMechanismStrings);
   917     PRBool found = PR_FALSE;
   918     Error rv;
   920     mechFlags =  SECMOD_PubMechFlagstoInternal(mechFlags);
   922     module = SECMOD_FindModule(moduleName);
   923     if(!module) {
   924 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   925 	rv = NO_SUCH_MODULE_ERR;
   926         goto loser;
   927     }
   929     for(s=0; s < module->slotCount; s++) {
   930 	slot = module->slots[s];
   931 	if ((slotName != NULL) &&
   932 	    !((strcmp(PK11_GetSlotName(slot),slotName) == 0) ||
   933 	    (strcmp(PK11_GetTokenName(slot),slotName) == 0)) ) {
   934 	    /* we are only interested in changing the one slot */
   935 	    continue;
   936 	}
   937 	for(i=0; i < pk11_DefaultArraySize ; i++) {
   938 	    if(pk11_DefaultArray[i].flag & mechFlags) {
   939 		PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]),
   940 		    PR_FALSE);
   941 	    }
   942 	}
   943     }
   944     if (slotName && !found) {
   945 	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
   946 	rv = NO_SUCH_SLOT_ERR;
   947         goto loser;
   948     }
   950     /* Delete and re-add module to save changes */
   951     if( SECMOD_UpdateModule(module) != SECSuccess ) {
   952 	PR_fprintf(PR_STDERR, errStrings[UNDEFAULT_FAILED_ERR],
   953 	  moduleName);
   954 	rv = UNDEFAULT_FAILED_ERR;
   955         goto loser;
   956     }
   958     PR_fprintf(PR_STDOUT, msgStrings[UNDEFAULT_SUCCESS_MSG]);
   959     rv = SUCCESS;
   960 loser:
   961     if (module) {
   962         SECMOD_DestroyModule(module);
   963     }
   964     return rv;
   965 }

mercurial