summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2001-10-31 02:48:09 +0000
committerrelyea%netscape.com <devnull@localhost>2001-10-31 02:48:09 +0000
commit90804aaa7f93b4ba8e638c66efc4646f0560019c (patch)
tree5ee4d2629af3908522dabe9cdb23bc0ac25acd6d
parent2993d46b81bf87d4a07ee66616e5ef1161b9c2bd (diff)
downloadnss-hg-90804aaa7f93b4ba8e638c66efc4646f0560019c.tar.gz
1) dead code removal.
2) changes to get key gen to work. 3) changes to allow initialization of multiple db's mapped to different tokens in the same module. 4) S/MIME profile support.
-rw-r--r--security/nss/lib/softoken/cdbhdl.h2
-rw-r--r--security/nss/lib/softoken/dbinit.c91
-rw-r--r--security/nss/lib/softoken/fipstokn.c71
-rw-r--r--security/nss/lib/softoken/keydb.c30
-rw-r--r--security/nss/lib/softoken/lowpbe.c (renamed from security/nss/lib/softoken/secpkcs5.c)12
-rw-r--r--security/nss/lib/softoken/lowpbe.h (renamed from security/nss/lib/softoken/secpkcs5.h)0
-rw-r--r--security/nss/lib/softoken/manifest.mn5
-rw-r--r--security/nss/lib/softoken/pcert.h25
-rw-r--r--security/nss/lib/softoken/pcertdb.c532
-rw-r--r--security/nss/lib/softoken/pk11db.c189
-rw-r--r--security/nss/lib/softoken/pkcs11.c833
-rw-r--r--security/nss/lib/softoken/pkcs11c.c385
-rw-r--r--security/nss/lib/softoken/pkcs11i.h50
-rw-r--r--security/nss/lib/softoken/pkcs11u.c240
14 files changed, 1166 insertions, 1299 deletions
diff --git a/security/nss/lib/softoken/cdbhdl.h b/security/nss/lib/softoken/cdbhdl.h
index 4f47d7bc3..b606e9876 100644
--- a/security/nss/lib/softoken/cdbhdl.h
+++ b/security/nss/lib/softoken/cdbhdl.h
@@ -48,8 +48,6 @@
*/
struct NSSLOWCERTCertDBHandleStr {
DB *permCertDB;
- DB *tempCertDB;
- void *spkDigestInfo;
PZMonitor *dbMon;
};
diff --git a/security/nss/lib/softoken/dbinit.c b/security/nss/lib/softoken/dbinit.c
index 7f986416c..eac1b0c3a 100644
--- a/security/nss/lib/softoken/dbinit.c
+++ b/security/nss/lib/softoken/dbinit.c
@@ -104,17 +104,14 @@ pk11_keydb_name_cb(void *arg, int dbVersion)
#define CKR_KEYDB_FAILED CKR_DEVICE_ERROR
static CK_RV
-pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly)
+pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly,
+ NSSLOWCERTCertDBHandle **certdbPtr)
{
NSSLOWCERTCertDBHandle *certdb;
- CK_RV crv = CKR_OK;
+ CK_RV crv = CKR_CERTDB_FAILED;
SECStatus rv;
char * name = NULL;
- certdb = nsslowcert_GetDefaultCertDB(); /* find a better way?? 3.4 */
- if (certdb)
- return CKR_OK; /* idempotency */
-
if (prefix == NULL) {
prefix = "";
}
@@ -129,26 +126,24 @@ pk11_OpenCertDB(const char * configdir, const char *prefix, PRBool readOnly)
/* fix when we get the DB in */
rv = nsslowcert_OpenCertDB(certdb, readOnly,
pk11_certdb_name_cb, (void *)name, PR_FALSE);
- if (rv == SECSuccess)
- nsslowcert_SetDefaultCertDB(certdb);
- else {
- PR_Free(certdb);
-loser:
- crv = CKR_CERTDB_FAILED;
+ if (rv == SECSuccess) {
+ crv = CKR_OK;
+ *certdbPtr = certdb;
+ certdb = NULL;
}
+loser:
+ if (certdb) PR_Free(certdb);
if (name) PORT_Free(name);
return crv;
}
static CK_RV
-pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly)
+pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly,
+ NSSLOWKEYDBHandle **keydbPtr)
{
NSSLOWKEYDBHandle *keydb;
char * name = NULL;
- keydb = nsslowkey_GetDefaultKeyDB();
- if (keydb)
- return SECSuccess;
if (prefix == NULL) {
prefix = "";
}
@@ -156,33 +151,14 @@ pk11_OpenKeyDB(const char * configdir, const char *prefix, PRBool readOnly)
if (name == NULL)
return SECFailure;
keydb = nsslowkey_OpenKeyDB(readOnly, pk11_keydb_name_cb, (void *)name);
+ PORT_Free(name);
if (keydb == NULL)
return CKR_KEYDB_FAILED;
- nsslowkey_SetDefaultKeyDB(keydb);
- PORT_Free(name);
+ *keydbPtr = keydb;
return CKR_OK;
}
-static NSSLOWCERTCertDBHandle 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 = nsslowcert_OpenCertDB(&certhandle, PR_FALSE, NULL, NULL, PR_TRUE);
- if (rv != SECSuccess) {
- return CKR_DEVICE_ERROR;
- }
- nsslowcert_SetDefaultCertDB(&certhandle);
- return CKR_OK;
-}
-
-/* forward declare so that a failure in the init case can shutdown */
-void pk11_Shutdown(void);
/*
* OK there are now lots of options here, lets go through them all:
@@ -203,55 +179,37 @@ void pk11_Shutdown(void);
*/
CK_RV
pk11_DBInit(const char *configdir, const char *certPrefix,
- const char *keyPrefix,
- const char *secmodName, PRBool readOnly, PRBool noCertDB,
- PRBool noModDB, PRBool forceOpen)
+ const char *keyPrefix, PRBool readOnly,
+ PRBool noCertDB, PRBool noKeyDB, PRBool forceOpen,
+ NSSLOWCERTCertDBHandle **certdbPtr, NSSLOWKEYDBHandle **keydbPtr)
{
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 (!noCertDB) {
+ crv = pk11_OpenCertDB(configdir, certPrefix, readOnly, certdbPtr);
if (crv != CKR_OK) {
if (!forceOpen) goto loser;
- crv = pk11_OpenVolatileCertDB();
- if (crv != CKR_OK) {
- goto loser;
- }
+ crv = CKR_OK;
}
+ }
+ if (!noKeyDB) {
- crv = pk11_OpenKeyDB(configdir, keyPrefix, readOnly);
+ crv = pk11_OpenKeyDB(configdir, keyPrefix, readOnly, keydbPtr);
if (crv != CKR_OK) {
if (!forceOpen) goto loser;
+ crv = CKR_OK;
}
}
- isInitialized = PR_TRUE;
loser:
- if (crv != CKR_OK) {
- pk11_Shutdown();
- }
return crv;
}
+#ifdef notdef
void
pk11_Shutdown(void)
{
@@ -271,3 +229,4 @@ pk11_Shutdown(void)
isInitialized = PR_FALSE;
}
+#endif
diff --git a/security/nss/lib/softoken/fipstokn.c b/security/nss/lib/softoken/fipstokn.c
index 909e8c167..5bc0ee4d7 100644
--- a/security/nss/lib/softoken/fipstokn.c
+++ b/security/nss/lib/softoken/fipstokn.c
@@ -53,28 +53,6 @@
#include "pkcs11.h"
#include "pkcs11i.h"
-/* The next two strings must be exactly 64 characters long, with the
- first 32 characters meaningful */
-static char *slotDescription =
- "Netscape Internal FIPS-140-1 Cryptographic Services ";
-static char *privSlotDescription =
- "Netscape FIPS-140-1 User Private Key Services ";
-
-
-/*
- * Configuration utils
- */
-void
-PK11_ConfigureFIPS(char *slotdes, char *pslotdes)
-{
- if (slotdes && (PORT_Strlen(slotdes) == 65)) {
- slotDescription = slotdes;
- }
- if (pslotdes && (PORT_Strlen(pslotdes) == 65)) {
- privSlotDescription = pslotdes;
- }
- return;
-}
/*
* ******************** Password Utilities *******************************
@@ -171,31 +149,24 @@ CK_RV FC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList) {
/* FC_Initialize initializes the PKCS #11 library. */
CK_RV FC_Initialize(CK_VOID_PTR pReserved) {
- CK_RV rv;
+ CK_RV crv;
static PRBool init= PR_FALSE;
- rv = PK11_LowInitialize(pReserved);
-
- if (rv == CKR_OK && !init) {
- init = PR_TRUE;
- rv = PK11_SlotInit(FIPS_SLOT_ID,PR_TRUE,nsslowcert_GetDefaultCertDB(),
- nsslowkey_GetDefaultKeyDB());
- /* fall through to check below */
- }
+ crv = nsc_CommonInitialize(pReserved, PR_TRUE);
/* not an 'else' rv can be set by either PK11_LowInit or PK11_SlotInit*/
- if (rv != CKR_OK) {
+ if (crv != CKR_OK) {
fatalError = PR_TRUE;
- return rv;
+ return crv;
}
fatalError = PR_FALSE; /* any error has been reset */
- rv = pk11_fipsPowerUpSelfTest();
- if (rv != CKR_OK) {
+ crv = pk11_fipsPowerUpSelfTest();
+ if (crv != CKR_OK) {
fatalError = PR_TRUE;
- return rv;
+ return crv;
}
return CKR_OK;
@@ -216,11 +187,7 @@ CK_RV FC_GetInfo(CK_INFO_PTR pInfo) {
/* FC_GetSlotList obtains a list of slots in the system. */
CK_RV FC_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount) {
- *pulCount = 1;
- if (pSlotList != NULL) {
- pSlotList[0] = FIPS_SLOT_ID;
- }
- return CKR_OK;
+ return NSC_GetSlotList(tokenPresent,pSlotList,pulCount);
}
/* FC_GetSlotInfo obtains information about a particular slot in the system. */
@@ -228,16 +195,11 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV crv;
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
-
- /* Use NETSCAPE_SLOT_ID as a basis so that we get Library version number,
- * not key_DB version number */
- crv = NSC_GetSlotInfo(NETSCAPE_SLOT_ID,pInfo);
+ crv = NSC_GetSlotInfo(slotID,pInfo);
if (crv != CKR_OK) {
return crv;
}
- PORT_Memcpy(pInfo->slotDescription,slotDescription,64);
return CKR_OK;
}
@@ -246,13 +208,8 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo) {
CK_RV crv;
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
-
- /* use PRIVATE_KEY_SLOT_ID so we get the correct
- Authentication information */
- crv = NSC_GetTokenInfo(PRIVATE_KEY_SLOT_ID,pInfo);
+ crv = NSC_GetTokenInfo(slotID,pInfo);
pInfo->flags |= CKF_RNG | CKF_LOGIN_REQUIRED;
- /* yes virginia, FIPS can do random number generation:) */
return crv;
}
@@ -263,9 +220,9 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_GetMechanismList(CK_SLOT_ID slotID,
CK_MECHANISM_TYPE_PTR pMechanismList, CK_ULONG_PTR pusCount) {
PK11_FIPSFATALCHECK();
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
+ if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
/* FIPS Slot supports all functions */
- return NSC_GetMechanismList(NETSCAPE_SLOT_ID,pMechanismList,pusCount);
+ return NSC_GetMechanismList(slotID,pMechanismList,pusCount);
}
@@ -274,9 +231,9 @@ CK_RV FC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo) {
CK_RV FC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
CK_MECHANISM_INFO_PTR pInfo) {
PK11_FIPSFATALCHECK();
- if (slotID != FIPS_SLOT_ID) return CKR_SLOT_ID_INVALID;
+ if (slotID == FIPS_SLOT_ID) slotID = NETSCAPE_SLOT_ID;
/* FIPS Slot supports all functions */
- return NSC_GetMechanismInfo(NETSCAPE_SLOT_ID,type,pInfo);
+ return NSC_GetMechanismInfo(slotID,type,pInfo);
}
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index ad21a733f..a4c7640c0 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -45,7 +45,7 @@
#include "secitem.h"
#include "pcert.h"
#include "mcom_db.h"
-#include "secpkcs5.h"
+#include "lowpbe.h"
#include "secerr.h"
#include "keydbi.h"
@@ -1333,7 +1333,6 @@ nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
/* encrypt the private key */
rv = seckey_put_private_key(handle, &namekey, pwitem, privkey, nickname,
PR_FALSE, algorithm);
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
return(rv);
}
@@ -1587,7 +1586,6 @@ nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
namekey.size = modulus->len;
pk = seckey_get_private_key(handle, &namekey, NULL, pwitem);
- SECITEM_ZfreeItem(pwitem, PR_TRUE);
/* no need to free dbkey, since its on the stack, and the data it
* points to is owned by the database
@@ -1686,22 +1684,24 @@ nsslowkey_SetKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
}
dest = nsspkcs5_CipherData(param, pwitem, &test_key, PR_TRUE, NULL);
- if(dest != NULL)
+ if (dest == NULL)
{
- rv = SECITEM_CopyItem(arena, &dbkey->salt, salt);
- if(rv == SECFailure)
- goto loser;
+ rv = SECFailure;
+ goto loser;
+ }
+
+ rv = SECITEM_CopyItem(arena, &dbkey->salt, salt);
+ if (rv == SECFailure) {
+ goto loser;
+ }
- rv = encodePWCheckEntry(arena, &dbkey->derPK, algorithm, dest);
+ rv = encodePWCheckEntry(arena, &dbkey->derPK, algorithm, dest);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
- } else {
- rv = SECFailure;
+ if ( rv != SECSuccess ) {
+ goto loser;
}
+
+ rv = put_dbkey(handle, &checkkey, dbkey, PR_TRUE);
/* let success fall through */
loser:
diff --git a/security/nss/lib/softoken/secpkcs5.c b/security/nss/lib/softoken/lowpbe.c
index 2337e74ca..845638b74 100644
--- a/security/nss/lib/softoken/secpkcs5.c
+++ b/security/nss/lib/softoken/lowpbe.c
@@ -42,7 +42,7 @@
#include "hasht.h"
#include "secasn1.h"
#include "secder.h"
-#include "secpkcs5.h"
+#include "lowpbe.h"
#include "secoid.h"
#include "alghmac.h"
#include "softoken.h"
@@ -791,9 +791,11 @@ nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
case NSSPKCS5_PBKDF1:
rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
NSSPKCS5PBEParameterTemplate, &algid->parameters);
+ break;
case NSSPKCS5_PKCS12_V2:
rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
NSSPKCS5PKCS12V2PBEParameterTemplate, &algid->parameters);
+ break;
case NSSPKCS5_PBKDF2:
break;
}
@@ -1133,6 +1135,14 @@ nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
if (algid == NULL) {
goto loser;
}
+
+ if (pbe_param->iteration.data == NULL) {
+ dummy = SEC_ASN1EncodeInteger(pbe_param->poolp,&pbe_param->iteration,
+ pbe_param->iter);
+ if (dummy == NULL) {
+ goto loser;
+ }
+ }
switch (pbe_param->pbeType) {
case NSSPKCS5_PBKDF1:
dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
diff --git a/security/nss/lib/softoken/secpkcs5.h b/security/nss/lib/softoken/lowpbe.h
index 8ddee11a6..8ddee11a6 100644
--- a/security/nss/lib/softoken/secpkcs5.h
+++ b/security/nss/lib/softoken/lowpbe.h
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
index 065a1ccc3..db7e3d1d3 100644
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -48,7 +48,6 @@ EXPORTS = \
pkcs11t.h \
pkcs11n.h \
pkcs11u.h \
- secpkcs5.h \
$(NULL)
PRIVATE_EXPORTS = \
@@ -65,13 +64,13 @@ CSRCS = \
keydb.c \
lowcert.c \
lowkey.c \
+ lowpbe.c \
padbuf.c \
+ pcertdb.c \
pk11db.c \
pkcs11.c \
pkcs11c.c \
pkcs11u.c \
rawhash.c \
rsawrapr.c \
- secpkcs5.c \
- pcertdb.c \
$(NULL)
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
index 9795899b4..b4392fb87 100644
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -305,23 +305,11 @@ SEC_BEGIN_PROTOS
** "nickname" is the nickname to use for the cert
** "trust" is the trust parameters for the cert
*/
-SECStatus SEC_AddPermCertificate(NSSLOWCERTCertDBHandle *handle, SECItem *derCert,
+SECStatus nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *handle,
+ NSSLOWCERTCertificate *cert,
char *nickname, NSSLOWCERTCertTrust *trust);
-certDBEntryCert *
-SEC_FindPermCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey);
-
-certDBEntryCert
-*SEC_FindPermCertByName(NSSLOWCERTCertDBHandle *handle, SECItem *name);
-
-#ifdef notdef
-SECStatus SEC_OpenPermCertDB(NSSLOWCERTCertDBHandle *handle,
- PRBool readOnly,
- NSSLOWCERTDBNameFunc namecb,
- void *cbarg);
-#endif
-
-SECStatus SEC_DeletePermCertificate(NSSLOWCERTCertificate *cert);
+SECStatus nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert);
typedef SECStatus (PR_CALLBACK * PermCertCallback)(NSSLOWCERTCertificate *cert,
SECItem *k, void *pdata);
@@ -402,6 +390,13 @@ nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *n
SECStatus
nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key);
+certDBEntrySMime *
+nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *certHandle,
+ char *emailAddr);
+void
+nsslowcert_DestroyDBEntry(certDBEntry *entry);
+
+
SEC_END_PROTOS
#endif /* _PCERTDB_H_ */
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
index 545963f95..1579692bd 100644
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -69,7 +69,7 @@ nsslowcert_FindCertByDERCertNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *d
static PZLock *dbLock = NULL;
void
-certdb_InitDBLock(void)
+certdb_InitDBLock(NSSLOWCERTCertDBHandle *handle)
{
if (dbLock == NULL) {
nss_InitLock(&dbLock, nssILockCertDB);
@@ -1233,6 +1233,13 @@ DestroyDBEntry(certDBEntry *entry)
return;
}
+void
+nsslowcert_DestroyDBEntry(certDBEntry *entry)
+{
+ DestroyDBEntry(entry);
+ return;
+}
+
/*
* Encode a database nickname record
*/
@@ -1543,10 +1550,6 @@ loser:
}
-/*
- * Encode a database smime record
- */
-static SECStatus
EncodeDBSMimeEntry(certDBEntrySMime *entry, PRArenaPool *arena,
SECItem *dbitem)
{
@@ -1824,8 +1827,8 @@ loser:
/*
* Read a SMIME entry
*/
-static certDBEntrySMime *
-ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
+certDBEntrySMime *
+nsslowcert_ReadDBSMimeEntry(NSSLOWCERTCertDBHandle *handle, char *emailAddr)
{
PRArenaPool *arena = NULL;
PRArenaPool *tmparena = NULL;
@@ -2420,25 +2423,29 @@ loser:
}
static SECStatus
-UpdateSubjectWithEmailAddr(NSSLOWCERTCertificate *cert, char *emailAddr)
+UpdateSubjectWithEmailAddr(NSSLOWCERTCertDBHandle *dbhandle,
+ SECItem *derSubject, char *emailAddr)
{
PRBool save = PR_FALSE, delold = PR_FALSE;
certDBEntrySubject *entry;
SECStatus rv;
-
- emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
- if ( emailAddr == NULL ) {
- return(SECFailure);
+
+ if (emailAddr) {
+ emailAddr = nsslowcert_FixupEmailAddr(emailAddr);
+ if (emailAddr == NULL) {
+ return SECFailure;
+ }
}
- entry = ReadDBSubjectEntry(cert->dbhandle,&cert->derSubject);
+ entry = ReadDBSubjectEntry(dbhandle,derSubject);
if ( entry->emailAddr ) {
- if ( PORT_Strcmp(entry->emailAddr, emailAddr) != 0 ) {
+ if ( (emailAddr == NULL) ||
+ (PORT_Strcmp(entry->emailAddr, emailAddr) != 0) ) {
save = PR_TRUE;
delold = PR_TRUE;
}
- } else {
+ } else if (emailAddr) {
save = PR_TRUE;
}
@@ -2448,35 +2455,39 @@ UpdateSubjectWithEmailAddr(NSSLOWCERTCertificate *cert, char *emailAddr)
*/
PORT_Assert(save);
PORT_Assert(entry->emailAddr != NULL);
- DeleteDBSMimeEntry(cert->dbhandle, entry->emailAddr);
+ DeleteDBSMimeEntry(dbhandle, entry->emailAddr);
}
if ( save ) {
unsigned int len;
PORT_Assert(entry != NULL);
- len = PORT_Strlen(emailAddr) + 1;
- entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, len);
- if ( entry->emailAddr == NULL ) {
- goto loser;
+ if (emailAddr) {
+ len = PORT_Strlen(emailAddr) + 1;
+ entry->emailAddr = (char *)PORT_ArenaAlloc(entry->common.arena, len);
+ if ( entry->emailAddr == NULL ) {
+ goto loser;
+ }
+ PORT_Memcpy(entry->emailAddr, emailAddr, len);
+ } else {
+ entry->emailAddr = NULL;
}
- PORT_Memcpy(entry->emailAddr, emailAddr, len);
/* delete the subject entry */
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
+ DeleteDBSubjectEntry(dbhandle, derSubject);
/* write the new one */
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
+ rv = WriteDBSubjectEntry(dbhandle, entry);
if ( rv != SECSuccess ) {
goto loser;
}
}
- PORT_Free(emailAddr);
+ if (emailAddr) PORT_Free(emailAddr);
return(SECSuccess);
loser:
- PORT_Free(emailAddr);
+ if (emailAddr) PORT_Free(emailAddr);
return(SECFailure);
}
@@ -2485,7 +2496,8 @@ loser:
* have one
*/
static SECStatus
-AddNicknameToSubject(NSSLOWCERTCertificate *cert, char *nickname)
+AddNicknameToSubject(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname)
{
certDBEntrySubject *entry;
SECStatus rv;
@@ -2494,7 +2506,7 @@ AddNicknameToSubject(NSSLOWCERTCertificate *cert, char *nickname)
return(SECFailure);
}
- entry = ReadDBSubjectEntry(cert->dbhandle,&cert->derSubject);
+ entry = ReadDBSubjectEntry(dbhandle,&cert->derSubject);
PORT_Assert(entry != NULL);
if ( entry == NULL ) {
goto loser;
@@ -2505,17 +2517,18 @@ AddNicknameToSubject(NSSLOWCERTCertificate *cert, char *nickname)
goto loser;
}
- entry->nickname = (nickname) ? PORT_ArenaStrdup(entry->common.arena, nickname) : NULL;
+ entry->nickname = (nickname) ?
+ PORT_ArenaStrdup(entry->common.arena, nickname) : NULL;
if ( entry->nickname == NULL ) {
goto loser;
}
/* delete the subject entry */
- DeleteDBSubjectEntry(cert->dbhandle, &cert->derSubject);
+ DeleteDBSubjectEntry(dbhandle, &cert->derSubject);
/* write the new one */
- rv = WriteDBSubjectEntry(cert->dbhandle, entry);
+ rv = WriteDBSubjectEntry(dbhandle, entry);
if ( rv != SECSuccess ) {
goto loser;
}
@@ -2886,7 +2899,7 @@ nsslowcert_TraversePermCertsForNickname(NSSLOWCERTCertDBHandle *handle, char *ni
if ( nnentry ) {
derSubject = &nnentry->subjectName;
} else {
- smentry = ReadDBSMimeEntry(handle, nickname);
+ smentry = nsslowcert_ReadDBSMimeEntry(handle, nickname);
if ( smentry ) {
derSubject = &smentry->subjectName;
}
@@ -2931,7 +2944,8 @@ nsslowcert_NumPermCertsForNickname(NSSLOWCERTCertDBHandle *handle, char *nicknam
* add a nickname to a cert that doesn't have one
*/
static SECStatus
-AddNicknameToPermCert(NSSLOWCERTCertificate *cert, char *nickname)
+AddNicknameToPermCert(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname)
{
certDBEntryCert *entry;
int rv;
@@ -2944,7 +2958,7 @@ AddNicknameToPermCert(NSSLOWCERTCertificate *cert, char *nickname)
entry->nickname = PORT_ArenaStrdup(entry->common.arena, nickname);
- rv = WriteDBCertEntry(cert->dbhandle, entry);
+ rv = WriteDBCertEntry(dbhandle, entry);
if ( rv ) {
goto loser;
}
@@ -2961,12 +2975,13 @@ loser:
* have one yet (it is probably an e-mail cert).
*/
SECStatus
-nsslowcert_AddPermNickname(NSSLOWCERTCertificate *cert, char *nickname)
+nsslowcert_AddPermNickname(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname)
{
SECStatus rv = SECFailure;
certDBEntrySubject *entry = NULL;
- nsslowcert_LockDB(cert->dbhandle);
+ nsslowcert_LockDB(dbhandle);
PORT_Assert(cert->nickname == NULL);
@@ -2975,22 +2990,22 @@ nsslowcert_AddPermNickname(NSSLOWCERTCertificate *cert, char *nickname)
goto loser;
}
- entry = ReadDBSubjectEntry(cert->dbhandle, &cert->derSubject);
+ entry = ReadDBSubjectEntry(dbhandle, &cert->derSubject);
if (entry == NULL) goto loser;
if ( entry->nickname == NULL ) {
/* no nickname for subject */
- rv = AddNicknameToSubject(cert, nickname);
+ rv = AddNicknameToSubject(dbhandle, cert, nickname);
if ( rv != SECSuccess ) {
goto loser;
}
- rv = AddNicknameToPermCert(cert, nickname);
+ rv = AddNicknameToPermCert(dbhandle, cert, nickname);
if ( rv != SECSuccess ) {
goto loser;
}
} else {
/* subject already has a nickname */
- rv = AddNicknameToPermCert(cert, entry->nickname);
+ rv = AddNicknameToPermCert(dbhandle, cert, entry->nickname);
if ( rv != SECSuccess ) {
goto loser;
}
@@ -3001,7 +3016,7 @@ loser:
if (entry) {
DestroyDBEntry((certDBEntry *)entry);
}
- nsslowcert_UnlockDB(cert->dbhandle);
+ nsslowcert_UnlockDB(dbhandle);
return(rv);
}
@@ -3251,7 +3266,7 @@ UpdateV6DB(NSSLOWCERTCertDBHandle *handle, DB *updatedb)
emailAddr = &((char *)key.data)[1];
/* get the matching smime entry in the new DB */
- emailEntry = ReadDBSMimeEntry(handle, emailAddr);
+ emailEntry = nsslowcert_ReadDBSMimeEntry(handle, emailAddr);
if ( emailEntry == NULL ) {
goto endloop;
}
@@ -3450,95 +3465,21 @@ nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle)
namekey.data = keyitem.data;
namekey.size = keyitem.len;
- /* lookup in the temporary database */
- ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0);
-
- if ( ret == 0 ) { /* found in temp database */
- goto loser;
- } else { /* not found in temporary database */
- ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
- if ( ret == 0 ) {
- goto loser;
- }
- }
-
- PORT_FreeArena(arena, PR_FALSE);
-
- return(PR_FALSE);
-loser:
- if ( arena ) {
- PORT_FreeArena(arena, PR_FALSE);
- }
-
- return(PR_TRUE);
-}
-
-#ifdef notdef
-
-/*
- * return true if a subject name conflict exists
- * NOTE: caller must have already made sure that this exact cert
- * doesn't exist in the DB
- */
-PRBool
-SEC_CertSubjectConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle)
-{
- SECStatus rv;
- DBT tmpdata;
- DBT namekey;
- int ret;
- SECItem keyitem;
- PRArenaPool *arena = NULL;
- SECItem derName;
-
- derName.data = NULL;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- goto loser;
- }
-
- /* get the subject name of the cert */
- rv = nsslowcert_NameFromDERCert(derCert, &derName);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- rv = EncodeDBSubjectKey(&derName, arena, &keyitem);
- if ( rv != SECSuccess ) {
+ ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
+ if ( ret == 0 ) {
goto loser;
}
-
- namekey.data = keyitem.data;
- namekey.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get(handle->tempCertDB, &namekey, &tmpdata, 0);
-
- if ( ret == 0 ) { /* found in temp database */
- return(PR_TRUE);
- } else { /* not found in temporary database */
- ret = certdb_Get(handle->permCertDB, &namekey, &tmpdata, 0);
- if ( ret == 0 ) {
- return(PR_TRUE);
- }
- }
PORT_FreeArena(arena, PR_FALSE);
- PORT_Free(derName.data);
return(PR_FALSE);
loser:
if ( arena ) {
PORT_FreeArena(arena, PR_FALSE);
}
- if ( derName.data ) {
- PORT_Free(derName.data);
- }
return(PR_TRUE);
}
-#endif
/*
* return true if a nickname conflict exists
@@ -3780,7 +3721,7 @@ nsslowcert_DeletePermCertificate(NSSLOWCERTCertificate *cert)
* Traverse all of the entries in the database of a particular type
* call the given function for each one.
*/
-static SECStatus
+SECStatus
nsslowcert_TraverseDBEntries(NSSLOWCERTCertDBHandle *handle,
certDBEntryType type,
SECStatus (* callback)(SECItem *data, SECItem *key,
@@ -4063,8 +4004,8 @@ done:
SECStatus
-nsslowcert_AddPermCert(NSSLOWCERTCertificate *cert, char *nickname,
- NSSLOWCERTCertTrust *trust)
+nsslowcert_AddPermCert(NSSLOWCERTCertDBHandle *dbhandle,
+ NSSLOWCERTCertificate *cert, char *nickname, NSSLOWCERTCertTrust *trust)
{
char *oldnn;
certDBEntryCert *entry;
@@ -4072,15 +4013,13 @@ nsslowcert_AddPermCert(NSSLOWCERTCertificate *cert, char *nickname,
PRBool conflict;
SECStatus ret;
- PORT_Assert(cert->dbhandle);
-
- nsslowcert_LockDB(cert->dbhandle);
+ nsslowcert_LockDB(dbhandle);
PORT_Assert(!cert->dbEntry);
/* don't add a conflicting nickname */
conflict = nsslowcert_CertNicknameConflict(nickname, &cert->derSubject,
- cert->dbhandle);
+ dbhandle);
if ( conflict ) {
ret = SECFailure;
goto done;
@@ -4089,7 +4028,7 @@ nsslowcert_AddPermCert(NSSLOWCERTCertificate *cert, char *nickname,
/* save old nickname so that we can delete it */
oldnn = cert->nickname;
- entry = AddCertToPermDB(cert->dbhandle, cert, nickname, trust);
+ entry = AddCertToPermDB(dbhandle, cert, nickname, trust);
if ( entry == NULL ) {
ret = SECFailure;
@@ -4102,7 +4041,7 @@ nsslowcert_AddPermCert(NSSLOWCERTCertificate *cert, char *nickname,
ret = SECSuccess;
done:
- nsslowcert_UnlockDB(cert->dbhandle);
+ nsslowcert_UnlockDB(dbhandle);
return(ret);
}
@@ -4115,28 +4054,13 @@ nsslowcert_OpenCertDB(NSSLOWCERTCertDBHandle *handle, PRBool readOnly,
NSSLOWCERTDBNameFunc namecb, void *cbarg, PRBool openVolatile)
{
int rv;
-#define DBM_DEFAULT 0
- static const HASHINFO hashInfo = {
- DBM_DEFAULT, /* bucket size */
- DBM_DEFAULT, /* fill factor */
- DBM_DEFAULT, /* number of elements */
- 256 * 1024, /* bytes to cache */
- DBM_DEFAULT, /* hash function */
- DBM_DEFAULT /* byte order */
- };
-
- certdb_InitDBLock();
+
+ certdb_InitDBLock(handle);
handle->dbMon = PZ_NewMonitor(nssILockCertDB);
PORT_Assert(handle->dbMon != NULL);
- if (openVolatile) {
- handle->permCertDB = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH,
- &hashInfo );
- rv = handle->permCertDB ? SECSuccess : SECFailure;
- } else {
- rv = nsslowcert_OpenPermCertDB(handle, readOnly, namecb, cbarg);
- }
+ rv = nsslowcert_OpenPermCertDB(handle, readOnly, namecb, cbarg);
if ( rv ) {
goto loser;
}
@@ -4454,313 +4378,63 @@ nsslowcert_hasTrust(NSSLOWCERTCertificate *cert)
(trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
}
-#ifdef notdef
-/*
- * find a cert by email address
- *
- * pick one that is a valid recipient, meaning that it is an encryption
- * cert.
- *
- */
-static NSSLOWCERTCertificate*
-find_smime_recipient_cert(NSSLOWCERTCertDBHandle* handle, const char* email_addr)
-{
- NSSLOWCERTCertificate* cert = NULL;
- NSSLOWCERTCertList* certList = NULL;
- SECStatus rv;
-
- certList = nsslowcert_CreateEmailAddrCertList(NULL, handle, (char*)email_addr,
- PR_Now(), PR_TRUE);
- if (certList == NULL) {
- return NULL;
- }
-
- rv = nsslowcert_FilterCertListByUsage(certList, certUsageEmailRecipient,
- PR_FALSE);
-
- if (!nsslowcert_LIST_END(nsslowcert_LIST_HEAD(certList), certList)) {
- cert = nsslowcert_DupCertificate(nsslowcert_LIST_HEAD(certList)->cert);
- }
-
- nsslowcert_DestroyCertList(certList);
-
- return cert; /* cert may point to a cert or may be NULL */
-}
-
/*
* This function has the logic that decides if another person's cert and
* email profile from an S/MIME message should be saved. It can deal with
* the case when there is no profile.
*/
SECStatus
-nsslowcert_SaveSMimeProfile(NSSLOWCERTCertificate *cert, SECItem *emailProfile,
- SECItem *profileTime)
+nsslowcert_SaveSMimeProfile(NSSLOWCERTCertDBHandle *dbhandle, char *emailAddr,
+ SECItem *derSubject, SECItem *emailProfile, SECItem *profileTime)
{
- certDBEntrySMime *entry = NULL, *oldentry = NULL;
- int64 oldtime;
- int64 newtime;
- SECStatus rv;
- NSSLOWCERTCertificate *oldcert = NULL;
- PRBool saveit;
- NSSLOWCERTCertTrust trust;
- NSSLOWCERTCertTrust tmptrust;
- char *emailAddr;
-
- emailAddr = cert->emailAddr;
-
- PORT_Assert(emailAddr);
- if ( emailAddr == NULL ) {
- goto loser;
- }
-
- saveit = PR_FALSE;
-
- oldcert = find_smime_recipient_cert(cert->dbhandle, emailAddr);
- if (oldcert) {
- /* see if there is an entry already */
- oldentry = ReadDBSMimeEntry(cert->dbhandle, emailAddr);
- }
-
- /* both profileTime and emailProfile have to exist or not exist */
- if ( emailProfile == NULL ) {
- profileTime = NULL;
- } else if ( profileTime == NULL ) {
- emailProfile = NULL;
- }
-
- if ( oldentry == NULL ) {
- /* no old entry for this address */
- PORT_Assert(oldcert == NULL);
- saveit = PR_TRUE;
- } else {
- /* there was already a profile for this email addr */
- if ( profileTime ) {
- /* we have an old and new profile - save whichever is more recent*/
- if ( oldentry->optionsDate.len == 0 ) {
- /* always replace if old entry doesn't have a time */
- oldtime = LL_MININT;
- } else {
- rv = DER_UTCTimeToTime(&oldtime, &oldentry->optionsDate);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
-
- rv = DER_UTCTimeToTime(&newtime, profileTime);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- if ( LL_CMP(newtime, >, oldtime ) ) {
- /* this is a newer profile, save it and cert */
- saveit = PR_TRUE;
- }
- } else {
- /* we don't have a new profile or time */
- if ( oldentry->optionsDate.len == 0 ) {
- /* the old entry doesn't have a time either, so compare certs*/
- if ( nsslowcert_IsNewer(cert, oldcert) ) {
- /* new cert is newer, use it instead */
- saveit = PR_TRUE;
- }
- } else {
- if (oldcert) {
- if (nsslowcert_IsNewer(cert, oldcert)) {
- saveit = PR_TRUE;
- }
- } else {
- saveit = PR_TRUE;
- }
- }
- }
- }
-
- if ( saveit ) {
- if ( oldcert && ( oldcert != cert ) ) {
- /* old cert is different from new cert */
- if ( PORT_Memcmp(oldcert->trust, &trust, sizeof(trust)) == 0 ) {
- /* old cert is only for e-mail, so delete it */
- SEC_DeletePermCertificate(oldcert);
- } else {
- /* old cert is for other things too, so just change trust */
- tmptrust = *oldcert->trust;
- tmptrust.emailFlags &= ( ~CERTDB_VALID_PEER );
- rv = nsslowcert_ChangeCertTrust(oldcert->dbhandle, oldcert,
- &tmptrust);
- if ( rv != SECSuccess ) {
- goto loser;
- }
- }
- }
-
-/* Subroutine */
- /* now save the entry */
- entry = NewDBSMimeEntry(emailAddr, &cert->derSubject, emailProfile,
- profileTime, 0);
- if ( entry == NULL ) {
- goto loser;
- }
+ certDBEntrySMime *entry = NULL;
+ SECStatus rv = SECFailure;;
- nsslowcert_LockDB(cert->dbhandle);
+ /* find our existing entry */
+ entry = nsslowcert_ReadDBSMimeEntry(dbhandle, emailAddr);
- rv = DeleteDBSMimeEntry(cert->dbhandle, emailAddr);
- /* if delete fails, try to write new entry anyway... */
-
- rv = WriteDBSMimeEntry(cert->dbhandle, entry);
- if ( rv != SECSuccess ) {
- nsslowcert_UnlockDB(cert->dbhandle);
- goto loser;
- }
-
- /* link subject entry back here */
- rv = UpdateSubjectWithEmailAddr(cert, emailAddr);
- if ( rv != SECSuccess ) {
- nsslowcert_UnlockDB(cert->dbhandle);
- goto loser;
- }
-
- nsslowcert_UnlockDB(cert->dbhandle);
-/* End Subroutine */
- }
-
- rv = SECSuccess;
- goto done;
-
-loser:
- rv = SECFailure;
-
-done:
- if ( oldcert ) {
- nsslowcert_DestroyCertificate(oldcert);
- }
-
if ( entry ) {
+ /* keep our old db entry consistant for old applications. */
+ if (!SECITEM_ItemsAreEqual(derSubject, &entry->subjectName)) {
+ UpdateSubjectWithEmailAddr(dbhandle, &entry->subjectName, NULL);
+ }
DestroyDBEntry((certDBEntry *)entry);
+ entry = NULL;
}
- if ( oldentry ) {
- DestroyDBEntry((certDBEntry *)oldentry);
- }
-
- return(rv);
-}
-
-/*
- * find the smime symmetric capabilities profile for a given cert
- */
-SECItem *
-nsslowcert_FindSMimeProfile(NSSLOWCERTCertificate *cert)
-{
- certDBEntrySMime *entry;
- SECItem *retitem = NULL;
-
- PORT_Assert(cert->emailAddr != NULL);
-
- if ( cert->emailAddr == NULL ) {
- return(NULL);
- }
-
- entry = ReadDBSMimeEntry(cert->dbhandle, cert->emailAddr);
- if ( entry ) {
- /* May not be for this cert... */
- if (SECITEM_ItemsAreEqual(&cert->derSubject, &entry->subjectName))
- retitem = SECITEM_DupItem(&entry->smimeOptions);
- DestroyDBEntry((certDBEntry *)entry);
+ /* now save the entry */
+ entry = NewDBSMimeEntry(emailAddr, derSubject, emailProfile,
+ profileTime, 0);
+ if ( entry == NULL ) {
+ rv = SECFailure;
+ goto loser;
}
- return(retitem);
-}
-
-SECStatus
-nsslowcert_ChangeCertTrustByUsage(NSSLOWCERTCertDBHandle *certdb,
- NSSLOWCERTCertificate *cert, SECCertUsage usage)
-{
- SECStatus rv;
- NSSLOWCERTCertTrust trust;
- NSSLOWCERTCertTrust tmptrust;
- unsigned int certtype;
- PRBool saveit;
-
- saveit = PR_TRUE;
-
- PORT_Memset((void *)&trust, 0, sizeof(trust));
-
- certtype = cert->nsCertType;
-
- /* if no app bits in cert type, then set all app bits */
- if ( ! ( certtype & NS_CERT_TYPE_APP ) ) {
- certtype |= NS_CERT_TYPE_APP;
- }
+ nsslowcert_LockDB(dbhandle);
- switch ( usage ) {
- case certUsageEmailSigner:
- case certUsageEmailRecipient:
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) {
- /* don't save it if KeyEncipherment is not allowed */
- saveit = PR_FALSE;
- }
- }
- break;
- case certUsageUserCertImport:
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- trust.emailFlags = CERTDB_VALID_PEER;
- }
- /* VALID_USER is already set if the cert was imported,
- * in the case that the cert was already in the database
- * through SMIME or other means, we should set the USER
- * flags, if they are not already set.
- */
- if( cert->isperm ) {
- if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) {
- if( !(cert->trust->sslFlags & CERTDB_USER) ) {
- trust.sslFlags |= CERTDB_USER;
- }
- }
-
- if ( certtype & NS_CERT_TYPE_EMAIL ) {
- if( !(cert->trust->emailFlags & CERTDB_USER) ) {
- trust.emailFlags |= CERTDB_USER;
- }
- }
-
- if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) {
- if( !(cert->trust->objectSigningFlags & CERTDB_USER) ) {
- trust.objectSigningFlags |= CERTDB_USER;
- }
- }
- }
- break;
- default: /* XXX added to quiet warnings; no other cases needed? */
- break;
- }
+ rv = DeleteDBSMimeEntry(dbhandle, emailAddr);
+ /* if delete fails, try to write new entry anyway... */
- if ( (trust.sslFlags | trust.emailFlags | trust.objectSigningFlags) == 0 ){
- saveit = PR_FALSE;
+ /* link subject entry back here */
+ rv = UpdateSubjectWithEmailAddr(dbhandle, derSubject, emailAddr);
+ if ( rv != SECSuccess ) {
+ nsslowcert_UnlockDB(dbhandle);
+ goto loser;
}
-
- if ( saveit && cert->isperm ) {
- /* Cert already in the DB. Just adjust flags */
- tmptrust = *cert->trust;
- tmptrust.sslFlags |= trust.sslFlags;
- tmptrust.emailFlags |= trust.emailFlags;
- tmptrust.objectSigningFlags |= trust.objectSigningFlags;
-
- rv = nsslowcert_ChangeCertTrust(cert->dbhandle, cert,
- &tmptrust);
- if ( rv != SECSuccess ) {
+
+ rv = WriteDBSMimeEntry(dbhandle, entry);
+ if ( rv != SECSuccess ) {
+ nsslowcert_UnlockDB(dbhandle);
goto loser;
- }
}
- rv = SECSuccess;
- goto done;
+ nsslowcert_UnlockDB(dbhandle);
+ rv = SECSuccess;
+
loser:
- rv = SECFailure;
-done:
-
+ if ( entry ) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
return(rv);
}
-#endif
diff --git a/security/nss/lib/softoken/pk11db.c b/security/nss/lib/softoken/pk11db.c
index d5a4a7b0c..a5cb842e4 100644
--- a/security/nss/lib/softoken/pk11db.c
+++ b/security/nss/lib/softoken/pk11db.c
@@ -43,64 +43,205 @@
#define FREE_CLEAR(p) if (p) { PORT_Free(p); p = NULL; }
static void
-secmod_parseFlags(char *tmp, pk11_parameters *parsed) {
+secmod_parseTokenFlags(char *tmp, pk11_token_parameters *parsed) {
parsed->readOnly = pk11_argHasFlag("flags","readOnly",tmp);
parsed->noCertDB = pk11_argHasFlag("flags","noCertDB",tmp);
+ parsed->noKeyDB = pk11_argHasFlag("flags","noKeyDB",tmp);
+ parsed->forceOpen = pk11_argHasFlag("flags","forceOpen",tmp);
+ parsed->pwRequired = pk11_argHasFlag("flags","passwordRequired",tmp);
+ return;
+}
+
+static void
+secmod_parseFlags(char *tmp, pk11_parameters *parsed) {
parsed->noModDB = pk11_argHasFlag("flags","noModDB",tmp);
+ parsed->readOnly = pk11_argHasFlag("flags","readOnly",tmp);
+ /* keep legacy interface working */
+ parsed->noCertDB = pk11_argHasFlag("flags","noCertDB",tmp);
parsed->forceOpen = pk11_argHasFlag("flags","forceOpen",tmp);
parsed->pwRequired = pk11_argHasFlag("flags","passwordRequired",tmp);
return;
}
+CK_RV
+secmod_parseTokenParameters(char *param, pk11_token_parameters *parsed)
+{
+ int next;
+ char *tmp;
+ char *index;
+ index = pk11_argStrip(param);
+
+ while (*index) {
+ PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configdir=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->certPrefix,"certprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->tokdes,"tokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,parsed->slotdes,"slotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=",
+ if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); })
+ PK11_HANDLE_STRING_ARG(index,tmp,"flags=",
+ if(tmp) { secmod_parseTokenFlags(param,parsed); PORT_Free(tmp); })
+ PK11_HANDLE_FINAL_ARG(index)
+ }
+ return CKR_OK;
+}
+
+static void
+secmod_parseTokens(char *tokenParams, pk11_parameters *parsed)
+{
+ char *tokenIndex;
+ pk11_token_parameters *tokens = NULL;
+ int i=0,count = 0,next;
+
+ if ((tokenParams == NULL) || (*tokenParams == 0)) return;
+ /* first count the number of slots */
+ for (tokenIndex = pk11_argStrip(tokenParams); *tokenIndex;
+ tokenIndex = pk11_argStrip(pk11_argSkipParameter(tokenIndex))) {
+ count++;
+ }
+
+ /* get the data structures */
+ tokens = (pk11_token_parameters *)
+ PORT_ZAlloc(count*sizeof(pk11_token_parameters));
+ if (tokens == NULL) return;
+
+ for (tokenIndex = pk11_argStrip(tokenParams), i = 0;
+ *tokenIndex && i < count ; i++ ) {
+ char *name;
+ name = pk11_argGetName(tokenIndex,&next);
+ tokenIndex += next;
+
+ tokens[i].slotID = pk11_argDecodeNumber(name);
+ tokens[i].readOnly = PR_TRUE;
+ tokens[i].noCertDB = PR_TRUE;
+ tokens[i].noKeyDB = PR_TRUE;
+ if (!pk11_argIsBlank(*tokenIndex)) {
+ char *args = pk11_argFetchValue(tokenIndex,&next);
+ tokenIndex += next;
+ if (args) {
+ secmod_parseTokenParameters(args,&tokens[i]);
+ PORT_Free(args);
+ }
+ }
+ if (name) PORT_Free(name);
+ tokenIndex = pk11_argStrip(tokenIndex);
+ }
+ parsed->token_count = i;
+ parsed->tokens = tokens;
+ return;
+}
CK_RV
-secmod_parseParameters(char *param, pk11_parameters *parsed)
+secmod_parseParameters(char *param, pk11_parameters *parsed, PRBool isFIPS)
{
int next;
char *tmp;
char *index;
+ char *certPrefix = NULL, *keyPrefix = NULL;
+ char *tokdes = NULL, *ptokdes = NULL;
+ char *slotdes = NULL, *pslotdes = NULL;
+ char *fslotdes = NULL, *fpslotdes = NULL;
+ char *minPW = NULL;
index = pk11_argStrip(param);
PORT_Memset(parsed, 0, sizeof(pk11_parameters));
while (*index) {
PK11_HANDLE_STRING_ARG(index,parsed->configdir,"configdir=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->certPrefix,"certprefix=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->keyPrefix,"keyprefix=",;)
PK11_HANDLE_STRING_ARG(index,parsed->secmodName,"secmod=",;)
PK11_HANDLE_STRING_ARG(index,parsed->man,"manufactureID=",;)
PK11_HANDLE_STRING_ARG(index,parsed->libdes,"libraryDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->tokdes,"cryptoTokenDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->ptokdes,"dbTokenDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->slotdes,"cryptoSlotDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->pslotdes,"dbSlotDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->fslotdes,"FIPSSlotDescription=",;)
- PK11_HANDLE_STRING_ARG(index,parsed->fpslotdes,"FIPSTokenDescription=",;)
- PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=",
- if(tmp) { parsed->minPW=atoi(tmp); PORT_Free(tmp); })
+ /* constructed values, used so legacy interfaces still work */
+ PK11_HANDLE_STRING_ARG(index,certPrefix,"certprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,keyPrefix,"keyprefix=",;)
+ PK11_HANDLE_STRING_ARG(index,tokdes,"cryptoTokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,ptokdes,"dbTokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,slotdes,"cryptoSlotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,pslotdes,"dbSlotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,fslotdes,"FIPSSlotDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,minPW,"FIPSTokenDescription=",;)
+ PK11_HANDLE_STRING_ARG(index,tmp,"minPWLen=",;)
+
PK11_HANDLE_STRING_ARG(index,tmp,"flags=",
if(tmp) { secmod_parseFlags(param,parsed); PORT_Free(tmp); })
+ PK11_HANDLE_STRING_ARG(index,tmp,"tokens=",
+ if(tmp) { secmod_parseTokens(tmp,parsed); PORT_Free(tmp); })
PK11_HANDLE_FINAL_ARG(index)
- }
- return CKR_OK;
+ }
+ if (parsed->tokens == NULL) {
+ int count = isFIPS ? 1 : 2;
+ int index = count-1;
+ pk11_token_parameters *tokens = NULL;
+
+ tokens = (pk11_token_parameters *)
+ PORT_ZAlloc(count*sizeof(pk11_token_parameters));
+ if (tokens == NULL) {
+ goto loser;
+ }
+ parsed->tokens = tokens;
+ parsed->token_count = 2;
+ tokens[index].slotID = isFIPS ? FIPS_SLOT_ID : PRIVATE_KEY_SLOT_ID;
+ tokens[index].certPrefix = certPrefix;
+ tokens[index].keyPrefix = keyPrefix;
+ tokens[index].minPW = minPW ? atoi(minPW) : 0;
+ tokens[index].readOnly = parsed->readOnly;
+ tokens[index].noCertDB = parsed->noCertDB;
+ tokens[index].forceOpen = parsed->forceOpen;
+ tokens[index].pwRequired = parsed->pwRequired;
+ certPrefix = NULL;
+ keyPrefix = NULL;
+ if (isFIPS) {
+ tokens[index].tokdes = fslotdes;
+ tokens[index].slotdes = fpslotdes;
+ fslotdes = NULL;
+ fpslotdes = NULL;
+ } else {
+ tokens[index].tokdes = ptokdes;
+ tokens[index].slotdes = pslotdes;
+ tokens[0].slotID = NETSCAPE_SLOT_ID;
+ tokens[0].tokdes = tokdes;
+ tokens[0].slotdes = slotdes;
+ tokens[0].noCertDB = PR_TRUE;
+ tokens[0].noKeyDB = PR_TRUE;
+ ptokdes = NULL;
+ pslotdes = NULL;
+ tokdes = NULL;
+ slotdes = NULL;
+ }
+ }
+
+loser:
+ FREE_CLEAR(certPrefix);
+ FREE_CLEAR(keyPrefix);
+ FREE_CLEAR(tokdes);
+ FREE_CLEAR(ptokdes);
+ FREE_CLEAR(slotdes);
+ FREE_CLEAR(pslotdes);
+ FREE_CLEAR(fslotdes);
+ FREE_CLEAR(fpslotdes);
+ FREE_CLEAR(minPW);
+ return CKR_OK;
}
void
secmod_freeParams(pk11_parameters *params)
{
+ int i;
+
+ for (i=0; i < params->token_count; i++) {
+ FREE_CLEAR(params->tokens[i].configdir);
+ FREE_CLEAR(params->tokens[i].certPrefix);
+ FREE_CLEAR(params->tokens[i].keyPrefix);
+ FREE_CLEAR(params->tokens[i].tokdes);
+ FREE_CLEAR(params->tokens[i].slotdes);
+ }
+
FREE_CLEAR(params->configdir);
- FREE_CLEAR(params->certPrefix);
- FREE_CLEAR(params->keyPrefix);
FREE_CLEAR(params->secmodName);
FREE_CLEAR(params->man);
FREE_CLEAR(params->libdes);
- FREE_CLEAR(params->tokdes);
- FREE_CLEAR(params->ptokdes);
- FREE_CLEAR(params->slotdes);
- FREE_CLEAR(params->pslotdes);
- FREE_CLEAR(params->fslotdes);
- FREE_CLEAR(params->fpslotdes);
+ FREE_CLEAR(params->tokens);
}
@@ -463,7 +604,7 @@ secmod_DecodeData(char *defParams, DBT *data, PRBool *retInternal)
trustOrder = 20;
}
- slotStrings[i] = pk11_mkSlotString(slotID,defaultFlags,
+ slotStrings[i] = pk11_mkSlotString(slotID,defaultFlags,
timeout,slots[i].askpw,hasRootCerts,hasRootTrust);
}
@@ -489,7 +630,7 @@ static DB *secmod_OpenDB(char *dbName, PRBool readOnly) {
if (readOnly) return NULL;
pkcs11db = dbopen( dbName,
- O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
+ O_RDWR | O_CREAT | O_TRUNC, 0600, DB_HASH, 0 );
if (pkcs11db) (* pkcs11db->sync)(pkcs11db, 0);
}
return pkcs11db;
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 76960cfce..8d0f4a786 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -70,6 +70,7 @@ static char *manufacturerID = "mozilla.org ";
static char manufacturerID_space[33];
static char *libraryDescription = "NSS Internal Crypto Services ";
static char libraryDescription_space[33];
+#ifdef notdef
static char *tokDescription = "NSS Generic Crypto Services ";
static char tokDescription_space[33];
static char *privTokDescription = "NSS Certificate DB ";
@@ -82,7 +83,13 @@ static char slotDescription_space[65];
static char *privSlotDescription =
"NSS User Private Key and Certificate Services ";
static char privSlotDescription_space[65];
-static int minimumPinLen = 0;
+/* The next two strings must be exactly 64 characters long, with the
+ first 32 characters meaningful */
+static char *slotDescription =
+ "Netscape Internal FIPS-140-1 Cryptographic Services ";
+static char *privSlotDescription =
+ "Netscape FIPS-140-1 User Private Key Services ";
+#endif
#define __PASTE(x,y) x##y
@@ -424,9 +431,7 @@ pk11_setStringName(char *inString, char *buffer, int buffer_length) {
* Configuration utils
*/
static CK_RV
-pk11_configure(char *man, char *libdes, char *tokdes, char *ptokdes,
- char *slotdes, char *pslotdes, char *fslotdes, char *fpslotdes,
- int minPwd, int pwRequired)
+pk11_configure(char *man, char *libdes)
{
/* make sure the internationalization was done correctly... */
@@ -438,32 +443,6 @@ pk11_configure(char *man, char *libdes, char *tokdes, char *ptokdes,
libraryDescription = pk11_setStringName(libdes,
libraryDescription_space, sizeof(libraryDescription_space));
}
- if (tokdes) {
- tokDescription = pk11_setStringName(tokdes,tokDescription_space,
- sizeof(tokDescription_space));
- }
- if (ptokdes) {
- privTokDescription = pk11_setStringName(ptokdes,
- privTokDescription_space, sizeof(privTokDescription_space));
- }
- if (slotdes) {
- slotDescription = pk11_setStringName(slotdes,slotDescription_space,
- sizeof(slotDescription_space));
- }
- if (pslotdes) {
- privSlotDescription = pk11_setStringName(pslotdes,
- privSlotDescription_space, sizeof(privSlotDescription_space));
- }
-
- if (minimumPinLen <= PK11_MAX_PIN) {
- minimumPinLen = minPwd;
- }
- if ((minimumPinLen == 0) && (pwRequired) &&
- (minimumPinLen <= PK11_MAX_PIN)) {
- minimumPinLen = 1;
- }
-
- PK11_ConfigureFIPS(fslotdes,fpslotdes);
return CKR_OK;
}
@@ -633,7 +612,7 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
}
if (!nsslowcert_CertDBKeyConflict(&derCert,slot->certDB)) {
if (!trust) trust = &defTrust;
- rv = nsslowcert_AddPermCert(cert,label, trust);
+ rv = nsslowcert_AddPermCert(slot->certDB, cert, label, trust);
} else {
rv = trust ? nsslowcert_ChangeCertTrust(slot->certDB,cert,trust) :
SECSuccess;
@@ -806,6 +785,88 @@ pk11_handleTrustObject(PK11Session *session,PK11Object *object)
* check the consistancy and initialize a Trust Object
*/
static CK_RV
+pk11_handleSMimeObject(PK11Session *session,PK11Object *object)
+{
+ char *label;
+
+ /* we can't store any certs private */
+ if (pk11_isTrue(object,CKA_PRIVATE)) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ /* certificates must have a type */
+ if ( !pk11_hasAttribute(object,CKA_SUBJECT) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_NETSCAPE_SMIME_TIMESTAMP) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_VALUE) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
+ PRBool isKRL = PR_FALSE;
+ SECItem derSubj,rawProfile,rawTime,emailKey;
+ char *email = NULL;
+ PK11Attribute *subject,*profile,*time;
+ SECStatus rv;
+
+ PORT_Assert(slot);
+ if (slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
+ /* lookup SUBJECT */
+ subject = pk11_FindAttribute(object,CKA_SUBJECT);
+ PORT_Assert(subject);
+ derSubj.data = (unsigned char *)subject->attrib.pValue;
+ derSubj.len = subject->attrib.ulValueLen ;
+
+ /* lookup VALUE */
+ profile = pk11_FindAttribute(object,CKA_VALUE);
+ PORT_Assert(profile);
+ rawProfile.data = (unsigned char *)profile->attrib.pValue;
+ rawProfile.len = profile->attrib.ulValueLen ;
+
+ /* lookup Time */
+ time = pk11_FindAttribute(object,CKA_NETSCAPE_SMIME_TIMESTAMP);
+ PORT_Assert(time);
+ rawTime.data = (unsigned char *)time->attrib.pValue;
+ rawTime.len = time->attrib.ulValueLen ;
+
+
+ email = pk11_getString(object,CKA_NETSCAPE_EMAIL);
+
+ /* Store CRL by SUBJECT */
+ rv = nsslowcert_SaveSMimeProfile(slot->certDB, email, &derSubj,
+ &rawProfile,&rawTime);
+
+ pk11_FreeAttribute(profile);
+ pk11_FreeAttribute(subject);
+ pk11_FreeAttribute(time);
+ if (rv != SECSuccess) {
+ PORT_Free(email);
+ return CKR_DEVICE_ERROR;
+ }
+ emailKey.data = (unsigned char *)email;
+ emailKey.len = PORT_Strlen(email)+1;
+
+ object->handle = pk11_mkHandle(slot, &emailKey, PK11_TOKEN_TYPE_SMIME);
+ PORT_Free(email);
+ }
+
+ return CKR_OK;
+}
+
+/*
+ * check the consistancy and initialize a Trust Object
+ */
+static CK_RV
pk11_handleCrlObject(PK11Session *session,PK11Object *object)
{
char *label;
@@ -864,7 +925,8 @@ pk11_handleCrlObject(PK11Session *session,PK11Object *object)
return CKR_DEVICE_ERROR;
}
- object->handle = pk11_mkHandle(slot,&derSubj,PK11_TOKEN_TYPE_CRL);
+ object->handle = pk11_mkHandle(slot,&derSubj,
+ isKRL ? PK11_TOKEN_KRL_HANDLE : PK11_TOKEN_TYPE_CRL);
pk11_FreeAttribute(subject);
}
@@ -947,7 +1009,7 @@ pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,
NSSLOWKEYPrivateKey *priv;
SECItem pubKey;
- crv = pk11_Attribute2SecItem(NULL,&pubKey,object,pubKeyAttr);
+ crv = pk11_Attribute2SSecItem(NULL,&pubKey,object,pubKeyAttr);
if (crv != CKR_OK) return crv;
PORT_Assert(pubKey.data);
@@ -1101,15 +1163,15 @@ pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE
object->objectInfo = pk11_mkPrivKey(object,key_type);
if (object->objectInfo == NULL) return CKR_HOST_MEMORY;
object->infoFree = (PK11Free) nsslowkey_DestroyPrivateKey;
- }
- /* now NULL out the sensitive attributes */
- if (pk11_isTrue(object,CKA_SENSITIVE)) {
- pk11_nullAttribute(object,CKA_PRIVATE_EXPONENT);
- pk11_nullAttribute(object,CKA_PRIME_1);
- pk11_nullAttribute(object,CKA_PRIME_2);
- pk11_nullAttribute(object,CKA_EXPONENT_1);
- pk11_nullAttribute(object,CKA_EXPONENT_2);
- pk11_nullAttribute(object,CKA_COEFFICIENT);
+ /* now NULL out the sensitive attributes */
+ if (pk11_isTrue(object,CKA_SENSITIVE)) {
+ pk11_nullAttribute(object,CKA_PRIVATE_EXPONENT);
+ pk11_nullAttribute(object,CKA_PRIME_1);
+ pk11_nullAttribute(object,CKA_PRIME_2);
+ pk11_nullAttribute(object,CKA_EXPONENT_1);
+ pk11_nullAttribute(object,CKA_EXPONENT_2);
+ pk11_nullAttribute(object,CKA_COEFFICIENT);
+ }
}
return CKR_OK;
}
@@ -1305,8 +1367,8 @@ pk11_handleKeyObject(PK11Session *session, PK11Object *object)
/*
* Handle Object does all the object consistancy checks, automatic attribute
* generation, attribute defaulting, etc. If handleObject succeeds, the object
- * will be assigned an object handle, and the object pointer will be adopted
- * by the session. (that is don't free object).
+ * will be assigned an object handle, and the object installed in the session
+ * or stored in the DB.
*/
CK_RV
pk11_handleObject(PK11Object *object, PK11Session *session)
@@ -1369,6 +1431,9 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
case CKO_NETSCAPE_CRL:
crv = pk11_handleCrlObject(session,object);
break;
+ case CKO_NETSCAPE_SMIME:
+ crv = pk11_handleSMimeObject(session,object);
+ break;
case CKO_PRIVATE_KEY:
case CKO_PUBLIC_KEY:
case CKO_SECRET_KEY:
@@ -1780,14 +1845,140 @@ pk11_HashNumber(const void *key)
}
/*
+ * eventually I'd like to expunge all occurances of XXX_SLOT_ID and
+ * just go with the info in the slot. This is one place, however,
+ * where it might be a little difficult.
+ */
+char *
+pk11_getDefTokName(CK_SLOT_ID slotID)
+{
+ static char buf[33];
+
+ switch (slotID) {
+ case NETSCAPE_SLOT_ID:
+ return "NSS Generic Crypto Services ";
+ case PRIVATE_KEY_SLOT_ID:
+ return "NSS Certificate DB ";
+ case FIPS_SLOT_ID:
+ return "NSS FIPS-140-1 Cerificate DB ";
+ default:
+ break;
+ }
+ sprintf(buf,"NSS Application Token %08x ",slotID);
+ return buf;
+}
+
+char *
+pk11_getDefSlotName(CK_SLOT_ID slotID)
+{
+ static char buf[65];
+
+ switch (slotID) {
+ case NETSCAPE_SLOT_ID:
+ return
+ "NSS Internal Cryptographic Services Version 3.4 ";
+ case PRIVATE_KEY_SLOT_ID:
+ return
+ "NSS User Private Key and Certificate Services ";
+ case FIPS_SLOT_ID:
+ return
+ "Netscape FIPS-140-1 User Private Key Services ";
+ default:
+ break;
+ }
+ sprintf(buf,
+ "NSS Application Slot %08x ",slotID);
+ return buf;
+}
+
+static CK_ULONG nscSlotCount = 0;
+static CK_SLOT_ID_PTR nscSlotList = NULL;
+static CK_ULONG nscSlotListSize = 0;
+static PLHashTable *nscSlotHashTable = NULL;
+
+/* look up a slot structure from the ID (used to be a macro when we only
+ * had two slots) */
+PK11Slot *
+pk11_SlotFromID(CK_SLOT_ID slotID)
+{
+ return (PK11Slot *)PL_HashTableLookupConst(nscSlotHashTable,
+ (void *)slotID);
+}
+
+PK11Slot *
+pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
+{
+ int slotIDIndex = (handle >> 24) & 0xff;
+
+ if (slotIDIndex >= nscSlotCount) {
+ return NULL;
+ }
+
+ return pk11_SlotFromID(nscSlotList[slotIDIndex]);
+}
+
+PK11Slot * pk11_NewSlotFromID(CK_SLOT_ID slotID)
+{
+ PK11Slot *slot = NULL;
+ PLHashEntry *entry;
+
+ if (nscSlotList == NULL) {
+ nscSlotListSize = NSC_SLOT_LIST_BLOCK_SIZE;
+ nscSlotList = (CK_SLOT_ID *)
+ PORT_ZAlloc(nscSlotListSize*sizeof(CK_SLOT_ID));
+ if (nscSlotList == NULL) {
+ return NULL;
+ }
+ }
+ if (nscSlotCount >= nscSlotListSize) {
+ nscSlotListSize += NSC_SLOT_LIST_BLOCK_SIZE;
+ nscSlotList = (CK_SLOT_ID *) PORT_Realloc(nscSlotList,
+ nscSlotListSize*sizeof(CK_SLOT_ID));
+ if (nscSlotList == NULL) {
+ return NULL;
+ }
+ }
+
+ if (nscSlotHashTable == NULL) {
+ nscSlotHashTable = PL_NewHashTable(64,pk11_HashNumber,PL_CompareValues,
+ PL_CompareValues, NULL, 0);
+ if (nscSlotHashTable == NULL) {
+ return NULL;
+ }
+ }
+
+ slot = (PK11Slot *) PORT_ZAlloc(sizeof(PK11Slot));
+ if (slot == NULL) {
+ return NULL;
+ }
+
+ entry = PL_HashTableAdd(nscSlotHashTable,(void *)slotID,slot);
+ if (entry == NULL) {
+ PORT_Free(slot);
+ return NULL;
+ }
+ slot->index = nscSlotCount;
+ nscSlotList[nscSlotCount++] = slotID;
+
+ return slot;
+}
+
+/*
* initialize one of the slot structures. figure out which by the ID
*/
CK_RV
-PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin,
- NSSLOWCERTCertDBHandle *certDB, NSSLOWKEYDBHandle *keyDB)
+PK11_SlotInit(char *configdir,pk11_token_parameters *params)
{
int i;
- PK11Slot *slot = pk11_SlotFromID(slotID);
+ CK_SLOT_ID slotID = params->slotID;
+ PK11Slot *slot = pk11_NewSlotFromID(slotID);
+ PRBool needLogin = !params->noKeyDB;
+ CK_RV crv;
+
+ if (slot == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
#ifdef PKCS11_USE_THREADS
slot->sessionLock = PZ_NewLock(nssILockSession);
if (slot->sessionLock == NULL) return CKR_HOST_MEMORY;
@@ -1819,64 +2010,39 @@ PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin,
slot->ssoLoggedIn = PR_FALSE;
slot->DB_loaded = PR_FALSE;
slot->slotID = slotID;
- slot->certDB = certDB;
- slot->keyDB = keyDB;
- if (needLogin) {
- /* if the data base is initialized with a null password,remember that */
- slot->needLogin = (PRBool)!pk11_hasNullPassword(keyDB,&slot->password);
- }
- return CKR_OK;
-}
-
-
-/*
- * common initialization routines between PKCS #11 and FIPS
- */
-CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved)
-{
- CK_RV crv = CKR_OK;
- CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved;
-
- /* NOTE:
- * we should be getting out mutexes from this list, not statically binding
- * them from NSPR. This should happen before we allow the internal to split
- * off from the rest on NSS.
- */
-
- /* initialize the key and cert db's */
- nsslowkey_SetDefaultKeyDBAlg
- (SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
-
- if ((init_args && init_args->LibraryParameters)) {
- pk11_parameters paramStrings;
-
- crv = secmod_parseParameters
- ((char *)init_args->LibraryParameters,&paramStrings);
+ slot->certDB = NULL;
+ slot->keyDB = NULL;
+ slot->minimumPinLen = 0;
+ slot->readOnly = params->readOnly;
+ pk11_setStringName(params->tokdes ? params->tokdes :
+ pk11_getDefTokName(slotID), slot->tokDescription,
+ sizeof(slot->tokDescription));
+ pk11_setStringName(params->slotdes ? params->slotdes :
+ pk11_getDefSlotName(slotID), slot->slotDescription,
+ sizeof(slot->slotDescription));
+
+ if ((!params->noCertDB) || (!params->noKeyDB)) {
+ crv = pk11_DBInit(params->configdir ? params->configdir : configdir,
+ params->certPrefix, params->keyPrefix, params->readOnly,
+ params->noCertDB, params->noKeyDB, params->forceOpen,
+ &slot->certDB, &slot->keyDB);
if (crv != CKR_OK) {
+ /* shoutdown slot? */
return crv;
}
-
- crv = pk11_DBInit(paramStrings.configdir,paramStrings.certPrefix,
- paramStrings.keyPrefix,paramStrings.secmodName, paramStrings.readOnly,paramStrings.noCertDB,
- paramStrings.noModDB, paramStrings.forceOpen);
- if (crv != CKR_OK) {
- secmod_freeParams(&paramStrings);
- return crv;
+ }
+ if (needLogin) {
+ /* if the data base is initialized with a null password,remember that */
+ slot->needLogin =
+ (PRBool)!pk11_hasNullPassword(slot->keyDB,&slot->password);
+ if (params->minPW <= PK11_MAX_PIN) {
+ slot->minimumPinLen = params->minPW;
}
- crv = pk11_configure(paramStrings.man, paramStrings.libdes,
- paramStrings.tokdes,paramStrings.ptokdes,paramStrings.slotdes,
- paramStrings.pslotdes,paramStrings.fslotdes,
- paramStrings.fpslotdes, paramStrings.minPW,
- paramStrings.pwRequired);
- secmod_freeParams(&paramStrings);
- if (crv != CKR_OK) {
- return crv;
+ if ((slot->minimumPinLen == 0) && (params->pwRequired) &&
+ (slot->minimumPinLen <= PK11_MAX_PIN)) {
+ slot->minimumPinLen = 1;
}
- } else {
- return CKR_ARGUMENTS_BAD;
}
-
-
return CKR_OK;
}
@@ -1907,26 +2073,67 @@ NSC_ModuleDBFunc(unsigned long function,char *parameters, char *args)
/* NSC_Initialize initializes the Cryptoki library. */
-CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
+CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS)
{
static PRBool init = PR_FALSE;
CK_RV crv = CKR_OK;
+ SECStatus rv;
+ CK_C_INITIALIZE_ARGS *init_args = (CK_C_INITIALIZE_ARGS *) pReserved;
+ int i;
- crv = PK11_LowInitialize(pReserved);
- if (crv != CKR_OK) return crv;
+ if (init) {
+ return crv;
+ }
- /* intialize all the slots */
- if (!init) {
- crv = PK11_SlotInit(NETSCAPE_SLOT_ID,PR_FALSE,NULL,NULL);
- if (crv != CKR_OK) return crv;
- crv = PK11_SlotInit(PRIVATE_KEY_SLOT_ID,PR_TRUE,
- nsslowcert_GetDefaultCertDB(), nsslowkey_GetDefaultKeyDB());
- init = PR_TRUE;
+ rv = RNG_RNGInit(); /* initialize random number generator */
+ if (rv != SECSuccess) {
+ crv = CKR_DEVICE_ERROR;
+ goto loser;
+ }
+ RNG_SystemInfoForRNG();
+
+
+ /* NOTE:
+ * we should be getting out mutexes from this list, not statically binding
+ * them from NSPR. This should happen before we allow the internal to split
+ * off from the rest on NSS.
+ */
+
+ /* initialize the key and cert db's */
+ nsslowkey_SetDefaultKeyDBAlg
+ (SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
+ crv = CKR_ARGUMENTS_BAD;
+ if ((init_args && init_args->LibraryParameters)) {
+ pk11_parameters paramStrings;
+
+ crv = secmod_parseParameters
+ ((char *)init_args->LibraryParameters,&paramStrings, isFIPS);
+ if (crv != CKR_OK) {
+ return crv;
+ }
+ crv = pk11_configure(paramStrings.man, paramStrings.libdes);
+ if (crv != CKR_OK) {
+ goto loser;
+ }
+
+ for (i=0; i < paramStrings.token_count; i++) {
+ crv =
+ PK11_SlotInit(paramStrings.configdir,&paramStrings.tokens[i]);
+ if (crv != CKR_OK) break;
+ }
+loser:
+ secmod_freeParams(&paramStrings);
}
+ init = (PRBool) (crv == CKR_OK);
return crv;
}
+CK_RV NSC_Initialize(CK_VOID_PTR pReserved)
+{
+ return nsc_CommonInitialize(pReserved,PR_FALSE);
+}
+
/* NSC_Finalize indicates that an application is done with the
* Cryptoki library.*/
CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
@@ -1952,10 +2159,9 @@ CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
CK_SLOT_ID_PTR pSlotList, CK_ULONG_PTR pulCount)
{
- *pulCount = 2;
+ *pulCount = nscSlotCount;
if (pSlotList != NULL) {
- pSlotList[0] = NETSCAPE_SLOT_ID;
- pSlotList[1] = PRIVATE_KEY_SLOT_ID;
+ PORT_Memcpy(pSlotList,nscSlotList,nscSlotCount*sizeof(CK_SLOT_ID));
}
return CKR_OK;
}
@@ -1963,28 +2169,19 @@ CK_RV NSC_GetSlotList(CK_BBOOL tokenPresent,
/* NSC_GetSlotInfo obtains information about a particular slot in the system. */
CK_RV NSC_GetSlotInfo(CK_SLOT_ID slotID, CK_SLOT_INFO_PTR pInfo)
{
+ PK11Slot *slot = pk11_SlotFromID(slotID);
+ if (slot == NULL) return CKR_SLOT_ID_INVALID;
+
pInfo->firmwareVersion.major = 0;
pInfo->firmwareVersion.minor = 0;
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->slotDescription,slotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
- pInfo->hardwareVersion.major = 3;
- pInfo->hardwareVersion.minor = 2;
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->slotDescription,privSlotDescription,64);
- pInfo->flags = CKF_TOKEN_PRESENT;
- /* ok we really should read it out of the keydb file. */
- pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION;
- pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- default:
- break;
- }
- return CKR_SLOT_ID_INVALID;
+ PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
+ PORT_Memcpy(pInfo->slotDescription,slot->slotDescription,64);
+ pInfo->flags = CKF_TOKEN_PRESENT;
+ /* ok we really should read it out of the keydb file. */
+ /* pInfo->hardwareVersion.major = NSSLOWKEY_DB_FILE_VERSION; */
+ pInfo->hardwareVersion.major = 3;
+ pInfo->hardwareVersion.minor = 2;
+ return CKR_OK;
}
#define CKF_THREAD_SAFE 0x8000 /* for now */
@@ -1999,7 +2196,7 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
if (slot == NULL) return CKR_SLOT_ID_INVALID;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
- PORT_Memcpy(pInfo->model,"Libsec 4.0 ",16);
+ PORT_Memcpy(pInfo->model,"NSS 3 ",16);
PORT_Memcpy(pInfo->serialNumber,"0000000000000000",16);
pInfo->ulMaxSessionCount = 0; /* arbitrarily large */
pInfo->ulSessionCount = slot->sessionCount;
@@ -2007,9 +2204,9 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->ulRwSessionCount = slot->rwSessionCount;
pInfo->firmwareVersion.major = 0;
pInfo->firmwareVersion.minor = 0;
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- PORT_Memcpy(pInfo->label,tokDescription,32);
+ PORT_Memcpy(pInfo->label,slot->tokDescription,32);
+ handle = slot->keyDB;
+ if (handle == NULL) {
pInfo->flags= CKF_RNG | CKF_WRITE_PROTECTED | CKF_THREAD_SAFE;
pInfo->ulMaxPinLen = 0;
pInfo->ulMinPinLen = 0;
@@ -2019,10 +2216,7 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->ulFreePrivateMemory = 0;
pInfo->hardwareVersion.major = 4;
pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
- PORT_Memcpy(pInfo->label,privTokDescription,32);
- handle = slot->keyDB;
+ } else {
/*
* we have three possible states which we may be in:
* (1) No DB password has been initialized. This also means we
@@ -2042,8 +2236,8 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
}
pInfo->ulMaxPinLen = PK11_MAX_PIN;
pInfo->ulMinPinLen = 0;
- if (minimumPinLen > 0) {
- pInfo->ulMinPinLen = (CK_ULONG)minimumPinLen;
+ if (slot->minimumPinLen > 0) {
+ pInfo->ulMinPinLen = (CK_ULONG)slot->minimumPinLen;
}
pInfo->ulTotalPublicMemory = 1;
pInfo->ulFreePublicMemory = 1;
@@ -2051,11 +2245,8 @@ CK_RV NSC_GetTokenInfo(CK_SLOT_ID slotID,CK_TOKEN_INFO_PTR pInfo)
pInfo->ulFreePrivateMemory = 1;
pInfo->hardwareVersion.major = CERT_DB_FILE_VERSION;
pInfo->hardwareVersion.minor = 0;
- return CKR_OK;
- default:
- break;
}
- return CKR_SLOT_ID_INVALID;
+ return CKR_OK;
}
@@ -2075,8 +2266,8 @@ CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID,
pMechanismList[i] = mechanisms[i].type;
}
}
- return CKR_OK;
- case PRIVATE_KEY_SLOT_ID:
+ break;
+ default:
*pulCount = 0;
for (i=0; i < (int) mechanismCount; i++) {
if (mechanisms[i].privkey) {
@@ -2086,11 +2277,9 @@ CK_RV NSC_GetMechanismList(CK_SLOT_ID slotID,
}
}
}
- return CKR_OK;
- default:
break;
}
- return CKR_SLOT_ID_INVALID;
+ return CKR_OK;
}
@@ -2106,11 +2295,9 @@ CK_RV NSC_GetMechanismInfo(CK_SLOT_ID slotID, CK_MECHANISM_TYPE type,
case NETSCAPE_SLOT_ID:
isPrivateKey = PR_FALSE;
break;
- case PRIVATE_KEY_SLOT_ID:
+ default:
isPrivateKey = PR_TRUE;
break;
- default:
- return CKR_SLOT_ID_INVALID;
}
for (i=0; i < (int) mechanismCount; i++) {
if (type == mechanisms[i].type) {
@@ -2211,7 +2398,7 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
PK11Slot *slot;
NSSLOWKEYDBHandle *handle;
SECItem *newPin;
- char newPinStr[256];
+ char newPinStr[PK11_MAX_PIN+1];
SECStatus rv;
@@ -2220,35 +2407,34 @@ CK_RV NSC_InitPIN(CK_SESSION_HANDLE hSession,
return CKR_SESSION_HANDLE_INVALID;
}
- if (sp->info.slotID == NETSCAPE_SLOT_ID) {
+ slot = pk11_SlotFromSession(sp);
+ if (slot == NULL) {
pk11_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_SESSION_HANDLE_INVALID;;
}
- /* should be an assert */
- if (!((sp->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (sp->info.slotID == FIPS_SLOT_ID)) ) {
+ handle = slot->keyDB;
+ if (handle == NULL) {
pk11_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
+ return CKR_PIN_LEN_RANGE;
}
+
if (sp->info.state != CKS_RW_SO_FUNCTIONS) {
pk11_FreeSession(sp);
return CKR_USER_NOT_LOGGED_IN;
}
- slot = pk11_SlotFromSession(sp);
pk11_FreeSession(sp);
/* make sure the pins aren't too long */
- if (ulPinLen > 255) {
+ if (ulPinLen > PK11_MAX_PIN) {
return CKR_PIN_LEN_RANGE;
}
-
- handle = slot->keyDB;
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ if (ulPinLen < slot->minimumPinLen) {
+ return CKR_PIN_LEN_RANGE;
}
+
if (nsslowkey_HasKeyDBPassword(handle) != SECFailure) {
return CKR_DEVICE_ERROR;
}
@@ -2288,7 +2474,7 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
NSSLOWKEYDBHandle *handle;
SECItem *newPin;
SECItem *oldPin;
- char newPinStr[256],oldPinStr[256];
+ char newPinStr[PK11_MAX_PIN+1],oldPinStr[PK11_MAX_PIN+1];
SECStatus rv;
@@ -2297,20 +2483,18 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
return CKR_SESSION_HANDLE_INVALID;
}
- if (sp->info.slotID == NETSCAPE_SLOT_ID) {
+ slot = pk11_SlotFromSession(sp);
+ if (!slot) {
pk11_FreeSession(sp);
- return CKR_PIN_LEN_RANGE;
+ return CKR_SESSION_HANDLE_INVALID;;
}
- /* should be an assert */
- /* should be an assert */
- if (!((sp->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (sp->info.slotID == FIPS_SLOT_ID)) ) {
+ handle = slot->keyDB;
+ if (handle == NULL) {
pk11_FreeSession(sp);
- return CKR_SESSION_HANDLE_INVALID;;
+ return CKR_PIN_LEN_RANGE;
}
- slot = pk11_SlotFromSession(sp);
if (slot->needLogin && sp->info.state != CKS_RW_USER_FUNCTIONS) {
pk11_FreeSession(sp);
return CKR_USER_NOT_LOGGED_IN;
@@ -2319,16 +2503,14 @@ CK_RV NSC_SetPIN(CK_SESSION_HANDLE hSession, CK_CHAR_PTR pOldPin,
pk11_FreeSession(sp);
/* make sure the pins aren't too long */
- if ((ulNewLen > 255) || (ulOldLen > 255)) {
+ if ((ulNewLen > PK11_MAX_PIN) || (ulOldLen > PK11_MAX_PIN)) {
return CKR_PIN_LEN_RANGE;
}
-
-
- handle = slot->keyDB;
- if (handle == NULL) {
- return CKR_TOKEN_WRITE_PROTECTED;
+ if (ulNewLen < slot->minimumPinLen) {
+ return CKR_PIN_LEN_RANGE;
}
+
/* convert to null terminated string */
PORT_Memcpy(newPinStr,pNewPin,ulNewLen);
newPinStr[ulNewLen] = 0;
@@ -2375,12 +2557,8 @@ CK_RV NSC_OpenSession(CK_SLOT_ID slotID, CK_FLAGS flags,
if (session == NULL) return CKR_HOST_MEMORY;
PK11_USE_THREADS(PZ_Lock(slot->sessionLock);)
- sessionID = slot->sessionIDCount++;
- if (slotID == PRIVATE_KEY_SLOT_ID) {
- sessionID |= PK11_PRIVATE_KEY_FLAG;
- } else if (slotID == FIPS_SLOT_ID) {
- sessionID |= PK11_FIPS_FLAG;
- } else if (flags & CKF_RW_SESSION) {
+ sessionID = slot->sessionIDCount++ | (slot->index << 24);
+ if (slot->readOnly && (flags & CKF_RW_SESSION)) {
/* NETSCAPE_SLOT_ID is Read ONLY */
session->info.flags &= ~CKF_RW_SESSION;
}
@@ -2504,7 +2682,7 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
PK11Session *session;
NSSLOWKEYDBHandle *handle;
SECItem *pin;
- char pinStr[256];
+ char pinStr[PK11_MAX_PIN+1];
/* get the slot */
@@ -2524,7 +2702,7 @@ CK_RV NSC_Login(CK_SESSION_HANDLE hSession, CK_USER_TYPE userType,
if (slot->isLoggedIn) return CKR_USER_ALREADY_LOGGED_IN;
slot->ssoLoggedIn = PR_FALSE;
- if (ulPinLen > 255) return CKR_PIN_LEN_RANGE;
+ if (ulPinLen > PK11_MAX_PIN) return CKR_PIN_LEN_RANGE;
/* convert to null terminated string */
PORT_Memcpy(pinStr,pPin,ulPinLen);
@@ -2659,14 +2837,11 @@ CK_RV NSC_CreateObject(CK_SESSION_HANDLE hSession,
* handle the base object stuff
*/
crv = pk11_handleObject(object,session);
+ *phObject = object->handle;
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(object);
- return crv;
- }
+ pk11_FreeObject(object);
- *phObject = object->handle;
- return CKR_OK;
+ return crv;
}
@@ -2747,12 +2922,9 @@ CK_RV NSC_CopyObject(CK_SESSION_HANDLE hSession,
crv = pk11_handleObject(destObject,session);
*phNewObject = destObject->handle;
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(destObject);
- return crv;
- }
+ pk11_FreeObject(destObject);
- return CKR_OK;
+ return crv;
}
@@ -2918,6 +3090,71 @@ CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
/*
* structure to collect key handles.
*/
+typedef struct pk11CrlDataStr {
+ PK11Slot *slot;
+ PK11SearchResults *searchHandles;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+} pk11CrlData;
+
+
+static SECStatus
+pk11_crl_collect(SECItem *data, SECItem *key, certDBEntryType type, void *arg)
+{
+ pk11CrlData *crlData;
+ CK_OBJECT_HANDLE class_handle;
+ PK11Slot *slot;
+
+ crlData = (pk11CrlData *)arg;
+ slot = crlData->slot;
+
+ class_handle = (type == certDBEntryTypeRevocation) ? PK11_TOKEN_TYPE_CRL :
+ PK11_TOKEN_KRL_HANDLE;
+ if (pk11_tokenMatch(slot, key, class_handle,
+ crlData->template, crlData->templ_count)) {
+ pk11_addHandle(crlData->searchHandles,
+ pk11_mkHandle(slot,key,class_handle));
+ }
+ return(SECSuccess);
+}
+
+static void
+pk11_searchCrls(PK11Slot *slot, SECItem *derSubject, PRBool isKrl,
+ unsigned long classFlags, PK11SearchResults *search,
+ CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
+{
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
+
+ certHandle = slot->certDB;
+ if (certHandle == NULL) {
+ return;
+ }
+ if (derSubject->data != NULL) {
+ SECItem *crl =
+ nsslowcert_FindCrlByKey(certHandle,derSubject,NULL,isKrl);
+
+ if (crl != NULL) {
+ pk11_addHandle(search, pk11_mkHandle(slot,derSubject,
+ isKrl ? PK11_TOKEN_KRL_HANDLE : PK11_TOKEN_TYPE_CRL));
+ }
+ } else {
+ pk11CrlData crlData;
+
+ /* traverse */
+ crlData.slot = slot;
+ crlData.searchHandles = search;
+ crlData.template = pTemplate;
+ crlData.templ_count = ulCount;
+ nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeRevocation,
+ pk11_crl_collect, (void *)&crlData);
+ nsslowcert_TraverseDBEntries(certHandle, certDBEntryTypeKeyRevocation,
+ pk11_crl_collect, (void *)&crlData);
+ }
+}
+
+/*
+ * structure to collect key handles.
+ */
typedef struct pk11KeyDataStr {
PK11Slot *slot;
PK11SearchResults *searchHandles;
@@ -2929,19 +3166,6 @@ typedef struct pk11KeyDataStr {
PRBool strict;
} pk11KeyData;
-/*
- * structure to collect certs into
- */
-typedef struct pk11CertDataStr {
- PK11Slot *slot;
- int cert_count;
- int max_cert_count;
- NSSLOWCERTCertificate **certs;
- CK_ATTRIBUTE *template;
- CK_ULONG templ_count;
- unsigned long classFlags;
- PRBool strict;
-} pk11CertData;
static SECStatus
pk11_key_collect(DBT *key, DBT *data, void *arg)
@@ -3013,6 +3237,58 @@ loser:
}
return(SECSuccess);
}
+
+static void
+pk11_searchKeys(PK11Slot *slot, SECItem *key_id, PRBool isLoggedIn,
+ unsigned long classFlags, PK11SearchResults *search,
+ CK_ATTRIBUTE *pTemplate, CK_ULONG ulCount)
+{
+ NSSLOWKEYDBHandle *keyHandle = NULL;
+ NSSLOWKEYPrivateKey *privKey;
+ pk11KeyData keyData;
+
+ keyHandle = slot->keyDB;
+ if (keyHandle == NULL) {
+ return;
+ }
+
+ if (key_id->data && (classFlags & NSC_KEY)) {
+ privKey = nsslowkey_FindKeyByPublicKey(keyHandle,key_id, slot->password);
+ if (privKey) {
+ pk11_addHandle(search,pk11_mkHandle(slot,key_id,PK11_TOKEN_TYPE_KEY));
+ nsslowkey_DestroyPrivateKey(privKey);
+ }
+ if ( !(classFlags & (NSC_PRIVATE|NSC_PUBLIC)) ) {
+ /* skip the traverse, nothing new to find */
+ return;
+ }
+ }
+ keyData.slot = slot;
+ keyData.searchHandles = search;
+ keyData.id = key_id;
+ keyData.template = pTemplate;
+ keyData.templ_count = ulCount;
+ keyData.isLoggedIn = isLoggedIn;
+ keyData.classFlags = classFlags;
+ keyData.strict = NSC_STRICT;
+
+ nsslowkey_TraverseKeys(keyHandle, pk11_key_collect, &keyData);
+}
+
+/*
+ * structure to collect certs into
+ */
+typedef struct pk11CertDataStr {
+ PK11Slot *slot;
+ int cert_count;
+ int max_cert_count;
+ NSSLOWCERTCertificate **certs;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+ unsigned long classFlags;
+ PRBool strict;
+} pk11CertData;
+
/*
* collect all the certs from the traverse call.
*/
@@ -3183,6 +3459,42 @@ pk11_searchCertsAndTrust(PK11Slot *slot, SECItem *derCert, SECItem *name,
return;
}
+static void
+pk11_searchSMime(PK11Slot *slot, SECItem *email, PK11SearchResults *handles,
+ CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
+{
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
+ certDBEntrySMime *entry;
+
+ certHandle = slot->certDB;
+ if (certHandle == NULL) return;
+
+ if (email->data != NULL) {
+ char *tmp_name = (char*)PORT_Alloc(email->len+1);
+ int count;
+
+ if (tmp_name == NULL) {
+ return;
+ }
+ PORT_Memcpy(tmp_name,email->data,email->len);
+ tmp_name[email->len] = 0;
+
+ entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name);
+ if (entry) {
+ SECItem emailKey;
+
+ emailKey.data = (unsigned char *)tmp_name;
+ emailKey.len = PORT_Strlen(tmp_name)+1;
+ pk11_addHandle(handles,
+ pk11_mkHandle(slot,&emailKey,PK11_TOKEN_TYPE_SMIME));
+ nsslowcert_DestroyDBEntry((certDBEntry *)entry);
+ }
+ PORT_Free(tmp_name);
+ }
+ return;
+}
+
+
static CK_RV
pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
CK_ATTRIBUTE *pTemplate, CK_LONG ulCount,
@@ -3193,6 +3505,7 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
SECItem derCert = { siBuffer, NULL, 0 };
SECItem derSubject = { siBuffer, NULL, 0 };
SECItem name = { siBuffer, NULL, 0 };
+ SECItem email = { siBuffer, NULL, 0 };
SECItem key_id = { siBuffer, NULL, 0 };
SECItem cert_sha1_hash = { siBuffer, NULL, 0 };
SECItem cert_md5_hash = { siBuffer, NULL, 0 };
@@ -3209,19 +3522,19 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
classFlags &= ~(NSC_PRIVATE|NSC_KEY);
}
-
/*
- * look for things to search on certs for. We only need one of these
- * items. If we find all the certs that match that item, import them
- * (as long as they are user certs). We'll let find objects filter out
- * the ones that don't apply.
+ * look for things to search on token objects for. If the right options
+ * are specified, we can use them as direct indeces into the database
+ * (rather than using linear searches. We can also use the attributes to
+ * limit the kinds of objects we are searching for. Later we can use this
+ * array to filter the remaining objects more finely.
*/
for (i=0 ;classFlags && i < (int)ulCount; i++) {
switch (pTemplate[i].type) {
case CKA_SUBJECT:
copy = &derSubject;
- classFlags &= (NSC_CERT|NSC_PRIVATE|NSC_PUBLIC);
+ classFlags &= (NSC_CERT|NSC_PRIVATE|NSC_PUBLIC|NSC_SMIME);
break;
case CKA_ISSUER:
copy = &issuerSN.derIssuer;
@@ -3233,11 +3546,18 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
break;
case CKA_VALUE:
copy = &derCert;
- classFlags &= (NSC_CERT|NSC_CRL);
+ classFlags &= (NSC_CERT|NSC_CRL|NSC_SMIME);
break;
case CKA_LABEL:
copy = &name;
break;
+ case CKA_NETSCAPE_EMAIL:
+ copy = &email;
+ classFlags &= NSC_SMIME;
+ break;
+ case CKA_NETSCAPE_SMIME_TIMESTAMP:
+ classFlags &= NSC_SMIME;
+ break;
case CKA_CLASS:
if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
classFlags = 0;
@@ -3253,6 +3573,9 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
case CKO_NETSCAPE_CRL:
classFlags &= NSC_CRL;
break;
+ case CKO_NETSCAPE_SMIME:
+ classFlags &= NSC_SMIME;
+ break;
case CKO_PRIVATE_KEY:
classFlags &= NSC_PRIVATE;
break;
@@ -3313,10 +3636,15 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
}
break;
case CKA_ID:
- copy = &key_id; break;
+ copy = &key_id;
+ classFlags &= (NSC_CERT|NSC_PRIVATE|NSC_KEY|NSC_PUBLIC);
+ break;
case CKA_NETSCAPE_KRL:
+ if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
+ classFlags = 0;
+ }
classFlags &= NSC_CRL;
- isKrl = PR_TRUE;
+ isKrl = (PRBool)(*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE);
break;
case CKA_MODIFIABLE:
break;
@@ -3366,64 +3694,19 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
/* keys */
if (classFlags & (NSC_PRIVATE|NSC_PUBLIC|NSC_KEY)) {
- NSSLOWKEYDBHandle *keyHandle = NULL;
- NSSLOWKEYPrivateKey *privKey;
- pk11KeyData keyData;
-
- keyHandle = slot->keyDB;
- if (keyHandle == NULL) {
- goto key_loser;
- }
-
- if (key_id.data && (classFlags & NSC_KEY)) {
- privKey = nsslowkey_FindKeyByPublicKey(keyHandle,&key_id,
- slot->password);
- if (privKey) {
- pk11_addHandle(search,pk11_mkHandle(slot,&key_id,
- PK11_TOKEN_TYPE_KEY));
- nsslowkey_DestroyPrivateKey(privKey);
- }
- if ( !(classFlags & (NSC_PRIVATE|NSC_PUBLIC)) ) {
- /* skip the traverse, nothing new to find */
- goto key_loser;
- }
- }
- keyData.slot = slot;
- keyData.searchHandles = search;
- keyData.id = &key_id;
- keyData.template = pTemplate;
- keyData.templ_count = ulCount;
- keyData.isLoggedIn = isLoggedIn;
- keyData.classFlags = classFlags;
- keyData.strict = NSC_STRICT;
-
- nsslowkey_TraverseKeys(keyHandle, pk11_key_collect, &keyData);
+ pk11_searchKeys(slot, &key_id, isLoggedIn, classFlags, search,
+ pTemplate, ulCount);
}
-key_loser:
/* crl's */
if (classFlags & NSC_CRL) {
- NSSLOWCERTCertDBHandle *certHandle = NULL;
-
- certHandle = slot->certDB;
- if (certHandle == NULL) {
- goto crl_loser;
- }
- if (derSubject.data != NULL) {
- SECItem *crl =
- nsslowcert_FindCrlByKey(certHandle,&derSubject,NULL,isKrl);
-
- if (crl != NULL) {
- pk11_addHandle(search,
- pk11_mkHandle(slot,&derSubject,PK11_TOKEN_TYPE_CRL));
- }
- } else {
- /* traverse */
- PORT_Assert(0);
- }
+ pk11_searchCrls(slot, &derSubject, isKrl, classFlags, search,
+ pTemplate, ulCount);
}
-crl_loser:
/* Add S/MIME entry stuff */
+ if (classFlags & NSC_SMIME) {
+ pk11_searchSMime(slot, &email, search, pTemplate, ulCount);
+ }
return CKR_OK;
}
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index f1ab1df0c..6da00d8b8 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -58,7 +58,7 @@
#include "sechash.h"
#include "secder.h"
#include "secdig.h"
-#include "secpkcs5.h" /* We do PBE below */
+#include "lowpbe.h" /* We do PBE below */
#include "pkcs11t.h"
#include "secoid.h"
#include "alghmac.h"
@@ -119,11 +119,6 @@ pk11_Space(void *data, PRBool freeit)
PORT_Free(data);
}
-static void pk11_FreeSignInfo(PK11HashSignInfo *data, PRBool freeit)
-{
- nsslowkey_DestroyPrivateKey(data->key);
- PORT_Free(data);
-}
/*
* turn a CDMF key into a des key. CDMF is an old IBM scheme to export DES by
@@ -176,9 +171,9 @@ pk11_cdmf2des(unsigned char *cdmfkey, unsigned char *deskey)
static CK_RV
-pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+pk11_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype,
- PK11ContextType contextType);
+ PK11ContextType contextType, PRBool isEncrypt);
/*
* Calculate a Lynx checksum for CKM_LYNX_WRAP mechanism.
*/
@@ -206,7 +201,8 @@ pk11_calcLynxChecksum(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hWrapKey,
/* encrypt with key 1 */
- crv = pk11_EncryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT,
+ PR_TRUE);
if (crv != CKR_OK) return crv;
crv = NSC_Encrypt(hSession,key,len,E,&Elen);
@@ -215,7 +211,8 @@ pk11_calcLynxChecksum(CK_SESSION_HANDLE hSession, CK_OBJECT_HANDLE hWrapKey,
E[8] = (sum2 >> 8) & 0xff;
E[9] = sum2 & 0xff;
- crv = pk11_EncryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession,&mech,hWrapKey,CKA_WRAP, PK11_ENCRYPT,
+ PR_TRUE);
if (crv != CKR_OK) return crv;
crv = NSC_Encrypt(hSession,&E[2],len,C,&Clen);
@@ -422,18 +419,19 @@ pk11_InitGeneric(PK11Session *session,PK11SessionContext **contextPtr,
context->hashInfo = NULL;
context->doPad = PR_FALSE;
context->padDataLength = 0;
+ context->key = key;
*contextPtr = context;
return CKR_OK;
}
-/* NSC_EncryptInit initializes an encryption operation. */
+/* NSC_CryptInit initializes an encryption/Decryption operation. */
/* This function is used by NSC_EncryptInit and NSC_WrapKey. The only difference
* in their uses if whether or not etype is CKA_ENCRYPT or CKA_WRAP */
static CK_RV
-pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
+pk11_CryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE etype,
- PK11ContextType contextType)
+ PK11ContextType contextType, PRBool isEncrypt)
{
PK11Session *session;
PK11Object *key;
@@ -456,7 +454,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- CKO_PUBLIC_KEY, etype);
+ isEncrypt ?CKO_PUBLIC_KEY:CKO_PRIVATE_KEY, etype);
if (crv != CKR_OK) {
pk11_FreeSession(session);
@@ -472,14 +470,22 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
break;
}
context->multi = PR_FALSE;
- pubKey = pk11_GetPubKey(key,CKK_RSA);
- if (pubKey == NULL) {
+ context->cipherInfo = isEncrypt ?
+ (void *)pk11_GetPubKey(key,CKK_RSA) :
+ (void *)pk11_GetPrivKey(key,CKK_RSA);
+ if (context->cipherInfo == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- context->cipherInfo = pubKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_EncryptRaw : RSA_EncryptBlock);
+ if (isEncrypt) {
+ context->update = (PK11Cipher)
+ (pMechanism->mechanism == CKM_RSA_X_509
+ ? RSA_EncryptRaw : RSA_EncryptBlock);
+ } else {
+ context->update = (PK11Cipher)
+ (pMechanism->mechanism == CKM_RSA_X_509
+ ? RSA_DecryptRaw : RSA_DecryptBlock);
+ }
context->destroy = pk11_Null;
break;
case CKM_RC2_CBC_PAD:
@@ -509,7 +515,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) RC2_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? RC2_Encrypt : RC2_Decrypt);
context->destroy = (PK11Destroy) RC2_DestroyContext;
break;
#if NSS_SOFTOKEN_DOES_RC5
@@ -541,7 +547,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) RC5_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? RC5_Encrypt : RC5_Decrypt);
context->destroy = (PK11Destroy) RC5_DestroyContext;
break;
#endif
@@ -563,7 +569,7 @@ pk11_EncryptInit(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
crv = CKR_HOST_MEMORY; /* WRONG !!! */
break;
}
- context->update = (PK11Cipher) RC4_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? RC4_Encrypt : RC4_Decrypt);
context->destroy = (PK11Destroy) RC4_DestroyContext;
break;
case CKM_CDMF_CBC_PAD:
@@ -630,13 +636,13 @@ finish_des:
}
context->cipherInfo = DES_CreateContext(
useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, PR_TRUE);
+ (unsigned char*)pMechanism->pParameter,t, isEncrypt);
pk11_FreeAttribute(att);
if (context->cipherInfo == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) DES_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? DES_Encrypt : DES_Decrypt);
context->destroy = (PK11Destroy) DES_DestroyContext;
break;
@@ -659,13 +665,13 @@ finish_des:
(unsigned char*)att->attrib.pValue,
(unsigned char*)pMechanism->pParameter,
pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC,
- PR_TRUE, att->attrib.ulValueLen, 16);
+ isEncrypt, att->attrib.ulValueLen, 16);
pk11_FreeAttribute(att);
if (context->cipherInfo == NULL) {
crv = CKR_HOST_MEMORY;
break;
}
- context->update = (PK11Cipher) AES_Encrypt;
+ context->update = (PK11Cipher) (isEncrypt ? AES_Encrypt : AES_Decrypt);
context->destroy = (PK11Destroy) AES_DestroyContext;
break;
@@ -674,7 +680,6 @@ finish_des:
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
pk11_FreeContext(context);
pk11_FreeSession(session);
@@ -689,8 +694,8 @@ finish_des:
CK_RV NSC_EncryptInit(CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
- return pk11_EncryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT,
- PK11_ENCRYPT);
+ return pk11_CryptInit(hSession, pMechanism, hKey, CKA_ENCRYPT,
+ PK11_ENCRYPT, PR_TRUE);
}
/* NSC_EncryptUpdate continues a multiple-part encryption operation. */
@@ -846,258 +851,11 @@ CK_RV NSC_Encrypt (CK_SESSION_HANDLE hSession, CK_BYTE_PTR pData,
*/
/* NSC_DecryptInit initializes a decryption operation. */
-static CK_RV pk11_DecryptInit( CK_SESSION_HANDLE hSession,
- CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey, CK_ATTRIBUTE_TYPE dtype,
- PK11ContextType contextType)
-{
- PK11Session *session;
- PK11Object *key;
- PK11Attribute *att;
- PK11SessionContext *context;
- CK_RC2_CBC_PARAMS *rc2_param;
-#if NSS_SOFTOKEN_DOES_RC5
- CK_RC5_CBC_PARAMS *rc5_param;
- SECItem rc5Key;
-#endif
- CK_KEY_TYPE key_type;
- CK_RV crv = CKR_OK;
- unsigned effectiveKeyLength;
- NSSLOWKEYPrivateKey *privKey;
- unsigned char newdeskey[8];
- PRBool useNewKey=PR_FALSE;
- int t;
-
- session = pk11_SessionFromHandle(hSession);
- if (session == NULL) return CKR_SESSION_HANDLE_INVALID;
-
- crv = pk11_InitGeneric(session,&context,contextType,&key,hKey,&key_type,
- CKO_PRIVATE_KEY,dtype);
- if (crv != CKR_OK) {
- pk11_FreeSession(session);
- return crv;
- }
-
- /*
- * now handle each mechanism
- */
- switch(pMechanism->mechanism) {
- case CKM_RSA_PKCS:
- case CKM_RSA_X_509:
- if (key_type != CKK_RSA) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- context->multi = PR_FALSE;
- privKey = pk11_GetPrivKey(key,CKK_RSA);
- if (privKey == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->cipherInfo = privKey;
- context->update = (PK11Cipher) (pMechanism->mechanism == CKM_RSA_X_509
- ? RSA_DecryptRaw : RSA_DecryptBlock);
- context->destroy = (context->cipherInfo == key->objectInfo) ?
- (PK11Destroy) pk11_Null : (PK11Destroy) pk11_FreePrivKey;
- break;
- case CKM_RC2_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_RC2_ECB:
- case CKM_RC2_CBC:
- if (key_type != CKK_RC2) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- rc2_param = (CK_RC2_CBC_PARAMS *)pMechanism->pParameter;
- effectiveKeyLength = (rc2_param->ulEffectiveBits+7)/8;
- context->cipherInfo = RC2_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen, rc2_param->iv,
- pMechanism->mechanism == CKM_RC2_ECB ? NSS_RC2 :
- NSS_RC2_CBC, effectiveKeyLength);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC2_Decrypt;
- context->destroy = (PK11Destroy) RC2_DestroyContext;
- break;
-#if NSS_SOFTOKEN_DOES_RC5
- case CKM_RC5_CBC_PAD:
- context->doPad = PR_TRUE;
- /* fall thru */
- case CKM_RC5_ECB:
- case CKM_RC5_CBC:
- if (key_type != CKK_RC5) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- rc5_param = (CK_RC5_CBC_PARAMS *)pMechanism->pParameter;
- if (context->doPad) {
- context->blockSize = rc5_param->ulWordsize*2;
- }
- rc5Key.data = (unsigned char*)att->attrib.pValue;
- rc5Key.len = att->attrib.ulValueLen;
- context->cipherInfo = RC5_CreateContext(&rc5Key,rc5_param->ulRounds,
- rc5_param->ulWordsize,rc5_param->pIv,
- pMechanism->mechanism == CKM_RC5_ECB ? NSS_RC5 : NSS_RC5_CBC);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC5_Decrypt;
- context->destroy = (PK11Destroy) RC5_DestroyContext;
- break;
-#endif
- case CKM_RC4:
- if (key_type != CKK_RC4) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- context->cipherInfo =
- RC4_CreateContext((unsigned char*)att->attrib.pValue,
- att->attrib.ulValueLen);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) RC4_Decrypt;
- context->destroy = (PK11Destroy) RC4_DestroyContext;
- break;
- case CKM_CDMF_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_CDMF_ECB:
- case CKM_CDMF_CBC:
- if (key_type != CKK_CDMF) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = (pMechanism->mechanism == CKM_CDMF_ECB) ? NSS_DES : NSS_DES_CBC;
- useNewKey = PR_TRUE;
- if (crv != CKR_OK) break;
- goto finish_des;
- case CKM_DES_ECB:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES;
- goto finish_des;
- case CKM_DES_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES_CBC:
- if (key_type != CKK_DES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_CBC;
- goto finish_des;
- case CKM_DES3_ECB:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3;
- goto finish_des;
- case CKM_DES3_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 8;
- /* fall thru */
- case CKM_DES3_CBC:
- if ((key_type != CKK_DES2) && (key_type != CKK_DES3)) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- t = NSS_DES_EDE3_CBC;
-finish_des:
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- if (useNewKey) {
- crv = pk11_cdmf2des((unsigned char*)att->attrib.pValue,newdeskey);
- if (crv != CKR_OK) {
- pk11_FreeAttribute(att);
- break;
- }
- }
- context->cipherInfo = DES_CreateContext(
- useNewKey ? newdeskey : (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,t, PR_FALSE);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) DES_Decrypt;
- context->destroy = (PK11Destroy) DES_DestroyContext;
-
- break;
- case CKM_AES_CBC_PAD:
- context->doPad = PR_TRUE;
- context->blockSize = 16;
- /* fall thru */
- case CKM_AES_ECB:
- case CKM_AES_CBC:
- if (key_type != CKK_AES) {
- crv = CKR_KEY_TYPE_INCONSISTENT;
- break;
- }
- att = pk11_FindAttribute(key,CKA_VALUE);
- if (att == NULL) {
- crv = CKR_KEY_HANDLE_INVALID;
- break;
- }
- context->cipherInfo = AES_CreateContext(
- (unsigned char*)att->attrib.pValue,
- (unsigned char*)pMechanism->pParameter,
- pMechanism->mechanism == CKM_AES_ECB ? NSS_AES : NSS_AES_CBC,
- PR_FALSE, att->attrib.ulValueLen,16);
- pk11_FreeAttribute(att);
- if (context->cipherInfo == NULL) {
- crv = CKR_HOST_MEMORY;
- break;
- }
- context->update = (PK11Cipher) AES_Decrypt;
- context->destroy = (PK11Destroy) AES_DestroyContext;
-
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- break;
- }
-
- pk11_FreeObject(key);
- if (crv != CKR_OK) {
- pk11_FreeContext(context);
- pk11_FreeSession(session);
- return crv;
- }
- pk11_SetContextByType(session, contextType, context);
- pk11_FreeSession(session);
- return CKR_OK;
-}
-
-/* NSC_DecryptInit initializes a decryption operation. */
CK_RV NSC_DecryptInit( CK_SESSION_HANDLE hSession,
CK_MECHANISM_PTR pMechanism, CK_OBJECT_HANDLE hKey)
{
- return pk11_DecryptInit(hSession,pMechanism,hKey,CKA_DECRYPT,PK11_DECRYPT);
+ return pk11_CryptInit(hSession, pMechanism, hKey, CKA_DECRYPT,
+ PK11_DECRYPT, PR_FALSE);
}
/* NSC_DecryptUpdate continues a multiple-part decryption operation. */
@@ -1867,8 +1625,8 @@ pk11_InitCBCMac(CK_SESSION_HANDLE hSession, CK_MECHANISM_PTR pMechanism,
return CKR_FUNCTION_NOT_SUPPORTED;
}
- crv = pk11_EncryptInit(hSession, &cbc_mechanism, hKey, keyUsage,
- contextType);
+ crv = pk11_CryptInit(hSession, &cbc_mechanism, hKey, keyUsage,
+ contextType, PR_TRUE);
if (crv != CKR_OK) return crv;
crv = pk11_GetContext(hSession,&context,contextType,PR_TRUE,NULL);
@@ -2063,23 +1821,14 @@ finish_rsa:
/* OK, info is allocated only if we're doing hash and sign mechanism.
* It's necessary to be able to set the correct OID in the final
* signature.
- * Second, what's special about privKey == key->objectInfo?
- * Well we don't 'cache' token versions
- * of private keys because (1) it's sensitive data, and (2) it never
- * gets destroyed. Instead we grab the key out of the database as
- * necessary, but now the key is our context, and we need to free
- * it when we are done. Non-token private keys will get freed when
- * the user destroys the session object (or the session the session
- * object lives in) */
+ */
if (info) {
info->key = privKey;
context->cipherInfo = info;
- context->destroy = (privKey == key->objectInfo) ?
- (PK11Destroy)pk11_Space:(PK11Destroy)pk11_FreeSignInfo;
+ context->destroy = (PK11Destroy)pk11_Space;
} else {
context->cipherInfo = privKey;
- context->destroy = (privKey == key->objectInfo) ?
- (PK11Destroy)pk11_Null:(PK11Destroy)pk11_FreePrivKey;
+ context->destroy = (PK11Destroy)pk11_Null;
}
break;
@@ -2141,9 +1890,8 @@ finish_rsa:
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
- PORT_Free(context);
+ pk11_FreeContext(context);
pk11_FreeSession(session);
return crv;
}
@@ -2546,7 +2294,6 @@ finish_rsa:
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
PORT_Free(context);
pk11_FreeSession(session);
@@ -2688,7 +2435,6 @@ CK_RV NSC_VerifyRecoverInit(CK_SESSION_HANDLE hSession,
break;
}
- pk11_FreeObject(key);
if (crv != CKR_OK) {
PORT_Free(context);
pk11_FreeSession(session);
@@ -3134,10 +2880,6 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
*/
crv = pk11_handleObject(key,session);
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
if (pk11_isTrue(key,CKA_SENSITIVE)) {
pk11_forceAttribute(key,CKA_ALWAYS_SENSITIVE,&cktrue,sizeof(CK_BBOOL));
}
@@ -3146,7 +2888,8 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
}
*phKey = key->handle;
- return CKR_OK;
+ pk11_FreeObject(key);
+ return crv;
}
@@ -3471,7 +3214,7 @@ dhgn_done:
/*
* handle the base object cleanup for the public Key
*/
- crv = pk11_handleObject(publicKey,session);
+ crv = pk11_handleObject(privateKey,session);
if (crv != CKR_OK) {
pk11_FreeSession(session);
pk11_FreeObject(privateKey);
@@ -3484,11 +3227,12 @@ dhgn_done:
* If we have any problems, we destroy the public Key we've
* created and linked.
*/
- crv = pk11_handleObject(privateKey,session);
+ crv = pk11_handleObject(publicKey,session);
pk11_FreeSession(session);
if (crv != CKR_OK) {
+ pk11_FreeObject(publicKey);
+ NSC_DestroyObject(hSession,privateKey->handle);
pk11_FreeObject(privateKey);
- NSC_DestroyObject(hSession,publicKey->handle);
return crv;
}
if (pk11_isTrue(privateKey,CKA_SENSITIVE)) {
@@ -3509,6 +3253,8 @@ dhgn_done:
}
*phPrivateKey = privateKey->handle;
*phPublicKey = publicKey->handle;
+ pk11_FreeObject(publicKey);
+ pk11_FreeObject(privateKey);
return CKR_OK;
}
@@ -3656,8 +3402,8 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
len = *pulWrappedKeyLen;
}
- crv = pk11_EncryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession, pMechanism, hWrappingKey,
+ CKA_WRAP, PK11_ENCRYPT, PR_TRUE);
if (crv != CKR_OK) {
pk11_FreeAttribute(attribute);
break;
@@ -3688,8 +3434,8 @@ CK_RV NSC_WrapKey(CK_SESSION_HANDLE hSession,
break;
}
- crv = pk11_EncryptInit(hSession, pMechanism, hWrappingKey,
- CKA_WRAP, PK11_ENCRYPT);
+ crv = pk11_CryptInit(hSession, pMechanism, hWrappingKey,
+ CKA_WRAP, PK11_ENCRYPT, PR_TRUE);
if(crv != CKR_OK) {
SECITEM_ZfreeItem(bpki, PR_TRUE);
crv = CKR_KEY_TYPE_INCONSISTENT;
@@ -3948,8 +3694,8 @@ CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
ulWrappedKeyLen -= 2; /* don't decrypt the checksum */
}
- crv = pk11_DecryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
- PK11_DECRYPT);
+ crv = pk11_CryptInit(hSession,pMechanism,hUnwrappingKey,CKA_UNWRAP,
+ PK11_DECRYPT, PR_FALSE);
if (crv != CKR_OK) {
pk11_FreeObject(key);
return pk11_mapWrap(crv);
@@ -4026,14 +3772,11 @@ CK_RV NSC_UnwrapKey(CK_SESSION_HANDLE hSession,
* handle the base object stuff
*/
crv = pk11_handleObject(key,session);
+ *phKey = key->handle;
pk11_FreeSession(session);
- if (crv != CKR_OK) {
- pk11_FreeObject(key);
- return crv;
- }
+ pk11_FreeObject(key);
- *phKey = key->handle;
- return CKR_OK;
+ return crv;
}
@@ -4091,10 +3834,7 @@ pk11_buildSSLKey(CK_SESSION_HANDLE hSession, PK11Object *baseKey,
crv = pk11_handleObject(key,session);
pk11_FreeSession(session);
- if (crv == CKR_OK) {
- *keyHandle = key->handle;
- return crv;
- }
+ *keyHandle = key->handle;
loser:
if (key) pk11_FreeObject(key);
return crv;
@@ -5212,10 +4952,7 @@ key_and_mac_derive_fail:
crv = pk11_handleObject(key,session);
pk11_FreeSession(session);
- if (crv == CKR_OK) {
- *phKey = key->handle;
- return crv;
- }
+ *phKey = key->handle;
pk11_FreeObject(key);
}
return crv;
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index 102fb5738..c09b2635e 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -88,6 +88,8 @@
/* default search block allocations and increments */
#define NSC_CERT_BLOCK_SIZE 50
#define NSC_SEARCH_BLOCK_SIZE 5
+#define NSC_SLOT_LIST_BLOCK_SIZE 10
+
/* these are data base storage hashes, not cryptographic hashes.. The define
* the effective size of the various object hash tables */
#define ATTRIBUTE_HASH_SIZE 32
@@ -278,6 +280,7 @@ struct PK11SessionContextStr {
PK11Destroy hashdestroy;
PK11Verify verify;
unsigned int maxLen;
+ PK11Object *key;
};
/*
@@ -315,15 +318,20 @@ struct PK11SlotStr {
PRBool ssoLoggedIn;
PRBool needLogin;
PRBool DB_loaded;
+ PRBool readOnly;
NSSLOWCERTCertDBHandle *certDB;
NSSLOWKEYDBHandle *keyDB;
+ int minimumPinLen;
int sessionIDCount;
int sessionCount;
int rwSessionCount;
int tokenIDCount;
+ int index;
PLHashTable *tokenHashTable;
PK11Object *tokObjects[TOKEN_OBJECT_HASH_SIZE];
PK11Session *head[SESSION_HASH_SIZE];
+ char tokDescription[33];
+ char slotDescription[64];
};
/*
@@ -354,8 +362,7 @@ struct PK11SSLMACInfoStr {
/*
* session handle modifiers
*/
-#define PK11_PRIVATE_KEY_FLAG 0x80000000L
-#define PK11_FIPS_FLAG 0x40000000L
+#define PK11_SESSION_SLOT_MASK 0xff000000L
/*
* object handle modifiers
@@ -373,6 +380,7 @@ struct PK11SSLMACInfoStr {
#define PK11_TOKEN_TYPE_SMIME 0x60000000L
#define PK11_TOKEN_TYPE_CERT 0x70000000L
+#define PK11_TOKEN_KRL_HANDLE (PK11_TOKEN_MAGIC|PK11_TOKEN_TYPE_CRL|0)
/* how big a password/pin we can deal with */
#define PK11_MAX_PIN 255
@@ -411,27 +419,36 @@ struct PK11SSLMACInfoStr {
#define pk11_attr_expand(ap) (ap)->type,(ap)->pValue,(ap)->ulValueLen
#define pk11_item_expand(ip) (ip)->data,(ip)->len
-typedef struct pk11_parametersStr {
+typedef struct pk11_token_parametersStr {
+ CK_SLOT_ID slotID;
char *configdir;
char *certPrefix;
char *keyPrefix;
- char *secmodName;
- char *man;
- char *libdes;
char *tokdes;
- char *ptokdes;
char *slotdes;
- char *pslotdes;
- char *fslotdes;
- char *fpslotdes;
int minPW;
PRBool readOnly;
PRBool noCertDB;
+ PRBool noKeyDB;
+ PRBool forceOpen;
+ PRBool pwRequired;
+} pk11_token_parameters;
+
+typedef struct pk11_parametersStr {
+ char *configdir;
+ char *secmodName;
+ char *man;
+ char *libdes;
+ PRBool readOnly;
PRBool noModDB;
+ PRBool noCertDB;
PRBool forceOpen;
PRBool pwRequired;
+ pk11_token_parameters *tokens;
+ int token_count;
} pk11_parameters;
+
/* machine dependent path stuff used by dbinit.c and pk11db.c */
#ifdef macintosh
#define PATH_SEPARATOR ":"
@@ -447,10 +464,9 @@ typedef struct pk11_parametersStr {
SEC_BEGIN_PROTOS
+extern CK_RV nsc_CommonInitialize(CK_VOID_PTR pReserved, PRBool isFIPS);
/* shared functions between PKCS11.c and PK11FIPS.c */
-extern CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved);
-extern CK_RV PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin,
- NSSLOWCERTCertDBHandle *certdb, NSSLOWKEYDBHandle *keydb);
+extern CK_RV PK11_SlotInit(char *configdir,pk11_token_parameters *params);
/* internal utility functions used by pkcs11.c */
extern PK11Attribute *pk11_FindAttribute(PK11Object *object,
@@ -518,7 +534,8 @@ extern void pk11_FormatDESKey(unsigned char *key, int length);
extern PRBool pk11_CheckDESKey(unsigned char *key);
extern PRBool pk11_IsWeakKey(unsigned char *key,CK_KEY_TYPE key_type);
-extern CK_RV secmod_parseParameters(char *param, pk11_parameters *parsed);
+extern CK_RV secmod_parseParameters(char *param, pk11_parameters *parsed,
+ PRBool isFIPS);
extern void secmod_freeParams(pk11_parameters *params);
extern char *secmod_getSecmodName(char *params, PRBool *rw);
extern char ** secmod_ReadPermDB(char *dbname, char *params, PRBool rw);
@@ -542,8 +559,9 @@ extern SECStatus secmod_AddPermDB(char *dbname, char *module, PRBool rw);
* 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);
+ const char *keyPrefix, PRBool readOnly, PRBool noCertDB,
+ PRBool noKeyDB, PRBool forceOpen,
+ NSSLOWCERTCertDBHandle **certDB, NSSLOWKEYDBHandle **keyDB);
/*
* narrow objects
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 1abdbe131..16f7a4ee0 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -40,15 +40,6 @@
#include "pcert.h"
#include "secasn1.h"
-
-/* declare the internal pkcs11 slot structures:
- * There are threee:
- * slot 0 is the generic crypto service token.
- * slot 1 is the Database service token.
- * slot 2 is the FIPS token (both generic and database).
- */
-static PK11Slot pk11_slot[3];
-
/*
* ******************** Attribute Utilities *******************************
*/
@@ -313,10 +304,35 @@ static const PK11Attribute pk11_StaticMustVerifyAttr =
PK11_DEF_ATTRIBUTE(&pk11_staticMustVerifyValue,
sizeof(pk11_staticMustVerifyValue));
-SECItem *
+static void pk11_FreeItem(SECItem *item)
+{
+ SECITEM_FreeItem(item, PR_TRUE);
+}
+
+static certDBEntrySMime *
+pk11_getSMime(PK11TokenObject *object)
+{
+ certDBEntrySMime *entry;
+
+ if (object->obj.objclass != CKO_NETSCAPE_SMIME) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (certDBEntrySMime *)object->obj.objectInfo;
+ }
+
+ entry = nsslowcert_ReadDBSMimeEntry(object->obj.slot->certDB,
+ (char *)object->dbKey.data);
+ object->obj.objectInfo = (void *)entry;
+ object->obj.infoFree = (PK11Free) nsslowcert_DestroyDBEntry;
+ return entry;
+}
+
+static SECItem *
pk11_getCrl(PK11TokenObject *object)
{
SECItem *crl;
+ PRBool isKrl;
if (object->obj.objclass != CKO_NETSCAPE_CRL) {
return NULL;
@@ -324,14 +340,39 @@ pk11_getCrl(PK11TokenObject *object)
if (object->obj.objectInfo) {
return (SECItem *)object->obj.objectInfo;
}
+
+ isKrl = (PRBool) object->obj.handle == PK11_TOKEN_KRL_HANDLE;
crl = nsslowcert_FindCrlByKey(object->obj.slot->certDB,&object->dbKey,
- NULL,PR_FALSE);
+ NULL,isKrl);
object->obj.objectInfo = (void *)crl;
- object->obj.infoFree = (PK11Free) SECITEM_FreeItem;
+ object->obj.infoFree = (PK11Free) pk11_FreeItem;
return crl;
}
-NSSLOWCERTCertificate *
+static char *
+pk11_getUrl(PK11TokenObject *object)
+{
+ SECItem *crl;
+ PRBool isKrl;
+ char *url = NULL;
+
+ if (object->obj.objclass != CKO_NETSCAPE_CRL) {
+ return NULL;
+ }
+
+ isKrl = (PRBool) object->obj.handle == PK11_TOKEN_KRL_HANDLE;
+ crl = nsslowcert_FindCrlByKey(object->obj.slot->certDB,&object->dbKey,
+ &url,isKrl);
+ if (object->obj.objectInfo == NULL) {
+ object->obj.objectInfo = (void *)crl;
+ object->obj.infoFree = (PK11Free) pk11_FreeItem;
+ } else {
+ if (crl) SECITEM_FreeItem(crl,PR_TRUE);
+ }
+ return url;
+}
+
+static NSSLOWCERTCertificate *
pk11_getCert(PK11TokenObject *object)
{
NSSLOWCERTCertificate *cert;
@@ -349,7 +390,7 @@ pk11_getCert(PK11TokenObject *object)
return cert;
}
-NSSLOWKEYPublicKey *
+static NSSLOWKEYPublicKey *
pk11_GetPublicKey(PK11TokenObject *object)
{
NSSLOWKEYPublicKey *pubKey;
@@ -370,12 +411,12 @@ pk11_GetPublicKey(PK11TokenObject *object)
return pubKey;
}
-NSSLOWKEYPrivateKey *
+static NSSLOWKEYPrivateKey *
pk11_GetPrivateKey(PK11TokenObject *object)
{
NSSLOWKEYPrivateKey *privKey;
- if (object->obj.objclass != CKO_PUBLIC_KEY) {
+ if (object->obj.objclass != CKO_PRIVATE_KEY) {
return NULL;
}
if (object->obj.objectInfo) {
@@ -418,7 +459,7 @@ static const SEC_ASN1Template pk11_SerialTemplate[] = {
{ 0 }
};
-PK11Attribute *
+static PK11Attribute *
pk11_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
{
unsigned char hash[SHA1_LENGTH];
@@ -448,7 +489,8 @@ pk11_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
}
return NULL;
}
-PK11Attribute *
+
+static PK11Attribute *
pk11_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
{
unsigned char hash[SHA1_LENGTH];
@@ -486,7 +528,8 @@ pk11_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
}
return NULL;
}
-PK11Attribute *
+
+static PK11Attribute *
pk11_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
{
unsigned char hash[SHA1_LENGTH];
@@ -520,15 +563,20 @@ pk11_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindPublicKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
NSSLOWKEYPublicKey *key;
switch (type) {
case CKA_PRIVATE:
- case CKA_MODIFIABLE:
+ case CKA_SENSITIVE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_NEVER_EXTRACTABLE:
return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_MODIFIABLE:
+ case CKA_EXTRACTABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
default:
break;
}
@@ -550,7 +598,8 @@ pk11_FindPublicKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+
+static PK11Attribute *
pk11_FindSecretKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
NSSLOWKEYPrivateKey *key;
@@ -592,7 +641,7 @@ pk11_FindSecretKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
CK_ATTRIBUTE_TYPE type)
{
@@ -630,7 +679,8 @@ pk11_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
}
return NULL;
}
-PK11Attribute *
+
+static PK11Attribute *
pk11_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
CK_ATTRIBUTE_TYPE type)
{
@@ -669,7 +719,7 @@ pk11_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
{
unsigned char hash[SHA1_LENGTH];
@@ -702,7 +752,7 @@ pk11_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindPrivateKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
NSSLOWKEYPrivateKey *key;
@@ -711,9 +761,9 @@ pk11_FindPrivateKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
case CKA_SENSITIVE:
case CKA_ALWAYS_SENSITIVE:
case CKA_EXTRACTABLE:
+ case CKA_MODIFIABLE:
return (PK11Attribute *) &pk11_StaticTrueAttr;
case CKA_NEVER_EXTRACTABLE:
- case CKA_MODIFIABLE:
return (PK11Attribute *) &pk11_StaticFalseAttr;
default:
break;
@@ -736,21 +786,42 @@ pk11_FindPrivateKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindSMIMEAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
+ certDBEntrySMime *entry;
NSSLOWCERTCertificate *cert;
switch (type) {
case CKA_PRIVATE:
case CKA_MODIFIABLE:
return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_NETSCAPE_EMAIL:
+ return pk11_NewTokenAttribute(type,object->dbKey.data,
+ object->dbKey.len, PR_FALSE);
+ default:
+ break;
+ }
+ entry = pk11_getSMime(object);
+ if (entry == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_NETSCAPE_SMIME_TIMESTAMP:
+ return pk11_NewTokenAttribute(type,entry->optionsDate.data,
+ entry->optionsDate.len, PR_FALSE);
+ case CKA_SUBJECT:
+ return pk11_NewTokenAttribute(type,entry->subjectName.data,
+ entry->subjectName.len, PR_FALSE);
+ case CKA_VALUE:
+ return pk11_NewTokenAttribute(type,entry->smimeOptions.data,
+ entry->smimeOptions.len, PR_FALSE);
default:
break;
}
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindTrustAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
NSSLOWCERTCertificate *cert;
@@ -819,15 +890,25 @@ trust:
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindCrlAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
SECItem *crl;
+ char *url;
switch (type) {
case CKA_PRIVATE:
case CKA_MODIFIABLE:
return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_NETSCAPE_KRL:
+ return (PK11Attribute *) ((object->obj.handle == PK11_TOKEN_KRL_HANDLE)
+ ? &pk11_StaticTrueAttr : &pk11_StaticFalseAttr);
+ case CKA_NETSCAPE_URL:
+ url = pk11_getUrl(object);
+ if (url == NULL) {
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ }
+ return pk11_NewTokenAttribute(type, url, PORT_Strlen(url)+1, PR_TRUE);
case CKA_VALUE:
crl = pk11_getCrl(object);
if (crl == NULL) break;
@@ -841,7 +922,7 @@ pk11_FindCrlAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindCertAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
{
NSSLOWCERTCertificate *cert;
@@ -900,7 +981,7 @@ pk11_FindCertAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
return NULL;
}
-PK11Attribute *
+static PK11Attribute *
pk11_FindTokenAttribute(PK11TokenObject *object,CK_ATTRIBUTE_TYPE type)
{
/* handle the common ones */
@@ -976,6 +1057,7 @@ pk11_hasAttributeToken(PK11TokenObject *object)
{
return PR_FALSE;
}
+
/*
* return true if object has attribute
*/
@@ -1115,6 +1197,33 @@ pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
pk11_FreeAttribute(attribute);
}
+static CK_RV
+pk11_forceTokenAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type,
+ void *value, unsigned int len)
+{
+ PK11Attribute *attribute;
+
+ /* if we are just setting it to the value we already have,
+ * allow it to happen. */
+ attribute=pk11_FindAttribute(object,type);
+ if ((attribute->attrib.ulValueLen == len) &&
+ PORT_Memcmp(attribute->attrib.pValue,value,len) == 0) {
+ pk11_FreeAttribute(attribute);
+ return CKR_OK;
+ }
+
+ switch (object->objclass) {
+ case CKO_CERTIFICATE:
+ /* change NICKNAME, EMAIL, */
+ break;
+ case CKO_NETSCAPE_CRL:
+ /* change URL */
+ break;
+ }
+ pk11_FreeAttribute(attribute);
+ return CKR_ATTRIBUTE_READ_ONLY;
+}
+
/*
* force an attribute to a spaecif value.
*/
@@ -1126,6 +1235,9 @@ pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
void *att_val = NULL;
PRBool freeData = PR_FALSE;
+ if (pk11_isToken(object->handle)) {
+ return pk11_forceTokenAttribute(object,type,value,len);
+ }
attribute=pk11_FindAttribute(object,type);
if (attribute == NULL) return pk11_AddAttributeType(object,type,value,len);
@@ -1172,6 +1284,7 @@ pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
attribute->attrib.ulValueLen = len;
attribute->freeData = freeData;
}
+ pk11_FreeAttribute(attribute);
return CKR_OK;
}
@@ -1742,6 +1855,7 @@ pk11_AddObject(PK11Session *session, PK11Object *object)
PK11_USE_THREADS(PZ_Unlock(session->objectLock);)
}
pk11_AddSlotObject(slot,object);
+ pk11_ReferenceObject(object);
}
/*
@@ -1757,6 +1871,7 @@ pk11_DeleteObject(PK11Session *session, PK11Object *object)
SECStatus rv;
NSSLOWCERTCertificate *cert;
NSSLOWCERTCertTrust tmptrust;
+ PRBool isKrl;
/* Handle Token case */
if (so && so->session) {
@@ -1768,6 +1883,7 @@ pk11_DeleteObject(PK11Session *session, PK11Object *object)
pk11queue_delete(object,object->handle,slot->tokObjects,
TOKEN_OBJECT_HASH_SIZE);
PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+ pk11_FreeObject(object); /* reduce it's reference count */
} else {
PORT_Assert(to);
/* remove the objects from the real data base */
@@ -1793,12 +1909,9 @@ pk11_DeleteObject(PK11Session *session, PK11Object *object)
nsslowcert_DestroyCertificate(cert);
break;
case PK11_TOKEN_TYPE_CRL:
- rv = nsslowcert_DeletePermCRL(slot->certDB,&to->dbKey,PR_FALSE);
- if (rv == SECFailure) {
- /* must be a KRL */
- rv = nsslowcert_DeletePermCRL(slot->certDB,&to->dbKey,PR_TRUE);
- if (rv == SECFailure) crv = CKR_DEVICE_ERROR;
- }
+ isKrl = (PRBool) (object->handle == PK11_TOKEN_KRL_HANDLE);
+ rv = nsslowcert_DeletePermCRL(slot->certDB,&to->dbKey,isKrl);
+ if (rv == SECFailure) crv = CKR_DEVICE_ERROR;
break;
case PK11_TOKEN_TYPE_TRUST:
cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
@@ -1824,7 +1937,6 @@ pk11_DeleteObject(PK11Session *session, PK11Object *object)
pk11_deleteTokenKeyByHandle(object->slot,object->handle);
pk11_tokenKeyUnlock(object->slot);
}
- pk11_FreeObject(object);
}
/*
@@ -2028,37 +2140,11 @@ pk11_FreeContext(PK11SessionContext *context)
if (context->hashInfo) {
(*context->hashdestroy)(context->hashInfo,PR_TRUE);
}
- PORT_Free(context);
-}
-
-/* look up a slot structure from the ID (used to be a macro when we only
- * had two slots) */
-PK11Slot *
-pk11_SlotFromID(CK_SLOT_ID slotID)
-{
- switch (slotID) {
- case NETSCAPE_SLOT_ID:
- return &pk11_slot[0];
- case PRIVATE_KEY_SLOT_ID:
- return &pk11_slot[1];
- case FIPS_SLOT_ID:
- return &pk11_slot[2];
- default:
- break; /* fall through to NULL */
- }
- return NULL;
-}
-
-PK11Slot *
-pk11_SlotFromSessionHandle(CK_SESSION_HANDLE handle)
-{
- if (handle & PK11_PRIVATE_KEY_FLAG) {
- return &pk11_slot[1];
- }
- if (handle & PK11_FIPS_FLAG) {
- return &pk11_slot[2];
+ if (context->key) {
+ pk11_FreeObject(context->key);
+ context->key = NULL;
}
- return &pk11_slot[0];
+ PORT_Free(context);
}
/*
@@ -2192,10 +2278,20 @@ pk11_mkHandle(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class)
CK_OBJECT_HANDLE handle;
SECItem *key;
- SHA1_HashBuf(hashBuf,dbKey->data,dbKey->len);
- handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) |
+ handle = class;
+ /* there is only one KRL, use a fixed handle for it */
+ if (handle != PK11_TOKEN_KRL_HANDLE) {
+ SHA1_HashBuf(hashBuf,dbKey->data,dbKey->len);
+ handle = (hashBuf[0] << 24) | (hashBuf[1] << 16) |
(hashBuf[2] << 8) | hashBuf[3];
- handle = PK11_TOKEN_MASK | class | (handle & ~PK11_TOKEN_TYPE_MASK);
+ handle = PK11_TOKEN_MAGIC | class |
+ (handle & ~(PK11_TOKEN_TYPE_MASK|PK11_TOKEN_MASK));
+ /* we have a CRL who's handle has randomly matched the reserved KRL
+ * handle, increment it */
+ if (handle == PK11_TOKEN_KRL_HANDLE) {
+ handle++;
+ }
+ }
pk11_tokenKeyLock(slot);
while (key = pk11_lookupTokenKeyByHandle(slot,handle)) {