1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/security/nss/lib/softoken/legacydb/pk11db.c Wed Dec 31 06:09:35 2014 +0100 1.3 @@ -0,0 +1,717 @@ 1.4 +/* This Source Code Form is subject to the terms of the Mozilla Public 1.5 + * License, v. 2.0. If a copy of the MPL was not distributed with this 1.6 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ 1.7 +/* 1.8 + * The following code handles the storage of PKCS 11 modules used by the 1.9 + * NSS. This file is written to abstract away how the modules are 1.10 + * stored so we can deside that later. 1.11 + */ 1.12 + 1.13 +#include "lgdb.h" 1.14 +#include "mcom_db.h" 1.15 +#include "secerr.h" 1.16 +#include "utilpars.h" 1.17 + 1.18 +#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; } 1.19 + 1.20 +/* Construct a database key for a given module */ 1.21 +static SECStatus lgdb_MakeKey(DBT *key, char * module) { 1.22 + int len = 0; 1.23 + char *commonName; 1.24 + 1.25 + commonName = NSSUTIL_ArgGetParamValue("name",module); 1.26 + if (commonName == NULL) { 1.27 + commonName = NSSUTIL_ArgGetParamValue("library",module); 1.28 + } 1.29 + if (commonName == NULL) return SECFailure; 1.30 + len = PORT_Strlen(commonName); 1.31 + key->data = commonName; 1.32 + key->size = len; 1.33 + return SECSuccess; 1.34 +} 1.35 + 1.36 +/* free out constructed database key */ 1.37 +static void 1.38 +lgdb_FreeKey(DBT *key) 1.39 +{ 1.40 + if (key->data) { 1.41 + PORT_Free(key->data); 1.42 + } 1.43 + key->data = NULL; 1.44 + key->size = 0; 1.45 +} 1.46 + 1.47 +typedef struct lgdbDataStr lgdbData; 1.48 +typedef struct lgdbSlotDataStr lgdbSlotData; 1.49 +struct lgdbDataStr { 1.50 + unsigned char major; 1.51 + unsigned char minor; 1.52 + unsigned char nameStart[2]; 1.53 + unsigned char slotOffset[2]; 1.54 + unsigned char internal; 1.55 + unsigned char fips; 1.56 + unsigned char ssl[8]; 1.57 + unsigned char trustOrder[4]; 1.58 + unsigned char cipherOrder[4]; 1.59 + unsigned char reserved1; 1.60 + unsigned char isModuleDB; 1.61 + unsigned char isModuleDBOnly; 1.62 + unsigned char isCritical; 1.63 + unsigned char reserved[4]; 1.64 + unsigned char names[6]; /* enough space for the length fields */ 1.65 +}; 1.66 + 1.67 +struct lgdbSlotDataStr { 1.68 + unsigned char slotID[4]; 1.69 + unsigned char defaultFlags[4]; 1.70 + unsigned char timeout[4]; 1.71 + unsigned char askpw; 1.72 + unsigned char hasRootCerts; 1.73 + unsigned char reserved[18]; /* this makes it a round 32 bytes */ 1.74 +}; 1.75 + 1.76 +#define LGDB_DB_VERSION_MAJOR 0 1.77 +#define LGDB_DB_VERSION_MINOR 6 1.78 +#define LGDB_DB_EXT1_VERSION_MAJOR 0 1.79 +#define LGDB_DB_EXT1_VERSION_MINOR 6 1.80 +#define LGDB_DB_NOUI_VERSION_MAJOR 0 1.81 +#define LGDB_DB_NOUI_VERSION_MINOR 4 1.82 + 1.83 +#define LGDB_PUTSHORT(dest,src) \ 1.84 + (dest)[1] = (unsigned char) ((src)&0xff); \ 1.85 + (dest)[0] = (unsigned char) (((src) >> 8) & 0xff); 1.86 +#define LGDB_PUTLONG(dest,src) \ 1.87 + (dest)[3] = (unsigned char) ((src)&0xff); \ 1.88 + (dest)[2] = (unsigned char) (((src) >> 8) & 0xff); \ 1.89 + (dest)[1] = (unsigned char) (((src) >> 16) & 0xff); \ 1.90 + (dest)[0] = (unsigned char) (((src) >> 24) & 0xff); 1.91 +#define LGDB_GETSHORT(src) \ 1.92 + ((unsigned short) (((src)[0] << 8) | (src)[1])) 1.93 +#define LGDB_GETLONG(src) \ 1.94 + ((unsigned long) (( (unsigned long) (src)[0] << 24) | \ 1.95 + ( (unsigned long) (src)[1] << 16) | \ 1.96 + ( (unsigned long) (src)[2] << 8) | \ 1.97 + (unsigned long) (src)[3])) 1.98 + 1.99 +/* 1.100 + * build a data base entry from a module 1.101 + */ 1.102 +static SECStatus 1.103 +lgdb_EncodeData(DBT *data, char * module) 1.104 +{ 1.105 + lgdbData *encoded = NULL; 1.106 + lgdbSlotData *slot; 1.107 + unsigned char *dataPtr; 1.108 + unsigned short len, len2 = 0, len3 = 0; 1.109 + int count = 0; 1.110 + unsigned short offset; 1.111 + int dataLen, i; 1.112 + unsigned long order; 1.113 + unsigned long ssl[2]; 1.114 + char *commonName = NULL , *dllName = NULL, *param = NULL, *nss = NULL; 1.115 + char *slotParams, *ciphers; 1.116 + struct NSSUTILPreSlotInfoStr *slotInfo = NULL; 1.117 + SECStatus rv = SECFailure; 1.118 + 1.119 + rv = NSSUTIL_ArgParseModuleSpec(module,&dllName,&commonName,¶m,&nss); 1.120 + if (rv != SECSuccess) return rv; 1.121 + rv = SECFailure; 1.122 + 1.123 + if (commonName == NULL) { 1.124 + /* set error */ 1.125 + goto loser; 1.126 + } 1.127 + 1.128 + len = PORT_Strlen(commonName); 1.129 + if (dllName) { 1.130 + len2 = PORT_Strlen(dllName); 1.131 + } 1.132 + if (param) { 1.133 + len3 = PORT_Strlen(param); 1.134 + } 1.135 + 1.136 + slotParams = NSSUTIL_ArgGetParamValue("slotParams",nss); 1.137 + slotInfo = NSSUTIL_ArgParseSlotInfo(NULL,slotParams,&count); 1.138 + if (slotParams) PORT_Free(slotParams); 1.139 + 1.140 + if (count && slotInfo == NULL) { 1.141 + /* set error */ 1.142 + goto loser; 1.143 + } 1.144 + 1.145 + dataLen = sizeof(lgdbData) + len + len2 + len3 + sizeof(unsigned short) + 1.146 + count*sizeof(lgdbSlotData); 1.147 + 1.148 + data->data = (unsigned char *) PORT_ZAlloc(dataLen); 1.149 + encoded = (lgdbData *)data->data; 1.150 + dataPtr = (unsigned char *) data->data; 1.151 + data->size = dataLen; 1.152 + 1.153 + if (encoded == NULL) { 1.154 + /* set error */ 1.155 + goto loser; 1.156 + } 1.157 + 1.158 + encoded->major = LGDB_DB_VERSION_MAJOR; 1.159 + encoded->minor = LGDB_DB_VERSION_MINOR; 1.160 + encoded->internal = (unsigned char) 1.161 + (NSSUTIL_ArgHasFlag("flags","internal",nss) ? 1 : 0); 1.162 + encoded->fips = (unsigned char) 1.163 + (NSSUTIL_ArgHasFlag("flags","FIPS",nss) ? 1 : 0); 1.164 + encoded->isModuleDB = (unsigned char) 1.165 + (NSSUTIL_ArgHasFlag("flags","isModuleDB",nss) ? 1 : 0); 1.166 + encoded->isModuleDBOnly = (unsigned char) 1.167 + (NSSUTIL_ArgHasFlag("flags","isModuleDBOnly",nss) ? 1 : 0); 1.168 + encoded->isCritical = (unsigned char) 1.169 + (NSSUTIL_ArgHasFlag("flags","critical",nss) ? 1 : 0); 1.170 + 1.171 + order = NSSUTIL_ArgReadLong("trustOrder", nss, 1.172 + NSSUTIL_DEFAULT_TRUST_ORDER, NULL); 1.173 + LGDB_PUTLONG(encoded->trustOrder,order); 1.174 + order = NSSUTIL_ArgReadLong("cipherOrder", nss, 1.175 + NSSUTIL_DEFAULT_CIPHER_ORDER, NULL); 1.176 + LGDB_PUTLONG(encoded->cipherOrder,order); 1.177 + 1.178 + 1.179 + ciphers = NSSUTIL_ArgGetParamValue("ciphers",nss); 1.180 + NSSUTIL_ArgParseCipherFlags(&ssl[0], ciphers); 1.181 + LGDB_PUTLONG(encoded->ssl,ssl[0]); 1.182 + LGDB_PUTLONG(&encoded->ssl[4],ssl[1]); 1.183 + if (ciphers) PORT_Free(ciphers); 1.184 + 1.185 + offset = (unsigned short) offsetof(lgdbData, names); 1.186 + LGDB_PUTSHORT(encoded->nameStart,offset); 1.187 + offset = offset + len + len2 + len3 + 3*sizeof(unsigned short); 1.188 + LGDB_PUTSHORT(encoded->slotOffset,offset); 1.189 + 1.190 + 1.191 + LGDB_PUTSHORT(&dataPtr[offset],((unsigned short)count)); 1.192 + slot = (lgdbSlotData *)(dataPtr+offset+sizeof(unsigned short)); 1.193 + 1.194 + offset = 0; 1.195 + LGDB_PUTSHORT(encoded->names,len); 1.196 + offset += sizeof(unsigned short); 1.197 + PORT_Memcpy(&encoded->names[offset],commonName,len); 1.198 + offset += len; 1.199 + 1.200 + 1.201 + LGDB_PUTSHORT(&encoded->names[offset],len2); 1.202 + offset += sizeof(unsigned short); 1.203 + if (len2) PORT_Memcpy(&encoded->names[offset],dllName,len2); 1.204 + offset += len2; 1.205 + 1.206 + LGDB_PUTSHORT(&encoded->names[offset],len3); 1.207 + offset += sizeof(unsigned short); 1.208 + if (len3) PORT_Memcpy(&encoded->names[offset],param,len3); 1.209 + offset += len3; 1.210 + 1.211 + if (count) { 1.212 + for (i=0; i < count; i++) { 1.213 + LGDB_PUTLONG(slot[i].slotID, slotInfo[i].slotID); 1.214 + LGDB_PUTLONG(slot[i].defaultFlags, 1.215 + slotInfo[i].defaultFlags); 1.216 + LGDB_PUTLONG(slot[i].timeout,slotInfo[i].timeout); 1.217 + slot[i].askpw = slotInfo[i].askpw; 1.218 + slot[i].hasRootCerts = slotInfo[i].hasRootCerts; 1.219 + PORT_Memset(slot[i].reserved, 0, sizeof(slot[i].reserved)); 1.220 + } 1.221 + } 1.222 + rv = SECSuccess; 1.223 + 1.224 +loser: 1.225 + if (commonName) PORT_Free(commonName); 1.226 + if (dllName) PORT_Free(dllName); 1.227 + if (param) PORT_Free(param); 1.228 + if (slotInfo) PORT_Free(slotInfo); 1.229 + if (nss) PORT_Free(nss); 1.230 + return rv; 1.231 + 1.232 +} 1.233 + 1.234 +static void 1.235 +lgdb_FreeData(DBT *data) 1.236 +{ 1.237 + if (data->data) { 1.238 + PORT_Free(data->data); 1.239 + } 1.240 +} 1.241 + 1.242 +static void 1.243 +lgdb_FreeSlotStrings(char **slotStrings, int count) 1.244 +{ 1.245 + int i; 1.246 + 1.247 + for (i=0; i < count; i++) { 1.248 + if (slotStrings[i]) { 1.249 + PR_smprintf_free(slotStrings[i]); 1.250 + slotStrings[i] = NULL; 1.251 + } 1.252 + } 1.253 +} 1.254 + 1.255 +/* 1.256 + * build a module from the data base entry. 1.257 + */ 1.258 +static char * 1.259 +lgdb_DecodeData(char *defParams, DBT *data, PRBool *retInternal) 1.260 +{ 1.261 + lgdbData *encoded; 1.262 + lgdbSlotData *slots; 1.263 + PLArenaPool *arena; 1.264 + char *commonName = NULL; 1.265 + char *dllName = NULL; 1.266 + char *parameters = NULL; 1.267 + char *nss; 1.268 + char *moduleSpec; 1.269 + char **slotStrings = NULL; 1.270 + unsigned char *names; 1.271 + unsigned long slotCount; 1.272 + unsigned long ssl0 =0; 1.273 + unsigned long ssl1 =0; 1.274 + unsigned long slotID; 1.275 + unsigned long defaultFlags; 1.276 + unsigned long timeout; 1.277 + unsigned long trustOrder = NSSUTIL_DEFAULT_TRUST_ORDER; 1.278 + unsigned long cipherOrder = NSSUTIL_DEFAULT_CIPHER_ORDER; 1.279 + unsigned short len; 1.280 + unsigned short namesOffset = 0; /* start of the names block */ 1.281 + unsigned long namesRunningOffset; /* offset to name we are 1.282 + * currently processing */ 1.283 + unsigned short slotOffset; 1.284 + PRBool isOldVersion = PR_FALSE; 1.285 + PRBool internal; 1.286 + PRBool isFIPS; 1.287 + PRBool isModuleDB =PR_FALSE; 1.288 + PRBool isModuleDBOnly =PR_FALSE; 1.289 + PRBool extended =PR_FALSE; 1.290 + int i; 1.291 + 1.292 + 1.293 + arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE); 1.294 + if (arena == NULL) 1.295 + return NULL; 1.296 + 1.297 +#define CHECK_SIZE(x) \ 1.298 + if ((unsigned int) data->size < (unsigned int)(x)) goto db_loser 1.299 + 1.300 + /* ------------------------------------------------------------- 1.301 + ** Process the buffer header, which is the lgdbData struct. 1.302 + ** It may be an old or new version. Check the length for each. 1.303 + */ 1.304 + 1.305 + CHECK_SIZE( offsetof(lgdbData, trustOrder[0]) ); 1.306 + 1.307 + encoded = (lgdbData *)data->data; 1.308 + 1.309 + internal = (encoded->internal != 0) ? PR_TRUE: PR_FALSE; 1.310 + isFIPS = (encoded->fips != 0) ? PR_TRUE: PR_FALSE; 1.311 + 1.312 + if (retInternal) 1.313 + *retInternal = internal; 1.314 + if (internal) { 1.315 + parameters = PORT_ArenaStrdup(arena,defParams); 1.316 + if (parameters == NULL) 1.317 + goto loser; 1.318 + } 1.319 + if (internal && (encoded->major == LGDB_DB_NOUI_VERSION_MAJOR) && 1.320 + (encoded->minor <= LGDB_DB_NOUI_VERSION_MINOR)) { 1.321 + isOldVersion = PR_TRUE; 1.322 + } 1.323 + if ((encoded->major == LGDB_DB_EXT1_VERSION_MAJOR) && 1.324 + (encoded->minor >= LGDB_DB_EXT1_VERSION_MINOR)) { 1.325 + CHECK_SIZE( sizeof(lgdbData)); 1.326 + trustOrder = LGDB_GETLONG(encoded->trustOrder); 1.327 + cipherOrder = LGDB_GETLONG(encoded->cipherOrder); 1.328 + isModuleDB = (encoded->isModuleDB != 0) ? PR_TRUE: PR_FALSE; 1.329 + isModuleDBOnly = (encoded->isModuleDBOnly != 0) ? PR_TRUE: PR_FALSE; 1.330 + extended = PR_TRUE; 1.331 + } 1.332 + if (internal && !extended) { 1.333 + trustOrder = 0; 1.334 + cipherOrder = 100; 1.335 + } 1.336 + /* decode SSL cipher enable flags */ 1.337 + ssl0 = LGDB_GETLONG(encoded->ssl); 1.338 + ssl1 = LGDB_GETLONG(encoded->ssl + 4); 1.339 + 1.340 + slotOffset = LGDB_GETSHORT(encoded->slotOffset); 1.341 + namesOffset = LGDB_GETSHORT(encoded->nameStart); 1.342 + 1.343 + 1.344 + /*-------------------------------------------------------------- 1.345 + ** Now process the variable length set of names. 1.346 + ** The names have this structure: 1.347 + ** struct { 1.348 + ** BYTE commonNameLen[ 2 ]; 1.349 + ** BYTE commonName [ commonNameLen ]; 1.350 + ** BTTE libNameLen [ 2 ]; 1.351 + ** BYTE libName [ libNameLen ]; 1.352 + ** If it is "extended" it also has these members: 1.353 + ** BYTE initStringLen[ 2 ]; 1.354 + ** BYTE initString [ initStringLen ]; 1.355 + ** } 1.356 + */ 1.357 + 1.358 + namesRunningOffset = namesOffset; 1.359 + /* copy the module's common name */ 1.360 + CHECK_SIZE( namesRunningOffset + 2); 1.361 + names = (unsigned char *)data->data; 1.362 + len = LGDB_GETSHORT(names+namesRunningOffset); 1.363 + 1.364 + CHECK_SIZE( namesRunningOffset + 2 + len); 1.365 + commonName = (char*)PORT_ArenaAlloc(arena,len+1); 1.366 + if (commonName == NULL) 1.367 + goto loser; 1.368 + PORT_Memcpy(commonName, names + namesRunningOffset + 2, len); 1.369 + commonName[len] = 0; 1.370 + namesRunningOffset += len + 2; 1.371 + 1.372 + /* copy the module's shared library file name. */ 1.373 + CHECK_SIZE( namesRunningOffset + 2); 1.374 + len = LGDB_GETSHORT(names + namesRunningOffset); 1.375 + if (len) { 1.376 + CHECK_SIZE( namesRunningOffset + 2 + len); 1.377 + dllName = (char*)PORT_ArenaAlloc(arena,len + 1); 1.378 + if (dllName == NULL) 1.379 + goto loser; 1.380 + PORT_Memcpy(dllName, names + namesRunningOffset + 2, len); 1.381 + dllName[len] = 0; 1.382 + } 1.383 + namesRunningOffset += len + 2; 1.384 + 1.385 + /* copy the module's initialization string, if present. */ 1.386 + if (!internal && extended) { 1.387 + CHECK_SIZE( namesRunningOffset + 2); 1.388 + len = LGDB_GETSHORT(names+namesRunningOffset); 1.389 + if (len) { 1.390 + CHECK_SIZE( namesRunningOffset + 2 + len ); 1.391 + parameters = (char*)PORT_ArenaAlloc(arena,len + 1); 1.392 + if (parameters == NULL) 1.393 + goto loser; 1.394 + PORT_Memcpy(parameters,names + namesRunningOffset + 2, len); 1.395 + parameters[len] = 0; 1.396 + } 1.397 + namesRunningOffset += len + 2; 1.398 + } 1.399 + 1.400 + /* 1.401 + * Consistency check: Make sure the slot and names blocks don't 1.402 + * overlap. These blocks can occur in any order, so this check is made 1.403 + * in 2 parts. First we check the case where the slot block starts 1.404 + * after the name block. Later, when we have the slot block length, 1.405 + * we check the case where slot block starts before the name block. 1.406 + * NOTE: in most cases any overlap will likely be detected by invalid 1.407 + * data read from the blocks, but it's better to find out sooner 1.408 + * than later. 1.409 + */ 1.410 + if (slotOffset >= namesOffset) { /* slot block starts after name block */ 1.411 + if (slotOffset < namesRunningOffset) { 1.412 + goto db_loser; 1.413 + } 1.414 + } 1.415 + 1.416 + /* ------------------------------------------------------------------ 1.417 + ** Part 3, process the slot table. 1.418 + ** This part has this structure: 1.419 + ** struct { 1.420 + ** BYTE slotCount [ 2 ]; 1.421 + ** lgdbSlotData [ slotCount ]; 1.422 + ** { 1.423 + */ 1.424 + 1.425 + CHECK_SIZE( slotOffset + 2 ); 1.426 + slotCount = LGDB_GETSHORT((unsigned char *)data->data + slotOffset); 1.427 + 1.428 + /* 1.429 + * Consistency check: Part 2. We now have the slot block length, we can 1.430 + * check the case where the slotblock procedes the name block. 1.431 + */ 1.432 + if (slotOffset < namesOffset) { /* slot block starts before name block */ 1.433 + if (namesOffset < slotOffset + 2 + slotCount*sizeof(lgdbSlotData)) { 1.434 + goto db_loser; 1.435 + } 1.436 + } 1.437 + 1.438 + CHECK_SIZE( (slotOffset + 2 + slotCount * sizeof(lgdbSlotData))); 1.439 + slots = (lgdbSlotData *) ((unsigned char *)data->data + slotOffset + 2); 1.440 + 1.441 + /* slotCount; */ 1.442 + slotStrings = (char **)PORT_ArenaZAlloc(arena, slotCount * sizeof(char *)); 1.443 + if (slotStrings == NULL) 1.444 + goto loser; 1.445 + for (i=0; i < (int) slotCount; i++, slots++) { 1.446 + PRBool hasRootCerts =PR_FALSE; 1.447 + PRBool hasRootTrust =PR_FALSE; 1.448 + slotID = LGDB_GETLONG(slots->slotID); 1.449 + defaultFlags = LGDB_GETLONG(slots->defaultFlags); 1.450 + timeout = LGDB_GETLONG(slots->timeout); 1.451 + hasRootCerts = slots->hasRootCerts; 1.452 + if (isOldVersion && internal && (slotID != 2)) { 1.453 + unsigned long internalFlags= 1.454 + NSSUTIL_ArgParseSlotFlags("slotFlags", 1.455 + NSSUTIL_DEFAULT_SFTKN_FLAGS); 1.456 + defaultFlags |= internalFlags; 1.457 + } 1.458 + if (hasRootCerts && !extended) { 1.459 + trustOrder = 100; 1.460 + } 1.461 + 1.462 + slotStrings[i] = NSSUTIL_MkSlotString(slotID, defaultFlags, timeout, 1.463 + (unsigned char)slots->askpw, 1.464 + hasRootCerts, hasRootTrust); 1.465 + if (slotStrings[i] == NULL) { 1.466 + lgdb_FreeSlotStrings(slotStrings,i); 1.467 + goto loser; 1.468 + } 1.469 + } 1.470 + 1.471 + nss = NSSUTIL_MkNSSString(slotStrings, slotCount, internal, isFIPS, 1.472 + isModuleDB, isModuleDBOnly, internal, trustOrder, 1.473 + cipherOrder, ssl0, ssl1); 1.474 + lgdb_FreeSlotStrings(slotStrings,slotCount); 1.475 + /* it's permissible (and normal) for nss to be NULL. it simply means 1.476 + * there are no NSS specific parameters in the database */ 1.477 + moduleSpec = NSSUTIL_MkModuleSpec(dllName,commonName,parameters,nss); 1.478 + PR_smprintf_free(nss); 1.479 + PORT_FreeArena(arena,PR_TRUE); 1.480 + return moduleSpec; 1.481 + 1.482 +db_loser: 1.483 + PORT_SetError(SEC_ERROR_BAD_DATABASE); 1.484 +loser: 1.485 + PORT_FreeArena(arena,PR_TRUE); 1.486 + return NULL; 1.487 +} 1.488 + 1.489 +static DB * 1.490 +lgdb_OpenDB(const char *appName, const char *filename, const char *dbName, 1.491 + PRBool readOnly, PRBool update) 1.492 +{ 1.493 + DB *pkcs11db = NULL; 1.494 + 1.495 + 1.496 + if (appName) { 1.497 + char *secname = PORT_Strdup(filename); 1.498 + int len = strlen(secname); 1.499 + int status = RDB_FAIL; 1.500 + 1.501 + if (len >= 3 && PORT_Strcmp(&secname[len-3],".db") == 0) { 1.502 + secname[len-3] = 0; 1.503 + } 1.504 + pkcs11db= 1.505 + rdbopen(appName, "", secname, readOnly ? NO_RDONLY:NO_RDWR, NULL); 1.506 + if (update && !pkcs11db) { 1.507 + DB *updatedb; 1.508 + 1.509 + pkcs11db = rdbopen(appName, "", secname, NO_CREATE, &status); 1.510 + if (!pkcs11db) { 1.511 + if (status == RDB_RETRY) { 1.512 + pkcs11db= rdbopen(appName, "", secname, 1.513 + readOnly ? NO_RDONLY:NO_RDWR, NULL); 1.514 + } 1.515 + PORT_Free(secname); 1.516 + return pkcs11db; 1.517 + } 1.518 + updatedb = dbopen(dbName, NO_RDONLY, 0600, DB_HASH, 0); 1.519 + if (updatedb) { 1.520 + db_Copy(pkcs11db,updatedb); 1.521 + (*updatedb->close)(updatedb); 1.522 + } else { 1.523 + (*pkcs11db->close)(pkcs11db); 1.524 + PORT_Free(secname); 1.525 + return NULL; 1.526 + } 1.527 + } 1.528 + PORT_Free(secname); 1.529 + return pkcs11db; 1.530 + } 1.531 + 1.532 + /* I'm sure we should do more checks here sometime... */ 1.533 + pkcs11db = dbopen(dbName, readOnly ? NO_RDONLY : NO_RDWR, 0600, DB_HASH, 0); 1.534 + 1.535 + /* didn't exist? create it */ 1.536 + if (pkcs11db == NULL) { 1.537 + if (readOnly) 1.538 + return NULL; 1.539 + 1.540 + pkcs11db = dbopen( dbName, NO_CREATE, 0600, DB_HASH, 0 ); 1.541 + if (pkcs11db) 1.542 + (* pkcs11db->sync)(pkcs11db, 0); 1.543 + } 1.544 + return pkcs11db; 1.545 +} 1.546 + 1.547 +static void 1.548 +lgdb_CloseDB(DB *pkcs11db) 1.549 +{ 1.550 + (*pkcs11db->close)(pkcs11db); 1.551 +} 1.552 + 1.553 + 1.554 +SECStatus legacy_AddSecmodDB(const char *appName, const char *filename, 1.555 + const char *dbname, char *module, PRBool rw); 1.556 + 1.557 +#define LGDB_STEP 10 1.558 +/* 1.559 + * Read all the existing modules in 1.560 + */ 1.561 +char ** 1.562 +legacy_ReadSecmodDB(const char *appName, const char *filename, 1.563 + const char *dbname, char *params, PRBool rw) 1.564 +{ 1.565 + DBT key,data; 1.566 + int ret; 1.567 + DB *pkcs11db = NULL; 1.568 + char **moduleList = NULL, **newModuleList = NULL; 1.569 + int moduleCount = 1; 1.570 + int useCount = LGDB_STEP; 1.571 + 1.572 + moduleList = (char **) PORT_ZAlloc(useCount*sizeof(char **)); 1.573 + if (moduleList == NULL) return NULL; 1.574 + 1.575 + pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_TRUE,rw); 1.576 + if (pkcs11db == NULL) goto done; 1.577 + 1.578 + /* read and parse the file or data base */ 1.579 + ret = (*pkcs11db->seq)(pkcs11db, &key, &data, R_FIRST); 1.580 + if (ret) goto done; 1.581 + 1.582 + 1.583 + do { 1.584 + char *moduleString; 1.585 + PRBool internal = PR_FALSE; 1.586 + if ((moduleCount+1) >= useCount) { 1.587 + useCount += LGDB_STEP; 1.588 + newModuleList = 1.589 + (char **)PORT_Realloc(moduleList,useCount*sizeof(char *)); 1.590 + if (newModuleList == NULL) goto done; 1.591 + moduleList = newModuleList; 1.592 + PORT_Memset(&moduleList[moduleCount+1],0, 1.593 + sizeof(char *)*LGDB_STEP); 1.594 + } 1.595 + moduleString = lgdb_DecodeData(params,&data,&internal); 1.596 + if (internal) { 1.597 + moduleList[0] = moduleString; 1.598 + } else { 1.599 + moduleList[moduleCount] = moduleString; 1.600 + moduleCount++; 1.601 + } 1.602 + } while ( (*pkcs11db->seq)(pkcs11db, &key, &data, R_NEXT) == 0); 1.603 + 1.604 +done: 1.605 + if (!moduleList[0]) { 1.606 + char * newparams = NSSUTIL_Quote(params,'"'); 1.607 + if (newparams) { 1.608 + moduleList[0] = PR_smprintf( 1.609 + NSSUTIL_DEFAULT_INTERNAL_INIT1 "%s" 1.610 + NSSUTIL_DEFAULT_INTERNAL_INIT2 "%s" 1.611 + NSSUTIL_DEFAULT_INTERNAL_INIT3, 1.612 + newparams, NSSUTIL_DEFAULT_SFTKN_FLAGS); 1.613 + PORT_Free(newparams); 1.614 + } 1.615 + } 1.616 + /* deal with trust cert db here */ 1.617 + 1.618 + if (pkcs11db) { 1.619 + lgdb_CloseDB(pkcs11db); 1.620 + } else if (moduleList[0] && rw) { 1.621 + legacy_AddSecmodDB(appName,filename,dbname,moduleList[0], rw) ; 1.622 + } 1.623 + if (!moduleList[0]) { 1.624 + PORT_Free(moduleList); 1.625 + moduleList = NULL; 1.626 + } 1.627 + return moduleList; 1.628 +} 1.629 + 1.630 +SECStatus 1.631 +legacy_ReleaseSecmodDBData(const char *appName, const char *filename, 1.632 + const char *dbname, char **moduleSpecList, PRBool rw) 1.633 +{ 1.634 + if (moduleSpecList) { 1.635 + char **index; 1.636 + for(index = moduleSpecList; *index; index++) { 1.637 + PR_smprintf_free(*index); 1.638 + } 1.639 + PORT_Free(moduleSpecList); 1.640 + } 1.641 + return SECSuccess; 1.642 +} 1.643 + 1.644 +/* 1.645 + * Delete a module from the Data Base 1.646 + */ 1.647 +SECStatus 1.648 +legacy_DeleteSecmodDB(const char *appName, const char *filename, 1.649 + const char *dbname, char *args, PRBool rw) 1.650 +{ 1.651 + DBT key; 1.652 + SECStatus rv = SECFailure; 1.653 + DB *pkcs11db = NULL; 1.654 + int ret; 1.655 + 1.656 + if (!rw) return SECFailure; 1.657 + 1.658 + /* make sure we have a db handle */ 1.659 + pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE); 1.660 + if (pkcs11db == NULL) { 1.661 + return SECFailure; 1.662 + } 1.663 + 1.664 + rv = lgdb_MakeKey(&key,args); 1.665 + if (rv != SECSuccess) goto done; 1.666 + rv = SECFailure; 1.667 + ret = (*pkcs11db->del)(pkcs11db, &key, 0); 1.668 + lgdb_FreeKey(&key); 1.669 + if (ret != 0) goto done; 1.670 + 1.671 + 1.672 + ret = (*pkcs11db->sync)(pkcs11db, 0); 1.673 + if (ret == 0) rv = SECSuccess; 1.674 + 1.675 +done: 1.676 + lgdb_CloseDB(pkcs11db); 1.677 + return rv; 1.678 +} 1.679 + 1.680 +/* 1.681 + * Add a module to the Data base 1.682 + */ 1.683 +SECStatus 1.684 +legacy_AddSecmodDB(const char *appName, const char *filename, 1.685 + const char *dbname, char *module, PRBool rw) 1.686 +{ 1.687 + DBT key,data; 1.688 + SECStatus rv = SECFailure; 1.689 + DB *pkcs11db = NULL; 1.690 + int ret; 1.691 + 1.692 + 1.693 + if (!rw) return SECFailure; 1.694 + 1.695 + /* make sure we have a db handle */ 1.696 + pkcs11db = lgdb_OpenDB(appName,filename,dbname,PR_FALSE,PR_FALSE); 1.697 + if (pkcs11db == NULL) { 1.698 + return SECFailure; 1.699 + } 1.700 + 1.701 + rv = lgdb_MakeKey(&key,module); 1.702 + if (rv != SECSuccess) goto done; 1.703 + rv = lgdb_EncodeData(&data,module); 1.704 + if (rv != SECSuccess) { 1.705 + lgdb_FreeKey(&key); 1.706 + goto done; 1.707 + } 1.708 + rv = SECFailure; 1.709 + ret = (*pkcs11db->put)(pkcs11db, &key, &data, 0); 1.710 + lgdb_FreeKey(&key); 1.711 + lgdb_FreeData(&data); 1.712 + if (ret != 0) goto done; 1.713 + 1.714 + ret = (*pkcs11db->sync)(pkcs11db, 0); 1.715 + if (ret == 0) rv = SECSuccess; 1.716 + 1.717 +done: 1.718 + lgdb_CloseDB(pkcs11db); 1.719 + return rv; 1.720 +}