pk11db.c (22541B)
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 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 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 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 242 lgdb_FreeData(DBT *data) 243 { 244 if (data->data) { 245 PORT_Free(data->data); 246 } 247 } 248 249 static void 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 * 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 * 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 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 ** 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 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 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 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 }