Bug Summary

File:s/cmd/modutil/pk11.c
Warning:line 207, column 5
Null pointer passed to 1st parameter expecting 'nonnull'

Annotated Source Code

Press '?' to see keyboard shortcuts

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