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

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

mercurial