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