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 * The following code handles the storage of PKCS 11 modules used by the
6 * NSS. This file is written to abstract away how the modules are
7 * stored so we can deside that later.
8 */
9
10 #include "lgdb.h"
11 #include "mcom_db.h"
12 #include "secerr.h"
13 #include "utilpars.h"
14
15 #define FREE_CLEAR(p) \
16 if (p) { \
17 PORT_Free(p); \
18 p = NULL; \
19 }
20
21 /* Construct a database key for a given module */
22 static SECStatus
lgdb_MakeKey(DBT * key,char * module)23 lgdb_MakeKey(DBT *key, char *module)
24 {
25 int len = 0;
26 char *commonName;
27
28 commonName = NSSUTIL_ArgGetParamValue("name", module);
29 if (commonName == NULL) {
30 commonName = NSSUTIL_ArgGetParamValue("library", module);
31 }
32 if (commonName == NULL)
33 return SECFailure;
34 len = PORT_Strlen(commonName);
35 key->data = commonName;
36 key->size = len;
37 return SECSuccess;
38 }
39
40 /* free out constructed database key */
41 static void
lgdb_FreeKey(DBT * key)42 lgdb_FreeKey(DBT *key)
43 {
44 if (key->data) {
45 PORT_Free(key->data);
46 }
47 key->data = NULL;
48 key->size = 0;
49 }
50
51 typedef struct lgdbDataStr lgdbData;
52 typedef struct lgdbSlotDataStr lgdbSlotData;
53 struct lgdbDataStr {
54 unsigned char major;
55 unsigned char minor;
56 unsigned char nameStart[2];
57 unsigned char slotOffset[2];
58 unsigned char internal;
59 unsigned char fips;
60 unsigned char ssl[8];
61 unsigned char trustOrder[4];
62 unsigned char cipherOrder[4];
63 unsigned char reserved1;
64 unsigned char isModuleDB;
65 unsigned char isModuleDBOnly;
66 unsigned char isCritical;
67 unsigned char reserved[4];
68 unsigned char names[6]; /* enough space for the length fields */
69 };
70
71 struct lgdbSlotDataStr {
72 unsigned char slotID[4];
73 unsigned char defaultFlags[4];
74 unsigned char timeout[4];
75 unsigned char askpw;
76 unsigned char hasRootCerts;
77 unsigned char reserved[18]; /* this makes it a round 32 bytes */
78 };
79
80 #define LGDB_DB_VERSION_MAJOR 0
81 #define LGDB_DB_VERSION_MINOR 6
82 #define LGDB_DB_EXT1_VERSION_MAJOR 0
83 #define LGDB_DB_EXT1_VERSION_MINOR 6
84 #define LGDB_DB_NOUI_VERSION_MAJOR 0
85 #define LGDB_DB_NOUI_VERSION_MINOR 4
86
87 #define LGDB_PUTSHORT(dest, src) \
88 (dest)[1] = (unsigned char)((src)&0xff); \
89 (dest)[0] = (unsigned char)(((src) >> 8) & 0xff);
90 #define LGDB_PUTLONG(dest, src) \
91 (dest)[3] = (unsigned char)((src)&0xff); \
92 (dest)[2] = (unsigned char)(((src) >> 8) & 0xff); \
93 (dest)[1] = (unsigned char)(((src) >> 16) & 0xff); \
94 (dest)[0] = (unsigned char)(((src) >> 24) & 0xff);
95 #define LGDB_GETSHORT(src) \
96 ((unsigned short)(((src)[0] << 8) | (src)[1]))
97 #define LGDB_GETLONG(src) \
98 ((unsigned long)(((unsigned long)(src)[0] << 24) | \
99 ((unsigned long)(src)[1] << 16) | \
100 ((unsigned long)(src)[2] << 8) | \
101 (unsigned long)(src)[3]))
102
103 /*
104 * build a data base entry from a module
105 */
106 static SECStatus
lgdb_EncodeData(DBT * data,char * module)107 lgdb_EncodeData(DBT *data, char *module)
108 {
109 lgdbData *encoded = NULL;
110 lgdbSlotData *slot;
111 unsigned char *dataPtr, *offsetPtr;
112 unsigned short len, len2 = 0, len3 = 0;
113 int count = 0;
114 unsigned short offset;
115 int dataLen, i;
116 unsigned long order;
117 unsigned long ssl[2];
118 char *commonName = NULL, *dllName = NULL, *param = NULL, *nss = NULL;
119 char *slotParams, *ciphers;
120 struct NSSUTILPreSlotInfoStr *slotInfo = NULL;
121 SECStatus rv = SECFailure;
122
123 rv = NSSUTIL_ArgParseModuleSpec(module, &dllName, &commonName, ¶m, &nss);
124 if (rv != SECSuccess)
125 return rv;
126 rv = SECFailure;
127
128 if (commonName == NULL) {
129 /* set error */
130 goto loser;
131 }
132
133 len = PORT_Strlen(commonName);
134 if (dllName) {
135 len2 = PORT_Strlen(dllName);
136 }
137 if (param) {
138 len3 = PORT_Strlen(param);
139 }
140
141 slotParams = NSSUTIL_ArgGetParamValue("slotParams", nss);
142 slotInfo = NSSUTIL_ArgParseSlotInfo(NULL, slotParams, &count);
143 if (slotParams)
144 PORT_Free(slotParams);
145
146 if (count && slotInfo == NULL) {
147 /* set error */
148 goto loser;
149 }
150
151 dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) +
152 count * sizeof(lgdbSlotData);
153
154 data->data = (unsigned char *)PORT_ZAlloc(dataLen);
155 encoded = (lgdbData *)data->data;
156 dataPtr = (unsigned char *)data->data;
157 data->size = dataLen;
158
159 if (encoded == NULL) {
160 /* set error */
161 goto loser;
162 }
163
164 encoded->major = LGDB_DB_VERSION_MAJOR;
165 encoded->minor = LGDB_DB_VERSION_MINOR;
166 encoded->internal = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "internal", nss) ? 1 : 0);
167 encoded->fips = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "FIPS", nss) ? 1 : 0);
168 encoded->isModuleDB = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "isModuleDB", nss) ? 1 : 0);
169 encoded->isModuleDBOnly = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "isModuleDBOnly", nss) ? 1 : 0);
170 encoded->isCritical = (unsigned char)(NSSUTIL_ArgHasFlag("flags", "critical", nss) ? 1 : 0);
171
172 order = NSSUTIL_ArgReadLong("trustOrder", nss,
173 NSSUTIL_DEFAULT_TRUST_ORDER, NULL);
174 LGDB_PUTLONG(encoded->trustOrder, order);
175 order = NSSUTIL_ArgReadLong("cipherOrder", nss,
176 NSSUTIL_DEFAULT_CIPHER_ORDER, NULL);
177 LGDB_PUTLONG(encoded->cipherOrder, order);
178
179 ciphers = NSSUTIL_ArgGetParamValue("ciphers", nss);
180 NSSUTIL_ArgParseCipherFlags(&ssl[0], ciphers);
181 LGDB_PUTLONG(encoded->ssl, ssl[0]);
182 LGDB_PUTLONG(&encoded->ssl[4], ssl[1]);
183 if (ciphers)
184 PORT_Free(ciphers);
185
186 offset = (unsigned short)offsetof(lgdbData, names);
187 LGDB_PUTSHORT(encoded->nameStart, offset);
188 offset = offset + len + len2 + len3 + 3 * sizeof(unsigned short);
189 LGDB_PUTSHORT(encoded->slotOffset, offset);
190
191 LGDB_PUTSHORT(&dataPtr[offset], ((unsigned short)count));
192 slot = (lgdbSlotData *)(dataPtr + offset + sizeof(unsigned short));
193
194 offsetPtr = encoded->names;
195 LGDB_PUTSHORT(encoded->names, len);
196 offsetPtr += sizeof(unsigned short);
197 PORT_Memcpy(offsetPtr, commonName, len);
198 offsetPtr += len;
199
200 LGDB_PUTSHORT(offsetPtr, len2);
201 offsetPtr += sizeof(unsigned short);
202 if (len2) {
203 PORT_Memcpy(offsetPtr, dllName, len2);
204 }
205 offsetPtr += len2;
206
207 LGDB_PUTSHORT(offsetPtr, len3);
208 offsetPtr += sizeof(unsigned short);
209 if (len3) {
210 PORT_Memcpy(offsetPtr, param, len3);
211 }
212 offsetPtr += len3;
213
214 if (count) {
215 for (i = 0; i < count; i++) {
216 LGDB_PUTLONG(slot[i].slotID, slotInfo[i].slotID);
217 LGDB_PUTLONG(slot[i].defaultFlags,
218 slotInfo[i].defaultFlags);
219 LGDB_PUTLONG(slot[i].timeout, slotInfo[i].timeout);
220 slot[i].askpw = slotInfo[i].askpw;
221 slot[i].hasRootCerts = slotInfo[i].hasRootCerts;
222 PORT_Memset(slot[i].reserved, 0, sizeof(slot[i].reserved));
223 }
224 }
225 rv = SECSuccess;
226
227 loser:
228 if (commonName)
229 PORT_Free(commonName);
230 if (dllName)
231 PORT_Free(dllName);
232 if (param)
233 PORT_Free(param);
234 if (slotInfo)
235 PORT_Free(slotInfo);
236 if (nss)
237 PORT_Free(nss);
238 return rv;
239 }
240
241 static void
lgdb_FreeData(DBT * data)242 lgdb_FreeData(DBT *data)
243 {
244 if (data->data) {
245 PORT_Free(data->data);
246 }
247 }
248
249 static void
lgdb_FreeSlotStrings(char ** slotStrings,int count)250 lgdb_FreeSlotStrings(char **slotStrings, int count)
251 {
252 int i;
253
254 for (i = 0; i < count; i++) {
255 if (slotStrings[i]) {
256 PR_smprintf_free(slotStrings[i]);
257 slotStrings[i] = NULL;
258 }
259 }
260 }
261
262 /*
263 * build a module from the data base entry.
264 */
265 static char *
lgdb_DecodeData(char * defParams,DBT * data,PRBool * retInternal)266 lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
267 {
268 lgdbData *encoded;
269 lgdbSlotData *slots;
270 PLArenaPool *arena;
271 char *commonName = NULL;
272 char *dllName = NULL;
273 char *parameters = NULL;
274 char *nss;
275 char *moduleSpec;
276 char **slotStrings = NULL;
277 unsigned char *names;
278 unsigned long slotCount;
279 unsigned long ssl0 = 0;
280 unsigned long ssl1 = 0;
281 unsigned long slotID;
282 unsigned long defaultFlags;
283 unsigned long timeout;
284 unsigned long trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER;
285 unsigned long cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER;
286 unsigned short len;
287 unsigned short namesOffset = 0; /* start of the names block */
288 unsigned long namesRunningOffset; /* offset to name we are
289 * currently processing */
290 unsigned short slotOffset;
291 PRBool isOldVersion = PR_FALSE;
292 PRBool internal;
293 PRBool isFIPS;
294 PRBool isModuleDB = PR_FALSE;
295 PRBool isModuleDBOnly = PR_FALSE;
296 PRBool extended = PR_FALSE;
297 int i;
298
299 arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
300 if (arena == NULL)
301 return NULL;
302
303 #define CHECK_SIZE(x) \
304 if ((unsigned int)data->size < (unsigned int)(x)) \
305 goto db_loser
306
307 /* -------------------------------------------------------------
308 ** Process the buffer header, which is the lgdbData struct.
309 ** It may be an old or new version. Check the length for each.
310 */
311
312 CHECK_SIZE(offsetof(lgdbData, trustOrder[0]));
313
314 encoded = (lgdbData *)data->data;
315
316 internal = (encoded->internal != 0) ? PR_TRUE : PR_FALSE;
317 isFIPS = (encoded->fips != 0) ? PR_TRUE : PR_FALSE;
318
319 if (retInternal)
320 *retInternal = internal;
321 if (internal) {
322 parameters = PORT_ArenaStrdup(arena, defParams);
323 if (parameters == NULL)
324 goto loser;
325 }
326 if (internal && (encoded->major == LGDB_DB_NOUI_VERSION_MAJOR) &&
327 (encoded->minor <= LGDB_DB_NOUI_VERSION_MINOR)) {
328 isOldVersion = PR_TRUE;
329 }
330 if ((encoded->major == LGDB_DB_EXT1_VERSION_MAJOR) &&
331 (encoded->minor >= LGDB_DB_EXT1_VERSION_MINOR)) {
332 CHECK_SIZE(sizeof(lgdbData));
333 trustOrder = LGDB_GETLONG(encoded->trustOrder);
334 cipherOrder = LGDB_GETLONG(encoded->cipherOrder);
335 isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE : PR_FALSE;
336 isModuleDBOnly = (encoded->isModuleDBOnly != 0) ? PR_TRUE : PR_FALSE;
337 extended = PR_TRUE;
338 }
339 if (internal && !extended) {
340 trustOrder = 0;
341 cipherOrder = 100;
342 }
343 /* decode SSL cipher enable flags */
344 ssl0 = LGDB_GETLONG(encoded->ssl);
345 ssl1 = LGDB_GETLONG(encoded->ssl + 4);
346
347 slotOffset = LGDB_GETSHORT(encoded->slotOffset);
348 namesOffset = LGDB_GETSHORT(encoded->nameStart);
349
350 /*--------------------------------------------------------------
351 ** Now process the variable length set of names.
352 ** The names have this structure:
353 ** struct {
354 ** BYTE commonNameLen[ 2 ];
355 ** BYTE commonName [ commonNameLen ];
356 ** BTTE libNameLen [ 2 ];
357 ** BYTE libName [ libNameLen ];
358 ** If it is "extended" it also has these members:
359 ** BYTE initStringLen[ 2 ];
360 ** BYTE initString [ initStringLen ];
361 ** }
362 */
363
364 namesRunningOffset = namesOffset;
365 /* copy the module's common name */
366 CHECK_SIZE(namesRunningOffset + 2);
367 names = (unsigned char *)data->data;
368 len = LGDB_GETSHORT(names + namesRunningOffset);
369
370 CHECK_SIZE(namesRunningOffset + 2 + len);
371 commonName = (char *)PORT_ArenaAlloc(arena, len + 1);
372 if (commonName == NULL)
373 goto loser;
374 PORT_Memcpy(commonName, names + namesRunningOffset + 2, len);
375 commonName[len] = 0;
376 namesRunningOffset += len + 2;
377
378 /* copy the module's shared library file name. */
379 CHECK_SIZE(namesRunningOffset + 2);
380 len = LGDB_GETSHORT(names + namesRunningOffset);
381 if (len) {
382 CHECK_SIZE(namesRunningOffset + 2 + len);
383 dllName = (char *)PORT_ArenaAlloc(arena, len + 1);
384 if (dllName == NULL)
385 goto loser;
386 PORT_Memcpy(dllName, names + namesRunningOffset + 2, len);
387 dllName[len] = 0;
388 }
389 namesRunningOffset += len + 2;
390
391 /* copy the module's initialization string, if present. */
392 if (!internal && extended) {
393 CHECK_SIZE(namesRunningOffset + 2);
394 len = LGDB_GETSHORT(names + namesRunningOffset);
395 if (len) {
396 CHECK_SIZE(namesRunningOffset + 2 + len);
397 parameters = (char *)PORT_ArenaAlloc(arena, len + 1);
398 if (parameters == NULL)
399 goto loser;
400 PORT_Memcpy(parameters, names + namesRunningOffset + 2, len);
401 parameters[len] = 0;
402 }
403 namesRunningOffset += len + 2;
404 }
405
406 /*
407 * Consistency check: Make sure the slot and names blocks don't
408 * overlap. These blocks can occur in any order, so this check is made
409 * in 2 parts. First we check the case where the slot block starts
410 * after the name block. Later, when we have the slot block length,
411 * we check the case where slot block starts before the name block.
412 * NOTE: in most cases any overlap will likely be detected by invalid
413 * data read from the blocks, but it's better to find out sooner
414 * than later.
415 */
416 if (slotOffset >= namesOffset) { /* slot block starts after name block */
417 if (slotOffset < namesRunningOffset) {
418 goto db_loser;
419 }
420 }
421
422 /* ------------------------------------------------------------------
423 ** Part 3, process the slot table.
424 ** This part has this structure:
425 ** struct {
426 ** BYTE slotCount [ 2 ];
427 ** lgdbSlotData [ slotCount ];
428 ** {
429 */
430
431 CHECK_SIZE(slotOffset + 2);
432 slotCount = LGDB_GETSHORT((unsigned char *)data->data + slotOffset);
433
434 /*
435 * Consistency check: Part 2. We now have the slot block length, we can
436 * check the case where the slotblock procedes the name block.
437 */
438 if (slotOffset < namesOffset) { /* slot block starts before name block */
439 if (namesOffset < slotOffset + 2 + slotCount * sizeof(lgdbSlotData)) {
440 goto db_loser;
441 }
442 }
443
444 CHECK_SIZE((slotOffset + 2 + slotCount * sizeof(lgdbSlotData)));
445 slots = (lgdbSlotData *)((unsigned char *)data->data + slotOffset + 2);
446
447 /* slotCount; */
448 slotStrings = (char **)PORT_ArenaZAlloc(arena, slotCount * sizeof(char *));
449 if (slotStrings == NULL)
450 goto loser;
451 for (i = 0; i < (int)slotCount; i++, slots++) {
452 PRBool hasRootCerts = PR_FALSE;
453 PRBool hasRootTrust = PR_FALSE;
454 slotID = LGDB_GETLONG(slots->slotID);
455 defaultFlags = LGDB_GETLONG(slots->defaultFlags);
456 timeout = LGDB_GETLONG(slots->timeout);
457 hasRootCerts = slots->hasRootCerts;
458 if (isOldVersion && internal && (slotID != 2)) {
459 unsigned long internalFlags =
460 NSSUTIL_ArgParseSlotFlags("slotFlags",
461 NSSUTIL_DEFAULT_SFTKN_FLAGS);
462 defaultFlags |= internalFlags;
463 }
464 if (hasRootCerts && !extended) {
465 trustOrder = 100;
466 }
467
468 slotStrings[i] = NSSUTIL_MkSlotString(slotID, defaultFlags, timeout,
469 (unsigned char)slots->askpw,
470 hasRootCerts, hasRootTrust);
471 if (slotStrings[i] == NULL) {
472 lgdb_FreeSlotStrings(slotStrings, i);
473 goto loser;
474 }
475 }
476
477 nss = NSSUTIL_MkNSSString(slotStrings, slotCount, internal, isFIPS,
478 isModuleDB, isModuleDBOnly, internal, trustOrder,
479 cipherOrder, ssl0, ssl1);
480 lgdb_FreeSlotStrings(slotStrings, slotCount);
481 /* it's permissible (and normal) for nss to be NULL. it simply means
482 * there are no NSS specific parameters in the database */
483 moduleSpec = NSSUTIL_MkModuleSpec(dllName, commonName, parameters, nss);
484 PR_smprintf_free(nss);
485 PORT_FreeArena(arena, PR_TRUE);
486 return moduleSpec;
487
488 db_loser:
489 PORT_SetError(SEC_ERROR_BAD_DATABASE);
490 loser:
491 PORT_FreeArena(arena, PR_TRUE);
492 return NULL;
493 }
494
495 static DB *
lgdb_OpenDB(const char * appName,const char * filename,const char * dbName,PRBool readOnly,PRBool update)496 lgdb_OpenDB(const char *appName, const char *filename, const char *dbName,
497 PRBool readOnly, PRBool update)
498 {
499 DB *pkcs11db = NULL;
500
501 if (appName) {
502 char *secname = PORT_Strdup(filename);
503 int len = strlen(secname);
504 int status = RDB_FAIL;
505
506 if (len >= 3 && PORT_Strcmp(&secname[len - 3], ".db") == 0) {
507 secname[len - 3] = 0;
508 }
509 pkcs11db =
510 rdbopen(appName, "", secname, readOnly ? NO_RDONLY : NO_RDWR, NULL);
511 if (update && !pkcs11db) {
512 DB *updatedb;
513
514 pkcs11db = rdbopen(appName, "", secname, NO_CREATE, &status);
515 if (!pkcs11db) {
516 if (status == RDB_RETRY) {
517 pkcs11db = rdbopen(appName, "", secname,
518 readOnly ? NO_RDONLY : NO_RDWR, NULL);
519 }
520 PORT_Free(secname);
521 return pkcs11db;
522 }
523 updatedb = dbopen(dbName, NO_RDONLY, 0600, DB_HASH, 0);
524 if (updatedb) {
525 db_Copy(pkcs11db, updatedb);
526 (*updatedb->close)(updatedb);
527 } else {
528 (*pkcs11db->close)(pkcs11db);
529 PORT_Free(secname);
530 return NULL;
531 }
532 }
533 PORT_Free(secname);
534 return pkcs11db;
535 }
536
537 /* I'm sure we should do more checks here sometime... */
538 pkcs11db = dbopen(dbName, readOnly ? NO_RDONLY : NO_RDWR, 0600, DB_HASH, 0);
539
540 /* didn't exist? create it */
541 if (pkcs11db == NULL) {
542 if (readOnly)
543 return NULL;
544
545 pkcs11db = dbopen(dbName, NO_CREATE, 0600, DB_HASH, 0);
546 if (pkcs11db)
547 (*pkcs11db->sync)(pkcs11db, 0);
548 }
549 return pkcs11db;
550 }
551
552 static void
lgdb_CloseDB(DB * pkcs11db)553 lgdb_CloseDB(DB *pkcs11db)
554 {
555 (*pkcs11db->close)(pkcs11db);
556 }
557
558 SECStatus legacy_AddSecmodDB(const char *appName, const char *filename,
559 const char *dbname, char *module, PRBool rw);
560
561 #define LGDB_STEP 10
562 /*
563 * Read all the existing modules in
564 */
565 char **
legacy_ReadSecmodDB(const char * appName,const char * filename,const char * dbname,char * params,PRBool rw)566 legacy_ReadSecmodDB(const char *appName, const char *filename,
567 const char *dbname, char *params, PRBool rw)
568 {
569 DBT key, data;
570 int ret;
571 DB *pkcs11db = NULL;
572 char **moduleList = NULL, **newModuleList = NULL;
573 int moduleCount = 1;
574 int useCount = LGDB_STEP;
575
576 moduleList = (char **)PORT_ZAlloc(useCount * sizeof(char **));
577 if (moduleList == NULL)
578 return NULL;
579
580 pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_TRUE, rw);
581 if (pkcs11db == NULL)
582 goto done;
583
584 /* read and parse the file or data base */
585 ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST);
586 if (ret)
587 goto done;
588
589 do {
590 char *moduleString;
591 PRBool internal = PR_FALSE;
592 if ((moduleCount + 1) >= useCount) {
593 useCount += LGDB_STEP;
594 newModuleList =
595 (char **)PORT_Realloc(moduleList, useCount * sizeof(char *));
596 if (newModuleList == NULL)
597 goto done;
598 moduleList = newModuleList;
599 PORT_Memset(&moduleList[moduleCount + 1], 0,
600 sizeof(char *) * LGDB_STEP);
601 }
602 moduleString = lgdb_DecodeData(params, &data, &internal);
603 if (internal) {
604 moduleList[0] = moduleString;
605 } else {
606 moduleList[moduleCount] = moduleString;
607 moduleCount++;
608 }
609 } while ((*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT) == 0);
610
611 done:
612 if (!moduleList[0]) {
613 char *newparams = NSSUTIL_Quote(params, '"');
614 if (newparams) {
615 moduleList[0] = PR_smprintf(
616 NSSUTIL_DEFAULT_INTERNAL_INIT1 "%s" NSSUTIL_DEFAULT_INTERNAL_INIT2 "%s" NSSUTIL_DEFAULT_INTERNAL_INIT3,
617 newparams, NSSUTIL_DEFAULT_SFTKN_FLAGS);
618 PORT_Free(newparams);
619 }
620 }
621 /* deal with trust cert db here */
622
623 if (pkcs11db) {
624 lgdb_CloseDB(pkcs11db);
625 } else if (moduleList[0] && rw) {
626 legacy_AddSecmodDB(appName, filename, dbname, moduleList[0], rw);
627 }
628 if (!moduleList[0]) {
629 PORT_Free(moduleList);
630 moduleList = NULL;
631 }
632 return moduleList;
633 }
634
635 SECStatus
legacy_ReleaseSecmodDBData(const char * appName,const char * filename,const char * dbname,char ** moduleSpecList,PRBool rw)636 legacy_ReleaseSecmodDBData(const char *appName, const char *filename,
637 const char *dbname, char **moduleSpecList, PRBool rw)
638 {
639 if (moduleSpecList) {
640 char **index;
641 for (index = moduleSpecList; *index; index++) {
642 PR_smprintf_free(*index);
643 }
644 PORT_Free(moduleSpecList);
645 }
646 return SECSuccess;
647 }
648
649 /*
650 * Delete a module from the Data Base
651 */
652 SECStatus
legacy_DeleteSecmodDB(const char * appName,const char * filename,const char * dbname,char * args,PRBool rw)653 legacy_DeleteSecmodDB(const char *appName, const char *filename,
654 const char *dbname, char *args, PRBool rw)
655 {
656 DBT key;
657 SECStatus rv = SECFailure;
658 DB *pkcs11db = NULL;
659 int ret;
660
661 if (!rw)
662 return SECFailure;
663
664 /* make sure we have a db handle */
665 pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_FALSE, PR_FALSE);
666 if (pkcs11db == NULL) {
667 return SECFailure;
668 }
669
670 rv = lgdb_MakeKey(&key, args);
671 if (rv != SECSuccess)
672 goto done;
673 rv = SECFailure;
674 ret = (*pkcs11db->del)(pkcs11db, &key, 0);
675 lgdb_FreeKey(&key);
676 if (ret != 0)
677 goto done;
678
679 ret = (*pkcs11db->sync)(pkcs11db, 0);
680 if (ret == 0)
681 rv = SECSuccess;
682
683 done:
684 lgdb_CloseDB(pkcs11db);
685 return rv;
686 }
687
688 /*
689 * Add a module to the Data base
690 */
691 SECStatus
legacy_AddSecmodDB(const char * appName,const char * filename,const char * dbname,char * module,PRBool rw)692 legacy_AddSecmodDB(const char *appName, const char *filename,
693 const char *dbname, char *module, PRBool rw)
694 {
695 DBT key, data;
696 SECStatus rv = SECFailure;
697 DB *pkcs11db = NULL;
698 int ret;
699
700 if (!rw)
701 return SECFailure;
702
703 /* make sure we have a db handle */
704 pkcs11db = lgdb_OpenDB(appName, filename, dbname, PR_FALSE, PR_FALSE);
705 if (pkcs11db == NULL) {
706 return SECFailure;
707 }
708
709 rv = lgdb_MakeKey(&key, module);
710 if (rv != SECSuccess)
711 goto done;
712 rv = lgdb_EncodeData(&data, module);
713 if (rv != SECSuccess) {
714 lgdb_FreeKey(&key);
715 goto done;
716 }
717 rv = SECFailure;
718 ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0);
719 lgdb_FreeKey(&key);
720 lgdb_FreeData(&data);
721 if (ret != 0)
722 goto done;
723
724 ret = (*pkcs11db->sync)(pkcs11db, 0);
725 if (ret == 0)
726 rv = SECSuccess;
727
728 done:
729 lgdb_CloseDB(pkcs11db);
730 return rv;
731 }
732