gecko/security/nss/cmd/modutil/pk11.c

984 lines
27 KiB
C
Raw Normal View History

2008-06-06 05:40:11 -07:00
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is the Netscape security libraries.
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1994-2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/* To edit this file, set TABSTOPS to 4 spaces.
* This is not the normal NSS convention.
*/
#include "modutil.h"
/* #include "secmodti.h" */
#include "pk11func.h"
static PK11DefaultArrayEntry *pk11_DefaultArray = NULL;
static int pk11_DefaultArraySize = 0;
/*************************************************************************
*
* 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;
const unsigned long mask;
} MaskString;
static const MaskString mechanismStrings[] = {
{"RSA", PUBLIC_MECH_RSA_FLAG},
{"DSA", PUBLIC_MECH_DSA_FLAG},
{"RC2", PUBLIC_MECH_RC2_FLAG},
{"RC4", PUBLIC_MECH_RC4_FLAG},
{"RC5", PUBLIC_MECH_RC5_FLAG},
{"DES", PUBLIC_MECH_DES_FLAG},
{"DH", PUBLIC_MECH_DH_FLAG},
{"FORTEZZA", PUBLIC_MECH_FORTEZZA_FLAG},
{"SHA1", PUBLIC_MECH_SHA1_FLAG},
{"MD5", PUBLIC_MECH_MD5_FLAG},
{"MD2", PUBLIC_MECH_MD2_FLAG},
{"SSL", PUBLIC_MECH_SSL_FLAG},
{"TLS", PUBLIC_MECH_TLS_FLAG},
{"AES", PUBLIC_MECH_AES_FLAG},
{"CAMELLIA", PUBLIC_MECH_CAMELLIA_FLAG},
{"SHA256", PUBLIC_MECH_SHA256_FLAG},
{"SHA512", PUBLIC_MECH_SHA512_FLAG},
{"RANDOM", PUBLIC_MECH_RANDOM_FLAG},
{"FRIENDLY", PUBLIC_MECH_FRIENDLY_FLAG}
};
static const int numMechanismStrings =
sizeof(mechanismStrings) / sizeof(mechanismStrings[0]);
static const MaskString cipherStrings[] = {
{"FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG}
};
static const int numCipherStrings =
sizeof(cipherStrings) / sizeof(cipherStrings[0]);
/* Maximum length of a colon-separated list of all the strings in an
* array. */
#define MAX_STRING_LIST_LEN 240 /* or less */
/************************************************************************
*
* 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;
}
/**********************************************************************
*
* 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());
copied = PR_GetErrorText(errtxt);
}
if (copied && errtxt) {
PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR],
2008-06-06 05:40:11 -07:00
moduleName, errtxt);
PR_Free(errtxt);
} else {
PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR],
moduleName, SECU_Strerror(PORT_GetError()));
2008-06-06 05:40:11 -07:00
}
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;
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);
}
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];
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));
}
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 int 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;
PK11DisableReasons reason;
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)) {
reason = PK11_GetDisabledReason(slot);
if(reason < numDisableReasonStr) {
PR_fprintf(PR_STDOUT, PAD"Status: DISABLED (%s)\n",
disableReasonStr[reason]);
} 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;
}
/************************************************************************
*
* 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 {
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]);
} 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) {
memset(oldpw, 0, strlen(oldpw));
PORT_Free(oldpw);
}
if(newpw) {
memset(newpw, 0, strlen(newpw));
PORT_Free(newpw);
}
if(newpw2) {
memset(newpw2, 0, strlen(newpw2));
PORT_Free(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;
if (pk11_DefaultArray == NULL) {
pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
if (pk11_DefaultArray == NULL) {
/* should assert. This shouldn't happen */
goto loser;
}
}
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;
if (pk11_DefaultArray == NULL) {
pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
if (pk11_DefaultArray == NULL) {
/* should assert. This shouldn't happen */
rv = UNSPECIFIED_ERR;
goto loser;
}
}
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;
}