| /* This Source Code Form is subject to the terms of the Mozilla Public |
| * License, v. 2.0. If a copy of the MPL was not distributed with this |
| * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
| |
| /* To edit this file, set TABSTOPS to 4 spaces. |
| * This is not the normal NSS convention. |
| */ |
| |
| #include "modutil.h" |
| #include "pk11func.h" |
| |
| /************************************************************************* |
| * |
| * F i p s M o d e |
| * If arg=="true", enable FIPS mode on the internal module. If arg=="false", |
| * disable FIPS mode on the internal module. |
| */ |
| Error |
| FipsMode(char *arg) |
| { |
| char *internal_name; |
| |
| if (!PORT_Strcasecmp(arg, "true")) { |
| if (!PK11_IsFIPS()) { |
| internal_name = PR_smprintf("%s", |
| SECMOD_GetInternalModule()->commonName); |
| if (SECMOD_DeleteInternalModule(internal_name) != SECSuccess) { |
| PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError())); |
| PR_smprintf_free(internal_name); |
| PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); |
| return FIPS_SWITCH_FAILED_ERR; |
| } |
| PR_smprintf_free(internal_name); |
| if (!PK11_IsFIPS()) { |
| PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); |
| return FIPS_SWITCH_FAILED_ERR; |
| } |
| PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]); |
| } else { |
| PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_ON_ERR]); |
| return FIPS_ALREADY_ON_ERR; |
| } |
| } else if (!PORT_Strcasecmp(arg, "false")) { |
| if (PK11_IsFIPS()) { |
| internal_name = PR_smprintf("%s", |
| SECMOD_GetInternalModule()->commonName); |
| if (SECMOD_DeleteInternalModule(internal_name) != SECSuccess) { |
| PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError())); |
| PR_smprintf_free(internal_name); |
| PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); |
| return FIPS_SWITCH_FAILED_ERR; |
| } |
| PR_smprintf_free(internal_name); |
| if (PK11_IsFIPS()) { |
| PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]); |
| return FIPS_SWITCH_FAILED_ERR; |
| } |
| PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]); |
| } else { |
| PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_OFF_ERR]); |
| return FIPS_ALREADY_OFF_ERR; |
| } |
| } else { |
| PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]); |
| return INVALID_FIPS_ARG; |
| } |
| |
| return SUCCESS; |
| } |
| |
| /************************************************************************* |
| * |
| * C h k F i p s M o d e |
| * If arg=="true", verify FIPS mode is enabled on the internal module. |
| * If arg=="false", verify FIPS mode is disabled on the internal module. |
| */ |
| Error |
| ChkFipsMode(char *arg) |
| { |
| if (!PORT_Strcasecmp(arg, "true")) { |
| if (PK11_IsFIPS()) { |
| PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]); |
| } else { |
| PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]); |
| return FIPS_SWITCH_FAILED_ERR; |
| } |
| |
| } else if (!PORT_Strcasecmp(arg, "false")) { |
| if (!PK11_IsFIPS()) { |
| PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]); |
| } else { |
| PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]); |
| return FIPS_SWITCH_FAILED_ERR; |
| } |
| } else { |
| PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]); |
| return INVALID_FIPS_ARG; |
| } |
| |
| return SUCCESS; |
| } |
| |
| /************************************************************************ |
| * Cipher and Mechanism name-bitmask translation tables |
| */ |
| |
| typedef struct { |
| const char *name; |
| unsigned long mask; |
| } MaskString; |
| |
| static const MaskString cipherStrings[] = { |
| { "FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG } |
| }; |
| static const int numCipherStrings = |
| sizeof(cipherStrings) / sizeof(cipherStrings[0]); |
| |
| /* Initialized by LoadMechanismList */ |
| static MaskString *mechanismStrings = NULL; |
| static int numMechanismStrings = 0; |
| const static PK11DefaultArrayEntry *pk11_DefaultArray = NULL; |
| static int pk11_DefaultArraySize = 0; |
| |
| /* Maximum length of a colon-separated list of all the strings in an |
| * array. */ |
| #define MAX_STRING_LIST_LEN 240 /* or less */ |
| |
| Error |
| LoadMechanismList(void) |
| { |
| int i; |
| |
| if (pk11_DefaultArray == NULL) { |
| pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize); |
| if (pk11_DefaultArray == NULL) { |
| /* should assert. This shouldn't happen */ |
| return UNSPECIFIED_ERR; |
| } |
| } |
| if (mechanismStrings != NULL) { |
| return SUCCESS; |
| } |
| |
| /* build the mechanismStrings array */ |
| mechanismStrings = PORT_NewArray(MaskString, pk11_DefaultArraySize); |
| if (mechanismStrings == NULL) { |
| return OUT_OF_MEM_ERR; |
| } |
| numMechanismStrings = pk11_DefaultArraySize; |
| for (i = 0; i < numMechanismStrings; i++) { |
| const char *name = pk11_DefaultArray[i].name; |
| unsigned long flag = pk11_DefaultArray[i].flag; |
| /* map new name to old */ |
| switch (flag) { |
| case SECMOD_FORTEZZA_FLAG: |
| name = "FORTEZZA"; |
| break; |
| case SECMOD_SHA1_FLAG: |
| name = "SHA1"; |
| break; |
| case SECMOD_CAMELLIA_FLAG: |
| name = "CAMELLIA"; |
| break; |
| case SECMOD_RANDOM_FLAG: |
| name = "RANDOM"; |
| break; |
| case SECMOD_FRIENDLY_FLAG: |
| name = "FRIENDLY"; |
| break; |
| default: |
| break; |
| } |
| mechanismStrings[i].name = name; |
| mechanismStrings[i].mask = SECMOD_InternaltoPubMechFlags(flag); |
| } |
| return SUCCESS; |
| } |
| |
| /************************************************************************ |
| * |
| * g e t F l a g s F r o m S t r i n g |
| * |
| * Parses a mechanism list passed on the command line and converts it |
| * to an unsigned long bitmask. |
| * string is a colon-separated string of constants |
| * array is an array of MaskStrings. |
| * elements is the number of elements in array. |
| */ |
| static unsigned long |
| getFlagsFromString(char *string, const MaskString array[], int elements) |
| { |
| unsigned long ret = 0; |
| short i = 0; |
| char *cp; |
| char *buf; |
| char *end; |
| |
| if (!string || !string[0]) { |
| return ret; |
| } |
| |
| /* Make a temporary copy of the string */ |
| buf = PR_Malloc(strlen(string) + 1); |
| if (!buf) { |
| out_of_memory(); |
| } |
| strcpy(buf, string); |
| |
| /* Look at each element of the list passed in */ |
| for (cp = buf; cp && *cp; cp = (end ? end + 1 : NULL)) { |
| /* Look at the string up to the next colon */ |
| end = strchr(cp, ':'); |
| if (end) { |
| *end = '\0'; |
| } |
| |
| /* Find which element this is */ |
| for (i = 0; i < elements; i++) { |
| if (!PORT_Strcasecmp(cp, array[i].name)) { |
| break; |
| } |
| } |
| if (i == elements) { |
| /* Skip a bogus string, but print a warning message */ |
| PR_fprintf(PR_STDERR, errStrings[INVALID_CONSTANT_ERR], cp); |
| continue; |
| } |
| ret |= array[i].mask; |
| } |
| |
| PR_Free(buf); |
| return ret; |
| } |
| |
| /********************************************************************** |
| * |
| * g e t S t r i n g F r o m F l a g s |
| * |
| * The return string's memory is owned by this function. Copy it |
| * if you need it permanently or you want to change it. |
| */ |
| static char * |
| getStringFromFlags(unsigned long flags, const MaskString array[], int elements) |
| { |
| static char buf[MAX_STRING_LIST_LEN]; |
| int i; |
| int count = 0; |
| |
| buf[0] = '\0'; |
| for (i = 0; i < elements; i++) { |
| if (flags & array[i].mask) { |
| ++count; |
| if (count != 1) { |
| strcat(buf, ":"); |
| } |
| strcat(buf, array[i].name); |
| } |
| } |
| return buf; |
| } |
| |
| static PRBool |
| IsP11KitProxyModule(SECMODModule *module) |
| { |
| CK_INFO modinfo; |
| static const char p11KitManufacturerID[33] = |
| "PKCS#11 Kit "; |
| static const char p11KitLibraryDescription[33] = |
| "PKCS#11 Kit Proxy Module "; |
| |
| if (PK11_GetModInfo(module, &modinfo) == SECSuccess && |
| PORT_Memcmp(modinfo.manufacturerID, |
| p11KitManufacturerID, |
| sizeof(modinfo.manufacturerID)) == 0 && |
| PORT_Memcmp(modinfo.libraryDescription, |
| p11KitLibraryDescription, |
| sizeof(modinfo.libraryDescription)) == 0) { |
| return PR_TRUE; |
| } |
| |
| return PR_FALSE; |
| } |
| |
| PRBool |
| IsP11KitEnabled(void) |
| { |
| SECMODListLock *lock; |
| SECMODModuleList *mlp; |
| PRBool found = PR_FALSE; |
| |
| lock = SECMOD_GetDefaultModuleListLock(); |
| if (!lock) { |
| PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]); |
| return found; |
| } |
| |
| SECMOD_GetReadLock(lock); |
| |
| mlp = SECMOD_GetDefaultModuleList(); |
| for (; mlp != NULL; mlp = mlp->next) { |
| if (IsP11KitProxyModule(mlp->module)) { |
| found = PR_TRUE; |
| break; |
| } |
| } |
| |
| SECMOD_ReleaseReadLock(lock); |
| return found; |
| } |
| |
| /********************************************************************** |
| * |
| * A d d M o d u l e |
| * |
| * Add the named module, with the given library file, ciphers, and |
| * default mechanism flags |
| */ |
| Error |
| AddModule(char *moduleName, char *libFile, char *cipherString, |
| char *mechanismString, char *modparms) |
| { |
| unsigned long ciphers; |
| unsigned long mechanisms; |
| SECStatus status; |
| |
| mechanisms = |
| getFlagsFromString(mechanismString, mechanismStrings, |
| numMechanismStrings); |
| ciphers = |
| getFlagsFromString(cipherString, cipherStrings, numCipherStrings); |
| |
| status = |
| SECMOD_AddNewModuleEx(moduleName, libFile, |
| SECMOD_PubMechFlagstoInternal(mechanisms), |
| SECMOD_PubCipherFlagstoInternal(ciphers), |
| modparms, NULL); |
| |
| if (status != SECSuccess) { |
| char *errtxt = NULL; |
| PRInt32 copied = 0; |
| if (PR_GetErrorTextLength()) { |
| errtxt = PR_Malloc(PR_GetErrorTextLength() + 1); |
| copied = PR_GetErrorText(errtxt); |
| } |
| if (copied && errtxt) { |
| PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR], |
| moduleName, errtxt); |
| PR_Free(errtxt); |
| } else { |
| PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR], |
| moduleName, SECU_Strerror(PORT_GetError())); |
| } |
| return ADD_MODULE_FAILED_ERR; |
| } else { |
| PR_fprintf(PR_STDOUT, msgStrings[ADD_MODULE_SUCCESS_MSG], moduleName); |
| return SUCCESS; |
| } |
| } |
| |
| /*********************************************************************** |
| * |
| * D e l e t e M o d u l e |
| * |
| * Deletes the named module from the database. |
| */ |
| Error |
| DeleteModule(char *moduleName) |
| { |
| SECStatus status; |
| int type; |
| |
| status = SECMOD_DeleteModule(moduleName, &type); |
| |
| if (status != SECSuccess) { |
| if (type == SECMOD_FIPS || type == SECMOD_INTERNAL) { |
| PR_fprintf(PR_STDERR, errStrings[DELETE_INTERNAL_ERR]); |
| return DELETE_INTERNAL_ERR; |
| } else { |
| PR_fprintf(PR_STDERR, errStrings[DELETE_FAILED_ERR], moduleName); |
| return DELETE_FAILED_ERR; |
| } |
| } |
| |
| PR_fprintf(PR_STDOUT, msgStrings[DELETE_SUCCESS_MSG], moduleName); |
| return SUCCESS; |
| } |
| |
| /************************************************************************ |
| * |
| * R a w L i s t M o d u l e s |
| * |
| * Lists all the modules in the database, along with their slots and tokens. |
| */ |
| Error |
| RawListModule(char *modulespec) |
| { |
| SECMODModule *module; |
| char **moduleSpecList; |
| |
| module = SECMOD_LoadModule(modulespec, NULL, PR_FALSE); |
| if (module == NULL) { |
| /* handle error */ |
| return NO_SUCH_MODULE_ERR; |
| } |
| |
| moduleSpecList = SECMOD_GetModuleSpecList(module); |
| if (!moduleSpecList || !moduleSpecList[0]) { |
| SECU_PrintError("modutil", |
| "no specs in secmod DB"); |
| return NO_SUCH_MODULE_ERR; |
| } |
| |
| for (; *moduleSpecList; moduleSpecList++) { |
| printf("%s\n\n", *moduleSpecList); |
| } |
| |
| return SUCCESS; |
| } |
| |
| Error |
| RawAddModule(char *dbmodulespec, char *modulespec) |
| { |
| SECMODModule *module; |
| SECMODModule *dbmodule; |
| |
| dbmodule = SECMOD_LoadModule(dbmodulespec, NULL, PR_TRUE); |
| if (dbmodule == NULL) { |
| /* handle error */ |
| return NO_SUCH_MODULE_ERR; |
| } |
| |
| module = SECMOD_LoadModule(modulespec, dbmodule, PR_FALSE); |
| if (module == NULL) { |
| /* handle error */ |
| return NO_SUCH_MODULE_ERR; |
| } |
| |
| if (SECMOD_UpdateModule(module) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec); |
| return UPDATE_MOD_FAILED_ERR; |
| } |
| return SUCCESS; |
| } |
| |
| static void |
| printModule(SECMODModule *module, int *count) |
| { |
| int slotCount = module->loaded ? module->slotCount : 0; |
| char *modUri; |
| int i; |
| |
| if ((*count)++) { |
| PR_fprintf(PR_STDOUT, "\n"); |
| } |
| PR_fprintf(PR_STDOUT, "%3d. %s\n", *count, module->commonName); |
| |
| if (module->dllName) { |
| PR_fprintf(PR_STDOUT, "\tlibrary name: %s\n", module->dllName); |
| } |
| |
| modUri = PK11_GetModuleURI(module); |
| if (modUri) { |
| PR_fprintf(PR_STDOUT, "\t uri: %s\n", modUri); |
| PORT_Free(modUri); |
| } |
| if (slotCount == 0) { |
| PR_fprintf(PR_STDOUT, |
| "\t slots: There are no slots attached to this module\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, "\t slots: %d slot%s attached\n", |
| slotCount, (slotCount == 1 ? "" : "s")); |
| } |
| |
| if (module->loaded == 0) { |
| PR_fprintf(PR_STDOUT, "\tstatus: Not loaded\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, "\tstatus: loaded\n"); |
| } |
| |
| /* Print slot and token names */ |
| for (i = 0; i < slotCount; i++) { |
| PK11SlotInfo *slot = module->slots[i]; |
| char *tokenUri = PK11_GetTokenURI(slot); |
| PR_fprintf(PR_STDOUT, "\n"); |
| PR_fprintf(PR_STDOUT, "\t slot: %s\n", PK11_GetSlotName(slot)); |
| PR_fprintf(PR_STDOUT, "\ttoken: %s\n", PK11_GetTokenName(slot)); |
| PR_fprintf(PR_STDOUT, "\t uri: %s\n", tokenUri); |
| PORT_Free(tokenUri); |
| } |
| return; |
| } |
| |
| /************************************************************************ |
| * |
| * L i s t M o d u l e s |
| * |
| * Lists all the modules in the database, along with their slots and tokens. |
| */ |
| Error |
| ListModules() |
| { |
| SECMODListLock *lock; |
| SECMODModuleList *list; |
| SECMODModuleList *deadlist; |
| SECMODModuleList *mlp; |
| Error ret = UNSPECIFIED_ERR; |
| int count = 0; |
| |
| lock = SECMOD_GetDefaultModuleListLock(); |
| if (!lock) { |
| PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]); |
| return NO_LIST_LOCK_ERR; |
| } |
| |
| SECMOD_GetReadLock(lock); |
| |
| list = SECMOD_GetDefaultModuleList(); |
| deadlist = SECMOD_GetDeadModuleList(); |
| if (!list && !deadlist) { |
| PR_fprintf(PR_STDERR, errStrings[NO_MODULE_LIST_ERR]); |
| ret = NO_MODULE_LIST_ERR; |
| goto loser; |
| } |
| |
| PR_fprintf(PR_STDOUT, |
| "\nListing of PKCS #11 Modules\n" |
| "-----------------------------------------------------------\n"); |
| |
| for (mlp = list; mlp != NULL; mlp = mlp->next) { |
| printModule(mlp->module, &count); |
| } |
| for (mlp = deadlist; mlp != NULL; mlp = mlp->next) { |
| printModule(mlp->module, &count); |
| } |
| |
| PR_fprintf(PR_STDOUT, |
| "-----------------------------------------------------------\n"); |
| |
| ret = SUCCESS; |
| |
| loser: |
| SECMOD_ReleaseReadLock(lock); |
| return ret; |
| } |
| |
| /* Strings describing PK11DisableReasons */ |
| static char *disableReasonStr[] = { |
| "no reason", |
| "user disabled", |
| "could not initialize token", |
| "could not verify token", |
| "token not present" |
| }; |
| static size_t numDisableReasonStr = |
| sizeof(disableReasonStr) / sizeof(disableReasonStr[0]); |
| |
| /*********************************************************************** |
| * |
| * L i s t M o d u l e |
| * |
| * Lists detailed information about the named module. |
| */ |
| Error |
| ListModule(char *moduleName) |
| { |
| SECMODModule *module = NULL; |
| PK11SlotInfo *slot; |
| int slotnum; |
| CK_INFO modinfo; |
| CK_SLOT_INFO slotinfo; |
| CK_TOKEN_INFO tokeninfo; |
| char *ciphers, *mechanisms; |
| size_t reasonIdx; |
| Error rv = SUCCESS; |
| |
| if (!moduleName) { |
| return SUCCESS; |
| } |
| |
| module = SECMOD_FindModule(moduleName); |
| if (!module) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName); |
| rv = NO_SUCH_MODULE_ERR; |
| goto loser; |
| } |
| |
| if ((module->loaded) && |
| (PK11_GetModInfo(module, &modinfo) != SECSuccess)) { |
| PR_fprintf(PR_STDERR, errStrings[MOD_INFO_ERR], moduleName); |
| rv = MOD_INFO_ERR; |
| goto loser; |
| } |
| |
| /* Module info */ |
| PR_fprintf(PR_STDOUT, |
| "\n-----------------------------------------------------------\n"); |
| PR_fprintf(PR_STDOUT, "Name: %s\n", module->commonName); |
| if (module->internal || !module->dllName) { |
| PR_fprintf(PR_STDOUT, "Library file: **Internal ONLY module**\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, "Library file: %s\n", module->dllName); |
| } |
| |
| if (module->loaded) { |
| PR_fprintf(PR_STDOUT, "Manufacturer: %.32s\n", modinfo.manufacturerID); |
| PR_fprintf(PR_STDOUT, "Description: %.32s\n", modinfo.libraryDescription); |
| PR_fprintf(PR_STDOUT, "PKCS #11 Version %d.%d\n", |
| modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor); |
| PR_fprintf(PR_STDOUT, "Library Version: %d.%d\n", |
| modinfo.libraryVersion.major, modinfo.libraryVersion.minor); |
| } else { |
| PR_fprintf(PR_STDOUT, "* Module not loaded\n"); |
| } |
| /* Get cipher and mechanism flags */ |
| ciphers = getStringFromFlags(module->ssl[0], cipherStrings, |
| numCipherStrings); |
| if (ciphers[0] == '\0') { |
| ciphers = "None"; |
| } |
| PR_fprintf(PR_STDOUT, "Cipher Enable Flags: %s\n", ciphers); |
| mechanisms = NULL; |
| if (module->slotCount > 0) { |
| mechanisms = getStringFromFlags( |
| PK11_GetDefaultFlags(module->slots[0]), |
| mechanismStrings, numMechanismStrings); |
| } |
| if ((mechanisms == NULL) || (mechanisms[0] == '\0')) { |
| mechanisms = "None"; |
| } |
| PR_fprintf(PR_STDOUT, "Default Mechanism Flags: %s\n", mechanisms); |
| |
| #define PAD " " |
| |
| /* Loop over each slot */ |
| for (slotnum = 0; slotnum < module->slotCount; slotnum++) { |
| slot = module->slots[slotnum]; |
| if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[SLOT_INFO_ERR], |
| PK11_GetSlotName(slot)); |
| rv = SLOT_INFO_ERR; |
| continue; |
| } |
| |
| /* Slot Info */ |
| PR_fprintf(PR_STDOUT, "\n" PAD "Slot: %s\n", PK11_GetSlotName(slot)); |
| mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot), |
| mechanismStrings, numMechanismStrings); |
| if (mechanisms[0] == '\0') { |
| mechanisms = "None"; |
| } |
| PR_fprintf(PR_STDOUT, PAD "Slot Mechanism Flags: %s\n", mechanisms); |
| PR_fprintf(PR_STDOUT, PAD "Manufacturer: %.32s\n", |
| slotinfo.manufacturerID); |
| if (PK11_IsHW(slot)) { |
| PR_fprintf(PR_STDOUT, PAD "Type: Hardware\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, PAD "Type: Software\n"); |
| } |
| PR_fprintf(PR_STDOUT, PAD "Version Number: %d.%d\n", |
| slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor); |
| PR_fprintf(PR_STDOUT, PAD "Firmware Version: %d.%d\n", |
| slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor); |
| if (PK11_IsDisabled(slot)) { |
| reasonIdx = PK11_GetDisabledReason(slot); |
| if (reasonIdx < numDisableReasonStr) { |
| PR_fprintf(PR_STDOUT, PAD "Status: DISABLED (%s)\n", |
| disableReasonStr[reasonIdx]); |
| } else { |
| PR_fprintf(PR_STDOUT, PAD "Status: DISABLED\n"); |
| } |
| } else { |
| PR_fprintf(PR_STDOUT, PAD "Status: Enabled\n"); |
| } |
| |
| if (PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[TOKEN_INFO_ERR], |
| PK11_GetTokenName(slot)); |
| rv = TOKEN_INFO_ERR; |
| continue; |
| } |
| |
| /* Token Info */ |
| PR_fprintf(PR_STDOUT, PAD "Token Name: %.32s\n", |
| tokeninfo.label); |
| PR_fprintf(PR_STDOUT, PAD "Token Manufacturer: %.32s\n", |
| tokeninfo.manufacturerID); |
| PR_fprintf(PR_STDOUT, PAD "Token Model: %.16s\n", tokeninfo.model); |
| PR_fprintf(PR_STDOUT, PAD "Token Serial Number: %.16s\n", |
| tokeninfo.serialNumber); |
| PR_fprintf(PR_STDOUT, PAD "Token Version: %d.%d\n", |
| tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor); |
| PR_fprintf(PR_STDOUT, PAD "Token Firmware Version: %d.%d\n", |
| tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor); |
| if (tokeninfo.flags & CKF_WRITE_PROTECTED) { |
| PR_fprintf(PR_STDOUT, PAD "Access: Write Protected\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, PAD "Access: NOT Write Protected\n"); |
| } |
| if (tokeninfo.flags & CKF_LOGIN_REQUIRED) { |
| PR_fprintf(PR_STDOUT, PAD "Login Type: Login required\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, PAD |
| "Login Type: Public (no login required)\n"); |
| } |
| if (tokeninfo.flags & CKF_USER_PIN_INITIALIZED) { |
| PR_fprintf(PR_STDOUT, PAD "User Pin: Initialized\n"); |
| } else { |
| PR_fprintf(PR_STDOUT, PAD "User Pin: NOT Initialized\n"); |
| } |
| } |
| PR_fprintf(PR_STDOUT, |
| "\n-----------------------------------------------------------\n"); |
| loser: |
| if (module) { |
| SECMOD_DestroyModule(module); |
| } |
| return rv; |
| } |
| |
| /************************************************************************ |
| * |
| * I n i t P W |
| */ |
| Error |
| InitPW(void) |
| { |
| PK11SlotInfo *slot; |
| Error ret = UNSPECIFIED_ERR; |
| |
| slot = PK11_GetInternalKeySlot(); |
| if (!slot) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], "internal"); |
| return NO_SUCH_TOKEN_ERR; |
| } |
| |
| /* Set the initial password to empty */ |
| if (PK11_NeedUserInit(slot)) { |
| if (PK11_InitPin(slot, NULL, "") != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[INITPW_FAILED_ERR]); |
| ret = INITPW_FAILED_ERR; |
| goto loser; |
| } |
| } |
| |
| ret = SUCCESS; |
| |
| loser: |
| PK11_FreeSlot(slot); |
| |
| return ret; |
| } |
| |
| /************************************************************************ |
| * |
| * C h a n g e P W |
| */ |
| Error |
| ChangePW(char *tokenName, char *pwFile, char *newpwFile) |
| { |
| char *oldpw = NULL, *newpw = NULL, *newpw2 = NULL; |
| PK11SlotInfo *slot; |
| Error ret = UNSPECIFIED_ERR; |
| PRBool matching; |
| |
| slot = PK11_FindSlotByName(tokenName); |
| if (!slot) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], tokenName); |
| return NO_SUCH_TOKEN_ERR; |
| } |
| |
| /* Get old password */ |
| if (!PK11_NeedUserInit(slot)) { |
| if (pwFile) { |
| oldpw = SECU_FilePasswd(NULL, PR_FALSE, pwFile); |
| if (PK11_CheckUserPassword(slot, oldpw) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[BAD_PW_ERR]); |
| ret = BAD_PW_ERR; |
| goto loser; |
| } |
| } else if (PK11_NeedLogin(slot)) { |
| for (matching = PR_FALSE; !matching;) { |
| oldpw = SECU_GetPasswordString(NULL, "Enter old password: "); |
| if (PK11_CheckUserPassword(slot, oldpw) == SECSuccess) { |
| matching = PR_TRUE; |
| } else { |
| PR_fprintf(PR_STDOUT, msgStrings[BAD_PW_MSG]); |
| } |
| } |
| } |
| } |
| |
| /* Get new password */ |
| if (newpwFile) { |
| newpw = SECU_FilePasswd(NULL, PR_FALSE, newpwFile); |
| } else { |
| for (matching = PR_FALSE; !matching;) { |
| newpw = SECU_GetPasswordString(NULL, "Enter new password: "); |
| newpw2 = SECU_GetPasswordString(NULL, "Re-enter new password: "); |
| if (strcmp(newpw, newpw2)) { |
| PR_fprintf(PR_STDOUT, msgStrings[PW_MATCH_MSG]); |
| PORT_ZFree(newpw, strlen(newpw)); |
| PORT_ZFree(newpw2, strlen(newpw2)); |
| } else { |
| matching = PR_TRUE; |
| } |
| } |
| } |
| |
| /* Change the password */ |
| if (PK11_NeedUserInit(slot)) { |
| if (PK11_InitPin(slot, NULL /*ssopw*/, newpw) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName); |
| ret = CHANGEPW_FAILED_ERR; |
| goto loser; |
| } |
| } else { |
| if (PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName); |
| ret = CHANGEPW_FAILED_ERR; |
| goto loser; |
| } |
| } |
| |
| PR_fprintf(PR_STDOUT, msgStrings[CHANGEPW_SUCCESS_MSG], tokenName); |
| ret = SUCCESS; |
| |
| loser: |
| if (oldpw) { |
| PORT_ZFree(oldpw, strlen(oldpw)); |
| } |
| if (newpw) { |
| PORT_ZFree(newpw, strlen(newpw)); |
| } |
| if (newpw2) { |
| PORT_ZFree(newpw2, strlen(newpw2)); |
| } |
| PK11_FreeSlot(slot); |
| |
| return ret; |
| } |
| |
| /*********************************************************************** |
| * |
| * E n a b l e M o d u l e |
| * |
| * If enable==PR_TRUE, enables the module or slot. |
| * If enable==PR_FALSE, disables the module or slot. |
| * moduleName is the name of the module. |
| * slotName is the name of the slot. It is optional. |
| */ |
| Error |
| EnableModule(char *moduleName, char *slotName, PRBool enable) |
| { |
| int i; |
| SECMODModule *module = NULL; |
| PK11SlotInfo *slot = NULL; |
| PRBool found = PR_FALSE; |
| Error rv; |
| |
| module = SECMOD_FindModule(moduleName); |
| if (!module) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName); |
| rv = NO_SUCH_MODULE_ERR; |
| goto loser; |
| } |
| |
| for (i = 0; i < module->slotCount; i++) { |
| slot = module->slots[i]; |
| if (slotName && strcmp(PK11_GetSlotName(slot), slotName)) { |
| /* Not the right slot */ |
| continue; |
| } |
| if (enable) { |
| if (!PK11_UserEnableSlot(slot)) { |
| PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR], |
| "enable", PK11_GetSlotName(slot)); |
| rv = ENABLE_FAILED_ERR; |
| goto loser; |
| } else { |
| found = PR_TRUE; |
| PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG], |
| PK11_GetSlotName(slot), "enabled"); |
| } |
| } else { |
| if (!PK11_UserDisableSlot(slot)) { |
| PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR], |
| "disable", PK11_GetSlotName(slot)); |
| rv = ENABLE_FAILED_ERR; |
| goto loser; |
| } else { |
| found = PR_TRUE; |
| PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG], |
| PK11_GetSlotName(slot), "disabled"); |
| } |
| } |
| } |
| |
| if (slotName && !found) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName); |
| rv = NO_SUCH_SLOT_ERR; |
| goto loser; |
| } |
| |
| /* Delete and re-add module to save changes */ |
| if (SECMOD_UpdateModule(module) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], moduleName); |
| rv = UPDATE_MOD_FAILED_ERR; |
| goto loser; |
| } |
| |
| rv = SUCCESS; |
| loser: |
| if (module) { |
| SECMOD_DestroyModule(module); |
| } |
| return rv; |
| } |
| |
| /************************************************************************* |
| * |
| * S e t D e f a u l t M o d u l e |
| * |
| */ |
| Error |
| SetDefaultModule(char *moduleName, char *slotName, char *mechanisms) |
| { |
| SECMODModule *module = NULL; |
| PK11SlotInfo *slot; |
| int s, i; |
| unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings, |
| numMechanismStrings); |
| PRBool found = PR_FALSE; |
| Error errcode = UNSPECIFIED_ERR; |
| |
| mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags); |
| |
| module = SECMOD_FindModule(moduleName); |
| if (!module) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName); |
| errcode = NO_SUCH_MODULE_ERR; |
| goto loser; |
| } |
| |
| /* Go through each slot */ |
| for (s = 0; s < module->slotCount; s++) { |
| slot = module->slots[s]; |
| |
| if ((slotName != NULL) && |
| !((strcmp(PK11_GetSlotName(slot), slotName) == 0) || |
| (strcmp(PK11_GetTokenName(slot), slotName) == 0))) { |
| /* we are only interested in changing the one slot */ |
| continue; |
| } |
| |
| found = PR_TRUE; |
| |
| /* Go through each mechanism */ |
| for (i = 0; i < pk11_DefaultArraySize; i++) { |
| if (pk11_DefaultArray[i].flag & mechFlags) { |
| /* Enable this default mechanism */ |
| PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]), |
| PR_TRUE); |
| } |
| } |
| } |
| if (slotName && !found) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName); |
| errcode = NO_SUCH_SLOT_ERR; |
| goto loser; |
| } |
| |
| /* Delete and re-add module to save changes */ |
| if (SECMOD_UpdateModule(module) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[DEFAULT_FAILED_ERR], |
| moduleName); |
| errcode = DEFAULT_FAILED_ERR; |
| goto loser; |
| } |
| |
| PR_fprintf(PR_STDOUT, msgStrings[DEFAULT_SUCCESS_MSG]); |
| |
| errcode = SUCCESS; |
| loser: |
| if (module) { |
| SECMOD_DestroyModule(module); |
| } |
| return errcode; |
| } |
| |
| /************************************************************************ |
| * |
| * U n s e t D e f a u l t M o d u l e |
| */ |
| Error |
| UnsetDefaultModule(char *moduleName, char *slotName, char *mechanisms) |
| { |
| SECMODModule *module = NULL; |
| PK11SlotInfo *slot; |
| int s, i; |
| unsigned long mechFlags = getFlagsFromString(mechanisms, |
| mechanismStrings, numMechanismStrings); |
| PRBool found = PR_FALSE; |
| Error rv; |
| |
| mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags); |
| |
| module = SECMOD_FindModule(moduleName); |
| if (!module) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName); |
| rv = NO_SUCH_MODULE_ERR; |
| goto loser; |
| } |
| |
| for (s = 0; s < module->slotCount; s++) { |
| slot = module->slots[s]; |
| if ((slotName != NULL) && |
| !((strcmp(PK11_GetSlotName(slot), slotName) == 0) || |
| (strcmp(PK11_GetTokenName(slot), slotName) == 0))) { |
| /* we are only interested in changing the one slot */ |
| continue; |
| } |
| for (i = 0; i < pk11_DefaultArraySize; i++) { |
| if (pk11_DefaultArray[i].flag & mechFlags) { |
| PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]), |
| PR_FALSE); |
| } |
| } |
| } |
| if (slotName && !found) { |
| PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName); |
| rv = NO_SUCH_SLOT_ERR; |
| goto loser; |
| } |
| |
| /* Delete and re-add module to save changes */ |
| if (SECMOD_UpdateModule(module) != SECSuccess) { |
| PR_fprintf(PR_STDERR, errStrings[UNDEFAULT_FAILED_ERR], |
| moduleName); |
| rv = UNDEFAULT_FAILED_ERR; |
| goto loser; |
| } |
| |
| PR_fprintf(PR_STDOUT, msgStrings[UNDEFAULT_SUCCESS_MSG]); |
| rv = SUCCESS; |
| loser: |
| if (module) { |
| SECMOD_DestroyModule(module); |
| } |
| return rv; |
| } |