security/nss/cmd/modutil/pk11.c

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/security/nss/cmd/modutil/pk11.c	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,965 @@
     1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public
     1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.7 +
     1.8 +/* To edit this file, set TABSTOPS to 4 spaces.
     1.9 + * This is not the normal NSS convention.
    1.10 + */
    1.11 +
    1.12 +#include "modutil.h"
    1.13 +#include "pk11func.h"
    1.14 +
    1.15 +/*************************************************************************
    1.16 + *
    1.17 + * F i p s M o d e
    1.18 + * If arg=="true", enable FIPS mode on the internal module.  If arg=="false",
    1.19 + * disable FIPS mode on the internal module.
    1.20 + */
    1.21 +Error
    1.22 +FipsMode(char *arg)
    1.23 +{
    1.24 +    char *internal_name;
    1.25 +
    1.26 +    if(!PORT_Strcasecmp(arg, "true")) {
    1.27 +	if(!PK11_IsFIPS()) {
    1.28 +	    internal_name = PR_smprintf("%s",
    1.29 +		SECMOD_GetInternalModule()->commonName);
    1.30 +	    if(SECMOD_DeleteInternalModule(internal_name) != SECSuccess) {
    1.31 +		PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError()));
    1.32 +		PR_smprintf_free(internal_name);
    1.33 +		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    1.34 +		return FIPS_SWITCH_FAILED_ERR;
    1.35 +	    }
    1.36 +	    PR_smprintf_free(internal_name);
    1.37 +	    if (!PK11_IsFIPS()) {
    1.38 +		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    1.39 +		return FIPS_SWITCH_FAILED_ERR;
    1.40 +	    }
    1.41 +	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
    1.42 +	} else {
    1.43 +	    PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_ON_ERR]);
    1.44 +	    return FIPS_ALREADY_ON_ERR;
    1.45 +	}
    1.46 +    } else if(!PORT_Strcasecmp(arg, "false")) {
    1.47 +	if(PK11_IsFIPS()) {
    1.48 +	    internal_name = PR_smprintf("%s",
    1.49 +		SECMOD_GetInternalModule()->commonName);
    1.50 +	    if(SECMOD_DeleteInternalModule(internal_name) != SECSuccess) {
    1.51 +		PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError()));
    1.52 +		PR_smprintf_free(internal_name);
    1.53 +		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    1.54 +		return FIPS_SWITCH_FAILED_ERR;
    1.55 +	    }
    1.56 +	    PR_smprintf_free(internal_name);
    1.57 +	    if (PK11_IsFIPS()) {
    1.58 +		PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
    1.59 +		return FIPS_SWITCH_FAILED_ERR;
    1.60 +	    }
    1.61 +	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
    1.62 +	} else {
    1.63 +	    PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_OFF_ERR]);
    1.64 +	    return FIPS_ALREADY_OFF_ERR;
    1.65 +	}
    1.66 +    } else {
    1.67 +	PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
    1.68 +	return INVALID_FIPS_ARG;
    1.69 +    }
    1.70 +
    1.71 +    return SUCCESS;
    1.72 +}
    1.73 +
    1.74 +/*************************************************************************
    1.75 + *
    1.76 + * C h k F i p s M o d e
    1.77 + * If arg=="true", verify FIPS mode is enabled on the internal module.  
    1.78 + * If arg=="false", verify FIPS mode is disabled on the internal module.
    1.79 + */
    1.80 +Error
    1.81 +ChkFipsMode(char *arg)
    1.82 +{
    1.83 +    if(!PORT_Strcasecmp(arg, "true")) {
    1.84 +	if (PK11_IsFIPS()) {
    1.85 +	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
    1.86 +	} else {
    1.87 +	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
    1.88 +	    return FIPS_SWITCH_FAILED_ERR;
    1.89 +	}
    1.90 +
    1.91 +    } else if(!PORT_Strcasecmp(arg, "false")) {
    1.92 +	if(!PK11_IsFIPS()) {
    1.93 +	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
    1.94 +	} else {
    1.95 +	    PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
    1.96 +	    return FIPS_SWITCH_FAILED_ERR;
    1.97 +	}
    1.98 +    } else {
    1.99 +	PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
   1.100 +	return INVALID_FIPS_ARG;
   1.101 +    }
   1.102 +
   1.103 +    return SUCCESS;
   1.104 +}
   1.105 +
   1.106 +/************************************************************************
   1.107 + * Cipher and Mechanism name-bitmask translation tables
   1.108 + */
   1.109 +
   1.110 +typedef struct {
   1.111 +    const char *name;
   1.112 +    unsigned long mask;
   1.113 +} MaskString;
   1.114 +
   1.115 +
   1.116 +static const MaskString cipherStrings[] = {
   1.117 +    {"FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG}
   1.118 +};
   1.119 +static const int numCipherStrings =
   1.120 +    sizeof(cipherStrings) / sizeof(cipherStrings[0]);
   1.121 +
   1.122 +/* Initialized by LoadMechanismList */
   1.123 +static MaskString *mechanismStrings =  NULL;
   1.124 +static int numMechanismStrings = 0;
   1.125 +const static PK11DefaultArrayEntry *pk11_DefaultArray = NULL;
   1.126 +static int pk11_DefaultArraySize = 0;
   1.127 +
   1.128 +/* Maximum length of a colon-separated list of all the strings in an
   1.129 + * array. */
   1.130 +#define MAX_STRING_LIST_LEN 240    /* or less */
   1.131 +
   1.132 +
   1.133 +Error
   1.134 +LoadMechanismList(void)
   1.135 +{
   1.136 +    int i;
   1.137 +
   1.138 +    if (pk11_DefaultArray == NULL) {
   1.139 +        pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
   1.140 +        if (pk11_DefaultArray == NULL) {
   1.141 +            /* should assert. This shouldn't happen */
   1.142 +            return UNSPECIFIED_ERR;
   1.143 +        }
   1.144 +    }
   1.145 +    if (mechanismStrings != NULL) {
   1.146 +	return SUCCESS;
   1.147 +    }
   1.148 +
   1.149 +    /* build the mechanismStrings array */
   1.150 +    mechanismStrings = PORT_NewArray(MaskString, pk11_DefaultArraySize);
   1.151 +    if (mechanismStrings == NULL) {
   1.152 +	return OUT_OF_MEM_ERR;
   1.153 +    }
   1.154 +    numMechanismStrings = pk11_DefaultArraySize;
   1.155 +    for (i = 0; i < numMechanismStrings; i++) {
   1.156 +	const char *name = pk11_DefaultArray[i].name;
   1.157 +	unsigned long flag = pk11_DefaultArray[i].flag;
   1.158 +	/* map new name to old */
   1.159 +	switch (flag) {
   1.160 +	case SECMOD_FORTEZZA_FLAG:
   1.161 +	    name = "FORTEZZA";
   1.162 +	    break;
   1.163 +	case SECMOD_SHA1_FLAG:
   1.164 +	    name = "SHA1";
   1.165 +	    break;
   1.166 +	case SECMOD_CAMELLIA_FLAG:
   1.167 +	    name = "CAMELLIA";
   1.168 +	    break;
   1.169 +	case SECMOD_RANDOM_FLAG:
   1.170 +	    name = "RANDOM";
   1.171 +	    break;
   1.172 +	case SECMOD_FRIENDLY_FLAG:
   1.173 +	    name = "FRIENDLY";
   1.174 +	    break;
   1.175 +	default:
   1.176 +	    break;
   1.177 +	}
   1.178 +	mechanismStrings[i].name = name;
   1.179 +	mechanismStrings[i].mask = SECMOD_InternaltoPubMechFlags(flag);
   1.180 +    }
   1.181 +    return SUCCESS;
   1.182 +}
   1.183 +
   1.184 +/************************************************************************
   1.185 + * 
   1.186 + * g e t F l a g s F r o m S t r i n g
   1.187 + *
   1.188 + * Parses a mechanism list passed on the command line and converts it
   1.189 + * to an unsigned long bitmask.
   1.190 + * string is a colon-separated string of constants
   1.191 + * array is an array of MaskStrings.
   1.192 + * elements is the number of elements in array.
   1.193 + */
   1.194 +static unsigned long
   1.195 +getFlagsFromString(char *string, const MaskString array[], int elements)
   1.196 +{
   1.197 +    unsigned long ret = 0;
   1.198 +    short i = 0;
   1.199 +    char *cp;
   1.200 +    char *buf;
   1.201 +    char *end;
   1.202 +
   1.203 +    if(!string || !string[0]) {
   1.204 +	return ret;
   1.205 +    }
   1.206 +
   1.207 +    /* Make a temporary copy of the string */
   1.208 +    buf = PR_Malloc(strlen(string)+1);
   1.209 +    if(!buf) {
   1.210 +	out_of_memory();
   1.211 +    }
   1.212 +    strcpy(buf, string);
   1.213 +
   1.214 +    /* Look at each element of the list passed in */
   1.215 +    for(cp=buf; cp && *cp; cp = (end ? end+1 : NULL) ) {
   1.216 +	/* Look at the string up to the next colon */
   1.217 +	end = strchr(cp, ':');
   1.218 +	if(end) {
   1.219 +	    *end = '\0';
   1.220 +	}
   1.221 +
   1.222 +	/* Find which element this is */
   1.223 +	for(i=0; i < elements; i++) {
   1.224 +	    if( !PORT_Strcasecmp(cp, array[i].name) ) {
   1.225 +		break;
   1.226 +	    }
   1.227 +	}
   1.228 +	if(i == elements) {
   1.229 +	    /* Skip a bogus string, but print a warning message */
   1.230 +	    PR_fprintf(PR_STDERR, errStrings[INVALID_CONSTANT_ERR], cp);
   1.231 +	    continue;
   1.232 +	}
   1.233 +	ret |= array[i].mask;
   1.234 +    }
   1.235 +
   1.236 +    PR_Free(buf);
   1.237 +    return ret;
   1.238 +}
   1.239 +
   1.240 +/**********************************************************************
   1.241 + *
   1.242 + * g e t S t r i n g F r o m F l a g s
   1.243 + * 
   1.244 + * The return string's memory is owned by this function.  Copy it
   1.245 + * if you need it permanently or you want to change it.
   1.246 + */
   1.247 +static char *
   1.248 +getStringFromFlags(unsigned long flags, const MaskString array[], int elements)
   1.249 +{
   1.250 +    static char buf[MAX_STRING_LIST_LEN];
   1.251 +    int i;
   1.252 +    int count=0;
   1.253 +
   1.254 +    buf[0] = '\0';
   1.255 +    for(i=0; i<elements; i++) {
   1.256 +	if( flags & array[i].mask ) {
   1.257 +	    ++count;
   1.258 +	    if(count!=1) {
   1.259 +		strcat(buf, ":");
   1.260 +	    }
   1.261 +	    strcat(buf, array[i].name);
   1.262 +	}
   1.263 +    }
   1.264 +    return buf;
   1.265 +}
   1.266 +
   1.267 +/**********************************************************************
   1.268 + *
   1.269 + * A d d M o d u l e
   1.270 + *
   1.271 + * Add the named module, with the given library file, ciphers, and
   1.272 + * default mechanism flags
   1.273 + */
   1.274 +Error
   1.275 +AddModule(char *moduleName, char *libFile, char *cipherString,
   1.276 +    char *mechanismString, char* modparms)
   1.277 +{
   1.278 +    unsigned long ciphers;
   1.279 +    unsigned long mechanisms;
   1.280 +    SECStatus status;
   1.281 +
   1.282 +    mechanisms =
   1.283 +	getFlagsFromString(mechanismString, mechanismStrings,
   1.284 +			   numMechanismStrings);
   1.285 +    ciphers =
   1.286 +	getFlagsFromString(cipherString, cipherStrings, numCipherStrings);
   1.287 +
   1.288 +    status =
   1.289 +	SECMOD_AddNewModuleEx(moduleName, libFile,
   1.290 +		  SECMOD_PubMechFlagstoInternal(mechanisms),
   1.291 +		  SECMOD_PubCipherFlagstoInternal(ciphers),
   1.292 +		  modparms, NULL );
   1.293 +
   1.294 +    if(status != SECSuccess) {
   1.295 +	char* errtxt=NULL;
   1.296 +	PRInt32 copied = 0;
   1.297 +	if (PR_GetErrorTextLength()) {
   1.298 +	    errtxt = PR_Malloc(PR_GetErrorTextLength() + 1);
   1.299 +	    copied = PR_GetErrorText(errtxt);
   1.300 +	}
   1.301 +	if (copied && errtxt) {
   1.302 +	    PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR], 
   1.303 +		       moduleName, errtxt);
   1.304 +	    PR_Free(errtxt);
   1.305 +	} else {
   1.306 +	    PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR], 
   1.307 +		       moduleName, SECU_Strerror(PORT_GetError()));
   1.308 +	}
   1.309 +	return ADD_MODULE_FAILED_ERR;
   1.310 +    } else {
   1.311 +	PR_fprintf(PR_STDOUT, msgStrings[ADD_MODULE_SUCCESS_MSG], moduleName);
   1.312 +	return SUCCESS;
   1.313 +    }
   1.314 +}
   1.315 +
   1.316 +/***********************************************************************
   1.317 + *
   1.318 + * D e l e t e M o d u l e
   1.319 + *
   1.320 + * Deletes the named module from the database.
   1.321 + */
   1.322 +Error
   1.323 +DeleteModule(char *moduleName)
   1.324 +{
   1.325 +    SECStatus status;
   1.326 +    int type;
   1.327 +    
   1.328 +    status = SECMOD_DeleteModule(moduleName, &type);
   1.329 +
   1.330 +    if(status != SECSuccess) {
   1.331 +	if(type == SECMOD_FIPS || type == SECMOD_INTERNAL) {
   1.332 +	    PR_fprintf(PR_STDERR, errStrings[DELETE_INTERNAL_ERR]);
   1.333 +	    return DELETE_INTERNAL_ERR;
   1.334 +	} else {
   1.335 +	    PR_fprintf(PR_STDERR, errStrings[DELETE_FAILED_ERR], moduleName);
   1.336 +	    return DELETE_FAILED_ERR;
   1.337 +	}
   1.338 +    }
   1.339 +
   1.340 +    PR_fprintf(PR_STDOUT, msgStrings[DELETE_SUCCESS_MSG], moduleName);
   1.341 +    return SUCCESS;
   1.342 +}
   1.343 +
   1.344 +/************************************************************************
   1.345 + *
   1.346 + * R a w L i s t M o d u l e s
   1.347 + *
   1.348 + * Lists all the modules in the database, along with their slots and tokens.
   1.349 + */
   1.350 +Error
   1.351 +RawListModule(char *modulespec)
   1.352 +{
   1.353 +    SECMODModule *module;
   1.354 +    char **moduleSpecList;
   1.355 +
   1.356 +    module = SECMOD_LoadModule(modulespec,NULL,PR_FALSE);
   1.357 +    if (module == NULL) {
   1.358 +	/* handle error */
   1.359 +	return NO_SUCH_MODULE_ERR;
   1.360 +    }
   1.361 +
   1.362 +    moduleSpecList = SECMOD_GetModuleSpecList(module);
   1.363 +    if (!moduleSpecList || !moduleSpecList[0]) {
   1.364 +	SECU_PrintError("modutil",
   1.365 +			    "no specs in secmod DB");
   1.366 +	return NO_SUCH_MODULE_ERR;
   1.367 +    }
   1.368 +
   1.369 +    for ( ;*moduleSpecList; moduleSpecList++) {
   1.370 +	printf("%s\n\n",*moduleSpecList);
   1.371 +    }
   1.372 +
   1.373 +    return SUCCESS;
   1.374 +}
   1.375 +
   1.376 +Error
   1.377 +RawAddModule(char *dbmodulespec, char *modulespec)
   1.378 +{
   1.379 +    SECMODModule *module;
   1.380 +    SECMODModule *dbmodule;
   1.381 +
   1.382 +
   1.383 +    dbmodule = SECMOD_LoadModule(dbmodulespec,NULL,PR_TRUE);
   1.384 +    if (dbmodule == NULL) {
   1.385 +	/* handle error */
   1.386 +	return NO_SUCH_MODULE_ERR;
   1.387 +    }
   1.388 +
   1.389 +    module = SECMOD_LoadModule(modulespec,dbmodule,PR_FALSE);
   1.390 +    if (module == NULL) {
   1.391 +	/* handle error */
   1.392 +	return NO_SUCH_MODULE_ERR;
   1.393 +    }
   1.394 +
   1.395 +    if( SECMOD_UpdateModule(module) != SECSuccess ) {
   1.396 +	PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec);
   1.397 +	return UPDATE_MOD_FAILED_ERR;
   1.398 +    }
   1.399 +    return SUCCESS;
   1.400 +}
   1.401 +
   1.402 +static void
   1.403 +printModule(SECMODModule *module, int *count) 
   1.404 +{
   1.405 +    int slotCount = module->loaded ? module->slotCount : 0;
   1.406 +    int i;
   1.407 +
   1.408 +    if ((*count)++) {
   1.409 +        PR_fprintf(PR_STDOUT,"\n");
   1.410 +    }
   1.411 +        PR_fprintf(PR_STDOUT, "%3d. %s\n", *count, module->commonName);
   1.412 +
   1.413 +    if (module->dllName) {
   1.414 +        PR_fprintf(PR_STDOUT, "\tlibrary name: %s\n", module->dllName);
   1.415 +    }
   1.416 +
   1.417 +    if (slotCount == 0) {
   1.418 +        PR_fprintf(PR_STDOUT,
   1.419 +	"\t slots: There are no slots attached to this module\n");
   1.420 +    } else {
   1.421 +        PR_fprintf(PR_STDOUT, "\t slots: %d slot%s attached\n",
   1.422 +		slotCount, (slotCount==1 ? "" : "s") );
   1.423 +    }
   1.424 +
   1.425 +    if (module->loaded == 0) {
   1.426 +        PR_fprintf(PR_STDOUT, "\tstatus: Not loaded\n");
   1.427 +    } else {
   1.428 +        PR_fprintf(PR_STDOUT, "\tstatus: loaded\n");
   1.429 +    }
   1.430 +
   1.431 +    /* Print slot and token names */
   1.432 +    for (i = 0; i < slotCount; i++) {
   1.433 +        PK11SlotInfo *slot = module->slots[i];
   1.434 +
   1.435 +        PR_fprintf(PR_STDOUT, "\n");
   1.436 +        PR_fprintf(PR_STDOUT, "\t slot: %s\n", PK11_GetSlotName(slot));
   1.437 +        PR_fprintf(PR_STDOUT, "\ttoken: %s\n", PK11_GetTokenName(slot));
   1.438 +    }
   1.439 +    return;
   1.440 +}
   1.441 +
   1.442 +/************************************************************************
   1.443 + *
   1.444 + * L i s t M o d u l e s
   1.445 + *
   1.446 + * Lists all the modules in the database, along with their slots and tokens.
   1.447 + */
   1.448 +Error
   1.449 +ListModules()
   1.450 +{
   1.451 +    SECMODListLock *lock;
   1.452 +    SECMODModuleList *list;
   1.453 +    SECMODModuleList *deadlist;
   1.454 +    SECMODModuleList *mlp;
   1.455 +    Error ret=UNSPECIFIED_ERR;
   1.456 +    int count = 0;
   1.457 +
   1.458 +    lock = SECMOD_GetDefaultModuleListLock();
   1.459 +    if(!lock) {
   1.460 +	PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]);
   1.461 +	return NO_LIST_LOCK_ERR;
   1.462 +    }
   1.463 +
   1.464 +    SECMOD_GetReadLock(lock);
   1.465 +
   1.466 +    list = SECMOD_GetDefaultModuleList();
   1.467 +    deadlist = SECMOD_GetDeadModuleList();
   1.468 +    if (!list && !deadlist) {
   1.469 +	PR_fprintf(PR_STDERR, errStrings[NO_MODULE_LIST_ERR]);
   1.470 +	ret = NO_MODULE_LIST_ERR;
   1.471 +	goto loser;
   1.472 +    }
   1.473 +
   1.474 +    PR_fprintf(PR_STDOUT,
   1.475 +	"\nListing of PKCS #11 Modules\n"
   1.476 +	"-----------------------------------------------------------\n");
   1.477 +    
   1.478 +    for(mlp=list; mlp != NULL; mlp = mlp->next) {
   1.479 +	printModule(mlp->module, &count);
   1.480 +    }
   1.481 +    for (mlp=deadlist; mlp != NULL; mlp = mlp->next) {
   1.482 +	printModule(mlp->module, &count);
   1.483 +    }
   1.484 +
   1.485 +
   1.486 +    PR_fprintf(PR_STDOUT,
   1.487 +	"-----------------------------------------------------------\n");
   1.488 +
   1.489 +    ret = SUCCESS;
   1.490 +
   1.491 +loser:
   1.492 +    SECMOD_ReleaseReadLock(lock);
   1.493 +    return ret;
   1.494 +}
   1.495 +
   1.496 +/* Strings describing PK11DisableReasons */
   1.497 +static char *disableReasonStr[] = {
   1.498 +    "no reason",
   1.499 +    "user disabled",
   1.500 +    "could not initialize token",
   1.501 +    "could not verify token",
   1.502 +    "token not present"
   1.503 +};
   1.504 +static int numDisableReasonStr =
   1.505 +    sizeof(disableReasonStr) / sizeof(disableReasonStr[0]);
   1.506 +
   1.507 +/***********************************************************************
   1.508 + *
   1.509 + * L i s t M o d u l e
   1.510 + *
   1.511 + * Lists detailed information about the named module.
   1.512 + */
   1.513 +Error
   1.514 +ListModule(char *moduleName)
   1.515 +{
   1.516 +    SECMODModule *module = NULL;
   1.517 +    PK11SlotInfo *slot;
   1.518 +    int slotnum;
   1.519 +    CK_INFO modinfo;
   1.520 +    CK_SLOT_INFO slotinfo;
   1.521 +    CK_TOKEN_INFO tokeninfo;
   1.522 +    char *ciphers, *mechanisms;
   1.523 +    PK11DisableReasons reason;
   1.524 +    Error  rv = SUCCESS;
   1.525 +
   1.526 +    if(!moduleName) {
   1.527 +	return SUCCESS;
   1.528 +    }
   1.529 +
   1.530 +    module = SECMOD_FindModule(moduleName);
   1.531 +    if(!module) {
   1.532 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   1.533 +	rv = NO_SUCH_MODULE_ERR;
   1.534 +        goto loser;
   1.535 +    }
   1.536 +
   1.537 +    if ((module->loaded) && 
   1.538 +			(PK11_GetModInfo(module, &modinfo) != SECSuccess)) {
   1.539 +	PR_fprintf(PR_STDERR, errStrings[MOD_INFO_ERR], moduleName);
   1.540 +	rv = MOD_INFO_ERR;
   1.541 +        goto loser;
   1.542 +    }
   1.543 +
   1.544 +    /* Module info */
   1.545 +    PR_fprintf(PR_STDOUT, 
   1.546 +	"\n-----------------------------------------------------------\n");
   1.547 +    PR_fprintf(PR_STDOUT, "Name: %s\n", module->commonName);
   1.548 +    if(module->internal || !module->dllName) {
   1.549 +	PR_fprintf(PR_STDOUT, "Library file: **Internal ONLY module**\n");
   1.550 +    } else {
   1.551 +	PR_fprintf(PR_STDOUT, "Library file: %s\n", module->dllName);
   1.552 +    }
   1.553 +
   1.554 +    if (module->loaded) {
   1.555 +	PR_fprintf(PR_STDOUT, "Manufacturer: %.32s\n", modinfo.manufacturerID);
   1.556 +	PR_fprintf(PR_STDOUT, "Description: %.32s\n", modinfo.libraryDescription);
   1.557 +	PR_fprintf(PR_STDOUT, "PKCS #11 Version %d.%d\n",
   1.558 +	modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor);
   1.559 +	PR_fprintf(PR_STDOUT, "Library Version: %d.%d\n",
   1.560 +	modinfo.libraryVersion.major, modinfo.libraryVersion.minor);
   1.561 +    } else {
   1.562 +	PR_fprintf(PR_STDOUT, "* Module not loaded\n");
   1.563 +    }
   1.564 +    /* Get cipher and mechanism flags */
   1.565 +    ciphers = getStringFromFlags(module->ssl[0], cipherStrings,
   1.566 +      numCipherStrings);
   1.567 +    if(ciphers[0] == '\0') {
   1.568 +	ciphers = "None";
   1.569 +    }
   1.570 +    PR_fprintf(PR_STDOUT, "Cipher Enable Flags: %s\n", ciphers);
   1.571 +    mechanisms = NULL;
   1.572 +    if (module->slotCount > 0) {
   1.573 +	mechanisms = getStringFromFlags(
   1.574 +	    PK11_GetDefaultFlags(module->slots[0]),
   1.575 +	    mechanismStrings, numMechanismStrings);
   1.576 +    }
   1.577 +    if ((mechanisms==NULL) || (mechanisms[0] =='\0')) {
   1.578 +	mechanisms = "None";
   1.579 +    }
   1.580 +    PR_fprintf(PR_STDOUT, "Default Mechanism Flags: %s\n", mechanisms);
   1.581 +
   1.582 +#define PAD "  "
   1.583 +
   1.584 +    /* Loop over each slot */
   1.585 +    for (slotnum=0; slotnum < module->slotCount; slotnum++) {
   1.586 +	slot = module->slots[slotnum];
   1.587 +	if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) {
   1.588 +	    PR_fprintf(PR_STDERR, errStrings[SLOT_INFO_ERR],
   1.589 +		PK11_GetSlotName(slot));
   1.590 +	    rv = SLOT_INFO_ERR;
   1.591 +	    continue;
   1.592 +	}
   1.593 +
   1.594 +	/* Slot Info */
   1.595 +	PR_fprintf(PR_STDOUT, "\n"PAD"Slot: %s\n", PK11_GetSlotName(slot));
   1.596 +	mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot),
   1.597 +	    mechanismStrings, numMechanismStrings);
   1.598 +	if(mechanisms[0] =='\0') {
   1.599 +	     mechanisms = "None";
   1.600 +	}
   1.601 +	PR_fprintf(PR_STDOUT, PAD"Slot Mechanism Flags: %s\n", mechanisms);
   1.602 +	PR_fprintf(PR_STDOUT, PAD"Manufacturer: %.32s\n",
   1.603 +	    slotinfo.manufacturerID);
   1.604 +	if (PK11_IsHW(slot)) {
   1.605 +	    PR_fprintf(PR_STDOUT, PAD"Type: Hardware\n");
   1.606 +	} else {
   1.607 +	    PR_fprintf(PR_STDOUT, PAD"Type: Software\n");
   1.608 +	}
   1.609 +	PR_fprintf(PR_STDOUT, PAD"Version Number: %d.%d\n",
   1.610 +	    slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor);
   1.611 +	PR_fprintf(PR_STDOUT, PAD"Firmware Version: %d.%d\n",
   1.612 +	    slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor);
   1.613 +	if (PK11_IsDisabled(slot)) {
   1.614 +	    reason  = PK11_GetDisabledReason(slot);
   1.615 +	    if(reason < numDisableReasonStr) {
   1.616 +		PR_fprintf(PR_STDOUT, PAD"Status: DISABLED (%s)\n",
   1.617 +		  disableReasonStr[reason]);
   1.618 +	    } else {
   1.619 +		PR_fprintf(PR_STDOUT, PAD"Status: DISABLED\n");
   1.620 +	    }
   1.621 +	} else {
   1.622 +	    PR_fprintf(PR_STDOUT, PAD"Status: Enabled\n");
   1.623 +	}
   1.624 +
   1.625 +	if(PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) {
   1.626 +	    PR_fprintf(PR_STDERR, errStrings[TOKEN_INFO_ERR],
   1.627 +	      PK11_GetTokenName(slot));
   1.628 +	    rv = TOKEN_INFO_ERR;
   1.629 +	    continue;
   1.630 +	}
   1.631 +
   1.632 +	/* Token Info */
   1.633 +	PR_fprintf(PR_STDOUT, PAD"Token Name: %.32s\n",
   1.634 +	    tokeninfo.label);
   1.635 +	PR_fprintf(PR_STDOUT, PAD"Token Manufacturer: %.32s\n",
   1.636 +	    tokeninfo.manufacturerID);
   1.637 +	PR_fprintf(PR_STDOUT, PAD"Token Model: %.16s\n", tokeninfo.model);
   1.638 +	PR_fprintf(PR_STDOUT, PAD"Token Serial Number: %.16s\n",
   1.639 +	    tokeninfo.serialNumber);
   1.640 +	PR_fprintf(PR_STDOUT, PAD"Token Version: %d.%d\n",
   1.641 +	    tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor);
   1.642 +	PR_fprintf(PR_STDOUT, PAD"Token Firmware Version: %d.%d\n",
   1.643 +	    tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor);
   1.644 +	if(tokeninfo.flags & CKF_WRITE_PROTECTED) {
   1.645 +	    PR_fprintf(PR_STDOUT, PAD"Access: Write Protected\n");
   1.646 +	} else {
   1.647 +	    PR_fprintf(PR_STDOUT, PAD"Access: NOT Write Protected\n");
   1.648 +	}
   1.649 +	if(tokeninfo.flags & CKF_LOGIN_REQUIRED) {
   1.650 +	    PR_fprintf(PR_STDOUT, PAD"Login Type: Login required\n");
   1.651 +	} else {
   1.652 +	    PR_fprintf(PR_STDOUT, PAD
   1.653 +	      "Login Type: Public (no login required)\n");
   1.654 +	}
   1.655 +	if(tokeninfo.flags & CKF_USER_PIN_INITIALIZED) {
   1.656 +	    PR_fprintf(PR_STDOUT, PAD"User Pin: Initialized\n");
   1.657 +	} else {
   1.658 +	    PR_fprintf(PR_STDOUT, PAD"User Pin: NOT Initialized\n");
   1.659 +	}
   1.660 +    }
   1.661 +    PR_fprintf(PR_STDOUT, 
   1.662 +	"\n-----------------------------------------------------------\n");
   1.663 +loser:
   1.664 +    if (module) {
   1.665 +        SECMOD_DestroyModule(module);
   1.666 +    }
   1.667 +    return rv;
   1.668 +}
   1.669 +
   1.670 +/************************************************************************
   1.671 + *
   1.672 + * C h a n g e P W
   1.673 + */
   1.674 +Error
   1.675 +ChangePW(char *tokenName, char *pwFile, char *newpwFile)
   1.676 +{
   1.677 +    char *oldpw=NULL, *newpw=NULL, *newpw2=NULL;
   1.678 +    PK11SlotInfo *slot;
   1.679 +    Error ret=UNSPECIFIED_ERR;
   1.680 +    PRBool matching;
   1.681 +
   1.682 +    slot = PK11_FindSlotByName(tokenName);
   1.683 +    if(!slot) {
   1.684 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], tokenName);
   1.685 +	return NO_SUCH_TOKEN_ERR;
   1.686 +    }
   1.687 +
   1.688 +    /* Get old password */
   1.689 +    if(! PK11_NeedUserInit(slot)) {
   1.690 +	if(pwFile) {
   1.691 +	    oldpw = SECU_FilePasswd(NULL, PR_FALSE, pwFile);
   1.692 +	    if(PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
   1.693 +		PR_fprintf(PR_STDERR, errStrings[BAD_PW_ERR]);
   1.694 +		ret=BAD_PW_ERR;
   1.695 +		goto loser;
   1.696 +	    }
   1.697 +	} else {
   1.698 +	    for(matching=PR_FALSE; !matching; ) {
   1.699 +		oldpw = SECU_GetPasswordString(NULL, "Enter old password: ");
   1.700 +		if(PK11_CheckUserPassword(slot, oldpw) == SECSuccess) {
   1.701 +		    matching = PR_TRUE;
   1.702 +		} else {
   1.703 +		    PR_fprintf(PR_STDOUT, msgStrings[BAD_PW_MSG]);
   1.704 +		}
   1.705 +	    }
   1.706 +	}
   1.707 +    }
   1.708 +
   1.709 +    /* Get new password */
   1.710 +    if(newpwFile) {
   1.711 +	newpw = SECU_FilePasswd(NULL, PR_FALSE, newpwFile);
   1.712 +    } else {
   1.713 +	for(matching=PR_FALSE; !matching; ) {
   1.714 +	    newpw = SECU_GetPasswordString(NULL, "Enter new password: ");
   1.715 +	    newpw2 = SECU_GetPasswordString(NULL, "Re-enter new password: ");
   1.716 +	    if(strcmp(newpw, newpw2)) {
   1.717 +		PR_fprintf(PR_STDOUT, msgStrings[PW_MATCH_MSG]);
   1.718 +	    } else {
   1.719 +		matching = PR_TRUE;
   1.720 +	    }
   1.721 +	}
   1.722 +    }
   1.723 +
   1.724 +    /* Change the password */
   1.725 +    if(PK11_NeedUserInit(slot)) {
   1.726 +	if(PK11_InitPin(slot, NULL /*ssopw*/, newpw) != SECSuccess) {
   1.727 +	    PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName);
   1.728 +	    ret = CHANGEPW_FAILED_ERR;
   1.729 +	    goto loser;
   1.730 +	}
   1.731 +    } else {
   1.732 +	if(PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
   1.733 +	    PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName);
   1.734 +	    ret = CHANGEPW_FAILED_ERR;
   1.735 +	    goto loser;
   1.736 +	}
   1.737 +    }
   1.738 +
   1.739 +    PR_fprintf(PR_STDOUT, msgStrings[CHANGEPW_SUCCESS_MSG], tokenName);
   1.740 +    ret = SUCCESS;
   1.741 +
   1.742 +loser:
   1.743 +    if(oldpw) {
   1.744 +	memset(oldpw, 0, strlen(oldpw));
   1.745 +	PORT_Free(oldpw);
   1.746 +    }
   1.747 +    if(newpw) {
   1.748 +	memset(newpw, 0, strlen(newpw));
   1.749 +	PORT_Free(newpw);
   1.750 +    }
   1.751 +    if(newpw2) {
   1.752 +	memset(newpw2, 0, strlen(newpw2));
   1.753 +	PORT_Free(newpw2);
   1.754 +    }
   1.755 +    PK11_FreeSlot(slot);
   1.756 +
   1.757 +    return ret;
   1.758 +}
   1.759 +
   1.760 +/***********************************************************************
   1.761 + *
   1.762 + * E n a b l e M o d u l e
   1.763 + *
   1.764 + * If enable==PR_TRUE, enables the module or slot.
   1.765 + * If enable==PR_FALSE, disables the module or slot.
   1.766 + * moduleName is the name of the module.
   1.767 + * slotName is the name of the slot.  It is optional.
   1.768 + */
   1.769 +Error
   1.770 +EnableModule(char *moduleName, char *slotName, PRBool enable)
   1.771 +{
   1.772 +    int i;
   1.773 +    SECMODModule *module = NULL;
   1.774 +    PK11SlotInfo *slot = NULL;
   1.775 +    PRBool found = PR_FALSE;
   1.776 +    Error rv;
   1.777 +
   1.778 +    module = SECMOD_FindModule(moduleName);
   1.779 +    if(!module) {
   1.780 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   1.781 +	rv = NO_SUCH_MODULE_ERR;
   1.782 +        goto loser;
   1.783 +    }
   1.784 +
   1.785 +    for(i=0; i < module->slotCount; i++) {
   1.786 +	slot = module->slots[i];
   1.787 +	if(slotName && strcmp(PK11_GetSlotName(slot), slotName)) {
   1.788 +		/* Not the right slot */
   1.789 +		continue;
   1.790 +	}
   1.791 +	if(enable) {
   1.792 +	    if(! PK11_UserEnableSlot(slot)) {
   1.793 +		PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR],
   1.794 +		    "enable", PK11_GetSlotName(slot));
   1.795 +		rv = ENABLE_FAILED_ERR;
   1.796 +                goto loser;
   1.797 +	    } else {
   1.798 +		found = PR_TRUE;
   1.799 +		PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG],
   1.800 +		    PK11_GetSlotName(slot), "enabled");
   1.801 +	    }
   1.802 +	} else {
   1.803 +	    if(! PK11_UserDisableSlot(slot)) {
   1.804 +		PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR],
   1.805 +		    "disable", PK11_GetSlotName(slot));
   1.806 +		rv = ENABLE_FAILED_ERR;
   1.807 +                goto loser;
   1.808 +	    } else {
   1.809 +		found = PR_TRUE;
   1.810 +		PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG],
   1.811 +		    PK11_GetSlotName(slot), "disabled");
   1.812 +	    }
   1.813 +	}
   1.814 +    }
   1.815 +
   1.816 +    if(slotName && !found) {
   1.817 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
   1.818 +	rv = NO_SUCH_SLOT_ERR;
   1.819 +        goto loser;
   1.820 +    }
   1.821 +
   1.822 +    /* Delete and re-add module to save changes */
   1.823 +    if( SECMOD_UpdateModule(module) != SECSuccess ) {
   1.824 +	PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], moduleName);
   1.825 +	rv = UPDATE_MOD_FAILED_ERR;
   1.826 +        goto loser;
   1.827 +    }
   1.828 +
   1.829 +    rv = SUCCESS;
   1.830 +loser:
   1.831 +    if (module) {
   1.832 +        SECMOD_DestroyModule(module);
   1.833 +    }
   1.834 +    return rv;
   1.835 +}
   1.836 +
   1.837 +/*************************************************************************
   1.838 + *
   1.839 + * S e t D e f a u l t M o d u l e
   1.840 + *
   1.841 + */
   1.842 +Error
   1.843 +SetDefaultModule(char *moduleName, char *slotName, char *mechanisms)
   1.844 +{
   1.845 +    SECMODModule *module = NULL;
   1.846 +    PK11SlotInfo *slot;
   1.847 +    int s, i;
   1.848 +    unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings,
   1.849 +	numMechanismStrings);
   1.850 +    PRBool found = PR_FALSE;
   1.851 +    Error errcode = UNSPECIFIED_ERR;
   1.852 +
   1.853 +    mechFlags =  SECMOD_PubMechFlagstoInternal(mechFlags);
   1.854 +
   1.855 +    module = SECMOD_FindModule(moduleName);
   1.856 +    if(!module) {
   1.857 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   1.858 +	errcode = NO_SUCH_MODULE_ERR;
   1.859 +	goto loser;
   1.860 +    }
   1.861 +
   1.862 +    /* Go through each slot */
   1.863 +    for(s=0; s < module->slotCount; s++) {
   1.864 +	slot = module->slots[s];
   1.865 +
   1.866 +	if ((slotName != NULL) &&
   1.867 +	    !((strcmp(PK11_GetSlotName(slot),slotName) == 0) ||
   1.868 +	    (strcmp(PK11_GetTokenName(slot),slotName) == 0)) ) {
   1.869 +	    /* we are only interested in changing the one slot */
   1.870 +	    continue;
   1.871 +	}
   1.872 +
   1.873 +	found = PR_TRUE;
   1.874 +
   1.875 +	/* Go through each mechanism */
   1.876 +	for(i=0; i < pk11_DefaultArraySize; i++) {
   1.877 +	    if(pk11_DefaultArray[i].flag & mechFlags) {
   1.878 +		/* Enable this default mechanism */
   1.879 +		PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]),
   1.880 +		    PR_TRUE);
   1.881 +	    }
   1.882 +	}
   1.883 +    }
   1.884 +    if (slotName && !found) {
   1.885 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
   1.886 +	errcode = NO_SUCH_SLOT_ERR;
   1.887 +	goto loser;
   1.888 +    }
   1.889 +
   1.890 +    /* Delete and re-add module to save changes */
   1.891 +    if( SECMOD_UpdateModule(module) != SECSuccess ) {
   1.892 +	PR_fprintf(PR_STDERR, errStrings[DEFAULT_FAILED_ERR],
   1.893 +	  moduleName);
   1.894 +	errcode = DEFAULT_FAILED_ERR;
   1.895 +	goto loser;
   1.896 +    }
   1.897 +
   1.898 +    PR_fprintf(PR_STDOUT, msgStrings[DEFAULT_SUCCESS_MSG]);
   1.899 +
   1.900 +    errcode = SUCCESS;
   1.901 +loser:
   1.902 +    if (module) {
   1.903 +        SECMOD_DestroyModule(module);
   1.904 +    }
   1.905 +    return errcode;
   1.906 +}
   1.907 +
   1.908 +/************************************************************************
   1.909 + *
   1.910 + * U n s e t D e f a u l t M o d u l e
   1.911 + */
   1.912 +Error
   1.913 +UnsetDefaultModule(char *moduleName, char *slotName, char *mechanisms)
   1.914 +{
   1.915 +    SECMODModule * module = NULL;
   1.916 +    PK11SlotInfo *slot;
   1.917 +    int s, i;
   1.918 +    unsigned long mechFlags = getFlagsFromString(mechanisms,
   1.919 +	mechanismStrings, numMechanismStrings);
   1.920 +    PRBool found = PR_FALSE;
   1.921 +    Error rv;
   1.922 +
   1.923 +    mechFlags =  SECMOD_PubMechFlagstoInternal(mechFlags);
   1.924 +
   1.925 +    module = SECMOD_FindModule(moduleName);
   1.926 +    if(!module) {
   1.927 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
   1.928 +	rv = NO_SUCH_MODULE_ERR;
   1.929 +        goto loser;
   1.930 +    }
   1.931 +
   1.932 +    for(s=0; s < module->slotCount; s++) {
   1.933 +	slot = module->slots[s];
   1.934 +	if ((slotName != NULL) &&
   1.935 +	    !((strcmp(PK11_GetSlotName(slot),slotName) == 0) ||
   1.936 +	    (strcmp(PK11_GetTokenName(slot),slotName) == 0)) ) {
   1.937 +	    /* we are only interested in changing the one slot */
   1.938 +	    continue;
   1.939 +	}
   1.940 +	for(i=0; i < pk11_DefaultArraySize ; i++) {
   1.941 +	    if(pk11_DefaultArray[i].flag & mechFlags) {
   1.942 +		PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]),
   1.943 +		    PR_FALSE);
   1.944 +	    }
   1.945 +	}
   1.946 +    }
   1.947 +    if (slotName && !found) {
   1.948 +	PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
   1.949 +	rv = NO_SUCH_SLOT_ERR;
   1.950 +        goto loser;
   1.951 +    }
   1.952 +
   1.953 +    /* Delete and re-add module to save changes */
   1.954 +    if( SECMOD_UpdateModule(module) != SECSuccess ) {
   1.955 +	PR_fprintf(PR_STDERR, errStrings[UNDEFAULT_FAILED_ERR],
   1.956 +	  moduleName);
   1.957 +	rv = UNDEFAULT_FAILED_ERR;
   1.958 +        goto loser;
   1.959 +    }
   1.960 +
   1.961 +    PR_fprintf(PR_STDOUT, msgStrings[UNDEFAULT_SUCCESS_MSG]);
   1.962 +    rv = SUCCESS;
   1.963 +loser:
   1.964 +    if (module) {
   1.965 +        SECMOD_DestroyModule(module);
   1.966 +    }
   1.967 +    return rv;
   1.968 +}

mercurial