summaryrefslogtreecommitdiffstats
path: root/security/nss/cmd/modutil/pk11.c
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-21 11:44:51 +0000
commit9e3c08db40b8916968b9f30096c7be3f00ce9647 (patch)
treea68f146d7fa01f0134297619fbe7e33db084e0aa /security/nss/cmd/modutil/pk11.c
parentInitial commit. (diff)
downloadthunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.tar.xz
thunderbird-9e3c08db40b8916968b9f30096c7be3f00ce9647.zip
Adding upstream version 1:115.7.0.upstream/1%115.7.0upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'security/nss/cmd/modutil/pk11.c')
-rw-r--r--security/nss/cmd/modutil/pk11.c1050
1 files changed, 1050 insertions, 0 deletions
diff --git a/security/nss/cmd/modutil/pk11.c b/security/nss/cmd/modutil/pk11.c
new file mode 100644
index 0000000000..6d17a33657
--- /dev/null
+++ b/security/nss/cmd/modutil/pk11.c
@@ -0,0 +1,1050 @@
+/* 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;
+}