2001-08-24 21:16:48 +00:00
|
|
|
/*
|
|
|
|
* NSS utility functions
|
|
|
|
*
|
|
|
|
* The contents of this file are subject to the Mozilla Public
|
|
|
|
* License Version 1.1 (the "License"); you may not use this file
|
|
|
|
* except in compliance with the License. You may obtain a copy of
|
|
|
|
* the License at http://www.mozilla.org/MPL/
|
|
|
|
*
|
|
|
|
* Software distributed under the License is distributed on an "AS
|
|
|
|
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
|
|
|
* implied. See the License for the specific language governing
|
|
|
|
* rights and limitations under the License.
|
|
|
|
*
|
|
|
|
* The Original Code is the Netscape security libraries.
|
|
|
|
*
|
|
|
|
* The Initial Developer of the Original Code is Netscape
|
|
|
|
* Communications Corporation. Portions created by Netscape are
|
|
|
|
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
|
|
|
|
* Rights Reserved.
|
|
|
|
*
|
|
|
|
* Contributor(s):
|
|
|
|
*
|
|
|
|
* Alternatively, the contents of this file may be used under the
|
|
|
|
* terms of the GNU General Public License Version 2 or later (the
|
|
|
|
* "GPL"), in which case the provisions of the GPL are applicable
|
|
|
|
* instead of those above. If you wish to allow use of your
|
|
|
|
* version of this file only under the terms of the GPL and not to
|
|
|
|
* allow others to use your version of this file under the MPL,
|
|
|
|
* indicate your decision by deleting the provisions above and
|
|
|
|
* replace them with the notice and other provisions required by
|
|
|
|
* the GPL. If you do not delete the provisions above, a recipient
|
|
|
|
* may use your version of this file under either the MPL or the
|
|
|
|
* GPL.
|
|
|
|
*
|
2001-08-25 21:28:16 +00:00
|
|
|
# $Id: dbinit.c,v 1.3 2001/08/25 21:28:16 mcgreer%netscape.com Exp $
|
2001-08-24 21:16:48 +00:00
|
|
|
*/
|
|
|
|
|
|
|
|
#include <ctype.h>
|
|
|
|
#include "seccomon.h"
|
|
|
|
#include "prinit.h"
|
|
|
|
#include "prprf.h"
|
|
|
|
#include "prmem.h"
|
|
|
|
#include "cert.h"
|
|
|
|
#include "key.h"
|
|
|
|
#include "ssl.h"
|
|
|
|
#include "sslproto.h"
|
|
|
|
#include "secmod.h"
|
|
|
|
#include "secmodi.h"
|
|
|
|
#include "secoid.h"
|
|
|
|
#include "nss.h"
|
|
|
|
#include "secrng.h"
|
|
|
|
#include "cdbhdl.h"
|
|
|
|
#include "pk11func.h"
|
|
|
|
|
|
|
|
#ifdef macintosh
|
|
|
|
#define PATH_SEPARATOR ":"
|
|
|
|
#define SECMOD_DB "Security Modules"
|
|
|
|
#define CERT_DB_FMT "%sCertificates%s"
|
|
|
|
#define KEY_DB_FMT "%sKey Database%s"
|
|
|
|
#else
|
|
|
|
#define PATH_SEPARATOR "/"
|
|
|
|
#define SECMOD_DB "secmod.db"
|
|
|
|
#define CERT_DB_FMT "%scert%s.db"
|
|
|
|
#define KEY_DB_FMT "%skey%s.db"
|
|
|
|
#endif
|
|
|
|
|
|
|
|
static char *secmodname = NULL;
|
|
|
|
|
|
|
|
static char *
|
|
|
|
pk11_certdb_name_cb(void *arg, int dbVersion)
|
|
|
|
{
|
|
|
|
const char *configdir = (const char *)arg;
|
|
|
|
const char *dbver;
|
|
|
|
|
|
|
|
switch (dbVersion) {
|
|
|
|
case 7:
|
|
|
|
dbver = "7";
|
|
|
|
break;
|
|
|
|
case 6:
|
|
|
|
dbver = "6";
|
|
|
|
break;
|
|
|
|
case 5:
|
|
|
|
dbver = "5";
|
|
|
|
break;
|
|
|
|
case 4:
|
|
|
|
default:
|
|
|
|
dbver = "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_smprintf(CERT_DB_FMT, configdir, dbver);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char *
|
|
|
|
pk11_keydb_name_cb(void *arg, int dbVersion)
|
|
|
|
{
|
|
|
|
const char *configdir = (const char *)arg;
|
|
|
|
const char *dbver;
|
|
|
|
|
|
|
|
switch (dbVersion) {
|
|
|
|
case 3:
|
|
|
|
dbver = "3";
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
dbver = "1";
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
default:
|
|
|
|
dbver = "";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return PR_smprintf(KEY_DB_FMT, configdir, dbver);
|
|
|
|
}
|
|
|
|
|
|
|
|
/* for now... we need to define vendor specific codes here.
|
|
|
|
*/
|
|
|
|
#define CKR_CERTDB_FAILED CKR_DEVICE_ERROR
|
|
|
|
#define CKR_KEYDB_FAILED CKR_DEVICE_ERROR
|
|
|
|
|
|
|
|
static CK_RV
|
|
|
|
pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly)
|
|
|
|
{
|
|
|
|
CERTCertDBHandle *certdb;
|
|
|
|
CK_RV crv = CKR_OK;
|
|
|
|
SECStatus rv;
|
|
|
|
char * name = NULL;
|
|
|
|
|
|
|
|
certdb = CERT_GetDefaultCertDB();
|
|
|
|
if (certdb)
|
|
|
|
return CKR_OK; /* idempotency */
|
|
|
|
|
|
|
|
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
|
|
|
|
if (name == NULL) goto loser;
|
|
|
|
|
|
|
|
certdb = (CERTCertDBHandle*)PORT_ZAlloc(sizeof(CERTCertDBHandle));
|
|
|
|
if (certdb == NULL)
|
|
|
|
goto loser;
|
|
|
|
|
|
|
|
/* fix when we get the DB in */
|
|
|
|
rv = CERT_OpenCertDB(certdb, readOnly, pk11_certdb_name_cb, (void *)name);
|
|
|
|
if (rv == SECSuccess)
|
|
|
|
CERT_SetDefaultCertDB(certdb);
|
|
|
|
else {
|
|
|
|
PR_Free(certdb);
|
|
|
|
loser:
|
|
|
|
crv = CKR_CERTDB_FAILED;
|
|
|
|
}
|
|
|
|
if (name) PORT_Free(name);
|
|
|
|
return crv;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CK_RV
|
|
|
|
pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly)
|
|
|
|
{
|
|
|
|
SECKEYKeyDBHandle *keydb;
|
|
|
|
char * name = NULL;
|
|
|
|
|
|
|
|
keydb = SECKEY_GetDefaultKeyDB();
|
|
|
|
if (keydb)
|
|
|
|
return SECSuccess;
|
|
|
|
name = PR_smprintf("%s" PATH_SEPARATOR "%s",configdir,prefix);
|
|
|
|
if (name == NULL)
|
|
|
|
return SECFailure;
|
|
|
|
keydb = SECKEY_OpenKeyDB(readOnly, pk11_keydb_name_cb, (void *)name);
|
|
|
|
if (keydb == NULL)
|
|
|
|
return CKR_KEYDB_FAILED;
|
|
|
|
SECKEY_SetDefaultKeyDB(keydb);
|
|
|
|
PORT_Free(name);
|
|
|
|
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
static CERTCertDBHandle certhandle = { 0 };
|
|
|
|
|
|
|
|
static PRBool isInitialized = PR_FALSE;
|
|
|
|
|
|
|
|
static CK_RV
|
|
|
|
pk11_OpenVolatileCertDB() {
|
|
|
|
SECStatus rv = SECSuccess;
|
|
|
|
/* now we want to verify the signature */
|
|
|
|
/* Initialize the cert code */
|
|
|
|
rv = CERT_OpenVolatileCertDB(&certhandle);
|
|
|
|
if (rv != SECSuccess) {
|
|
|
|
return CKR_DEVICE_ERROR;
|
|
|
|
}
|
|
|
|
CERT_SetDefaultCertDB(&certhandle);
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
2001-08-25 21:28:16 +00:00
|
|
|
/* forward declare so that a failure in the init case can shutdown */
|
|
|
|
void pk11_Shutdown(void);
|
|
|
|
|
2001-08-24 21:16:48 +00:00
|
|
|
/*
|
|
|
|
* OK there are now lots of options here, lets go through them all:
|
|
|
|
*
|
|
|
|
* configdir - base directory where all the cert, key, and module datbases live.
|
|
|
|
* certPrefix - prefix added to the beginning of the cert database example: "
|
|
|
|
* "https-server1-"
|
|
|
|
* keyPrefix - prefix added to the beginning of the key database example: "
|
|
|
|
* "https-server1-"
|
|
|
|
* secmodName - name of the security module database (usually "secmod.db").
|
|
|
|
* readOnly - Boolean: true if the databases are to be openned read only.
|
|
|
|
* nocertdb - Don't open the cert DB and key DB's, just initialize the
|
|
|
|
* Volatile certdb.
|
|
|
|
* nomoddb - Don't open the security module DB, just initialize the
|
|
|
|
* PKCS #11 module.
|
|
|
|
* forceOpen - Continue to force initializations even if the databases cannot
|
|
|
|
* be opened.
|
|
|
|
*/
|
|
|
|
CK_RV
|
|
|
|
pk11_DBInit(const char *configdir, const char *certPrefix,
|
|
|
|
const char *keyPrefix,
|
|
|
|
const char *secmodName, PRBool readOnly, PRBool noCertDB,
|
|
|
|
PRBool noModDB, PRBool forceOpen)
|
|
|
|
{
|
|
|
|
SECStatus rv = SECFailure;
|
|
|
|
CK_RV crv = CKR_OK;
|
|
|
|
|
|
|
|
if( isInitialized ) {
|
|
|
|
return CKR_OK;
|
|
|
|
}
|
|
|
|
|
|
|
|
rv = RNG_RNGInit(); /* initialize random number generator */
|
|
|
|
if (rv != SECSuccess) {
|
|
|
|
crv = CKR_DEVICE_ERROR;
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
RNG_SystemInfoForRNG();
|
|
|
|
|
|
|
|
if (noCertDB) {
|
|
|
|
crv = pk11_OpenVolatileCertDB();
|
|
|
|
if (crv != CKR_OK) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
crv = pk11_OpenCertDB(configdir, certPrefix, readOnly);
|
|
|
|
if (crv != CKR_OK) {
|
|
|
|
if (!forceOpen) goto loser;
|
|
|
|
crv = pk11_OpenVolatileCertDB();
|
|
|
|
if (crv != CKR_OK) {
|
|
|
|
goto loser;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
crv = pk11_OpenKeyDB(configdir, keyPrefix, readOnly);
|
|
|
|
if (crv != CKR_OK) {
|
|
|
|
if (!forceOpen) goto loser;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
isInitialized = PR_TRUE;
|
|
|
|
|
|
|
|
loser:
|
|
|
|
if (crv != CKR_OK) {
|
2001-08-25 21:01:38 +00:00
|
|
|
pk11_Shutdown();
|
2001-08-24 21:16:48 +00:00
|
|
|
}
|
|
|
|
return crv;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
void
|
|
|
|
pk11_Shutdown(void)
|
|
|
|
{
|
|
|
|
CERTCertDBHandle *certHandle;
|
|
|
|
SECKEYKeyDBHandle *keyHandle;
|
|
|
|
|
|
|
|
PR_FREEIF(secmodname);
|
|
|
|
certHandle = CERT_GetDefaultCertDB();
|
|
|
|
if (certHandle)
|
|
|
|
CERT_ClosePermCertDB(certHandle);
|
|
|
|
CERT_SetDefaultCertDB(NULL);
|
|
|
|
|
|
|
|
keyHandle = SECKEY_GetDefaultKeyDB();
|
|
|
|
if (keyHandle)
|
|
|
|
SECKEY_CloseKeyDB(keyHandle);
|
|
|
|
SECKEY_SetDefaultKeyDB(NULL);
|
|
|
|
|
|
|
|
isInitialized = PR_FALSE;
|
|
|
|
}
|