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