1 /* ***** BEGIN LICENSE BLOCK *****
2 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 * The contents of this file are subject to the Mozilla Public License Version
5 * 1.1 (the "License"); you may not use this file except in compliance with
6 * the License. You may obtain a copy of the License at
7 * http://www.mozilla.org/MPL/
9 * Software distributed under the License is distributed on an "AS IS" basis,
10 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
11 * for the specific language governing rights and limitations under the
14 * The Original Code is the Netscape security libraries.
16 * The Initial Developer of the Original Code is
17 * Netscape Communications Corporation.
18 * Portions created by the Initial Developer are Copyright (C) 1994-2000
19 * the Initial Developer. All Rights Reserved.
23 * Alternatively, the contents of this file may be used under the terms of
24 * either the GNU General Public License Version 2 or later (the "GPL"), or
25 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
26 * in which case the provisions of the GPL or the LGPL are applicable instead
27 * of those above. If you wish to allow use of your version of this file only
28 * under the terms of either the GPL or the LGPL, and not to allow others to
29 * use your version of this file under the terms of the MPL, indicate your
30 * decision by deleting the provisions above and replace them with the notice
31 * and other provisions required by the GPL or the LGPL. If you do not delete
32 * the provisions above, a recipient may use your version of this file under
33 * the terms of any one of the MPL, the GPL or the LGPL.
35 * ***** END LICENSE BLOCK ***** */
37 * The following code handles the storage of PKCS 11 modules used by the
38 * NSS. This file is written to abstract away how the modules are
39 * stored so we can deside that later.
47 #define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
49 /* Construct a database key for a given module */
50 static SECStatus
secmod_MakeKey(DBT
*key
, char * module
) {
54 commonName
= secmod_argGetParamValue("name",module
);
55 if (commonName
== NULL
) {
56 commonName
= secmod_argGetParamValue("library",module
);
58 if (commonName
== NULL
) return SECFailure
;
59 len
= PORT_Strlen(commonName
);
60 key
->data
= commonName
;
65 /* free out constructed database key */
67 secmod_FreeKey(DBT
*key
)
76 typedef struct secmodDataStr secmodData
;
77 typedef struct secmodSlotDataStr secmodSlotData
;
78 struct secmodDataStr
{
81 unsigned char nameStart
[2];
82 unsigned char slotOffset
[2];
83 unsigned char internal
;
86 unsigned char trustOrder
[4];
87 unsigned char cipherOrder
[4];
88 unsigned char reserved1
;
89 unsigned char isModuleDB
;
90 unsigned char isModuleDBOnly
;
91 unsigned char isCritical
;
92 unsigned char reserved
[4];
93 unsigned char names
[6]; /* enough space for the length fields */
96 struct secmodSlotDataStr
{
97 unsigned char slotID
[4];
98 unsigned char defaultFlags
[4];
99 unsigned char timeout
[4];
101 unsigned char hasRootCerts
;
102 unsigned char reserved
[18]; /* this makes it a round 32 bytes */
105 #define SECMOD_DB_VERSION_MAJOR 0
106 #define SECMOD_DB_VERSION_MINOR 6
107 #define SECMOD_DB_EXT1_VERSION_MAJOR 0
108 #define SECMOD_DB_EXT1_VERSION_MINOR 6
109 #define SECMOD_DB_NOUI_VERSION_MAJOR 0
110 #define SECMOD_DB_NOUI_VERSION_MINOR 4
112 #define SECMOD_PUTSHORT(dest,src) \
113 (dest)[1] = (unsigned char) ((src)&0xff); \
114 (dest)[0] = (unsigned char) (((src) >> 8) & 0xff);
115 #define SECMOD_PUTLONG(dest,src) \
116 (dest)[3] = (unsigned char) ((src)&0xff); \
117 (dest)[2] = (unsigned char) (((src) >> 8) & 0xff); \
118 (dest)[1] = (unsigned char) (((src) >> 16) & 0xff); \
119 (dest)[0] = (unsigned char) (((src) >> 24) & 0xff);
120 #define SECMOD_GETSHORT(src) \
121 ((unsigned short) (((src)[0] << 8) | (src)[1]))
122 #define SECMOD_GETLONG(src) \
123 ((unsigned long) (( (unsigned long) (src)[0] << 24) | \
124 ( (unsigned long) (src)[1] << 16) | \
125 ( (unsigned long) (src)[2] << 8) | \
126 (unsigned long) (src)[3]))
129 * build a data base entry from a module
132 secmod_EncodeData(DBT
*data
, char * module
)
134 secmodData
*encoded
= NULL
;
135 secmodSlotData
*slot
;
136 unsigned char *dataPtr
;
137 unsigned short len
, len2
= 0, len3
= 0;
139 unsigned short offset
;
142 unsigned long ssl
[2];
143 char *commonName
= NULL
, *dllName
= NULL
, *param
= NULL
, *nss
= NULL
;
144 char *slotParams
, *ciphers
;
145 PK11PreSlotInfo
*slotInfo
= NULL
;
146 SECStatus rv
= SECFailure
;
148 rv
= secmod_argParseModuleSpec(module
,&dllName
,&commonName
,¶m
,&nss
);
149 if (rv
!= SECSuccess
) return rv
;
152 if (commonName
== NULL
) {
157 len
= PORT_Strlen(commonName
);
159 len2
= PORT_Strlen(dllName
);
162 len3
= PORT_Strlen(param
);
165 slotParams
= secmod_argGetParamValue("slotParams",nss
);
166 slotInfo
= secmod_argParseSlotInfo(NULL
,slotParams
,&count
);
167 if (slotParams
) PORT_Free(slotParams
);
169 if (count
&& slotInfo
== NULL
) {
174 dataLen
= sizeof(secmodData
) + len
+ len2
+ len3
+ sizeof(unsigned short) +
175 count
*sizeof(secmodSlotData
);
177 data
->data
= (unsigned char *) PORT_ZAlloc(dataLen
);
178 encoded
= (secmodData
*)data
->data
;
179 dataPtr
= (unsigned char *) data
->data
;
180 data
->size
= dataLen
;
182 if (encoded
== NULL
) {
187 encoded
->major
= SECMOD_DB_VERSION_MAJOR
;
188 encoded
->minor
= SECMOD_DB_VERSION_MINOR
;
189 encoded
->internal
= (unsigned char)
190 (secmod_argHasFlag("flags","internal",nss
) ? 1 : 0);
191 encoded
->fips
= (unsigned char)
192 (secmod_argHasFlag("flags","FIPS",nss
) ? 1 : 0);
193 encoded
->isModuleDB
= (unsigned char)
194 (secmod_argHasFlag("flags","isModuleDB",nss
) ? 1 : 0);
195 encoded
->isModuleDBOnly
= (unsigned char)
196 (secmod_argHasFlag("flags","isModuleDBOnly",nss
) ? 1 : 0);
197 encoded
->isCritical
= (unsigned char)
198 (secmod_argHasFlag("flags","critical",nss
) ? 1 : 0);
200 order
= secmod_argReadLong("trustOrder", nss
, SECMOD_DEFAULT_TRUST_ORDER
,
202 SECMOD_PUTLONG(encoded
->trustOrder
,order
);
203 order
= secmod_argReadLong("cipherOrder", nss
, SECMOD_DEFAULT_CIPHER_ORDER
,
205 SECMOD_PUTLONG(encoded
->cipherOrder
,order
);
208 ciphers
= secmod_argGetParamValue("ciphers",nss
);
209 secmod_argSetNewCipherFlags(&ssl
[0], ciphers
);
210 SECMOD_PUTLONG(encoded
->ssl
,ssl
[0]);
211 SECMOD_PUTLONG(&encoded
->ssl
[4],ssl
[1]);
212 if (ciphers
) PORT_Free(ciphers
);
214 offset
= (unsigned short) &(((secmodData
*)0)->names
[0]);
215 SECMOD_PUTSHORT(encoded
->nameStart
,offset
);
216 offset
= offset
+ len
+ len2
+ len3
+ 3*sizeof(unsigned short);
217 SECMOD_PUTSHORT(encoded
->slotOffset
,offset
);
220 SECMOD_PUTSHORT(&dataPtr
[offset
],((unsigned short)count
));
221 slot
= (secmodSlotData
*)(dataPtr
+offset
+sizeof(unsigned short));
224 SECMOD_PUTSHORT(encoded
->names
,len
);
225 offset
+= sizeof(unsigned short);
226 PORT_Memcpy(&encoded
->names
[offset
],commonName
,len
);
230 SECMOD_PUTSHORT(&encoded
->names
[offset
],len2
);
231 offset
+= sizeof(unsigned short);
232 if (len2
) PORT_Memcpy(&encoded
->names
[offset
],dllName
,len2
);
235 SECMOD_PUTSHORT(&encoded
->names
[offset
],len3
);
236 offset
+= sizeof(unsigned short);
237 if (len3
) PORT_Memcpy(&encoded
->names
[offset
],param
,len3
);
241 for (i
=0; i
< count
; i
++) {
242 SECMOD_PUTLONG(slot
[i
].slotID
, slotInfo
[i
].slotID
);
243 SECMOD_PUTLONG(slot
[i
].defaultFlags
,
244 slotInfo
[i
].defaultFlags
);
245 SECMOD_PUTLONG(slot
[i
].timeout
,slotInfo
[i
].timeout
);
246 slot
[i
].askpw
= slotInfo
[i
].askpw
;
247 slot
[i
].hasRootCerts
= slotInfo
[i
].hasRootCerts
;
248 PORT_Memset(slot
[i
].reserved
, 0, sizeof(slot
[i
].reserved
));
254 if (commonName
) PORT_Free(commonName
);
255 if (dllName
) PORT_Free(dllName
);
256 if (param
) PORT_Free(param
);
257 if (slotInfo
) PORT_Free(slotInfo
);
258 if (nss
) PORT_Free(nss
);
264 secmod_FreeData(DBT
*data
)
267 PORT_Free(data
->data
);
272 secmod_FreeSlotStrings(char **slotStrings
, int count
)
276 for (i
=0; i
< count
; i
++) {
277 if (slotStrings
[i
]) {
278 PR_smprintf_free(slotStrings
[i
]);
279 slotStrings
[i
] = NULL
;
285 * build a module from the data base entry.
288 secmod_DecodeData(char *defParams
, DBT
*data
, PRBool
*retInternal
)
291 secmodSlotData
*slots
;
293 char *commonName
= NULL
;
294 char *dllName
= NULL
;
295 char *parameters
= NULL
;
298 char **slotStrings
= NULL
;
299 unsigned char *names
;
300 unsigned long slotCount
;
301 unsigned long ssl0
=0;
302 unsigned long ssl1
=0;
303 unsigned long slotID
;
304 unsigned long defaultFlags
;
305 unsigned long timeout
;
306 unsigned long trustOrder
=SECMOD_DEFAULT_TRUST_ORDER
;
307 unsigned long cipherOrder
=SECMOD_DEFAULT_CIPHER_ORDER
;
309 unsigned short namesOffset
= 0; /* start of the names block */
310 unsigned long namesRunningOffset
; /* offset to name we are
311 * currently processing */
312 unsigned short slotOffset
;
313 PRBool isOldVersion
= PR_FALSE
;
316 PRBool isModuleDB
=PR_FALSE
;
317 PRBool isModuleDBOnly
=PR_FALSE
;
318 PRBool extended
=PR_FALSE
;
322 arena
= PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE
);
326 #define CHECK_SIZE(x) \
327 if ((unsigned int) data->size < (unsigned int)(x)) goto db_loser
329 /* -------------------------------------------------------------
330 ** Process the buffer header, which is the secmodData struct.
331 ** It may be an old or new version. Check the length for each.
334 CHECK_SIZE( offsetof(secmodData
, trustOrder
[0]) );
336 encoded
= (secmodData
*)data
->data
;
338 internal
= (encoded
->internal
!= 0) ? PR_TRUE
: PR_FALSE
;
339 isFIPS
= (encoded
->fips
!= 0) ? PR_TRUE
: PR_FALSE
;
342 *retInternal
= internal
;
344 parameters
= PORT_ArenaStrdup(arena
,defParams
);
345 if (parameters
== NULL
)
348 if (internal
&& (encoded
->major
== SECMOD_DB_NOUI_VERSION_MAJOR
) &&
349 (encoded
->minor
<= SECMOD_DB_NOUI_VERSION_MINOR
)) {
350 isOldVersion
= PR_TRUE
;
352 if ((encoded
->major
== SECMOD_DB_EXT1_VERSION_MAJOR
) &&
353 (encoded
->minor
>= SECMOD_DB_EXT1_VERSION_MINOR
)) {
354 CHECK_SIZE( sizeof(secmodData
));
355 trustOrder
= SECMOD_GETLONG(encoded
->trustOrder
);
356 cipherOrder
= SECMOD_GETLONG(encoded
->cipherOrder
);
357 isModuleDB
= (encoded
->isModuleDB
!= 0) ? PR_TRUE
: PR_FALSE
;
358 isModuleDBOnly
= (encoded
->isModuleDBOnly
!= 0) ? PR_TRUE
: PR_FALSE
;
361 if (internal
&& !extended
) {
365 /* decode SSL cipher enable flags */
366 ssl0
= SECMOD_GETLONG(encoded
->ssl
);
367 ssl1
= SECMOD_GETLONG(encoded
->ssl
+ 4);
369 slotOffset
= SECMOD_GETSHORT(encoded
->slotOffset
);
370 namesOffset
= SECMOD_GETSHORT(encoded
->nameStart
);
373 /*--------------------------------------------------------------
374 ** Now process the variable length set of names.
375 ** The names have this structure:
377 ** BYTE commonNameLen[ 2 ];
378 ** BYTE commonName [ commonNameLen ];
379 ** BTTE libNameLen [ 2 ];
380 ** BYTE libName [ libNameLen ];
381 ** If it is "extended" it also has these members:
382 ** BYTE initStringLen[ 2 ];
383 ** BYTE initString [ initStringLen ];
387 namesRunningOffset
= namesOffset
;
388 /* copy the module's common name */
389 CHECK_SIZE( namesRunningOffset
+ 2);
390 names
= (unsigned char *)data
->data
;
391 len
= SECMOD_GETSHORT(names
+namesRunningOffset
);
393 CHECK_SIZE( namesRunningOffset
+ 2 + len
);
394 commonName
= (char*)PORT_ArenaAlloc(arena
,len
+1);
395 if (commonName
== NULL
)
397 PORT_Memcpy(commonName
, names
+ namesRunningOffset
+ 2, len
);
399 namesRunningOffset
+= len
+ 2;
401 /* copy the module's shared library file name. */
402 CHECK_SIZE( namesRunningOffset
+ 2);
403 len
= SECMOD_GETSHORT(names
+ namesRunningOffset
);
405 CHECK_SIZE( namesRunningOffset
+ 2 + len
);
406 dllName
= (char*)PORT_ArenaAlloc(arena
,len
+ 1);
409 PORT_Memcpy(dllName
, names
+ namesRunningOffset
+ 2, len
);
412 namesRunningOffset
+= len
+ 2;
414 /* copy the module's initialization string, if present. */
415 if (!internal
&& extended
) {
416 CHECK_SIZE( namesRunningOffset
+ 2);
417 len
= SECMOD_GETSHORT(names
+namesRunningOffset
);
419 CHECK_SIZE( namesRunningOffset
+ 2 + len
);
420 parameters
= (char*)PORT_ArenaAlloc(arena
,len
+ 1);
421 if (parameters
== NULL
)
423 PORT_Memcpy(parameters
,names
+ namesRunningOffset
+ 2, len
);
426 namesRunningOffset
+= len
+ 2;
430 * Consistency check: Make sure the slot and names blocks don't
431 * overlap. These blocks can occur in any order, so this check is made
432 * in 2 parts. First we check the case where the slot block starts
433 * after the name block. Later, when we have the slot block length,
434 * we check the case where slot block starts before the name block.
435 * NOTE: in most cases any overlap will likely be detected by invalid
436 * data read from the blocks, but it's better to find out sooner
439 if (slotOffset
>= namesOffset
) { /* slot block starts after name block */
440 if (slotOffset
< namesRunningOffset
) {
445 /* ------------------------------------------------------------------
446 ** Part 3, process the slot table.
447 ** This part has this structure:
449 ** BYTE slotCount [ 2 ];
450 ** secmodSlotData [ slotCount ];
454 CHECK_SIZE( slotOffset
+ 2 );
455 slotCount
= SECMOD_GETSHORT((unsigned char *)data
->data
+ slotOffset
);
458 * Consistency check: Part 2. We now have the slot block length, we can
459 * check the case where the slotblock procedes the name block.
461 if (slotOffset
< namesOffset
) { /* slot block starts before name block */
462 if (namesOffset
< slotOffset
+ 2 + slotCount
*sizeof(secmodSlotData
)) {
467 CHECK_SIZE( (slotOffset
+ 2 + slotCount
* sizeof(secmodSlotData
)));
468 slots
= (secmodSlotData
*) ((unsigned char *)data
->data
+ slotOffset
+ 2);
471 slotStrings
= (char **)PORT_ArenaZAlloc(arena
, slotCount
* sizeof(char *));
472 if (slotStrings
== NULL
)
474 for (i
=0; i
< (int) slotCount
; i
++, slots
++) {
475 PRBool hasRootCerts
=PR_FALSE
;
476 PRBool hasRootTrust
=PR_FALSE
;
477 slotID
= SECMOD_GETLONG(slots
->slotID
);
478 defaultFlags
= SECMOD_GETLONG(slots
->defaultFlags
);
479 timeout
= SECMOD_GETLONG(slots
->timeout
);
480 hasRootCerts
= slots
->hasRootCerts
;
481 if (isOldVersion
&& internal
&& (slotID
!= 2)) {
482 unsigned long internalFlags
=
483 secmod_argSlotFlags("slotFlags",SECMOD_SLOT_FLAGS
);
484 defaultFlags
|= internalFlags
;
486 if (hasRootCerts
&& !extended
) {
490 slotStrings
[i
] = secmod_mkSlotString(slotID
, defaultFlags
, timeout
,
491 (unsigned char)slots
->askpw
,
492 hasRootCerts
, hasRootTrust
);
493 if (slotStrings
[i
] == NULL
) {
494 secmod_FreeSlotStrings(slotStrings
,i
);
499 nss
= secmod_mkNSS(slotStrings
, slotCount
, internal
, isFIPS
, isModuleDB
,
500 isModuleDBOnly
, internal
, trustOrder
, cipherOrder
,
502 secmod_FreeSlotStrings(slotStrings
,slotCount
);
503 /* it's permissible (and normal) for nss to be NULL. it simply means
504 * there are no NSS specific parameters in the database */
505 moduleSpec
= secmod_mkNewModuleSpec(dllName
,commonName
,parameters
,nss
);
506 PR_smprintf_free(nss
);
507 PORT_FreeArena(arena
,PR_TRUE
);
511 PORT_SetError(SEC_ERROR_BAD_DATABASE
);
513 PORT_FreeArena(arena
,PR_TRUE
);
518 secmod_OpenDB(const char *appName
, const char *filename
, const char *dbName
,
519 PRBool readOnly
, PRBool update
)
525 char *secname
= PORT_Strdup(filename
);
526 int len
= strlen(secname
);
527 int status
= RDB_FAIL
;
529 if (len
>= 3 && PORT_Strcmp(&secname
[len
-3],".db") == 0) {
533 rdbopen(appName
, "", secname
, readOnly
? NO_RDONLY
:NO_RDWR
, NULL
);
534 if (update
&& !pkcs11db
) {
537 pkcs11db
= rdbopen(appName
, "", secname
, NO_CREATE
, &status
);
539 if (status
== RDB_RETRY
) {
540 pkcs11db
= rdbopen(appName
, "", secname
,
541 readOnly
? NO_RDONLY
:NO_RDWR
, NULL
);
546 updatedb
= dbopen(dbName
, NO_RDONLY
, 0600, DB_HASH
, 0);
548 db_Copy(pkcs11db
,updatedb
);
549 (*updatedb
->close
)(updatedb
);
551 (*pkcs11db
->close
)(pkcs11db
);
560 /* I'm sure we should do more checks here sometime... */
561 pkcs11db
= dbopen(dbName
, readOnly
? NO_RDONLY
: NO_RDWR
, 0600, DB_HASH
, 0);
563 /* didn't exist? create it */
564 if (pkcs11db
== NULL
) {
568 pkcs11db
= dbopen( dbName
, NO_CREATE
, 0600, DB_HASH
, 0 );
570 (* pkcs11db
->sync
)(pkcs11db
, 0);
576 secmod_CloseDB(DB
*pkcs11db
)
578 (*pkcs11db
->close
)(pkcs11db
);
582 secmod_addEscape(const char *string
, char quote
)
585 int escapes
= 0, size
= 0;
589 for (src
=string
; *src
; src
++) {
590 if ((*src
== quote
) || (*src
== '\\')) escapes
++;
594 newString
= PORT_ZAlloc(escapes
+size
+1);
595 if (newString
== NULL
) {
599 for (src
=string
, dest
=newString
; *src
; src
++,dest
++) {
600 if ((*src
== '\\') || (*src
== quote
)) {
609 SECStatus
legacy_AddSecmodDB(const char *appName
, const char *filename
,
610 const char *dbname
, char *module
, PRBool rw
);
612 #define SECMOD_STEP 10
613 #define SFTK_DEFAULT_INTERNAL_INIT "library= name=\"NSS Internal PKCS #11 Module\" parameters=\"%s\" NSS=\"Flags=internal,critical trustOrder=75 cipherOrder=100 slotParams=(1={%s askpw=any timeout=30})\""
615 * Read all the existing modules in
618 legacy_ReadSecmodDB(const char *appName
, const char *filename
,
619 const char *dbname
, char *params
, PRBool rw
)
624 char **moduleList
= NULL
, **newModuleList
= NULL
;
626 int useCount
= SECMOD_STEP
;
628 moduleList
= (char **) PORT_ZAlloc(useCount
*sizeof(char **));
629 if (moduleList
== NULL
) return NULL
;
631 pkcs11db
= secmod_OpenDB(appName
,filename
,dbname
,PR_TRUE
,rw
);
632 if (pkcs11db
== NULL
) goto done
;
634 /* read and parse the file or data base */
635 ret
= (*pkcs11db
->seq
)(pkcs11db
, &key
, &data
, R_FIRST
);
641 PRBool internal
= PR_FALSE
;
642 if ((moduleCount
+1) >= useCount
) {
643 useCount
+= SECMOD_STEP
;
645 (char **)PORT_Realloc(moduleList
,useCount
*sizeof(char *));
646 if (newModuleList
== NULL
) goto done
;
647 moduleList
= newModuleList
;
648 PORT_Memset(&moduleList
[moduleCount
+1],0,
649 sizeof(char *)*SECMOD_STEP
);
651 moduleString
= secmod_DecodeData(params
,&data
,&internal
);
653 moduleList
[0] = moduleString
;
655 moduleList
[moduleCount
] = moduleString
;
658 } while ( (*pkcs11db
->seq
)(pkcs11db
, &key
, &data
, R_NEXT
) == 0);
661 if (!moduleList
[0]) {
662 char * newparams
= secmod_addEscape(params
,'"');
664 moduleList
[0] = PR_smprintf(SFTK_DEFAULT_INTERNAL_INIT
,newparams
,
666 PORT_Free(newparams
);
669 /* deal with trust cert db here */
672 secmod_CloseDB(pkcs11db
);
673 } else if (moduleList
[0] && rw
) {
674 legacy_AddSecmodDB(appName
,filename
,dbname
,moduleList
[0], rw
) ;
676 if (!moduleList
[0]) {
677 PORT_Free(moduleList
);
684 legacy_ReleaseSecmodDBData(const char *appName
, const char *filename
,
685 const char *dbname
, char **moduleSpecList
, PRBool rw
)
687 if (moduleSpecList
) {
689 for(index
= moduleSpecList
; *index
; index
++) {
690 PR_smprintf_free(*index
);
692 PORT_Free(moduleSpecList
);
698 * Delete a module from the Data Base
701 legacy_DeleteSecmodDB(const char *appName
, const char *filename
,
702 const char *dbname
, char *args
, PRBool rw
)
705 SECStatus rv
= SECFailure
;
709 if (!rw
) return SECFailure
;
711 /* make sure we have a db handle */
712 pkcs11db
= secmod_OpenDB(appName
,filename
,dbname
,PR_FALSE
,PR_FALSE
);
713 if (pkcs11db
== NULL
) {
717 rv
= secmod_MakeKey(&key
,args
);
718 if (rv
!= SECSuccess
) goto done
;
720 ret
= (*pkcs11db
->del
)(pkcs11db
, &key
, 0);
721 secmod_FreeKey(&key
);
722 if (ret
!= 0) goto done
;
725 ret
= (*pkcs11db
->sync
)(pkcs11db
, 0);
726 if (ret
== 0) rv
= SECSuccess
;
729 secmod_CloseDB(pkcs11db
);
734 * Add a module to the Data base
737 legacy_AddSecmodDB(const char *appName
, const char *filename
,
738 const char *dbname
, char *module
, PRBool rw
)
741 SECStatus rv
= SECFailure
;
746 if (!rw
) return SECFailure
;
748 /* make sure we have a db handle */
749 pkcs11db
= secmod_OpenDB(appName
,filename
,dbname
,PR_FALSE
,PR_FALSE
);
750 if (pkcs11db
== NULL
) {
754 rv
= secmod_MakeKey(&key
,module
);
755 if (rv
!= SECSuccess
) goto done
;
756 rv
= secmod_EncodeData(&data
,module
);
757 if (rv
!= SECSuccess
) {
758 secmod_FreeKey(&key
);
762 ret
= (*pkcs11db
->put
)(pkcs11db
, &key
, &data
, 0);
763 secmod_FreeKey(&key
);
764 secmod_FreeData(&data
);
765 if (ret
!= 0) goto done
;
767 ret
= (*pkcs11db
->sync
)(pkcs11db
, 0);
768 if (ret
== 0) rv
= SECSuccess
;
771 secmod_CloseDB(pkcs11db
);