Import from 1.9a8 tarball
[mozilla-nss.git] / security / nss / cmd / modutil / pk11.c
blob6988931a8e796a4216788eff37e6fe5b799bdfa6
1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
12 * License.
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
21 * Contributor(s):
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 /* To edit this file, set TABSTOPS to 4 spaces.
38 * This is not the normal NSS convention.
41 #include "modutil.h"
42 /* #include "secmodti.h" */
43 #include "pk11func.h"
45 static PK11DefaultArrayEntry *pk11_DefaultArray = NULL;
46 static int pk11_DefaultArraySize = 0;
48 /*************************************************************************
50 * F i p s M o d e
51 * If arg=="true", enable FIPS mode on the internal module. If arg=="false",
52 * disable FIPS mode on the internal module.
54 Error
55 FipsMode(char *arg)
57 char *internal_name;
59 if(!PORT_Strcasecmp(arg, "true")) {
60 if(!PK11_IsFIPS()) {
61 internal_name = PR_smprintf("%s",
62 SECMOD_GetInternalModule()->commonName);
63 if(SECMOD_DeleteInternalModule(internal_name) != SECSuccess) {
64 PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError()));
65 PR_smprintf_free(internal_name);
66 PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
67 return FIPS_SWITCH_FAILED_ERR;
69 PR_smprintf_free(internal_name);
70 if (!PK11_IsFIPS()) {
71 PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
72 return FIPS_SWITCH_FAILED_ERR;
74 PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
75 } else {
76 PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_ON_ERR]);
77 return FIPS_ALREADY_ON_ERR;
79 } else if(!PORT_Strcasecmp(arg, "false")) {
80 if(PK11_IsFIPS()) {
81 internal_name = PR_smprintf("%s",
82 SECMOD_GetInternalModule()->commonName);
83 if(SECMOD_DeleteInternalModule(internal_name) != SECSuccess) {
84 PR_fprintf(PR_STDERR, "%s\n", SECU_Strerror(PORT_GetError()));
85 PR_smprintf_free(internal_name);
86 PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
87 return FIPS_SWITCH_FAILED_ERR;
89 PR_smprintf_free(internal_name);
90 if (PK11_IsFIPS()) {
91 PR_fprintf(PR_STDERR, errStrings[FIPS_SWITCH_FAILED_ERR]);
92 return FIPS_SWITCH_FAILED_ERR;
94 PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
95 } else {
96 PR_fprintf(PR_STDERR, errStrings[FIPS_ALREADY_OFF_ERR]);
97 return FIPS_ALREADY_OFF_ERR;
99 } else {
100 PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
101 return INVALID_FIPS_ARG;
104 return SUCCESS;
107 /*************************************************************************
109 * C h k F i p s M o d e
110 * If arg=="true", verify FIPS mode is enabled on the internal module.
111 * If arg=="false", verify FIPS mode is disabled on the internal module.
113 Error
114 ChkFipsMode(char *arg)
116 if(!PORT_Strcasecmp(arg, "true")) {
117 if (PK11_IsFIPS()) {
118 PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
119 } else {
120 PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
121 return FIPS_SWITCH_FAILED_ERR;
124 } else if(!PORT_Strcasecmp(arg, "false")) {
125 if(!PK11_IsFIPS()) {
126 PR_fprintf(PR_STDOUT, msgStrings[FIPS_DISABLED_MSG]);
127 } else {
128 PR_fprintf(PR_STDOUT, msgStrings[FIPS_ENABLED_MSG]);
129 return FIPS_SWITCH_FAILED_ERR;
131 } else {
132 PR_fprintf(PR_STDERR, errStrings[INVALID_FIPS_ARG]);
133 return INVALID_FIPS_ARG;
136 return SUCCESS;
139 /************************************************************************
140 * Cipher and Mechanism name-bitmask translation tables
143 typedef struct {
144 const char *name;
145 const unsigned long mask;
146 } MaskString;
148 static const MaskString mechanismStrings[] = {
149 {"RSA", PUBLIC_MECH_RSA_FLAG},
150 {"DSA", PUBLIC_MECH_DSA_FLAG},
151 {"RC2", PUBLIC_MECH_RC2_FLAG},
152 {"RC4", PUBLIC_MECH_RC4_FLAG},
153 {"RC5", PUBLIC_MECH_RC5_FLAG},
154 {"DES", PUBLIC_MECH_DES_FLAG},
155 {"DH", PUBLIC_MECH_DH_FLAG},
156 {"FORTEZZA", PUBLIC_MECH_FORTEZZA_FLAG},
157 {"SHA1", PUBLIC_MECH_SHA1_FLAG},
158 {"MD5", PUBLIC_MECH_MD5_FLAG},
159 {"MD2", PUBLIC_MECH_MD2_FLAG},
160 {"SSL", PUBLIC_MECH_SSL_FLAG},
161 {"TLS", PUBLIC_MECH_TLS_FLAG},
162 {"AES", PUBLIC_MECH_AES_FLAG},
163 {"CAMELLIA", PUBLIC_MECH_CAMELLIA_FLAG},
164 {"SHA256", PUBLIC_MECH_SHA256_FLAG},
165 {"SHA512", PUBLIC_MECH_SHA512_FLAG},
166 {"RANDOM", PUBLIC_MECH_RANDOM_FLAG},
167 {"FRIENDLY", PUBLIC_MECH_FRIENDLY_FLAG}
169 static const int numMechanismStrings =
170 sizeof(mechanismStrings) / sizeof(mechanismStrings[0]);
172 static const MaskString cipherStrings[] = {
173 {"FORTEZZA", PUBLIC_CIPHER_FORTEZZA_FLAG}
175 static const int numCipherStrings =
176 sizeof(cipherStrings) / sizeof(cipherStrings[0]);
178 /* Maximum length of a colon-separated list of all the strings in an
179 * array. */
180 #define MAX_STRING_LIST_LEN 240 /* or less */
182 /************************************************************************
184 * g e t F l a g s F r o m S t r i n g
186 * Parses a mechanism list passed on the command line and converts it
187 * to an unsigned long bitmask.
188 * string is a colon-separated string of constants
189 * array is an array of MaskStrings.
190 * elements is the number of elements in array.
192 static unsigned long
193 getFlagsFromString(char *string, const MaskString array[], int elements)
195 unsigned long ret = 0;
196 short i = 0;
197 char *cp;
198 char *buf;
199 char *end;
201 if(!string || !string[0]) {
202 return ret;
205 /* Make a temporary copy of the string */
206 buf = PR_Malloc(strlen(string)+1);
207 if(!buf) {
208 out_of_memory();
210 strcpy(buf, string);
212 /* Look at each element of the list passed in */
213 for(cp=buf; cp && *cp; cp = (end ? end+1 : NULL) ) {
214 /* Look at the string up to the next colon */
215 end = strchr(cp, ':');
216 if(end) {
217 *end = '\0';
220 /* Find which element this is */
221 for(i=0; i < elements; i++) {
222 if( !PORT_Strcasecmp(cp, array[i].name) ) {
223 break;
226 if(i == elements) {
227 /* Skip a bogus string, but print a warning message */
228 PR_fprintf(PR_STDERR, errStrings[INVALID_CONSTANT_ERR], cp);
229 continue;
231 ret |= array[i].mask;
234 PR_Free(buf);
235 return ret;
238 /**********************************************************************
240 * g e t S t r i n g F r o m F l a g s
242 * The return string's memory is owned by this function. Copy it
243 * if you need it permanently or you want to change it.
245 static char *
246 getStringFromFlags(unsigned long flags, const MaskString array[], int elements)
248 static char buf[MAX_STRING_LIST_LEN];
249 int i;
250 int count=0;
252 buf[0] = '\0';
253 for(i=0; i<elements; i++) {
254 if( flags & array[i].mask ) {
255 ++count;
256 if(count!=1) {
257 strcat(buf, ":");
259 strcat(buf, array[i].name);
262 return buf;
265 /**********************************************************************
267 * A d d M o d u l e
269 * Add the named module, with the given library file, ciphers, and
270 * default mechanism flags
272 Error
273 AddModule(char *moduleName, char *libFile, char *cipherString,
274 char *mechanismString, char* modparms)
276 unsigned long ciphers;
277 unsigned long mechanisms;
278 SECStatus status;
280 mechanisms =
281 getFlagsFromString(mechanismString, mechanismStrings,
282 numMechanismStrings);
283 ciphers =
284 getFlagsFromString(cipherString, cipherStrings, numCipherStrings);
286 status =
287 SECMOD_AddNewModuleEx(moduleName, libFile,
288 SECMOD_PubMechFlagstoInternal(mechanisms),
289 SECMOD_PubCipherFlagstoInternal(ciphers),
290 modparms, NULL );
292 if(status != SECSuccess) {
293 char* errtxt=NULL;
294 PRInt32 copied = 0;
295 if (PR_GetErrorTextLength()) {
296 errtxt = PR_Malloc(PR_GetErrorTextLength());
297 copied = PR_GetErrorText(errtxt);
299 if (copied && errtxt) {
300 PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_STATUS_ERR],
301 moduleName, errtxt);
302 PR_Free(errtxt);
303 } else {
304 PR_fprintf(PR_STDERR, errStrings[ADD_MODULE_FAILED_ERR],
305 moduleName);
307 return ADD_MODULE_FAILED_ERR;
308 } else {
309 PR_fprintf(PR_STDOUT, msgStrings[ADD_MODULE_SUCCESS_MSG], moduleName);
310 return SUCCESS;
314 /***********************************************************************
316 * D e l e t e M o d u l e
318 * Deletes the named module from the database.
320 Error
321 DeleteModule(char *moduleName)
323 SECStatus status;
324 int type;
326 status = SECMOD_DeleteModule(moduleName, &type);
328 if(status != SECSuccess) {
329 if(type == SECMOD_FIPS || type == SECMOD_INTERNAL) {
330 PR_fprintf(PR_STDERR, errStrings[DELETE_INTERNAL_ERR]);
331 return DELETE_INTERNAL_ERR;
332 } else {
333 PR_fprintf(PR_STDERR, errStrings[DELETE_FAILED_ERR], moduleName);
334 return DELETE_FAILED_ERR;
338 PR_fprintf(PR_STDOUT, msgStrings[DELETE_SUCCESS_MSG], moduleName);
339 return SUCCESS;
342 /************************************************************************
344 * R a w L i s t M o d u l e s
346 * Lists all the modules in the database, along with their slots and tokens.
348 Error
349 RawListModule(char *modulespec)
351 SECMODModule *module;
352 char **moduleSpecList;
354 module = SECMOD_LoadModule(modulespec,NULL,PR_FALSE);
355 if (module == NULL) {
356 /* handle error */
357 return NO_SUCH_MODULE_ERR;
360 moduleSpecList = SECMOD_GetModuleSpecList(module);
361 if (!moduleSpecList || !moduleSpecList[0]) {
362 SECU_PrintError("modutil",
363 "no specs in secmod DB");
364 return NO_SUCH_MODULE_ERR;
367 for ( ;*moduleSpecList; moduleSpecList++) {
368 printf("%s\n\n",*moduleSpecList);
371 return SUCCESS;
374 Error
375 RawAddModule(char *dbmodulespec, char *modulespec)
377 SECMODModule *module;
378 SECMODModule *dbmodule;
381 dbmodule = SECMOD_LoadModule(dbmodulespec,NULL,PR_TRUE);
382 if (dbmodule == NULL) {
383 /* handle error */
384 return NO_SUCH_MODULE_ERR;
387 module = SECMOD_LoadModule(modulespec,dbmodule,PR_FALSE);
388 if (module == NULL) {
389 /* handle error */
390 return NO_SUCH_MODULE_ERR;
393 if( SECMOD_UpdateModule(module) != SECSuccess ) {
394 PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], modulespec);
395 return UPDATE_MOD_FAILED_ERR;
397 return SUCCESS;
400 static void
401 printModule(SECMODModule *module, int *count)
403 int slotCount = module->loaded ? module->slotCount : 0;
404 int i;
406 if ((*count)++) {
407 PR_fprintf(PR_STDOUT,"\n");
409 PR_fprintf(PR_STDOUT, "%3d. %s\n", *count, module->commonName);
411 if (module->dllName) {
412 PR_fprintf(PR_STDOUT, "\tlibrary name: %s\n", module->dllName);
415 if (slotCount == 0) {
416 PR_fprintf(PR_STDOUT,
417 "\t slots: There are no slots attached to this module\n");
418 } else {
419 PR_fprintf(PR_STDOUT, "\t slots: %d slot%s attached\n",
420 slotCount, (slotCount==1 ? "" : "s") );
423 if (module->loaded == 0) {
424 PR_fprintf(PR_STDOUT, "\tstatus: Not loaded\n");
425 } else {
426 PR_fprintf(PR_STDOUT, "\tstatus: loaded\n");
429 /* Print slot and token names */
430 for (i = 0; i < slotCount; i++) {
431 PK11SlotInfo *slot = module->slots[i];
433 PR_fprintf(PR_STDOUT, "\n");
434 PR_fprintf(PR_STDOUT, "\t slot: %s\n", PK11_GetSlotName(slot));
435 PR_fprintf(PR_STDOUT, "\ttoken: %s\n", PK11_GetTokenName(slot));
437 return;
440 /************************************************************************
442 * L i s t M o d u l e s
444 * Lists all the modules in the database, along with their slots and tokens.
446 Error
447 ListModules()
449 SECMODListLock *lock;
450 SECMODModuleList *list;
451 SECMODModuleList *deadlist;
452 SECMODModuleList *mlp;
453 Error ret=UNSPECIFIED_ERR;
454 int count = 0;
456 lock = SECMOD_GetDefaultModuleListLock();
457 if(!lock) {
458 PR_fprintf(PR_STDERR, errStrings[NO_LIST_LOCK_ERR]);
459 return NO_LIST_LOCK_ERR;
462 SECMOD_GetReadLock(lock);
464 list = SECMOD_GetDefaultModuleList();
465 deadlist = SECMOD_GetDeadModuleList();
466 if (!list && !deadlist) {
467 PR_fprintf(PR_STDERR, errStrings[NO_MODULE_LIST_ERR]);
468 ret = NO_MODULE_LIST_ERR;
469 goto loser;
472 PR_fprintf(PR_STDOUT,
473 "\nListing of PKCS #11 Modules\n"
474 "-----------------------------------------------------------\n");
476 for(mlp=list; mlp != NULL; mlp = mlp->next) {
477 printModule(mlp->module, &count);
479 for (mlp=deadlist; mlp != NULL; mlp = mlp->next) {
480 printModule(mlp->module, &count);
484 PR_fprintf(PR_STDOUT,
485 "-----------------------------------------------------------\n");
487 ret = SUCCESS;
489 loser:
490 SECMOD_ReleaseReadLock(lock);
491 return ret;
494 /* Strings describing PK11DisableReasons */
495 static char *disableReasonStr[] = {
496 "no reason",
497 "user disabled",
498 "could not initialize token",
499 "could not verify token",
500 "token not present"
502 static int numDisableReasonStr =
503 sizeof(disableReasonStr) / sizeof(disableReasonStr[0]);
505 /***********************************************************************
507 * L i s t M o d u l e
509 * Lists detailed information about the named module.
511 Error
512 ListModule(char *moduleName)
514 SECMODModule *module = NULL;
515 PK11SlotInfo *slot;
516 int slotnum;
517 CK_INFO modinfo;
518 CK_SLOT_INFO slotinfo;
519 CK_TOKEN_INFO tokeninfo;
520 char *ciphers, *mechanisms;
521 PK11DisableReasons reason;
522 Error rv = SUCCESS;
524 if(!moduleName) {
525 return SUCCESS;
528 module = SECMOD_FindModule(moduleName);
529 if(!module) {
530 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
531 rv = NO_SUCH_MODULE_ERR;
532 goto loser;
535 if ((module->loaded) &&
536 (PK11_GetModInfo(module, &modinfo) != SECSuccess)) {
537 PR_fprintf(PR_STDERR, errStrings[MOD_INFO_ERR], moduleName);
538 rv = MOD_INFO_ERR;
539 goto loser;
542 /* Module info */
543 PR_fprintf(PR_STDOUT,
544 "\n-----------------------------------------------------------\n");
545 PR_fprintf(PR_STDOUT, "Name: %s\n", module->commonName);
546 if(module->internal || !module->dllName) {
547 PR_fprintf(PR_STDOUT, "Library file: **Internal ONLY module**\n");
548 } else {
549 PR_fprintf(PR_STDOUT, "Library file: %s\n", module->dllName);
552 if (module->loaded) {
553 PR_fprintf(PR_STDOUT, "Manufacturer: %.32s\n", modinfo.manufacturerID);
554 PR_fprintf(PR_STDOUT, "Description: %.32s\n", modinfo.libraryDescription);
555 PR_fprintf(PR_STDOUT, "PKCS #11 Version %d.%d\n",
556 modinfo.cryptokiVersion.major, modinfo.cryptokiVersion.minor);
557 PR_fprintf(PR_STDOUT, "Library Version: %d.%d\n",
558 modinfo.libraryVersion.major, modinfo.libraryVersion.minor);
559 } else {
560 PR_fprintf(PR_STDOUT, "* Module not loaded\n");
562 /* Get cipher and mechanism flags */
563 ciphers = getStringFromFlags(module->ssl[0], cipherStrings,
564 numCipherStrings);
565 if(ciphers[0] == '\0') {
566 ciphers = "None";
568 PR_fprintf(PR_STDOUT, "Cipher Enable Flags: %s\n", ciphers);
569 mechanisms = NULL;
570 if (module->slotCount > 0) {
571 mechanisms = getStringFromFlags(
572 PK11_GetDefaultFlags(module->slots[0]),
573 mechanismStrings, numMechanismStrings);
575 if ((mechanisms==NULL) || (mechanisms[0] =='\0')) {
576 mechanisms = "None";
578 PR_fprintf(PR_STDOUT, "Default Mechanism Flags: %s\n", mechanisms);
580 #define PAD " "
582 /* Loop over each slot */
583 for (slotnum=0; slotnum < module->slotCount; slotnum++) {
584 slot = module->slots[slotnum];
585 if (PK11_GetSlotInfo(slot, &slotinfo) != SECSuccess) {
586 PR_fprintf(PR_STDERR, errStrings[SLOT_INFO_ERR],
587 PK11_GetSlotName(slot));
588 rv = SLOT_INFO_ERR;
589 continue;
592 /* Slot Info */
593 PR_fprintf(PR_STDOUT, "\n"PAD"Slot: %s\n", PK11_GetSlotName(slot));
594 mechanisms = getStringFromFlags(PK11_GetDefaultFlags(slot),
595 mechanismStrings, numMechanismStrings);
596 if(mechanisms[0] =='\0') {
597 mechanisms = "None";
599 PR_fprintf(PR_STDOUT, PAD"Slot Mechanism Flags: %s\n", mechanisms);
600 PR_fprintf(PR_STDOUT, PAD"Manufacturer: %.32s\n",
601 slotinfo.manufacturerID);
602 if (PK11_IsHW(slot)) {
603 PR_fprintf(PR_STDOUT, PAD"Type: Hardware\n");
604 } else {
605 PR_fprintf(PR_STDOUT, PAD"Type: Software\n");
607 PR_fprintf(PR_STDOUT, PAD"Version Number: %d.%d\n",
608 slotinfo.hardwareVersion.major, slotinfo.hardwareVersion.minor);
609 PR_fprintf(PR_STDOUT, PAD"Firmware Version: %d.%d\n",
610 slotinfo.firmwareVersion.major, slotinfo.firmwareVersion.minor);
611 if (PK11_IsDisabled(slot)) {
612 reason = PK11_GetDisabledReason(slot);
613 if(reason < numDisableReasonStr) {
614 PR_fprintf(PR_STDOUT, PAD"Status: DISABLED (%s)\n",
615 disableReasonStr[reason]);
616 } else {
617 PR_fprintf(PR_STDOUT, PAD"Status: DISABLED\n");
619 } else {
620 PR_fprintf(PR_STDOUT, PAD"Status: Enabled\n");
623 if(PK11_GetTokenInfo(slot, &tokeninfo) != SECSuccess) {
624 PR_fprintf(PR_STDERR, errStrings[TOKEN_INFO_ERR],
625 PK11_GetTokenName(slot));
626 rv = TOKEN_INFO_ERR;
627 continue;
630 /* Token Info */
631 PR_fprintf(PR_STDOUT, PAD"Token Name: %.32s\n",
632 tokeninfo.label);
633 PR_fprintf(PR_STDOUT, PAD"Token Manufacturer: %.32s\n",
634 tokeninfo.manufacturerID);
635 PR_fprintf(PR_STDOUT, PAD"Token Model: %.16s\n", tokeninfo.model);
636 PR_fprintf(PR_STDOUT, PAD"Token Serial Number: %.16s\n",
637 tokeninfo.serialNumber);
638 PR_fprintf(PR_STDOUT, PAD"Token Version: %d.%d\n",
639 tokeninfo.hardwareVersion.major, tokeninfo.hardwareVersion.minor);
640 PR_fprintf(PR_STDOUT, PAD"Token Firmware Version: %d.%d\n",
641 tokeninfo.firmwareVersion.major, tokeninfo.firmwareVersion.minor);
642 if(tokeninfo.flags & CKF_WRITE_PROTECTED) {
643 PR_fprintf(PR_STDOUT, PAD"Access: Write Protected\n");
644 } else {
645 PR_fprintf(PR_STDOUT, PAD"Access: NOT Write Protected\n");
647 if(tokeninfo.flags & CKF_LOGIN_REQUIRED) {
648 PR_fprintf(PR_STDOUT, PAD"Login Type: Login required\n");
649 } else {
650 PR_fprintf(PR_STDOUT, PAD
651 "Login Type: Public (no login required)\n");
653 if(tokeninfo.flags & CKF_USER_PIN_INITIALIZED) {
654 PR_fprintf(PR_STDOUT, PAD"User Pin: Initialized\n");
655 } else {
656 PR_fprintf(PR_STDOUT, PAD"User Pin: NOT Initialized\n");
659 PR_fprintf(PR_STDOUT,
660 "\n-----------------------------------------------------------\n");
661 loser:
662 if (module) {
663 SECMOD_DestroyModule(module);
665 return rv;
668 /************************************************************************
670 * C h a n g e P W
672 Error
673 ChangePW(char *tokenName, char *pwFile, char *newpwFile)
675 char *oldpw=NULL, *newpw=NULL, *newpw2=NULL;
676 PK11SlotInfo *slot;
677 Error ret=UNSPECIFIED_ERR;
678 PRBool matching;
680 slot = PK11_FindSlotByName(tokenName);
681 if(!slot) {
682 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_TOKEN_ERR], tokenName);
683 return NO_SUCH_TOKEN_ERR;
686 PK11_SetPasswordFunc(SECU_GetModulePassword);
688 /* Get old password */
689 if(! PK11_NeedUserInit(slot)) {
690 if(pwFile) {
691 oldpw = SECU_FilePasswd(NULL, PR_FALSE, pwFile);
692 if(PK11_CheckUserPassword(slot, oldpw) != SECSuccess) {
693 PR_fprintf(PR_STDERR, errStrings[BAD_PW_ERR]);
694 ret=BAD_PW_ERR;
695 goto loser;
697 } else {
698 for(matching=PR_FALSE; !matching; ) {
699 oldpw = SECU_GetPasswordString(NULL, "Enter old password: ");
700 if(PK11_CheckUserPassword(slot, oldpw) == SECSuccess) {
701 matching = PR_TRUE;
702 } else {
703 PR_fprintf(PR_STDOUT, msgStrings[BAD_PW_MSG]);
709 /* Get new password */
710 if(newpwFile) {
711 newpw = SECU_FilePasswd(NULL, PR_FALSE, newpwFile);
712 } else {
713 for(matching=PR_FALSE; !matching; ) {
714 newpw = SECU_GetPasswordString(NULL, "Enter new password: ");
715 newpw2 = SECU_GetPasswordString(NULL, "Re-enter new password: ");
716 if(strcmp(newpw, newpw2)) {
717 PR_fprintf(PR_STDOUT, msgStrings[PW_MATCH_MSG]);
718 } else {
719 matching = PR_TRUE;
724 /* Change the password */
725 if(PK11_NeedUserInit(slot)) {
726 if(PK11_InitPin(slot, NULL /*ssopw*/, newpw) != SECSuccess) {
727 PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName);
728 ret = CHANGEPW_FAILED_ERR;
729 goto loser;
731 } else {
732 if(PK11_ChangePW(slot, oldpw, newpw) != SECSuccess) {
733 PR_fprintf(PR_STDERR, errStrings[CHANGEPW_FAILED_ERR], tokenName);
734 ret = CHANGEPW_FAILED_ERR;
735 goto loser;
739 PR_fprintf(PR_STDOUT, msgStrings[CHANGEPW_SUCCESS_MSG], tokenName);
740 ret = SUCCESS;
742 loser:
743 if(oldpw) {
744 memset(oldpw, 0, strlen(oldpw));
745 PORT_Free(oldpw);
747 if(newpw) {
748 memset(newpw, 0, strlen(newpw));
749 PORT_Free(newpw);
751 if(newpw2) {
752 memset(newpw2, 0, strlen(newpw2));
753 PORT_Free(newpw2);
755 PK11_FreeSlot(slot);
757 return ret;
760 /***********************************************************************
762 * E n a b l e M o d u l e
764 * If enable==PR_TRUE, enables the module or slot.
765 * If enable==PR_FALSE, disables the module or slot.
766 * moduleName is the name of the module.
767 * slotName is the name of the slot. It is optional.
769 Error
770 EnableModule(char *moduleName, char *slotName, PRBool enable)
772 int i;
773 SECMODModule *module = NULL;
774 PK11SlotInfo *slot = NULL;
775 PRBool found = PR_FALSE;
776 Error rv;
778 module = SECMOD_FindModule(moduleName);
779 if(!module) {
780 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
781 rv = NO_SUCH_MODULE_ERR;
782 goto loser;
785 for(i=0; i < module->slotCount; i++) {
786 slot = module->slots[i];
787 if(slotName && strcmp(PK11_GetSlotName(slot), slotName)) {
788 /* Not the right slot */
789 continue;
791 if(enable) {
792 if(! PK11_UserEnableSlot(slot)) {
793 PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR],
794 "enable", PK11_GetSlotName(slot));
795 rv = ENABLE_FAILED_ERR;
796 goto loser;
797 } else {
798 found = PR_TRUE;
799 PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG],
800 PK11_GetSlotName(slot), "enabled");
802 } else {
803 if(! PK11_UserDisableSlot(slot)) {
804 PR_fprintf(PR_STDERR, errStrings[ENABLE_FAILED_ERR],
805 "disable", PK11_GetSlotName(slot));
806 rv = ENABLE_FAILED_ERR;
807 goto loser;
808 } else {
809 found = PR_TRUE;
810 PR_fprintf(PR_STDOUT, msgStrings[ENABLE_SUCCESS_MSG],
811 PK11_GetSlotName(slot), "disabled");
816 if(slotName && !found) {
817 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
818 rv = NO_SUCH_SLOT_ERR;
819 goto loser;
822 /* Delete and re-add module to save changes */
823 if( SECMOD_UpdateModule(module) != SECSuccess ) {
824 PR_fprintf(PR_STDERR, errStrings[UPDATE_MOD_FAILED_ERR], moduleName);
825 rv = UPDATE_MOD_FAILED_ERR;
826 goto loser;
829 rv = SUCCESS;
830 loser:
831 if (module) {
832 SECMOD_DestroyModule(module);
834 return rv;
837 /*************************************************************************
839 * S e t D e f a u l t M o d u l e
842 Error
843 SetDefaultModule(char *moduleName, char *slotName, char *mechanisms)
845 SECMODModule *module = NULL;
846 PK11SlotInfo *slot;
847 int s, i;
848 unsigned long mechFlags = getFlagsFromString(mechanisms, mechanismStrings,
849 numMechanismStrings);
850 PRBool found = PR_FALSE;
851 Error errcode = UNSPECIFIED_ERR;
853 if (pk11_DefaultArray == NULL) {
854 pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
855 if (pk11_DefaultArray == NULL) {
856 /* should assert. This shouldn't happen */
857 goto loser;
861 mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags);
863 module = SECMOD_FindModule(moduleName);
864 if(!module) {
865 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
866 errcode = NO_SUCH_MODULE_ERR;
867 goto loser;
870 /* Go through each slot */
871 for(s=0; s < module->slotCount; s++) {
872 slot = module->slots[s];
874 if ((slotName != NULL) &&
875 !((strcmp(PK11_GetSlotName(slot),slotName) == 0) ||
876 (strcmp(PK11_GetTokenName(slot),slotName) == 0)) ) {
877 /* we are only interested in changing the one slot */
878 continue;
881 found = PR_TRUE;
883 /* Go through each mechanism */
884 for(i=0; i < pk11_DefaultArraySize; i++) {
885 if(pk11_DefaultArray[i].flag & mechFlags) {
886 /* Enable this default mechanism */
887 PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]),
888 PR_TRUE);
892 if (slotName && !found) {
893 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
894 errcode = NO_SUCH_SLOT_ERR;
895 goto loser;
898 /* Delete and re-add module to save changes */
899 if( SECMOD_UpdateModule(module) != SECSuccess ) {
900 PR_fprintf(PR_STDERR, errStrings[DEFAULT_FAILED_ERR],
901 moduleName);
902 errcode = DEFAULT_FAILED_ERR;
903 goto loser;
906 PR_fprintf(PR_STDOUT, msgStrings[DEFAULT_SUCCESS_MSG]);
908 errcode = SUCCESS;
909 loser:
910 if (module) {
911 SECMOD_DestroyModule(module);
913 return errcode;
916 /************************************************************************
918 * U n s e t D e f a u l t M o d u l e
920 Error
921 UnsetDefaultModule(char *moduleName, char *slotName, char *mechanisms)
923 SECMODModule * module = NULL;
924 PK11SlotInfo *slot;
925 int s, i;
926 unsigned long mechFlags = getFlagsFromString(mechanisms,
927 mechanismStrings, numMechanismStrings);
928 PRBool found = PR_FALSE;
929 Error rv;
931 if (pk11_DefaultArray == NULL) {
932 pk11_DefaultArray = PK11_GetDefaultArray(&pk11_DefaultArraySize);
933 if (pk11_DefaultArray == NULL) {
934 /* should assert. This shouldn't happen */
935 rv = UNSPECIFIED_ERR;
936 goto loser;
940 mechFlags = SECMOD_PubMechFlagstoInternal(mechFlags);
942 module = SECMOD_FindModule(moduleName);
943 if(!module) {
944 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_MODULE_ERR], moduleName);
945 rv = NO_SUCH_MODULE_ERR;
946 goto loser;
949 for(s=0; s < module->slotCount; s++) {
950 slot = module->slots[s];
951 if ((slotName != NULL) &&
952 !((strcmp(PK11_GetSlotName(slot),slotName) == 0) ||
953 (strcmp(PK11_GetTokenName(slot),slotName) == 0)) ) {
954 /* we are only interested in changing the one slot */
955 continue;
957 for(i=0; i < pk11_DefaultArraySize ; i++) {
958 if(pk11_DefaultArray[i].flag & mechFlags) {
959 PK11_UpdateSlotAttribute(slot, &(pk11_DefaultArray[i]),
960 PR_FALSE);
964 if (slotName && !found) {
965 PR_fprintf(PR_STDERR, errStrings[NO_SUCH_SLOT_ERR], slotName);
966 rv = NO_SUCH_SLOT_ERR;
967 goto loser;
970 /* Delete and re-add module to save changes */
971 if( SECMOD_UpdateModule(module) != SECSuccess ) {
972 PR_fprintf(PR_STDERR, errStrings[UNDEFAULT_FAILED_ERR],
973 moduleName);
974 rv = UNDEFAULT_FAILED_ERR;
975 goto loser;
978 PR_fprintf(PR_STDOUT, msgStrings[UNDEFAULT_SUCCESS_MSG]);
979 rv = SUCCESS;
980 loser:
981 if (module) {
982 SECMOD_DestroyModule(module);
984 return rv;