summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2001-10-22 17:54:20 +0000
committerrelyea%netscape.com <devnull@localhost>2001-10-22 17:54:20 +0000
commit2604a8216cecec79d0f034064252368919160ccb (patch)
tree2caaf2269366eedcf4410116a94449c028cb6755
parent11000f66863c5fe6fa83b6489e53bc875c1ed936 (diff)
downloadnss-hg-2604a8216cecec79d0f034064252368919160ccb.tar.gz
1) Get nss3.dll and ssl3.dll to build.
2) Implement several of the CERT stub functions to go directly to pkcs #11. 3) updates to searching token objects.
-rw-r--r--security/nss/lib/certdb/cert.h85
-rw-r--r--security/nss/lib/certdb/certdb.c357
-rw-r--r--security/nss/lib/certdb/certinit.c414
-rw-r--r--security/nss/lib/certdb/certt.h6
-rw-r--r--security/nss/lib/certdb/crl.c186
-rw-r--r--security/nss/lib/certdb/manifest.mn5
-rw-r--r--security/nss/lib/certhigh/certhigh.c34
-rw-r--r--security/nss/lib/certhigh/certvfy.c22
-rw-r--r--security/nss/lib/certhigh/ocsp.c296
-rw-r--r--security/nss/lib/certhigh/ocsp.h5
-rw-r--r--security/nss/lib/certhigh/ocspti.h6
-rw-r--r--security/nss/lib/ckfw/ckt.h3
-rw-r--r--security/nss/lib/cryptohi/seckey.c8
-rw-r--r--security/nss/lib/manifest.mn2
-rw-r--r--security/nss/lib/nss/config.mk90
-rw-r--r--security/nss/lib/nss/manifest.mn2
-rw-r--r--security/nss/lib/pk11wrap/manifest.mn4
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c587
-rw-r--r--security/nss/lib/pk11wrap/pk11func.h8
-rw-r--r--security/nss/lib/pk11wrap/pk11kea.c10
-rw-r--r--security/nss/lib/pk11wrap/pk11pk12.c30
-rw-r--r--security/nss/lib/pk11wrap/pk11pqg.c12
-rw-r--r--security/nss/lib/pk11wrap/pk11skey.c31
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c27
-rw-r--r--security/nss/lib/pk11wrap/secmodt.h9
-rw-r--r--security/nss/lib/pk11wrap/secmodti.h29
-rw-r--r--security/nss/lib/pkcs12/p12d.c15
-rw-r--r--security/nss/lib/softoken/alghmac.c22
-rw-r--r--security/nss/lib/softoken/alghmac.h4
-rw-r--r--security/nss/lib/softoken/config.mk71
-rw-r--r--security/nss/lib/softoken/keydb.c299
-rw-r--r--security/nss/lib/softoken/lowcert.c3
-rw-r--r--security/nss/lib/softoken/lowkeyi.h11
-rw-r--r--security/nss/lib/softoken/lowkeyti.h19
-rw-r--r--security/nss/lib/softoken/manifest.mn6
-rw-r--r--security/nss/lib/softoken/pcert.h91
-rw-r--r--security/nss/lib/softoken/pcertdb.c226
-rw-r--r--security/nss/lib/softoken/pcertt.h17
-rw-r--r--security/nss/lib/softoken/pk11pars.h2
-rw-r--r--security/nss/lib/softoken/pkcs11.c2347
-rw-r--r--security/nss/lib/softoken/pkcs11.h13
-rw-r--r--security/nss/lib/softoken/pkcs11c.c336
-rw-r--r--security/nss/lib/softoken/pkcs11f.h9
-rw-r--r--security/nss/lib/softoken/pkcs11i.h142
-rw-r--r--security/nss/lib/softoken/pkcs11t.h336
-rw-r--r--security/nss/lib/softoken/pkcs11u.c1387
-rw-r--r--security/nss/lib/softoken/secpkcs5.c1867
-rw-r--r--security/nss/lib/softoken/secpkcs5.h127
-rw-r--r--security/nss/lib/ssl/ssl3con.c32
-rw-r--r--security/nss/lib/ssl/sslcon.c6
-rw-r--r--security/nss/lib/ssl/sslsnce.c3
-rw-r--r--security/nss/lib/util/secitem.c42
-rw-r--r--security/nss/lib/util/secitem.h6
-rw-r--r--security/nss/lib/util/secoid.c127
54 files changed, 4620 insertions, 5214 deletions
diff --git a/security/nss/lib/certdb/cert.h b/security/nss/lib/certdb/cert.h
index 5a70d7302..431341f89 100644
--- a/security/nss/lib/certdb/cert.h
+++ b/security/nss/lib/certdb/cert.h
@@ -397,26 +397,7 @@ extern void CERT_DestroyCrl (CERTSignedCrl *crl);
** Decode a certificate and put it into the temporary certificate database
*/
extern CERTCertificate *
-CERT_NewTempCertificate (CERTCertDBHandle *handle, SECItem *derCert,
- char *nickname, PRBool isperm, PRBool copyDER);
-
-/*
-** Add a certificate to the temporary database.
-** "dbCert" is the certificate from the perm database.
-** "isperm" indicates if the cert is in the permanent database.
-*/
-extern CERTCertificate *
-CERT_AddTempCertificate (CERTCertDBHandle *handle, certDBEntryCert *entry,
- PRBool isperm);
-
-/*
-** Add a temporary certificate to the permanent database.
-** "cert" is the temporary cert
-** "nickname" is the permanent nickname to use
-** "trust" is the certificate trust parameters to assign to the cert
-*/
-extern SECStatus
-CERT_AddTempCertToPerm (CERTCertificate *cert, char *nickname, CERTCertTrust *trust);
+CERT_DecodeCertificate (SECItem *derCert, char *nickname,PRBool copyDER);
/*
** Find a certificate in the database
@@ -425,16 +406,6 @@ CERT_AddTempCertToPerm (CERTCertificate *cert, char *nickname, CERTCertTrust *tr
extern CERTCertificate *CERT_FindCertByKey(CERTCertDBHandle *handle, SECItem *key);
/*
- * Lookup a certificate in the databases without locking
- * "certKey" is the database key to look for
- *
- * XXX - this should be internal, but pkcs 11 needs to call it during a
- * traversal.
- */
-CERTCertificate *
-CERT_FindCertByKeyNoLocking(CERTCertDBHandle *handle, SECItem *certKey);
-
-/*
** Find a certificate in the database by name
** "name" is the distinguished name to look up
*/
@@ -470,6 +441,7 @@ CERT_FindCertByIssuerAndSN (CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAnd
*/
extern CERTCertificate *
CERT_FindCertByNickname (CERTCertDBHandle *handle, char *nickname);
+
/*
** Find a certificate in the database by a DER encoded certificate
** "derCert" is the DER encoded certificate
@@ -505,17 +477,6 @@ CERTCertificate *
CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage);
/*
-** Delete a certificate from the temporary database
-** "cert" is the certificate to be deleted
-*/
-extern SECStatus CERT_DeleteTempCertificate(CERTCertificate *cert);
-
-/*
-** Flush and close the permanent database.
-*/
-extern void CERT_ClosePermCertDB(CERTCertDBHandle *handle);
-
-/*
** Check the validity times of a certificate vs. time 't', allowing
** some slop for broken clocks and stuff.
** "cert" is the certificate to be checked
@@ -641,6 +602,14 @@ extern char *CERT_HTMLCertInfo(CERTCertificate *cert, PRBool showImages,
*/
extern SECItem *CERT_DecodeAVAValue(SECItem *derAVAValue);
+/*
+ * take a DER certificate and decode it into a certificate structure
+ */
+CERTCertificate *
+CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+ char *nickname);
+
+
/*
** extract various element strings from a distinguished name.
@@ -926,32 +895,6 @@ extern void CERT_DestroyCertificateList(CERTCertificateList *list);
/* is cert a newer than cert b? */
PRBool CERT_IsNewer(CERTCertificate *certa, CERTCertificate *certb);
-typedef SECStatus (* CERTCertCallback)(CERTCertificate *cert, void *arg);
-
-SECStatus
-CERT_TraversePermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject,
- CERTCertCallback cb, void *cbarg);
-int
-CERT_NumPermCertsForSubject(CERTCertDBHandle *handle, SECItem *derSubject);
-
-SECStatus
-CERT_TraversePermCertsForNickname(CERTCertDBHandle *handle, char *nickname,
- CERTCertCallback cb, void *cbarg);
-
-int
-CERT_NumPermCertsForNickname(CERTCertDBHandle *handle, char *nickname);
-
-int
-CERT_NumCertsForCertSubject(CERTCertificate *cert);
-
-int
-CERT_NumPermCertsForCertSubject(CERTCertificate *cert);
-
-SECStatus
-CERT_TraverseCertsForSubject(CERTCertDBHandle *handle,
- CERTSubjectList *subjectList,
- CERTCertCallback cb, void *cbarg);
-
/* currently a stub for address book */
PRBool
CERT_IsCertRevoked(CERTCertificate *cert);
@@ -1009,12 +952,6 @@ CERT_SaveSMimeProfile(CERTCertificate *cert, SECItem *emailProfile,
SECItem *
CERT_FindSMimeProfile(CERTCertificate *cert);
-int
-CERT_GetDBContentVersion(CERTCertDBHandle *handle);
-
-void
-CERT_SetDBContentVersion(int version, CERTCertDBHandle *handle);
-
SECStatus
CERT_AddNewCerts(CERTCertDBHandle *handle);
@@ -1370,6 +1307,8 @@ CERT_GetStatusConfig(CERTCertDBHandle *handle);
void
CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *config);
+
+
/*
* Acquire the cert reference count lock
* There is currently one global lock for all certs, but I'm putting a cert
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
index a0c970164..06c5a5d15 100644
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -49,7 +49,7 @@
#include "keyhi.h"
#include "secitem.h"
#include "mcom_db.h"
-#include "certtrust.h"
+#include "certrust.h"
#include "prprf.h"
#include "sechash.h"
#include "prlong.h"
@@ -58,6 +58,7 @@
#include "secerr.h"
#include "sslerr.h"
#include "nsslocks.h"
+#include "pk11func.h"
/*
* Certificate database handling code
@@ -456,7 +457,7 @@ fortezzaIsCA( CERTCertificate *cert) {
unsigned char *end;
int len;
- rawkey = spki->subjectPublicKey;
+ rawkey = spki->subjectPublicKey;
DER_ConvertBitString(&rawkey);
rawptr = rawkey.data;
end = rawkey.data + rawkey.len;
@@ -483,7 +484,7 @@ fortezzaIsCA( CERTCertificate *cert) {
/* DSSPrivilege (the string up to the first byte with the hi-bit on */
if (*rawptr & 0x30) isCA = PR_TRUE;
-
+
}
return isCA;
}
@@ -621,12 +622,12 @@ CERT_GetCertType(CERTCertificate *cert)
cert->nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
NS_CERT_TYPE_EMAIL;
- /* if the basic constraint extension says the cert is a CA, then
+ /* if the basic constraint extension says the cert is a CA, then
allow SSL CA and EMAIL CA and Status Responder */
if ((basicConstraintPresent == PR_TRUE)
&& (basicConstraint.isCA)) {
- cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
- cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
} else if (CERT_IsCACert(cert, NULL) == PR_TRUE) {
cert->nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
@@ -634,8 +635,8 @@ CERT_GetCertType(CERTCertificate *cert)
/* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */
if (fortezzaIsCA(cert)) {
- cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
- cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_SSL_CA;
+ cert->nsCertType |= NS_CERT_TYPE_EMAIL_CA;
}
}
@@ -682,9 +683,9 @@ cert_GetKeyID(CERTCertificate *cert)
cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, 8);
if ( cert->subjectKeyID.data != NULL ) {
- PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8);
- cert->subjectKeyID.len = 8;
- cert->keyIDGenerated = PR_FALSE;
+ PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8);
+ cert->subjectKeyID.len = 8;
+ cert->keyIDGenerated = PR_FALSE;
}
}
@@ -699,7 +700,7 @@ cert_GetKeyID(CERTCertificate *cert)
*/
cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH);
if ( cert->subjectKeyID.data != NULL ) {
- rv = SHA1_HashBuf(cert->subjectKeyID.data,
+ rv = PK11_HashBuf(SEC_OID_SHA1,cert->subjectKeyID.data,
cert->derPublicKey.data,
cert->derPublicKey.len);
if ( rv == SECSuccess ) {
@@ -719,7 +720,7 @@ cert_GetKeyID(CERTCertificate *cert)
* take a DER certificate and decode it into a certificate structure
*/
CERTCertificate *
-__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
char *nickname)
{
CERTCertificate *cert;
@@ -827,7 +828,7 @@ __CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
cert->referenceCount = 1;
cert->slot = NULL;
- cert->pkcs11ID = CK_INVALID_KEY;
+ cert->pkcs11ID = CK_INVALID_HANDLE;
cert->dbnickname = NULL;
return(cert);
@@ -842,12 +843,13 @@ loser:
}
CERTCertificate *
-CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
+__CERT_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
char *nickname)
{
- return(__CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname));
+ return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname);
}
+
/*
** Amount of time that a certifiate is allowed good before it is actually
** good. This is used for pending certificates, ones that are about to be
@@ -903,7 +905,7 @@ CERT_CheckCertValidTimes(CERTCertificate *c, PRTime t, PRBool allowOverride)
/* if cert is already marked OK, then don't bother to check */
if ( allowOverride && c->timeOK ) {
- return(secCertTimeValid);
+ return(secCertTimeValid);
}
rv = CERT_GetCertTimes(c, &notBefore, &notAfter);
@@ -1178,68 +1180,6 @@ CERT_GetDefaultCertDB(void)
return(default_cert_db_handle);
}
-/*
- * Open volatile certificate database and index databases. This is a
- * fallback if the real databases can't be opened or created. It is only
- * resident in memory, so it will not be persistent. We do this so that
- * we don't crash if the databases can't be created.
- */
-SECStatus
-CERT_OpenVolatileCertDB(CERTCertDBHandle *handle)
-{
-#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 */
- };
- /*
- * Open the memory resident perm cert database.
- */
- handle->permCertDB = dbopen(0, O_RDWR | O_CREAT, 0600, DB_HASH, &hashInfo);
- if ( !handle->permCertDB ) {
- goto loser;
- }
-
- /*
- * Open the memory resident decoded cert database.
- */
- handle->tempCertDB = dbopen(0, O_RDWR | O_CREAT, 0600, DB_HASH, &hashInfo);
- if ( !handle->tempCertDB ) {
- goto loser;
- }
-
- handle->dbMon = PZ_NewMonitor(nssILockCertDB);
- PORT_Assert(handle->dbMon != NULL);
-
- handle->spkDigestInfo = NULL;
- handle->statusConfig = NULL;
-
- /* initialize the cert database */
- (void) CERT_InitCertDB(handle);
-
- return (SECSuccess);
-
-loser:
-
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
-
- if ( handle->permCertDB ) {
- (* handle->permCertDB->close)(handle->permCertDB);
- handle->permCertDB = 0;
- }
-
- if ( handle->tempCertDB ) {
- (* handle->tempCertDB->close)(handle->tempCertDB);
- handle->tempCertDB = 0;
- }
-
- return(SECFailure);
-}
-
/* XXX this would probably be okay/better as an xp routine? */
static void
sec_lower_string(char *s)
@@ -1264,14 +1204,14 @@ SECStatus
CERT_AddOKDomainName(CERTCertificate *cert, const char *hn)
{
CERTOKDomainName *domainOK;
- int newNameLen;
+ int newNameLen;
if (!hn || !(newNameLen = strlen(hn))) {
PORT_SetError(SEC_ERROR_INVALID_ARGS);
return SECFailure;
}
domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena,
- (sizeof *domainOK) + newNameLen);
+ (sizeof *domainOK) + newNameLen);
if (!domainOK)
return SECFailure; /* error code is already set. */
@@ -1697,14 +1637,12 @@ CERT_IsCACert(CERTCertificate *cert, unsigned int *rettype)
return(ret);
}
-
PRBool
CERT_IsCADERCert(SECItem *derCert, unsigned int *type) {
CERTCertificate *cert;
PRBool isCA;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return PR_FALSE;
isCA = CERT_IsCACert(cert,type);
@@ -1953,8 +1891,8 @@ CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
/* decode all of the certs into the temporary DB */
for ( i = 0, fcerts= 0; i < ncerts; i++) {
- certs[fcerts] = CERT_NewTempCertificate(certdb, derCerts[i], NULL,
- PR_FALSE, PR_TRUE);
+ certs[fcerts] = CERT_DecodeDERCertificate(derCerts[i], PR_FALSE,
+ NULL);
if (certs[fcerts]) fcerts++;
}
@@ -1967,10 +1905,11 @@ CERT_ImportCerts(CERTCertDBHandle *certdb, SECCertUsage usage,
* otherwise if there are more than one cert, we don't
* know which cert it belongs to.
*/
- rv = CERT_SaveImportedCert(certs[i], usage, caOnly, NULL);
+ rv = PK11_ImportCert(PK11_GetInternalKeySlot(),certs[i],
+ CK_INVALID_HANDLE,NULL,PR_TRUE);
} else {
- rv = CERT_SaveImportedCert(certs[i], usage, caOnly,
- nickname);
+ rv = PK11_ImportCert(PK11_GetInternalKeySlot(),certs[i],
+ CK_INVALID_HANDLE,nickname,PR_TRUE);
}
/* don't care if it fails - keep going */
}
@@ -2313,36 +2252,6 @@ loser:
return(SECFailure);
}
-/*
- * Acquire the global lock on the cert database.
- * This lock is currently used for the following operations:
- * adding or deleting a cert to either the temp or perm databases
- * converting a temp to perm or perm to temp
- * changing(maybe just adding !?) the trust of a cert
- * chaning the DB status checking Configuration
- */
-void
-CERT_LockDB(CERTCertDBHandle *handle)
-{
- PZ_EnterMonitor(handle->dbMon);
- return;
-}
-
-/*
- * Free the global cert database lock.
- */
-void
-CERT_UnlockDB(CERTCertDBHandle *handle)
-{
- PRStatus prstat;
-
- prstat = PZ_ExitMonitor(handle->dbMon);
-
- PORT_Assert(prstat == PR_SUCCESS);
-
- return;
-}
-
static PZLock *certRefCountLock = NULL;
/*
@@ -2424,7 +2333,12 @@ CERT_UnlockCertTrust(CERTCertificate *cert)
CERTStatusConfig *
CERT_GetStatusConfig(CERTCertDBHandle *handle)
{
+#ifdef notdef
return handle->statusConfig;
+#else
+ PORT_Assert(0);
+ return NULL;
+#endif
}
/*
@@ -2434,7 +2348,210 @@ CERT_GetStatusConfig(CERTCertDBHandle *handle)
void
CERT_SetStatusConfig(CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
{
+#ifdef notdef
PORT_Assert(handle->statusConfig == NULL);
-
handle->statusConfig = statusConfig;
+#else
+ PORT_Assert(0);
+#endif
+}
+
+typedef struct cert_buildCertListArgsStr {
+ CERTCertList *certList;
+ int64 sorttime;
+ PRBool validOnly;
+ SECStatus status;
+} cert_buildCertListArgs;
+
+SECStatus
+cert_buildCertList(CERTCertificate *cert, void *inArgs)
+{
+ cert_buildCertListArgs *args = (cert_buildCertListArgs *)inArgs;
+
+ if (args->status != SECSuccess) {
+ return args->status;
+ }
+ /* if validOnly, then check validity period before adding to list*/
+ if ( ( !args->validOnly ) ||
+ ( CERT_CheckCertValidTimes(cert, args->sorttime, PR_FALSE)
+ == secCertTimeValid ) ) {
+ args->status = CERT_AddCertToListSorted(args->certList, cert,
+ CERT_SortCBValidity, (void *)&args->sorttime);
+ }
+
+ return args->status;
+}
+
+
+/*
+ * Creates or adds to a list of all certs with a give subject name, sorted by
+ * validity time, newest first. Invalid certs are considered older than
+ * valid certs. If validOnly is set, do not include invalid certs on list.
+ */
+CERTCertList *
+CERT_CreateSubjectCertList(CERTCertList *inCertList, CERTCertDBHandle *handle,
+ SECItem *name, int64 sorttime, PRBool validOnly)
+{
+ CERTCertList *certList = NULL;
+ cert_buildCertListArgs args;
+ CERTCertificate subjectCert;
+
+ certList = (inCertList) ? inCertList : CERT_NewCertList();
+
+ if ( certList == NULL ) {
+ goto loser;
+ }
+
+ subjectCert.derSubject.data=name->data;
+ subjectCert.derSubject.len=name->len;
+ subjectCert.slot = NULL;
+
+ args.certList = certList;
+ args.sorttime = sorttime;
+ args.validOnly = validOnly;
+ args.status = SECSuccess;
+
+ PK11_TraverseCertsForSubject(&subjectCert,cert_buildCertList,&args);
+
+ if (args.status == SECFailure) {
+ goto loser;
+ }
+
+ return(certList);
+
+loser:
+ if (( inCertList == NULL ) && ( certList != NULL )) {
+ CERT_DestroyCertList(certList);
+ }
+
+ return NULL;
+}
+
+
+/*
+ * Find Cert calls
+ */
+CERTCertificate *
+CERT_FindCertByName(CERTCertDBHandle *handle,SECItem *derSubj)
+{
+ CERTCertList *list =
+ CERT_CreateSubjectCertList(NULL,handle,derSubj,0,PR_FALSE);
+ CERTCertificate *cert = NULL;
+
+ if (list) {
+ CERTCertListNode *node = CERT_LIST_HEAD(list);
+ if (node) {
+ cert = CERT_DupCertificate(node->cert);
+ }
+ CERT_DestroyCertList(list);
+ }
+
+ return cert;
+}
+
+/*
+ * Lookup a certificate in the database by name and key ID
+ */
+CERTCertificate *
+CERT_FindCertByKeyID(CERTCertDBHandle *handle, SECItem *name, SECItem *keyID)
+{
+ CERTCertList *list =
+ CERT_CreateSubjectCertList(NULL,handle,name,0,PR_FALSE);
+ CERTCertificate *cert = NULL;
+ CERTCertListNode *node = CERT_LIST_HEAD(list);
+
+ if (list == NULL) return NULL;
+
+ for (node = CERT_LIST_HEAD(list); node ; node = CERT_LIST_NEXT(node)) {
+ if (SECITEM_ItemsAreEqual(&cert->subjectKeyID, keyID) ) {
+ cert = CERT_DupCertificate(node->cert);
+ break;
+ }
+ }
+ return cert;
+}
+
+
+CERTCertificate *
+CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerSN)
+{
+ PK11SlotInfo *slot;
+ CERTCertificate *cert;
+
+ cert = PK11_FindCertByIssuerAndSN(&slot,issuerSN,NULL);
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+
+ return cert;
+}
+
+
+CERTCertificate *
+CERT_FindCertByNickname(CERTCertDBHandle *handle, char *nickname)
+{
+ return PK11_FindCertFromNickname(nickname, NULL);
+}
+
+CERTCertificate *
+CERT_FindCertByNicknameOrEmailAddr(CERTCertDBHandle *handle, char *nickname)
+{
+ return PK11_FindCertFromNickname(nickname, NULL);
+}
+
+CERTCertificate *
+CERT_FindCertByDERCert(CERTCertDBHandle *handle, SECItem *derCert)
+{
+ PK11SlotList *list;
+ PK11SlotListElement *le;
+ CERTCertificate *cert;
+ CERTCertificate fake_cert;
+ SECStatus rv;
+
+ /* get them all! */
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,NULL);
+ if (list == NULL) return NULL;
+
+ /* horible hack! */
+ fake_cert.derCert.data = derCert->data;
+ fake_cert.derCert.len = derCert->len;
+
+ /* look at each slot and authenticate as necessary */
+ for (le = list->head ; le; le = le->next) {
+ cert = PK11_FindCertFromDERCert(le->slot,&fake_cert,NULL);
+ if (cert) break;
+ }
+
+ PK11_FreeSlotList(list);
+
+ return SECSuccess;
+}
+
+void
+CERT_DestroyCertificate(CERTCertificate *cert)
+{
+ int refCount;
+ CERTCertDBHandle *handle;
+
+ if ( cert ) {
+ CERT_LockCertRefCount(cert);
+ PORT_Assert(cert->referenceCount > 0);
+ refCount = --cert->referenceCount;
+ CERT_UnlockCertRefCount(cert);
+
+ if ( ( refCount == 0 ) && !cert->keepSession ) {
+ PRArenaPool * arena = cert->arena;
+
+ /* zero cert before freeing. Any stale references to this cert
+ * after this point will probably cause an exception. */
+ PORT_Memset(cert, 0, sizeof *cert);
+
+ cert = NULL;
+
+ /* free the arena that contains the cert. */
+ PORT_FreeArena(arena, PR_FALSE);
+ }
+ }
+
+ return;
}
diff --git a/security/nss/lib/certdb/certinit.c b/security/nss/lib/certdb/certinit.c
deleted file mode 100644
index 85b7713c2..000000000
--- a/security/nss/lib/certdb/certinit.c
+++ /dev/null
@@ -1,414 +0,0 @@
-/*
- * The contents of this file are subject to the Mozilla Public
- * License Version 1.1 (the "License"); you may not use this file
- * except in compliance with the License. You may obtain a copy of
- * the License at http://www.mozilla.org/MPL/
- *
- * Software distributed under the License is distributed on an "AS
- * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
- * implied. See the License for the specific language governing
- * rights and limitations under the License.
- *
- * The Original Code is the Netscape security libraries.
- *
- * The Initial Developer of the Original Code is Netscape
- * Communications Corporation. Portions created by Netscape are
- * Copyright (C) 1994-2000 Netscape Communications Corporation. All
- * Rights Reserved.
- *
- * Contributor(s):
- *
- * Alternatively, the contents of this file may be used under the
- * terms of the GNU General Public License Version 2 or later (the
- * "GPL"), in which case the provisions of the GPL are applicable
- * instead of those above. If you wish to allow use of your
- * version of this file only under the terms of the GPL and not to
- * allow others to use your version of this file under the MPL,
- * indicate your decision by deleting the provisions above and
- * replace them with the notice and other provisions required by
- * the GPL. If you do not delete the provisions above, a recipient
- * may use your version of this file under either the MPL or the
- * GPL.
- */
-
-#include "cert.h"
-#include "base64.h"
-#include "mcom_db.h"
-#include "certrust.h"
-
-#ifdef STATIC_CERT_INIT
-static char example_com_server_ca[] =
-"MIICBTCCAW6gAwIBAgIBATANBgkqhkiG9w0BAQQFADA+MREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRIwEAYDVQQDEwlTZXJ2ZXIgQ0Ew"
-"HhcNMDAwMjAzMjIyMDA3WhcNMTAwNTAzMjIyMDA3WjA+MREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRIwEAYDVQQDEwlTZXJ2ZXIgQ0Ew"
-"gZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALGiKEvTd2k4ZJbdAVWokfFlB6Hz"
-"WJXveXm8+IgmFlgtAnicZI11z5wAutFRvDpun7WmRLgHxvEhU3tLoiACGYdGJXPw"
-"+lI2pzHzFSd63B0qcA/NVAW3EOBJeaEFwy0jkUaCIki8qQV06g8RosNX/zv6a+OF"
-"d5NMpS0fecK4fEvdAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcN"
-"AQEEBQADgYEAi5rFiG6afWS1PHigssk2LwAJws5cszPbVIeIMHCBbtu259V7uWts"
-"gNxUPJRjeQBsK0ItAfinC0xxLeuMbRfIdZoRYv/OYDxCwGW7hUcNLi+fHlGnJNXH"
-"TWaCRdOwkljnws4v8ABas2DYA/k7xUFAygkIJd9NtE29ZrdrWpfSavI=";
-
-static char example_com_individual_ca[] =
-"MIICDTCCAXagAwIBAgIBAjANBgkqhkiG9w0BAQQFADBCMREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRYwFAYDVQQDEw1JbmRpdmlkdWFs"
-"IENBMB4XDTAwMDIwMzIyMjE1NFoXDTEwMDUwMzIyMjE1NFowQjERMA8GCAmSJvWY"
-"HmQBEwNjb20xFTATBggJkib1mB5kARMHRXhhbXBsZTEWMBQGA1UEAxMNSW5kaXZp"
-"ZHVhbCBDQTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAu5syfboe93MOkGec"
-"dOuJholyX42wcaH/RgnL3C/8NnZp9WWaTaguvn7KrbCj4TAMzu0pabUN8apB3J60"
-"9C/FlixjXF7r73OzbyTCM5ja6/bPfmHMPmDl9l/9tKqhh+loFvRizXDaWSFRViDS"
-"XvKNeQztwwAOpEAqnJwyTkn4FjECAwEAAaMTMBEwDwYDVR0TAQH/BAUwAwEB/zAN"
-"BgkqhkiG9w0BAQQFAAOBgQB1XK+5pXdXYq3O3TC/ZY5LWlZ7zuoWUO75OpuMY7XF"
-"iW/jeXbVT5IYZXoRGXJFGGaDmnAuK1/m6FTDhjSTG0XUmd5tg4aFieI+LY4rkYEv"
-"mbJElxKabXl5hVD4mg2bwYlFY7XBmifTa1Ll3HDX3VZM0DC1bm4KCHBnY0qXjSYq"
-"PA==";
-
-static char example_com_objsign_ca[] =
-"MIICETCCAXqgAwIBAgIBAzANBgkqhkiG9w0BAQQFADBEMREwDwYICZIm9ZgeZAET"
-"A2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRgwFgYDVQQDEw9Db2RlIFNpZ25p"
-"bmcgQ0EwHhcNMDAwMjAzMjIyMzEzWhcNMTAwNTAzMjIyMzEzWjBEMREwDwYICZIm"
-"9ZgeZAETA2NvbTEVMBMGCAmSJvWYHmQBEwdFeGFtcGxlMRgwFgYDVQQDEw9Db2Rl"
-"IFNpZ25pbmcgQ0EwgZ8wDQYJKoZIhvcNAQEBBQADgY0AMIGJAoGBALcy76InmpM9"
-"S9K2MlNSjusx6nkYWWbx7eDRTV+xhRPeDxW4t8jtKPqDF5LTusyM9WCI/nneqsIP"
-"7iTSHpxlGx37J1VbqKX5fZsfJ3wKv6ZIylzeRuFY9MFypPA2UmVd1ACDOUB3YDvY"
-"mrCVkOPEhjnZKbq4FfCpf8KNL2A5EBcZAgMBAAGjEzARMA8GA1UdEwEB/wQFMAMB"
-"Af8wDQYJKoZIhvcNAQEEBQADgYEAI0IXzwgBRXvow3JQi8Y4YdG2wZc4BWRGW87x"
-"2zOD7GOA0CWN149vb6rEchECykDsJj9LoBl6o1aRxk9WkIFnXmMOJSuJA+ilCe//"
-"81a5OhKbe0p7ym6rh190BLwh2VePFeyabq6NipfZlN6qgWUzoepf+jVblufW/2EI"
-"fbMSylc=";
-#endif
-
-/* This is the cert->certKey (serial number and issuer name) of
- * the cert that we want to revoke.
- */
-static unsigned char revoked_system_principal_key[] = {
-0x40, 0x18, 0xf2, 0x35, 0x86, 0x06, 0x78, 0xce, 0x87, 0x89,
-0x0c, 0x5d, 0x68, 0x67, 0x33, 0x09, 0x30, 0x81, 0xc1, 0x31,
-0x1f, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x16,
-0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x54,
-0x72, 0x75, 0x73, 0x74, 0x20, 0x4e, 0x65, 0x74, 0x77, 0x6f,
-0x72, 0x6b, 0x31, 0x17, 0x30, 0x15, 0x06, 0x03, 0x55, 0x04,
-0x0b, 0x13, 0x0e, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69, 0x67,
-0x6e, 0x2c, 0x20, 0x49, 0x6e, 0x63, 0x2e, 0x31, 0x3a, 0x30,
-0x38, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x31, 0x56, 0x65,
-0x72, 0x69, 0x53, 0x69, 0x67, 0x6e, 0x20, 0x4f, 0x62, 0x6a,
-0x65, 0x63, 0x74, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e,
-0x67, 0x20, 0x43, 0x41, 0x20, 0x2d, 0x20, 0x43, 0x6c, 0x61,
-0x73, 0x73, 0x20, 0x33, 0x20, 0x4f, 0x72, 0x67, 0x61, 0x6e,
-0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x31, 0x49, 0x30,
-0x47, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x40, 0x77, 0x77,
-0x77, 0x2e, 0x76, 0x65, 0x72, 0x69, 0x73, 0x69, 0x67, 0x6e,
-0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x43, 0x50, 0x53, 0x20, 0x49,
-0x6e, 0x63, 0x6f, 0x72, 0x70, 0x2e, 0x62, 0x79, 0x20, 0x52,
-0x65, 0x66, 0x2e, 0x20, 0x4c, 0x49, 0x41, 0x42, 0x49, 0x4c,
-0x49, 0x54, 0x59, 0x20, 0x4c, 0x54, 0x44, 0x2e, 0x28, 0x63,
-0x29, 0x39, 0x37, 0x20, 0x56, 0x65, 0x72, 0x69, 0x53, 0x69,
-0x67, 0x6e
-};
-
-SECStatus
-CERT_CheckForEvilCert(CERTCertificate *cert)
-{
- if ( cert->certKey.len == sizeof(revoked_system_principal_key) ) {
- if ( PORT_Memcmp(cert->certKey.data,
- revoked_system_principal_key,
- sizeof(revoked_system_principal_key)) == 0 ) {
- return(SECFailure);
- }
- }
-
- return(SECSuccess);
-}
-
-#ifdef STATIC_CERT_INIT
-
-#define DEFAULT_TRUST_FLAGS (CERTDB_VALID_CA | \
- CERTDB_TRUSTED_CA | \
- CERTDB_NS_TRUSTED_CA)
-
-typedef enum {
- certUpdateNone,
- certUpdateAdd,
- certUpdateDelete,
- certUpdateAddTrust,
- certUpdateRemoveTrust,
- certUpdateSetTrust
-} certUpdateOp;
-
-typedef struct {
- char *cert;
- char *nickname;
- CERTCertTrust trust;
- int updateVersion;
- certUpdateOp op;
- CERTCertTrust trustDelta;
-} certInitEntry;
-
-static certInitEntry initialcerts[] = {
- {
- example_com_server_ca,
- "Example.com Server CA",
- { DEFAULT_TRUST_FLAGS | CERTDB_GOVT_APPROVED_CA, 0, 0 },
- 1,
- certUpdateAdd,
- { 0, 0, 0 }
- },
- {
- example_com_server_ca,
- "Example.com Server CA",
- { DEFAULT_TRUST_FLAGS | CERTDB_GOVT_APPROVED_CA, 0, 0 },
- 2,
- certUpdateAddTrust,
- { CERTDB_GOVT_APPROVED_CA, 0, 0 }
- },
-
- {
- example_com_individual_ca,
- "Example.com Individual CA",
- { 0, DEFAULT_TRUST_FLAGS, 0 },
- 1,
- certUpdateAdd,
- { 0, 0, 0 }
- },
- {
- example_com_individual_ca,
- "Example.com Individual CA",
- { 0, DEFAULT_TRUST_FLAGS, 0 },
- 2,
- certUpdateRemoveTrust,
- { 0, 0, DEFAULT_TRUST_FLAGS }
- },
-
- {
- example_com_objsign_ca,
- "Example.com Code Signing CA",
- { 0, 0, DEFAULT_TRUST_FLAGS },
- 2,
- certUpdateAdd,
- { 0, 0, 0 }
- },
-
- {
- 0, 0
- }
-};
-
-
-static SECStatus
-ConvertAndCheckCertificate(CERTCertDBHandle *handle, char *asciicert,
- char *nickname, CERTCertTrust *trust)
-{
- SECItem sdder;
- SECStatus rv;
- CERTCertificate *cert;
- PRBool conflict;
- SECItem derSubject;
-
- /* First convert ascii to binary */
- rv = ATOB_ConvertAsciiToItem (&sdder, asciicert);
- if (rv != SECSuccess) {
- return(rv);
- }
-
- /*
- ** Inside the ascii is a Signed Certificate.
- */
-
- cert = NULL;
-
- /* make sure that no conflicts exist */
- conflict = SEC_CertDBKeyConflict(&sdder, handle);
- if ( conflict ) {
- goto done;
- }
-
- rv = CERT_NameFromDERCert(&sdder, &derSubject);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- conflict = SEC_CertNicknameConflict(nickname, &derSubject, handle);
- if ( conflict ) {
- goto done;
- }
-
- cert = CERT_NewTempCertificate(handle, &sdder, NULL, PR_FALSE, PR_TRUE);
- if ( cert == NULL ) {
- goto loser;
- }
-
- rv = CERT_AddTempCertToPerm(cert, nickname, trust);
-
- CERT_DestroyCertificate(cert);
-
- if (rv == SECSuccess) {
- /*
- ** XXX should verify signatures too, if we have the certificate for
- ** XXX its issuer...
- */
- }
-
-done:
- PORT_Free(sdder.data);
- return(rv);
-
-loser:
- return(SECFailure);
-}
-
-#endif
-
-extern void certdb_InitDBLock(void);
-
-SECStatus
-CERT_InitCertDB(CERTCertDBHandle *handle)
-{
-#ifdef STATIC_CERT_INIT
- SECStatus rv;
- certInitEntry *entry;
- certdb_InitDBLock();
-
- entry = initialcerts;
-
- while ( entry->cert != NULL) {
- if ( entry->op != certUpdateDelete ) {
- rv = ConvertAndCheckCertificate(handle, entry->cert,
- entry->nickname, &entry->trust);
- /* keep going */
- }
-
- entry++;
- }
-done:
- CERT_SetDBContentVersion(CERT_DB_CONTENT_VERSION, handle);
- return(rv);
-#else
- certdb_InitDBLock();
- CERT_SetDBContentVersion(0, handle);
- return(SECSuccess);
-#endif
-}
-
-#ifdef STATIC_CERT_INIT
-static CERTCertificate *
-CertFromEntry(CERTCertDBHandle *handle, char *asciicert)
-{
- SECItem sdder;
- SECStatus rv;
- CERTCertificate *cert;
-
- /* First convert ascii to binary */
- rv = ATOB_ConvertAsciiToItem (&sdder, asciicert);
- if (rv != SECSuccess) {
- return(NULL);
- }
-
- /*
- ** Inside the ascii is a Signed Certificate.
- */
-
- cert = CERT_NewTempCertificate(handle, &sdder, NULL, PR_FALSE, PR_TRUE);
-
- return(cert);
-}
-#endif
-
-SECStatus
-CERT_AddNewCerts(CERTCertDBHandle *handle)
-{
-#ifdef STATIC_CERT_INIT
- int oldversion;
- int newversion;
- certInitEntry *entry;
- CERTCertTrust tmptrust;
- SECStatus rv;
- CERTCertificate *cert;
-
- newversion = CERT_DB_CONTENT_VERSION;
-
- oldversion = CERT_GetDBContentVersion(handle);
-
- if ( newversion > oldversion ) {
- entry = initialcerts;
-
- while ( entry->cert != NULL ) {
- if ( entry->updateVersion > oldversion ) {
- switch ( entry->op ) {
- default:
- break;
- case certUpdateAdd:
- rv = ConvertAndCheckCertificate(handle, entry->cert,
- entry->nickname,
- &entry->trust);
- break;
- case certUpdateDelete:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- rv = SEC_DeletePermCertificate(cert);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- case certUpdateAddTrust:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- tmptrust = *cert->trust;
- tmptrust.sslFlags |= entry->trustDelta.sslFlags;
- tmptrust.emailFlags |=
- entry->trustDelta.emailFlags;
- tmptrust.objectSigningFlags |=
- entry->trustDelta.objectSigningFlags;
- rv = CERT_ChangeCertTrust(handle, cert,
-&tmptrust);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- case certUpdateRemoveTrust:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- tmptrust = *cert->trust;
- tmptrust.sslFlags &=
- (~entry->trustDelta.sslFlags);
- tmptrust.emailFlags &=
- (~entry->trustDelta.emailFlags);
- tmptrust.objectSigningFlags &=
- (~entry->trustDelta.objectSigningFlags);
- rv = CERT_ChangeCertTrust(handle, cert,
-&tmptrust);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- case certUpdateSetTrust:
- cert = CertFromEntry(handle, entry->cert);
- if ( cert != NULL ) {
- if ( cert->isperm ) {
- tmptrust = *cert->trust;
- tmptrust.sslFlags = entry->trustDelta.sslFlags;
- tmptrust.emailFlags =
- entry->trustDelta.emailFlags;
- tmptrust.objectSigningFlags =
- entry->trustDelta.objectSigningFlags;
- rv = CERT_ChangeCertTrust(handle, cert,
-&tmptrust);
- }
- CERT_DestroyCertificate(cert);
- }
- break;
- }
- }
-
- entry++;
- }
-
- CERT_SetDBContentVersion(newversion, handle);
- }
-
-#endif
- return(SECSuccess);
-}
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h
index 71ad723b1..b82a7f28c 100644
--- a/security/nss/lib/certdb/certt.h
+++ b/security/nss/lib/certdb/certt.h
@@ -392,8 +392,10 @@ struct CERTCrlKeyStr {
struct CERTSignedCrlStr {
PRArenaPool *arena;
CERTCrl crl;
- certDBEntryRevocation *dbEntry; /* database entry struct */
- PRBool keep; /* keep this crl in the cache for the session*/
+ /*certDBEntryRevocation *dbEntry; database entry struct */
+ PK11SlotInfo *slot;
+ /* PRBool keep; keep this crl in the cache for the session*/
+ CK_OBJECT_HANDLE pkcs11ID;
PRBool isperm;
PRBool istemp;
int referenceCount;
diff --git a/security/nss/lib/certdb/crl.c b/security/nss/lib/certdb/crl.c
index 957d72fb5..13877aab1 100644
--- a/security/nss/lib/certdb/crl.c
+++ b/security/nss/lib/certdb/crl.c
@@ -41,10 +41,11 @@
#include "secder.h"
#include "secasn1.h"
#include "secoid.h"
-#include "certtrust.h"
+#include "certrust.h"
#include "certxutl.h"
#include "prtime.h"
#include "secerr.h"
+#include "pk11func.h"
const SEC_ASN1Template SEC_CERTExtensionTemplate[] = {
{ SEC_ASN1_SEQUENCE,
@@ -389,6 +390,189 @@ loser:
return(0);
}
+/*
+ * Lookup a CRL in the databases. We mirror the same fast caching data base
+ * caching stuff used by certificates....?
+ */
+CERTSignedCrl *
+SEC_FindCrlByKeyOnSlot(PK11SlotInfo *slot, SECItem *crlKey, int type)
+{
+ CERTSignedCrl *crl = NULL;
+ SECItem *derCrl;
+ CK_OBJECT_HANDLE crlHandle;
+
+ if (slot) {
+ PK11_ReferenceSlot(slot);
+ }
+
+ derCrl = PK11_FindCrlByName(&slot, &crlHandle, crlKey,type);
+ if (derCrl == NULL) {
+ goto loser;
+ }
+
+ crl = CERT_DecodeDERCrl(NULL, derCrl, type);
+ if (crl) {
+ crl->slot = slot;
+ slot = NULL; /* adopt it */
+ }
+
+loser:
+ if (slot) {
+ PK11_FreeSlot(slot);
+ }
+ return(crl);
+}
+
+SECStatus SEC_DestroyCrl(CERTSignedCrl *crl);
+
+CERTSignedCrl *
+crl_storeCRL (PK11SlotInfo *slot,char *url,
+ CERTSignedCrl *newCrl, SECItem *derCrl, int type)
+{
+ CERTSignedCrl *oldCrl = NULL, *crl = NULL;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+ CK_OBJECT_HANDLE crlHandle;
+
+ oldCrl = SEC_FindCrlByKeyOnSlot(slot, &newCrl->crl.derName, type);
+
+ /* if there is an old crl, make sure the one we are installing
+ * is newer. If not, exit out, otherwise delete the old crl.
+ */
+ if (oldCrl != NULL) {
+ if (!SEC_CrlIsNewer(&newCrl->crl,&oldCrl->crl)) {
+
+ if (type == SEC_CRL_TYPE) {
+ PORT_SetError(SEC_ERROR_OLD_CRL);
+ } else {
+ PORT_SetError(SEC_ERROR_OLD_KRL);
+ }
+
+ goto done;
+ }
+
+ if ((SECITEM_CompareItem(&newCrl->crl.derName,
+ &oldCrl->crl.derName) != SECEqual) &&
+ (type == SEC_KRL_TYPE) ) {
+
+ PORT_SetError(SEC_ERROR_CKL_CONFLICT);
+ goto done;
+ }
+
+ /* if we have a url in the database, use that one */
+ if (oldCrl->url) {
+ url = oldCrl->url;
+ }
+
+
+ /* really destroy this crl */
+ /* first drum it out of the permanment Data base */
+ SEC_DeletePermCRL(oldCrl);
+ }
+
+ /* Write the new entry into the data base */
+ crlHandle = PK11_PutCrl(slot, derCrl, &newCrl->crl.derName, url, type);
+ if (crlHandle != CK_INVALID_HANDLE) {
+ crl = newCrl;
+ crl->slot = PK11_ReferenceSlot(slot);
+ crl->pkcs11ID = crlHandle;
+ }
+
+done:
+ if (oldCrl) SEC_DestroyCrl(oldCrl);
+
+ return crl;
+}
+
+CERTSignedCrl *
+SEC_FindCrlByName(CERTCertDBHandle *handle, SECItem *crlKey, int type)
+{
+ return SEC_FindCrlByKeyOnSlot(NULL,crlKey,type);
+}
+
+/*
+ *
+ * create a new CRL from DER material.
+ *
+ * The signature on this CRL must be checked before you
+ * load it. ???
+ */
+CERTSignedCrl *
+SEC_NewCrl(CERTCertDBHandle *handle, char *url, SECItem *derCrl, int type)
+{
+ CERTSignedCrl *newCrl = NULL, *crl = NULL;
+ PK11SlotInfo *slot;
+
+ /* make this decode dates! */
+ newCrl = CERT_DecodeDERCrl(NULL, derCrl, type);
+ if (newCrl == NULL) {
+ if (type == SEC_CRL_TYPE) {
+ PORT_SetError(SEC_ERROR_CRL_INVALID);
+ } else {
+ PORT_SetError(SEC_ERROR_KRL_INVALID);
+ }
+ goto done;
+ }
+
+ slot = PK11_GetInternalKeySlot();
+ crl = crl_storeCRL(slot, url, newCrl, derCrl, type);
+ PK11_FreeSlot(slot);
+
+
+done:
+ if (crl == NULL) {
+ if (newCrl) {
+ PORT_FreeArena(newCrl->arena, PR_FALSE);
+ }
+ }
+
+ return crl;
+}
+
+
+CERTSignedCrl *
+SEC_FindCrlByDERCert(CERTCertDBHandle *handle, SECItem *derCrl, int type)
+{
+ PRArenaPool *arena;
+ SECItem crlKey;
+ SECStatus rv;
+ CERTSignedCrl *crl = NULL;
+
+ /* create a scratch arena */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if ( arena == NULL ) {
+ return(NULL);
+ }
+
+ /* extract the database key from the cert */
+ rv = CERT_KeyFromDERCrl(arena, derCrl, &crlKey);
+ if ( rv != SECSuccess ) {
+ goto loser;
+ }
+
+ /* find the crl */
+ crl = SEC_FindCrlByName(handle, &crlKey, type);
+
+loser:
+ PORT_FreeArena(arena, PR_FALSE);
+ return(crl);
+}
+
+
+SECStatus
+SEC_DestroyCrl(CERTSignedCrl *crl)
+{
+ if (crl) {
+ if (crl->referenceCount-- <= 1) {
+ if (crl->slot) {
+ PK11_FreeSlot(crl->slot);
+ }
+ PORT_FreeArena(crl->arena, PR_FALSE);
+ }
+ }
+ return SECSuccess;
+}
+
/* These functions simply return the address of the above-declared templates.
** This is necessary for Windows DLLs. Sigh.
*/
diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn
index 8f2cc51ab..9b5ae12a0 100644
--- a/security/nss/lib/certdb/manifest.mn
+++ b/security/nss/lib/certdb/manifest.mn
@@ -35,24 +35,21 @@ CORE_DEPTH = ../../..
EXPORTS = \
cert.h \
certt.h \
+ certrust.h \
$(NULL)
PRIVATE_EXPORTS = \
genname.h \
xconst.h \
certxutl.h \
- certrust.h \
$(NULL)
MODULE = security
-CERTINIT=certinit.c
-
CSRCS = \
alg1485.c \
certdb.c \
certv3.c \
- $(CERTINIT) \
certxutl.c \
crl.c \
genname.c \
diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c
index 094de1933..68294cfe0 100644
--- a/security/nss/lib/certhigh/certhigh.c
+++ b/security/nss/lib/certhigh/certhigh.c
@@ -418,18 +418,11 @@ CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
names->what = what;
names->totallen = 0;
- rv = SEC_TraversePermCerts(handle, CollectNicknames, (void *)names);
+ rv = PK11_TraverseSlotCerts(CollectNicknames, (void *)names, wincx);
if ( rv ) {
goto loser;
}
- if ( wincx != NULL ) {
- rv = PK11_TraverseSlotCerts(CollectNicknames, (void *)names, wincx);
- if ( rv ) {
- goto loser;
- }
- }
-
if ( names->numnicknames ) {
names->nicknames = (char**)PORT_ArenaAlloc(arena,
names->numnicknames * sizeof(char *));
@@ -562,7 +555,7 @@ CERT_GetSSLCACerts(CERTCertDBHandle *handle)
names->names = NULL;
/* collect the names from the database */
- rv = SEC_TraversePermCerts(handle, CollectDistNames, (void *)names);
+ rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL);
if ( rv ) {
goto loser;
}
@@ -781,22 +774,6 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
while (numcerts--) {
derCert = certs;
certs++;
-
- /* get the key (issuer+cn) from the cert */
- rv = CERT_KeyFromDERCert(arena, derCert, &certKey);
- if ( rv != SECSuccess ) {
- goto loser;
- }
-
- /* same cert already exists in the database, don't need to do
- * anything more with it
- */
- cert = CERT_FindCertByKey(handle, &certKey);
- if ( cert ) {
- CERT_DestroyCertificate(cert);
- cert = NULL;
- continue;
- }
/* decode my certificate */
newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
@@ -860,7 +837,7 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
}
}
- cert = CERT_NewTempCertificate(handle, derCert, NULL, PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if ( cert == NULL ) {
goto loser;
}
@@ -868,7 +845,10 @@ cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool
/* get a default nickname for it */
nickname = CERT_MakeCANickname(cert);
- rv = CERT_AddTempCertToPerm(cert, nickname, &trust);
+ cert->trust = &trust;
+ rv = PK11_ImportCert(PK11_GetInternalKeySlot(), cert,
+ CK_INVALID_HANDLE, nickname, PR_TRUE);
+
/* free the nickname */
if ( nickname ) {
PORT_Free(nickname);
diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c
index 1b8f37a47..982ec0b9e 100644
--- a/security/nss/lib/certhigh/certvfy.c
+++ b/security/nss/lib/certhigh/certvfy.c
@@ -351,14 +351,16 @@ CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage)
*/
if (caName != NULL) {
- rv = CERT_KeyFromIssuerAndSN(tmpArena, caName,
- &authorityKeyID->authCertSerialNumber,
- &issuerCertKey);
- if ( rv == SECSuccess ) {
- issuerCert = CERT_FindCertByKey(cert->dbhandle,
- &issuerCertKey);
- }
-
+ CERTIssuerAndSN issuerSN;
+
+ issuerSN.derIssuer.data = caName->data;
+ issuerSN.derIssuer.len = caName->len;
+ issuerSN.serialNumber.data =
+ authorityKeyID->authCertSerialNumber.data;
+ issuerSN.serialNumber.len =
+ authorityKeyID->authCertSerialNumber.len;
+ issuerCert = CERT_FindCertByIssuerAndSN(cert->dbhandle,
+ &issuerSN);
if ( issuerCert == NULL ) {
PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER);
goto loser;
@@ -964,13 +966,15 @@ CERT_VerifyCert(CERTCertDBHandle *handle, CERTCertificate *cert,
PRBool allowOverride;
SECCertTimeValidity validity;
CERTStatusConfig *statusConfig;
-
+
+#ifdef notdef
/* check if this cert is in the Evil list */
rv = CERT_CheckForEvilCert(cert);
if ( rv != SECSuccess ) {
PORT_SetError(SEC_ERROR_REVOKED_CERTIFICATE);
LOG_ERROR_OR_EXIT(log,cert,0,0);
}
+#endif
/* make sure that the cert is valid at time t */
allowOverride = (PRBool)((certUsage == certUsageSSLServer) ||
diff --git a/security/nss/lib/certhigh/ocsp.c b/security/nss/lib/certhigh/ocsp.c
index 150977149..2dc75e474 100644
--- a/security/nss/lib/certhigh/ocsp.c
+++ b/security/nss/lib/certhigh/ocsp.c
@@ -653,6 +653,28 @@ ocsp_CreateCertID(PRArenaPool *arena, CERTCertificate *cert, int64 time)
if (rv != SECSuccess) {
goto loser;
}
+ certID->issuerSHA1NameHash.data = certID->issuerNameHash.data;
+ certID->issuerSHA1NameHash.len = certID->issuerNameHash.len;
+ /* cache the other two hash algorithms as well */
+ if (SECITEM_AllocItem(arena, &(certID->issuerMD5NameHash),
+ MD5_LENGTH) == NULL) {
+ goto loser;
+ }
+ rv = PK11_HashBuf(SEC_OID_MD5, certID->issuerMD5NameHash.data,
+ tempItem->data, tempItem->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ if (SECITEM_AllocItem(arena, &(certID->issuerMD2NameHash),
+ MD2_LENGTH) == NULL) {
+ goto loser;
+ }
+ rv = PK11_HashBuf(SEC_OID_MD2, certID->issuerMD2NameHash.data,
+ tempItem->data, tempItem->len);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
SECITEM_FreeItem(tempItem, PR_TRUE);
tempItem = NULL;
@@ -660,6 +682,18 @@ ocsp_CreateCertID(PRArenaPool *arena, CERTCertificate *cert, int64 time)
&(certID->issuerKeyHash)) == NULL) {
goto loser;
}
+ certID->issuerSHA1KeyHash.data = certID->issuerKeyHash.data;
+ certID->issuerSHA1KeyHash.len = certID->issuerKeyHash.len;
+ /* cache the other two hash algorithms as well */
+ if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_MD5,
+ &(certID->issuerMD5KeyHash)) == NULL) {
+ goto loser;
+ }
+ if (CERT_SPKDigestValueForCert(arena, issuerCert, SEC_OID_MD2,
+ &(certID->issuerMD2KeyHash)) == NULL) {
+ goto loser;
+ }
+
/* now we are done with issuerCert */
CERT_DestroyCertificate(issuerCert);
@@ -2368,6 +2402,40 @@ ocsp_CertHasNoCheckExtension(CERTCertificate *cert)
}
#endif /* LATER */
+static PRBool
+ocsp_matchcert(SECItem *certIndex,CERTCertificate *testCert)
+{
+ SECItem item;
+ unsigned char buf[SHA1_LENGTH]; /* MAX Hash Len */
+
+ item.data = buf;
+ item.len = SHA1_LENGTH;
+
+ if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_SHA1, &item) == NULL) {
+ return PR_FALSE;
+ }
+ if (SECITEM_ItemsAreEqual(certIndex,&item)) {
+ return PR_TRUE;
+ }
+ if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_MD5, &item) == NULL) {
+ return PR_FALSE;
+ }
+ if (SECITEM_ItemsAreEqual(certIndex,&item)) {
+ return PR_TRUE;
+ }
+ if (CERT_SPKDigestValueForCert(NULL,testCert,SEC_OID_MD2, &item) == NULL) {
+ return PR_FALSE;
+ }
+ if (SECITEM_ItemsAreEqual(certIndex,&item)) {
+ return PR_TRUE;
+ }
+
+ return PR_FALSE;
+}
+
+static CERTCertificate *
+ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID);
+
/*
* Check the signature on some OCSP data. This is a helper function that
* can be used to check either a request or a response. The result is
@@ -2397,15 +2465,18 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
const SEC_ASN1Template *encodeTemplate,
CERTCertDBHandle *handle, SECCertUsage certUsage,
int64 checkTime, PRBool lookupByName, void *certIndex,
- void *pwArg, CERTCertificate **pSignerCert)
+ void *pwArg, CERTCertificate **pSignerCert,
+ CERTCertificate *issuer)
{
SECItem rawSignature;
SECItem *encodedTBS = NULL;
+ CERTCertificate *responder = NULL;
CERTCertificate *signerCert = NULL;
SECKEYPublicKey *signerKey = NULL;
CERTCertificate **certs = NULL;
SECStatus rv = SECFailure;
int certCount;
+ int i;
/*
* If this signature has already gone through verification, just
@@ -2432,6 +2503,7 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
if (signature->derCerts != NULL) {
for (; signature->derCerts[certCount] != NULL; certCount++) {
/* just counting */
+ /*IMPORT CERT TO SPKI TABLE */
}
}
rv = CERT_ImportCerts(handle, certUsage, certCount,
@@ -2455,7 +2527,22 @@ ocsp_CheckSignature(ocspSignature *signature, void *tbs,
signerCert = CERT_FindCertByName(handle, encodedName);
SECITEM_FreeItem(encodedName, PR_TRUE);
} else {
- signerCert = CERT_FindCertBySPKDigest(handle, certIndex);
+ /*
+ * The signer is either 1) a known issuer CA we passed in,
+ * 2) the default OCSP responder, or 3) and intermediate CA
+ * passed in the cert list to use. Figure out which it is.
+ */
+ responder = ocsp_CertGetDefaultResponder(handle,NULL);
+ if (responder && ocsp_matchcert(certIndex,responder)) {
+ signerCert = CERT_DupCertificate(responder);
+ } else if (issuer && ocsp_matchcert(certIndex,issuer)) {
+ signerCert = CERT_DupCertificate(issuer);
+ }
+ for (i=0; (signerCert == NULL) && (i < certCount); i++) {
+ if (ocsp_matchcert(certIndex,certs[i])) {
+ signerCert = CERT_DupCertificate(certs[i]);
+ }
+ }
}
if (signerCert == NULL) {
@@ -2546,6 +2633,7 @@ finish:
if (certs != NULL)
CERT_DestroyCertArray(certs, certCount);
+ /* Free CERTS from SPKDigest Table */
return rv;
}
@@ -2583,7 +2671,8 @@ finish:
SECStatus
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
CERTCertDBHandle *handle, void *pwArg,
- CERTCertificate **pSignerCert)
+ CERTCertificate **pSignerCert,
+ CERTCertificate *issuer)
{
ocspResponseData *tbsData; /* this is what is signed */
PRBool byName;
@@ -2623,7 +2712,7 @@ CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
return ocsp_CheckSignature(ocsp_GetResponseSignature(response),
tbsData, ocsp_ResponseDataTemplate,
handle, certUsageStatusResponder, producedAt,
- byName, certIndex, pwArg, pSignerCert);
+ byName, certIndex, pwArg, pSignerCert, issuer);
}
/*
@@ -2635,12 +2724,10 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle,
CERTOCSPCertID *certID1, CERTOCSPCertID *certID2)
{
PRBool match = PR_FALSE;
- CERTCertificate *issuer1 = NULL;
- CERTCertificate *issuer2 = NULL;
SECItem *foundHash = NULL;
- CERTCertificate *found;
SECOidTag hashAlg;
- SECItem *givenHash;
+ SECItem *keyHash;
+ SECItem *nameHash;
/*
* In order to match, they must have the same issuer and the same
@@ -2668,63 +2755,34 @@ ocsp_CertIDsMatch(CERTCertDBHandle *handle,
goto done;
}
- /*
- * The hash algorithms are different; this is harder. We have
- * to do a lookup of each one and compare them.
- */
- issuer1 = CERT_FindCertBySPKDigest(handle, &certID1->issuerKeyHash);
- issuer2 = CERT_FindCertBySPKDigest(handle, &certID2->issuerKeyHash);
-
- if (issuer1 == NULL && issuer2 == NULL) {
- /* If we cannot find an issuer cert, we have no way to compare. */
- goto done;
- }
-
- if (issuer1 != NULL && issuer2 != NULL) {
- /* If we found a cert for each hash, we can just compare them. */
- if (issuer1 == issuer2)
- match = PR_TRUE;
- goto done;
- }
-
- /*
- * We found one issuer, but not both. So we have to use the other certID
- * hash algorithm on the key in the found issuer cert to see if they match.
- */
-
- if (issuer1 != NULL) {
- found = issuer1;
- hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm);
- givenHash = &certID2->issuerKeyHash;
- } else {
- found = issuer2;
- hashAlg = SECOID_FindOIDTag(&certID1->hashAlgorithm.algorithm);
- givenHash = &certID1->issuerKeyHash;
+ hashAlg = SECOID_FindOIDTag(&certID2->hashAlgorithm.algorithm);
+ switch (hashAlg) {
+ case SEC_OID_SHA1:
+ keyHash = &certID1->issuerSHA1KeyHash;
+ nameHash = &certID1->issuerSHA1NameHash;
+ break;
+ case SEC_OID_MD5:
+ keyHash = &certID1->issuerMD5KeyHash;
+ nameHash = &certID1->issuerMD5NameHash;
+ break;
+ case SEC_OID_MD2:
+ keyHash = &certID1->issuerMD2KeyHash;
+ nameHash = &certID1->issuerMD2NameHash;
+ break;
+ default:
+ foundHash == NULL;
}
- foundHash = CERT_SPKDigestValueForCert(NULL, found, hashAlg, NULL);
if (foundHash == NULL) {
goto done;
}
- if (SECITEM_CompareItem(foundHash, givenHash) == SECEqual) {
- /*
- * Strictly speaking, we should compare the issuerNameHash, too,
- * but I think the added complexity doesn't actually buy anything.
- */
+ if ((SECITEM_CompareItem(nameHash, &certID2->issuerNameHash) == SECEqual)
+ && (SECITEM_CompareItem(keyHash, &certID2->issuerKeyHash) == SECEqual)) {
match = PR_TRUE;
}
done:
- if (issuer1 != NULL) {
- CERT_DestroyCertificate(issuer1);
- }
- if (issuer2 != NULL) {
- CERT_DestroyCertificate(issuer2);
- }
- if (foundHash != NULL) {
- SECITEM_FreeItem(foundHash, PR_TRUE);
- }
return match;
}
@@ -2788,15 +2846,12 @@ ocsp_GetCheckingContext(CERTCertDBHandle *handle)
return ocspcx;
}
-
/*
* Return true if the given signerCert is the default responder for
* the given certID. If not, or if any error, return false.
*/
-static PRBool
-ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle,
- CERTCertificate *signerCert,
- CERTOCSPCertID *certID)
+static CERTCertificate *
+ocsp_CertGetDefaultResponder(CERTCertDBHandle *handle,CERTOCSPCertID *certID)
{
ocspCheckingContext *ocspcx;
@@ -2814,12 +2869,26 @@ ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle,
*/
if (ocspcx->useDefaultResponder) {
PORT_Assert(ocspcx->defaultResponderCert != NULL);
- if (ocspcx->defaultResponderCert == signerCert)
- return PR_TRUE;
+ return ocspcx->defaultResponderCert;
}
loser:
- return PR_FALSE;
+ return NULL;
+}
+
+/*
+ * Return true if the given signerCert is the default responder for
+ * the given certID. If not, or if any error, return false.
+ */
+static PRBool
+ocsp_CertIsDefaultResponderForCertID(CERTCertDBHandle *handle,
+ CERTCertificate *signerCert,
+ CERTOCSPCertID *certID)
+{
+ CERTCertificate *defaultResponderCert;
+
+ defaultResponderCert = ocsp_CertGetDefaultResponder(handle, certID);
+ return (PRBool) (defaultResponderCert == signerCert);
}
/*
@@ -3300,6 +3369,7 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
CERTOCSPRequest *request = NULL;
CERTOCSPResponse *response = NULL;
CERTCertificate *signerCert = NULL;
+ CERTCertificate *issuerCert = NULL;
ocspResponseData *responseData;
int64 producedAt;
CERTOCSPCertID *certID;
@@ -3413,7 +3483,9 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
* If we've made it this far, we expect a response with a good signature.
* So, check for that.
*/
- rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert);
+ issuerCert = CERT_FindCertIssuer(cert, time, certUsageAnyCA);
+ rv = CERT_VerifyOCSPResponseSignature(response, handle, pwArg, &signerCert,
+ issuerCert);
if (rv != SECSuccess)
goto loser;
@@ -3471,6 +3543,8 @@ CERT_CheckOCSPStatus(CERTCertDBHandle *handle, CERTCertificate *cert,
rv = ocsp_CertHasGoodStatus(single, time);
loser:
+ if (issuerCert != NULL)
+ CERT_DestroyCertificate(issuerCert);
if (signerCert != NULL)
CERT_DestroyCertificate(signerCert);
if (response != NULL)
@@ -3905,3 +3979,97 @@ CERT_DisableOCSPDefaultResponder(CERTCertDBHandle *handle)
statusContext->useDefaultResponder = PR_FALSE;
return SECSuccess;
}
+static const SECHashObject *
+OidTagToDigestObject(SECOidTag digestAlg)
+{
+ const SECHashObject *rawDigestObject;
+
+ switch (digestAlg) {
+ case SEC_OID_MD2:
+ rawDigestObject = &SECHashObjects[HASH_AlgMD2];
+ break;
+ case SEC_OID_MD5:
+ rawDigestObject = &SECHashObjects[HASH_AlgMD5];
+ break;
+ case SEC_OID_SHA1:
+ rawDigestObject = &SECHashObjects[HASH_AlgSHA1];
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ rawDigestObject = NULL;
+ break;
+ }
+ return(rawDigestObject);
+}
+
+/*
+ * Digest the cert's subject public key using the specified algorithm.
+ * The necessary storage for the digest data is allocated. If "fill" is
+ * non-null, the data is put there, otherwise a SECItem is allocated.
+ * Allocation from "arena" if it is non-null, heap otherwise. Any problem
+ * results in a NULL being returned (and an appropriate error set).
+ */
+SECItem *
+CERT_SPKDigestValueForCert(PRArenaPool *arena, CERTCertificate *cert,
+ SECOidTag digestAlg, SECItem *fill)
+{
+ const SECHashObject *digestObject;
+ void *digestContext;
+ SECItem *result = NULL;
+ void *mark = NULL;
+ SECItem spk;
+
+ if ( arena != NULL ) {
+ mark = PORT_ArenaMark(arena);
+ }
+
+ digestObject = OidTagToDigestObject(digestAlg);
+ if ( digestObject == NULL ) {
+ goto loser;
+ }
+
+ if ((fill == NULL) || (fill->data == NULL)) {
+ result = SECITEM_AllocItem(arena, fill, digestObject->length);
+ if ( result == NULL ) {
+ goto loser;
+ }
+ fill = result;
+ }
+
+ /*
+ * Copy just the length and data pointer (nothing needs to be freed)
+ * of the subject public key so we can convert the length from bits
+ * to bytes, which is what the digest function expects.
+ */
+ spk = cert->subjectPublicKeyInfo.subjectPublicKey;
+ DER_ConvertBitString(&spk);
+
+ /*
+ * Now digest the value, using the specified algorithm.
+ */
+ digestContext = digestObject->create();
+ if ( digestContext == NULL ) {
+ goto loser;
+ }
+ digestObject->begin(digestContext);
+ digestObject->update(digestContext, spk.data, spk.len);
+ digestObject->end(digestContext, fill->data, &(fill->len), fill->len);
+ digestObject->destroy(digestContext, PR_TRUE);
+
+ if ( arena != NULL ) {
+ PORT_ArenaUnmark(arena, mark);
+ }
+ return(fill);
+
+loser:
+ if ( arena != NULL ) {
+ PORT_ArenaRelease(arena, mark);
+ } else {
+ if ( result != NULL ) {
+ SECITEM_FreeItem(result, (fill == NULL) ? PR_TRUE : PR_FALSE);
+ }
+ }
+ return(NULL);
+}
+
+
diff --git a/security/nss/lib/certhigh/ocsp.h b/security/nss/lib/certhigh/ocsp.h
index 51f81e867..e4bd7dbdd 100644
--- a/security/nss/lib/certhigh/ocsp.h
+++ b/security/nss/lib/certhigh/ocsp.h
@@ -353,6 +353,8 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList,
* Pointer to CERTCertDBHandle for certificate DB to use for verification.
* void *pwArg
* Pointer to argument for password prompting, if needed.
+ * CERTCertificate *issuerCert
+ * Issuer of the certificate that generated the OCSP request.
* OUTPUTS:
* CERTCertificate **pSignerCert
* Pointer in which to store signer's certificate; only filled-in if
@@ -371,7 +373,8 @@ CERT_GetEncodedOCSPResponse(PRArenaPool *arena, CERTCertList *certList,
extern SECStatus
CERT_VerifyOCSPResponseSignature(CERTOCSPResponse *response,
CERTCertDBHandle *handle, void *pwArg,
- CERTCertificate **pSignerCert);
+ CERTCertificate **pSignerCert,
+ CERTCertificate *issuerCert);
/*
* FUNCTION: CERT_GetOCSPAuthorityInfoAccessLocation
diff --git a/security/nss/lib/certhigh/ocspti.h b/security/nss/lib/certhigh/ocspti.h
index 5f530c4bf..9c739bef4 100644
--- a/security/nss/lib/certhigh/ocspti.h
+++ b/security/nss/lib/certhigh/ocspti.h
@@ -194,6 +194,12 @@ struct CERTOCSPCertIDStr {
SECItem issuerNameHash; /* an OCTET STRING */
SECItem issuerKeyHash; /* an OCTET STRING */
SECItem serialNumber; /* an INTEGER */
+ SECItem issuerSHA1NameHash; /* keep other hashes around when */
+ SECItem issuerMD5NameHash; /* we have them */
+ SECItem issuerMD2NameHash;
+ SECItem issuerSHA1KeyHash; /* keep other hashes around when */
+ SECItem issuerMD5KeyHash; /* we have them */
+ SECItem issuerMD2KeyHash;
};
/*
diff --git a/security/nss/lib/ckfw/ckt.h b/security/nss/lib/ckfw/ckt.h
index 762a70a0b..20e7d4caf 100644
--- a/security/nss/lib/ckfw/ckt.h
+++ b/security/nss/lib/ckfw/ckt.h
@@ -128,6 +128,8 @@ static const char CKT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#define CKA_TRUST_IPSEC_TUNNEL (CKA_TRUST + 13)
#define CKA_TRUST_IPSEC_USER (CKA_TRUST + 14)
#define CKA_TRUST_TIME_STAMPING (CKA_TRUST + 15)
+
+/* locate the Trust entry */
#define CKA_CERT_SHA1_HASH (CKA_TRUST + 100)
#define CKA_CERT_MD5_HASH (CKA_TRUST + 101)
@@ -187,6 +189,7 @@ typedef CK_ULONG CK_TRUST;
#define CKT_NETSCAPE_TRUSTED (CKT_NETSCAPE + 1)
#define CKT_NETSCAPE_TRUSTED_DELEGATOR (CKT_NETSCAPE + 2)
#define CKT_NETSCAPE_UNTRUSTED (CKT_NETSCAPE + 3)
+#define CKT_NETSCAPE_MUST_VERIFY (CKT_NETSCAPE + 4)
/*
* These may well remain Netscape-specific; I'm only using them
diff --git a/security/nss/lib/cryptohi/seckey.c b/security/nss/lib/cryptohi/seckey.c
index b486e7352..29e8b8de0 100644
--- a/security/nss/lib/cryptohi/seckey.c
+++ b/security/nss/lib/cryptohi/seckey.c
@@ -858,7 +858,7 @@ seckey_ExtractPublicKey(CERTSubjectPublicKeyInfo *spki)
pubk->arena = arena;
pubk->pkcs11Slot = 0;
- pubk->pkcs11ID = CK_INVALID_KEY;
+ pubk->pkcs11ID = CK_INVALID_HANDLE;
/* Convert bit string length from bits to bytes */
@@ -1034,7 +1034,7 @@ SECKEY_CopyPrivateKey(SECKEYPrivateKey *privk)
if (privk->pkcs11IsTemp) {
copyk->pkcs11ID =
PK11_CopyKey(privk->pkcs11Slot,privk->pkcs11ID);
- if (copyk->pkcs11ID == CK_INVALID_KEY) goto fail;
+ if (copyk->pkcs11ID == CK_INVALID_HANDLE) goto fail;
} else {
copyk->pkcs11ID = privk->pkcs11ID;
}
@@ -1069,7 +1069,7 @@ SECKEY_CopyPublicKey(SECKEYPublicKey *pubk)
copyk->arena = arena;
copyk->keyType = pubk->keyType;
copyk->pkcs11Slot = NULL; /* go get own reference */
- copyk->pkcs11ID = CK_INVALID_KEY;
+ copyk->pkcs11ID = CK_INVALID_HANDLE;
switch (pubk->keyType) {
case rsaKey:
rv = SECITEM_CopyItem(arena, &copyk->u.rsa.modulus,
@@ -1198,7 +1198,7 @@ SECKEY_ConvertToPublicKey(SECKEYPrivateKey *privk)
}
pubk->keyType = privk->keyType;
pubk->pkcs11Slot = NULL;
- pubk->pkcs11ID = CK_INVALID_KEY;
+ pubk->pkcs11ID = CK_INVALID_HANDLE;
pubk->arena = arena;
/*
diff --git a/security/nss/lib/manifest.mn b/security/nss/lib/manifest.mn
index 0518e7654..e20ffd4f3 100644
--- a/security/nss/lib/manifest.mn
+++ b/security/nss/lib/manifest.mn
@@ -36,8 +36,8 @@ DEPTH = ../..
DIRS = util freebl softoken \
certhigh pk11wrap cryptohi \
certdb crypto nss \
- pkcs12 pkcs7 smime\
ssl \
+ pkcs12 pkcs7 smime\
base ckfw \
crmf jar \
fortcrypt
diff --git a/security/nss/lib/nss/config.mk b/security/nss/lib/nss/config.mk
index aa35a3775..c571f2278 100644
--- a/security/nss/lib/nss/config.mk
+++ b/security/nss/lib/nss/config.mk
@@ -48,25 +48,15 @@ ifeq ($(OS_ARCH), WINNT)
SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
-DLLFLAGS += -DEF:nss.def
-RES = $(OBJDIR)/nss.res
-RESNAME = nss.rc
+RES = $(OBJDIR)/$(LIBRARY_NAME).res
+RESNAME = $(LIBRARY_NAME).rc
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-CRYPTOLIB=$(DIST)/lib/freebl.lib
-CRYPTODIR=../freebl
-ifdef MOZILLA_SECURITY_BUILD
- CRYPTOLIB=$(DIST)/lib/crypto.lib
- CRYPTODIR=../crypto
-endif
-
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/certhi.lib \
$(DIST)/lib/cryptohi.lib \
$(DIST)/lib/pk11wrap.lib \
$(DIST)/lib/certdb.lib \
- $(DIST)/lib/softoken.lib \
- $(CRYPTOLIB) \
$(DIST)/lib/secutil.lib \
$(NULL)
@@ -75,61 +65,31 @@ SHARED_LIBRARY_DIRS = \
../cryptohi \
../pk11wrap \
../certdb \
- ../softoken \
- $(CRYPTODIR) \
../util \
$(NULL)
-EXTRA_LIBS += \
- $(DIST)/lib/dbm.lib \
- $(NULL)
-
-ifdef MOZILLA_BSAFE_BUILD
- EXTRA_LIBS+=$(DIST)/lib/bsafe$(BSAFEVER).lib
-endif
-
EXTRA_SHARED_LIBS += \
+ $(DIST)/lib/softokn3.lib \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plc4.lib \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
$(NULL)
-
-# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
-#OS_LIBS += \
-# wsock32.lib \
-# winmm.lib \
-# $(NULL)
else
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
-CRYPTOLIB=$(DIST)/lib/libfreebl.$(LIB_SUFFIX)
-CRYPTODIR=../freebl
-ifdef MOZILLA_SECURITY_BUILD
- CRYPTOLIB=$(DIST)/lib/libcrypto.$(LIB_SUFFIX)
- CRYPTODIR=../crypto
-endif
SHARED_LIBRARY_LIBS = \
$(DIST)/lib/libcerthi.$(LIB_SUFFIX) \
$(DIST)/lib/libpk11wrap.$(LIB_SUFFIX) \
$(DIST)/lib/libcryptohi.$(LIB_SUFFIX) \
- $(DIST)/lib/libsoftoken.$(LIB_SUFFIX) \
$(DIST)/lib/libcertdb.$(LIB_SUFFIX) \
- $(CRYPTOLIB) \
$(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
$(NULL)
-EXTRA_LIBS += \
- $(DIST)/lib/libdbm.$(LIB_SUFFIX) \
- $(NULL)
-ifdef MOZILLA_BSAFE_BUILD
- EXTRA_LIBS+=$(DIST)/lib/libbsafe.$(LIB_SUFFIX)
-endif
+
SHARED_LIBRARY_DIRS = \
../certhigh \
../pk11wrap \
../cryptohi \
- ../softoken \
../certdb \
- $(CRYPTODIR) \
../util \
$(NULL)
@@ -137,49 +97,9 @@ SHARED_LIBRARY_DIRS = \
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
EXTRA_SHARED_LIBS += \
-L$(DIST)/lib/ \
+ -lsoftokn3 \
-lplc4 \
-lplds4 \
-lnspr4 \
$(NULL)
endif
-
-ifeq ($(OS_ARCH),SunOS)
-MAPFILE = $(OBJDIR)/nssmap.sun
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -M $(MAPFILE)
-ifndef USE_64
-ifeq ($(CPU_ARCH),sparc)
-# The -R '$ORIGIN' linker option instructs libnss3.so to search for its
-# dependencies (libfreebl_*.so) in the same directory where it resides.
-MKSHLIB += -R '$$ORIGIN'
-endif
-endif
-endif
-
-ifeq ($(OS_ARCH),AIX)
-MAPFILE = $(OBJDIR)/nssmap.aix
-ALL_TRASH += $(MAPFILE)
-EXPORT_RULES = -bexport:$(MAPFILE)
-endif
-
-ifeq ($(OS_ARCH),HP-UX)
-MAPFILE = $(OBJDIR)/nssmap.hp
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -c $(MAPFILE)
-endif
-
-ifeq ($(OS_ARCH), OSF1)
-MAPFILE = $(OBJDIR)/nssmap.osf
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -hidden -input $(MAPFILE)
-endif
-
-ifeq ($(OS_ARCH),Linux)
-MAPFILE = $(OBJDIR)/nssmap.linux
-ALL_TRASH += $(MAPFILE)
-MKSHLIB += -Wl,--version-script,$(MAPFILE)
-endif
-
-
-
-
diff --git a/security/nss/lib/nss/manifest.mn b/security/nss/lib/nss/manifest.mn
index 5d822c170..1fbdc045d 100644
--- a/security/nss/lib/nss/manifest.mn
+++ b/security/nss/lib/nss/manifest.mn
@@ -49,5 +49,7 @@ CSRCS = \
REQUIRES = security dbm
+MAPFILE = $(OBJDIR)/nss.def
+
LIBRARY_NAME = nss
LIBRARY_VERSION = 3
diff --git a/security/nss/lib/pk11wrap/manifest.mn b/security/nss/lib/pk11wrap/manifest.mn
index c043af789..6b87792ab 100644
--- a/security/nss/lib/pk11wrap/manifest.mn
+++ b/security/nss/lib/pk11wrap/manifest.mn
@@ -41,8 +41,7 @@ EXPORTS = \
$(NULL)
PRIVATE_EXPORTS = \
- secmodi.h \
- secmodti.h \
+ pk11init.h \
$(NULL)
MODULE = security
@@ -60,6 +59,7 @@ CSRCS = \
pk11sdr.c \
pk11pqg.c \
pk11pk12.c \
+ pk11pbe.c \
$(NULL)
REQUIRES = security dbm
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index 6bb3aa8f4..7d5f952d0 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -52,9 +52,6 @@
#include "secerr.h"
#include "sslerr.h"
-#define NSSCKT_H /* we included pkcs11t.h, so block ckt.h from including nssckt.h */
-#include "ckt.h"
-
#define PK11_SEARCH_CHUNKSIZE 10
CK_OBJECT_HANDLE
@@ -137,7 +134,7 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize
if (crv != CKR_OK) {
PK11_ExitSlotMonitor(slot);
PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
crv=PK11_GETTAB(slot)->C_FindObjects(slot->session,&object,1,&objectCount);
@@ -147,11 +144,11 @@ pk11_FindObjectByTemplate(PK11SlotInfo *slot,CK_ATTRIBUTE *theTemplate,int tsize
/* shouldn't use SSL_ERROR... here */
PORT_SetError( crv != CKR_OK ? PK11_MapError(crv) :
SSL_ERROR_NO_CERTIFICATE);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/* blow up if the PKCS #11 module returns us and invalid object handle */
- PORT_Assert(object != CK_INVALID_KEY);
+ PORT_Assert(object != CK_INVALID_HANDLE);
return object;
}
@@ -239,13 +236,13 @@ PK11_MatchItem(PK11SlotInfo *slot, CK_OBJECT_HANDLE searchID,
/* now we need to create space for the public key */
arena = PORT_NewArena( DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) return CK_INVALID_KEY;
+ if (arena == NULL) return CK_INVALID_HANDLE;
crv = PK11_GetAttributes(arena,slot,searchID,theTemplate,tsize);
if (crv != CKR_OK) {
PORT_FreeArena(arena,PR_FALSE);
PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/*
@@ -273,7 +270,7 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) {
theClass = CKO_PUBLIC_KEY;
}
- if (PK11_MatchItem(slot, certID , theClass) != CK_INVALID_KEY) {
+ if (PK11_MatchItem(slot, certID , theClass) != CK_INVALID_HANDLE) {
return PR_TRUE;
}
@@ -310,7 +307,7 @@ PK11_IsUserCert(PK11SlotInfo *slot, CERTCertificate *cert,
return PR_FALSE;
}
pk11_SignedToUnsigned(&theTemplate);
- if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_KEY) {
+ if (pk11_FindObjectByTemplate(slot,&theTemplate,1) != CK_INVALID_HANDLE) {
SECKEY_DestroyPublicKey(pubKey);
return PR_TRUE;
}
@@ -393,8 +390,7 @@ CERTCertificate
/* figure out the nickname.... */
nickname = pk11_buildNickname(slot,label,privateLabel,id);
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), &derCert, nickname,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(&derCert, PR_FALSE, nickname);
if (nickptr) {
*nickptr = nickname;
} else {
@@ -438,11 +434,7 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
CK_OBJECT_HANDLE tobjID;
unsigned char sha1_hash[SHA1_LENGTH];
- CK_TRUST serverAuth, codeSigning, emailProtection;
-/*
- CK_TRUST digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment,
- keyAgreement, keyCertSign, crlSign, serverAuth, clientAuth, codeSigning,
- emailProtection, ipsecEndSystem, ipsecTunnel, ipsecUser, timeStamping; */
+ CK_TRUST serverAuth, codeSigning, emailProtection, clientAuth;
PK11_HashBuf(SEC_OID_SHA1, sha1_hash, cert->derCert.data, cert->derCert.len);
@@ -452,7 +444,7 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
tobjID = pk11_FindObjectByTemplate(slot, tobjTemplate,
sizeof(tobjTemplate)/sizeof(tobjTemplate[0]));
- if( CK_INVALID_KEY == tobjID ) {
+ if( CK_INVALID_HANDLE == tobjID ) {
return PR_FALSE;
}
@@ -468,29 +460,16 @@ pk11_HandleTrustObject(PK11SlotInfo *slot, CERTCertificate *cert, CERTCertTrust
/* We could verify CKA_EXPIRES here */
- /* "Usage" trust information */
- /* digitalSignature = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_DIGITAL_SIGNATURE); */
- /* nonRepudiation = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_NON_REPUDIATION); */
- /* keyEncipherment = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_KEY_ENCIPHERMENT); */
- /* dataEncipherment = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_DATA_ENCIPHERMENT); */
- /* keyAgreement = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_KEY_AGREEMENT); */
- /* keyCertSign = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_KEY_CERT_SIGN); */
- /* crlSign = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CRL_SIGN); */
/* "Purpose" trust information */
- serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
- /* clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH); */
- codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
- emailProtection = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_EMAIL_PROTECTION);
- /* ipsecEndSystem = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_IPSEC_END_SYSTEM); */
- /* ipsecTunnel = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_IPSEC_TUNNEL); */
- /* ipsecUser = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_IPSEC_USER); */
- /* timeStamping = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_TIME_STAMPING); */
-
- /* Here's where the fun logic happens. We have to map back from the key usage,
- * extended key usage, purpose, and possibly other trust values into the old
- * trust-flags bits.
- */
+ serverAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_SERVER_AUTH);
+ clientAuth = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CLIENT_AUTH);
+ codeSigning = pk11_GetTrustField(slot, arena, tobjID, CKA_TRUST_CODE_SIGNING);
+ emailProtection = pk11_GetTrustField(slot, arena, tobjID,
+ CKA_TRUST_EMAIL_PROTECTION);
+ /* Here's where the fun logic happens. We have to map back from the
+ * key usage, extended key usage, purpose, and possibly other trust values
+ * into the old trust-flags bits. */
/* First implementation: keep it simple for testing. We can study what other
* mappings would be appropriate and add them later.. fgmr 20000724 */
@@ -562,6 +541,7 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
cert->ownSlot = PR_TRUE;
}
+ if(! pk11_HandleTrustObject(slot, cert, trust) ) {
if (cert->trust == NULL) {
unsigned int type;
@@ -572,14 +552,6 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
PORT_Memset(trust,0, sizeof(CERTCertTrust));
cert->trust = trust;
/* build some cert trust flags */
-
- /* First, see if there's a trust object for this cert. */
- /* For the first implementation, we'll just check this slot
- * and worry about overriding trust info later. */
- if( pk11_HandleTrustObject(slot, cert, trust) ) {
- ;
- } else
-
if (CERT_IsCACert(cert, &type)) {
unsigned int trustflags = CERTDB_VALID_CA;
@@ -612,6 +584,7 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
} else {
trust = cert->trust;
}
+ }
if (PK11_IsUserCert(slot,cert,certID)) {
trust->sslFlags |= CERTDB_USER;
@@ -619,29 +592,6 @@ PK11_MakeCertFromHandle(PK11SlotInfo *slot,CK_OBJECT_HANDLE certID,
/* trust->objectSigningFlags |= CERTDB_USER; */
}
-
- /* if fortezza, write the root cert to the DB */
- if ((isFortezzaRootCA) && (!cert->isperm)) {
- char *name = NULL;
- if (swapNickname) {
- nickname = cert->nickname;
- cert->nickname = cert->dbnickname;
- }
- if (cert->nickname) {
- name = PORT_Strdup(cert->nickname);
- }
- if (name == NULL) name = CERT_MakeCANickname(cert);
- CERT_AddTempCertToPerm(cert,name,cert->trust);
- if (name) PORT_Free(name);
- if (swapNickname) {
- if (cert->nickname != NULL) {
- cert->dbnickname = cert->nickname;
- }
- cert->nickname = PORT_ArenaStrdup(cert->arena,nickname);
- }
-
- }
-
return cert;
loser:
@@ -663,7 +613,7 @@ PK11_GetCertFromPrivateKey(SECKEYPrivateKey *privKey)
SECStatus rv;
CERTCertificate *cert;
- if (certID == CK_INVALID_KEY) {
+ if (certID == CK_INVALID_HANDLE) {
/* couldn't find it on the card, look in our data base */
SECItem derSubject;
@@ -722,7 +672,7 @@ PK11_DeleteTokenCertAndKey(CERTCertificate *cert,void *wincx)
PK11_DestroyTokenObject(cert->slot,cert->pkcs11ID);
PK11_DeleteTokenPrivateKey(privKey);
}
- if ((pubKey != CK_INVALID_KEY) && (slot != NULL)) {
+ if ((pubKey != CK_INVALID_HANDLE) && (slot != NULL)) {
PK11_DestroyTokenObject(slot,pubKey);
PK11_FreeSlot(slot);
}
@@ -774,13 +724,14 @@ PK11_NumberObjectsFor(PK11SlotInfo *slot, CK_ATTRIBUTE *findTemplate,
typedef struct pk11DoCertCallbackStr {
SECStatus(* callback)(PK11SlotInfo *slot, CERTCertificate*, void *);
SECStatus(* noslotcallback)(CERTCertificate*, void *);
+ SECStatus(* itemcallback)(CERTCertificate*, SECItem *, void *);
void *callbackArg;
} pk11DoCertCallback;
/*
* callback to map object handles to certificate structures.
*/
-SECStatus
+static SECStatus
pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg)
{
CERTCertificate *cert;
@@ -799,6 +750,9 @@ pk11_DoCerts(PK11SlotInfo *slot, CK_OBJECT_HANDLE certID, void *arg)
if (certcb->noslotcallback) {
(*certcb->noslotcallback)(cert, certcb->callbackArg);
}
+ if (certcb->itemcallback) {
+ (*certcb->itemcallback)(cert, NULL, certcb->callbackArg);
+ }
}
CERT_DestroyCertificate(cert);
@@ -884,191 +838,25 @@ typedef struct pk11CertCallbackStr {
void *callbackArg;
} pk11CertCallback;
-static SECStatus
-pk11_SaveCert(PK11SlotInfo *slot, CERTCertificate *cert, void *arg)
-{
- pk11CertCallback *certcb = (pk11CertCallback *)arg;
- SECStatus rv = SECSuccess;
-
- if (slot->cert_count == slot->array_size) return CKR_OK;
-
- slot->cert_array[slot->cert_count] = CERT_DupCertificate(cert);
- if (slot->cert_array[slot->cert_count] == NULL) {
- return SECFailure;
- }
- /* now the slot has a hold of the cert, free the slot's element in the
- * cert.. */
- if (cert->ownSlot && (slot == cert->slot)) {
- PK11_FreeSlot(cert->slot);
- cert->ownSlot = PR_FALSE;
- }
- slot->cert_count++;
-
- if (certcb->callback) {
- rv = (*certcb->callback)(cert, NULL, certcb->callbackArg);
- }
- return rv;
-}
-
-
-/* free the slots */
-void
-PK11_FreeSlotCerts(PK11SlotInfo *slot)
-{
- int i;
-
- if (slot->cert_array) {
- for (i=0; i < slot->cert_count; i++) {
- /* if we point the cert on our array, the cert doesn't have a
- * reference to use (otherwise you would never be able to free
- * a slot :) */
- if ((slot->cert_array[i]->slot == slot) &&
- (!slot->cert_array[i]->ownSlot)) {
- slot->cert_array[i]->slot = NULL;
- }
- CERT_DestroyCertificate(slot->cert_array[i]);
- }
- PORT_Free(slot->cert_array);
- slot->cert_array = NULL;
- slot->cert_count = 0;
- }
- return;
-}
-
-/*
- * Update PQG parameters for all the certs on a slot.
- */
-static SECStatus
-pk11_UpdateSlotPQG(PK11SlotInfo *slot)
-{
- int i, tag;
- CERTCertificate * cert;
- SECOidData *oid;
- SECStatus rv1 = SECSuccess;
- SECStatus rv2 = SECSuccess;
-
- if (slot->cert_array) {
- for (i=0; i < slot->cert_count; i++) {
-
- cert = slot->cert_array[i];
-
- oid = SECOID_FindOID(&cert->subjectPublicKeyInfo.algorithm.algorithm);
-
- if (oid != NULL) {
- tag = oid->offset;
-
- /* Check if cert has a DSA or Fortezza public key */
- if ( (tag == SEC_OID_MISSI_KEA_DSS_OLD) ||
- (tag == SEC_OID_MISSI_DSS_OLD) ||
- (tag == SEC_OID_MISSI_KEA_DSS) ||
- (tag == SEC_OID_MISSI_DSS) ||
- (tag == SEC_OID_ANSIX9_DSA_SIGNATURE) ||
- (tag == SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST) ||
- (tag == SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST) ) {
-
- /* update PQG parameters */
-
- rv1 = SECKEY_UpdateCertPQG(cert);
- if (rv1 == SECFailure) {
- rv2 = rv1;
- }
- }
- } /* end of if oid != NULL */
- } /* end of for loop */
- }
- return rv2;
-}
-
-
-/*
- * Extract all the certs on a card from a slot.
- */
-static SECStatus
-pk11_ExtractCertsFromSlot(PK11SlotInfo *slot, void *arg)
-{
- pk11TraverseSlot *slotcb = (pk11TraverseSlot*) arg;
- int object_count;
- SECStatus rv;
-
- rv = SECSuccess;
-
- PK11_FreeSlotCerts(slot);
-
- object_count = PK11_NumberObjectsFor(slot,slotcb->findTemplate,
- slotcb->templateCount);
-
- /*Actually this isn't a failure... there just were no certs to be found*/
- if (object_count == 0) {
- return SECSuccess;
- }
-
- slot->cert_array = (CERTCertificate **)
- PORT_Alloc(sizeof(CERTCertificate *)*object_count);
- if (slot->cert_array == NULL) {
- return SECFailure;
- }
- slot->cert_count = 0;
- slot->array_size = object_count;
- PK11_TraverseSlot(slot,arg);
-
- /* Update the PQG parameters for the extracted certs. */
- rv = pk11_UpdateSlotPQG(slot);
-
- return rv;
-}
-
-/*
- * read all the certs from a slot
- */
-SECStatus
-PK11_ReadSlotCerts(PK11SlotInfo *slot)
-{
-
- /* build slot list */
- pk11CertCallback caller;
- pk11DoCertCallback saver;
- pk11TraverseSlot creater;
- CK_ATTRIBUTE theTemplate;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
-
- PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass));
-
- caller.callback = NULL;
- caller.callbackArg = NULL;
- saver.callback = pk11_SaveCert;
- saver.noslotcallback = NULL;
- saver.callbackArg = (void *) & caller;
- creater.callback = pk11_DoCerts;
- creater.callbackArg = (void *) & saver;
- creater.findTemplate = &theTemplate;
- creater.templateCount = 1;
-
- return pk11_ExtractCertsFromSlot(slot, &creater);
-}
-
/*
* Extract all the certs on a card from a slot.
*/
static SECStatus
-pk11_TraverseAllSlots(PRBool loadCerts,
- SECStatus (*callback)(PK11SlotInfo *,void *),void *arg,void *wincx) {
+pk11_TraverseAllSlots( SECStatus (*callback)(PK11SlotInfo *,void *),
+ void *arg,void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
SECStatus rv;
/* get them all! */
- list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,loadCerts,wincx);
+ list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_FALSE,wincx);
if (list == NULL) return SECFailure;
/* look at each slot and authenticate as necessary */
for (le = list->head ; le; le = le->next) {
- /* don't nab internal slots */
- if ((!loadCerts) && le->slot->isInternal == PR_TRUE) {
- continue;
- }
- if (loadCerts || !PK11_IsFriendly(le->slot)) {
- rv = PK11_Authenticate(le->slot, loadCerts, wincx);
+ if (!PK11_IsFriendly(le->slot)) {
+ rv = PK11_Authenticate(le->slot, PR_FALSE, wincx);
if (rv != SECSuccess) continue;
}
(*callback)(le->slot,arg);
@@ -1085,26 +873,23 @@ pk11_TraverseAllSlots(PRBool loadCerts,
SECStatus
PK11_TraverseSlotCerts(SECStatus(* callback)(CERTCertificate*,SECItem *,void *),
void *arg, void *wincx) {
- pk11CertCallback caller;
- pk11DoCertCallback saver;
+ pk11DoCertCallback caller;
pk11TraverseSlot creater;
CK_ATTRIBUTE theTemplate;
CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
PK11_SETATTRS(&theTemplate, CKA_CLASS, &certClass, sizeof(certClass));
- caller.callback = callback;
+ caller.callback = NULL;
+ caller.noslotcallback = NULL;
+ caller.itemcallback = callback;
caller.callbackArg = arg;
- saver.callback = pk11_SaveCert;
- saver.noslotcallback = NULL;
- saver.callbackArg = (void *) & caller;
creater.callback = pk11_DoCerts;
- creater.callbackArg = (void *) & saver;
+ creater.callbackArg = (void *) & caller;
creater.findTemplate = &theTemplate;
creater.templateCount = 1;
- return pk11_TraverseAllSlots(PR_FALSE, pk11_ExtractCertsFromSlot,
- &creater, wincx);
+ return pk11_TraverseAllSlots(PK11_TraverseSlot, &creater, wincx);
}
/***********************************************************************
@@ -1186,7 +971,7 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
*slotptr = slot = PK11_GetInternalKeySlot();
}
if (slot == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
if (!PK11_IsFriendly(slot)) {
@@ -1194,7 +979,7 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
if (rv != SECSuccess) {
PK11_FreeSlot(slot);
*slotptr = NULL;
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
}
@@ -1229,7 +1014,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
CKO_CERTIFICATE, &count, wincx);
CERTCertificate *cert;
- if (certID == CK_INVALID_KEY) return NULL;
+ if (certID == CK_INVALID_HANDLE) return NULL;
cert = PK11_MakeCertFromHandle(slot,certID[0],NULL);
PK11_FreeSlot(slot);
PORT_Free(certID);
@@ -1481,7 +1266,7 @@ pk11_getcerthandle(PK11SlotInfo *slot, CERTCertificate *cert,
if (cert->slot == slot) {
certh = cert->pkcs11ID;
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
certh = pk11_FindObjectByTemplate(slot,theTemplate,tsize);
cert->pkcs11ID = certh;
}
@@ -1522,11 +1307,11 @@ PK11_FindPrivateKeyFromCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
return NULL;
}
keyh = PK11_MatchItem(slot,certh,CKO_PRIVATE_KEY);
- if (keyh == CK_INVALID_KEY) { return NULL; }
+ if (keyh == CK_INVALID_HANDLE) { return NULL; }
return PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyh, wincx);
}
@@ -1580,7 +1365,7 @@ PK11_KeyForCertExists(CERTCertificate *cert, CK_OBJECT_HANDLE *keyPtr,
if (rv != SECSuccess) continue;
key = pk11_FindPrivateKeyFromCertID(le->slot,keyID);
- if (key != CK_INVALID_KEY) {
+ if (key != CK_INVALID_HANDLE) {
slot = PK11_ReferenceSlot(le->slot);
if (keyPtr) *keyPtr = key;
break;
@@ -1602,8 +1387,7 @@ PK11_KeyForDERCertExists(SECItem *derCert, CK_OBJECT_HANDLE *keyPtr,
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return NULL;
slot = PK11_KeyForCertExists(cert, keyPtr, wincx);
@@ -1635,8 +1419,7 @@ PK11_ImportDERCertForKey(SECItem *derCert, char *nickname,void *wincx) {
CERTCertificate *cert;
PK11SlotInfo *slot = NULL;
- cert = CERT_NewTempCertificate(CERT_GetDefaultCertDB(), derCert, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
if (cert == NULL) return NULL;
slot = PK11_ImportCertForKey(cert, nickname, wincx);
@@ -1649,7 +1432,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
CK_ATTRIBUTE *searchTemplate, int count, void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
PK11SlotInfo *slot = NULL;
SECStatus rv;
@@ -1659,7 +1442,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
if (list == NULL) {
if (list) PK11_FreeSlotList(list);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
@@ -1671,7 +1454,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
}
certHandle = pk11_FindObjectByTemplate(le->slot,searchTemplate,count);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
slot = PK11_ReferenceSlot(le->slot);
break;
}
@@ -1680,7 +1463,7 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
PK11_FreeSlotList(list);
if (slot == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
*slotPtr = slot;
return certHandle;
@@ -1729,7 +1512,7 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
ri->id.issuerAndSN->serialNumber.data,ri->id.issuerAndSN->serialNumber.len);
certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
CERTCertificate *cert = pk11_fastCert(slot,certHandle,NULL,NULL);
if (PK11_IsUserCert(slot,cert,certHandle)) {
/* we've found a cert handle, now let's see if there is a key
@@ -1744,7 +1527,7 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
}
}
*rlIndex = -1;
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/*
@@ -1758,14 +1541,14 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
{
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
SECStatus rv;
/* get them all! */
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
if (list == NULL) {
if (list) PK11_FreeSlotList(list);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/* Look for the slot that holds the Key */
@@ -1776,13 +1559,13 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
}
certHandle = pk11_FindCertObjectByRecipientNew(le->slot, recipientlist, rlIndex);
- if (certHandle != CK_INVALID_KEY)
+ if (certHandle != CK_INVALID_HANDLE)
break;
}
PK11_FreeSlotList(list);
- return (le == NULL) ? CK_INVALID_KEY : certHandle;
+ return (le == NULL) ? CK_INVALID_HANDLE : certHandle;
}
/*
@@ -1822,7 +1605,7 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
ri->issuerAndSN->serialNumber.data,ri->issuerAndSN->serialNumber.len);
certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
CERTCertificate *cert = pk11_fastCert(slot,certHandle,NULL,NULL);
if (PK11_IsUserCert(slot,cert,certHandle)) {
/* we've found a cert handle, now let's see if there is a key
@@ -1836,7 +1619,7 @@ pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
}
}
*rip = NULL;
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
/*
@@ -1848,7 +1631,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
PK11SlotInfo *slot = NULL;
SECStatus rv;
@@ -1858,7 +1641,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,PR_FALSE,PR_TRUE,wincx);
if (list == NULL) {
if (list) PK11_FreeSlotList(list);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
*rip = NULL;
@@ -1872,7 +1655,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
certHandle = pk11_FindCertObjectByRecipient(le->slot,
recipientArray,rip);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
slot = PK11_ReferenceSlot(le->slot);
break;
}
@@ -1881,7 +1664,7 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
PK11_FreeSlotList(list);
if (slot == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
*slotPtr = slot;
return certHandle;
@@ -1899,14 +1682,14 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
SEC_PKCS7RecipientInfo **array, SEC_PKCS7RecipientInfo **rip,
SECKEYPrivateKey**privKey, void *wincx)
{
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
- CK_OBJECT_HANDLE keyHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE keyHandle = CK_INVALID_HANDLE;
CERTCertificate *cert = NULL;
SECStatus rv;
*privKey = NULL;
certHandle = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
@@ -1918,7 +1701,7 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
}
keyHandle = PK11_MatchItem(*slotPtr,certHandle,CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(*slotPtr);
*slotPtr = NULL;
return NULL;
@@ -1949,13 +1732,13 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
int
PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx)
{
- CK_OBJECT_HANDLE certHandle = CK_INVALID_KEY;
- CK_OBJECT_HANDLE keyHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE keyHandle = CK_INVALID_HANDLE;
NSSCMSRecipient *rl;
int rlIndex;
certHandle = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return -1;
}
@@ -1972,7 +1755,7 @@ PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *win
/* try to get a private key handle for the cert we found */
keyHandle = PK11_MatchItem(rl->slot, certHandle, CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(rl->slot);
rl->slot = NULL;
return -1;
@@ -2003,13 +1786,16 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
{
CK_OBJECT_HANDLE certHandle;
CERTCertificate *cert = NULL;
+ CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
CK_ATTRIBUTE searchTemplate[] = {
+ { CKA_CLASS, NULL, 0 },
{ CKA_ISSUER, NULL, 0 },
{ CKA_SERIAL_NUMBER, NULL, 0}
};
int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE);
CK_ATTRIBUTE *attrs = searchTemplate;
+ PK11_SETATTRS(attrs, CKA_CLASS, &certClass, sizeof(certClass)); attrs++;
PK11_SETATTRS(attrs, CKA_ISSUER, issuerSN->derIssuer.data,
issuerSN->derIssuer.len); attrs++;
PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER, issuerSN->serialNumber.data,
@@ -2017,7 +1803,7 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN,
certHandle = pk11_FindCertObjectByTemplate
(slotPtr,searchTemplate,count,wincx);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
cert = PK11_MakeCertFromHandle(*slotPtr,certHandle,NULL);
@@ -2039,14 +1825,14 @@ PK11_FindObjectForCert(CERTCertificate *cert, void *wincx, PK11SlotInfo **pSlot)
if (cert->slot) {
certHandle = pk11_getcerthandle(cert->slot,cert,&searchTemplate,1);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
*pSlot = PK11_ReferenceSlot(cert->slot);
return certHandle;
}
}
certHandle = pk11_FindCertObjectByTemplate(pSlot,&searchTemplate,1,wincx);
- if (certHandle != CK_INVALID_KEY) {
+ if (certHandle != CK_INVALID_HANDLE) {
if (cert->slot == NULL) {
cert->slot = PK11_ReferenceSlot(*pSlot);
cert->pkcs11ID = certHandle;
@@ -2067,7 +1853,7 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
SECStatus rv;
certHandle = PK11_FindObjectForCert(cert, wincx, &slot);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
@@ -2076,7 +1862,7 @@ PK11_FindKeyByAnyCert(CERTCertificate *cert, void *wincx)
return NULL;
}
keyHandle = PK11_MatchItem(slot,certHandle,CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(slot);
return NULL;
}
@@ -2092,13 +1878,13 @@ pk11_FindPubKeyByAnyCert(CERTCertificate *cert, PK11SlotInfo **slot, void *wincx
CK_OBJECT_HANDLE keyHandle;
certHandle = PK11_FindObjectForCert(cert, wincx, slot);
- if (certHandle == CK_INVALID_KEY) {
- return CK_INVALID_KEY;
+ if (certHandle == CK_INVALID_HANDLE) {
+ return CK_INVALID_HANDLE;
}
keyHandle = PK11_MatchItem(*slot,certHandle,CKO_PUBLIC_KEY);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
PK11_FreeSlot(*slot);
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
return keyHandle;
}
@@ -2110,7 +1896,7 @@ PK11_FindKeyByKeyID(PK11SlotInfo *slot, SECItem *keyID, void *wincx)
SECKEYPrivateKey *privKey;
keyHandle = pk11_FindPrivateKeyFromCertID(slot, keyID);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
return NULL;
}
privKey = PK11_MakePrivKey(slot, nullKey, PR_TRUE, keyHandle, wincx);
@@ -2134,8 +1920,18 @@ PK11_NumberCertsForCertSubject(CERTCertificate *cert)
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
- if ((cert->slot == NULL) || (cert->slot->isInternal)) {
- return 0;
+ if (cert->slot == NULL) {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+ int count = 0;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ count += PK11_NumberObjectsFor(le->slot,theTemplate,templateSize);
+ }
+ PK11_FreeSlotList(list);
+ return count;
}
return PK11_NumberObjectsFor(cert->slot,theTemplate,templateSize);
@@ -2151,6 +1947,19 @@ PK11_TraverseCertsForSubject(CERTCertificate *cert,
if(!cert) {
return SECFailure;
}
+ if (cert->slot == NULL) {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ PK11_TraverseCertsForSubjectInSlot(cert,le->slot,callback,arg);
+ }
+ PK11_FreeSlotList(list);
+ return SECSuccess;
+
+ }
return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
}
@@ -2172,11 +1981,12 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_SUBJECT,cert->derSubject.data,cert->derSubject.len);
- if ((slot == NULL) || (slot->isInternal)) {
+ if (slot == NULL) {
return SECSuccess;
}
caller.noslotcallback = callback;
caller.callback = NULL;
+ caller.itemcallback = NULL;
caller.callbackArg = arg;
callarg.callback = pk11_DoCerts;
callarg.callbackArg = (void *) & caller;
@@ -2207,12 +2017,13 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
PK11_SETATTRS(attr,CKA_CLASS, &certClass, sizeof(certClass)); attr++;
PK11_SETATTRS(attr,CKA_LABEL,nickname->data,nickname->len);
- if ((slot == NULL) || (slot->isInternal)) {
+ if (slot == NULL) {
return SECSuccess;
}
caller.noslotcallback = callback;
caller.callback = NULL;
+ caller.itemcallback = NULL;
caller.callbackArg = arg;
callarg.callback = pk11_DoCerts;
callarg.callbackArg = (void *) & caller;
@@ -2243,6 +2054,7 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
caller.noslotcallback = callback;
caller.callback = NULL;
+ caller.itemcallback = NULL;
caller.callbackArg = arg;
callarg.callback = pk11_DoCerts;
callarg.callbackArg = (void *) & caller;
@@ -2283,7 +2095,7 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
return NULL;
}
return PK11_MakeCertFromHandle(slot, certh, NULL);
@@ -2323,7 +2135,7 @@ PK11_FindCertFromDERSubjectAndNickname(PK11SlotInfo *slot,
}
certh = pk11_getcerthandle(slot,cert,theTemplate,tsize);
- if (certh == CK_INVALID_KEY) {
+ if (certh == CK_INVALID_HANDLE) {
return NULL;
}
@@ -2343,15 +2155,15 @@ pk11_findKeyObjectByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
SECStatus rv;
if((slot == NULL) || (cert == NULL)) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
keyID = pk11_mkcertKeyID(cert);
if(keyID == NULL) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
- key = CK_INVALID_KEY;
+ key = CK_INVALID_HANDLE;
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
if (rv != SECSuccess) goto loser;
@@ -2374,7 +2186,7 @@ PK11_FindKeyByDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
return NULL;
}
@@ -2393,7 +2205,7 @@ PK11_ImportCertForKeyToSlot(PK11SlotInfo *slot, CERTCertificate *cert,
}
keyHandle = pk11_findKeyObjectByDERCert(slot, cert, wincx);
- if (keyHandle == CK_INVALID_KEY) {
+ if (keyHandle == CK_INVALID_HANDLE) {
return SECFailure;
}
@@ -2548,7 +2360,7 @@ PK11_FindCertInSlot(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx)
*/
rv = PK11_Authenticate(slot, PR_TRUE, wincx);
if (rv != SECSuccess) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
return pk11_getcerthandle(slot,cert,theTemplate,tsize);
@@ -2567,7 +2379,7 @@ PK11_GetKeyIDFromCert(CERTCertificate *cert, void *wincx)
CK_RV crv;
handle = PK11_FindObjectForCert(cert,wincx,&slot);
- if (handle == CK_INVALID_KEY) {
+ if (handle == CK_INVALID_HANDLE) {
goto loser;
}
@@ -2716,9 +2528,6 @@ PK11_ListCerts(PK11CertListType type, void *pwarg)
listCerts.type = type;
listCerts.certList = certList;
- SEC_TraversePermCerts(CERT_GetDefaultCertDB(),pk11ListCertCallback,
- &listCerts);
-
PK11_TraverseSlotCerts(pk11ListCertCallback,&listCerts,pwarg);
if (CERT_LIST_HEAD(certList) == NULL) {
@@ -2783,13 +2592,13 @@ PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
certHandle = pk11_getcerthandle(slot,cert,theTemplate,tsize);
} else {
certHandle = PK11_FindObjectForCert(cert, wincx, &slotRef);
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return pk11_mkcertKeyID(cert);
}
slot = slotRef;
}
- if (certHandle == CK_INVALID_KEY) {
+ if (certHandle == CK_INVALID_HANDLE) {
return NULL;
}
@@ -2860,3 +2669,149 @@ PK11_ListPrivateKeysInSlot(PK11SlotInfo *slot)
return keys;
}
+/*
+ * return the certificate associated with a derCert
+ */
+SECItem *
+PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
+ SECItem *name, int type)
+{
+ CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE theTemplate[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_KRL, NULL, 0 },
+ };
+ CK_ATTRIBUTE crlData = { CKA_VALUE, NULL, 0 };
+ /* if you change the array, change the variable below as well */
+ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_BBOOL ck_false = CK_FALSE;
+ CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE;
+ CK_ATTRIBUTE *attrs = theTemplate;
+ CK_RV crv;
+ SECStatus rv;
+ SECItem *derCrl = NULL;
+
+ PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ?
+ &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++;
+
+ if (*slot) {
+ crlh = pk11_FindObjectByTemplate(*slot,theTemplate,tsize);
+ } else {
+ PK11SlotList *list = PK11_GetAllTokens(CKM_INVALID_MECHANISM,
+ PR_FALSE,PR_TRUE,NULL);
+ PK11SlotListElement *le;
+
+ /* loop through all the fortezza tokens */
+ for (le = list->head; le; le = le->next) {
+ crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
+ if (crlh != CK_INVALID_HANDLE) {
+ *slot = PK11_ReferenceSlot(le->slot);
+ break;
+ }
+ }
+ PK11_FreeSlotList(list);
+ }
+
+ if (crlh == CK_INVALID_HANDLE) {
+ PORT_SetError(SEC_ERROR_NO_KRL);
+ return NULL;
+ }
+ crv = PK11_GetAttributes(NULL,*slot,crlh,&crlData,1);
+ if (crv != CKR_OK) {
+ PORT_SetError(PK11_MapError (crv));
+ goto loser;
+ }
+
+ derCrl = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
+ if (derCrl == NULL) {
+ goto loser;
+ }
+
+ derCrl->data = crlData.pValue;
+ derCrl->len = crlData.ulValueLen;
+
+ if (crlHandle) {
+ *crlHandle = crlh;
+ }
+
+loser:
+ return derCrl;
+}
+
+CK_OBJECT_HANDLE
+PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
+ char *url, int type)
+{
+ CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE theTemplate[] = {
+ { CKA_SUBJECT, NULL, 0 },
+ { CKA_CLASS, NULL, 0 },
+ { CKA_NETSCAPE_KRL, NULL, 0 },
+ { CKA_NETSCAPE_URL, NULL, 0 },
+ { CKA_VALUE, NULL, 0 }
+ };
+ CK_ATTRIBUTE crlData = { CKA_VALUE, NULL, 0 };
+ /* if you change the array, change the variable below as well */
+ int tsize = sizeof(theTemplate)/sizeof(theTemplate[0]);
+ CK_BBOOL ck_true = CK_TRUE;
+ CK_BBOOL ck_false = CK_FALSE;
+ CK_OBJECT_HANDLE crlh = CK_INVALID_HANDLE;
+ CK_ATTRIBUTE *attrs = theTemplate;
+ CK_SESSION_HANDLE rwsession;
+ CK_RV crv;
+
+ PK11_SETATTRS(attrs, CKA_SUBJECT, name->data, name->len); attrs++;
+ PK11_SETATTRS(attrs, CKA_CLASS, &crlClass, sizeof(crlClass)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_KRL, (type == SEC_CRL_TYPE) ?
+ &ck_false : &ck_true, sizeof (CK_BBOOL)); attrs++;
+ PK11_SETATTRS(attrs, CKA_NETSCAPE_URL, url, PORT_Strlen(url)+1); attrs++;
+ PK11_SETATTRS(attrs, CKA_VALUE,crl->data,crl->len); attrs++;
+
+ rwsession = PK11_GetRWSession(slot);
+ if (rwsession == CK_INVALID_SESSION) {
+ PORT_SetError(SEC_ERROR_READ_ONLY);
+ return crlh;
+ }
+
+ crv = PK11_GETTAB(slot)->
+ C_CreateObject(rwsession,attrs,tsize,&crlh);
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ }
+
+ PK11_RestoreROSession(slot,rwsession);
+ return crlh;
+}
+
+
+
+/*
+ * delete a cert and it's private key (if no other certs are pointing to the
+ * private key.
+ */
+SECStatus
+SEC_DeletePermCRL(CERTSignedCrl *crl)
+{
+ PK11SlotInfo *slot = crl->slot;
+ CK_RV crv;
+
+ if (slot == NULL) {
+ /* shouldn't happen */
+ PORT_SetError( SEC_ERROR_CRL_INVALID);
+ return SECFailure;
+ }
+
+ crv = PK11_DestroyTokenObject(slot,crl->pkcs11ID);
+ if (crv != CKR_OK) {
+ PORT_SetError( PK11_MapError(crv) );
+ goto loser;
+ }
+ crl->slot = NULL;
+ PK11_FreeSlot(slot);
+loser:
+ return SECSuccess;
+}
diff --git a/security/nss/lib/pk11wrap/pk11func.h b/security/nss/lib/pk11wrap/pk11func.h
index 0a7c27812..d05e1045f 100644
--- a/security/nss/lib/pk11wrap/pk11func.h
+++ b/security/nss/lib/pk11wrap/pk11func.h
@@ -483,6 +483,14 @@ PK11_GetLowLevelKeyIDForCert(PK11SlotInfo *slot,
SECItem *
PK11_GetLowLevelKeyIDForPrivateKey(SECKEYPrivateKey *key);
+SECItem *
+PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *handle,
+ SECItem *derName, int type);
+
+CK_OBJECT_HANDLE
+PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl,
+ SECItem *name, char *url, int type);
+
SEC_END_PROTOS
#endif
diff --git a/security/nss/lib/pk11wrap/pk11kea.c b/security/nss/lib/pk11wrap/pk11kea.c
index c50b9d8b6..b5b810d0b 100644
--- a/security/nss/lib/pk11wrap/pk11kea.c
+++ b/security/nss/lib/pk11wrap/pk11kea.c
@@ -85,8 +85,8 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
/* RSA */
if (PK11_DoesMechanism(symKey->slot, CKM_RSA_PKCS) &&
PK11_DoesMechanism(slot,CKM_RSA_PKCS)) {
- CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_KEY;
- CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_KEY;
+ CK_OBJECT_HANDLE pubKeyHandle = CK_INVALID_HANDLE;
+ CK_OBJECT_HANDLE privKeyHandle = CK_INVALID_HANDLE;
SECKEYPublicKey *pubKey = NULL;
SECKEYPrivateKey *privKey = NULL;
SECItem wrapData;
@@ -95,12 +95,12 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
/* find RSA Public Key on target */
pubKeyHandle = pk11_FindRSAPubKey(slot);
- if (pubKeyHandle != CK_INVALID_KEY) {
+ if (pubKeyHandle != CK_INVALID_HANDLE) {
privKeyHandle = PK11_MatchItem(slot,pubKeyHandle,CKO_PRIVATE_KEY);
}
/* if no key exists, generate a key pair */
- if (privKeyHandle == CK_INVALID_KEY) {
+ if (privKeyHandle == CK_INVALID_HANDLE) {
unsigned int symKeyLength = PK11_GetKeyLength(symKey);
PK11RSAGenParams rsaParams;
@@ -125,7 +125,7 @@ pk11_KeyExchange(PK11SlotInfo *slot,CK_MECHANISM_TYPE type,
if (pubKey && pubKey->pkcs11Slot) {
PK11_FreeSlot(pubKey->pkcs11Slot);
pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_KEY;
+ pubKey->pkcs11ID = CK_INVALID_HANDLE;
}
}
}
diff --git a/security/nss/lib/pk11wrap/pk11pk12.c b/security/nss/lib/pk11wrap/pk11pk12.c
index df6646e04..ac34bbff5 100644
--- a/security/nss/lib/pk11wrap/pk11pk12.c
+++ b/security/nss/lib/pk11wrap/pk11pk12.c
@@ -106,9 +106,37 @@ struct SECKEYRawPrivateKeyStr {
} u;
};
typedef struct SECKEYRawPrivateKeyStr SECKEYRawPrivateKey;
-/*const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[];*/
+/* ASN1 Templates for new decoder/encoder */
+/*
+ * Attribute value for PKCS8 entries (static?)
+ */
+const SEC_ASN1Template SECKEY_AttributeTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(SECKEYAttribute) },
+ { SEC_ASN1_OBJECT_ID, offsetof(SECKEYAttribute, attrType) },
+ { SEC_ASN1_SET_OF, offsetof(SECKEYAttribute, attrValue),
+ SEC_AnyTemplate },
+ { 0 }
+};
+
+const SEC_ASN1Template SECKEY_SetOfAttributeTemplate[] = {
+ { SEC_ASN1_SET_OF, 0, SECKEY_AttributeTemplate },
+};
+
+const SEC_ASN1Template SECKEY_PrivateKeyInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYPrivateKeyInfo) },
+ { SEC_ASN1_INTEGER, offsetof(SECKEYPrivateKeyInfo,version) },
+ { SEC_ASN1_INLINE, offsetof(SECKEYPrivateKeyInfo,algorithm),
+ SECOID_AlgorithmIDTemplate },
+ { SEC_ASN1_OCTET_STRING, offsetof(SECKEYPrivateKeyInfo,privateKey) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(SECKEYPrivateKeyInfo,attributes),
+ SECKEY_SetOfAttributeTemplate },
+ { 0 }
+};
+
const SEC_ASN1Template SECKEY_RSAPrivateKeyExportTemplate[] = {
{ SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SECKEYRawPrivateKey) },
{ SEC_ASN1_INTEGER, offsetof(SECKEYRawPrivateKey,u.rsa.version) },
diff --git a/security/nss/lib/pk11wrap/pk11pqg.c b/security/nss/lib/pk11wrap/pk11pqg.c
index ef741198b..530548c36 100644
--- a/security/nss/lib/pk11wrap/pk11pqg.c
+++ b/security/nss/lib/pk11wrap/pk11pqg.c
@@ -42,7 +42,11 @@
*/
extern SECStatus
PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) {
+#ifdef notdef
return PQG_ParamGen(j, pParams, pVfy);
+#else
+ return SECFailure;
+#endif
}
/* Generate PQGParams and PQGVerify structs.
@@ -53,7 +57,11 @@ PK11_PQG_ParamGen(unsigned int j, PQGParams **pParams, PQGVerify **pVfy) {
extern SECStatus
PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
PQGParams **pParams, PQGVerify **pVfy) {
+#ifdef notdef
return PQG_ParamGenSeedLen(j, seedBytes, pParams, pVfy);
+#else
+ return SECFailure;
+#endif
}
/* Test PQGParams for validity as DSS PQG values.
@@ -85,7 +93,11 @@ PK11_PQG_ParamGenSeedLen( unsigned int j, unsigned int seedBytes,
extern SECStatus
PK11_PQG_VerifyParams(const PQGParams *params,
const PQGVerify *vfy, SECStatus *result) {
+#ifdef notdef
return PQG_VerifyParams(params, vfy, result);
+#else
+ return SECFailure;
+#endif
}
diff --git a/security/nss/lib/pk11wrap/pk11skey.c b/security/nss/lib/pk11wrap/pk11skey.c
index c036e46a0..86d418fa2 100644
--- a/security/nss/lib/pk11wrap/pk11skey.c
+++ b/security/nss/lib/pk11wrap/pk11skey.c
@@ -225,7 +225,7 @@ PK11_CreateSymKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, void *wincx)
symKey->data.data = NULL;
symKey->data.len = 0;
symKey->owner = PR_TRUE;
- symKey->objectID = CK_INVALID_KEY;
+ symKey->objectID = CK_INVALID_HANDLE;
symKey->slot = slot;
symKey->series = slot->series;
symKey->cx = wincx;
@@ -253,7 +253,7 @@ PK11_FreeSymKey(PK11SymKey *symKey)
}
PK11_USE_THREADS(PZ_Unlock(symKey->refLock);)
if (destroy) {
- if ((symKey->owner) && symKey->objectID != CK_INVALID_KEY) {
+ if ((symKey->owner) && symKey->objectID != CK_INVALID_HANDLE) {
pk11_EnterKeyMonitor(symKey);
(void) PK11_GETTAB(symKey->slot)->
C_DestroyObject(symKey->session, symKey->objectID);
@@ -301,7 +301,7 @@ PK11_SymKeyFromHandle(PK11SlotInfo *slot, PK11SymKey *parent, PK11Origin origin,
{
PK11SymKey *symKey;
- if (keyID == CK_INVALID_KEY) {
+ if (keyID == CK_INVALID_HANDLE) {
return NULL;
}
@@ -338,7 +338,7 @@ PK11_GetWrapKey(PK11SlotInfo *slot, int wrap, CK_MECHANISM_TYPE type,
PK11SymKey *symKey = NULL;
if (slot->series != series) return NULL;
- if (slot->refKeys[wrap] == CK_INVALID_KEY) return NULL;
+ if (slot->refKeys[wrap] == CK_INVALID_HANDLE) return NULL;
if (type == CKM_INVALID_MECHANISM) type = slot->wrapMechanism;
symKey = PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive,
@@ -535,7 +535,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
/* what about fortezza??? */
default:
PORT_SetError( SEC_ERROR_BAD_KEY );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
templateCount = attrs - theTemplate;
@@ -547,7 +547,7 @@ PK11_ImportPublicKey(PK11SlotInfo *slot, SECKEYPublicKey *pubKey,
rv = PK11_CreateNewObject(slot, CK_INVALID_SESSION, theTemplate,
templateCount, isToken, &objectID);
if ( rv != SECSuccess) {
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
}
@@ -588,7 +588,7 @@ PK11_FindFixedKey(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *keyID,
PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
key_id = pk11_FindObjectByTemplate(slot,findTemp,tsize);
- if (key_id == CK_INVALID_KEY) {
+ if (key_id == CK_INVALID_HANDLE) {
return NULL;
}
return PK11_SymKeyFromHandle(slot, NULL, PK11_OriginDerive, type, key_id,
@@ -1140,7 +1140,7 @@ PK11_CopyKey(PK11SlotInfo *slot, CK_OBJECT_HANDLE srcObject)
PK11_ExitSlotMonitor(slot);
if (crv == CKR_OK) return destObject;
PORT_SetError( PK11_MapError(crv) );
- return CK_INVALID_KEY;
+ return CK_INVALID_HANDLE;
}
@@ -1374,7 +1374,7 @@ pk11_PairwiseConsistencyCheck(SECKEYPublicKey *pubKey,
}
id = PK11_ImportPublicKey(slot,pubKey,PR_FALSE);
- if (id == CK_INVALID_KEY) {
+ if (id == CK_INVALID_HANDLE) {
PK11_FreeSlot(slot);
return SECFailure;
}
@@ -1702,7 +1702,7 @@ pk11_loadPrivKey(PK11SlotInfo *slot,SECKEYPrivateKey *privKey,
if (pubKey->pkcs11Slot) {
PK11_FreeSlot(pubKey->pkcs11Slot);
pubKey->pkcs11Slot = NULL;
- pubKey->pkcs11ID = CK_INVALID_KEY;
+ pubKey->pkcs11ID = CK_INVALID_HANDLE;
}
}
@@ -2491,7 +2491,7 @@ PK11_MakeKEAPubKey(unsigned char *keyData,int length)
pubk->arena = arena;
pubk->pkcs11Slot = 0;
- pubk->pkcs11ID = CK_INVALID_KEY;
+ pubk->pkcs11ID = CK_INVALID_HANDLE;
pubk->keyType = fortezzaKey;
rv = SECITEM_CopyItem(arena, &pubk->u.fortezza.KEAKey, &pkData);
if (rv != SECSuccess) {
@@ -3226,7 +3226,7 @@ pk11_restoreContext(PK11Context *context,void *space, unsigned long savedLength)
{
CK_RV crv;
CK_OBJECT_HANDLE objectID = (context->key) ? context->key->objectID:
- CK_INVALID_KEY;
+ CK_INVALID_HANDLE;
PORT_Assert(space != NULL);
if (space == NULL) {
@@ -4096,9 +4096,10 @@ PK11_DestroyPBEParams(SECItem *params)
SECAlgorithmID *
PK11_CreatePBEAlgorithmID(SECOidTag algorithm, int iteration, SECItem *salt)
{
- SECAlgorithmID *algid;
-
+ SECAlgorithmID *algid = NULL;
+#ifdef notdef
algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, iteration);
+#endif
return algid;
}
@@ -4372,7 +4373,9 @@ PK11_ExportEncryptedPrivateKeyInfo(PK11SlotInfo *slot, SECOidTag algTag,
goto loser;
}
epki->arena = arena;
+#ifdef notdef
algid = SEC_PKCS5CreateAlgorithmID(algTag, NULL, iteration);
+#endif
if(algid == NULL) {
rv = SECFailure;
goto loser;
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index f468c217b..b2ade4304 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -50,8 +50,6 @@
#include "prlong.h"
#include "secerr.h"
#include "secpkcs5.h"
-#define NSSCKT_H /* we included pkcs11t.h, so block ckt.h from including nssckt.h */
-#include "ckt.h"
/*************************************************************
@@ -419,7 +417,7 @@ PK11_NewSlotInfo(void)
slot->series = 0;
slot->wrapKey = 0;
slot->wrapMechanism = CKM_INVALID_MECHANISM;
- slot->refKeys[0] = CK_INVALID_KEY;
+ slot->refKeys[0] = CK_INVALID_HANDLE;
slot->reason = PK11_DIS_NONE;
slot->readOnly = PR_TRUE;
slot->needLogin = PR_FALSE;
@@ -467,9 +465,6 @@ PK11_DestroySlot(PK11SlotInfo *slot)
PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
}
- /* now free up all the certificates we grabbed on this slot */
- PK11_FreeSlotCerts(slot);
-
/* free up the cached keys and sessions */
PK11_CleanKeyList(slot);
@@ -1082,9 +1077,6 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
if (rv != SECWouldBlock) break;
}
if (rv == SECSuccess) {
- if ((loadCerts) && (!slot->isInternal) && (slot->cert_count == 0)) {
- PK11_ReadSlotCerts(slot);
- }
rv = pk11_CheckVerifyTest(slot);
} else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);
return rv;
@@ -1715,14 +1707,6 @@ PK11_InitToken(PK11SlotInfo *slot, PRBool loadCerts)
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
}
- /*if we have cached slotcerts, free them they are almost certainly stale*/
- PK11_FreeSlotCerts(slot);
-
- if (loadCerts && (!slot->isInternal) &&
- ((!slot->needLogin) || (slot->defaultFlags & SECMOD_FRIENDLY_FLAG))) {
- PK11_ReadSlotCerts(slot);
- }
-
if (!(slot->needLogin)) {
return pk11_CheckVerifyTest(slot);
}
@@ -1783,7 +1767,7 @@ pk11_isRootSlot(PK11SlotInfo *slot)
PORT_Assert(tsize <= sizeof(findTemp)/sizeof(CK_ATTRIBUTE));
handle = pk11_FindObjectByTemplate(slot,findTemp,tsize);
- if (handle == CK_INVALID_KEY) {
+ if (handle == CK_INVALID_HANDLE) {
return PR_FALSE;
}
return PR_TRUE;
@@ -1891,7 +1875,6 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
PK11_GETTAB(slot)->C_CloseSession(slot->session);
slot->session = CK_INVALID_SESSION;
/* force certs to be freed */
- PK11_FreeSlotCerts(slot);
}
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
return PR_FALSE;
@@ -1904,7 +1887,6 @@ pk11_IsPresentCertLoad(PK11SlotInfo *slot, PRBool loadCerts)
if (crv != CKR_OK) {
PK11_GETTAB(slot)->C_CloseSession(slot->session);
slot->session = CK_INVALID_SESSION;
- PK11_FreeSlotCerts(slot);
}
}
if (!slot->isThreadSafe) PK11_ExitSlotMonitor(slot);
@@ -3341,6 +3323,7 @@ static unsigned long rc2_unmap(unsigned long x)
SECStatus
pk11_pbe_decode(SECAlgorithmID *algid, SECItem *mech)
{
+#ifdef notdef
CK_PBE_PARAMS *pbe_params = NULL;
SEC_PKCS5PBEParameter *p5_param;
SECItem *p5_misc = NULL;
@@ -3385,6 +3368,7 @@ loser:
}
PORT_Free(pbe_params);
SEC_PKCS5DestroyPBEParameter(p5_param);
+#endif
return SECFailure;
}
@@ -4285,7 +4269,6 @@ PK11_ResetToken(PK11SlotInfo *slot, char *sso_pwd)
/* first shutdown the token. Existing sessions will get closed here */
PK11_GETTAB(slot)->C_CloseAllSessions(slot->slotID);
slot->session = CK_INVALID_SESSION;
- PK11_FreeSlotCerts(slot);
/* now re-init the token */
crv = PK11_GETTAB(slot)->C_InitToken(slot->slotID,
@@ -4357,6 +4340,7 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
SECAlgorithmID temp_algid;
SECItem param, *iv;
+#ifdef notdef
if((pPBEMechanism == CK_NULL_PTR) || (pCryptoMechanism == CK_NULL_PTR)) {
return CKR_HOST_MEMORY;
}
@@ -4392,6 +4376,7 @@ PK11_MapPBEMechanismToCryptoMechanism(CK_MECHANISM_PTR pPBEMechanism,
}
}
}
+#endif
switch(pPBEMechanism->mechanism) {
case CKM_PBE_MD2_DES_CBC:
diff --git a/security/nss/lib/pk11wrap/secmodt.h b/security/nss/lib/pk11wrap/secmodt.h
index b36350ae6..de2ae10f3 100644
--- a/security/nss/lib/pk11wrap/secmodt.h
+++ b/security/nss/lib/pk11wrap/secmodt.h
@@ -162,8 +162,6 @@ struct PK11DefaultArrayEntryStr {
#define CKM_FAKE_RANDOM 0x80000efeL
#define CKM_INVALID_MECHANISM 0xffffffffL
#define CKA_DIGEST 0x81000000L
-#define CK_INVALID_KEY 0
-#define CK_INVALID_SESSION 0
/* Cryptographic module types */
#define SECMOD_EXTERNAL 0 /* external module */
@@ -206,11 +204,11 @@ typedef PRBool (*PK11IsLoggedInFunc)(PK11SlotInfo *slot, void *arg);
/*
** Attributes
*/
-struct SECKEYPrivAttributeStr {
+struct SECKEYAttributeStr {
SECItem attrType;
SECItem **attrValue;
};
-typedef struct SECKEYPrivAttributeStr SECKEYPrivAttribute;
+typedef struct SECKEYAttributeStr SECKEYAttribute;
/*
** A PKCS#8 private key info object
@@ -220,10 +218,9 @@ struct SECKEYPrivateKeyInfoStr {
SECItem version;
SECAlgorithmID algorithm;
SECItem privateKey;
- SECKEYPrivAttribute **attributes;
+ SECKEYAttribute **attributes;
};
typedef struct SECKEYPrivateKeyInfoStr SECKEYPrivateKeyInfo;
-#define SEC_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
/*
** A PKCS#8 private key info object
diff --git a/security/nss/lib/pk11wrap/secmodti.h b/security/nss/lib/pk11wrap/secmodti.h
index 789e63da1..beed44ed2 100644
--- a/security/nss/lib/pk11wrap/secmodti.h
+++ b/security/nss/lib/pk11wrap/secmodti.h
@@ -35,9 +35,12 @@
* pkcs11 specific client and server files.
*/
+#ifndef _SECMODTI_H_
+#define _SECMODTI_H_ 1
#include "prmon.h"
#include "prtypes.h"
#include "nssilckt.h"
+#include "pk11init.h"
/* internal data structures */
@@ -109,9 +112,7 @@ struct PK11SlotInfoStr {
* token */
int mechanismCount;
/* cache the certificates stored on the token of this slot */
-#ifdef HACK_IT /*!!! */
CERTCertificate **cert_array;
-#endif
int array_size;
int cert_count;
char serial[16];
@@ -125,29 +126,6 @@ struct PK11SlotInfoStr {
CK_FLAGS RSAInfoFlags;
};
-/* hold slot default flags until we initialize a slot. This structure is only
- * useful between the time we define a module (either by hand or from the
- * database) and the time the module is loaded. Not reference counted */
-struct PK11PreSlotInfoStr {
- CK_SLOT_ID slotID; /* slot these flags are for */
- unsigned long defaultFlags; /* bit mask of default implementation this slot
- * provides */
- int askpw; /* slot specific password bits */
- long timeout; /* slot specific timeout value */
- char hasRootCerts; /* is this the root cert PKCS #11 module? */
- char hasRootTrust; /* is this the root cert PKCS #11 module? */
-};
-
-#define SECMOD_SLOT_FLAGS "slotFlags=[RSA,DSA,DH,RC2,RC4,DES,RANDOM,SHA1,MD5,MD2,SSL,TLS,AES]"
-
-#define SECMOD_MAKE_NSS_FLAGS(fips,slot) \
-"Flags=internal,critical"fips" slotparams=("#slot"={"SECMOD_SLOT_FLAGS"})"
-
-#define SECMOD_INT_NAME "NSS Internal PKCS #11 Module"
-#define SECMOD_INT_FLAGS SECMOD_MAKE_NSS_FLAGS("",1)
-#define SECMOD_FIPS_NAME "NSS Internal FIPS PKCS #11 Module"
-#define SECMOD_FIPS_FLAGS SECMOD_MAKE_NSS_FLAGS(",fips",3)
-
/* Symetric Key structure. Reference Counted */
struct PK11SymKeyStr {
CK_MECHANISM_TYPE type; /* type of operation this key was created for*/
@@ -199,3 +177,4 @@ struct PK11ContextStr {
* non-standard semantics*/
};
+#endif /* _SECMODTI_H_ */
diff --git a/security/nss/lib/pkcs12/p12d.c b/security/nss/lib/pkcs12/p12d.c
index 3a77578d7..64a0ea353 100644
--- a/security/nss/lib/pkcs12/p12d.c
+++ b/security/nss/lib/pkcs12/p12d.c
@@ -1875,15 +1875,6 @@ sec_pkcs12_get_existing_nick_for_dn(sec_PKCS12SafeBag *cert, void *wincx)
/* if the token is local, first traverse the cert database
* then traverse the token.
*/
- if(PK11_IsInternal(cert->slot)) {
- if(CERT_TraversePermCertsForSubject(CERT_GetDefaultCertDB(),
- &tempCert->derSubject, gatherNicknames,
- nickArg) != SECSuccess) {
- returnDn = NULL;
- goto loser;
- }
- }
-
if(PK11_TraverseCertsForSubjectInSlot(tempCert, cert->slot, gatherNicknames,
(void *)nickArg) != SECSuccess) {
returnDn = NULL;
@@ -1944,12 +1935,6 @@ sec_pkcs12_certs_for_nickname_exist(SECItem *nickname, PK11SlotInfo *slot)
}
/* we want to check the local database first if we are importing to it */
- if(PK11_IsInternal(slot)) {
- CERT_TraversePermCertsForNickname(CERT_GetDefaultCertDB(),
- (char *)nickname->data,
- countCertificate, (void *)&nCerts);
- }
-
PK11_TraverseCertsForNicknameInSlot(nickname, slot, countCertificate,
(void *)&nCerts);
if(nCerts) return PR_TRUE;
diff --git a/security/nss/lib/softoken/alghmac.c b/security/nss/lib/softoken/alghmac.c
index aef81a76b..60abd73d0 100644
--- a/security/nss/lib/softoken/alghmac.c
+++ b/security/nss/lib/softoken/alghmac.c
@@ -31,10 +31,10 @@
* GPL.
*/
-#include "alghmac.h"
#include "sechash.h"
-#include "secoid.h"
#include "secport.h"
+#include "alghmac.h"
+/*#include "secoid.h"*/
#define HMAC_PAD_SIZE 64
@@ -57,8 +57,7 @@ HMAC_Destroy(HMACContext *cx)
}
HMACContext *
-HMAC_Create(SECOidTag hash_alg,
- const unsigned char *secret,
+HMAC_Create(const SECHashObject *hash_obj, const unsigned char *secret,
unsigned int secret_len)
{
HMACContext *cx;
@@ -68,20 +67,7 @@ HMAC_Create(SECOidTag hash_alg,
cx = (HMACContext*)PORT_ZAlloc(sizeof(HMACContext));
if (cx == NULL)
return NULL;
-
- switch (hash_alg) {
- case SEC_OID_MD5:
- cx->hashobj = &SECRawHashObjects[HASH_AlgMD5];
- break;
- case SEC_OID_MD2:
- cx->hashobj = &SECRawHashObjects[HASH_AlgMD2];
- break;
- case SEC_OID_SHA1:
- cx->hashobj = &SECRawHashObjects[HASH_AlgSHA1];
- break;
- default:
- goto loser;
- }
+ cx->hashobj = hash_obj;
cx->hash = cx->hashobj->create();
if (cx->hash == NULL)
diff --git a/security/nss/lib/softoken/alghmac.h b/security/nss/lib/softoken/alghmac.h
index 10d598267..3cb1a74dc 100644
--- a/security/nss/lib/softoken/alghmac.h
+++ b/security/nss/lib/softoken/alghmac.h
@@ -34,8 +34,6 @@
#ifndef _ALGHMAC_H_
#define _ALGHMAC_H_
-#include "secoid.h"
-
typedef struct HMACContextStr HMACContext;
SEC_BEGIN_PROTOS
@@ -53,7 +51,7 @@ HMAC_Destroy(HMACContext *cx);
* NULL is returned if an error occurs or the secret is > 64 bytes.
*/
extern HMACContext *
-HMAC_Create(SECOidTag hash_alg, const unsigned char *secret,
+HMAC_Create(const SECHashObject *hashObj, const unsigned char *secret,
unsigned int secret_len);
/* reset HMAC for a fresh round */
diff --git a/security/nss/lib/softoken/config.mk b/security/nss/lib/softoken/config.mk
index d5f06c3ed..702802b8c 100644
--- a/security/nss/lib/softoken/config.mk
+++ b/security/nss/lib/softoken/config.mk
@@ -48,9 +48,8 @@ ifeq ($(OS_ARCH), WINNT)
SHARED_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).dll
IMPORT_LIBRARY = $(OBJDIR)/$(LIBRARY_NAME)$(LIBRARY_VERSION).lib
-DLLFLAGS += -DEF:nss.def
-RES = $(OBJDIR)/nss.res
-RESNAME = nss.rc
+RES = $(OBJDIR)/$(LIBRARY_NAME).res
+RESNAME = $(LIBRARY_NAME).rc
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
CRYPTOLIB=$(DIST)/lib/freebl.lib
@@ -65,11 +64,6 @@ EXTRA_SHARED_LIBRARY_LIBS += \
$(DIST)/lib/secutil.lib \
$(NULL)
-#SHARED_LIBRARY_DIRS = \
-# $(CRYPTODIR) \
-# ../util \
-# $(NULL)
-
EXTRA_LIBS += \
$(DIST)/lib/dbm.lib \
$(NULL)
@@ -83,12 +77,6 @@ EXTRA_SHARED_LIBS += \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)plds4.lib \
$(DIST)/lib/$(NSPR31_LIB_PREFIX)nspr4.lib \
$(NULL)
-
-# $(PROGRAM) has NO explicit dependencies on $(OS_LIBS)
-#OS_LIBS += \
-# wsock32.lib \
-# winmm.lib \
-# $(NULL)
else
# $(PROGRAM) has explicit dependencies on $(EXTRA_LIBS)
@@ -101,17 +89,11 @@ endif
EXTRA_LIBS += \
$(CRYPTOLIB) \
$(DIST)/lib/libsecutil.$(LIB_SUFFIX) \
- $(NULL)
-EXTRA_LIBS += \
$(DIST)/lib/libdbm.$(LIB_SUFFIX) \
$(NULL)
ifdef MOZILLA_BSAFE_BUILD
EXTRA_LIBS+=$(DIST)/lib/libbsafe.$(LIB_SUFFIX)
endif
-#SHARED_LIBRARY_DIRS = \
-# $(CRYPTODIR) \
-# ../util \
-# $(NULL)
# $(PROGRAM) has NO explicit dependencies on $(EXTRA_SHARED_LIBS)
# $(EXTRA_SHARED_LIBS) come before $(OS_LIBS), except on AIX.
@@ -123,43 +105,12 @@ EXTRA_SHARED_LIBS += \
$(NULL)
endif
-#ifeq ($(OS_ARCH),SunOS)
-#MAPFILE = $(OBJDIR)/nssmap.sun
-#ALL_TRASH += $(MAPFILE)
-#MKSHLIB += -M $(MAPFILE)
-#ifndef USE_64
-#ifeq ($(CPU_ARCH),sparc)
-## The -R '$ORIGIN' linker option instructs libnss3.so to search for its
-## dependencies (libfreebl_*.so) in the same directory where it resides.
-#MKSHLIB += -R '$$ORIGIN'
-#endif
-#endif
-#endif
-#
-#ifeq ($(OS_ARCH),AIX)
-#MAPFILE = $(OBJDIR)/nssmap.aix
-#ALL_TRASH += $(MAPFILE)
-#EXPORT_RULES = -bexport:$(MAPFILE)
-#endif
-#
-#ifeq ($(OS_ARCH),HP-UX)
-#MAPFILE = $(OBJDIR)/nssmap.hp
-#ALL_TRASH += $(MAPFILE)
-#MKSHLIB += -c $(MAPFILE)
-#endif
-#
-#ifeq ($(OS_ARCH), OSF1)
-#MAPFILE = $(OBJDIR)/nssmap.osf
-#ALL_TRASH += $(MAPFILE)
-#MKSHLIB += -hidden -input $(MAPFILE)
-#endif
-#
-#ifeq ($(OS_ARCH),Linux)
-#MAPFILE = $(OBJDIR)/nssmap.linux
-#ALL_TRASH += $(MAPFILE)
-#MKSHLIB += -Wl,--version-script,$(MAPFILE)
-#endif
-#
-#
-
-
+ifeq ($(OS_ARCH),SunOS)
+ifndef USE_64
+ifeq ($(CPU_ARCH),sparc)
+# The -R '$ORIGIN' linker option instructs libnss3.so to search for its
+# dependencies (libfreebl_*.so) in the same directory where it resides.
+MKSHLIB += -R '$$ORIGIN'
+endif
+endif
+endif
diff --git a/security/nss/lib/softoken/keydb.c b/security/nss/lib/softoken/keydb.c
index 8ad3d7674..eed5b9173 100644
--- a/security/nss/lib/softoken/keydb.c
+++ b/security/nss/lib/softoken/keydb.c
@@ -64,22 +64,6 @@
#define SALT_LENGTH 16
/* ASN1 Templates for new decoder/encoder */
-/*
- * Attribute value for PKCS8 entries (static?)
- */
-const SEC_ASN1Template nsslowkey_AttributeTemplate[] = {
- { SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(NSSLOWKEYAttribute) },
- { SEC_ASN1_OBJECT_ID, offsetof(NSSLOWKEYAttribute, attrType) },
- { SEC_ASN1_SET_OF, offsetof(NSSLOWKEYAttribute, attrValue),
- SEC_AnyTemplate },
- { 0 }
-};
-
-const SEC_ASN1Template nsslowkey_SetOfAttributeTemplate[] = {
- { SEC_ASN1_SET_OF, 0, nsslowkey_AttributeTemplate },
-};
-
const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
{ SEC_ASN1_SEQUENCE,
0, NULL, sizeof(NSSLOWKEYPrivateKeyInfo) },
@@ -90,9 +74,6 @@ const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[] = {
SECOID_AlgorithmIDTemplate },
{ SEC_ASN1_OCTET_STRING,
offsetof(NSSLOWKEYPrivateKeyInfo,privateKey) },
- { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
- offsetof(NSSLOWKEYPrivateKeyInfo,attributes),
- nsslowkey_SetOfAttributeTemplate },
{ 0 }
};
@@ -799,10 +780,10 @@ nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
NSSLOWKEYPrivateKey *privkey,
SECItem *pubKeyData,
char *nickname,
- NSSLOWKEYGetPasswordKey f, void *arg)
+ SECItem *arg)
{
- return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData, nickname,
- f, arg, nsslowkey_GetDefaultKeyDBAlg());
+ return nsslowkey_StoreKeyByPublicKeyAlg(handle, privkey, pubKeyData,
+ nickname, arg, nsslowkey_GetDefaultKeyDBAlg());
}
/* see if the public key for this cert is in the database filed
@@ -853,47 +834,6 @@ nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cer
}
/*
- * find the private key for a cert
- */
-NSSLOWKEYPrivateKey *
-nsslowkey_FindKeyByCert(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cert,
- NSSLOWKEYGetPasswordKey f, void *arg)
-{
- NSSLOWKEYPublicKey *pubkey = NULL;
- SECItem *keyItem = NULL;
- NSSLOWKEYPrivateKey *privKey = NULL;
-
- /* get cert's public key */
- pubkey = nsslowcert_ExtractPublicKey(cert);
- if ( !pubkey ) {
- goto loser;
- }
-
- /* TNH - make record key from NSSLOWKEYPublicKey (again) */
- switch (pubkey->keyType) {
- case NSSLOWKEYRSAKey:
- keyItem = &pubkey->u.rsa.modulus;
- break;
- case NSSLOWKEYDSAKey:
- keyItem = &pubkey->u.dsa.publicValue;
- break;
- case NSSLOWKEYDHKey:
- keyItem = &pubkey->u.dh.publicValue;
- break;
- case NSSLOWKEYNullKey:
- goto loser;
- }
- PORT_Assert( keyItem != NULL );
-
- privKey = nsslowkey_FindKeyByPublicKey(handle, keyItem, f, arg);
-
- /* success falls through */
-loser:
- nsslowkey_DestroyPublicKey(pubkey);
- return(privKey);
-}
-
-/*
* check to see if the user has a password
*/
SECStatus
@@ -934,19 +874,6 @@ nsslowkey_SetKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
nsslowkey_GetDefaultKeyDBAlg());
}
-/*
- * Re-encrypt the entire key database with a new password.
- * NOTE: This really should create a new database rather than doing it
- * in place in the original
- */
-SECStatus
-nsslowkey_ChangeKeyDBPassword(NSSLOWKEYDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem)
-{
- return nsslowkey_ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem,
- nsslowkey_GetDefaultKeyDBAlg());
-}
-
static SECStatus
HashPassword(unsigned char *hashresult, char *pw, SECItem *salt)
{
@@ -1124,7 +1051,7 @@ seckey_create_rc4_salt(void)
}
SECItem *
-seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
+seckey_rc4_decode(SECItem *key, SECItem *src)
{
SECItem *dest = NULL;
RC4Context *ctxt = NULL;
@@ -1144,11 +1071,7 @@ seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
ctxt = RC4_CreateContext(key->data, key->len);
if(ctxt != NULL)
{
- if(encrypt == PR_TRUE)
- rv = RC4_Encrypt(ctxt, dest->data, &dest->len,
- src->len + 64, src->data, src->len);
- else
- rv = RC4_Decrypt(ctxt, dest->data, &dest->len,
+ rv = RC4_Decrypt(ctxt, dest->data, &dest->len,
src->len + 64, src->data, src->len);
RC4_DestroyContext(ctxt, PR_TRUE);
}
@@ -1169,16 +1092,18 @@ seckey_rc4_cipher(SECItem *key, SECItem *src, PRBool encrypt)
NSSLOWKEYEncryptedPrivateKeyInfo *
seckey_encrypt_private_key(
NSSLOWKEYPrivateKey *pk, SECItem *pwitem, NSSLOWKEYDBHandle *keydb,
- SECOidTag algorithm)
+ SECOidTag algorithm, SECItem **salt)
{
NSSLOWKEYEncryptedPrivateKeyInfo *epki = NULL;
NSSLOWKEYPrivateKeyInfo *pki = NULL;
SECStatus rv = SECFailure;
- SECAlgorithmID *algid = NULL;
PLArenaPool *temparena = NULL, *permarena = NULL;
- SECItem *key = NULL, *salt = NULL, *der_item = NULL;
+ SECItem *key = NULL, *der_item = NULL;
+ NSSPKCS5PBEParameter *param;
SECItem *dummy = NULL, *dest = NULL;
+ SECAlgorithmID *algid;
+ *salt = NULL;
permarena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
if(permarena == NULL)
return NULL;
@@ -1200,7 +1125,7 @@ seckey_encrypt_private_key(
/* setup private key info */
dummy = SEC_ASN1EncodeInteger(temparena, &(pki->version),
- SEC_PRIVATE_KEY_INFO_VERSION);
+ NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
if(dummy == NULL)
goto loser;
@@ -1272,72 +1197,59 @@ seckey_encrypt_private_key(
}
rv = SECFailure; /* assume failure */
- switch(algorithm)
- {
- case SEC_OID_RC4:
- salt = seckey_create_rc4_salt();
- if(salt != NULL)
- {
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, der_item, PR_TRUE);
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &epki->encryptedData,
- dest);
- if(rv == SECSuccess)
- rv = SECOID_SetAlgorithmID(permarena,
- &epki->algorithm, SEC_OID_RC4, salt);
- }
- }
- }
- if(dest != NULL)
- SECITEM_FreeItem(dest, PR_TRUE);
- if(key != NULL)
- SECITEM_ZfreeItem(key, PR_TRUE);
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm, NULL, 1);
- if(algid != NULL)
- {
- dest = SEC_PKCS5CipherData(algid, pwitem,
- der_item, PR_TRUE, NULL);
- if(dest != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &epki->encryptedData,
- dest);
- if(rv == SECSuccess)
- rv = SECOID_CopyAlgorithmID(permarena,
- &epki->algorithm, algid);
- }
- }
- if(dest != NULL)
- SECITEM_FreeItem(dest, PR_TRUE);
- if(algid != NULL)
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
- break;
+ *salt = seckey_create_rc4_salt();
+ if (*salt == NULL) {
+ goto loser;
}
- /* let success fall through */
+ param = nsspkcs5_NewParam(algorithm,*salt,1);
+ if (param == NULL) {
+ goto loser;
+ }
+
+ dest = nsspkcs5_CipherData(param, pwitem, der_item, PR_TRUE, NULL);
+ if (dest == NULL) {
+ goto loser;
+ }
+
+ rv = SECITEM_CopyItem(permarena, &epki->encryptedData, dest);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ algid = nsspkcs5_CreateAlgorithmID(permarena, algorithm, param);
+ if (algid == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ rv = SECOID_CopyAlgorithmID(permarena, &epki->algorithm, algid);
+ SECOID_DestroyAlgorithmID(algid, PR_TRUE);
+
loser:
+ if(dest != NULL)
+ SECITEM_FreeItem(dest, PR_TRUE);
+
+ if(param != NULL)
+ nsspkcs5_DestroyPBEParameter(param);
+
+ /* let success fall through */
if(rv == SECFailure)
{
PORT_FreeArena(permarena, PR_TRUE);
- epki = NULL;
+ epki = NULL;
+ if(*salt != NULL)
+ SECITEM_FreeItem(*salt, PR_TRUE);
}
if(temparena != NULL)
PORT_FreeArena(temparena, PR_TRUE);
-
- if(salt != NULL)
- SECITEM_FreeItem(salt, PR_TRUE);
return epki;
}
-SECStatus
+static SECStatus
seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
NSSLOWKEYPrivateKey *pk, char *nickname, PRBool update,
SECOidTag algorithm)
@@ -1365,29 +1277,15 @@ seckey_put_private_key(NSSLOWKEYDBHandle *keydb, DBT *index, SECItem *pwitem,
/* TNH - for RC4, the salt should be created here */
- epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm);
+ epki = seckey_encrypt_private_key(pk, pwitem, keydb, algorithm, &salt);
if(epki == NULL)
goto loser;
temparena = epki->arena;
- /* extract salt for db key */
- switch(algorithm)
+ if(salt != NULL)
{
- case SEC_OID_RC4:
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt),
- &(epki->algorithm.parameters));
- epki->algorithm.parameters.len = 0;
- epki->algorithm.parameters.data = NULL;
- break;
- default:
- /* TNH - this should not be necessary */
- salt = SEC_PKCS5GetSalt(&epki->algorithm);
- if(salt != NULL)
- {
- rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt);
- SECITEM_ZfreeItem(salt, PR_TRUE);
- }
- break;
+ rv = SECITEM_CopyItem(permarena, &(dbkey->salt), salt);
+ SECITEM_ZfreeItem(salt, PR_TRUE);
}
dummy = SEC_ASN1EncodeItem(permarena, &(dbkey->derPK), epki,
@@ -1417,11 +1315,10 @@ nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
NSSLOWKEYPrivateKey *privkey,
SECItem *pubKeyData,
char *nickname,
- NSSLOWKEYGetPasswordKey f, void *arg,
+ SECItem *pwitem,
SECOidTag algorithm)
{
DBT namekey;
- SECItem *pwitem = NULL;
SECStatus rv;
if (handle == NULL) {
@@ -1433,11 +1330,6 @@ nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
namekey.data = pubKeyData->data;
namekey.size = pubKeyData->len;
- pwitem = (*f )(arg, handle);
- if ( pwitem == NULL ) {
- return(SECFailure);
- }
-
/* encrypt the private key */
rv = seckey_put_private_key(handle, &namekey, pwitem, privkey, nickname,
PR_FALSE, algorithm);
@@ -1456,6 +1348,7 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki,
SECOidTag algorithm;
PLArenaPool *temparena = NULL, *permarena = NULL;
SECItem *salt = NULL, *dest = NULL, *key = NULL;
+ NSSPKCS5PBEParameter *param;
if((epki == NULL) || (pwitem == NULL))
goto loser;
@@ -1488,8 +1381,7 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki,
key = seckey_create_rc4_key(pwitem, salt);
if(key != NULL)
{
- dest = seckey_rc4_cipher(key, &epki->encryptedData,
- PR_FALSE);
+ dest = seckey_rc4_decode(key, &epki->encryptedData);
}
}
if(salt != NULL)
@@ -1501,8 +1393,13 @@ seckey_decrypt_private_key(NSSLOWKEYEncryptedPrivateKeyInfo *epki,
/* we depend on the fact that if this key was encoded with
* DES, that the pw was also encoded with DES, so we don't have
* to do the update here, the password code will handle it. */
- dest = SEC_PKCS5CipherData(&epki->algorithm, pwitem,
- &epki->encryptedData, PR_FALSE, NULL);
+ param = nsspkcs5_AlgidToParam(&epki->algorithm);
+ if (param == NULL) {
+ break;
+ }
+ dest = nsspkcs5_CipherData(param, pwitem, &epki->encryptedData,
+ PR_FALSE, NULL);
+ nsspkcs5_DestroyPBEParameter(param);
break;
}
@@ -1675,11 +1572,10 @@ nsslowkey_DecryptKey(DBT *key, SECItem *pwitem,
*/
NSSLOWKEYPrivateKey *
nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
- NSSLOWKEYGetPasswordKey f, void *arg)
+ SECItem *pwitem)
{
DBT namekey;
NSSLOWKEYPrivateKey *pk = NULL;
- SECItem *pwitem = NULL;
if (handle == NULL) {
PORT_SetError(SEC_ERROR_BAD_DATABASE);
@@ -1690,11 +1586,6 @@ nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
namekey.data = modulus->data;
namekey.size = modulus->len;
- pwitem = (*f )(arg, handle);
- if ( pwitem == NULL ) {
- return(NULL);
- }
-
pk = seckey_get_private_key(handle, &namekey, NULL, pwitem);
SECITEM_ZfreeItem(pwitem, PR_TRUE);
@@ -1753,7 +1644,7 @@ nsslowkey_SetKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
SECItem *pwitem, SECOidTag algorithm)
{
DBT checkkey;
- SECAlgorithmID *algid = NULL;
+ NSSPKCS5PBEParameter *param = NULL;
SECStatus rv = SECFailure;
NSSLOWKEYDBKey *dbkey = NULL;
PLArenaPool *arena;
@@ -1788,24 +1679,13 @@ nsslowkey_SetKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
goto loser;
}
- switch(algorithm)
- {
- case SEC_OID_RC4:
- key = seckey_create_rc4_key(pwitem, salt);
- if(key != NULL)
- {
- dest = seckey_rc4_cipher(key, &test_key, PR_TRUE);
- SECITEM_FreeItem(key, PR_TRUE);
- }
- break;
- default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm, salt, 1);
- if(algid != NULL)
- dest = SEC_PKCS5CipherData(algid, pwitem, &test_key,
- PR_TRUE, NULL);
- break;
+ param = nsspkcs5_NewParam(algorithm, salt, 1);
+ if (param != NULL) {
+ rv = SECFailure;
+ goto loser;
}
+ dest = nsspkcs5_CipherData(param, pwitem, &test_key, PR_TRUE, NULL);
if(dest != NULL)
{
rv = SECITEM_CopyItem(arena, &dbkey->salt, salt);
@@ -1836,6 +1716,10 @@ loser:
if ( salt != NULL ) {
SECITEM_ZfreeItem(salt, PR_TRUE);
}
+
+ if (param != NULL) {
+ nsspkcs5_DestroyPBEParameter(param);
+ }
return(rv);
}
@@ -1954,7 +1838,7 @@ nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
{
DBT checkkey;
DBT checkdata;
- SECAlgorithmID *algid = NULL;
+ NSSPKCS5PBEParameter *param = NULL;
SECStatus rv = SECFailure;
NSSLOWKEYDBKey *dbkey = NULL;
SECItem *key = NULL;
@@ -2017,14 +1901,13 @@ nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
case SEC_OID_RC4:
key = seckey_create_rc4_key(pwitem, &dbkey->salt);
if(key != NULL) {
- dest = seckey_rc4_cipher(key, &encstring, PR_FALSE);
+ dest = seckey_rc4_decode(key, &encstring);
SECITEM_FreeItem(key, PR_TRUE);
}
break;
default:
- algid = SEC_PKCS5CreateAlgorithmID(algorithm,
- &dbkey->salt, 1);
- if(algid != NULL) {
+ param = nsspkcs5_NewParam(algorithm, &dbkey->salt, 1);
+ if (param != NULL) {
/* Decrypt - this function implements a workaround for
* a previous coding error. It will decrypt values using
* DES rather than 3DES, if the initial try at 3DES
@@ -2032,9 +1915,9 @@ nsslowkey_CheckKeyDBPassword(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
* set to TRUE. This indication is used later to force
* an update of the database to "real" 3DES encryption.
*/
- dest = SEC_PKCS5CipherData(algid, pwitem,
+ dest = nsspkcs5_CipherData(param, pwitem,
&encstring, PR_FALSE, &update);
- SECOID_DestroyAlgorithmID(algid, PR_TRUE);
+ nsspkcs5_DestroyPBEParameter(param);
}
break;
}
@@ -2141,7 +2024,6 @@ ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
newkey.size = privkey->u.dh.publicValue.len;
break;
default:
- /* XXX We don't do Fortezza. */
return SECFailure;
}
@@ -2177,9 +2059,8 @@ loser:
* in place in the original
*/
SECStatus
-nsslowkey_ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
- SECItem *oldpwitem, SECItem *newpwitem,
- SECOidTag new_algorithm)
+nsslowkey_ChangeKeyDBPassword(NSSLOWKEYDBHandle *handle,
+ SECItem *oldpwitem, SECItem *newpwitem)
{
SECStatus rv;
@@ -2194,7 +2075,8 @@ nsslowkey_ChangeKeyDBPasswordAlg(NSSLOWKEYDBHandle *handle,
return(SECFailure); /* return rv? */
}
- rv = ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem, new_algorithm);
+ rv = ChangeKeyDBPasswordAlg(handle, oldpwitem, newpwitem,
+ nsslowkey_GetDefaultKeyDBAlg());
loser:
return(rv);
@@ -2203,7 +2085,7 @@ loser:
/*
* Second pass of updating the key db. This time we have a password.
*/
-SECStatus
+static SECStatus
nsslowkey_UpdateKeyDBPass2(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
{
SECStatus rv;
@@ -2217,7 +2099,7 @@ nsslowkey_UpdateKeyDBPass2(NSSLOWKEYDBHandle *handle, SECItem *pwitem)
/*
* currently updates key database from v2 to v3
*/
-SECStatus
+static SECStatus
nsslowkey_UpdateKeyDBPass1(NSSLOWKEYDBHandle *handle)
{
SECStatus rv;
@@ -2473,12 +2355,3 @@ done:
return (errors == 0 ? SECSuccess : SECFailure);
}
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-*/
-SEC_ASN1_CHOOSER_IMPLEMENT(nsslowkey_PrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(nsslowkey_PointerToPrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(nsslowkey_EncryptedPrivateKeyInfoTemplate)
-SEC_ASN1_CHOOSER_IMPLEMENT(nsslowkey_PointerToEncryptedPrivateKeyInfoTemplate)
-
diff --git a/security/nss/lib/softoken/lowcert.c b/security/nss/lib/softoken/lowcert.c
index 774f1d996..c376f9643 100644
--- a/security/nss/lib/softoken/lowcert.c
+++ b/security/nss/lib/softoken/lowcert.c
@@ -45,6 +45,7 @@
#include "lowkeyi.h"
#include "pcert.h"
#include "secasn1.h"
+#include "secoid.h"
/* should have been in a 'util' header */
extern const SEC_ASN1Template CERT_ValidityTemplate[];
@@ -313,7 +314,7 @@ nsslowcert_DecodeDERCertificate(SECItem *derSignedCert, PRBool copyDER,
rv = SEC_ASN1DecodeItem(arena, cert, nsslowcert_SignedCertificateTemplate,
&cert->derCert);
- /* cert->subjectKeyID; /* x509v3 subject key identifier */
+ /* cert->subjectKeyID; x509v3 subject key identifier */
cert->dbEntry = NULL;
cert ->trust = NULL;
diff --git a/security/nss/lib/softoken/lowkeyi.h b/security/nss/lib/softoken/lowkeyi.h
index b84c0729a..9227e250b 100644
--- a/security/nss/lib/softoken/lowkeyi.h
+++ b/security/nss/lib/softoken/lowkeyi.h
@@ -118,17 +118,12 @@ extern SECStatus nsslowkey_StoreKeyByPublicKey(NSSLOWKEYDBHandle *handle,
NSSLOWKEYPrivateKey *pk,
SECItem *pubKeyData,
char *nickname,
- NSSLOWKEYGetPasswordKey f,
- void *arg);
+ SECItem *arg);
/* does the key for this cert exist in the database filed by modulus */
extern SECStatus nsslowkey_KeyForCertExists(NSSLOWKEYDBHandle *handle,
NSSLOWCERTCertificate *cert);
-NSSLOWKEYPrivateKey *
-nsslowkey_FindKeyByCert(NSSLOWKEYDBHandle *handle, NSSLOWCERTCertificate *cert,
- NSSLOWKEYGetPasswordKey f, void *arg);
-
extern SECStatus nsslowkey_HasKeyDBPassword(NSSLOWKEYDBHandle *handle);
extern SECStatus nsslowkey_SetKeyDBPassword(NSSLOWKEYDBHandle *handle,
SECItem *pwitem);
@@ -226,7 +221,7 @@ nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
NSSLOWKEYPrivateKey *privkey,
SECItem *pubKeyData,
char *nickname,
- NSSLOWKEYGetPasswordKey f, void *arg,
+ SECItem *arg,
SECOidTag algorithm);
/* Find key by modulus. This function is the inverse of store key
@@ -237,7 +232,7 @@ nsslowkey_StoreKeyByPublicKeyAlg(NSSLOWKEYDBHandle *handle,
*/
extern NSSLOWKEYPrivateKey *
nsslowkey_FindKeyByPublicKey(NSSLOWKEYDBHandle *handle, SECItem *modulus,
- NSSLOWKEYGetPasswordKey f, void *arg);
+ SECItem *arg);
/* Make a copy of a low private key in it's own arena.
* a return of NULL indicates an error.
diff --git a/security/nss/lib/softoken/lowkeyti.h b/security/nss/lib/softoken/lowkeyti.h
index 248940a62..b8941bb0d 100644
--- a/security/nss/lib/softoken/lowkeyti.h
+++ b/security/nss/lib/softoken/lowkeyti.h
@@ -64,9 +64,6 @@ typedef struct NSSLOWKEYDBHandleStr NSSLOWKEYDBHandle;
/*
** Typedef for callback to get a password "key".
*/
-typedef SECItem * (* NSSLOWKEYGetPasswordKey)(void *arg,
- NSSLOWKEYDBHandle *handle);
-
extern const SEC_ASN1Template nsslowkey_PQGParamsTemplate[];
extern const SEC_ASN1Template nsslowkey_RSAPrivateKeyTemplate[];
extern const SEC_ASN1Template nsslowkey_DSAPrivateKeyTemplate[];
@@ -76,20 +73,7 @@ extern const SEC_ASN1Template nsslowkey_DHPrivateKeyExportTemplate[];
extern const SEC_ASN1Template nsslowkey_PrivateKeyInfoTemplate[];
extern const SEC_ASN1Template nsslowkey_EncryptedPrivateKeyInfoTemplate[];
-extern const SEC_ASN1Template nsslowkey_AttributeTemplate[];
-
-/* These functions simply return the address of the above-declared templates.
-** This is necessary for Windows DLLs. Sigh.
-extern SEC_ASN1TemplateChooser NSS_Get_nsslowkey_EncryptedPrivateKeyInfoTemplate; */
-/*
-** Attributes
-*/
-struct NSSLOWKEYAttributeStr {
- SECItem attrType;
- SECItem **attrValue;
-};
-typedef struct NSSLOWKEYAttributeStr NSSLOWKEYAttribute;
/*
** A PKCS#8 private key info object
@@ -99,10 +83,9 @@ struct NSSLOWKEYPrivateKeyInfoStr {
SECItem version;
SECAlgorithmID algorithm;
SECItem privateKey;
- NSSLOWKEYAttribute **attributes;
};
typedef struct NSSLOWKEYPrivateKeyInfoStr NSSLOWKEYPrivateKeyInfo;
-#define NSS_LOW_KEY_INFO_VERSION 0 /* what we *create* */
+#define NSSLOWKEY_PRIVATE_KEY_INFO_VERSION 0 /* what we *create* */
/*
** A PKCS#8 private key info object
diff --git a/security/nss/lib/softoken/manifest.mn b/security/nss/lib/softoken/manifest.mn
index f385f88a9..065a1ccc3 100644
--- a/security/nss/lib/softoken/manifest.mn
+++ b/security/nss/lib/softoken/manifest.mn
@@ -36,8 +36,9 @@ MODULE = security
REQUIRES = dbm
-LIBRARY_NAME = softoken
+LIBRARY_NAME = softokn
LIBRARY_VERSION = 3
+MAPFILE = $(OBJDIR)/softokn.def
EXPORTS = \
@@ -45,6 +46,7 @@ EXPORTS = \
pkcs11f.h \
pkcs11p.h \
pkcs11t.h \
+ pkcs11n.h \
pkcs11u.h \
secpkcs5.h \
$(NULL)
@@ -73,5 +75,3 @@ CSRCS = \
secpkcs5.c \
pcertdb.c \
$(NULL)
-
-
diff --git a/security/nss/lib/softoken/pcert.h b/security/nss/lib/softoken/pcert.h
index 3d92c88d8..9795899b4 100644
--- a/security/nss/lib/softoken/pcert.h
+++ b/security/nss/lib/softoken/pcert.h
@@ -288,6 +288,14 @@ typedef union {
#define CERTDB_TRUSTED_CLIENT_CA (1<<7) /* trusted for issuing client certs */
#define CERTDB_INVISIBLE_CA (1<<8) /* don't show in UI */
#define CERTDB_GOVT_APPROVED_CA (1<<9) /* can do strong crypto in export ver */
+#define CERTDB_NOT_TRUSTED (1<<10) /* explicitly don't trust this cert */
+#define CERTDB_TRUSTED_UNKNOWN (1<<11) /* accept trust from another source */
+
+/* bits not affected by the CKO_NETSCAPE_TRUST object */
+#define CERTDB_PRESERVE_TRUST_BITS (CERTDB_USER | CERTDB_VALID_PEER | \
+ CERTDB_NS_TRUSTED_CA | CERTDB_VALID_CA | CERTDB_INVISIBLE_CA | \
+ CERTDB_GOVT_APPROVED_CA)
+
SEC_BEGIN_PROTOS
@@ -328,73 +336,19 @@ nsslowcert_TraversePermCerts(NSSLOWCERTCertDBHandle *handle,
PermCertCallback certfunc,
void *udata );
-SECStatus
-SEC_AddTempNickname(NSSLOWCERTCertDBHandle *handle, char *nickname, SECItem *certKey);
-
-SECStatus
-SEC_DeleteTempNickname(NSSLOWCERTCertDBHandle *handle, char *nickname);
-
-PRBool
-SEC_CertNicknameConflict(char *nickname, SECItem *derSubject,
- NSSLOWCERTCertDBHandle *handle);
-
PRBool
-SEC_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle);
-
-SECStatus
-SEC_GetCrlTimes(NSSLOWCERTCrl *dates, PRTime *notBefore, PRTime *notAfter);
-
-SECCertTimeValidity
-SEC_CheckCrlTimes(NSSLOWCERTCrl *crl, PRTime t);
-
-PRBool
-SEC_CrlIsNewer(NSSLOWCERTCrl *inNew, NSSLOWCERTCrl *old);
-
-NSSLOWCERTSignedCrl *
-SEC_AddPermCrlToTemp(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry);
-
-SECStatus
-SEC_DeleteTempCrl(NSSLOWCERTSignedCrl *crl);
-
-NSSLOWCERTSignedCrl *
-SEC_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey, int type);
+nsslowcert_CertDBKeyConflict(SECItem *derCert, NSSLOWCERTCertDBHandle *handle);
-NSSLOWCERTSignedCrl *
-SEC_FindCrlByName(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey, int type);
+SECItem *
+nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey,
+ char **urlp, PRBool isKRL);
-NSSLOWCERTSignedCrl *
-SEC_FindCrlByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl, int type);
-
-SECStatus
-SEC_DestroyCrl(NSSLOWCERTSignedCrl *crl);
-
-NSSLOWCERTSignedCrl *
-SEC_NewCrl(NSSLOWCERTCertDBHandle *handle, char *url, SECItem *derCrl, int type);
-
-NSSLOWCERTSignedCrl *
-cert_DBInsertCRL
- (NSSLOWCERTCertDBHandle *handle, char *url,
- NSSLOWCERTSignedCrl *newCrl, SECItem *derCrl, int type);
-
-#ifdef ntodef
SECStatus
-SEC_CheckKRL(NSSLOWCERTCertDBHandle *handle,NSSLOWKEYPublicKey *key,
- NSSLOWCERTCertificate *rootCert, int64 t, void *wincx);
-
+nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle,SECItem *derName,
+ PRBool isKRL);
SECStatus
-SEC_CheckCRL(NSSLOWCERTCertDBHandle *handle,NSSLOWCERTCertificate *cert,
- NSSLOWCERTCertificate *caCert, int64 t, void *wincx);
-
-SECStatus
-SEC_DeletePermCRL(NSSLOWCERTSignedCrl *crl);
-
-
-SECStatus
-SEC_LookupCrls(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTCrlHeadNode **nodes, int type);
-
-SECStatus
-SEC_CrlReplaceUrl(NSSLOWCERTSignedCrl *crl,char *url);
-#endif
+nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl ,
+ SECItem *derKey, char *url, PRBool isKRL);
NSSLOWCERTCertDBHandle *nsslowcert_GetDefaultCertDB();
NSSLOWKEYPublicKey *nsslowcert_ExtractPublicKey(NSSLOWCERTCertificate *);
@@ -414,7 +368,7 @@ void nsslowcert_DestroyCertificate(NSSLOWCERTCertificate *cert);
* traversal.
*/
NSSLOWCERTCertificate *
-nsslowcert_FindCertByKeyNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *certKey);
+nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey);
/*
** Generate a certificate key from the issuer and serialnumber, then look it
@@ -444,21 +398,10 @@ char *nsslowcert_FixupEmailAddr(char *emailAddr);
*/
extern NSSLOWCERTCertificate *
nsslowcert_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname);
-/*
-** Decode a DER encoded CRL/KRL into an NSSLOWCERTSignedCrl structure
-** "derSignedCrl" is the DER encoded signed crl/krl.
-** "type" is this a CRL or KRL.
-*/
-#define SEC_CRL_TYPE 1
-#define SEC_KRL_TYPE 0
-
-extern NSSLOWCERTSignedCrl *
-nsslowcert_DecodeDERCrl (PRArenaPool *arena, SECItem *derSignedCrl,int type);
SECStatus
nsslowcert_KeyFromDERCert(PRArenaPool *arena, SECItem *derCert, SECItem *key);
-
SEC_END_PROTOS
#endif /* _PCERTDB_H_ */
diff --git a/security/nss/lib/softoken/pcertdb.c b/security/nss/lib/softoken/pcertdb.c
index 9ea42dd87..545963f95 100644
--- a/security/nss/lib/softoken/pcertdb.c
+++ b/security/nss/lib/softoken/pcertdb.c
@@ -1078,11 +1078,12 @@ loser:
static SECStatus
-WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry )
+WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry,
+ SECItem *crlKey )
{
SECItem dbkey;
PRArenaPool *tmparena = NULL;
- SECItem tmpitem,encodedEntry;
+ SECItem encodedEntry;
SECStatus rv;
tmparena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
@@ -1090,18 +1091,12 @@ WriteDBCrlEntry(NSSLOWCERTCertDBHandle *handle, certDBEntryRevocation *entry )
goto loser;
}
- /* get the database key and format it */
- rv = nsslowcert_KeyFromDERCrl(tmparena, &entry->derCrl, &tmpitem);
- if ( rv == SECFailure ) {
- goto loser;
- }
-
rv = EncodeDBCrlEntry(entry, tmparena, &encodedEntry);
if ( rv == SECFailure ) {
goto loser;
}
- rv = EncodeDBGenericKey(&tmpitem, tmparena, &dbkey, entry->common.type);
+ rv = EncodeDBGenericKey(crlKey, tmparena, &dbkey, entry->common.type);
if ( rv == SECFailure ) {
goto loser;
}
@@ -2769,7 +2764,7 @@ AddPermSubjectNode(certDBEntrySubject *entry, NSSLOWCERTCertificate *cert,
}
for ( i = 0; i < ncerts; i++ ) {
- cmpcert = nsslowcert_FindCertByKeyNoLocking(cert->dbhandle,
+ cmpcert = nsslowcert_FindCertByKey(cert->dbhandle,
&entry->certKeys[i]);
PORT_Assert(cmpcert);
if ( nsslowcert_IsNewer(cert, cmpcert) ) {
@@ -2846,7 +2841,7 @@ nsslowcert_TraversePermCertsForSubject(NSSLOWCERTCertDBHandle *handle,
}
for( i = 0; i < entry->ncerts; i++ ) {
- cert = nsslowcert_FindCertByKeyNoLocking(handle, &entry->certKeys[i]);
+ cert = nsslowcert_FindCertByKey(handle, &entry->certKeys[i]);
rv = (* cb)(cert, cbarg);
nsslowcert_DestroyCertificate(cert);
if ( rv == SECFailure ) {
@@ -4215,7 +4210,7 @@ loser:
* Lookup a certificate in the databases without locking
*/
NSSLOWCERTCertificate *
-nsslowcert_FindCertByKeyNoLocking(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
+nsslowcert_FindCertByKey(NSSLOWCERTCertDBHandle *handle, SECItem *certKey)
{
return(FindCertByKey(handle, certKey, PR_FALSE));
}
@@ -4245,7 +4240,7 @@ nsslowcert_FindCertByIssuerAndSN(NSSLOWCERTCertDBHandle *handle, NSSLOWCERTIssue
PORT_Memcpy( &certKey.data[issuerAndSN->serialNumber.len],
issuerAndSN->derIssuer.data, issuerAndSN->derIssuer.len);
- cert = nsslowcert_FindCertByKeyNoLocking(handle, &certKey);
+ cert = nsslowcert_FindCertByKey(handle, &certKey);
PORT_Free(certKey.data);
@@ -4276,7 +4271,7 @@ nsslowcert_FindCertByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCert)
}
/* find the certificate */
- cert = nsslowcert_FindCertByKeyNoLocking(handle, &certKey);
+ cert = nsslowcert_FindCertByKey(handle, &certKey);
loser:
PORT_FreeArena(arena, PR_FALSE);
@@ -4345,24 +4340,24 @@ nsslowcert_DestroyCertificateNoLocking(NSSLOWCERTCertificate *cert)
return;
}
-#ifdef notdef
/*
* Lookup a CRL in the databases. We mirror the same fast caching data base
* caching stuff used by certificates....?
*/
-NSSLOWCERTSignedCrl *
-SEC_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey, int type)
+SECItem *
+nsslowcert_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey,
+ char **url, PRBool isKRL)
{
DBT tmpdata;
int ret;
SECItem keyitem;
DBT key;
SECStatus rv;
- NSSLOWCERTSignedCrl *crl = NULL;
+ SECItem *crl = NULL;
PRArenaPool *arena = NULL;
certDBEntryRevocation *entry;
- certDBEntryType crlType = (type == SEC_CRL_TYPE) ?
- certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation;
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if ( arena == NULL ) {
@@ -4376,199 +4371,90 @@ SEC_FindCrlByKey(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey, int type)
key.data = keyitem.data;
key.size = keyitem.len;
-
- /* lookup in the temporary database */
- ret = certdb_Get( handle->tempCertDB, &key, &tmpdata, 0 );
- /* error accessing the database */
- if ( ret < 0 ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
+ /* find in perm database */
+ entry = ReadDBCrlEntry(handle, crlKey, crlType);
+
+ if ( entry == NULL ) {
goto loser;
}
- if ( ret == 0 ) { /* found in temp database */
- if ( tmpdata.size != sizeof(NSSLOWCERTSignedCrl *) ) {
- PORT_SetError(SEC_ERROR_BAD_DATABASE);
- goto loser;
- }
-
- PORT_Memcpy(&crl, tmpdata.data, tmpdata.size);
- crl->referenceCount++;
- } else { /* not found in temporary database */
-
- /* find in perm database */
- entry = ReadDBCrlEntry(handle, crlKey, crlType);
-
- if ( entry == NULL ) {
- goto loser;
- }
+ if (entry->url) {
+ *url = PORT_Strdup(entry->url);
}
+ crl = SECITEM_DupItem(&entry->derCrl);
+
loser:
if ( arena ) {
PORT_FreeArena(arena, PR_FALSE);
}
-
- return(crl);
-}
-
-
-NSSLOWCERTSignedCrl *
-SEC_FindCrlByName(NSSLOWCERTCertDBHandle *handle, SECItem *crlKey, int type)
-{
- return SEC_FindCrlByKey(handle,crlKey,type);
-}
-
-NSSLOWCERTSignedCrl *
-SEC_FindCrlByDERCert(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl, int type)
-{
- PRArenaPool *arena;
- SECItem crlKey;
- SECStatus rv;
- NSSLOWCERTSignedCrl *crl = NULL;
-
- /* create a scratch arena */
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( arena == NULL ) {
- return(NULL);
- }
-
- /* extract the database key from the cert */
- rv = nsslowcert_KeyFromDERCrl(arena, derCrl, &crlKey);
- if ( rv != SECSuccess ) {
- goto loser;
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
}
-
- /* find the crl */
- crl = SEC_FindCrlByKey(handle, &crlKey, type);
-loser:
- PORT_FreeArena(arena, PR_FALSE);
return(crl);
}
-
-SECStatus
-SEC_DestroyCrl(NSSLOWCERTSignedCrl *crl)
-{
- if (crl) {
- if (crl->referenceCount-- <= 1) {
- if (!crl->keep) {
- if (crl->dbEntry) {
- DestroyDBEntry((certDBEntry *)crl->dbEntry);
- }
- PORT_FreeArena(crl->arena, PR_FALSE);
- }
- }
- }
- return SECSuccess;
-}
-
-NSSLOWCERTSignedCrl *
-cert_DBInsertCRL (NSSLOWCERTCertDBHandle *handle, char *url,
- NSSLOWCERTSignedCrl *newCrl, SECItem *derCrl, int type)
-{
- NSSLOWCERTSignedCrl *oldCrl = NULL, *crl = NULL;
- certDBEntryRevocation *entry = NULL;
- PRArenaPool *arena = NULL;
- SECCertTimeValidity validity;
- certDBEntryType crlType = (type == SEC_CRL_TYPE) ?
- certDBEntryTypeRevocation : certDBEntryTypeKeyRevocation;
- SECStatus rv;
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if (arena == NULL) goto done;
-
- oldCrl = SEC_FindCrlByKey(handle, derName, type);
-
- /* if there is an old crl, make sure the one we are installing
- * is newer. If not, exit out, otherwise delete the old crl.
- */
- if (oldCrl != NULL) {
- if (!SEC_CrlIsNewer(derNewCRL,oldEntry->crl)) {
-
- if (type == SEC_CRL_TYPE) {
- PORT_SetError(SEC_ERROR_OLD_CRL);
- } else {
- PORT_SetError(SEC_ERROR_OLD_KRL);
- }
-
- goto done;
- }
-
- if ((SECITEM_CompareItem(derName,derOldName) != SECEqual) &&
- (type == SEC_KRL_TYPE) ) {
-
- PORT_SetError(SEC_ERROR_CKL_CONFLICT);
- goto done;
- }
-
- /* if we have a url in the database, use that one */
- if (oldEntry->url) {
- int nnlen = PORT_Strlen(oldCrl->url) + 1;
- url = (char *)PORT_ArenaAlloc(arena, nnlen);
- if ( url != NULL ) {
- PORT_Memcpy(url, oldCrl->url, nnlen);
- }
- }
-
-
- /* really destroy this crl */
- /* first drum it out of the permanment Data base */
- SEC_DeletePermCRL(oldCrl);
-
- }
-
- /* Write the new entry into the data base */
- entry = NewDBCrlEntry(derCrl, url, crlType, 0);
- if (entry == NULL) goto done;
-
- rv = WriteDBCrlEntry(handle, entry);
- if (rv != SECSuccess) goto done;
-
-done:
- if (entry) DestroyDBEntry((certDBEntry *)entry);
- if (arena) PORT_FreeArena(arena, PR_FALSE);
- if (oldCrl) /* SEC_DestroyCrl(oldCrl); */
-
- return crl;
-}
-
/*
* replace the existing URL in the data base with a new one
*/
SECStatus
-NSSLOWCERT_CrlReplaceUrl(NSSLOWCERTDBHandle *handle, SECItem *derCrl,char *url,
- int type)
+nsslowcert_AddCrl(NSSLOWCERTCertDBHandle *handle, SECItem *derCrl,
+ SECItem *crlKey, char *url, PRBool isKRL)
{
SECStatus rv = SECFailure;
certDBEntryRevocation *entry = NULL;
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
int nnlen=0;
- SEC_DeletePermCRL(crl);
+ DeleteDBCrlEntry(handle, crlKey, crlType);
/* Write the new entry into the data base */
- entry = NewDBCrlEntry(derCrl, url, type, 0);
+ entry = NewDBCrlEntry(derCrl, url, crlType, 0);
if (entry == NULL) goto done;
- rv = WriteDBCrlEntry(handle, entry);
+ rv = WriteDBCrlEntry(handle, entry, crlKey);
if (rv != SECSuccess) goto done;
done:
+ if (entry) {
+ DestroyDBEntry((certDBEntry *)entry);
+ }
return rv;
}
SECStatus
-NSSLOWCERT_DeletePermCRL(NSSLOWCERTDBHandle *handle,SECItem *derName,int type)
+nsslowcert_DeletePermCRL(NSSLOWCERTCertDBHandle *handle, SECItem *derName,
+ PRBool isKRL)
{
SECStatus rv;
+ certDBEntryType crlType = isKRL ? certDBEntryTypeKeyRevocation
+ : certDBEntryTypeRevocation;
- rv = DeleteDBCrlEntry(handle, derName, type);
+ rv = DeleteDBCrlEntry(handle, derName, crlType);
if (rv != SECSuccess) goto done;
done:
return rv;
}
+
+PRBool
+nsslowcert_hasTrust(NSSLOWCERTCertificate *cert)
+{
+ NSSLOWCERTCertTrust *trust;
+
+ if (cert->trust == NULL) {
+ return PR_FALSE;
+ }
+ trust = cert->trust;
+ return !((trust->sslFlags & CERTDB_TRUSTED_UNKNOWN) &&
+ (trust->emailFlags & CERTDB_TRUSTED_UNKNOWN) &&
+ (trust->objectSigningFlags & CERTDB_TRUSTED_UNKNOWN));
+}
+
+#ifdef notdef
/*
* find a cert by email address
*
diff --git a/security/nss/lib/softoken/pcertt.h b/security/nss/lib/softoken/pcertt.h
index f5afb22eb..69cc361ce 100644
--- a/security/nss/lib/softoken/pcertt.h
+++ b/security/nss/lib/softoken/pcertt.h
@@ -41,7 +41,7 @@
#include "prclist.h"
#include "pkcs11t.h"
#include "seccomon.h"
-#include "secmodt.h"
+/*#include "secmodt.h" */
#include "secoidt.h"
#include "plarena.h"
#include "prcvar.h"
@@ -115,21 +115,6 @@ struct NSSLOWCERTCertTrustStr {
};
/*
- * defined the types of trust that exist
- */
-typedef enum {
- trustSSL = 0,
- trustEmail = 1,
- trustObjectSigning = 2,
- trustTypeNone = 3
-} SECTrustType;
-
-#define SEC_GET_TRUST_FLAGS(trust,type) \
- (((type)==trustSSL)?((trust)->sslFlags): \
- (((type)==trustEmail)?((trust)->emailFlags): \
- (((type)==trustObjectSigning)?((trust)->objectSigningFlags):0)))
-
-/*
** An X.509 certificate object (the unsigned form)
*/
struct NSSLOWCERTCertificateStr {
diff --git a/security/nss/lib/softoken/pk11pars.h b/security/nss/lib/softoken/pk11pars.h
index 683e4f02d..9e273f104 100644
--- a/security/nss/lib/softoken/pk11pars.h
+++ b/security/nss/lib/softoken/pk11pars.h
@@ -46,7 +46,7 @@
#include "seccomon.h"
#include "prprf.h"
#include "secmodt.h"
-#include "secmodti.h"
+#include "pk11init.h"
#define PK11_ARG_LIBRARY_PARAMETER "library="
#define PK11_ARG_NAME_PARAMETER "name="
diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c
index 9d1b217a9..4105b552f 100644
--- a/security/nss/lib/softoken/pkcs11.c
+++ b/security/nss/lib/softoken/pkcs11.c
@@ -103,7 +103,7 @@ static int minimumPinLen = 0;
/* build the crypto module table */
-static CK_FUNCTION_LIST pk11_funcList = {
+static const CK_FUNCTION_LIST pk11_funcList = {
{ 1, 10 },
#undef CK_PKCS11_FUNCTION_INFO
@@ -123,7 +123,7 @@ static CK_FUNCTION_LIST pk11_funcList = {
/* List of DES Weak Keys */
typedef unsigned char desKey[8];
-static desKey pk11_desWeakTable[] = {
+static const desKey pk11_desWeakTable[] = {
#ifdef noParity
/* weak */
{ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 },
@@ -177,12 +177,12 @@ static desKey pk11_desWeakTable[] = {
};
-static int pk11_desWeakTableSize = sizeof(pk11_desWeakTable)/
+static const int pk11_desWeakTableSize = sizeof(pk11_desWeakTable)/
sizeof(pk11_desWeakTable[0]);
/* DES KEY Parity conversion table. Takes each byte/2 as an index, returns
* that byte with the proper parity bit set */
-static unsigned char parityTable[256] = {
+static const unsigned char parityTable[256] = {
/* Even...0x00,0x02,0x04,0x06,0x08,0x0a,0x0c,0x0e */
/* E */ 0x01,0x02,0x04,0x07,0x08,0x0b,0x0d,0x0e,
/* Odd....0x10,0x12,0x14,0x16,0x18,0x1a,0x1c,0x1e */
@@ -238,7 +238,9 @@ struct mechanismList {
#define CKF_SN_VR_RE CKF_SN_VR | CKF_SN_RE
#define CKF_DUZ_IT_ALL CKF_EN_DE_WR_UN | CKF_SN_VR_RE
-static struct mechanismList mechanisms[] = {
+#define CK_MAX 0xffffffff
+
+static const struct mechanismList mechanisms[] = {
/*
* PKCS #11 Mechanism List.
@@ -261,16 +263,16 @@ static struct mechanismList mechanisms[] = {
*/
/* ------------------------- RSA Operations ---------------------------*/
- {CKM_RSA_PKCS_KEY_PAIR_GEN,{128,0xffffffff,CKF_GENERATE_KEY_PAIR},PR_TRUE},
- {CKM_RSA_PKCS, {128,0xffffffff, CKF_DUZ_IT_ALL},PR_TRUE},
+ {CKM_RSA_PKCS_KEY_PAIR_GEN,{128,CK_MAX,CKF_GENERATE_KEY_PAIR},PR_TRUE},
+ {CKM_RSA_PKCS, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
#ifdef PK11_RSA9796_SUPPORTED
- {CKM_RSA_9796, {128,0xffffffff, CKF_DUZ_IT_ALL},PR_TRUE},
+ {CKM_RSA_9796, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
#endif
- {CKM_RSA_X_509, {128,0xffffffff, CKF_DUZ_IT_ALL},PR_TRUE},
+ {CKM_RSA_X_509, {128,CK_MAX,CKF_DUZ_IT_ALL}, PR_TRUE},
/* -------------- RSA Multipart Signing Operations -------------------- */
- {CKM_MD2_RSA_PKCS, {128,0xffffffff, CKF_SN_VR}, PR_TRUE},
- {CKM_MD5_RSA_PKCS, {128,0xffffffff, CKF_SN_VR}, PR_TRUE},
- {CKM_SHA1_RSA_PKCS, {128,0xffffffff, CKF_SN_VR}, PR_TRUE},
+ {CKM_MD2_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
+ {CKM_MD5_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
+ {CKM_SHA1_RSA_PKCS, {128,CK_MAX,CKF_SN_VR}, PR_TRUE},
/* ------------------------- DSA Operations --------------------------- */
{CKM_DSA_KEY_PAIR_GEN, {512, 1024, CKF_GENERATE_KEY_PAIR}, PR_TRUE},
{CKM_DSA, {512, 1024, CKF_SN_VR}, PR_TRUE},
@@ -329,7 +331,7 @@ static struct mechanismList mechanisms[] = {
{CKM_SHA_1_HMAC_GENERAL, {1, 128, CKF_SN_VR}, PR_FALSE},
{CKM_TLS_PRF_GENERAL, {0, 512, CKF_SN_VR}, PR_FALSE},
/* ------------------------- CAST Operations --------------------------- */
-#ifdef PK11_CAST_SUPPORTED
+#ifdef NSS_SOFTOKEN_DOES_CAST
/* Cast operations are not supported ( yet? ) */
{CKM_CAST_KEY_GEN, {1, 8, CKF_GENERATE}, PR_FALSE},
{CKM_CAST_ECB, {1, 8, CKF_EN_DE_WR_UN}, PR_FALSE},
@@ -353,13 +355,13 @@ static struct mechanismList mechanisms[] = {
#if NSS_SOFTOKEN_DOES_RC5
/* ------------------------- RC5 Operations --------------------------- */
{CKM_RC5_KEY_GEN, {1, 32, CKF_GENERATE}, PR_FALSE},
- {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
+ {CKM_RC5_ECB, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
{CKM_RC5_CBC, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
{CKM_RC5_MAC, {1, 32, CKF_SN_VR}, PR_FALSE},
{CKM_RC5_MAC_GENERAL, {1, 32, CKF_SN_VR}, PR_FALSE},
{CKM_RC5_CBC_PAD, {1, 32, CKF_EN_DE_WR_UN}, PR_FALSE},
#endif
-#ifdef PK11_IDEA_SUPPORTED
+#ifdef NSS_SOFTOKEN_DOES_IDEA
/* ------------------------- IDEA Operations -------------------------- */
{CKM_IDEA_KEY_GEN, {16, 16, CKF_GENERATE}, PR_FALSE},
{CKM_IDEA_ECB, {16, 16, CKF_EN_DE_WR_UN}, PR_FALSE},
@@ -393,12 +395,7 @@ static struct mechanismList mechanisms[] = {
{CKM_PBE_MD5_DES_CBC, {8, 8, CKF_DERIVE}, PR_TRUE},
/* ------------------ NETSCAPE PBE Key Derivations ------------------- */
{CKM_NETSCAPE_PBE_SHA1_DES_CBC, { 8, 8, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
{CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, {40,40, CKF_GENERATE}, PR_TRUE},
- {CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, {128,128, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_DES3_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_DES2_EDE_CBC, {24,24, CKF_GENERATE}, PR_TRUE},
{CKM_PBE_SHA1_RC2_40_CBC, {40,40, CKF_GENERATE}, PR_TRUE},
@@ -410,9 +407,6 @@ static struct mechanismList mechanisms[] = {
{CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN, {1,32, CKF_GENERATE}, PR_TRUE},
};
static CK_ULONG mechanismCount = sizeof(mechanisms)/sizeof(mechanisms[0]);
-/* load up our token database */
-static CK_RV pk11_importKeyDB(PK11Slot *slot);
-
static char *
pk11_setStringName(char *inString, char *buffer, int buffer_length) {
@@ -478,17 +472,6 @@ pk11_configure(char *man, char *libdes, char *tokdes, char *ptokdes,
* ******************** Password Utilities *******************************
*/
-/* Handle to give the password to the database. user arg should be a pointer
- * to the slot. */
-static SECItem *pk11_givePass(void *sp,NSSLOWKEYDBHandle *handle)
-{
- PK11Slot *slot = (PK11Slot *)sp;
-
- if (slot->password == NULL) return NULL;
-
- return SECITEM_DupItem(slot->password);
-}
-
/*
* see if the key DB password is enabled
*/
@@ -560,13 +543,13 @@ pk11_handleDataObject(PK11Session *session,PK11Object *object)
static CK_RV
pk11_handleCertObject(PK11Session *session,PK11Object *object)
{
- PK11Attribute *attribute;
CK_CERTIFICATE_TYPE type;
- SECItem derCert;
+ PK11Attribute *attribute;
char *label;
- NSSLOWCERTCertDBHandle *handle;
- NSSLOWCERTCertificate *cert;
CK_RV crv;
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ PORT_Assert(sessObject);
/* certificates must have a type */
if ( !pk11_hasAttribute(object,CKA_CERTIFICATE_TYPE) ) {
@@ -600,73 +583,286 @@ pk11_handleCertObject(PK11Session *session,PK11Object *object)
return CKR_TEMPLATE_INCOMPLETE;
}
- /* get the nickname */
- label = pk11_getString(object,CKA_LABEL);
- object->label = label;
- if (label == NULL) {
- return CKR_HOST_MEMORY;
+ /* in PKCS #11, Issuer is a required field */
+ if ( !pk11_hasAttribute(object,CKA_ISSUER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+
+ /* in PKCS #11, Serial is a required field */
+ if ( !pk11_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
}
/* add it to the object */
- object->objectInfo = cert;
- object->infoFree = (PK11Free) nsslowcert_DestroyCertificate;
+ object->objectInfo = NULL;
+ object->infoFree = (PK11Free) NULL;
/* now just verify the required date fields */
crv = pk11_defaultAttribute(object, CKA_ID, NULL, 0);
if (crv != CKR_OK) { return crv; }
- crv = pk11_defaultAttribute(object,CKA_ISSUER,
- pk11_item_expand(&cert->derIssuer));
- if (crv != CKR_OK) { return crv; }
- crv = pk11_defaultAttribute(object,CKA_SERIAL_NUMBER,
- pk11_item_expand(&cert->serialNumber));
- if (crv != CKR_OK) { return crv; }
-
if (pk11_isTrue(object,CKA_TOKEN)) {
- NSSLOWCERTCertTrust trust = { CERTDB_USER, CERTDB_USER, CERTDB_USER };
PK11Slot *slot = session->slot;
- PRBool isUser = PR_FALSE;
+ SECItem derCert;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertTrust *trust = NULL;
+ NSSLOWCERTCertTrust userTrust =
+ { CERTDB_USER, CERTDB_USER, CERTDB_USER };
+ SECStatus rv;
if (slot->certDB == NULL) {
return CKR_TOKEN_WRITE_PROTECTED;
}
- if (slot->keyDB &&
- ((nsslowkey_KeyForCertExists(slot->keyDB, cert) == SECSuccess))) {
- isUser = PR_TRUE;
- }
-
/* get the der cert */
attribute = pk11_FindAttribute(object,CKA_VALUE);
derCert.data = (unsigned char *)attribute->attrib.pValue;
derCert.len = attribute->attrib.ulValueLen ;
- if (nsslowcert_CertDBKeyConflict(&derCert,slot->certDB)) {
- /* cert already exists in the database, update the status of the
- * user bits */
- nsslowcert_ChangeCertTrust(cert->dbhandle,cert,&trust);
+ cert = nsslowcert_DecodeDERCertificate(&derCert,PR_FALSE,label);
+ if (cert == NULL) {
+ pk11_FreeAttribute(attribute);
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ if (slot->keyDB && nsslowkey_KeyForCertExists(slot->keyDB,cert)) {
+ trust = &userTrust;
+ }
+ if (!nsslowcert_CertDBKeyConflict(&derCert,slot->certDB)) {
+ rv = nsslowcert_AddPermCert(cert,label, trust);
} else {
- SECStatus rv;
- cert = nsslowcert_DecodeDERCertificate(&derCert,PR_FALSE,label);
- if (cert == NULL) {
- pk11_FreeAttribute(attribute);
- return CKR_ATTRIBUTE_VALUE_INVALID;
- }
- rv = nsslowcert_AddPermCert(cert,label,isUser ? &trust : NULL);
+ rv = trust ? nsslowcert_ChangeCertTrust(slot->certDB,cert,trust) :
+ SECSuccess;
+ }
+
+ pk11_FreeAttribute(attribute);
+ if (rv != SECSuccess) {
nsslowcert_DestroyCertificate(cert);
- if (rv != SECSuccess) {
- pk11_FreeAttribute(attribute);
- return CKR_DEVICE_ERROR;
+ return CKR_DEVICE_ERROR;
+ }
+ object->handle=pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_CERT);
+ nsslowcert_DestroyCertificate(cert);
+ }
+
+ return CKR_OK;
+}
+static unsigned int
+pk11_MapTrust(CK_TRUST trust, PRBool clientAuth)
+{
+ unsigned int trustCA = clientAuth ? CERTDB_TRUSTED_CLIENT_CA :
+ CERTDB_TRUSTED_CA;
+ switch (trust) {
+ case CKT_NETSCAPE_TRUSTED:
+ return CERTDB_VALID_PEER|CERTDB_TRUSTED;
+ case CKT_NETSCAPE_TRUSTED_DELEGATOR:
+ return CERTDB_VALID_CA|trustCA;
+ case CKT_NETSCAPE_UNTRUSTED:
+ return CERTDB_NOT_TRUSTED;
+ case CKT_NETSCAPE_MUST_VERIFY:
+ return 0;
+ case CKT_NETSCAPE_VALID: /* implies must verify */
+ return CERTDB_VALID_PEER;
+ case CKT_NETSCAPE_VALID_DELEGATOR: /* implies must verify */
+ return CERTDB_VALID_CA;
+ default:
+ break;
+ }
+ return CERTDB_TRUSTED_UNKNOWN;
+}
+
+
+/*
+ * check the consistancy and initialize a Trust Object
+ */
+static CK_RV
+pk11_handleTrustObject(PK11Session *session,PK11Object *object)
+{
+ PK11Attribute *attribute;
+ CK_CERTIFICATE_TYPE type;
+ SECItem derCert;
+ char *label;
+ NSSLOWCERTCertDBHandle *handle;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTIssuerAndSN issuerSN;
+ CK_RV crv;
+
+ /* 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_ISSUER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_SERIAL_NUMBER) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_CERT_SHA1_HASH) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+ if ( !pk11_hasAttribute(object,CKA_CERT_MD5_HASH) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
+ PK11Attribute *issuer = NULL;
+ PK11Attribute *serial = NULL;
+ NSSLOWCERTCertificate *cert = NULL;
+ PK11Attribute *trust;
+ CK_TRUST sslTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ CK_TRUST clientTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ CK_TRUST emailTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ CK_TRUST signTrust = CKT_NETSCAPE_TRUST_UNKNOWN;
+ NSSLOWCERTCertTrust dbTrust;
+ SECStatus rv;
+
+
+ if (slot->certDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+ issuer = pk11_FindAttribute(object,CKA_ISSUER);
+ PORT_Assert(issuer);
+ issuerSN.derIssuer.data = (unsigned char *)issuer->attrib.pValue;
+ issuerSN.derIssuer.len = issuer->attrib.ulValueLen ;
+
+ serial = pk11_FindAttribute(object,CKA_SERIAL_NUMBER);
+ PORT_Assert(serial);
+ issuerSN.serialNumber.data = (unsigned char *)serial->attrib.pValue;
+ issuerSN.serialNumber.len = serial->attrib.ulValueLen ;
+
+ cert = nsslowcert_FindCertByIssuerAndSN(slot->certDB,&issuerSN);
+ pk11_FreeAttribute(serial);
+ pk11_FreeAttribute(issuer);
+
+ if (cert == NULL) {
+ return CKR_ATTRIBUTE_VALUE_INVALID;
+ }
+
+ trust = pk11_FindAttribute(object,CKA_TRUST_SERVER_AUTH);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&sslTrust,trust->attrib.pValue, sizeof(sslTrust));
}
+ pk11_FreeAttribute(trust);
+ }
+ trust = pk11_FindAttribute(object,CKA_TRUST_CLIENT_AUTH);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&clientTrust,trust->attrib.pValue,
+ sizeof(clientTrust));
+ }
+ pk11_FreeAttribute(trust);
+ }
+ trust = pk11_FindAttribute(object,CKA_TRUST_EMAIL_PROTECTION);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&emailTrust,trust->attrib.pValue,
+ sizeof(emailTrust));
+ }
+ pk11_FreeAttribute(trust);
+ }
+ trust = pk11_FindAttribute(object,CKA_TRUST_CODE_SIGNING);
+ if (trust) {
+ if (trust->attrib.ulValueLen == sizeof(CK_TRUST)) {
+ PORT_Memcpy(&signTrust,trust->attrib.pValue,
+ sizeof(signTrust));
+ }
+ pk11_FreeAttribute(trust);
+ }
+
+ /* preserve certain old fields */
+ if (cert->trust) {
+ dbTrust.sslFlags =
+ cert->trust->sslFlags & CERTDB_PRESERVE_TRUST_BITS;
+ dbTrust.emailFlags=
+ cert->trust->emailFlags & CERTDB_PRESERVE_TRUST_BITS;
+ dbTrust.objectSigningFlags =
+ cert->trust->objectSigningFlags & CERTDB_PRESERVE_TRUST_BITS;
}
- pk11_FreeAttribute(attribute);
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
- object->inDB = PR_TRUE;
+ dbTrust.sslFlags = pk11_MapTrust(sslTrust,PR_FALSE);
+ dbTrust.sslFlags |= pk11_MapTrust(clientTrust,PR_TRUE);
+ dbTrust.emailFlags = pk11_MapTrust(emailTrust,PR_FALSE);
+ dbTrust.objectSigningFlags = pk11_MapTrust(signTrust,FALSE);
+
+ rv = nsslowcert_ChangeCertTrust(slot->certDB,cert,&dbTrust);
+ object->handle=pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_TRUST);
+ nsslowcert_DestroyCertificate(cert);
+ if (rv != SECSuccess) {
+ return CKR_DEVICE_ERROR;
+ }
+ }
+
+ return CKR_OK;
+}
+
+/*
+ * check the consistancy and initialize a Trust Object
+ */
+static CK_RV
+pk11_handleCrlObject(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_VALUE) ) {
+ return CKR_TEMPLATE_INCOMPLETE;
+ }
+
+ if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
+ PRBool isKRL = PR_FALSE;
+ SECItem derSubj,derCrl;
+ char *url = NULL;
+ PK11Attribute *subject,*crl;
+ 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 */
+ crl = pk11_FindAttribute(object,CKA_VALUE);
+ PORT_Assert(crl);
+ derCrl.data = (unsigned char *)crl->attrib.pValue;
+ derCrl.len = crl->attrib.ulValueLen ;
- /* label has been adopted by object->label */
- /*PORT_Free(label); */
+
+ url = pk11_getString(object,CKA_NETSCAPE_URL);
+ isKRL = pk11_isTrue(object,CKA_NETSCAPE_KRL);
+
+ /* Store CRL by SUBJECT */
+ rv = nsslowcert_AddCrl(slot->certDB, &derCrl, &derSubj, url, isKRL);
+
+ if (url) {
+ PORT_Free(label);
+ }
+ pk11_FreeAttribute(crl);
+ if (rv != SECSuccess) {
+ pk11_FreeAttribute(subject);
+ return CKR_DEVICE_ERROR;
+ }
+
+ object->handle = pk11_mkHandle(slot,&derSubj,PK11_TOKEN_TYPE_CRL);
+ pk11_FreeAttribute(subject);
+ }
return CKR_OK;
}
@@ -676,12 +872,16 @@ NSSLOWKEYPublicKey * pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key);
* check the consistancy and initialize a Public Key Object
*/
static CK_RV
-pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
+pk11_handlePublicKeyObject(PK11Session *session, PK11Object *object,
+ CK_KEY_TYPE key_type)
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
CK_BBOOL recover = CK_TRUE;
CK_BBOOL wrap = CK_TRUE;
+ CK_BBOOL derive = CK_FALSE;
+ CK_BBOOL verify = CK_TRUE;
+ CK_ATTRIBUTE_TYPE pubKeyAttr = CKA_VALUE;
CK_RV crv;
switch (key_type) {
@@ -692,6 +892,7 @@ pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if ( !pk11_hasAttribute(object, CKA_PUBLIC_EXPONENT)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ pubKeyAttr = CKA_MODULUS;
break;
case CKK_DSA:
if ( !pk11_hasAttribute(object, CKA_SUBPRIME)) {
@@ -707,6 +908,10 @@ pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if ( !pk11_hasAttribute(object, CKA_VALUE)) {
return CKR_TEMPLATE_INCOMPLETE;
}
+ if (key_type == CKK_DH) {
+ verify = CK_FALSE;
+ derive = CK_TRUE;
+ }
encrypt = CK_FALSE;
recover = CK_FALSE;
wrap = CK_FALSE;
@@ -720,147 +925,47 @@ pk11_handlePublicKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_ENCRYPT,&encrypt,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
- crv = pk11_defaultAttribute(object,CKA_VERIFY,&cktrue,sizeof(CK_BBOOL));
+ crv = pk11_defaultAttribute(object,CKA_VERIFY,&verify,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_VERIFY_RECOVER,
&recover,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
crv = pk11_defaultAttribute(object,CKA_WRAP,&wrap,sizeof(CK_BBOOL));
if (crv != CKR_OK) return crv;
+ crv = pk11_defaultAttribute(object,CKA_DERIVE,&derive,sizeof(CK_BBOOL));
+ if (crv != CKR_OK) return crv;
object->objectInfo = pk11_GetPubKey(object,key_type);
object->infoFree = (PK11Free) nsslowkey_DestroyPublicKey;
if (pk11_isTrue(object,CKA_TOKEN)) {
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);
- }
-
- return CKR_OK;
-}
-/* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
-static SECItem *
-pk11_GetPubItem(NSSLOWKEYPublicKey *pubKey) {
- SECItem *pubItem = NULL;
- /* get value to compare from the cert's public key */
- switch ( pubKey->keyType ) {
- case NSSLOWKEYRSAKey:
- pubItem = &pubKey->u.rsa.modulus;
- break;
- case NSSLOWKEYDSAKey:
- pubItem = &pubKey->u.dsa.publicValue;
- break;
- case NSSLOWKEYDHKey:
- pubItem = &pubKey->u.dh.publicValue;
- break;
- default:
- break;
- }
- return pubItem;
-}
-
-typedef struct {
- NSSLOWCERTCertificate *cert;
- SECItem *pubKey;
-} find_cert_callback_arg;
-
-static SECStatus
-find_cert_by_pub_key(NSSLOWCERTCertificate *cert, SECItem *k, void *arg)
-{
- find_cert_callback_arg *cbarg;
- NSSLOWKEYPublicKey *pubKey = NULL;
- SECItem *pubItem;
-
- if((cert == NULL) || (arg == NULL)) {
- return SECFailure;
- }
-
- /* if this cert doesn't look like a user cert, we aren't interested */
- if (!((cert->trust) &&
- (( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER )) &&
- ( cert->nickname != NULL ) ) ) {
- goto done;
- }
-
- /* get cert's public key */
- pubKey = nsslowcert_ExtractPublicKey(cert);
- if ( pubKey == NULL ) {
- goto done;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
- pubItem = pk11_GetPubItem(pubKey);
- if (pubItem == NULL) goto done;
-
- cbarg = (find_cert_callback_arg *)arg;
-
- if(SECITEM_CompareItem(pubItem, cbarg->pubKey) == SECEqual) {
- cbarg->cert = nsslowcert_DupCertificate(cert);
- return SECFailure;
- }
-
-done:
- if ( pubKey ) {
- nsslowkey_DestroyPublicKey(pubKey);
- }
-
- return (SECSuccess);
-}
-
-static PK11Object *pk11_importCertificate(PK11Slot *slot,NSSLOWCERTCertificate *cert,
- unsigned char *data, unsigned int size, PRBool needCert);
-/*
- * find a cert associated with the key and load it.
- */
-static SECStatus
-reload_existing_certificate(PK11Object *privKeyObject,SECItem *pubKey)
-{
- find_cert_callback_arg cbarg;
- SECItem nickName;
- NSSLOWCERTCertificate *cert = NULL;
- CK_RV crv;
- SECStatus rv;
+ PK11Slot *slot = session->slot;
+ NSSLOWKEYPrivateKey *priv;
+ SECItem pubKey;
- PORT_Assert(privKeyObject->slot->certDB);
- if (privKeyObject->slot->certDB == NULL) return SECFailure;
-
- cbarg.pubKey = pubKey;
- cbarg.cert = NULL;
- nsslowcert_TraversePermCerts(privKeyObject->slot->certDB,
- find_cert_by_pub_key, (void *)&cbarg);
- if (cbarg.cert != NULL) {
- NSSLOWCERTCertificate *cert = NULL;
- cert = cbarg.cert;
+ crv = pk11_Attribute2SecItem(NULL,&pubKey,object,pubKeyAttr);
+ if (crv != CKR_OK) return crv;
- if (cert && !cert->nickname) {
- crv=pk11_Attribute2SecItem(NULL,&nickName,privKeyObject,CKA_LABEL);
- if (crv != CKR_OK) {
- goto loser;
- }
- rv = nsslowcert_AddPermNickname(cert, (char *)nickName.data);
- SECITEM_ZfreeItem(&nickName, PR_FALSE);
- if (rv != SECSuccess) {
- goto loser;
- }
+ PORT_Assert(pubKey.data);
+ if (slot->keyDB == NULL) {
+ PORT_Free(pubKey.data);
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+ /* make sure the associated private key already exists */
+ /* only works if we are logged in */
+ priv = nsslowkey_FindKeyByPublicKey(slot->keyDB, &pubKey,
+ slot->password);
+ if (priv == NULL) {
+ PORT_Free(pubKey.data);
+ return CKR_ATTRIBUTE_VALUE_INVALID;
}
+ nsslowkey_DestroyPrivateKey(priv);
- /* associate the certificate with the key */
- pk11_importCertificate(privKeyObject->slot, cert, pubKey->data,
- pubKey->len, PR_FALSE);
+ object->handle = pk11_mkHandle(slot, &pubKey, PK11_TOKEN_TYPE_PUB);
+ PORT_Free(pubKey.data);
}
- return SECSuccess;
-loser:
- if (cbarg.cert) nsslowcert_DestroyCertificate(cbarg.cert);
- return SECFailure;
+ return CKR_OK;
}
static NSSLOWKEYPrivateKey * pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key);
@@ -868,7 +973,7 @@ static NSSLOWKEYPrivateKey * pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key);
* check the consistancy and initialize a Private Key Object
*/
static CK_RV
-pk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
+pk11_handlePrivateKeyObject(PK11Session *session,PK11Object *object,CK_KEY_TYPE key_type)
{
CK_BBOOL cktrue = CK_TRUE;
CK_BBOOL encrypt = CK_TRUE;
@@ -961,37 +1066,33 @@ pk11_handlePrivateKeyObject(PK11Object *object,CK_KEY_TYPE key_type)
if (crv != CKR_OK) return crv;
if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
NSSLOWKEYPrivateKey *privKey;
char *label;
SECStatus rv = SECSuccess;
SECItem pubKey;
+ if (slot->keyDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
+
privKey=pk11_mkPrivKey(object,key_type);
if (privKey == NULL) return CKR_HOST_MEMORY;
- label = object->label = pk11_getString(object,CKA_LABEL);
+ label = pk11_getString(object,CKA_LABEL);
crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv == CKR_OK) {
- PORT_Assert(object->slot->keyDB);
- rv = nsslowkey_StoreKeyByPublicKey(object->slot->keyDB,
- privKey, &pubKey, label,
- (NSSLOWKEYGetPasswordKey) pk11_givePass, object->slot);
-
- /* check for the existance of an existing certificate and activate
- * it if necessary */
- if (rv == SECSuccess) {
- reload_existing_certificate(object,&pubKey);
- }
-
- if (pubKey.data) PORT_Free(pubKey.data);
- } else {
- rv = SECFailure;
+ if (crv != CKR_OK) {
+ nsslowkey_DestroyPrivateKey(privKey);
+ return CKR_TEMPLATE_INCOMPLETE;
}
+ rv = nsslowkey_StoreKeyByPublicKey(object->slot->keyDB,
+ privKey, &pubKey, label, object->slot->password);
+
+ object->handle = pk11_mkHandle(slot,&pubKey,PK11_TOKEN_TYPE_PRIV);
+ if (pubKey.data) PORT_Free(pubKey.data);
nsslowkey_DestroyPrivateKey(privKey);
if (rv != SECSuccess) return CKR_DEVICE_ERROR;
- object->inDB = PR_TRUE;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
} else {
object->objectInfo = pk11_mkPrivKey(object,key_type);
if (object->objectInfo == NULL) return CKR_HOST_MEMORY;
@@ -1015,7 +1116,8 @@ static NSSLOWKEYPrivateKey *pk11_mkSecretKeyRep(PK11Object *object);
/* Validate secret key data, and set defaults */
static CK_RV
-validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
+validateSecretKey(PK11Session *session, PK11Object *object,
+ CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
CK_BBOOL cktrue = CK_TRUE;
@@ -1061,9 +1163,14 @@ validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
#if NSS_SOFTOKEN_DOES_RC5
case CKK_RC5:
#endif
+#ifdef NSS_SOFTOKEN_DOES_CAST
case CKK_CAST:
case CKK_CAST3:
case CKK_CAST5:
+#endif
+#if NSS_SOFTOKEN_DOES_IDEA
+ case CKK_IDEA:
+#endif
attribute = pk11_FindAttribute(object,CKA_VALUE);
/* shouldn't happen */
if (attribute == NULL) return CKR_TEMPLATE_INCOMPLETE;
@@ -1093,8 +1200,8 @@ validateSecretKey(PK11Object *object, CK_KEY_TYPE key_type, PRBool isFIPS)
* check the consistancy and initialize a Secret Key Object
*/
static CK_RV
-pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
- PRBool isFIPS)
+pk11_handleSecretKeyObject(PK11Session *session,PK11Object *object,
+ CK_KEY_TYPE key_type, PRBool isFIPS)
{
CK_RV crv;
NSSLOWKEYPrivateKey *privKey = NULL;
@@ -1103,32 +1210,36 @@ pk11_handleSecretKeyObject(PK11Object *object,CK_KEY_TYPE key_type,
pubKey.data = 0;
/* First validate and set defaults */
- crv = validateSecretKey(object, key_type, isFIPS);
+ crv = validateSecretKey(session, object, key_type, isFIPS);
if (crv != CKR_OK) goto loser;
/* If the object is a TOKEN object, store in the database */
if (pk11_isTrue(object,CKA_TOKEN)) {
+ PK11Slot *slot = session->slot;
char *label;
SECStatus rv = SECSuccess;
+ if (slot->keyDB == NULL) {
+ return CKR_TOKEN_WRITE_PROTECTED;
+ }
privKey=pk11_mkSecretKeyRep(object);
if (privKey == NULL) return CKR_HOST_MEMORY;
- label = object->label = pk11_getString(object,CKA_LABEL);
+ label = pk11_getString(object,CKA_LABEL);
- crv = pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_ID); /* Should this be ID? */
+ crv = pk11_Attribute2SecItem(NULL, &pubKey, object, CKA_ID);
+ /* Should this be ID? */
if (crv != CKR_OK) goto loser;
- PORT_Assert(object->slot->keyDB);
- rv = nsslowkey_StoreKeyByPublicKey(object->slot->keyDB,
- privKey, &pubKey, label,
- (NSSLOWKEYGetPasswordKey) pk11_givePass, object->slot);
+ PORT_Assert(slot->keyDB);
+ rv = nsslowkey_StoreKeyByPublicKey(slot->keyDB,
+ privKey, &pubKey, label, slot->password);
if (rv != SECSuccess) {
crv = CKR_DEVICE_ERROR;
+ goto loser;
}
- object->inDB = PR_TRUE;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
+ object->handle = pk11_mkHandle(slot,&pubKey,PK11_TOKEN_TYPE_PRIV);
}
loser:
@@ -1174,12 +1285,12 @@ pk11_handleKeyObject(PK11Session *session, PK11Object *object)
switch (object->objclass) {
case CKO_PUBLIC_KEY:
- return pk11_handlePublicKeyObject(object,key_type);
+ return pk11_handlePublicKeyObject(session,object,key_type);
case CKO_PRIVATE_KEY:
- return pk11_handlePrivateKeyObject(object,key_type);
+ return pk11_handlePrivateKeyObject(session,object,key_type);
case CKO_SECRET_KEY:
/* make sure the required fields exist */
- return pk11_handleSecretKeyObject(object,key_type,
+ return pk11_handleSecretKeyObject(session,object,key_type,
(PRBool)(session->slot->slotID == FIPS_SLOT_ID));
default:
break;
@@ -1224,17 +1335,6 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
(pk11_isTrue(object,CKA_TOKEN))) {
return CKR_SESSION_READ_ONLY;
}
-
- if (pk11_isTrue(object, CKA_TOKEN)) {
- if (slot->DB_loaded == PR_FALSE) {
- /* we are creating a token object, make sure we load the database
- * first so we don't get duplicates....
- * ... NOTE: This assumes we are logged in as well!
- */
- pk11_importKeyDB(slot);
- slot->DB_loaded = PR_TRUE;
- }
- }
/* PKCS #11 object ID's are unique for all objects on a
* token */
@@ -1255,9 +1355,16 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
switch (object->objclass) {
case CKO_DATA:
crv = pk11_handleDataObject(session,object);
+ break;
case CKO_CERTIFICATE:
crv = pk11_handleCertObject(session,object);
break;
+ case CKO_NETSCAPE_TRUST:
+ crv = pk11_handleTrustObject(session,object);
+ break;
+ case CKO_NETSCAPE_CRL:
+ crv = pk11_handleCrlObject(session,object);
+ break;
case CKO_PRIVATE_KEY:
case CKO_PUBLIC_KEY:
case CKO_SECRET_KEY:
@@ -1275,649 +1382,14 @@ pk11_handleObject(PK11Object *object, PK11Session *session)
}
/* now link the object into the slot and session structures */
- object->slot = slot;
- pk11_AddObject(session,object);
-
- return CKR_OK;
-}
-
-/* import a private key as an object. We don't call handle object.
- * because we the private key came from the key DB and we don't want to
- * write back out again */
-static PK11Object *
-pk11_importPrivateKey(PK11Slot *slot,NSSLOWKEYPrivateKey *lowPriv,
- SECItem *dbKey)
-{
- PK11Object *privateKey;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL sign = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL decrypt = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS privClass = CKO_PRIVATE_KEY;
- unsigned char cka_id[SHA1_LENGTH];
-
- /*
- * now lets create an object to hang the attributes off of
- */
- privateKey = pk11_NewObject(slot); /* fill in the handle later */
- if (privateKey == NULL) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* Netscape Private Attribute for dealing with database storeage */
- if (pk11_AddAttributeType(privateKey, CKA_NETSCAPE_DB,
- pk11_item_expand(dbKey)) ) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* now force the CKA_ID */
- SHA1_HashBuf(cka_id, (unsigned char *)dbKey->data, (uint32)dbKey->len);
- if (pk11_AddAttributeType(privateKey, CKA_ID, cka_id, sizeof(cka_id))) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
-
- /* Fill in the common Default values */
- if (pk11_AddAttributeType(privateKey,CKA_CLASS, &privClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_PRIVATE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_LABEL, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DERIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- /* local: well we really don't know for sure... it could have been an
- * imported key, but it's not a useful attribute anyway. */
- if (pk11_AddAttributeType(privateKey,CKA_LOCAL, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SENSITIVE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_EXTRACTABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- /* is this really true? Maybe we should just say false here? */
- if (pk11_AddAttributeType(privateKey,CKA_ALWAYS_SENSITIVE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_NEVER_EXTRACTABLE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- /* NOTE: for safety sake we *DO NOT* remember critical attributes. PKCS #11
- * will look them up again from the database when it needs them.
- */
- switch (lowPriv->keyType) {
- case NSSLOWKEYRSAKey:
- /* format the keys */
- key_type = CKK_RSA;
- sign = CK_TRUE;
- recover = CK_TRUE;
- decrypt = CK_TRUE;
- derive = CK_FALSE;
- /* now fill in the RSA dependent parameters in the public key */
- crv = pk11_AddAttributeType(privateKey,CKA_MODULUS,
- pk11_item_expand(&lowPriv->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIVATE_EXPONENT,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lowPriv->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_1,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME_2,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_1,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_EXPONENT_2,NULL,0);
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_COEFFICIENT,NULL,0);
- break;
- case NSSLOWKEYDSAKey:
- key_type = CKK_DSA;
- sign = CK_TRUE;
- recover = CK_FALSE;
- decrypt = CK_FALSE;
- derive = CK_FALSE;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_SUBPRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_VALUE,NULL,0);
- if (crv != CKR_OK) break;
- break;
- case NSSLOWKEYDHKey:
- key_type = CKK_DH;
- sign = CK_FALSE;
- decrypt = CK_FALSE;
- recover = CK_FALSE;
- derive = CK_TRUE;
- crv = pk11_AddAttributeType(privateKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dh.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dh.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(privateKey,CKA_VALUE,NULL,0);
- if (crv != CKR_OK) break;
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (crv != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
-
-
- if (pk11_AddAttributeType(privateKey,CKA_SIGN, &sign,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_SIGN_RECOVER, &recover,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DECRYPT, &decrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_UNWRAP, &decrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_DERIVE, &derive,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- if (pk11_AddAttributeType(privateKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- pk11_FreeObject(privateKey);
- return NULL;
- }
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- privateKey->handle = slot->tokenIDCount++;
- privateKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- privateKey->objclass = privClass;
- privateKey->slot = slot;
- privateKey->inDB = PR_TRUE;
-
- return privateKey;
-}
-
-/* import a private key or cert as a public key object.*/
-static PK11Object *
-pk11_importPublicKey(PK11Slot *slot,
- NSSLOWKEYPrivateKey *lowPriv, NSSLOWCERTCertificate *cert, SECItem *dbKey)
-{
- PK11Object *publicKey = NULL;
- CK_KEY_TYPE key_type;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_BBOOL verify = CK_TRUE;
- CK_BBOOL recover = CK_TRUE;
- CK_BBOOL encrypt = CK_TRUE;
- CK_BBOOL derive = CK_FALSE;
- CK_RV crv = CKR_OK;
- CK_OBJECT_CLASS pubClass = CKO_PUBLIC_KEY;
- unsigned char cka_id[SHA1_LENGTH];
- NSSLOWKEYType keyType = NSSLOWKEYNullKey;
- NSSLOWKEYPublicKey *pubKey = NULL;
- CK_ATTRIBUTE theTemplate[2];
- PK11ObjectListElement *objectList = NULL;
-
- if (lowPriv == NULL) {
- pubKey = nsslowcert_ExtractPublicKey(cert);
- if (pubKey == NULL) {
- goto failed;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise. All callers
- * should include this comment.
- */
- dbKey = pk11_GetPubItem(pubKey);
- if (dbKey == NULL) {
- goto failed;
- }
- }
- SHA1_HashBuf(cka_id, (unsigned char *)dbKey->data, (uint32)dbKey->len);
- theTemplate[0].type = CKA_ID;
- theTemplate[0].pValue = cka_id;
- theTemplate[0].ulValueLen = sizeof(cka_id);
- theTemplate[1].type = CKA_CLASS;
- theTemplate[1].pValue = &pubClass;
- theTemplate[1].ulValueLen = sizeof(CK_OBJECT_CLASS);
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, theTemplate, 2, slot->isLoggedIn);
- if ((crv == CKR_OK) && (objectList != NULL)) {
- goto failed;
- }
- /*
- * now lets create an object to hang the attributes off of
- */
- publicKey = pk11_NewObject(slot); /* fill in the handle later */
- if (publicKey == NULL) {
- goto failed;
- }
-
- /* now force the CKA_ID */
- if (pk11_AddAttributeType(publicKey, CKA_ID, cka_id, sizeof(cka_id))) {
- goto failed;
- }
-
- /* Fill in the common Default values */
- if (pk11_AddAttributeType(publicKey,CKA_CLASS,&pubClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_LABEL, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_START_DATE, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_END_DATE, NULL, 0) != CKR_OK) {
- goto failed;
- }
- /* local: well we really don't know for sure... it could have been an
- * imported key, but it's not a useful attribute anyway. */
- if (pk11_AddAttributeType(publicKey,CKA_LOCAL, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_SUBJECT, NULL, 0) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_SENSITIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_EXTRACTABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_ALWAYS_SENSITIVE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_NEVER_EXTRACTABLE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
-
- /* Now Set up the parameters to generate the key (based on mechanism) */
- if (lowPriv == NULL) {
- keyType = pubKey->keyType;
- } else {
- keyType = lowPriv->keyType;
- }
-
-
- switch (keyType) {
- case NSSLOWKEYRSAKey:
- /* format the keys */
- key_type = CKK_RSA;
- verify = CK_TRUE;
- recover = CK_TRUE;
- encrypt = CK_TRUE;
- derive = CK_FALSE;
- /* now fill in the RSA dependent parameters in the public key */
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&lowPriv->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&lowPriv->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_MODULUS,
- pk11_item_expand(&pubKey->u.rsa.modulus));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_PUBLIC_EXPONENT,
- pk11_item_expand(&pubKey->u.rsa.publicExponent));
- if (crv != CKR_OK) break;
- }
- break;
- case NSSLOWKEYDSAKey:
- key_type = CKK_DSA;
- verify = CK_TRUE;
- recover = CK_FALSE;
- encrypt = CK_FALSE;
- derive = CK_FALSE;
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME,
- pk11_item_expand(&lowPriv->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&lowPriv->u.dsa.publicValue));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&pubKey->u.dsa.params.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_SUBPRIME,
- pk11_item_expand(&pubKey->u.dsa.params.subPrime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&pubKey->u.dsa.params.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&pubKey->u.dsa.publicValue));
- if (crv != CKR_OK) break;
- }
- break;
- case NSSLOWKEYDHKey:
- key_type = CKK_DH;
- verify = CK_FALSE;
- encrypt = CK_FALSE;
- recover = CK_FALSE;
- derive = CK_TRUE;
- if (lowPriv) {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&lowPriv->u.dh.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&lowPriv->u.dh.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&lowPriv->u.dh.publicValue));
- if (crv != CKR_OK) break;
- } else {
- crv = pk11_AddAttributeType(publicKey,CKA_PRIME,
- pk11_item_expand(&pubKey->u.dh.prime));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_BASE,
- pk11_item_expand(&pubKey->u.dh.base));
- if (crv != CKR_OK) break;
- crv = pk11_AddAttributeType(publicKey,CKA_VALUE,
- pk11_item_expand(&pubKey->u.dh.publicValue));
- if (crv != CKR_OK) break;
- }
- break;
- default:
- crv = CKR_MECHANISM_INVALID;
- }
-
- if (pubKey) {
- nsslowkey_DestroyPublicKey(pubKey);
- pubKey = NULL;
- }
-
- if (crv != CKR_OK) {
- goto failed;
- }
-
- if (pk11_AddAttributeType(publicKey,CKA_VERIFY, &verify,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_VERIFY_RECOVER, &recover,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_ENCRYPT, &encrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_WRAP, &encrypt,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_DERIVE, &derive,
- sizeof(CK_BBOOL)) != CKR_OK) {
- goto failed;
- }
- if (pk11_AddAttributeType(publicKey,CKA_KEY_TYPE,&key_type,
- sizeof(CK_KEY_TYPE)) != CKR_OK) {
- goto failed;
- }
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- publicKey->handle = slot->tokenIDCount++;
- publicKey->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PUB);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- publicKey->objclass = pubClass;
- publicKey->slot = slot;
- publicKey->inDB = PR_FALSE; /* not really in the Database */
-
- return publicKey;
-failed:
- if (pubKey) nsslowkey_DestroyPublicKey(pubKey);
- if (publicKey) pk11_FreeObject(publicKey);
- return NULL;
-}
-
-/*
- * Question.. Why doesn't import Cert call pk11_handleObject, or
- * pk11 handleCertObject? Answer: because they will try to write
- * this cert back out to the Database, even though it is already in
- * the database.
- */
-static PK11Object *
-pk11_importCertificate(PK11Slot *slot, NSSLOWCERTCertificate *cert,
- unsigned char *data, unsigned int size, PRBool needObject)
-{
- PK11Object *certObject = NULL;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_CERTIFICATE_TYPE certType = CKC_X_509;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- unsigned char cka_id[SHA1_LENGTH];
- CK_ATTRIBUTE theTemplate;
- PK11ObjectListElement *objectList = NULL;
- CK_RV crv;
-
-
- /*
- * first make sure that no object for this cert already exists.
- */
- theTemplate.type = CKA_VALUE;
- theTemplate.pValue = cert->derCert.data;
- theTemplate.ulValueLen = cert->derCert.len;
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, &theTemplate, 1, slot->isLoggedIn);
- if ((crv == CKR_OK) && (objectList != NULL)) {
- if (needObject) {
- pk11_ReferenceObject(objectList->object);
- certObject = objectList->object;
- }
- pk11_FreeObjectList(objectList);
- return certObject;
- }
-
- /*
- * now lets create an object to hang the attributes off of
- */
- certObject = pk11_NewObject(slot); /* fill in the handle later */
- if (certObject == NULL) {
- return NULL;
- }
-
- /* First set the CKA_ID */
- if (data == NULL) {
- NSSLOWKEYPublicKey *pubKey = nsslowcert_ExtractPublicKey(cert);
- SECItem *pubItem;
- if (pubKey == NULL) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise.
- */
- pubItem =pk11_GetPubItem(pubKey);
- if (pubItem == NULL) {
- nsslowkey_DestroyPublicKey(pubKey);
- pk11_FreeObject(certObject);
- return NULL;
- }
- SHA1_HashBuf(cka_id, (unsigned char *)pubItem->data,
- (uint32)pubItem->len);
- nsslowkey_DestroyPublicKey(pubKey);
- } else {
- SHA1_HashBuf(cka_id, (unsigned char *)data, (uint32)size);
- }
- if (pk11_AddAttributeType(certObject, CKA_ID, cka_id, sizeof(cka_id))) {
- pk11_FreeObject(certObject);
- return NULL;
- }
-
- /* initalize the certificate attributes */
- if (pk11_AddAttributeType(certObject, CKA_CLASS, &certClass,
- sizeof(CK_OBJECT_CLASS)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_TOKEN, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_LABEL, cert->nickname,
- PORT_Strlen(cert->nickname))
- != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_MODIFIABLE, &cktrue,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_CERTIFICATE_TYPE, &certType,
- sizeof(CK_CERTIFICATE_TYPE))!=CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_VALUE,
- pk11_item_expand(&cert->derCert)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_ISSUER,
- pk11_item_expand(&cert->derIssuer)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_SUBJECT,
- pk11_item_expand(&cert->derSubject)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
- if (pk11_AddAttributeType(certObject, CKA_SERIAL_NUMBER,
- pk11_item_expand(&cert->serialNumber)) != CKR_OK) {
- pk11_FreeObject(certObject);
- return NULL;
- }
-
-
- certObject->objectInfo = NULL;
- certObject->infoFree = (PK11Free) NULL;
-
- /* now just verify the required date fields */
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- certObject->handle = slot->tokenIDCount++;
- certObject->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_CERT);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- certObject->objclass = certClass;
- certObject->slot = slot;
- certObject->inDB = PR_TRUE;
- pk11_AddSlotObject(slot, certObject);
- if (needObject) {
- pk11_ReferenceObject(certObject);
+ if (pk11_isToken(object->handle)) {
+ pk11_convertSessionToToken(object);
} else {
- certObject = NULL;
+ object->slot = slot;
+ pk11_AddObject(session,object);
}
- return certObject;
+ return CKR_OK;
}
/*
@@ -1934,6 +1406,10 @@ NSSLOWKEYPublicKey *pk11_GetPubKey(PK11Object *object,CK_KEY_TYPE key_type)
return NULL;
}
+ if (pk11_isToken(object->handle)) {
+/* ferret out the token object handle */
+ }
+
/* If we already have a key, use it */
if (object->objectInfo) {
return (NSSLOWKEYPublicKey *)object->objectInfo;
@@ -2009,6 +1485,7 @@ pk11_mkPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
CK_RV crv = CKR_OK;
SECStatus rv;
+ PORT_Assert(!pk11_isToken(object->handle));
arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
if (arena == NULL) return NULL;
@@ -2111,39 +1588,18 @@ pk11_GetPrivKey(PK11Object *object,CK_KEY_TYPE key_type)
return (NSSLOWKEYPrivateKey *)object->objectInfo;
}
- if (pk11_isTrue(object,CKA_TOKEN)) {
+ if (pk11_isToken(object->handle)) {
/* grab it from the data base */
- SECItem pubKey;
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
CK_RV crv;
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) return NULL;
-
+ PORT_Assert(to);
PORT_Assert(object->slot->keyDB);
- priv=nsslowkey_FindKeyByPublicKey(object->slot->keyDB,&pubKey,
- (NSSLOWKEYGetPasswordKey) pk11_givePass,
- object->slot);
- if (!priv && pubKey.data[0] == 0) {
- /* Because of legacy code issues, sometimes the public key has
- * a '0' prepended to it, forcing it to be unsigned. The database
- * may not store that '0', so remove it and try again.
- */
- SECItem tmpPubKey;
- tmpPubKey.data = pubKey.data + 1;
- tmpPubKey.len = pubKey.len - 1;
- priv=nsslowkey_FindKeyByPublicKey(object->slot->keyDB,
- &tmpPubKey, (NSSLOWKEYGetPasswordKey) pk11_givePass,
- object->slot);
- }
- if (pubKey.data) PORT_Free(pubKey.data);
-
- /* don't 'cache' DB private keys */
- return priv;
- }
-
- priv = pk11_mkPrivKey(object, key_type);
+ priv = nsslowkey_FindKeyByPublicKey(object->slot->keyDB, &to->dbKey,
+ object->slot->password);
+ } else {
+ priv = pk11_mkPrivKey(object, key_type);
+ }
object->objectInfo = priv;
object->infoFree = (PK11Free) nsslowkey_DestroyPrivateKey;
return priv;
@@ -2293,86 +1749,6 @@ isSecretKey(NSSLOWKEYPrivateKey *privKey)
return PR_FALSE;
}
-/* Import a Secret Key */
-static PRBool
-importSecretKey(PK11Slot *slot, NSSLOWKEYPrivateKey *priv)
-{
- PK11Object *object;
- CK_OBJECT_CLASS secretClass = CKO_SECRET_KEY;
- CK_BBOOL cktrue = CK_TRUE;
- CK_BBOOL ckfalse = CK_FALSE;
- CK_KEY_TYPE key_type;
-
- /* Check for secret key representation, return if it isn't one */
- if (!isSecretKey(priv))
- return PR_FALSE;
-
- /*
- * now lets create an object to hang the attributes off of
- */
- object = pk11_NewObject(slot); /* fill in the handle later */
- if (object == NULL) {
- goto loser;
- }
-
- /* Set the ID value */
- if (pk11_AddAttributeType(object, CKA_ID,
- priv->u.rsa.modulus.data, priv->u.rsa.modulus.len)) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- /* initalize the object attributes */
- if (pk11_AddAttributeType(object, CKA_CLASS, &secretClass,
- sizeof(secretClass)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_TOKEN, &cktrue,
- sizeof(cktrue)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_PRIVATE, &ckfalse,
- sizeof(CK_BBOOL)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_VALUE,
- pk11_item_expand(&priv->u.rsa.privateExponent)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
-
- if (pk11_AddAttributeType(object, CKA_KEY_TYPE,
- pk11_item_expand(&priv->u.rsa.coefficient)) != CKR_OK) {
- pk11_FreeObject(object);
- goto loser;
- }
- key_type = *(CK_KEY_TYPE*)priv->u.rsa.coefficient.data;
-
- /* Validate and add default attributes */
- validateSecretKey(object, key_type, (PRBool)(slot->slotID == FIPS_SLOT_ID));
-
- /* now just verify the required date fields */
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- object->handle = slot->tokenIDCount++;
- object->handle |= (PK11_TOKEN_MAGIC | PK11_TOKEN_TYPE_PRIV);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
-
- object->objclass = secretClass;
- object->slot = slot;
- object->inDB = PR_TRUE;
- pk11_AddSlotObject(slot, object);
-
-loser:
- return PR_TRUE;
-}
-
-
/**********************************************************************
*
* Start of PKCS 11 functions
@@ -2383,10 +1759,22 @@ loser:
/* return the function list */
CK_RV NSC_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
{
- *pFunctionList = &pk11_funcList;
+ *pFunctionList = (CK_FUNCTION_LIST_PTR) &pk11_funcList;
return CKR_OK;
}
+/* return the function list */
+CK_RV C_GetFunctionList(CK_FUNCTION_LIST_PTR *pFunctionList)
+{
+ return NSC_GetFunctionList(pFunctionList);
+}
+
+static PLHashNumber
+pk11_HashNumber(const void *key)
+{
+ return (PLHashNumber) key;
+}
+
/*
* initialize one of the slot structures. figure out which by the ID
*/
@@ -2411,6 +1799,11 @@ PK11_SlotInit(CK_SLOT_ID slotID, PRBool needLogin,
for(i=0; i < TOKEN_OBJECT_HASH_SIZE; i++) {
slot->tokObjects[i] = NULL;
}
+ slot->tokenHashTable = PL_NewHashTable(64,pk11_HashNumber,PL_CompareValues,
+ SECITEM_HashCompare, NULL, 0);
+ if (slot->tokenHashTable == NULL) {
+ return CKR_HOST_MEMORY;
+ }
slot->password = NULL;
slot->hasTokens = PR_FALSE;
slot->sessionIDCount = 1;
@@ -2447,7 +1840,8 @@ CK_RV PK11_LowInitialize(CK_VOID_PTR pReserved)
*/
/* initialize the key and cert db's */
- nsslowkey_SetDefaultKeyDBAlg(SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
+ nsslowkey_SetDefaultKeyDBAlg
+ (SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC);
if ((init_args && init_args->LibraryParameters)) {
pk11_parameters paramStrings;
@@ -2541,7 +1935,7 @@ CK_RV NSC_Finalize (CK_VOID_PTR pReserved)
CK_RV NSC_GetInfo(CK_INFO_PTR pInfo)
{
pInfo->cryptokiVersion.major = 2;
- pInfo->cryptokiVersion.minor = 1;
+ pInfo->cryptokiVersion.minor = 11;
PORT_Memcpy(pInfo->manufacturerID,manufacturerID,32);
pInfo->libraryVersion.major = 3;
pInfo->libraryVersion.minor = 2;
@@ -3506,439 +2900,311 @@ CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession,
return CKR_OK;
}
-/* stolen from keydb.c */
-#define KEYDB_PW_CHECK_STRING "password-check"
-#define KEYDB_PW_CHECK_LEN 14
+/*
+ * find any certs that may match the template and load them.
+ */
+#define NSC_CERT 0x00000001
+#define NSC_TRUST 0x00000002
+#define NSC_CRL 0x00000004
+#define NSC_SMIME 0x00000008
+#define NSC_PRIVATE 0x00000010
+#define NSC_PUBLIC 0x00000020
+#define NSC_KEY 0x00000040
-NSSLOWKEYPrivateKey * nsslowkey_DecryptKey(DBT *key, SECItem *pwitem,
- NSSLOWKEYDBHandle *handle);
-typedef struct pk11keyNodeStr {
- struct pk11keyNodeStr *next;
- NSSLOWKEYPrivateKey *privKey;
- NSSLOWCERTCertificate *cert;
- SECItem *pubItem;
-} pk11keyNode;
+/*
+ * structure to collect key handles.
+ */
+typedef struct pk11KeyDataStr {
+ PK11Slot *slot;
+ PK11SearchResults *searchHandles;
+ SECItem *id;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+ unsigned long classFlags;
+ PRBool isLoggedIn;
+ PRBool strict;
+} pk11KeyData;
-typedef struct {
- PLArenaPool *arena;
- pk11keyNode *head;
+/*
+ * structure to collect certs into
+ */
+typedef struct pk11CertDataStr {
PK11Slot *slot;
-} keyList;
+ int cert_count;
+ int max_cert_count;
+ NSSLOWCERTCertificate **certs;
+ CK_ATTRIBUTE *template;
+ CK_ULONG templ_count;
+ unsigned long classFlags;
+ PRBool strict;
+} pk11CertData;
static SECStatus
-add_key_to_list(DBT *key, DBT *data, void *arg)
+pk11_key_collect(DBT *key, DBT *data, void *arg)
{
- keyList *keylist;
- pk11keyNode *node;
- void *keydata;
+ pk11KeyData *keyData;
NSSLOWKEYPrivateKey *privKey = NULL;
+ SECItem tmpDBKey;
+ PK11Slot *slot;
- keylist = (keyList *)arg;
+ keyData = (pk11KeyData *)arg;
+ slot = keyData->slot;
- PORT_Assert(keylist->slot->keyDB);
- privKey = nsslowkey_DecryptKey(key, keylist->slot->password,
- keylist->slot->keyDB);
- if ( privKey == NULL ) {
- goto loser;
- }
+ tmpDBKey.data = key->data;
+ tmpDBKey.len = key->size;
- /* allocate the node struct */
- node = (pk11keyNode*)PORT_ArenaZAlloc(keylist->arena, sizeof(pk11keyNode));
- if ( node == NULL ) {
- goto loser;
+ PORT_Assert(slot->keyDB);
+ if (!keyData->strict && keyData->id) {
+ SECItem result;
+ unsigned char hashKey[SHA1_LENGTH];
+ result.data = hashKey;
+ result.len = sizeof(hashKey);
+
+ SHA1_HashBuf( hashKey, key->data, key->size );
+ if (SECITEM_ItemsAreEqual(keyData->id,&result)) {
+ if (keyData->classFlags & NSC_PRIVATE) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(slot,&tmpDBKey,PK11_TOKEN_TYPE_PRIV));
+ }
+ if (keyData->classFlags & NSC_PUBLIC) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(slot,&tmpDBKey,PK11_TOKEN_TYPE_PUB));
+ }
+ /* NSC_KEY Already handled */
+ }
+ return SECSuccess;
}
-
- /* allocate room for key data */
- keydata = PORT_ArenaZAlloc(keylist->arena, key->size);
- if ( keydata == NULL ) {
+
+ privKey = nsslowkey_FindKeyByPublicKey(keyData->slot->keyDB, &tmpDBKey,
+ keyData->slot->password);
+ if ( privKey == NULL ) {
goto loser;
}
- /* link node into list */
- node->next = keylist->head;
- keylist->head = node;
-
- node->privKey = privKey;
- switch (privKey->keyType) {
- case NSSLOWKEYRSAKey:
- node->pubItem = &privKey->u.rsa.modulus;
- break;
- case NSSLOWKEYDSAKey:
- node->pubItem = &privKey->u.dsa.publicValue;
- break;
- case NSSLOWKEYDHKey:
- node->pubItem = &privKey->u.dh.publicValue;
- break;
- default:
- break;
+ if (isSecretKey(privKey)) {
+ if ((keyData->classFlags & NSC_KEY) &&
+ pk11_tokenMatch(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_KEY,
+ keyData->template, keyData->templ_count)) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_KEY));
+ }
+ } else {
+ if ((keyData->classFlags & NSC_PRIVATE) &&
+ pk11_tokenMatch(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_PRIV,
+ keyData->template, keyData->templ_count)) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(keyData->slot,&tmpDBKey,PK11_TOKEN_TYPE_PRIV));
+ }
+ if ((keyData->classFlags & NSC_PUBLIC) &&
+ pk11_tokenMatch(keyData->slot, &tmpDBKey, PK11_TOKEN_TYPE_PUB,
+ keyData->template, keyData->templ_count)) {
+ pk11_addHandle(keyData->searchHandles,
+ pk11_mkHandle(keyData->slot, &tmpDBKey,PK11_TOKEN_TYPE_PUB));
+ }
}
-
- return(SECSuccess);
+
loser:
if ( privKey ) {
nsslowkey_DestroyPrivateKey(privKey);
}
return(SECSuccess);
}
-
/*
- * If the cert is a user cert, then try to match it to a key on the
- * linked list of private keys built earlier.
- * If the cert matches one on the list, then save it.
- */
+ * collect all the certs from the traverse call.
+ */
static SECStatus
-add_cert_to_list(NSSLOWCERTCertificate *cert, SECItem *k, void *pdata)
+pk11_cert_collect(NSSLOWCERTCertificate *cert,void *arg)
{
- keyList *keylist;
- pk11keyNode *node;
- NSSLOWKEYPublicKey *pubKey = NULL;
- SECItem *pubItem;
- NSSLOWCERTCertificate *oldcert;
-
- keylist = (keyList *)pdata;
-
- /* only if it is a user cert and has a nickname!! */
- if ( ( ( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER ) ) &&
- ( cert->nickname != NULL ) ) {
-
- /* get cert's public key */
- pubKey = nsslowcert_ExtractPublicKey(cert);
- if ( pubKey == NULL ) {
- goto done;
- }
+ pk11CertData *cd = (pk11CertData *)arg;
- /* pk11_GetPubItem returns data associated with the public key.
- * one only needs to free the public key. This comment is here
- * because this sematic would be non-obvious otherwise.
- */
- pubItem = pk11_GetPubItem(pubKey);
- if (pubItem == NULL) goto done;
-
- node = keylist->head;
- while ( node ) {
- /* if key type is different, then there is no match */
- if (node->privKey->keyType == pubKey->keyType) {
-
- /* compare public value from cert with public value from
- * the key
- */
- if ( SECITEM_CompareItem(pubItem, node->pubItem) == SECEqual ){
- /* this is a match */
-
- /* if no cert has yet been found for this key, or this
- * cert is newer, then save this cert
- */
- if ( ( node->cert == NULL )
-#ifdef notdef
- || CERT_IsNewer(cert, node->cert )
-#endif
- ) {
-
- oldcert = node->cert;
-
- /* get a real DB copy of the cert, since the one
- * passed in here is not properly recorded in the
- * temp database
- */
-
- /* We need a better way to deal with this */
- PORT_Assert(keylist->slot->certDB);
- node->cert =
- nsslowcert_FindCertByKeyNoLocking(
- keylist->slot->certDB,
- &cert->certKey);
-
- /* free the old cert if there was one */
- if ( oldcert ) {
- nsslowcert_DestroyCertificate(oldcert);
- }
- }
- }
- }
-
- node = node->next;
+ if (cd->certs == NULL) {
+ return SECFailure;
+ }
+
+ if (cd->strict) {
+ if ((cd->classFlags & NSC_CERT) && !pk11_tokenMatch(cd->slot,
+ &cert->certKey, PK11_TOKEN_TYPE_CERT, cd->template,cd->templ_count)) {
+ return SECSuccess;
+ }
+ if ((cd->classFlags & NSC_TRUST) && !pk11_tokenMatch(cd->slot,
+ &cert->certKey, PK11_TOKEN_TYPE_TRUST,
+ cd->template, cd->templ_count)) {
+ return SECSuccess;
}
}
-done:
- if ( pubKey ) {
- nsslowkey_DestroyPublicKey(pubKey);
+
+ /* allocate more space if we need it. This should only happen in
+ * the general traversal case */
+ if (cd->cert_count >= cd->max_cert_count) {
+ int size;
+ cd->max_cert_count += NSC_CERT_BLOCK_SIZE;
+ size = cd->max_cert_count * sizeof (NSSLOWCERTCertificate *);
+ cd->certs = (NSSLOWCERTCertificate **)PORT_Realloc(cd->certs,size);
+ if (cd->certs == NULL) {
+ return SECFailure;
+ }
}
- return(SECSuccess);
+ cd->certs[cd->cert_count++] = nsslowcert_DupCertificate(cert);
+ return SECSuccess;
}
-#if 0
-/* This appears to be obsolete - TNH */
-static SECItem *
-decodeKeyDBGlobalSalt(DBT *saltData)
+/* provide impedence matching ... */
+static SECStatus
+pk11_cert_collect2(NSSLOWCERTCertificate *cert, SECItem *dymmy, void *arg)
{
- SECItem *saltitem;
-
- saltitem = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if ( saltitem == NULL ) {
- return(NULL);
- }
-
- saltitem->data = (unsigned char *)PORT_ZAlloc(saltData->size);
- if ( saltitem->data == NULL ) {
- PORT_Free(saltitem);
- return(NULL);
- }
-
- saltitem->len = saltData->size;
- PORT_Memcpy(saltitem->data, saltData->data, saltitem->len);
-
- return(saltitem);
+ return pk11_cert_collect(cert, arg);
}
-#endif
-
-#if 0
-/*
- * Create a (fixed) DES3 key [ testing ]
- */
-static unsigned char keyValue[] = {
- 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
- 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
- 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17
-};
-static SECItem keyItem = {
- 0,
- keyValue,
- sizeof keyValue
-};
-
-static unsigned char keyID[] = {
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
-};
-
-static SECItem keyIDItem = {
- 0,
- keyID,
- sizeof keyID
-};
-/* +AAA */
-static CK_RV
-pk11_createFixedDES3Key(PK11Slot *slot)
+static void
+pk11_searchSingleCert(pk11CertData *certData,NSSLOWCERTCertificate *cert)
{
- CK_RV rv = CKR_OK;
- PK11Object *keyObject;
- CK_BBOOL true = CK_TRUE;
- CK_OBJECT_CLASS class = CKO_SECRET_KEY;
- CK_KEY_TYPE keyType = CKK_DES3;
-
- /*
- * Create the object
- */
- keyObject = pk11_NewObject(slot); /* fill in the handle later */
- if (keyObject == NULL) {
- return CKR_HOST_MEMORY;
- }
-
- /* Add attributes to the object */
- rv = pk11_AddAttributeType(keyObject, CKA_ID, keyID, sizeof keyID);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+ if (cert == NULL) {
+ return;
}
-
- rv = pk11_AddAttributeType(keyObject, CKA_VALUE, keyValue, sizeof keyValue);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+ if (certData->strict &&
+ !pk11_tokenMatch(certData->slot, &cert->certKey, PK11_TOKEN_TYPE_CERT,
+ certData->template,certData->templ_count)) {
+ nsslowcert_DestroyCertificate(cert);
+ return;
}
-
- rv = pk11_AddAttributeType(keyObject, CKA_TOKEN, &true, sizeof true);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+ certData->certs = (NSSLOWCERTCertificate **)
+ PORT_Alloc(sizeof (NSSLOWCERTCertificate *));
+ if (certData->certs == NULL) {
+ nsslowcert_DestroyCertificate(cert);
+ return;
}
+ certData->certs[0] = cert;
+ certData->cert_count = 1;
+}
- rv = pk11_AddAttributeType(keyObject, CKA_CLASS, &class, sizeof class);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
- }
+static void
+pk11_CertSetupData(pk11CertData *certData,int count)
+{
+ certData->max_cert_count = count;
- rv = pk11_AddAttributeType(keyObject, CKA_KEY_TYPE, &keyType, sizeof keyType);
- if (rv != CKR_OK) {
- pk11_FreeObject(keyObject);
- return rv;
+ if (certData->max_cert_count <= 0) {
+ return;
}
-
- pk11_handleSecretKeyObject(keyObject, keyType, PR_TRUE);
-
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- keyObject->handle = slot->tokenIDCount++;
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
- keyObject->slot = slot;
- keyObject->objclass = CKO_SECRET_KEY;
- pk11_AddSlotObject(slot, keyObject);
-
- return rv;
+ certData->certs = (NSSLOWCERTCertificate **)
+ PORT_Alloc( count * sizeof(NSSLOWCERTCertificate *));
+ return;
}
-#endif /* Fixed DES key */
-/*
- * load up our token database
- */
-static CK_RV
-pk11_importKeyDB(PK11Slot *slot)
+static void
+pk11_searchCertsAndTrust(PK11Slot *slot, SECItem *derCert, SECItem *name,
+ SECItem *derSubject, NSSLOWCERTIssuerAndSN *issuerSN,
+ unsigned long classFlags, PK11SearchResults *handles,
+ CK_ATTRIBUTE *pTemplate, CK_LONG ulCount)
{
- keyList keylist;
- pk11keyNode *node;
- CK_RV crv;
- SECStatus rv;
- PK11Object *privateKeyObject;
- PK11Object *publicKeyObject;
- PK11Object *certObject;
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
+ pk11CertData certData;
+ int i;
- /* traverse the database, collecting the index keys of all
- * records into a linked list
- */
- keylist.arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if ( keylist.arena == NULL ) {
- return CKR_HOST_MEMORY;
- }
- keylist.head = NULL;
- keylist.slot = slot;
-
- /* collect all of the keys */
- PORT_Assert(slot->keyDB);
- rv = nsslowkey_TraverseKeys(slot->keyDB,
- add_key_to_list, (void *)&keylist);
- if (rv != SECSuccess) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
+ certHandle = slot->certDB;
+ if (certHandle == NULL) return;
+
+ certData.slot = slot;
+ certData.max_cert_count = 0;
+ certData.certs = NULL;
+ certData.cert_count = 0;
+ certData.template = pTemplate;
+ certData.templ_count = ulCount;
+ certData.classFlags = classFlags;
+ certData.strict = NSC_STRICT;
- /* find certs that match any of the keys */
- PORT_Assert(slot->certDB);
- crv = nsslowcert_TraversePermCerts(slot->certDB,
- add_cert_to_list, (void *)&keylist);
- if ( crv != SECSuccess ) {
- PORT_FreeArena(keylist.arena, PR_FALSE);
- return CKR_HOST_MEMORY;
- }
- /* now traverse the list and entry certs/keys into the
- * pkcs11 world
+ /*
+ * Find the Cert.
*/
- for (node = keylist.head; node != NULL; node=node->next ) {
- /* Check for "special" private key that wraps a symmetric key */
- if (isSecretKey(node->privKey)) {
- importSecretKey(slot, node->privKey);
- goto end_loop;
- }
-
- /* create the private key object */
- privateKeyObject = pk11_importPrivateKey(slot, node->privKey,
- node->pubItem);
- if ( privateKeyObject == NULL ) {
- goto end_loop;
- }
+ if (derCert->data != NULL) {
+ NSSLOWCERTCertificate *cert =
+ nsslowcert_FindCertByDERCert(certHandle,derCert);
+ pk11_searchSingleCert(&certData,cert);
+ } else if (name->data != NULL) {
+ char *tmp_name = (char*)PORT_Alloc(name->len+1);
+ int count;
- publicKeyObject = pk11_importPublicKey(slot, node->privKey, NULL,
- node->pubItem);
- if ( node->cert ) {
- /* Now import the Cert */
- certObject = pk11_importCertificate(slot, node->cert,
- node->pubItem->data,
- node->pubItem->len, PR_TRUE);
-
- /* Copy the subject */
- if ( certObject ) {
- /* NOTE: cert has been adopted */
- PK11Attribute *attribute;
-
- /* Copy the Subject */
- attribute = pk11_FindAttribute(certObject,CKA_SUBJECT);
- if (attribute) {
- pk11_forceAttribute(privateKeyObject,
- pk11_attr_expand(&attribute->attrib));
- if (publicKeyObject) {
- pk11_forceAttribute(publicKeyObject,
- pk11_attr_expand(&attribute->attrib));
- }
- pk11_FreeAttribute(attribute);
- }
- pk11_FreeObject(certObject);
- }
+ if (tmp_name == NULL) {
+ return;
}
+ PORT_Memcpy(tmp_name,name->data,name->len);
+ tmp_name[name->len] = 0;
- if ( publicKeyObject != NULL ) {
- pk11_AddSlotObject(slot, publicKeyObject);
- }
+ count= nsslowcert_NumPermCertsForNickname(certHandle,tmp_name);
+ pk11_CertSetupData(&certData,count);
+ nsslowcert_TraversePermCertsForNickname(certHandle,tmp_name,
+ pk11_cert_collect, &certData);
+ PORT_Free(tmp_name);
+ } else if (derSubject->data != NULL) {
+ int count;
- pk11_AddSlotObject(slot, privateKeyObject);
+ count = nsslowcert_NumPermCertsForSubject(certHandle,derSubject);
+ pk11_CertSetupData(&certData,count);
+ nsslowcert_TraversePermCertsForSubject(certHandle,derSubject,
+ pk11_cert_collect, &certData);
+ } else if ((issuerSN->derIssuer.data != NULL) &&
+ (issuerSN->serialNumber.data != NULL)) {
+ NSSLOWCERTCertificate *cert =
+ nsslowcert_FindCertByIssuerAndSN(certHandle,issuerSN);
-end_loop:
- nsslowkey_DestroyPrivateKey(node->privKey);
- if ( node->cert ) {
- nsslowcert_DestroyCertificate(node->cert);
- }
-
+ pk11_searchSingleCert(&certData,cert);
+ } else {
+ /* we aren't filtering the certs, we are working on all, so turn
+ * on the strict filters. */
+ certData.strict = PR_TRUE;
+ pk11_CertSetupData(&certData,NSC_CERT_BLOCK_SIZE);
+ nsslowcert_TraversePermCerts(certHandle, pk11_cert_collect2, &certData);
}
- PORT_FreeArena(keylist.arena, PR_FALSE);
-
- return CKR_OK;
-}
-/*
- * structure to collect certs into
- */
-typedef struct pk11CertDataStr {
- int cert_count;
- int max_cert_count;
- NSSLOWCERTCertificate **certs;
-} pk11CertData;
-
-/*
- * collect all the certs from the traverse call.
- */
-static SECStatus
-pk11_cert_collect(NSSLOWCERTCertificate *cert,void *arg) {
- pk11CertData *cd = (pk11CertData *)arg;
+ /*
+ * build the handles
+ */
+ for (i=0 ; i < certData.cert_count ; i++) {
+ NSSLOWCERTCertificate *cert = certData.certs[i];
- /* shouldn't happen, but don't crash if it does */
- if (cd->cert_count >= cd->max_cert_count) {
- PORT_Assert(0);
- return SECFailure;
+ /* if we filtered it would have been on the stuff above */
+ if (classFlags & NSC_CERT) {
+ pk11_addHandle(handles,
+ pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_CERT));
+ }
+ if ((classFlags & NSC_TRUST) && nsslowcert_hasTrust(cert)) {
+ pk11_addHandle(handles,
+ pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_TRUST));
+ }
+ nsslowcert_DestroyCertificate(cert);
}
- cd->certs[cd->cert_count++] = nsslowcert_DupCertificate(cert);
- return SECSuccess;
+ if (certData.certs) PORT_Free(certData.certs);
+ return;
}
-/*
- * find any certs that may match the template and load them.
- */
-static void
-pk11_searchCerts(PK11Slot *slot, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) {
+static CK_RV
+pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search,
+ CK_ATTRIBUTE *pTemplate, CK_LONG ulCount,
+ PRBool *tokenOnly, PRBool isLoggedIn)
+{
int i;
+ PRBool isKrl = PR_FALSE;
SECItem derCert = { siBuffer, NULL, 0 };
SECItem derSubject = { siBuffer, NULL, 0 };
SECItem name = { siBuffer, NULL, 0 };
+ SECItem key_id = { siBuffer, NULL, 0 };
+ SECItem cert_sha1_hash = { siBuffer, NULL, 0 };
+ SECItem cert_md5_hash = { siBuffer, NULL, 0 };
NSSLOWCERTIssuerAndSN issuerSN = {
{ siBuffer, NULL, 0 },
{ siBuffer, NULL, 0 }
};
SECItem *copy = NULL;
- NSSLOWCERTCertDBHandle *handle = NULL;
- NSSLOWKEYDBHandle *keyHandle = NULL;
- pk11CertData certData;
+ unsigned long classFlags =
+ NSC_CERT|NSC_TRUST|NSC_PRIVATE|NSC_PUBLIC|NSC_KEY|NSC_SMIME ;
+ /* if we aren't logged in, don't look for private or secret keys */
+ if (!isLoggedIn) {
+ classFlags &= ~(NSC_PRIVATE|NSC_KEY);
+ }
- /*
- * These should be stored in the slot some day in the future
- */
- handle = slot->certDB;
- if (handle == NULL) return;
- keyHandle = slot->keyDB;
- if (keyHandle == NULL) return;
/*
* look for things to search on certs for. We only need one of these
@@ -3946,139 +3212,216 @@ pk11_searchCerts(PK11Slot *slot, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) {
* (as long as they are user certs). We'll let find objects filter out
* the ones that don't apply.
*/
- for (i=0 ;i < (int)ulCount; i++) {
+ for (i=0 ;classFlags && i < (int)ulCount; i++) {
switch (pTemplate[i].type) {
- case CKA_SUBJECT: copy = &derSubject; break;
- case CKA_ISSUER: copy = &issuerSN.derIssuer; break;
- case CKA_SERIAL_NUMBER: copy = &issuerSN.serialNumber; break;
- case CKA_VALUE: copy = &derCert; break;
- case CKA_LABEL: copy = &name; break;
+ case CKA_SUBJECT:
+ copy = &derSubject;
+ classFlags &= (NSC_CERT|NSC_PRIVATE|NSC_PUBLIC);
+ break;
+ case CKA_ISSUER:
+ copy = &issuerSN.derIssuer;
+ classFlags &= (NSC_CERT|NSC_CRL|NSC_TRUST);
+ break;
+ case CKA_SERIAL_NUMBER:
+ copy = &issuerSN.serialNumber;
+ classFlags &= (NSC_CERT|NSC_TRUST);
+ break;
+ case CKA_VALUE:
+ copy = &derCert;
+ classFlags &= (NSC_CERT|NSC_CRL);
+ break;
+ case CKA_LABEL:
+ copy = &name;
+ break;
case CKA_CLASS:
if (pTemplate[i].ulValueLen != sizeof(CK_OBJECT_CLASS)) {
- return;
+ classFlags = 0;
+ break;;
}
- if (*((CK_OBJECT_CLASS *)pTemplate[i].pValue) != CKO_CERTIFICATE) {
- return;
+ switch (*((CK_OBJECT_CLASS *)pTemplate[i].pValue)) {
+ case CKO_CERTIFICATE:
+ classFlags &= NSC_CERT;
+ break;
+ case CKO_NETSCAPE_TRUST:
+ classFlags &= NSC_CERT;
+ break;
+ case CKO_NETSCAPE_CRL:
+ classFlags &= NSC_CERT;
+ break;
+ case CKO_PRIVATE_KEY:
+ classFlags &= NSC_PRIVATE;
+ break;
+ case CKO_PUBLIC_KEY:
+ classFlags &= NSC_PUBLIC;
+ break;
+ case CKO_SECRET_KEY:
+ classFlags &= NSC_KEY;
+ break;
+ default:
+ classFlags = 0;
+ break;
}
- copy = NULL; break;
+ break;
case CKA_PRIVATE:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- return;
+ classFlags = 0;
+ }
+ if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
+ classFlags &= (NSC_PRIVATE|NSC_KEY);
+ } else {
+ classFlags &= ~(NSC_PRIVATE|NSC_KEY);
+ }
+ break;
+ case CKA_SENSITIVE:
+ if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
+ classFlags = 0;
}
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_FALSE) {
- return;
+ if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
+ classFlags &= (NSC_PRIVATE|NSC_KEY);
+ } else {
+ classFlags = 0;
}
- copy = NULL; break;
+ break;
case CKA_TOKEN:
if (pTemplate[i].ulValueLen != sizeof(CK_BBOOL)) {
- return;
+ classFlags = 0;
}
- if (*((CK_BBOOL *)pTemplate[i].pValue) != CK_TRUE) {
- return;
+ if (*((CK_BBOOL *)pTemplate[i].pValue) == CK_TRUE) {
+ *tokenOnly = PR_TRUE;
+ } else {
+ classFlags = 0;
}
- copy = NULL; break;
+ break;
+ case CKA_CERT_SHA1_HASH:
+ classFlags &= NSC_TRUST;
+ copy = &cert_sha1_hash; break;
+ case CKA_CERT_MD5_HASH:
+ classFlags &= NSC_TRUST;
+ copy = &cert_md5_hash; break;
case CKA_CERTIFICATE_TYPE:
+ if (pTemplate[i].ulValueLen != sizeof(CK_CERTIFICATE_TYPE)) {
+ classFlags = 0;
+ }
+ classFlags &= NSC_CERT;
+ if (*((CK_CERTIFICATE_TYPE *)pTemplate[i].pValue) != CKC_X_509) {
+ classFlags = 0;
+ }
+ break;
case CKA_ID:
+ copy = &key_id; break;
+ case CKA_NETSCAPE_KRL:
+ classFlags &= NSC_CRL;
+ isKrl = PR_TRUE;
+ break;
case CKA_MODIFIABLE:
- copy = NULL; break;
+ break;
+ case CKA_KEY_TYPE:
+ case CKA_DERIVE:
+ classFlags &= NSC_PUBLIC|NSC_PRIVATE|NSC_KEY;
+ break;
+ case CKA_VERIFY_RECOVER:
+ classFlags &= NSC_PUBLIC;
+ break;
+ case CKA_SIGN_RECOVER:
+ classFlags &= NSC_PRIVATE;
+ break;
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_WRAP:
+ classFlags &= NSC_PUBLIC|NSC_KEY;
+ break;
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_UNWRAP:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_EXTRACTABLE:
+ case CKA_NEVER_EXTRACTABLE:
+ classFlags &= NSC_PRIVATE|NSC_KEY;
+ break;
/* can't be a certificate if it doesn't match one of the above
* attributes */
- default: return;
+ default:
+ classFlags = 0;
+ break;
}
if (copy) {
copy->data = (unsigned char*)pTemplate[i].pValue;
copy->len = pTemplate[i].ulValueLen;
}
+ copy = NULL;
}
- certData.max_cert_count = 0;
- certData.certs = NULL;
- certData.cert_count = 0;
- if (derCert.data != NULL) {
- NSSLOWCERTCertificate *cert = nsslowcert_FindCertByDERCert(handle,&derCert);
- if (cert != NULL) {
- certData.certs =
- (NSSLOWCERTCertificate **) PORT_Alloc(sizeof (NSSLOWCERTCertificate *));
- if (certData.certs) {
- certData.certs[0] = cert;
- certData.cert_count = 1;
- } else nsslowcert_DestroyCertificate(cert);
- }
- } else if (name.data != NULL) {
- char *tmp_name = (char*)PORT_Alloc(name.len+1);
+ /* certs */
+ if (classFlags & (NSC_CERT|NSC_TRUST)) {
+ pk11_searchCertsAndTrust(slot,&derCert,&name,&derSubject,
+ &issuerSN,classFlags,search,
+ pTemplate, ulCount);
+ }
- if (tmp_name == NULL) {
- return;
- }
- PORT_Memcpy(tmp_name,name.data,name.len);
- tmp_name[name.len] = 0;
-
- certData.max_cert_count=nsslowcert_NumPermCertsForNickname(handle,tmp_name);
- if (certData.max_cert_count > 0) {
- certData.certs = (NSSLOWCERTCertificate **)
- PORT_Alloc(certData.max_cert_count *sizeof(NSSLOWCERTCertificate *));
- if (certData.certs) {
- nsslowcert_TraversePermCertsForNickname(handle,tmp_name,
- pk11_cert_collect, &certData);
- }
-
+ /* 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;
}
- PORT_Free(tmp_name);
- } else if (derSubject.data != NULL) {
- certData.max_cert_count=nsslowcert_NumPermCertsForSubject(handle,&derSubject);
- if (certData.max_cert_count > 0) {
- certData.certs = (NSSLOWCERTCertificate **)
- PORT_Alloc(certData.max_cert_count *sizeof(NSSLOWCERTCertificate *));
- if (certData.certs) {
- nsslowcert_TraversePermCertsForSubject(handle,&derSubject,
- pk11_cert_collect, &certData);
+ 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;
}
}
- } else if ((issuerSN.derIssuer.data != NULL) &&
- (issuerSN.serialNumber.data != NULL)) {
- NSSLOWCERTCertificate *cert = nsslowcert_FindCertByIssuerAndSN(handle,&issuerSN);
-
- if (cert != NULL) {
- certData.certs =
- (NSSLOWCERTCertificate **) PORT_Alloc(sizeof (NSSLOWCERTCertificate *));
- if (certData.certs) {
- certData.certs[0] = cert;
- certData.cert_count = 1;
- } else nsslowcert_DestroyCertificate(cert);
- }
- } else {
- /* PORT_Assert(0); may get called when not looking for certs */
- /* look up all the certs sometime, and get rid of the assert */;
+ 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;
-/* we need to search on email address and S/MIME data */
-/* we also need to add CRL searching code */
-/* we also need to add TRUST searching code */
+ nsslowkey_TraverseKeys(keyHandle, pk11_key_collect, &keyData);
}
+key_loser:
+ /* crl's */
+ if (classFlags & NSC_CRL) {
+ NSSLOWCERTCertDBHandle *certHandle = NULL;
- for (i=0 ; i < certData.cert_count ; i++) {
- NSSLOWCERTCertificate *cert = certData.certs[i];
-
- /* we are only interested in permanment user certs here */
- if ((cert->trust) &&
- (( cert->trust->sslFlags & CERTDB_USER ) ||
- ( cert->trust->emailFlags & CERTDB_USER ) ||
- ( cert->trust->objectSigningFlags & CERTDB_USER )) &&
- ( cert->nickname != NULL ) &&
- (nsslowkey_KeyForCertExists(keyHandle, cert) == SECSuccess)) {
- PK11Object *obj;
- pk11_importCertificate(slot, cert, NULL, 0, PR_FALSE);
- obj = pk11_importPublicKey(slot, NULL, cert, NULL);
- if (obj) pk11_AddSlotObject(slot, obj);
+ certHandle = slot->certDB;
+ if (certHandle == NULL) {
+ goto crl_loser;
}
- nsslowcert_DestroyCertificate(cert);
+ 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);
+ }
}
- if (certData.certs) PORT_Free(certData.certs);
+crl_loser:
+ /* Add S/MIME entry stuff */
- return;
+ return CKR_OK;
}
@@ -4087,74 +3430,51 @@ pk11_searchCerts(PK11Slot *slot, CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) {
CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
CK_ATTRIBUTE_PTR pTemplate,CK_ULONG ulCount)
{
- PK11ObjectListElement *objectList = NULL;
- PK11ObjectListElement *olp;
PK11SearchResults *search,*freeSearch;
- PK11Session *session;
+ PK11Session *session = NULL;
PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
+ PRBool tokenOnly = PR_FALSE;
int count, i;
- CK_RV crv;
+ CK_RV crv = CKR_OK;
+ PRBool isLoggedIn;
session = pk11_SessionFromHandle(hSession);
if (session == NULL) {
- return CKR_SESSION_HANDLE_INVALID;
- }
-
- /* resync token objects with the data base */
- if ((session->info.slotID == PRIVATE_KEY_SLOT_ID) ||
- (session->info.slotID == FIPS_SLOT_ID)) {
- if (slot->DB_loaded == PR_FALSE) {
- /* if we aren't logged in, we can't unload all key keys
- * and certs. Just unload those certs we need for this search
- */
- if ((!slot->isLoggedIn) && (slot->needLogin)) {
- pk11_searchCerts(slot,pTemplate,ulCount);
- } else {
- pk11_importKeyDB(slot);
- slot->DB_loaded = PR_TRUE;
- }
- }
- }
-
-
- /* build list of found objects in the session */
- crv = pk11_searchObjectList(&objectList,slot->tokObjects,
- slot->objectLock, pTemplate, ulCount, (PRBool)((!slot->needLogin) ||
- slot->isLoggedIn));
- if (crv != CKR_OK) {
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return crv;
- }
-
-
- /* copy list to session */
- count = 0;
- for (olp = objectList; olp != NULL; olp = olp->next) {
- count++;
+ crv = CKR_SESSION_HANDLE_INVALID;
+ goto loser;
}
+
search = (PK11SearchResults *)PORT_Alloc(sizeof(PK11SearchResults));
if (search == NULL) {
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return CKR_HOST_MEMORY;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
}
search->handles = (CK_OBJECT_HANDLE *)
- PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * count);
+ PORT_Alloc(sizeof(CK_OBJECT_HANDLE) * NSC_SEARCH_BLOCK_SIZE);
if (search->handles == NULL) {
- PORT_Free(search);
- pk11_FreeObjectList(objectList);
- pk11_FreeSession(session);
- return CKR_HOST_MEMORY;
+ crv = CKR_HOST_MEMORY;
+ goto loser;
+ }
+ search->index = 0;
+ search->size = 0;
+ search->array_size = NSC_SEARCH_BLOCK_SIZE;
+ isLoggedIn = (PRBool)((!slot->needLogin) || slot->isLoggedIn);
+
+ crv = pk11_searchTokenList(slot, search, pTemplate, ulCount, &tokenOnly,
+ isLoggedIn);
+ if (crv != CKR_OK) {
+ goto loser;
}
- for (i=0; i < count; i++) {
- search->handles[i] = objectList->object->handle;
- objectList = pk11_FreeObjectListElement(objectList);
+
+ /* build list of found objects in the session */
+ if (!tokenOnly) {
+ crv = pk11_searchObjectList(search, slot->tokObjects,
+ slot->objectLock, pTemplate, ulCount, isLoggedIn);
+ }
+ if (crv != CKR_OK) {
+ goto loser;
}
- /* store the search info */
- search->index = 0;
- search->size = count;
if ((freeSearch = session->search) != NULL) {
session->search = NULL;
pk11_FreeSearch(freeSearch);
@@ -4162,6 +3482,15 @@ CK_RV NSC_FindObjectsInit(CK_SESSION_HANDLE hSession,
session->search = search;
pk11_FreeSession(session);
return CKR_OK;
+
+loser:
+ if (freeSearch) {
+ pk11_FreeSearch(freeSearch);
+ }
+ if (session) {
+ pk11_FreeSession(session);
+ }
+ return crv;
}
diff --git a/security/nss/lib/softoken/pkcs11.h b/security/nss/lib/softoken/pkcs11.h
index 9ada2625e..9b54421e7 100644
--- a/security/nss/lib/softoken/pkcs11.h
+++ b/security/nss/lib/softoken/pkcs11.h
@@ -16,7 +16,7 @@
* Copyright (C) 1994-2000 Netscape Communications Corporation. All
* Rights Reserved.
*
- * Contributor(s):
+ * Contributor(s): RSA Labs
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@@ -35,6 +35,9 @@
* is granted provided that it is identified as "RSA Security In.c Public-Key
* Cryptography Standards (PKCS)" in all material mentioning or referencing
* this document.
+ *
+ * The latest version of this header can be found at:
+ * http://www.rsalabs.com/pkcs/pkcs-11/index.html
*/
#ifndef _PKCS11_H_
#define _PKCS11_H_ 1
@@ -313,12 +316,4 @@ struct CK_FUNCTION_LIST {
}
#endif
-/*
-** Functions called directly by applications to configure the FIPS token.
-*/
-extern void PK11_ConfigurePKCS11(char *man, char *libdes, char *tokdes,
- char *ptokdes, char *slotdes, char *pslotdes, char *fslotdes,
- char *fpslotdes, int minPwd, int pwdRequired);
-extern void PK11_ConfigureFIPS(char *slotdes, char *pslotdes);
-
#endif
diff --git a/security/nss/lib/softoken/pkcs11c.c b/security/nss/lib/softoken/pkcs11c.c
index d702c1452..f1ab1df0c 100644
--- a/security/nss/lib/softoken/pkcs11c.c
+++ b/security/nss/lib/softoken/pkcs11c.c
@@ -1448,17 +1448,19 @@ pk11_HMACCmp(CK_ULONG *copyLen,unsigned char *sig,unsigned int sigLen,
* common HMAC initalization routine
*/
static CK_RV
-pk11_doHMACInit(PK11SessionContext *context,SECOidTag oid,
+pk11_doHMACInit(PK11SessionContext *context,HASH_HashType hash,
PK11Object *key, CK_ULONG mac_size)
{
PK11Attribute *keyval;
HMACContext *HMACcontext;
CK_ULONG *intpointer;
+ const SECHashObject *hashObj = &SECRawHashObjects[hash];
keyval = pk11_FindAttribute(key,CKA_VALUE);
if (keyval == NULL) return CKR_KEY_SIZE_RANGE;
- HMACcontext = HMAC_Create(oid, (const unsigned char*)keyval->attrib.pValue,
+ HMACcontext = HMAC_Create(hashObj,
+ (const unsigned char*)keyval->attrib.pValue,
keyval->attrib.ulValueLen);
context->hashInfo = HMACcontext;
context->multi = PR_TRUE;
@@ -2103,25 +2105,25 @@ finish_rsa:
break;
case CKM_MD2_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD2_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,MD2_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,MD2_LENGTH);
break;
case CKM_MD5_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD5_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,MD5_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,MD5_LENGTH);
break;
case CKM_SHA_1_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_SHA_1_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,SHA1_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
break;
case CKM_SSL3_MD5_MAC:
crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,
@@ -2508,25 +2510,25 @@ finish_rsa:
break;
case CKM_MD2_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD2_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD2,key,MD2_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD2,key,MD2_LENGTH);
break;
case CKM_MD5_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_MD5_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_MD5,key,MD5_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgMD5,key,MD5_LENGTH);
break;
case CKM_SHA_1_HMAC_GENERAL:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,
*(CK_ULONG *)pMechanism->pParameter);
break;
case CKM_SHA_1_HMAC:
- crv = pk11_doHMACInit(context,SEC_OID_SHA1,key,SHA1_LENGTH);
+ crv = pk11_doHMACInit(context,HASH_AlgSHA1,key,SHA1_LENGTH);
break;
case CKM_SSL3_MD5_MAC:
crv = pk11_doSSLMACInit(context,SEC_OID_MD5,key,
@@ -2755,105 +2757,52 @@ CK_RV NSC_GenerateRandom(CK_SESSION_HANDLE hSession,
**************************** Key Functions: ************************
*/
-CK_RV
-pk11_pbe_hmac_key_gen(CK_MECHANISM_PTR pMechanism, char *buf,
- unsigned long *len, PRBool faultyPBE3DES)
-{
- PBEBitGenContext *pbeCx;
- SECItem pwd, salt, *key;
- SECOidTag hashAlg;
- unsigned long keylenbits;
- CK_PBE_PARAMS *pbe_params = NULL;
- pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- pwd.data = (unsigned char *)pbe_params->pPassword;
- pwd.len = (unsigned int)pbe_params->ulPasswordLen;
- salt.data = (unsigned char *)pbe_params->pSalt;
- salt.len = (unsigned int)pbe_params->ulSaltLen;
- switch (pMechanism->mechanism) {
- case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
- hashAlg = SEC_OID_SHA1; keylenbits = 160; break;
- case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
- hashAlg = SEC_OID_MD5; keylenbits = 128; break;
- case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- hashAlg = SEC_OID_MD2; keylenbits = 128; break;
- default:
- return CKR_MECHANISM_INVALID;
- }
- pbeCx = PBE_CreateContext(hashAlg, pbeBitGenIntegrityKey, &pwd,
- &salt, keylenbits, pbe_params->ulIteration);
- key = PBE_GenerateBits(pbeCx);
- PORT_Memcpy(buf, key->data, key->len);
- *len = key->len;
- PBE_DestroyContext(pbeCx);
- SECITEM_ZfreeItem(key, PR_TRUE);
- return CKR_OK;
-}
/*
* generate a password based encryption key. This code uses
- * PKCS5 to do the work. Note that it calls PBE_PK11ParamToAlgid, which is
- * a utility function in secpkcs5.c. This function is used in here
- * and in PK11_ParamToAlgid.
+ * PKCS5 to do the work.
*/
-CK_RV
-pk11_pbe_key_gen(SECOidTag algtag,CK_MECHANISM_PTR pMechanism,
- char *buf,CK_ULONG *key_length, PRBool faulty3DES)
+static CK_RV
+nsc_pbe_key_gen(NSSPKCS5PBEParameter *pkcs5_pbe, CK_MECHANISM_PTR pMechanism,
+ char *buf, CK_ULONG *key_length, PRBool faulty3DES)
{
SECAlgorithmID algid;
- SECItem *pbe_key = NULL, mech;
+ SECItem *pbe_key = NULL, iv, pwitem;
CK_PBE_PARAMS *pbe_params = NULL;
SECStatus pbe_rv;
*key_length = 0;
+ iv.data = NULL; iv.len = 0;
- mech.data = (unsigned char *)pMechanism->pParameter;
- mech.len = (unsigned int)pMechanism->ulParameterLen;
-
- /* A common routine to map from Params to AlgIDs for PBE
- * algorithms was created in secpkcs5.c. This function is
- * called both by PK11_ParamToAlgid and this function.
- */
- pbe_rv = PBE_PK11ParamToAlgid(algtag, &mech, NULL, &algid);
- if (pbe_rv != SECSuccess) {
- return CKR_DATA_INVALID;
- }
pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
- mech.data = (unsigned char *)pbe_params->pPassword;
- mech.len = (unsigned int)pbe_params->ulPasswordLen;
- pbe_key = SEC_PKCS5GetKey(&algid, &mech, faulty3DES);
+
+ pwitem.data = (unsigned char *)pbe_params->pPassword;
+ pwitem.len = (unsigned int)pbe_params->ulPasswordLen;
+ pbe_key = nsspkcs5_ComputeKeyAndIV(pkcs5_pbe, &pwitem, &iv, faulty3DES);
if (pbe_key == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
return CKR_HOST_MEMORY;
}
+
PORT_Memcpy(buf, pbe_key->data, pbe_key->len);
*key_length = pbe_key->len;
SECITEM_ZfreeItem(pbe_key, PR_TRUE);
pbe_key = NULL;
- if (pbe_params->pInitVector == NULL) {
- pbe_key = SEC_PKCS5GetIV(&algid, &mech, faulty3DES);
- if (pbe_key == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- return CKR_HOST_MEMORY;
- }
+ if (iv.data && pbe_params->pInitVector == NULL) {
pbe_params->pInitVector = (CK_CHAR_PTR)PORT_ZAlloc(pbe_key->len);
if (pbe_params->pInitVector == NULL) {
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
return CKR_HOST_MEMORY;
}
- PORT_Memcpy(pbe_params->pInitVector, pbe_key->data, pbe_key->len);
+ PORT_Memcpy(pbe_params->pInitVector, iv.data, iv.len);
}
- SECITEM_ZfreeItem(pbe_key, PR_TRUE);
- SECOID_DestroyAlgorithmID(&algid, PR_FALSE);
return CKR_OK;
}
static CK_RV
-nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism,
- CK_KEY_TYPE *key_type,CK_ULONG *key_length) {
+nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism, CK_KEY_TYPE *key_type,
+ CK_ULONG *key_length)
+{
CK_RV crv = CKR_OK;
switch (mechanism) {
@@ -2904,81 +2853,112 @@ nsc_SetupBulkKeyGen(CK_MECHANISM_TYPE mechanism,
return crv;
}
+CK_RV
+nsc_SetupHMACKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe)
+{
+ SECItem pwd, salt, *key;
+ HASH_HashType hashType;
+ unsigned long keylenbits;
+ CK_PBE_PARAMS *pbe_params = NULL;
+ NSSPKCS5PBEParameter *params;
+ PRArenaPool *arena = NULL;
+ SECStatus rv;
+
+ *pbe == NULL;
+
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (arena == NULL) {
+ return CKR_HOST_MEMORY;
+ }
+
+ params = (NSSPKCS5PBEParameter *) PORT_ArenaZAlloc(arena,
+ sizeof(NSSPKCS5PBEParameter));
+ if (params == NULL) {
+ PORT_FreeArena(arena,PR_TRUE);
+ return CKR_HOST_MEMORY;
+ }
+
+ params->ivLen = 0;
+ params->pbeType = NSSPKCS5_PKCS12_V2;
+ params->hashType = HASH_AlgSHA1;
+ params->encAlg = SEC_OID_SHA1; /* any invalid value */
+ params->is2KeyDES = PR_FALSE;
+ params->keyID = pbeBitGenIntegrityKey;
+ params->iter = pbe_params->ulIteration;
+
+ pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
+ salt.data = (unsigned char *)pbe_params->pSalt;
+ salt.len = (unsigned int)pbe_params->ulSaltLen;
+ rv = SECITEM_CopyItem(arena,&params->salt,&salt);
+ if (rv != SECSuccess) {
+ PORT_FreeArena(arena,PR_TRUE);
+ return CKR_HOST_MEMORY;
+ }
+ switch (pMechanism->mechanism) {
+ case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
+ params->hashType = HASH_AlgSHA1;
+ params->keyLen = 20;
+ break;
+ case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
+ params->hashType = HASH_AlgMD5;
+ params->keyLen = 16;
+ break;
+ case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
+ params->hashType = HASH_AlgMD2;
+ params->keyLen = 16;
+ break;
+ default:
+ PORT_FreeArena(arena,PR_TRUE);
+ return CKR_MECHANISM_INVALID;
+ }
+ *pbe = params;
+ return CKR_OK;
+}
+/* maybe this should be table driven? */
static CK_RV
-nsc_SetupPBEKeyGen(CK_MECHANISM_TYPE mechanism,SECOidTag *algtag,
- CK_KEY_TYPE *key_type,CK_ULONG *key_length) {
+nsc_SetupPBEKeyGen(CK_MECHANISM_PTR pMechanism, NSSPKCS5PBEParameter **pbe,
+ CK_KEY_TYPE *key_type)
+{
CK_RV crv = CKR_OK;
+ SECOidData *oid;
+ CK_PBE_PARAMS *pbe_params;
+ NSSPKCS5PBEParameter *params;
+ SECItem salt;
- switch (mechanism) {
- case CKM_PBE_MD2_DES_CBC:
- *algtag = SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
+ oid = SECOID_FindOIDByMechanism(pMechanism->mechanism);
+ if (oid == NULL) {
+ return CKR_MECHANISM_INVALID;
+ }
+
+ pbe_params = (CK_PBE_PARAMS *)pMechanism->pParameter;
+ salt.data = (unsigned char *)pbe_params->pSalt;
+ salt.len = (unsigned int)pbe_params->ulSaltLen;
+
+ params=nsspkcs5_NewParam(oid->offset, &salt, pbe_params->ulIteration);
+ if (params == NULL) {
+ return CKR_MECHANISM_INVALID;
+ }
+
+
+ switch (params->encAlg) {
+ case SEC_OID_DES_CBC:
*key_type = CKK_DES;
break;
+ case SEC_OID_DES_EDE3_CBC:
+ *key_type = params->is2KeyDES ? CKK_DES2 : CKK_DES3;
case CKM_PBE_MD5_DES_CBC:
- *algtag = SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC;
*key_type = CKK_DES;
break;
- case CKM_PBE_SHA1_RC4_40:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- *key_length = 5;
+ case SEC_OID_RC2_CBC:
*key_type = CKK_RC4;
break;
- case CKM_PBE_SHA1_RC4_128:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- *key_length = 16;
- *key_type = CKK_RC4;
- break;
- case CKM_PBE_SHA1_RC2_40_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- *key_length = 5;
- *key_type = CKK_RC2;
- break;
- case CKM_PBE_SHA1_RC2_128_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- *key_length = 16;
- *key_type = CKK_RC2;
- break;
- case CKM_PBE_SHA1_DES3_EDE_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- *key_length = 24;
- *key_type = CKK_DES3;
- break;
- case CKM_PBE_SHA1_DES2_EDE_CBC:
- *algtag = SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- *key_length = 16;
- *key_type = CKK_DES2;
- break;
- case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
- *algtag = SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- *key_type = CKK_DES;
- break;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC;
- *key_type = CKK_DES3;
- break;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- *key_type = CKK_RC2;
- break;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- *key_type = CKK_RC2;
- break;
- case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4;
- *key_type = CKK_RC4;
- break;
- case CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4:
- *algtag = SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4;
+ case SEC_OID_RC4:
*key_type = CKK_RC4;
break;
default:
- PORT_Assert(0);
crv = CKR_MECHANISM_INVALID;
break;
}
-
return crv;
}
@@ -2998,8 +2978,8 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
int i;
PK11Slot *slot = pk11_SlotFromSessionHandle(hSession);
char buf[MAX_KEY_LEN];
- enum {pk11_pbe, pk11_pbe_hmac, pk11_ssl, pk11_bulk} key_gen_type;
- SECOidTag algtag = SEC_OID_UNKNOWN;
+ enum {nsc_pbe, nsc_ssl, nsc_bulk} key_gen_type;
+ NSSPKCS5PBEParameter *pbe_param;
SSL3RSAPreMasterSecret *rsa_pms;
CK_VERSION *version;
/* in very old versions of NSS, there were implementation errors with key
@@ -3040,7 +3020,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
pk11_DeleteAttributeType(key,CKA_VALUE);
/* Now Set up the parameters to generate the key (based on mechanism) */
- key_gen_type = pk11_bulk; /* bulk key by default */
+ key_gen_type = nsc_bulk; /* bulk key by default */
switch (pMechanism->mechanism) {
case CKM_CDMF_KEY_GEN:
case CKM_DES_KEY_GEN:
@@ -3059,16 +3039,17 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
case CKM_SSL3_PRE_MASTER_KEY_GEN:
key_type = CKK_GENERIC_SECRET;
key_length = 48;
- key_gen_type = pk11_ssl;
+ key_gen_type = nsc_ssl;
break;
- case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
- faultyPBE3DES = PR_TRUE;
case CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN:
case CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN:
- key_gen_type = pk11_pbe_hmac;
+ key_gen_type = nsc_pbe;
key_type = CKK_GENERIC_SECRET;
+ crv = nsc_SetupHMACKeyGen(pMechanism, &pbe_param);
break;
+ case CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC:
+ faultyPBE3DES = PR_TRUE;
case CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC:
case CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC:
case CKM_NETSCAPE_PBE_SHA1_DES_CBC:
@@ -3083,9 +3064,8 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
case CKM_PBE_SHA1_RC4_40:
case CKM_PBE_MD5_DES_CBC:
case CKM_PBE_MD2_DES_CBC:
- key_gen_type = pk11_pbe;
- crv = nsc_SetupPBEKeyGen(pMechanism->mechanism,&algtag,
- &key_type,&key_length);
+ key_gen_type = nsc_pbe;
+ crv = nsc_SetupPBEKeyGen(pMechanism,&pbe_param, &key_type);
break;
default:
crv = CKR_MECHANISM_INVALID;
@@ -3109,15 +3089,11 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
* now to the actual key gen.
*/
switch (key_gen_type) {
- case pk11_pbe_hmac:
- crv = pk11_pbe_hmac_key_gen(pMechanism, buf, &key_length,
- faultyPBE3DES);
- break;
- case pk11_pbe:
- crv = pk11_pbe_key_gen(algtag, pMechanism, buf, &key_length,
+ case nsc_pbe:
+ crv = nsc_pbe_key_gen(pbe_param, pMechanism, buf, &key_length,
faultyPBE3DES);
break;
- case pk11_ssl:
+ case nsc_ssl:
rsa_pms = (SSL3RSAPreMasterSecret *)buf;
version = (CK_VERSION *)pMechanism->pParameter;
rsa_pms->client_version[0] = version->major;
@@ -3125,7 +3101,7 @@ CK_RV NSC_GenerateKey(CK_SESSION_HANDLE hSession,
crv =
NSC_GenerateRandom(0,&rsa_pms->random[0], sizeof(rsa_pms->random));
break;
- case pk11_bulk:
+ case nsc_bulk:
/* get the key, check for weak keys and repeat if found */
do {
crv = NSC_GenerateRandom(0, (unsigned char *)buf, key_length);
@@ -3609,7 +3585,7 @@ static SECItem *pk11_PackagePrivateKey(PK11Object *key)
}
dummy = SEC_ASN1EncodeInteger(arena, &pki->version,
- SEC_PRIVATE_KEY_INFO_VERSION);
+ NSSLOWKEY_PRIVATE_KEY_INFO_VERSION);
if(!dummy) {
rv = SECFailure;
goto loser;
@@ -4080,10 +4056,10 @@ pk11_buildSSLKey(CK_SESSION_HANDLE hSession, PK11Object *baseKey,
/*
* now lets create an object to hang the attributes off of
*/
- *keyHandle = CK_INVALID_KEY;
+ *keyHandle = CK_INVALID_HANDLE;
key = pk11_NewObject(baseKey->slot);
if (key == NULL) return CKR_HOST_MEMORY;
- key->wasDerived = PR_TRUE;
+ pk11_narrowToSessionObject(key)->wasDerived = PR_TRUE;
crv = pk11_CopyObject(key,baseKey);
if (crv != CKR_OK) goto loser;
@@ -4131,16 +4107,16 @@ loser:
static void
pk11_freeSSLKeys(CK_SESSION_HANDLE session,
CK_SSL3_KEY_MAT_OUT *returnedMaterial ) {
- if (returnedMaterial->hClientMacSecret != CK_INVALID_KEY) {
+ if (returnedMaterial->hClientMacSecret != CK_INVALID_HANDLE) {
NSC_DestroyObject(session,returnedMaterial->hClientMacSecret);
}
- if (returnedMaterial->hServerMacSecret != CK_INVALID_KEY) {
+ if (returnedMaterial->hServerMacSecret != CK_INVALID_HANDLE) {
NSC_DestroyObject(session, returnedMaterial->hServerMacSecret);
}
- if (returnedMaterial->hClientKey != CK_INVALID_KEY) {
+ if (returnedMaterial->hClientKey != CK_INVALID_HANDLE) {
NSC_DestroyObject(session, returnedMaterial->hClientKey);
}
- if (returnedMaterial->hServerKey != CK_INVALID_KEY) {
+ if (returnedMaterial->hServerKey != CK_INVALID_HANDLE) {
NSC_DestroyObject(session, returnedMaterial->hServerKey);
}
}
@@ -4233,7 +4209,7 @@ pk11_MapKeySize(CK_KEY_TYPE keyType) {
/* TLS P_hash function */
static SECStatus
-pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
+pk11_P_hash(HASH_HashType hashType, const SECItem *secret, const char *label,
SECItem *seed, SECItem *result)
{
unsigned char state[PHASH_STATE_MAX_LEN];
@@ -4244,6 +4220,7 @@ pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
SECStatus status;
HMACContext *cx;
SECStatus rv = SECFailure;
+ const SECHashObject *hashObj = &SECRawHashObjects[hashType];
PORT_Assert((secret != NULL) && (secret->data != NULL || !secret->len));
PORT_Assert((seed != NULL) && (seed->data != NULL));
@@ -4255,7 +4232,7 @@ pk11_P_hash(SECOidTag alg, const SECItem *secret, const char *label,
if (label != NULL)
label_len = PORT_Strlen(label);
- cx = HMAC_Create(alg, secret->data, secret->len);
+ cx = HMAC_Create(hashObj, secret->data, secret->len);
if (cx == NULL)
goto loser;
@@ -4330,11 +4307,11 @@ pk11_PRF(const SECItem *secret, const char *label, SECItem *seed,
goto loser;
tmp.len = result->len;
- status = pk11_P_hash(SEC_OID_MD5, &S1, label, seed, result);
+ status = pk11_P_hash(HASH_AlgMD5, &S1, label, seed, result);
if (status != SECSuccess)
goto loser;
- status = pk11_P_hash(SEC_OID_SHA1, &S2, label, seed, &tmp);
+ status = pk11_P_hash(HASH_AlgSHA1, &S2, label, seed, &tmp);
if (status != SECSuccess)
goto loser;
@@ -4404,7 +4381,7 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
/*
* now lets create an object to hang the attributes off of
*/
- if (phKey) *phKey = CK_INVALID_KEY;
+ if (phKey) *phKey = CK_INVALID_HANDLE;
key = pk11_NewObject(slot); /* fill in the handle later */
if (key == NULL) {
@@ -4513,9 +4490,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
ssl3_master = (CK_SSL3_MASTER_KEY_DERIVE_PARAMS *)
pMechanism->pParameter;
if (ssl3_master->pVersion) {
+ PK11SessionObject *sessKey = pk11_narrowToSessionObject(key);
rsa_pms = (SSL3RSAPreMasterSecret *) att->attrib.pValue;
/* don't leak more key material then necessary for SSL to work */
- if (key->wasDerived) {
+ if ((sessKey == NULL) || sessKey->wasDerived) {
ssl3_master->pVersion->major = 0xff;
ssl3_master->pVersion->minor = 0xff;
} else {
@@ -4652,10 +4630,10 @@ CK_RV NSC_DeriveKey( CK_SESSION_HANDLE hSession,
* clear out our returned keys so we can recover on failure
*/
ssl3_keys_out = ssl3_keys->pReturnedKeyMaterial;
- ssl3_keys_out->hClientMacSecret = CK_INVALID_KEY;
- ssl3_keys_out->hServerMacSecret = CK_INVALID_KEY;
- ssl3_keys_out->hClientKey = CK_INVALID_KEY;
- ssl3_keys_out->hServerKey = CK_INVALID_KEY;
+ ssl3_keys_out->hClientMacSecret = CK_INVALID_HANDLE;
+ ssl3_keys_out->hServerMacSecret = CK_INVALID_HANDLE;
+ ssl3_keys_out->hClientKey = CK_INVALID_HANDLE;
+ ssl3_keys_out->hServerKey = CK_INVALID_HANDLE;
/*
* generate the key material: This looks amazingly similar to the
@@ -5222,8 +5200,10 @@ key_and_mac_derive_fail:
/* link the key object into the list */
if (key) {
+ PK11SessionObject *sessKey = pk11_narrowToSessionObject(key);
+ PORT_Assert(sessKey);
/* get the session */
- key->wasDerived = PR_TRUE;
+ sessKey->wasDerived = PR_TRUE;
session = pk11_SessionFromHandle(hSession);
if (session == NULL) {
pk11_FreeObject(key);
diff --git a/security/nss/lib/softoken/pkcs11f.h b/security/nss/lib/softoken/pkcs11f.h
index 71ee2676a..70d34da5e 100644
--- a/security/nss/lib/softoken/pkcs11f.h
+++ b/security/nss/lib/softoken/pkcs11f.h
@@ -150,10 +150,11 @@ CK_PKCS11_FUNCTION_INFO(C_GetMechanismInfo)
CK_PKCS11_FUNCTION_INFO(C_InitToken)
#ifdef CK_NEED_ARG_LIST
(
- CK_SLOT_ID slotID, /* ID of the token's slot */
- CK_CHAR_PTR pPin, /* the SO's initial PIN */
- CK_ULONG ulPinLen, /* length in bytes of the PIN */
- CK_CHAR_PTR pLabel /* 32-byte token label (blank padded) */
+/* pLabel changed from CK_CHAR_PTR to CK_UTF8CHAR_PTR for v2.10 */
+ CK_SLOT_ID slotID, /* ID of the token's slot */
+ CK_CHAR_PTR pPin, /* the SO's initial PIN */
+ CK_ULONG ulPinLen, /* length in bytes of the PIN */
+ CK_UTF8CHAR_PTR pLabel /* 32-byte token label (blank padded) */
);
#endif
diff --git a/security/nss/lib/softoken/pkcs11i.h b/security/nss/lib/softoken/pkcs11i.h
index bada687f7..102fb5738 100644
--- a/security/nss/lib/softoken/pkcs11i.h
+++ b/security/nss/lib/softoken/pkcs11i.h
@@ -43,11 +43,61 @@
#include "pkcs11t.h"
#include "pcertt.h"
-#define PKCS11_USE_THREADS
-#define NO_ARENA
-#define MAX_OBJS_ATTRS 45
-#define ATTR_SPACE 50 /* hold up to a SSL premaster secret */
+/*
+ * Configuration Defines
+ *
+ * The following defines affect the space verse speed trade offs of
+ * the PKCS #11 module. For the most part the current settings are optimized
+ * for web servers, where we want faster speed and lower lock contention at
+ * the expense of space.
+ */
+
+#define PKCS11_USE_THREADS /* set to true of you are need threads */
+/*
+ * Attribute Allocation strategy:
+ *
+ * 1) static allocation (PKCS11_STATIC_ATTRIBUTES set
+ * PKCS11_REF_COUNT_ATTRIBUTES not set)
+ * Attributes are pre-allocated as part of the session object and used from
+ * the object array.
+ *
+ * 2) heap allocation with ref counting (PKCS11_STATIC_ATTRIBUTES not set
+ * PKCS11_REF_COUNT_ATTRIBUTES set)
+ * Attributes are allocated from the heap when needed and freed when their
+ * reference count goes to zero.
+ *
+ * 3) arena allocation (PKCS11_STATIC_ATTRIBUTES not set
+ * PKCS11_REF_COUNT_ATTRIBUTE not set)
+ * Attributes are allocated from the arena when needed and freed only when
+ * the object goes away.
+ */
+#define PKCS11_STATIC_ATTRIBUTES
+/*#define PKCS11_REF_COUNT_ATTRIBUTES */
+/* the next two are only active if PKCS11_STATIC_ATTRIBUTES is set */
+#define MAX_OBJS_ATTRS 45 /* number of attributes to preallocate in
+ * the object (must me the absolute max) */
+#define ATTR_SPACE 50 /* Maximum size of attribute data before extra
+ * data needs to be allocated. This is set to
+ * enough space to hold an SSL MASTER secret */
+
+#define NSC_STRICT PR_FALSE /* forces the code to do strict template
+ * matching when doing C_FindObject on token
+ * objects. This will slow down search in
+ * NSS. */
+/* default search block allocations and increments */
+#define NSC_CERT_BLOCK_SIZE 50
+#define NSC_SEARCH_BLOCK_SIZE 5
+/* 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
+#define SESSION_OBJECT_HASH_SIZE 32
+#define TOKEN_OBJECT_HASH_SIZE 1024
+#define SESSION_HASH_SIZE 512
+#define MAX_OBJECT_LIST_SIZE 800 /* how many objects to keep on the free list
+ * before we start freeing them */
+#define MAX_KEY_LEN 256
+
#ifdef PKCS11_USE_THREADS
@@ -61,6 +111,8 @@ typedef struct PK11AttributeStr PK11Attribute;
typedef struct PK11ObjectListStr PK11ObjectList;
typedef struct PK11ObjectListElementStr PK11ObjectListElement;
typedef struct PK11ObjectStr PK11Object;
+typedef struct PK11SessionObjectStr PK11SessionObject;
+typedef struct PK11TokenObjectStr PK11TokenObject;
typedef struct PK11SessionStr PK11Session;
typedef struct PK11SlotStr PK11Slot;
typedef struct PK11SessionContextStr PK11SessionContext;
@@ -79,17 +131,6 @@ typedef void (*PK11Hash)(void *,void *,unsigned int);
typedef void (*PK11End)(void *,void *,unsigned int *,unsigned int);
typedef void (*PK11Free)(void *);
-/*
- * 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
-#define SESSION_OBJECT_HASH_SIZE 32
-#define TOKEN_OBJECT_HASH_SIZE 1024
-#define SESSION_HASH_SIZE 512
-#define MAX_KEY_LEN 256
-#define MAX_OBJECT_LIST_SIZE 800
-
/* Value to tell if an attribute is modifiable or not.
* NEVER: attribute is only set on creation.
* ONCOPY: attribute is set on creation and can only be changed on copy.
@@ -119,14 +160,16 @@ typedef enum {
struct PK11AttributeStr {
PK11Attribute *next;
PK11Attribute *prev;
-#ifdef REF_COUNT_ATTRIBUTE
+ PRBool freeAttr;
+ PRBool freeData;
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
int refCount;
PZLock *refLock;
#endif
/*must be called handle to make pk11queue_find work */
CK_ATTRIBUTE_TYPE handle;
CK_ATTRIBUTE attrib;
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
unsigned char space[ATTR_SPACE];
#endif
};
@@ -146,27 +189,33 @@ struct PK11ObjectListStr {
*/
struct PK11ObjectStr {
PK11Object *next;
- PK11Object *prev;
- PK11ObjectList sessionList;
- CK_OBJECT_HANDLE handle;
-#ifdef NO_ARENA
- int nextAttr;
-#else
- PLArenaPool *arena;
-#endif
- int refCount;
+ PK11Object *prev;
+ CK_OBJECT_CLASS objclass;
+ CK_OBJECT_HANDLE handle;
+ int refCount;
PZLock *refLock;
- PZLock *attributeLock;
- PK11Session *session;
PK11Slot *slot;
- CK_OBJECT_CLASS objclass;
void *objectInfo;
PK11Free infoFree;
- char *label;
- PRBool inDB;
+#ifndef PKCS11_STATIC_ATTRIBUTES
+ PLArenaPool *arena;
+#endif
+};
+
+struct PK11TokenObjectStr {
+ PK11Object obj;
+ SECItem dbKey;
+};
+
+struct PK11SessionObjectStr {
+ PK11Object obj;
+ PK11ObjectList sessionList;
+ PZLock *attributeLock;
+ PK11Session *session;
PRBool wasDerived;
PK11Attribute *head[ATTRIBUTE_HASH_SIZE];
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ int nextAttr;
PK11Attribute attrList[MAX_OBJS_ATTRS];
#endif
};
@@ -186,6 +235,7 @@ struct PK11SearchResultsStr {
CK_OBJECT_HANDLE *handles;
int size;
int index;
+ int array_size;
};
@@ -271,6 +321,7 @@ struct PK11SlotStr {
int sessionCount;
int rwSessionCount;
int tokenIDCount;
+ PLHashTable *tokenHashTable;
PK11Object *tokObjects[TOKEN_OBJECT_HASH_SIZE];
PK11Session *head[SESSION_HASH_SIZE];
};
@@ -312,9 +363,15 @@ struct PK11SSLMACInfoStr {
#define PK11_TOKEN_MASK 0x80000000L
#define PK11_TOKEN_MAGIC 0x80000000L
#define PK11_TOKEN_TYPE_MASK 0x70000000L
-#define PK11_TOKEN_TYPE_CERT 0x00000000L
+/* keydb (high bit == 0) */
#define PK11_TOKEN_TYPE_PRIV 0x10000000L
#define PK11_TOKEN_TYPE_PUB 0x20000000L
+#define PK11_TOKEN_TYPE_KEY 0x30000000L
+/* certdb (high bit == 1) */
+#define PK11_TOKEN_TYPE_TRUST 0x40000000L
+#define PK11_TOKEN_TYPE_CRL 0x50000000L
+#define PK11_TOKEN_TYPE_SMIME 0x60000000L
+#define PK11_TOKEN_TYPE_CERT 0x70000000L
/* how big a password/pin we can deal with */
#define PK11_MAX_PIN 255
@@ -426,14 +483,14 @@ extern CK_RV pk11_defaultAttribute(PK11Object *object, CK_ATTRIBUTE_TYPE type,
extern PK11Object *pk11_NewObject(PK11Slot *slot);
extern CK_RV pk11_CopyObject(PK11Object *destObject, PK11Object *srcObject);
extern PK11FreeStatus pk11_FreeObject(PK11Object *object);
-extern void pk11_DeleteObject(PK11Session *session, PK11Object *object);
+extern CK_RV pk11_DeleteObject(PK11Session *session, PK11Object *object);
extern void pk11_ReferenceObject(PK11Object *object);
extern PK11Object *pk11_ObjectFromHandle(CK_OBJECT_HANDLE handle,
PK11Session *session);
extern void pk11_AddSlotObject(PK11Slot *slot, PK11Object *object);
extern void pk11_AddObject(PK11Session *session, PK11Object *object);
-extern CK_RV pk11_searchObjectList(PK11ObjectListElement **objectList,
+extern CK_RV pk11_searchObjectList(PK11SearchResults *search,
PK11Object **head, PZLock *lock,
CK_ATTRIBUTE_PTR inTemplate, int count,
PRBool isLoggedIn);
@@ -488,7 +545,22 @@ CK_RV pk11_DBInit(const char *configdir, const char *certPrefix,
const char *keyPrefix, const char *secmodName, PRBool readOnly,
PRBool noCertDB, PRBool noModDB, PRBool forceOpen);
+/*
+ * narrow objects
+ */
+PK11SessionObject * pk11_narrowToSessionObject(PK11Object *);
+PK11TokenObject * pk11_narrowToTokenObject(PK11Object *);
+/*
+ * token object utilities
+ */
+void pk11_addHandle(PK11SearchResults *search, CK_OBJECT_HANDLE handle);
+PRBool pk11_tokenMatch(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class,
+ CK_ATTRIBUTE_PTR theTemplate,int count);
+CK_OBJECT_HANDLE pk11_mkHandle(PK11Slot *slot,
+ SECItem *dbKey, CK_OBJECT_HANDLE class);
+PK11Object * pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey,
+ CK_OBJECT_HANDLE handle);
SEC_END_PROTOS
#endif /* _PKCS11I_H_ */
diff --git a/security/nss/lib/softoken/pkcs11t.h b/security/nss/lib/softoken/pkcs11t.h
index aa3d70496..124a1bb27 100644
--- a/security/nss/lib/softoken/pkcs11t.h
+++ b/security/nss/lib/softoken/pkcs11t.h
@@ -17,7 +17,6 @@
* Rights Reserved.
*
* Contributor(s):
- * Dr Stephen Henson <stephen.henson@gemplus.com>
*
* Alternatively, the contents of this file may be used under the
* terms of the GNU General Public License Version 2 or later (the
@@ -61,12 +60,17 @@
#define CK_DECLARE_FUNCTION(rv,func) PR_EXTERN(rv) func
#define CK_DECLARE_FUNCTION_POINTER(rv,func) rv (PR_CALLBACK * func)
+#define CK_INVALID_SESSION 0
+
/* an unsigned 8-bit value */
typedef unsigned char CK_BYTE;
/* an unsigned 8-bit character */
typedef CK_BYTE CK_CHAR;
+/* an unsigned 8-bit character */
+typedef CK_BYTE CK_UTF8CHAR;
+
/* a BYTE-sized Boolean flag */
typedef CK_BYTE CK_BBOOL;
@@ -88,6 +92,7 @@ typedef CK_ULONG CK_FLAGS;
typedef CK_BYTE CK_PTR CK_BYTE_PTR;
typedef CK_CHAR CK_PTR CK_CHAR_PTR;
+typedef CK_UTF8CHAR CK_PTR CK_UTF8CHAR_PTR;
typedef CK_ULONG CK_PTR CK_ULONG_PTR;
typedef void CK_PTR CK_VOID_PTR;
@@ -112,12 +117,14 @@ typedef CK_VERSION CK_PTR CK_VERSION_PTR;
typedef struct CK_INFO {
+ /* manufacturerID and libraryDecription have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
CK_VERSION cryptokiVersion; /* PKCS #11 interface ver */
- CK_CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags; /* must be zero */
/* libraryDescription and libraryVersion are new for v2.0 */
- CK_CHAR libraryDescription[32]; /* blank padded */
+ CK_UTF8CHAR libraryDescription[32]; /* blank padded */
CK_VERSION libraryVersion; /* version of library */
} CK_INFO;
@@ -139,8 +146,10 @@ typedef CK_SLOT_ID CK_PTR CK_SLOT_ID_PTR;
/* CK_SLOT_INFO provides information about a slot */
typedef struct CK_SLOT_INFO {
- CK_CHAR slotDescription[64]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
+ /* slotDescription and manufacturerID have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR slotDescription[64]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
CK_FLAGS flags;
/* hardwareVersion and firmwareVersion are new for v2.0 */
@@ -160,9 +169,11 @@ typedef CK_SLOT_INFO CK_PTR CK_SLOT_INFO_PTR;
/* CK_TOKEN_INFO provides information about a token */
typedef struct CK_TOKEN_INFO {
- CK_CHAR label[32]; /* blank padded */
- CK_CHAR manufacturerID[32]; /* blank padded */
- CK_CHAR model[16]; /* blank padded */
+ /* label, manufacturerID, and model have been changed from
+ * CK_CHAR to CK_UTF8CHAR for v2.10 */
+ CK_UTF8CHAR label[32]; /* blank padded */
+ CK_UTF8CHAR manufacturerID[32]; /* blank padded */
+ CK_UTF8CHAR model[16]; /* blank padded */
CK_CHAR serialNumber[16]; /* blank padded */
CK_FLAGS flags; /* see below */
@@ -223,6 +234,57 @@ typedef struct CK_TOKEN_INFO {
* and sign) */
#define CKF_DUAL_CRYPTO_OPERATIONS 0x00000200
+/* CKF_TOKEN_INITIALIZED if new for v2.10. If it is true, the
+ * token has been initialized using C_InitializeToken or an
+ * equivalent mechanism outside the scope of PKCS #11.
+ * Calling C_InitializeToken when this flag is set will cause
+ * the token to be reinitialized. */
+#define CKF_TOKEN_INITIALIZED 0x00000400
+
+/* CKF_SECONDARY_AUTHENTICATION if new for v2.10. If it is
+ * true, the token supports secondary authentication for
+ * private key objects. */
+/* DEPRICATED in v2.11 */
+#define CKF_SECONDARY_AUTHENTICATION 0x00000800
+
+/* CKF_USER_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect user login PIN has been entered at least once
+ * since the last successful authentication. */
+#define CKF_USER_PIN_COUNT_LOW 0x00010000
+
+/* CKF_USER_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect user PIN will it to become locked. */
+#define CKF_USER_PIN_FINAL_TRY 0x00020000
+
+/* CKF_USER_PIN_LOCKED if new for v2.10. If it is true, the
+ * user PIN has been locked. User login to the token is not
+ * possible. */
+#define CKF_USER_PIN_LOCKED 0x00040000
+
+/* CKF_USER_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the user PIN value is the default value set by token
+ * initialization or manufacturing. */
+#define CKF_USER_PIN_TO_BE_CHANGED 0x00080000
+
+/* CKF_SO_PIN_COUNT_LOW if new for v2.10. If it is true, an
+ * incorrect SO login PIN has been entered at least once since
+ * the last successful authentication. */
+#define CKF_SO_PIN_COUNT_LOW 0x00100000
+
+/* CKF_SO_PIN_FINAL_TRY if new for v2.10. If it is true,
+ * supplying an incorrect SO PIN will it to become locked. */
+#define CKF_SO_PIN_FINAL_TRY 0x00200000
+
+/* CKF_SO_PIN_LOCKED if new for v2.10. If it is true, the SO
+ * PIN has been locked. SO login to the token is not possible.
+ */
+#define CKF_SO_PIN_LOCKED 0x00400000
+
+/* CKF_SO_PIN_TO_BE_CHANGED if new for v2.10. If it is true,
+ * the SO PIN value is the default value set by token
+ * initialization or manufacturing. */
+#define CKF_SO_PIN_TO_BE_CHANGED 0x00800000
+
typedef CK_TOKEN_INFO CK_PTR CK_TOKEN_INFO_PTR;
@@ -289,15 +351,28 @@ typedef CK_OBJECT_HANDLE CK_PTR CK_OBJECT_HANDLE_PTR;
typedef CK_ULONG CK_OBJECT_CLASS;
/* The following classes of objects are defined: */
-#define CKO_DATA 0x00000000
-#define CKO_CERTIFICATE 0x00000001
-#define CKO_PUBLIC_KEY 0x00000002
-#define CKO_PRIVATE_KEY 0x00000003
-#define CKO_SECRET_KEY 0x00000004
-#define CKO_VENDOR_DEFINED 0x80000000
+/* CKO_HW_FEATURE is new for v2.10 */
+/* CKO_DOMAIN_PARAMETERS is new for v2.11 */
+#define CKO_DATA 0x00000000
+#define CKO_CERTIFICATE 0x00000001
+#define CKO_PUBLIC_KEY 0x00000002
+#define CKO_PRIVATE_KEY 0x00000003
+#define CKO_SECRET_KEY 0x00000004
+#define CKO_HW_FEATURE 0x00000005
+#define CKO_DOMAIN_PARAMETERS 0x00000006
+#define CKO_VENDOR_DEFINED 0x80000000
typedef CK_OBJECT_CLASS CK_PTR CK_OBJECT_CLASS_PTR;
+/* CK_HW_FEATURE_TYPE is new for v2.10. CK_HW_FEATURE_TYPE is a
+ * value that identifies the hardware feature type of an object
+ * with CK_OBJECT_CLASS equal to CKO_HW_FEATURE. */
+typedef CK_ULONG CK_HW_FEATURE_TYPE;
+
+/* The following hardware feature types are defined */
+#define CKH_MONOTONIC_COUNTER 0x00000001
+#define CKH_CLOCK 0x00000002
+#define CKH_VENDOR_DEFINED 0x80000000
/* CK_KEY_TYPE is a value that identifies a key type */
/* CK_KEY_TYPE was changed from CK_USHORT to CK_ULONG for v2.0 */
@@ -309,10 +384,10 @@ typedef CK_ULONG CK_KEY_TYPE;
#define CKK_DH 0x00000002
/* CKK_ECDSA and CKK_KEA are new for v2.0 */
-
-/* PKCS #11 V2.01 probably won't actually have ECDSA in it */
-#define CKK_ECDSA 0x00000003
-
+/* CKK_X9_42_DH is new for v2.11 */
+#define CKK_ECDSA 0x00000003 /* deprecated in v2.11 */
+#define CKK_EC 0x00000003
+#define CKK_X9_42_DH 0x00000004
#define CKK_KEA 0x00000005
#define CKK_GENERIC_SECRET 0x00000010
@@ -325,8 +400,8 @@ typedef CK_ULONG CK_KEY_TYPE;
/* all these key types are new for v2.0 */
#define CKK_CAST 0x00000016
#define CKK_CAST3 0x00000017
-#define CKK_CAST5 0x00000018
-#define CKK_CAST128 0x00000018 /* CAST128=CAST5 */
+#define CKK_CAST5 0x00000018 /* deprecated in v2.11 */
+#define CKK_CAST128 0x00000018
#define CKK_RC5 0x00000019
#define CKK_IDEA 0x0000001A
#define CKK_SKIPJACK 0x0000001B
@@ -348,7 +423,9 @@ typedef CK_ULONG CK_KEY_TYPE;
typedef CK_ULONG CK_CERTIFICATE_TYPE;
/* The following certificate types are defined: */
+/* CKC_X_509_ATTR_CERT is new for v2.10 */
#define CKC_X_509 0x00000000
+#define CKC_X_509_ATTR_CERT 0x00000001
#define CKC_VENDOR_DEFINED 0x80000000
@@ -365,9 +442,22 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_LABEL 0x00000003
#define CKA_APPLICATION 0x00000010
#define CKA_VALUE 0x00000011
+
+/* CKA_OBJECT_ID is new for v2.10 */
+#define CKA_OBJECT_ID 0x00000012
+
#define CKA_CERTIFICATE_TYPE 0x00000080
#define CKA_ISSUER 0x00000081
#define CKA_SERIAL_NUMBER 0x00000082
+
+/* CKA_AC_ISSUER, CKA_OWNER, and CKA_ATTR_TYPES are new
+ * for v2.10 */
+#define CKA_AC_ISSUER 0x00000083
+#define CKA_OWNER 0x00000084
+#define CKA_ATTR_TYPES 0x00000085
+/* CKA_TRUSTED is new for v2.11 */
+#define CKA_TRUSTED 0x00000086
+
#define CKA_KEY_TYPE 0x00000100
#define CKA_SUBJECT 0x00000101
#define CKA_ID 0x00000102
@@ -395,16 +485,34 @@ typedef CK_ULONG CK_ATTRIBUTE_TYPE;
#define CKA_PRIME 0x00000130
#define CKA_SUBPRIME 0x00000131
#define CKA_BASE 0x00000132
+/* CKA_PRIME_BITS and CKA_SUB_PRIME_BITS are new for v2.11 */
+#define CKA_PRIME_BITS 0x00000133
+#define CKA_SUB_PRIME_BITS 0x00000134
#define CKA_VALUE_BITS 0x00000160
#define CKA_VALUE_LEN 0x00000161
/* CKA_EXTRACTABLE, CKA_LOCAL, CKA_NEVER_EXTRACTABLE,
- * CKA_ALWAYS_SENSITIVE, and CKA_MODIFIABLE are new for v2.0 */
+ * CKA_ALWAYS_SENSITIVE, CKA_MODIFIABLE, CKA_ECDSA_PARAMS,
+ * and CKA_EC_POINT are new for v2.0 */
#define CKA_EXTRACTABLE 0x00000162
#define CKA_LOCAL 0x00000163
#define CKA_NEVER_EXTRACTABLE 0x00000164
#define CKA_ALWAYS_SENSITIVE 0x00000165
+/* CKA_KEY_GEN_MECHANISM is new for v2.11 */
+#define CKA_KEY_GEN_MECHANISM 0x00000166
#define CKA_MODIFIABLE 0x00000170
+#define CKA_ECDSA_PARAMS 0x00000180 /* depricated v2.11 */
+#define CKA_EC_PARAMS 0x00000180
+#define CKA_EC_POINT 0x00000181
+
+/* CKA_SECONDARY_AUTH, CKA_AUTH_PIN_FLAGS,
+ * CKA_HW_FEATURE_TYPE, CKA_RESET_ON_INIT, and CKA_HAS_RESET
+ * are new for v2.10 */
+#define CKA_SECONDARY_AUTH 0x00000200 /* depricated v2.11 */
+#define CKA_AUTH_PIN_FLAGS 0x00000201 /* depricated v2.11 */
+#define CKA_HW_FEATURE_TYPE 0x00000300
+#define CKA_RESET_ON_INIT 0x00000301
+#define CKA_HAS_RESET 0x00000302
#define CKA_VENDOR_DEFINED 0x80000000
@@ -448,11 +556,32 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_MD5_RSA_PKCS 0x00000005
#define CKM_SHA1_RSA_PKCS 0x00000006
+/* CKM_RIPEMD128_RSA_PKCS, CKM_RIPEMD160_RSA_PKCS & CKM_RSA_OAEP
+ * are new for 2.10 */
+#define CKM_RIPEMD128_RSA_PKCS 0x00000007
+#define CKM_RIPEMD160_RSA_PKCS 0x00000008
+#define CKM_RSA_PKCS_OAEP 0x00000009
+
+/* CKM_RSA_X9_31, CKM_SHA1_RSA_X9_31 & CKM_RSA_X9_31_KEY_PAIR_GEN
+ * are new for 2.11 */
+#define CKM_RSA_X9_31_KEY_PAIR_GEN 0x0000000A
+#define CKM_RSA_X9_31 0x0000000B
+#define CKM_SHA1_RSA_X9_31 0x0000000C
+
#define CKM_DSA_KEY_PAIR_GEN 0x00000010
#define CKM_DSA 0x00000011
#define CKM_DSA_SHA1 0x00000012
#define CKM_DH_PKCS_KEY_PAIR_GEN 0x00000020
#define CKM_DH_PKCS_DERIVE 0x00000021
+
+/* CKM_X9_42_DH_PKCS_KEY_PAIR_GEN, CKM_X9_42_DH_DERIVE,
+ * CKM_X9_42_DH_HYBRID_DERIVE, & CKM_X9_42_MQV_DERIVE
+ * are new for v2.11 */
+#define CKM_X9_42_DH_PKCS_KEY_PAIR_GEN 0x00000030
+#define CKM_X9_42_DH_DERIVE 0x00000031
+#define CKM_X9_42_DH_HYBRID_DERIVE 0x00000032
+#define CKM_X9_42_MQV_DERIVE 0x00000033
+
#define CKM_RC2_KEY_GEN 0x00000100
#define CKM_RC2_ECB 0x00000101
#define CKM_RC2_CBC 0x00000102
@@ -509,6 +638,16 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_SHA_1_HMAC 0x00000221
#define CKM_SHA_1_HMAC_GENERAL 0x00000222
+/* CKM_RIPEMD128, CKM_RIPEMD128_HMAC,
+ * CKM_RIPEMD128_HMAC_GENERAL, CKM_RIPEMD160, CKM_RIPEMD160_HMAC,
+ * and CKM_RIPEMD160_HMAC_GENERAL are new for v2.10 */
+#define CKM_RIPEMD128 0x00000230
+#define CKM_RIPEMD128_HMAC 0x00000231
+#define CKM_RIPEMD128_HMAC_GENERAL 0x00000232
+#define CKM_RIPEMD160 0x00000240
+#define CKM_RIPEMD160_HMAC 0x00000241
+#define CKM_RIPEMD160_HMAC_GENERAL 0x00000242
+
/* All of the following mechanisms are new for v2.0 */
/* Note that CAST128 and CAST5 are the same algorithm */
#define CKM_CAST_KEY_GEN 0x00000300
@@ -556,6 +695,17 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_SSL3_PRE_MASTER_KEY_GEN 0x00000370
#define CKM_SSL3_MASTER_KEY_DERIVE 0x00000371
#define CKM_SSL3_KEY_AND_MAC_DERIVE 0x00000372
+
+/* CKM_SSL3_MASTER_KEY_DERIVE_DH, CKM_TLS_PRE_MASTER_KEY_GEN,
+ * CKM_TLS_MASTER_KEY_DERIVE, CKM_TLS_KEY_AND_MAC_DERIVE,
+ * CKM_TLS_MASTER_KEY_DERIVE_DH, & CKM_SSL3_MASTER_KEY_DERIVE_DH
+ * are new for v2.11. */
+#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x00000373
+#define CKM_TLS_PRE_MASTER_KEY_GEN 0x00000374
+#define CKM_TLS_MASTER_KEY_DERIVE 0x00000375
+#define CKM_TLS_KEY_AND_MAC_DERIVE 0x00000376
+#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x00000377
+
#define CKM_SSL3_MD5_MAC 0x00000380
#define CKM_SSL3_SHA1_MAC 0x00000381
#define CKM_MD5_KEY_DERIVATION 0x00000390
@@ -575,6 +725,10 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_PBE_SHA1_DES2_EDE_CBC 0x000003A9
#define CKM_PBE_SHA1_RC2_128_CBC 0x000003AA
#define CKM_PBE_SHA1_RC2_40_CBC 0x000003AB
+
+/* CKM_PKCS5_PBKD2 is new for v2.10 */
+#define CKM_PKCS5_PBKD2 0x000003B0
+
#define CKM_PBA_SHA1_WITH_SHA1_HMAC 0x000003C0
#define CKM_KEY_WRAP_LYNKS 0x00000400
#define CKM_KEY_WRAP_SET_OAEP 0x00000401
@@ -601,12 +755,16 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_BATON_COUNTER 0x00001034
#define CKM_BATON_SHUFFLE 0x00001035
#define CKM_BATON_WRAP 0x00001036
-
-/* PKCS #11 V2.01 probably won't actually have ECDSA in it */
-#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040
+#define CKM_ECDSA_KEY_PAIR_GEN 0x00001040 /* depricated in v2.11 */
+#define CKM_EC_KEY_PAIR_GEN 0x00001040
#define CKM_ECDSA 0x00001041
#define CKM_ECDSA_SHA1 0x00001042
+/* ECDH1 is new for 2.11 */
+#define CKM_ECDH1_DERIVE 0x00001043
+#define CKM_ECDH1_COFACTOR_DERIVE 0x00001044
+#define CKM_ECMQV_DERIVE 0x00001045
+
#define CKM_JUNIPER_KEY_GEN 0x00001060
#define CKM_JUNIPER_ECB128 0x00001061
#define CKM_JUNIPER_CBC128 0x00001062
@@ -615,6 +773,7 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_JUNIPER_WRAP 0x00001065
#define CKM_FASTHASH 0x00001070
+/* AES is new for 2.11 */
#define CKM_AES_KEY_GEN 0x00001080
#define CKM_AES_ECB 0x00001081
#define CKM_AES_CBC 0x00001082
@@ -622,6 +781,12 @@ typedef CK_ULONG CK_MECHANISM_TYPE;
#define CKM_AES_MAC_GENERAL 0x00001084
#define CKM_AES_CBC_PAD 0x00001085
+/* CKM_DSA_PARAMETER_GEN, CKM_DH_PKCS_PARAMETER_GEN,
+ * and CKM_DH_X9_42_PARAMETER_GEN are new for 2.11 */
+#define CKM_DSA_PARAMETER_GEN 0x00002000
+#define CKM_DH_PKCS_PARAMETER_GEN 0x00002001
+#define CKM_DH_X9_42_PARAMETER_GEN 0x00002002
+
#define CKM_VENDOR_DEFINED 0x80000000
typedef CK_MECHANISM_TYPE CK_PTR CK_MECHANISM_TYPE_PTR;
@@ -658,6 +823,8 @@ typedef struct CK_MECHANISM_INFO {
* CKF_GENERATE, CKF_GENERATE_KEY_PAIR, CKF_WRAP, CKF_UNWRAP,
* and CKF_DERIVE are new for v2.0. They specify whether or not
* a mechanism can be used for a particular task */
+/* The flags CKF_EC_FP, CKF_EC_F_2M, CKF_EC_ECPARAMETERS, CKF_EC_NAMEDCURVE,
+ * CKF_EC_UNCOMPRESS, and CKF_EC_COMPRESS are new for v2.11 */
#define CKF_ENCRYPT 0x00000100
#define CKF_DECRYPT 0x00000200
#define CKF_DIGEST 0x00000400
@@ -670,6 +837,12 @@ typedef struct CK_MECHANISM_INFO {
#define CKF_WRAP 0x00020000
#define CKF_UNWRAP 0x00040000
#define CKF_DERIVE 0x00080000
+#define CKF_EC_FP 0x00100000
+#define CKF_EC_F_2M 0x00200000
+#define CKF_EC_ECPARAMETERS 0x00400000
+#define CKF_EC_NAMEDCURVE 0x00800000
+#define CKF_EC_UNCOMPRESS 0x01000000
+#define CKF_EC_COMPRESS 0x02000000
#define CKF_EXTENSION 0x80000000 /* FALSE for 2.01 */
@@ -735,6 +908,9 @@ typedef CK_ULONG CK_RV;
#define CKR_KEY_NOT_WRAPPABLE 0x00000069
#define CKR_KEY_UNEXTRACTABLE 0x0000006A
+/* CKR_KEY_PARAMS_INVALID is new for v2.11 */
+#define CKR_KEY_PARAMS_INVALID 0x0000006B
+
#define CKR_MECHANISM_INVALID 0x00000070
#define CKR_MECHANISM_PARAM_INVALID 0x00000071
@@ -790,8 +966,13 @@ typedef CK_ULONG CK_RV;
#define CKR_WRAPPING_KEY_TYPE_INCONSISTENT 0x00000115
#define CKR_RANDOM_SEED_NOT_SUPPORTED 0x00000120
-/* These are new to v2.0 */
+/* New for v2.0 */
#define CKR_RANDOM_NO_RNG 0x00000121
+
+/* New for v2.11 */
+#define CKR_DOMAIN_PARAMS_INVALID 0x00000130
+
+/* These are new to v2.0 */
#define CKR_BUFFER_TOO_SMALL 0x00000150
#define CKR_SAVED_STATE_INVALID 0x00000160
#define CKR_INFORMATION_SENSITIVE 0x00000170
@@ -878,6 +1059,41 @@ typedef CK_C_INITIALIZE_ARGS CK_PTR CK_C_INITIALIZE_ARGS_PTR;
/* CKF_DONT_BLOCK is for the function C_WaitForSlotEvent */
#define CKF_DONT_BLOCK 1
+/* CK_RSA_PKCS_OAEP_MGF_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_MGF_TYPE is used to indicate the Message
+ * Generation Function (MGF) applied to a message block when
+ * formatting a message block for the PKCS #1 OAEP encryption
+ * scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_MGF_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_MGF_TYPE CK_PTR CK_RSA_PKCS_OAEP_MGF_TYPE_PTR;
+
+/* The following MGFs are defined */
+#define CKG_MGF1_SHA1 0x00000001
+
+/* CK_RSA_PKCS_OAEP_SOURCE_TYPE is new for v2.10.
+ * CK_RSA_PKCS_OAEP_SOURCE_TYPE is used to indicate the source
+ * of the encoding parameter when formatting a message block
+ * for the PKCS #1 OAEP encryption scheme. */
+typedef CK_ULONG CK_RSA_PKCS_OAEP_SOURCE_TYPE;
+
+typedef CK_RSA_PKCS_OAEP_SOURCE_TYPE CK_PTR CK_RSA_PKCS_OAEP_SOURCE_TYPE_PTR;
+
+/* The following encoding parameter sources are defined */
+#define CKZ_DATA_SPECIFIED 0x00000001
+
+/* CK_RSA_PKCS_OAEP_PARAMS is new for v2.10.
+ * CK_RSA_PKCS_OAEP_PARAMS provides the parameters to the
+ * CKM_RSA_PKCS_OAEP mechanism. */
+typedef struct CK_RSA_PKCS_OAEP_PARAMS {
+ CK_MECHANISM_TYPE hashAlg;
+ CK_RSA_PKCS_OAEP_MGF_TYPE mgf;
+ CK_RSA_PKCS_OAEP_SOURCE_TYPE source;
+ CK_VOID_PTR pSourceData;
+ CK_ULONG ulSourceDataLen;
+} CK_RSA_PKCS_OAEP_PARAMS;
+
+typedef CK_RSA_PKCS_OAEP_PARAMS CK_PTR CK_RSA_PKCS_OAEP_PARAMS_PTR;
/* CK_KEA_DERIVE_PARAMS provides the parameters to the
* CKM_KEA_DERIVE mechanism */
@@ -1102,36 +1318,46 @@ typedef CK_ULONG CK_EXTRACT_PARAMS;
typedef CK_EXTRACT_PARAMS CK_PTR CK_EXTRACT_PARAMS_PTR;
-/* Do not attempt to use these. They are only used by NETSCAPE's internal
- * PKCS #11 interface. Most of these are place holders for other mechanism
- * and will change in the future.
- */
-#define CKM_NETSCAPE_PBE_KEY_GEN 0x80000001L
-#define CKM_NETSCAPE_PBE_SHA1_DES_CBC 0x80000002L
-#define CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC 0x80000003L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC 0x80000004L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC 0x80000005L
-#define CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4 0x80000006L
-#define CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4 0x80000007L
-#define CKM_NETSCAPE_PBE_SHA1_FAULTY_3DES_CBC 0x80000008L
-#define CKM_NETSCAPE_PBE_SHA1_HMAC_KEY_GEN 0x80000009L
-#define CKM_NETSCAPE_PBE_MD5_HMAC_KEY_GEN 0x8000000aL
-#define CKM_NETSCAPE_PBE_MD2_HMAC_KEY_GEN 0x8000000bL
-#define CKM_TLS_MASTER_KEY_DERIVE 0x80000371L
-#define CKM_TLS_KEY_AND_MAC_DERIVE 0x80000372L
-#define CKM_TLS_PRF_GENERAL 0x80000373L
-#define CKM_SSL3_MASTER_KEY_DERIVE_DH 0x80000374L
-#define CKM_TLS_MASTER_KEY_DERIVE_DH 0x80000375L
-
-/* define used to pass in the database key for DSA private keys */
-#define CKA_NETSCAPE_DB 0xD5A0DB00L
-#define CKA_NETSCAPE_TRUST 0x80000001L
-
-#define SECMOD_MODULE_DB_FUNCTION_FIND 0
-#define SECMOD_MODULE_DB_FUNCTION_ADD 1
-#define SECMOD_MODULE_DB_FUNCTION_DEL 2
-typedef char ** (PR_CALLBACK *SECMODModuleDBFunc)(unsigned long function,
- char *parameters, char *moduleSpec);
+/* CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE is used to
+ * indicate the Pseudo-Random Function (PRF) used to generate
+ * key bits using PKCS #5 PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE;
+
+typedef CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE CK_PTR CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE_PTR;
+
+/* The following PRFs are defined in PKCS #5 v2.0. */
+#define CKP_PKCS5_PBKD2_HMAC_SHA1 0x00000001
+
+
+/* CK_PKCS5_PBKD2_SALT_SOURCE_TYPE is new for v2.10.
+ * CK_PKCS5_PBKD2_SALT_SOURCE_TYPE is used to indicate the
+ * source of the salt value when deriving a key using PKCS #5
+ * PBKDF2. */
+typedef CK_ULONG CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE;
+
+typedef CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE CK_PTR CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE_PTR;
+
+/* The following salt value sources are defined in PKCS #5 v2.0. */
+#define CKZ_SALT_SPECIFIED 0x00000001
+
+/* CK_PKCS5_PBKD2_PARAMS is new for v2.10.
+ * CK_PKCS5_PBKD2_PARAMS is a structure that provides the
+ * parameters to the CKM_PKCS5_PBKD2 mechanism. */
+typedef struct CK_PKCS5_PBKD2_PARAMS {
+ CK_PKCS5_PBKDF2_SALT_SOURCE_TYPE saltSource;
+ CK_VOID_PTR pSaltSourceData;
+ CK_ULONG ulSaltSourceDataLen;
+ CK_ULONG iterations;
+ CK_PKCS5_PBKD2_PSEUDO_RANDOM_FUNCTION_TYPE prf;
+ CK_VOID_PTR pPrfData;
+ CK_ULONG ulPrfDataLen;
+} CK_PKCS5_PBKD2_PARAMS;
+
+typedef CK_PKCS5_PBKD2_PARAMS CK_PTR CK_PKCS5_PBKD2_PARAMS_PTR;
+
+/* Netscape Specific defines */
+#include "pkcs11n.h"
/* undo packing */
#include "pkcs11u.h"
diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c
index 536d938a0..cbd5b371c 100644
--- a/security/nss/lib/softoken/pkcs11u.c
+++ b/security/nss/lib/softoken/pkcs11u.c
@@ -38,6 +38,7 @@
#include "pcertt.h"
#include "lowkeyi.h"
#include "pcert.h"
+#include "secasn1.h"
/* declare the internal pkcs11 slot structures:
@@ -62,27 +63,36 @@ pk11_NewAttribute(PK11Object *object,
{
PK11Attribute *attribute;
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
int index;
+
+ if (so == NULL) {
+ /* allocate new attribute in a buffer */
+ PORT_Assert(0);
+ }
/*
- * NO_ARENA attempts to keep down contention on Malloc and Arena locks
+ * PKCS11_STATIC_ATTRIBUTES attempts to keep down contention on Malloc and Arena locks
* by limiting the number of these calls on high traversed paths. this
* is done for attributes by 'allocating' them from a pool already allocated
* by the parent object.
*/
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- index = object->nextAttr++;
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Lock(so->attributeLock);)
+ index = so->nextAttr++;
+ PK11_USE_THREADS(PZ_Unlock(so->attributeLock);)
PORT_Assert(index < MAX_OBJS_ATTRS);
if (index >= MAX_OBJS_ATTRS) return NULL;
- attribute = &object->attrList[index];
+ attribute = &so->attrList[index];
attribute->attrib.type = type;
+ attribute->freeAttr = PR_FALSE;
+ attribute->freeData = PR_FALSE;
if (value) {
if (len <= ATTR_SPACE) {
attribute->attrib.pValue = attribute->space;
} else {
attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
}
if (attribute->attrib.pValue == NULL) {
return NULL;
@@ -94,23 +104,27 @@ pk11_NewAttribute(PK11Object *object,
attribute->attrib.ulValueLen = 0;
}
#else
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
+ attribute->freeAttr = PR_TRUE;
#else
attribute = (PK11Attribute*)PORT_ArenaAlloc(object->arena,sizeof(PK11Attribute));
-#endif /* REF_COUNT_ATTRIBUTE */
+ attribute->freeAttr = PR_FALSE;
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
if (attribute == NULL) return NULL;
+ attribute->freeData = PR_FALSE;
if (value) {
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
#else
attribute->attrib.pValue = PORT_ArenaAlloc(object->arena,len);
-#endif /* REF_COUNT_ATTRIBUTE */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
if (attribute->attrib.pValue == NULL) {
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
PORT_Free(attribute);
-#endif /* REF_COUNT_ATTRIBUTE */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
return NULL;
}
PORT_Memcpy(attribute->attrib.pValue,value,len);
@@ -119,11 +133,11 @@ pk11_NewAttribute(PK11Object *object,
attribute->attrib.pValue = NULL;
attribute->attrib.ulValueLen = 0;
}
-#endif /* NO_ARENA */
+#endif /* PKCS11_STATIC_ATTRIBUTES */
attribute->attrib.type = type;
attribute->handle = type;
attribute->next = attribute->prev = NULL;
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
attribute->refCount = 1;
#ifdef PKCS11_USE_THREADS
attribute->refLock = PZ_NewLock(nssILockRefLock);
@@ -135,31 +149,751 @@ pk11_NewAttribute(PK11Object *object,
#else
attribute->refLock = NULL;
#endif
-#endif /* REF_COUNT_ATTRIBUTE */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
return attribute;
}
+static PK11Attribute *
+pk11_NewTokenAttribute(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value,
+ CK_ULONG len, PRBool copy)
+{
+ PK11Attribute *attribute;
+
+ attribute = (PK11Attribute*)PORT_Alloc(sizeof(PK11Attribute));
+
+ if (attribute == NULL) return NULL;
+ attribute->attrib.type = type;
+ attribute->handle = type;
+ attribute->next = attribute->prev = NULL;
+ attribute->freeAttr = PR_TRUE;
+ attribute->freeData = PR_FALSE;
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ attribute->refCount = 1;
+#ifdef PKCS11_USE_THREADS
+ attribute->refLock = PZ_NewLock(nssILockRefLock);
+ if (attribute->refLock == NULL) {
+ PORT_Free(attribute);
+ return NULL;
+ }
+#else
+ attribute->refLock = NULL;
+#endif
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
+ attribute->attrib.type = type;
+ if (!copy) {
+ attribute->attrib.pValue = value;
+ attribute->attrib.ulValueLen = len;
+ return attribute;
+ }
+
+ if (value) {
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ if (len <= ATTR_SPACE) {
+ attribute->attrib.pValue = attribute->space;
+ } else {
+ attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
+ }
+#else
+ attribute->attrib.pValue = PORT_Alloc(len);
+ attribute->freeData = PR_TRUE;
+#endif
+ if (attribute->attrib.pValue == NULL) {
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ if (attribute->refLock) {
+ PK11_USE_THREADS(PZ_DestroyLock(attribute->refLock);)
+ }
+#endif
+ PORT_Free(attribute);
+ return NULL;
+ }
+ PORT_Memcpy(attribute->attrib.pValue,value,len);
+ attribute->attrib.ulValueLen = len;
+ } else {
+ attribute->attrib.pValue = NULL;
+ attribute->attrib.ulValueLen = 0;
+ }
+ return attribute;
+}
+
+static PK11Attribute *
+pk11_NewTokenAttributeSigned(CK_ATTRIBUTE_TYPE type, CK_VOID_PTR value,
+ CK_ULONG len, PRBool copy)
+{
+ unsigned char * dval = (unsigned char *)value;
+ if (*dval == 0) {
+ dval++;
+ len--;
+ }
+ return pk11_NewTokenAttribute(type,dval,len,copy);
+}
+
/*
* Free up all the memory associated with an attribute. Reference count
* must be zero to call this.
*/
-#ifdef REF_COUNT_ATTRIBUTE
static void
pk11_DestroyAttribute(PK11Attribute *attribute)
{
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
PORT_Assert(attribute->refCount == 0);
PK11_USE_THREADS(PZ_DestroyLock(attribute->refLock);)
+#endif
if (attribute->attrib.pValue) {
/* clear out the data in the attribute value... it may have been
* sensitive data */
PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
+ }
+ if (attribute->freeData) {
PORT_Free(attribute->attrib.pValue);
}
PORT_Free(attribute);
}
+
+/*
+ * release a reference to an attribute structure
+ */
+void
+pk11_FreeAttribute(PK11Attribute *attribute)
+{
+ PRBool destroy = PR_FALSE;
+
+ if (attribute->freeAttr) {
+ pk11_DestroyAttribute(attribute);
+ return;
+ }
+
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ PK11_USE_THREADS(PZ_Lock(attribute->refLock);)
+ if (attribute->refCount == 1) destroy = PR_TRUE;
+ attribute->refCount--;
+ PK11_USE_THREADS(PZ_Unlock(attribute->refLock);)
+
+ if (destroy) pk11_DestroyAttribute(attribute);
#endif
+}
+
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+#define PK11_DEF_ATTRIBUTE(value,len) \
+ { NULL, NULL, PR_FALSE, PR_FALSE, 1, NULL, 0, { 0, value, len } }
+
+#else
+#define PK11_DEF_ATTRIBUTE(value,len) \
+ { NULL, NULL, PR_FALSE, PR_FALSE, 0, { 0, value, len } }
+#endif
+
+CK_BBOOL pk11_staticTrueValue = CK_TRUE;
+CK_BBOOL pk11_staticFalseValue = CK_FALSE;
+static const PK11Attribute pk11_StaticTrueAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticTrueValue,sizeof(pk11_staticTrueValue));
+static const PK11Attribute pk11_StaticFalseAttr =
+ PK11_DEF_ATTRIBUTE(&pk11_staticFalseValue,sizeof(pk11_staticFalseValue));
+static const PK11Attribute pk11_StaticNullAttr = PK11_DEF_ATTRIBUTE(NULL,0);
+
+SECItem *
+pk11_getCrl(PK11TokenObject *object)
+{
+ SECItem *crl;
+
+ if (object->obj.objclass != CKO_NETSCAPE_CRL) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (SECItem *)object->obj.objectInfo;
+ }
+ crl = nsslowcert_FindCrlByKey(object->obj.slot->certDB,&object->dbKey,
+ NULL,PR_FALSE);
+ object->obj.objectInfo = (void *)crl;
+ object->obj.infoFree = (PK11Free) SECITEM_FreeItem;
+ return crl;
+}
+
+NSSLOWCERTCertificate *
+pk11_getCert(PK11TokenObject *object)
+{
+ NSSLOWCERTCertificate *cert;
+
+ if ((object->obj.objclass != CKO_CERTIFICATE) &&
+ (object->obj.objclass != CKO_NETSCAPE_TRUST)) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (NSSLOWCERTCertificate *)object->obj.objectInfo;
+ }
+ cert = nsslowcert_FindCertByKey(object->obj.slot->certDB,&object->dbKey);
+ object->obj.objectInfo = (void *)cert;
+ object->obj.infoFree = (PK11Free) nsslowcert_DestroyCertificate ;
+ return cert;
+}
+
+NSSLOWKEYPublicKey *
+pk11_GetPublicKey(PK11TokenObject *object)
+{
+ NSSLOWKEYPublicKey *pubKey;
+ NSSLOWKEYPrivateKey *privKey;
+
+ if (object->obj.objclass != CKO_PUBLIC_KEY) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (NSSLOWKEYPublicKey *)object->obj.objectInfo;
+ }
+ privKey = nsslowkey_FindKeyByPublicKey(object->obj.slot->keyDB,
+ &object->dbKey, object->obj.slot->password);
+ pubKey = nsslowkey_ConvertToPublicKey(privKey);
+ nsslowkey_DestroyPrivateKey(privKey);
+ object->obj.objectInfo = (void *) pubKey;
+ object->obj.infoFree = (PK11Free) nsslowkey_DestroyPublicKey ;
+ return pubKey;
+}
+
+NSSLOWKEYPrivateKey *
+pk11_GetPrivateKey(PK11TokenObject *object)
+{
+ NSSLOWKEYPrivateKey *privKey;
+
+ if (object->obj.objclass != CKO_PUBLIC_KEY) {
+ return NULL;
+ }
+ if (object->obj.objectInfo) {
+ return (NSSLOWKEYPrivateKey *)object->obj.objectInfo;
+ }
+ privKey = nsslowkey_FindKeyByPublicKey(object->obj.slot->keyDB,
+ &object->dbKey, object->obj.slot->password);
+ object->obj.objectInfo = (void *) privKey;
+ object->obj.infoFree = (PK11Free) nsslowkey_DestroyPrivateKey ;
+ return privKey;
+}
+
+/* pk11_GetPubItem returns data associated with the public key.
+ * one only needs to free the public key. This comment is here
+ * because this sematic would be non-obvious otherwise. All callers
+ * should include this comment.
+ */
+static SECItem *
+pk11_GetPubItem(NSSLOWKEYPublicKey *pubKey) {
+ SECItem *pubItem = NULL;
+ /* get value to compare from the cert's public key */
+ switch ( pubKey->keyType ) {
+ case NSSLOWKEYRSAKey:
+ pubItem = &pubKey->u.rsa.modulus;
+ break;
+ case NSSLOWKEYDSAKey:
+ pubItem = &pubKey->u.dsa.publicValue;
+ break;
+ case NSSLOWKEYDHKey:
+ pubItem = &pubKey->u.dh.publicValue;
+ break;
+ default:
+ break;
+ }
+ return pubItem;
+}
+
+static const SEC_ASN1Template pk11_SerialTemplate[] = {
+ { SEC_ASN1_INTEGER, offsetof(NSSLOWCERTCertificate,serialNumber) },
+ { 0 }
+};
+
+PK11Attribute *
+pk11_FindRSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_RSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ default:
+ case CKA_MODULUS:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.modulus.data,
+ key->u.rsa.modulus.len, PR_FALSE);
+ case CKA_PUBLIC_EXPONENT:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.publicExponent.data,
+ key->u.rsa.publicExponent.len, PR_FALSE);
+ break;
+ }
+ return NULL;
+}
+PK11Attribute *
+pk11_FindDSAPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ case CKA_ENCRYPT:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VERIFY:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_VALUE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len, PR_FALSE);
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.prime.data,
+ key->u.dsa.params.prime.len, PR_FALSE);
+ case CKA_SUBPRIME:
+ return pk11_NewTokenAttributeSigned(type,
+ key->u.dsa.params.subPrime.data,
+ key->u.dsa.params.subPrime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.base.data,
+ key->u.dsa.params.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+PK11Attribute *
+pk11_FindDHPublicKeyAttribute(NSSLOWKEYPublicKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DH;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_ENCRYPT:
+ case CKA_VERIFY:
+ case CKA_VERIFY_RECOVER:
+ case CKA_WRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.publicValue.data,
+ key->u.dh.publicValue.len, PR_FALSE);
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.prime.data,
+ key->u.dh.prime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.base.data,
+ key->u.dh.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindPublicKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWKEYPublicKey *key;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ default:
+ break;
+ }
+
+ key = pk11_GetPublicKey(object);
+ if (key == NULL) {
+ return NULL;
+ }
+ switch (key->keyType) {
+ case NSSLOWKEYRSAKey:
+ return pk11_FindRSAPublicKeyAttribute(key,type);
+ case NSSLOWKEYDSAKey:
+ return pk11_FindDSAPublicKeyAttribute(key,type);
+ case NSSLOWKEYDHKey:
+ return pk11_FindDHPublicKeyAttribute(key,type);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+PK11Attribute *
+pk11_FindSecretKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWKEYPrivateKey *key;
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_SENSITIVE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_EXTRACTABLE:
+ case CKA_DERIVE:
+ case CKA_ENCRYPT:
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_VERIFY:
+ case CKA_WRAP:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ default:
+ break;
+ }
+
+ key = pk11_GetPrivateKey(object);
+ if (key == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,key->u.rsa.coefficient.data,
+ key->u.rsa.coefficient.len, PR_FALSE);
+ case CKA_VALUE:
+ return pk11_NewTokenAttribute(type,key->u.rsa.privateExponent.data,
+ key->u.rsa.privateExponent.len, PR_FALSE);
+ }
+
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindRSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
+ CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_RSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.rsa.modulus.data,key->u.rsa.modulus.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_MODULUS:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.modulus.data,
+ key->u.rsa.modulus.len, PR_FALSE);
+ case CKA_PUBLIC_EXPONENT:
+ return pk11_NewTokenAttributeSigned(type,key->u.rsa.publicExponent.data,
+ key->u.rsa.publicExponent.len, PR_FALSE);
+ case CKA_PRIVATE_EXPONENT:
+ case CKA_PRIME_1:
+ case CKA_PRIME_2:
+ case CKA_EXPONENT_1:
+ case CKA_EXPONENT_2:
+ case CKA_COEFFICIENT:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ default:
+ break;
+ }
+ return NULL;
+}
+PK11Attribute *
+pk11_FindDSAPrivateKeyAttribute(NSSLOWKEYPrivateKey *key,
+ CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DSA;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dsa.publicValue.data,
+ key->u.dsa.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ case CKA_DECRYPT:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_SIGN:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_VALUE:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.prime.data,
+ key->u.dsa.params.prime.len, PR_FALSE);
+ case CKA_SUBPRIME:
+ return pk11_NewTokenAttributeSigned(type,
+ key->u.dsa.params.subPrime.data,
+ key->u.dsa.params.subPrime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dsa.params.base.data,
+ key->u.dsa.params.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindDHPrivateKeyAttribute(NSSLOWKEYPrivateKey *key, CK_ATTRIBUTE_TYPE type)
+{
+ unsigned char hash[SHA1_LENGTH];
+ CK_KEY_TYPE keyType = CKK_DH;
+
+ switch (type) {
+ case CKA_KEY_TYPE:
+ return pk11_NewTokenAttribute(type,&keyType,sizeof(keyType), PR_TRUE);
+ case CKA_ID:
+ SHA1_HashBuf(hash,key->u.dh.publicValue.data,key->u.dh.publicValue.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_DERIVE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_DECRYPT:
+ case CKA_SIGN:
+ case CKA_SIGN_RECOVER:
+ case CKA_UNWRAP:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ return (PK11Attribute *) &pk11_StaticNullAttr;
+ case CKA_PRIME:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.prime.data,
+ key->u.dh.prime.len, PR_FALSE);
+ case CKA_BASE:
+ return pk11_NewTokenAttributeSigned(type,key->u.dh.base.data,
+ key->u.dh.base.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindPrivateKeyAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWKEYPrivateKey *key;
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_SENSITIVE:
+ case CKA_ALWAYS_SENSITIVE:
+ case CKA_EXTRACTABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_NEVER_EXTRACTABLE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ default:
+ break;
+ }
+ key = pk11_GetPrivateKey(object);
+ if (key == NULL) {
+ return NULL;
+ }
+ switch (key->keyType) {
+ case NSSLOWKEYRSAKey:
+ return pk11_FindRSAPrivateKeyAttribute(key,type);
+ case NSSLOWKEYDSAKey:
+ return pk11_FindDSAPrivateKeyAttribute(key,type);
+ case NSSLOWKEYDHKey:
+ return pk11_FindDHPrivateKeyAttribute(key,type);
+ default:
+ break;
+ }
+
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindSMIMEAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWCERTCertificate *cert;
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ default:
+ break;
+ }
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindTrustAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWCERTCertificate *cert;
+ unsigned char hash[SHA1_LENGTH];
+ SECItem *item;
+ PK11Attribute *attr;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ default:
+ break;
+ }
+ cert = pk11_getCert(object);
+ if (cert == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_CERT_SHA1_HASH:
+ SHA1_HashBuf(hash,cert->derCert.data,cert->derCert.len);
+ return pk11_NewTokenAttribute(type,hash,SHA1_LENGTH, PR_TRUE);
+ case CKA_CERT_MD5_HASH:
+ MD5_HashBuf(hash,cert->derCert.data,cert->derCert.len);
+ return pk11_NewTokenAttribute(type,hash,MD5_LENGTH, PR_TRUE);
+ case CKA_ISSUER:
+ return pk11_NewTokenAttribute(type,cert->derIssuer.data,
+ cert->derIssuer.len, PR_FALSE);
+ case CKA_SERIAL_NUMBER:
+ item = SEC_ASN1EncodeItem(NULL,NULL,cert,pk11_SerialTemplate);
+ if (item == NULL) break;
+ attr = pk11_NewTokenAttribute(type, item->data, item->len, PR_TRUE);
+ SECITEM_FreeItem(item,PR_TRUE);
+ return attr;
+ case CKA_TRUST_SERVER_AUTH:
+ case CKA_TRUST_CLIENT_AUTH:
+ case CKA_TRUST_EMAIL_PROTECTION:
+ case CKA_TRUST_CODE_SIGNING:
+ /* XXXXXX */
+ default:
+ break;
+ }
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindCrlAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ SECItem *crl;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_VALUE:
+ crl = pk11_getCrl(object);
+ if (crl == NULL) break;
+ return pk11_NewTokenAttribute(type, crl->data, crl->len, PR_FALSE);
+ case CKA_SUBJECT:
+ return pk11_NewTokenAttribute(type,object->dbKey.data,
+ object->dbKey.len, PR_FALSE);
+ default:
+ break;
+ }
+ return NULL;
+}
+
+PK11Attribute *
+pk11_FindCertAttribute(PK11TokenObject *object, CK_ATTRIBUTE_TYPE type)
+{
+ NSSLOWCERTCertificate *cert;
+ NSSLOWKEYPublicKey *pubKey;
+ unsigned char hash[SHA1_LENGTH];
+ SECItem *item;
+ PK11Attribute *attr;
+
+ switch (type) {
+ case CKA_PRIVATE:
+ return (PK11Attribute *) &pk11_StaticFalseAttr;
+ case CKA_MODIFIABLE:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ default:
+ break;
+ }
+ cert = pk11_getCert(object);
+ if (cert == NULL) {
+ return NULL;
+ }
+ switch (type) {
+ case CKA_VALUE:
+ return pk11_NewTokenAttribute(type,cert->derCert.data,
+ cert->derCert.len,PR_FALSE);
+ case CKA_ID:
+ pubKey = nsslowcert_ExtractPublicKey(cert);
+ if (pubKey == NULL) break;
+ item = pk11_GetPubItem(pubKey);
+ if (item == NULL) {
+ nsslowkey_DestroyPublicKey(pubKey);
+ break;
+ }
+ SHA1_Hash(hash,item->data,item->len);
+ /* item is imbedded in pubKey, just free the key */
+ nsslowkey_DestroyPublicKey(pubKey);
+ return pk11_NewTokenAttribute(type, hash, SHA1_LENGTH, PR_TRUE);
+ case CKA_LABEL:
+ return cert->nickname ? pk11_NewTokenAttribute(type, cert->nickname,
+ PORT_Strlen(cert->nickname)+1, PR_FALSE) :
+ (PK11Attribute *) &pk11_StaticNullAttr;
+ case CKA_SUBJECT:
+ return pk11_NewTokenAttribute(type,cert->derSubject.data,
+ cert->derSubject.len, PR_FALSE);
+ case CKA_ISSUER:
+ return pk11_NewTokenAttribute(type,cert->derIssuer.data,
+ cert->derIssuer.len, PR_FALSE);
+ case CKA_SERIAL_NUMBER:
+ item = SEC_ASN1EncodeItem(NULL,NULL,cert,pk11_SerialTemplate);
+ if (item == NULL) break;
+ attr = pk11_NewTokenAttribute(type, item->data, item->len, PR_TRUE);
+ SECITEM_FreeItem(item,PR_TRUE);
+ return attr;
+ default:
+ break;
+ }
+ return NULL;
+}
-
+PK11Attribute *
+pk11_FindTokenAttribute(PK11TokenObject *object,CK_ATTRIBUTE_TYPE type)
+{
+ /* handle the common ones */
+ switch (type) {
+ case CKA_CLASS:
+ return pk11_NewTokenAttribute(type,&object->obj.objclass,
+ sizeof(object->obj.objclass),PR_FALSE);
+ case CKA_TOKEN:
+ return (PK11Attribute *) &pk11_StaticTrueAttr;
+ case CKA_LABEL:
+ return (object->obj.objclass != CKO_CERTIFICATE) ?
+ (PK11Attribute *) &pk11_StaticNullAttr :
+ pk11_FindCertAttribute(object,type);
+ default:
+ break;
+ }
+ switch (object->obj.objclass) {
+ case CKO_CERTIFICATE:
+ return pk11_FindCertAttribute(object,type);
+ case CKO_NETSCAPE_CRL:
+ return pk11_FindCrlAttribute(object,type);
+ case CKO_NETSCAPE_TRUST:
+ return pk11_FindTrustAttribute(object,type);
+ case CKO_NETSCAPE_SMIME:
+ return pk11_FindSMIMEAttribute(object,type);
+ case CKO_PUBLIC_KEY:
+ return pk11_FindPublicKeyAttribute(object,type);
+ case CKO_PRIVATE_KEY:
+ return pk11_FindPrivateKeyAttribute(object,type);
+ case CKO_SECRET_KEY:
+ return pk11_FindSecretKeyAttribute(object,type);
+ default:
+ break;
+ }
+ PORT_Assert(0);
+ return NULL;
+}
+
/*
* look up and attribute structure from a type and Object structure.
* The returned attribute is referenced and needs to be freed when
@@ -169,10 +903,15 @@ PK11Attribute *
pk11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
{
PK11Attribute *attribute;
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- pk11queue_find(attribute,type,object->head,ATTRIBUTE_HASH_SIZE);
-#ifdef REF_COUNT_ATTRIBUTE
+ if (sessObject == NULL) {
+ return pk11_FindTokenAttribute(pk11_narrowToTokenObject(object),type);
+ }
+
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
+ pk11queue_find(attribute,type,sessObject->head,ATTRIBUTE_HASH_SIZE);
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
if (attribute) {
/* atomic increment would be nice here */
PK11_USE_THREADS(PZ_Lock(attribute->refLock);)
@@ -180,31 +919,18 @@ pk11_FindAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
PK11_USE_THREADS(PZ_Unlock(attribute->refLock);)
}
#endif
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
return(attribute);
}
-/*
- * release a reference to an attribute structure
- */
-void
-pk11_FreeAttribute(PK11Attribute *attribute)
-{
-#ifdef REF_COUNT_ATTRIBUTE
- PRBool destroy = PR_FALSE;
-
- PK11_USE_THREADS(PZ_Lock(attribute->refLock);)
- if (attribute->refCount == 1) destroy = PR_TRUE;
- attribute->refCount--;
- PK11_USE_THREADS(PZ_Unlock(attribute->refLock);)
- if (destroy) pk11_DestroyAttribute(attribute);
-#endif
+PRBool
+pk11_hasAttributeToken(PK11TokenObject *object)
+{
+ return PR_FALSE;
}
-
-
/*
* return true if object has attribute
*/
@@ -212,10 +938,15 @@ PRBool
pk11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
{
PK11Attribute *attribute;
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ if (sessObject == NULL) {
+ return pk11_hasAttributeToken(pk11_narrowToTokenObject(object));
+ }
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- pk11queue_find(attribute,type,object->head,ATTRIBUTE_HASH_SIZE);
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
+ pk11queue_find(attribute,type,sessObject->head,ATTRIBUTE_HASH_SIZE);
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
return (PRBool)(attribute != NULL);
}
@@ -223,12 +954,16 @@ pk11_hasAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
/*
* add an attribute to an object
*/
-static
-void pk11_AddAttribute(PK11Object *object,PK11Attribute *attribute)
+static void
+pk11_AddAttribute(PK11Object *object,PK11Attribute *attribute)
{
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
- pk11queue_add(attribute,attribute->handle,object->head,ATTRIBUTE_HASH_SIZE);
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ if (sessObject == NULL) return;
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
+ pk11queue_add(attribute,attribute->handle,
+ sessObject->head,ATTRIBUTE_HASH_SIZE);
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
}
/*
@@ -277,13 +1012,18 @@ pk11_Attribute2SSecItem(PLArenaPool *arena,SECItem *item,PK11Object *object,
static void
pk11_DeleteAttribute(PK11Object *object, PK11Attribute *attribute)
{
- PK11_USE_THREADS(PZ_Lock(object->attributeLock);)
+ PK11SessionObject *sessObject = pk11_narrowToSessionObject(object);
+
+ if (sessObject == NULL) {
+ return ;
+ }
+ PK11_USE_THREADS(PZ_Lock(sessObject->attributeLock);)
if (pk11queue_is_queued(attribute,attribute->handle,
- object->head,ATTRIBUTE_HASH_SIZE)) {
+ sessObject->head,ATTRIBUTE_HASH_SIZE)) {
pk11queue_delete(attribute,attribute->handle,
- object->head,ATTRIBUTE_HASH_SIZE);
+ sessObject->head,ATTRIBUTE_HASH_SIZE);
}
- PK11_USE_THREADS(PZ_Unlock(object->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(sessObject->attributeLock);)
pk11_FreeAttribute(attribute);
}
@@ -320,14 +1060,10 @@ pk11_nullAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type)
if (attribute->attrib.pValue != NULL) {
PORT_Memset(attribute->attrib.pValue,0,attribute->attrib.ulValueLen);
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute->attrib.pValue);
-#endif /* REF_COUNT_ATTRIBUTE */
-#ifdef NO_ARENA
- if (attribute->attrib.pValue != attribute->space) {
+ if (attribute->freeData) {
PORT_Free(attribute->attrib.pValue);
}
-#endif /* NO_ARENA */
+ attribute->freeData = PR_FALSE;
attribute->attrib.pValue = NULL;
attribute->attrib.ulValueLen = 0;
}
@@ -343,25 +1079,28 @@ pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
{
PK11Attribute *attribute;
void *att_val = NULL;
+ PRBool freeData = PR_FALSE;
attribute=pk11_FindAttribute(object,type);
if (attribute == NULL) return pk11_AddAttributeType(object,type,value,len);
if (value) {
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
if (len <= ATTR_SPACE) {
att_val = attribute->space;
} else {
att_val = PORT_Alloc(len);
+ freeData = PR_TRUE;
}
#else
-#ifdef REF_COUNT_ATTRIBUTE
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
att_val = PORT_Alloc(len);
+ freeData = PR_TRUE;
#else
att_val = PORT_ArenaAlloc(object->arena,len);
-#endif /* REF_COUNT_ATTRIBUTE */
-#endif /* NO_ARENA */
+#endif /* PKCS11_REF_COUNT_ATTRIBUTES */
+#endif /* PKCS11_STATIC_ATTRIBUTES */
if (att_val == NULL) {
return CKR_HOST_MEMORY;
}
@@ -376,20 +1115,17 @@ pk11_forceAttribute(PK11Object *object,CK_ATTRIBUTE_TYPE type, void *value,
PORT_Memset(attribute->attrib.pValue,0,
attribute->attrib.ulValueLen);
}
-#ifdef REF_COUNT_ATTRIBUTE
- PORT_Free(attribute->attrib.pValue);
-#endif /* REF_COUNT_ATTRIBUTE */
-#ifdef NO_ARENA
- if (attribute->attrib.pValue != attribute->space) {
+ if (attribute->freeData) {
PORT_Free(attribute->attrib.pValue);
}
-#endif /* NO_ARENA */
+ attribute->freeData = PR_FALSE;
attribute->attrib.pValue = NULL;
attribute->attrib.ulValueLen = 0;
}
if (att_val) {
attribute->attrib.pValue = att_val;
attribute->attrib.ulValueLen = len;
+ attribute->freeData = freeData;
}
return CKR_OK;
}
@@ -591,6 +1327,62 @@ pk11_AddAttributeType(PK11Object *object,CK_ATTRIBUTE_TYPE type,void *valPtr,
* ******************** Object Utilities *******************************
*/
+static SECStatus
+pk11_deleteTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle)
+{
+ SECItem *item;
+ PRBool rem;
+
+ item = (SECItem *)PL_HashTableLookupConst(slot->tokenHashTable,
+ (void *)handle);
+ if (item) {
+ SECITEM_FreeItem(item,PR_TRUE);
+ }
+ rem = PL_HashTableRemove(slot->tokenHashTable,(void *)handle) ;
+ return rem ? SECSuccess : SECFailure;
+}
+
+static SECStatus
+pk11_addTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle, SECItem *key)
+{
+ PLHashEntry *entry;
+ SECItem *item;
+
+ item = SECITEM_DupItem(key);
+ if (item == NULL) {
+ return SECFailure;
+ }
+ entry = PL_HashTableAdd(slot->tokenHashTable,(void *)handle,item);
+ if (entry == NULL) {
+ SECITEM_FreeItem(item,PR_TRUE);
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+static SECItem *
+pk11_lookupTokenKeyByHandle(PK11Slot *slot, CK_OBJECT_HANDLE handle)
+{
+ return (SECItem *)PL_HashTableLookupConst(slot->tokenHashTable,
+ (void *)handle);
+}
+
+/*
+ * use the refLock. This operations should be very rare, so the added
+ * contention on the ref lock should be lower than the overhead of adding
+ * a new lock. We use separate functions for this just in case I'm wrong.
+ */
+static void
+pk11_tokenKeyLock(PK11Slot *slot) {
+ PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
+}
+
+static void
+pk11_tokenKeyUnlock(PK11Slot *slot) {
+ PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+}
+
+
/* allocation hooks that allow us to recycle old object structures */
#ifdef MAX_OBJECT_LIST_SIZE
static PK11Object * objectFreeList = NULL;
@@ -620,26 +1412,26 @@ pk11_GetObjectFromList(PRBool *hasLocks) {
}
#endif
- object = (PK11Object*)PORT_ZAlloc(sizeof(PK11Object));
+ object = (PK11Object*)PORT_ZAlloc(sizeof(PK11SessionObject));
*hasLocks = PR_FALSE;
return object;
}
static void
-pk11_PutObjectToList(PK11Object *object) {
+pk11_PutObjectToList(PK11SessionObject *object) {
#ifdef MAX_OBJECT_LIST_SIZE
if (object_count < MAX_OBJECT_LIST_SIZE) {
PK11_USE_THREADS(PZ_Lock(objectLock));
- object->next = objectFreeList;
- objectFreeList = object;
+ object->obj.next = objectFreeList;
+ objectFreeList = &object->obj;
object_count++;
PK11_USE_THREADS(PZ_Unlock(objectLock));
return;
}
#endif
PK11_USE_THREADS(PZ_DestroyLock(object->attributeLock);)
- PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
- object->attributeLock = object->refLock = NULL;
+ PK11_USE_THREADS(PZ_DestroyLock(object->obj.refLock);)
+ object->attributeLock = object->obj.refLock = NULL;
PORT_Free(object);
}
@@ -651,58 +1443,63 @@ PK11Object *
pk11_NewObject(PK11Slot *slot)
{
PK11Object *object;
+ PK11SessionObject *sessObject;
PRBool hasLocks = PR_FALSE;
int i;
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
object = pk11_GetObjectFromList(&hasLocks);
if (object == NULL) {
return NULL;
}
- object->nextAttr = 0;
+ sessObject = (PK11SessionObject *)object;
+ sessObject->nextAttr = 0;
+
+ for (i=0; i < MAX_OBJS_ATTRS; i++) {
+ sessObject->attrList[i].attrib.pValue = NULL;
+ sessObject->attrList[i].freeData = PR_FALSE;
+ }
#else
+ PRArenaPool *arena;
+
arena = PORT_NewArena(2048);
if (arena == NULL) return NULL;
- object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11Object));
+ object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11SessionObject));
if (object == NULL) {
PORT_FreeArena(arena,PR_FALSE);
return NULL;
}
object->arena = arena;
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- object->attrList[i].attrib.pValue = NULL;
- }
+ sessObject = (PK11SessionObject *)object;
#endif
object->handle = 0;
object->next = object->prev = NULL;
- object->sessionList.next = NULL;
- object->sessionList.prev = NULL;
- object->sessionList.parent = object;
- object->inDB = PR_FALSE;
- object->label = NULL;
- object->refCount = 1;
- object->session = NULL;
object->slot = slot;
object->objclass = 0xffff;
- object->wasDerived = PR_FALSE;
+ object->refCount = 1;
+ sessObject->sessionList.next = NULL;
+ sessObject->sessionList.prev = NULL;
+ sessObject->sessionList.parent = object;
+ sessObject->session = NULL;
+ sessObject->wasDerived = PR_FALSE;
#ifdef PKCS11_USE_THREADS
if (!hasLocks) object->refLock = PZ_NewLock(nssILockRefLock);
if (object->refLock == NULL) {
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
PORT_Free(object);
#else
PORT_FreeArena(arena,PR_FALSE);
#endif
return NULL;
}
- if (!hasLocks) object->attributeLock = PZ_NewLock(nssILockAttribute);
- if (object->attributeLock == NULL) {
+ if (!hasLocks) sessObject->attributeLock = PZ_NewLock(nssILockAttribute);
+ if (sessObject->attributeLock == NULL) {
PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
-#ifdef NO_ARENA
+#ifdef PKCS11_STATIC_ATTRIBUTES
PORT_Free(object);
#else
PORT_FreeArena(arena,PR_FALSE);
@@ -710,17 +1507,55 @@ pk11_NewObject(PK11Slot *slot)
return NULL;
}
#else
- object->attributeLock = NULL;
+ sessObject->attributeLock = NULL;
object->refLock = NULL;
#endif
for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- object->head[i] = NULL;
+ sessObject->head[i] = NULL;
}
object->objectInfo = NULL;
object->infoFree = NULL;
return object;
}
+static CK_RV
+pk11_DestroySessionObjectData(PK11SessionObject *so)
+{
+ int i;
+
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ for (i=0; i < MAX_OBJS_ATTRS; i++) {
+ unsigned char *value = so->attrList[i].attrib.pValue;
+ if (value) {
+ PORT_Memset(value,0,so->attrList[i].attrib.ulValueLen);
+ if (so->attrList[i].freeData) {
+ PORT_Free(value);
+ }
+ so->attrList[i].attrib.pValue = NULL;
+ so->attrList[i].freeData = PR_FALSE;
+ }
+ }
+#endif
+
+#ifdef PKCS11_REF_COUNT_ATTRIBUTES
+ /* clean out the attributes */
+ /* since no one is referencing us, it's safe to walk the chain
+ * without a lock */
+ for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
+ PK11Attribute *ap,*next;
+ for (ap = so->head[i]; ap != NULL; ap = next) {
+ next = ap->next;
+ /* paranoia */
+ ap->next = ap->prev = NULL;
+ pk11_FreeAttribute(ap);
+ }
+ so->head[i] = NULL;
+ }
+#endif
+ PK11_USE_THREADS(PZ_DestroyLock(so->attributeLock));
+ return CKR_OK;
+}
+
/*
* free all the data associated with an object. Object reference count must
* be 'zero'.
@@ -728,88 +1563,38 @@ pk11_NewObject(PK11Slot *slot)
static CK_RV
pk11_DestroyObject(PK11Object *object)
{
-#if defined(REF_COUNT_ATTRIBUTE) || defined(NO_ARENA)
+#if defined(PKCS11_REF_COUNT_ATTRIBUTES) || defined(PKCS11_STATIC_ATTRIBUTES)
int i;
#endif
SECItem pubKey;
CK_RV crv = CKR_OK;
SECStatus rv;
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
PORT_Assert(object->refCount == 0);
/* delete the database value */
- if (object->inDB) {
- if (pk11_isToken(object->handle)) {
- /* remove the objects from the real data base */
- switch (object->handle & PK11_TOKEN_TYPE_MASK) {
- case PK11_TOKEN_TYPE_PRIV:
- /* KEYID is the public KEY for DSA and DH, and the MODULUS for
- * RSA */
- crv=pk11_Attribute2SecItem(NULL,&pubKey,object,CKA_NETSCAPE_DB);
- if (crv != CKR_OK) break;
- rv = nsslowkey_DeleteKey(nsslowkey_GetDefaultKeyDB(), &pubKey);
- if (rv != SECSuccess && pubKey.data[0] == 0) {
- /* Because of legacy code issues, sometimes the public key
- * has a '0' prepended to it, forcing it to be unsigned.
- * The database may not store that '0', so remove it and
- * try again.
- */
- SECItem tmpPubKey;
- tmpPubKey.data = pubKey.data + 1;
- tmpPubKey.len = pubKey.len - 1;
- rv = nsslowkey_DeleteKey(nsslowkey_GetDefaultKeyDB(), &tmpPubKey);
- }
- if (rv != SECSuccess) crv= CKR_DEVICE_ERROR;
- break;
- case PK11_TOKEN_TYPE_CERT:
-
- /* USE THE DER CERT To LOOK THINGS UP XXXX */
- rv = nsslowcert_DeletePermCertificate((NSSLOWCERTCertificate *)object->objectInfo);
- if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
- break;
- }
+ if (to) {
+ if (to->dbKey.data) {
+ PORT_Free(to->dbKey.data);
+ to->dbKey.data = NULL;
}
}
- if (object->label) PORT_Free(object->label);
-
- object->inDB = PR_FALSE;
- object->label = NULL;
-
-#ifdef NO_ARENA
- for (i=0; i < MAX_OBJS_ATTRS; i++) {
- unsigned char *value = object->attrList[i].attrib.pValue;
- if (value) {
- PORT_Memset(value,0,object->attrList[i].attrib.ulValueLen);
- if (value != object->attrList[i].space) {
- PORT_Free(value);
- }
- object->attrList[i].attrib.pValue = NULL;
- }
- }
-#endif
-
-#ifdef REF_COUNT_ATTRIBUTE
- /* clean out the attributes */
- /* since no one is referencing us, it's safe to walk the chain
- * without a lock */
- for (i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- PK11Attribute *ap,*next;
- for (ap = object->head[i]; ap != NULL; ap = next) {
- next = ap->next;
- /* paranoia */
- ap->next = ap->prev = NULL;
- pk11_FreeAttribute(ap);
- }
- object->head[i] = NULL;
+ if (so) {
+ pk11_DestroySessionObjectData(so);
}
-#endif
if (object->objectInfo) {
(*object->infoFree)(object->objectInfo);
}
-#ifdef NO_ARENA
- pk11_PutObjectToList(object);
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ if (so) {
+ pk11_PutObjectToList(so);
+ } else {
+ PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
+ PORT_Free(to);;
+ }
#else
- PK11_USE_THREADS(PZ_DestroyLock(object->attributeLock);)
PK11_USE_THREADS(PZ_DestroyLock(object->refLock);)
arena = object->arena;
PORT_FreeArena(arena,PR_FALSE);
@@ -832,6 +1617,10 @@ pk11_ObjectFromHandleOnSlot(CK_OBJECT_HANDLE handle, PK11Slot *slot)
PZLock *lock;
PK11Object *object;
+ if (pk11_isToken(handle)) {
+ return pk11_NewTokenObject(slot, NULL, handle);
+ }
+
head = slot->tokObjects;
lock = slot->objectLock;
@@ -890,7 +1679,8 @@ void
pk11_AddSlotObject(PK11Slot *slot, PK11Object *object)
{
PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- pk11queue_add(object,object->handle,slot->tokObjects,TOKEN_OBJECT_HASH_SIZE);
+ pk11queue_add(object,object->handle,slot->tokObjects,
+ TOKEN_OBJECT_HASH_SIZE);
PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
}
@@ -898,11 +1688,12 @@ void
pk11_AddObject(PK11Session *session, PK11Object *object)
{
PK11Slot *slot = pk11_SlotFromSession(session);
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
- if (!pk11_isToken(object->handle)) {
+ if (so) {
PK11_USE_THREADS(PZ_Lock(session->objectLock);)
- pk11queue_add(&object->sessionList,0,session->objects,0);
- object->session = session;
+ pk11queue_add(&so->sessionList,0,session->objects,0);
+ so->session = session;
PK11_USE_THREADS(PZ_Unlock(session->objectLock);)
}
pk11_AddSlotObject(slot,object);
@@ -911,21 +1702,83 @@ pk11_AddObject(PK11Session *session, PK11Object *object)
/*
* add an object to a slot andsession queue
*/
-void
+CK_RV
pk11_DeleteObject(PK11Session *session, PK11Object *object)
{
PK11Slot *slot = pk11_SlotFromSession(session);
+ PK11SessionObject *so = pk11_narrowToSessionObject(object);
+ PK11TokenObject *to = pk11_narrowToTokenObject(object);
+ CK_RV crv = CKR_OK;
+ SECStatus rv;
+ NSSLOWCERTCertificate *cert;
+ NSSLOWCERTCertTrust tmptrust;
- if (object->session) {
- PK11Session *session = object->session;
+ /* Handle Token case */
+ if (so && so->session) {
+ PK11Session *session = so->session;
PK11_USE_THREADS(PZ_Lock(session->objectLock);)
- pk11queue_delete(&object->sessionList,0,session->objects,0);
+ pk11queue_delete(&so->sessionList,0,session->objects,0);
PK11_USE_THREADS(PZ_Unlock(session->objectLock);)
- }
- PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
- pk11queue_delete(object,object->handle,slot->tokObjects,
+ PK11_USE_THREADS(PZ_Lock(slot->objectLock);)
+ pk11queue_delete(object,object->handle,slot->tokObjects,
TOKEN_OBJECT_HASH_SIZE);
- PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+ PK11_USE_THREADS(PZ_Unlock(slot->objectLock);)
+ } else {
+ PORT_Assert(to);
+ /* remove the objects from the real data base */
+ switch (object->handle & PK11_TOKEN_TYPE_MASK) {
+ case PK11_TOKEN_TYPE_PRIV:
+ case PK11_TOKEN_TYPE_KEY:
+ /* KEYID is the public KEY for DSA and DH, and the MODULUS for
+ * RSA */
+ PORT_Assert(slot->keyDB);
+ rv = nsslowkey_DeleteKey(slot->keyDB, &to->dbKey);
+ if (rv != SECSuccess) crv= CKR_DEVICE_ERROR;
+ break;
+ case PK11_TOKEN_TYPE_PUB:
+ break; /* public keys only exist at the behest of the priv key */
+ case PK11_TOKEN_TYPE_CERT:
+ cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
+ if (cert == NULL) {
+ crv = CKR_DEVICE_ERROR;
+ break;
+ }
+ rv = nsslowcert_DeletePermCertificate(cert);
+ if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
+ 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;
+ }
+ break;
+ case PK11_TOKEN_TYPE_TRUST:
+ cert = nsslowcert_FindCertByKey(slot->certDB,&to->dbKey);
+ if (cert == NULL) {
+ crv = CKR_DEVICE_ERROR;
+ break;
+ }
+ tmptrust = *cert->trust;
+ tmptrust.sslFlags &= CERTDB_PRESERVE_TRUST_BITS;
+ tmptrust.emailFlags &= CERTDB_PRESERVE_TRUST_BITS;
+ tmptrust.objectSigningFlags &= CERTDB_PRESERVE_TRUST_BITS;
+ tmptrust.sslFlags |= CERTDB_TRUSTED_UNKNOWN;
+ tmptrust.emailFlags |= CERTDB_TRUSTED_UNKNOWN;
+ tmptrust.objectSigningFlags |= CERTDB_TRUSTED_UNKNOWN;
+ rv = nsslowcert_ChangeCertTrust(slot->certDB,cert,&tmptrust);
+ if (rv != SECSuccess) crv = CKR_DEVICE_ERROR;
+ nsslowcert_DestroyCertificate(cert);
+ break;
+ default:
+ break;
+ }
+ pk11_tokenKeyLock(object->slot);
+ pk11_deleteTokenKeyByHandle(object->slot,object->handle);
+ pk11_tokenKeyUnlock(object->slot);
+ }
pk11_FreeObject(object);
}
@@ -938,11 +1791,16 @@ CK_RV
pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
{
PK11Attribute *attribute;
+ PK11SessionObject *src_so = pk11_narrowToSessionObject(srcObject);
int i;
- PK11_USE_THREADS(PZ_Lock(srcObject->attributeLock);)
+ if (src_so == NULL) {
+ return CKR_DEVICE_ERROR; /* can't copy token objects yet */
+ }
+
+ PK11_USE_THREADS(PZ_Lock(src_so->attributeLock);)
for(i=0; i < ATTRIBUTE_HASH_SIZE; i++) {
- attribute = srcObject->head[i];
+ attribute = src_so->head[i];
do {
if (attribute) {
if (!pk11_hasAttribute(destObject,attribute->handle)) {
@@ -951,7 +1809,7 @@ pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
PK11Attribute *newAttribute = pk11_NewAttribute(
destObject,pk11_attr_expand(&attribute->attrib));
if (newAttribute == NULL) {
- PK11_USE_THREADS(PZ_Unlock(srcObject->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(src_so->attributeLock);)
return CKR_HOST_MEMORY;
}
pk11_AddAttribute(destObject,newAttribute);
@@ -960,7 +1818,7 @@ pk11_CopyObject(PK11Object *destObject,PK11Object *srcObject)
}
} while (attribute != NULL);
}
- PK11_USE_THREADS(PZ_Unlock(srcObject->attributeLock);)
+ PK11_USE_THREADS(PZ_Unlock(src_so->attributeLock);)
return CKR_OK;
}
@@ -1014,7 +1872,7 @@ pk11_objectMatch(PK11Object *object,CK_ATTRIBUTE_PTR theTemplate,int count)
* in the object list.
*/
CK_RV
-pk11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
+pk11_searchObjectList(PK11SearchResults *search,PK11Object **head,
PZLock *lock, CK_ATTRIBUTE_PTR theTemplate, int count, PRBool isLoggedIn)
{
int i;
@@ -1029,10 +1887,7 @@ pk11_searchObjectList(PK11ObjectListElement **objectList,PK11Object **head,
if (pk11_objectMatch(object,theTemplate,count)) {
/* don't return objects that aren't yet visible */
if ((!isLoggedIn) && pk11_isTrue(object,CKA_PRIVATE)) continue;
- crv = AddToList(objectList,object);
- if (crv != CKR_OK) {
- break;
- }
+ pk11_addHandle(search,object->handle);
}
}
PK11_USE_THREADS(PZ_Unlock(lock);)
@@ -1280,3 +2135,177 @@ pk11_FreeSession(PK11Session *session)
if (destroy) pk11_DestroySession(session);
}
+/*
+ * handle Token Object stuff
+ */
+
+/* Make a token handle for an object and record it so we can find it again */
+CK_OBJECT_HANDLE
+pk11_mkHandle(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class)
+{
+ unsigned char hashBuf[SHA1_LENGTH];
+ CK_OBJECT_HANDLE handle;
+ SECItem *key;
+
+ SHA1_HashBuf(hashBuf,dbKey->data,dbKey->len);
+ handle = PK11_TOKEN_MASK | class | (hashBuf[0] << 24) | hashBuf[1] << 16
+ | hashBuf[2] << 8 ;
+
+ pk11_tokenKeyLock(slot);
+ while (key = pk11_lookupTokenKeyByHandle(slot,handle)) {
+ if (SECITEM_ItemsAreEqual(key,dbKey)) {
+ pk11_tokenKeyUnlock(slot);
+ return handle;
+ }
+ handle++;
+ }
+ pk11_addTokenKeyByHandle(slot,handle,dbKey);
+ pk11_tokenKeyUnlock(slot);
+}
+
+void
+pk11_addHandle(PK11SearchResults *search, CK_OBJECT_HANDLE handle)
+{
+ if (search->handles == NULL) {
+ return;
+ }
+ if (search->size >= search->array_size) {
+ search->array_size += NSC_SEARCH_BLOCK_SIZE;
+ search->handles = (CK_OBJECT_HANDLE *) PORT_Realloc(search->handles,
+ sizeof(CK_OBJECT_HANDLE)* search->array_size);
+ if (search->handles == NULL) {
+ return;
+ }
+ }
+ search->handles[search->size] = handle;
+ search->size++;
+}
+
+static const CK_OBJECT_HANDLE pk11_classArray[] = {
+ 0, CKO_PRIVATE_KEY, CKO_PUBLIC_KEY, CKO_SECRET_KEY,
+ CKO_NETSCAPE_TRUST, CKO_NETSCAPE_CRL, CKO_NETSCAPE_SMIME,
+ CKO_CERTIFICATE };
+
+#define handleToClass(handle) \
+ pk11_classArray[((handle & PK11_TOKEN_TYPE_MASK))>>24]
+
+PK11Object *
+pk11_NewTokenObject(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE handle)
+{
+ PK11Object *object = NULL;
+ PK11TokenObject *tokObject = NULL;
+ SECStatus rv;
+
+#ifdef PKCS11_STATIC_ATTRIBUTES
+ object = (PK11Object *) PORT_ZAlloc(sizeof(PK11TokenObject));
+ if (object == NULL) {
+ return NULL;
+ }
+#else
+ PRArenaPool *arena;
+
+ arena = PORT_NewArena(2048);
+ if (arena == NULL) return NULL;
+
+ object = (PK11Object*)PORT_ArenaAlloc(arena,sizeof(PK11TokenObject));
+ if (object == NULL) {
+ PORT_FreeArena(arena,PR_FALSE);
+ return NULL;
+ }
+ object->arena = arena;
+#endif
+ tokObject = (PK11TokenObject *) object;
+
+ object->objclass = handleToClass(handle);
+ object->handle = handle;
+ object->refCount = 1;
+ object->slot = slot;
+ object->objectInfo = NULL;
+ object->infoFree = NULL;
+ if (dbKey == NULL) {
+ pk11_tokenKeyLock(slot);
+ dbKey = pk11_lookupTokenKeyByHandle(slot,handle);
+ if (dbKey == NULL) {
+ pk11_tokenKeyUnlock(slot);
+ goto loser;
+ }
+ rv = SECITEM_CopyItem(NULL,&tokObject->dbKey,dbKey);
+ pk11_tokenKeyUnlock(slot);
+ } else {
+ rv = SECITEM_CopyItem(NULL,&tokObject->dbKey,dbKey);
+ }
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+#ifdef PKCS11_USE_THREADS
+ object->refLock = PZ_NewLock(nssILockRefLock);
+ if (object->refLock == NULL) {
+ goto loser;
+ }
+#endif
+
+ return object;
+loser:
+ if (object) {
+ pk11_FreeObject(object);
+ }
+ return NULL;
+
+}
+
+PRBool
+pk11_tokenMatch(PK11Slot *slot, SECItem *dbKey, CK_OBJECT_HANDLE class,
+ CK_ATTRIBUTE_PTR theTemplate,int count)
+{
+ PK11Object *object;
+ PRBool ret;
+
+ object = pk11_NewTokenObject(slot,dbKey,PK11_TOKEN_MASK|class);
+ if (object == NULL) {
+ return PR_FALSE;
+ }
+
+ ret = pk11_objectMatch(object,theTemplate,count);
+ pk11_FreeObject(object);
+ return ret;
+}
+
+PK11TokenObject *
+pk11_convertSessionToToken(PK11SessionObject *so)
+{
+ SECItem *key;
+ PK11TokenObject *to = pk11_narrowToTokenObject(&so->obj);
+ SECStatus rv;
+
+ pk11_DestroySessionObjectData(so);
+ if (to == NULL) {
+ return NULL;
+ }
+ pk11_tokenKeyLock(so->obj.slot);
+ key = pk11_lookupTokenKeyByHandle(so->obj.slot,so->obj.handle);
+ if (key == NULL) {
+ pk11_tokenKeyUnlock(so->obj.slot);
+ return NULL;
+ }
+ rv = SECITEM_CopyItem(NULL,&to->dbKey,key);
+ pk11_tokenKeyUnlock(so->obj.slot);
+ if (rv == SECFailure) {
+ return NULL;
+ }
+
+ return to;
+
+}
+
+PK11SessionObject *
+pk11_narrowToSessionObject(PK11Object *obj)
+{
+ return !pk11_isToken(obj->handle) ? (PK11SessionObject *)obj : NULL;
+}
+
+PK11TokenObject *
+pk11_narrowToTokenObject(PK11Object *obj)
+{
+ return pk11_isToken(obj->handle) ? (PK11TokenObject *)obj : NULL;
+}
+
diff --git a/security/nss/lib/softoken/secpkcs5.c b/security/nss/lib/softoken/secpkcs5.c
index 1cfa37206..126184ef3 100644
--- a/security/nss/lib/softoken/secpkcs5.c
+++ b/security/nss/lib/softoken/secpkcs5.c
@@ -39,7 +39,7 @@
#include "hasht.h"
#include "pkcs11t.h"
#include "blapi.h"
-#include "sechash.h"
+#include "hasht.h"
#include "secasn1.h"
#include "secder.h"
#include "secpkcs5.h"
@@ -48,385 +48,52 @@
#include "softoken.h"
#include "secerr.h"
-#define DES_IV_LENGTH 8
-#define RC2_IV_LENGTH 8
-#define MD2_LENGTH 16
-#define MD5_LENGTH 16
-#define SHA1_LENGTH 20
-#define SEED_LENGTH 16
-#define SALT_LENGTH 8
-#define PBE_SALT_LENGTH 16
-
/* template for PKCS 5 PBE Parameter. This template has been expanded
* based upon the additions in PKCS 12. This should eventually be moved
* if RSA updates PKCS 5.
*/
-const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[] =
+static const SEC_ASN1Template NSSPKCS5PBEParameterTemplate[] =
{
{ SEC_ASN1_SEQUENCE,
- 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
+ 0, NULL, sizeof(NSSPKCS5PBEParameter) },
{ SEC_ASN1_OCTET_STRING,
- offsetof(SEC_PKCS5PBEParameter, salt) },
+ offsetof(NSSPKCS5PBEParameter, salt) },
{ SEC_ASN1_INTEGER,
- offsetof(SEC_PKCS5PBEParameter, iteration) },
+ offsetof(NSSPKCS5PBEParameter, iteration) },
{ 0 }
};
-const SEC_ASN1Template SEC_V2PKCS12PBEParameterTemplate[] =
+static const SEC_ASN1Template NSSPKCS5PKCS12V2PBEParameterTemplate[] =
{
- { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(SEC_PKCS5PBEParameter) },
- { SEC_ASN1_OCTET_STRING, offsetof(SEC_PKCS5PBEParameter, salt) },
- { SEC_ASN1_INTEGER, offsetof(SEC_PKCS5PBEParameter, iteration) },
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSPKCS5PBEParameter) },
+ { SEC_ASN1_OCTET_STRING, offsetof(NSSPKCS5PBEParameter, salt) },
+ { SEC_ASN1_INTEGER, offsetof(NSSPKCS5PBEParameter, iteration) },
{ 0 }
};
-pbeBitGenParameters pbeHashAlgorithmParams[] = {
- { 0, 0, SEC_OID_UNKNOWN },
- { 128, 512, SEC_OID_MD2 },
- { 128, 512, SEC_OID_MD5 },
- { 160, 512, SEC_OID_SHA1 },
-};
-
-/* generate some random bytes. this is used to generate the
- * salt if it is not specified.
- */
-static SECStatus
-sec_pkcs5_generate_random_bytes(PRArenaPool *poolp,
- SECItem *dest, int len)
-{
- SECStatus rv = SECFailure;
-
- if(dest != NULL)
- {
- void *mark = PORT_ArenaMark(poolp);
- dest->data = (unsigned char *)PORT_ArenaZAlloc(poolp, len);
- if(dest->data != NULL)
- {
- dest->len = len;
- RNG_GenerateGlobalRandomBytes(dest->data, dest->len);
- PORT_ArenaUnmark(poolp, mark);
- rv = SECSuccess;
- } else
- PORT_ArenaRelease(poolp, mark);
- }
-
- return rv;
-}
-
-/* maps hash algorithm from PBE algorithm.
- */
-static SECOidTag
-sec_pkcs5_hash_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_SHA1;
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return SEC_OID_MD5;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_MD2;
- default:
- break;
- }
- return SEC_OID_UNKNOWN;
-}
-
-/* get the iv length needed for the PBE algorithm
- */
-static int
-sec_pkcs5_iv_length(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return DES_IV_LENGTH;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- return RC2_IV_LENGTH;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return 0;
- default:
- break;
- }
- return -1;
-}
-
-/* get the key length needed for the PBE algorithm
- */
-static int
-sec_pkcs5_key_length(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- return 24;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return 8;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return 5;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- return 16;
- default:
- break;
- }
- return -1;
-}
-
-/* the V2 algorithms only encode the salt, there is no iteration
- * count so we need a check for V2 algorithm parameters.
- */
-static PRBool
-sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return PR_TRUE;
- default:
- break;
- }
-
- return PR_FALSE;
-}
-
-/* creates a PBE parameter based on the PBE algorithm. the only required
- * parameters are algorithm and interation. the return is a PBE parameter
- * which conforms to PKCS 5 parameter unless an extended parameter is needed.
- * this is primarily if keyLen and a variable key length algorithm are
- * specified.
- * salt - if null, a salt will be generated from random bytes.
- * iteration - number of iterations to perform hashing.
- * keyLen - only used in variable key length algorithms
- * iv - if null, the IV will be generated based on PKCS 5 when needed.
- * params - optional, currently unsupported additional parameters.
- * once a parameter is allocated, it should be destroyed calling
- * sec_pkcs5_destroy_pbe_parameter or SEC_PKCS5DestroyPBEParameter.
- */
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_create_pbe_parameter(SECOidTag algorithm,
- SECItem *salt,
- int iteration)
-{
- PRArenaPool *poolp = NULL;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
- SECStatus rv;
- void *dummy = NULL;
-
- if(iteration < 0) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
- return NULL;
-
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
- if(!pbe_param) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- pbe_param->poolp = poolp;
- pbe_param->algorithm = algorithm;
-
- /* should we generate the salt? */
- if(!salt || !salt->data) {
- rv = sec_pkcs5_generate_random_bytes(poolp, &pbe_param->salt,
- SALT_LENGTH);
- } else {
- rv = SECITEM_CopyItem(poolp, &pbe_param->salt, salt);
- }
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_TRUE);
- return NULL;
- }
-
- /* encode the integer */
- dummy = SEC_ASN1EncodeInteger(poolp, &pbe_param->iteration,
- iteration);
- rv = (dummy) ? SECSuccess : SECFailure;
-
- if(rv != SECSuccess) {
- PORT_FreeArena(poolp, PR_FALSE);
- return NULL;
- }
-
- return pbe_param;
-}
-
-/* generate bits for key and iv using MD5 hashing
- */
-static SECItem *
-sec_pkcs5_compute_md5_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool dummy)
-{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0)) {
- return NULL;
- }
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if((hash != NULL) && (pre_hash != NULL)) {
- unsigned int i, ph_len;
-
- ph_len = MD5_LENGTH;
- if(ph_len < (salt->len + pwd->len)) {
- ph_len = salt->len + pwd->len;
- }
-
- rv = SECFailure;
- hash->data = (unsigned char *)PORT_ZAlloc(MD5_LENGTH);
- hash->len = MD5_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
- pre_hash->len = salt->len + pwd->len;
-
- if((hash->data != NULL) && (pre_hash->data != NULL)) {
- rv = SECSuccess;
- /* handle 0 length password */
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
- for(i = 0; ((i < (unsigned int)iter) && (rv == SECSuccess)); i++) {
- rv = MD5_HashBuf(hash->data, pre_hash->data, pre_hash->len);
- if(rv != SECFailure) {
- PORT_Memcpy(pre_hash->data, hash->data, MD5_LENGTH);
- pre_hash->len = MD5_LENGTH;
- }
- }
- }
- }
-
- if(pre_hash != NULL)
- SECITEM_FreeItem(pre_hash, PR_TRUE);
-
- if((rv == SECFailure) && (hash)) {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
-}
-
-/* generate bits for key and iv using MD2 hashing
- */
-static SECItem *
-sec_pkcs5_compute_md2_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool dummy)
+SECStatus
+nsspkcs5_HashBuf(const SECHashObject *hashObj, unsigned char *dest,
+ unsigned char *src, int len)
{
- SECItem *hash = NULL, *pre_hash = NULL;
- SECStatus rv = SECFailure;
-
- if((salt == NULL) || (pwd == NULL) || (iter < 0))
- return NULL;
-
- hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- pre_hash = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if((hash != NULL) && (pre_hash != NULL))
- {
- int i, ph_len;
-
- ph_len = MD2_LENGTH;
- if((salt->len + pwd->len) > MD2_LENGTH)
- ph_len = salt->len+pwd->len;
-
- rv = SECFailure;
- hash->data = (unsigned char *)PORT_ZAlloc(MD2_LENGTH);
- hash->len = MD2_LENGTH;
- pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
- pre_hash->len = salt->len + pwd->len;
-
- if((hash->data != NULL) && (pre_hash->data != NULL))
- {
- MD2Context *ctxt;
-
- rv = SECSuccess;
- if(pwd->len > 0) {
- PORT_Memcpy(pre_hash->data, pwd->data, pwd->len);
- }
- if(salt->len > 0) {
- PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
- }
+ void *ctx;
+ unsigned int retLen;
- for(i = 0; ((i < iter) && (rv == SECSuccess)); i++)
- {
- ctxt = MD2_NewContext();
- if(ctxt == NULL)
- rv = SECFailure;
- else
- {
- MD2_Update(ctxt, pre_hash->data, pre_hash->len);
- MD2_End(ctxt, hash->data, &hash->len, hash->len);
- PORT_Memcpy(pre_hash->data, hash->data, MD2_LENGTH);
- pre_hash->len = MD2_LENGTH;
- MD2_DestroyContext(ctxt, PR_TRUE);
- }
- }
- }
+ ctx = hashObj->create();
+ if(ctx == NULL) {
+ return SECFailure;
}
-
- if(pre_hash != NULL)
- SECITEM_FreeItem(pre_hash, PR_TRUE);
-
- if(rv != SECSuccess)
- if(hash != NULL)
- {
- SECITEM_FreeItem(hash, PR_TRUE);
- hash = NULL;
- }
-
- return hash;
+ hashObj->begin(ctx);
+ hashObj->update(ctx, src, len);
+ hashObj->end(ctx, dest, &retLen, hashObj->length);
+ hashObj->destroy(ctx, PR_TRUE);
+ return SECSuccess;
}
-/* generate bits using SHA1 hash
+/* generate bits using any hash
*/
static SECItem *
-sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
- PRBool faulty3DES)
+nsspkcs5_PBKDF1(const SECHashObject *hashObj, SECItem *salt, SECItem *pwd,
+ int iter, PRBool faulty3DES)
{
SECItem *hash = NULL, *pre_hash = NULL;
SECStatus rv = SECFailure;
@@ -441,8 +108,8 @@ sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
if((hash != NULL) && (pre_hash != NULL)) {
int i, ph_len;
- ph_len = SHA1_LENGTH;
- if((salt->len + pwd->len) > SHA1_LENGTH) {
+ ph_len = hashObj->length;
+ if((salt->len + pwd->len) > hashObj->length) {
ph_len = salt->len + pwd->len;
}
@@ -450,21 +117,21 @@ sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
/* allocate buffers */
hash->data = (unsigned char *)PORT_ZAlloc(SHA1_LENGTH);
- hash->len = SHA1_LENGTH;
+ hash->len = hashObj->length;
pre_hash->data = (unsigned char *)PORT_ZAlloc(ph_len);
/* in pbeSHA1TripleDESCBC there was an allocation error that made
* it into the caller. We do not want to propagate those errors
* further, so we are doing it correctly, but reading the old method.
*/
- if(faulty3DES) {
+ if (faulty3DES) {
pre_hash->len = ph_len;
} else {
pre_hash->len = salt->len + pwd->len;
}
/* preform hash */
- if((hash->data != NULL) && (pre_hash->data != NULL)) {
+ if ((hash->data != NULL) && (pre_hash->data != NULL)) {
rv = SECSuccess;
/* check for 0 length password */
if(pwd->len > 0) {
@@ -474,10 +141,11 @@ sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
PORT_Memcpy((pre_hash->data+pwd->len), salt->data, salt->len);
}
for(i = 0; ((i < iter) && (rv == SECSuccess)); i++) {
- rv = SHA1_HashBuf(hash->data, pre_hash->data, pre_hash->len);
+ rv = nsspkcs5_HashBuf(hashObj, hash->data,
+ pre_hash->data, pre_hash->len);
if(rv != SECFailure) {
- pre_hash->len = SHA1_LENGTH;
- PORT_Memcpy(pre_hash->data, hash->data, SHA1_LENGTH);
+ pre_hash->len = hashObj->length;
+ PORT_Memcpy(pre_hash->data, hash->data, hashObj->length);
}
}
}
@@ -495,101 +163,6 @@ sec_pkcs5_compute_sha1_hash(SECItem *salt, SECItem *pwd, int iter,
return hash;
}
-/* bit generation/key and iv generation routines. */
-typedef SECItem *(* sec_pkcs5_hash_func)(SECItem *s, SECItem *p,
- int iter, PRBool faulty3DES);
-
-/* generates bits needed for the key and iv based on PKCS 5,
- * be concatenating the password and salt and using the appropriate
- * hash algorithm. This function serves as a front end to the
- * specific hash functions above. a return of NULL indicates an
- * error.
- */
-static SECItem *
-sec_pkcs5_compute_hash(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
-{
- sec_pkcs5_hash_func hash_func;
- SECOidTag hash_alg;
- SECItem *hash = NULL;
- SECItem *salt = NULL;
-
- hash_alg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- salt = &(pbe_param->salt);
- switch(hash_alg)
- {
- case SEC_OID_SHA1:
- hash_func = sec_pkcs5_compute_sha1_hash;
- break;
- case SEC_OID_MD2:
- hash_func = sec_pkcs5_compute_md2_hash;
- break;
- case SEC_OID_MD5:
- hash_func = sec_pkcs5_compute_md5_hash;
- break;
- default:
- hash_func = NULL;
- }
-
- if(hash_func) {
- hash = (* hash_func)(salt, pwitem, pbe_param->iter, faulty3DES);
- }
-
- return hash;
-}
-
-/* determines the number of bits needed for key and iv generation
- * based upon the algorithm identifier. if a number of
- * bits greater than the hash algorithm can produce are needed,
- * the bits will be generated based upon the extended PKCS 5
- * described in PKCS 12.
- *
- * a return of -1 indicates an error.
- */
-static int
-sec_pkcs5_bits_needed(SEC_PKCS5PBEParameter *pbe_param)
-{
- int iv_bits;
- int key_bits;
-
- if(pbe_param == NULL) {
- return -1;
- }
-
- iv_bits = sec_pkcs5_iv_length(pbe_param->algorithm) * 8;
- key_bits = sec_pkcs5_key_length(pbe_param->algorithm) * 8;
-
- if(key_bits != 0) {
- return iv_bits + key_bits;
- }
-
- return -1;
-}
-
-/* determines the number of bits generated by each hash algorithm.
- * in case of an error, -1 is returned.
- */
-static int
-sec_pkcs5_hash_bits_generated(SEC_PKCS5PBEParameter *pbe_param)
-{
- if(pbe_param == NULL) {
- return -1;
- }
-
- switch(sec_pkcs5_hash_algorithm(pbe_param->algorithm)) {
- case SEC_OID_SHA1:
- return SHA1_LENGTH * 8;
- case SEC_OID_MD2:
- return MD2_LENGTH * 8;
- case SEC_OID_MD5:
- return MD5_LENGTH * 8;
- default:
- break;
- }
-
- return -1;
-}
-
/* this bit generation routine is described in PKCS 12 and the proposed
* extensions to PKCS 5. an initial hash is generated following the
* instructions laid out in PKCS 5. If the number of bits generated is
@@ -598,9 +171,8 @@ sec_pkcs5_hash_bits_generated(SEC_PKCS5PBEParameter *pbe_param)
* function. And the P_Hash function from the TLS standard.
*/
static SECItem *
-sec_pkcs5_bit_generator(SEC_PKCS5PBEParameter *pbe_param,
- SECItem *init_hash,
- unsigned int bits_needed)
+nsspkcs5_PFXPBE(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
+ SECItem *init_hash, unsigned int bytes_needed)
{
SECItem *ret_bits = NULL;
int hash_size = 0;
@@ -612,12 +184,8 @@ sec_pkcs5_bit_generator(SEC_PKCS5PBEParameter *pbe_param,
unsigned int state_len;
HMACContext *cx = NULL;
- hash_size = sec_pkcs5_hash_bits_generated(pbe_param);
- if(hash_size == -1)
- return NULL;
-
- hash_iter = (bits_needed + (unsigned int)hash_size - 1) / hash_size;
- hash_size /= 8;
+ hash_size = hashObj->length;
+ hash_iter = (bytes_needed + (unsigned int)hash_size - 1) / hash_size;
/* allocate return buffer */
ret_bits = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
@@ -648,8 +216,7 @@ sec_pkcs5_bit_generator(SEC_PKCS5PBEParameter *pbe_param,
PORT_Memcpy(state, pbe_param->salt.data, pbe_param->salt.len);
}
- cx = HMAC_Create(sec_pkcs5_hash_algorithm(pbe_param->algorithm),
- init_hash->data, init_hash->len);
+ cx = HMAC_Create(hashObj, init_hash->data, init_hash->len);
if (cx == NULL) {
rv = SECFailure;
goto loser;
@@ -694,151 +261,371 @@ loser:
* based on the extension proposed in PKCS 12
*/
static SECItem *
-sec_pkcs5_generate_bits(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
+nsspkcs5_PBKDF1Extended(const SECHashObject *hashObj,
+ NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem, PRBool faulty3DES)
{
SECItem * hash = NULL;
SECItem * newHash = NULL;
- int bits_needed;
- int bits_available;
+ int bytes_needed;
+ int bytes_available;
- bits_needed = sec_pkcs5_bits_needed(pbe_param);
- bits_available = sec_pkcs5_hash_bits_generated(pbe_param);
-
- if((bits_needed == -1) || (bits_available == -1)) {
- return NULL;
- }
+ bytes_needed = pbe_param->ivLen + pbe_param->keyLen;
+ bytes_available = hashObj->length;
+
+ hash = nsspkcs5_PBKDF1(hashObj, &pbe_param->salt, pwitem,
+ pbe_param->iter, faulty3DES);
- hash = sec_pkcs5_compute_hash(pbe_param, pwitem, faulty3DES);
if(hash == NULL) {
return NULL;
}
- if(bits_needed <= bits_available) {
+ if(bytes_needed <= bytes_available) {
return hash;
}
- newHash = sec_pkcs5_bit_generator(pbe_param, hash, bits_needed);
+ newHash = nsspkcs5_PFXPBE(hashObj, pbe_param, hash, bytes_needed);
if (hash != newHash)
SECITEM_FreeItem(hash, PR_TRUE);
return newHash;
}
-/* compute the IV as per PKCS 5
+#ifdef PBKDF2
+
+/*
+ * PBDKDF2 is PKCS #5 v2.0 it's currently not used by NSS
*/
-static SECItem *
-sec_pkcs5_compute_iv(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
+/*
+ * We This is safe because hLen for all our
+ * HMAC algorithms are multiples of 4.
+ */
+static void
+xorbytes(unsigned char *dest, unsigned char *src, int len)
{
- SECItem *hash = NULL, *iv = NULL;
+#ifdef PARANOIA
+ while (len--) {
+ *dest = *dest ^ *src;
+ dest++;
+ src++;
+ }
+#else
+ PRUInt32 dest32 = (PRUInt32 *)dest;
+ PRUInt32 src32 = (PRUInt32 *)dest;
+ while (len -= sizeof(PRUInt32)) {
+ *dest32 = *dest32 ^ *src32;
+ dest++;
+ src++;
+ }
+#endif
+}
- if((pbe_param == NULL) || (pwitem == NULL)) {
- return NULL;
+static SECStatus
+nsspkcs5_PBKFD2_F(const SECHashObject *hashobj, SECItem *pwitem, SECItem *salt,
+ int iterations, unsigned int i, unsigned char *T)
+{
+ int j;
+ HMACContext *cx = NULL;
+ unsigned int hLen = hashObject->length
+ SECStatus rv = SECFailure;
+ unsigned char *last = NULL;
+ int lastLength = salt->len + 4;
+
+ cx=HMAC_Create(hashobj,pwitem->data,pwitem->len);
+ if (cx == NULL) {
+ goto loser;
+ }
+ PORT_Memset(T,0,hLen);
+ realLastLength= MAX(lastLength,hLen);
+ last = PORT_Alloc(realLastLength);
+ if (last == NULL) {
+ goto loser;
+ }
+ PORT_Memcpy(last,salt.data,salt.len);
+ last[salt->len ] = (i >> 24) & 0xff;
+ last[salt->len+1] = (i >> 16) & 0xff;
+ last[salt->len+2] = (i >> 8) & 0xff;
+ last[salt->len+3] = i & 0xff;
+
+ /* NOTE: we need at least one iteration to return success! */
+ for (j=0; j < interations; j++) {
+ rv =HMAC_Begin(cx);
+ if (rv !=SECSuccess) {
+ break;
+ }
+ HMAC_Update(cx,last,lastLength);
+ rv =HMAC_Finish(cx,last,&lastLength,hLen);
+ if (rv !=SECSuccess) {
+ break;
+ }
+ do_xor(T,last,hLen);
+ }
+loser:
+ if (cx) {
+ HMAC_DestroyContext(cx);
}
+ if (last) {
+ PORT_ZFree(last,reaLastLength);
+ }
+ return rv;
+}
- /* generate iv */
- iv = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(!iv) {
+static SECItem *
+nsspkcs5_PBKFD2(const SECHashObject *hashObj, NSSPKCS5PBEParameter *pbe_param,
+ SECItem *pwitem)
+{
+ unsigned int dkLen = bytesNeeded;
+ unsigned int hLen = hashObject->length
+ unsigned int l = (dkLen+hLen-1) / hLen;
+ unsigned char *rp;
+ SECItem *result;
+ SECItem *salt = pbe_param->salt;
+ int interations = pbe_param->iter;
+ int bytesNeeded = pbe_param->keyLen;
+
+ result = SECITEM_AllocItem(NULL,NULL,l*hLen);
+ if (result == NULL) {
return NULL;
}
- iv->len = sec_pkcs5_iv_length(pbe_param->algorithm);
- if(iv->len == -1) {
- PORT_Free(iv);
- return NULL;
+ T = PORT_Alloc(hLen);
+ if (T == NULL) {
+ goto loser;
+ }
+
+ for (i=0,rp=results->data; i < l ; i++, rp +=hLen) {
+ rv = nsspkcs5_PBKFD2_F(hashobj,pwitem,salt,iterations,i,T);
+ if (rv != SECSuccess) {
+ break;
+ }
+ PORT_Memcpy(rp,T,hLen);
+ }
+
+loser:
+ if (T) {
+ PORT_ZFree(T);
}
+ if (rv != SECSuccess) {
+ SECITEM_FreeITEM(result,PR_TRUE);
+ result = NULL;
+ } else {
+ result->len = dkLen;
+ }
+
+ return result;
+}
+#endif
- iv->data = (unsigned char *)PORT_ZAlloc(iv->len);
- if(iv->data == NULL) {
- PORT_Free(iv);
+#define HMAC_BUFFER 64
+#define ROUNDUP(x,y) ((((x)+((y)-1))/(y))*(y))
+/*
+ * This is the extended PBE function defined by the final PKCS #12 spec.
+ */
+static SECItem *
+nsspkcs5_PKCS12PBE(const SECHashObject *hashObject,
+ NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ PBEBitGenID bitGenPurpose, unsigned int bytesNeeded)
+{
+ PRArenaPool *arena = NULL;
+ unsigned int SLen,PLen;
+ unsigned int hashLength = hashObject->length;
+ unsigned char *S, *P;
+ SECItem *A = NULL, B, D, I;
+ SECItem *salt = &pbe_param->salt;
+ unsigned int c,i = 0;
+ unsigned int hashLen, n, iter;
+ unsigned char *iterBuf;
+ void *hash = NULL;
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if(!arena) {
return NULL;
}
- if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(pbe_param->algorithm)) {
- SECOidTag hashAlg;
- PBEBitGenContext *ctxt;
- hashAlg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- ctxt = PBE_CreateContext(hashAlg, pbeBitGenCipherIV,
- pwitem, &pbe_param->salt,
- iv->len * 8, pbe_param->iter);
- if(!ctxt) {
- SECITEM_FreeItem(iv, PR_TRUE);
- return NULL;
+ /* how many hash object lengths are needed */
+ c = (bytesNeeded + (hashLength-1))/hashLength;
+
+ /* initialize our buffers */
+ D.len = HMAC_BUFFER;
+ /* B and D are the same length, use one alloc go get both */
+ D.data = (unsigned char*)PORT_ArenaZAlloc(arena, D.len*2);
+ B.len = D.len;
+ B.data = D.data + D.len;
+
+ /* if all goes well, A will be returned, so don't use our temp arena */
+ A = SECITEM_AllocItem(NULL,NULL,c*hashLength);
+ if (A == NULL) {
+ goto loser;
+ }
+
+ SLen = ROUNDUP(salt->len,HMAC_BUFFER);
+ PLen = ROUNDUP(pwitem->len,HMAC_BUFFER);
+ I.len = SLen+PLen;
+ I.data = (unsigned char*)PORT_ArenaZAlloc(arena, I.len);
+ if (I.data == NULL) {
+ goto loser;
+ }
+
+ /* S & P are only used to initialize I */
+ S = I.data;
+ P = S + SLen;
+
+ PORT_Memset(D.data, (char)bitGenPurpose, D.len);
+ if (SLen) {
+ PORT_Memcpy(S, salt->data, salt->len);
+ if (salt->len != SLen) {
+ PORT_Memcpy(S+salt->len, salt->data, SLen-(salt->len));
+ }
+ }
+ if (PLen) {
+ PORT_Memcpy(P, salt->data, salt->len);
+ if (salt->len != PLen) {
+ PORT_Memcpy(P+salt->len, salt->data, PLen-salt->len);
}
+ }
- hash = PBE_GenerateBits(ctxt);
- PBE_DestroyContext(ctxt);
- } else {
- hash = sec_pkcs5_generate_bits(pbe_param, pwitem, faulty3DES);
+ iterBuf = (unsigned char*)PORT_ArenaZAlloc(arena,hashLength);
+ if (iterBuf == NULL) {
+ goto loser;
}
+ hash = hashObject->create();
if(!hash) {
- SECITEM_FreeItem(iv, PR_TRUE);
- return NULL;
+ goto loser;
}
+ /* calculate the PBE now */
+ for(i = 0; i < c; i++) {
+ int Bidx; /* must be signed or the for loop won't terminate */
+ unsigned int k, j;
+ unsigned char *Ai = A->data+i*hashLength;
- PORT_Memcpy(iv->data, (hash->data+(hash->len - iv->len)), iv->len);
- SECITEM_FreeItem(hash, PR_TRUE);
- return iv;
+ for(iter = 0; iter < pbe_param->iter; iter++) {
+ hashObject->begin(hash);
+
+ if (iter) {
+ hashObject->update(hash, iterBuf, hashLen);
+ } else {
+ hashObject->update(hash, D.data, D.len);
+ hashObject->update(hash, I.data, I.len);
+ }
+
+ hashObject->end(hash, iterBuf, &hashLen, hashObject->length);
+ if(hashLen != hashObject->length) {
+ break;
+ }
+ }
+
+ PORT_Memcpy(&(A->data[i*hashLength]), iterBuf, hashLength);
+ for (Bidx = 0; Bidx < B.len; B.len += hashLength) {
+ PORT_Memcpy(B.data +Bidx, iterBuf,
+ (((Bidx + hashLength) > B.len) ? (B.len - Bidx) :
+ hashLength));
+ }
+
+ k = I.len/B.len;
+ for(j = 0; j < k; j++) {
+ unsigned int q, carryBit;
+ unsigned char *Ij = I.data + j*B.len;
+
+ /* (Ij = Ij+B+1) */
+ for (Bidx = (B.len-1), q=1, carryBit=0; Bidx >= 0; Bidx--,q=0) {
+ q += (unsigned int)Ij[Bidx];
+ q += (unsigned int)B.data[Bidx];
+ q += carryBit;
+
+ carryBit = (q > 0xff);
+ Ij[Bidx] = (unsigned char)(q & 0xff);
+ }
+ }
+ }
+loser:
+ if (hash) {
+ hashObject->destroy(hash, PR_TRUE);
+ }
+ if(arena) {
+ PORT_FreeArena(arena, PR_TRUE);
+ }
+
+ /* if i != c, then we didn't complete the loop above and must of failed
+ * somwhere along the way */
+ if (i != c) {
+ SECITEM_ZfreeItem(A,PR_TRUE);
+ A = NULL;
+ } else {
+ A->len = bytesNeeded;
+ }
+
+ return A;
}
-/* generate key as per PKCS 5
+/*
+ * generate key as per PKCS 5
*/
-static SECItem *
-sec_pkcs5_compute_key(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
- PRBool faulty3DES)
+SECItem *
+nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ SECItem *iv, PRBool faulty3DES)
{
SECItem *hash = NULL, *key = NULL;
+ const SECHashObject *hashObj;
+ PRBool getIV = PR_FALSE;
if((pbe_param == NULL) || (pwitem == NULL)) {
return NULL;
}
- key = (SECItem *)PORT_ZAlloc(sizeof(SECItem));
- if(!key) {
+ key = SECITEM_AllocItem(NULL,NULL,pbe_param->keyLen);
+ if (key == NULL) {
return NULL;
}
- key->len = sec_pkcs5_key_length(pbe_param->algorithm);
- if(key->len == -1) {
- PORT_Free(key);
- return NULL;
- }
-
- key->data = (unsigned char *)PORT_ZAlloc(sizeof(unsigned char) *
- key->len);
- if(!key->data) {
- PORT_Free(key);
- return NULL;
+ if ((pbe_param->ivLen) && (iv->data == NULL)) {
+ getIV = PR_TRUE;
+ iv->data = (unsigned char *)PORT_Alloc(pbe_param->ivLen);
+ if (iv->data == NULL) {
+ goto loser;
+ }
+ iv->len = pbe_param->ivLen;
}
-
- if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(pbe_param->algorithm)) {
- SECOidTag hashAlg;
- PBEBitGenContext *ctxt;
- hashAlg = sec_pkcs5_hash_algorithm(pbe_param->algorithm);
- ctxt = PBE_CreateContext(hashAlg, pbeBitGenCipherKey,
- pwitem, &pbe_param->salt,
- key->len * 8, pbe_param->iter);
- if(!ctxt) {
- SECITEM_FreeItem(key, PR_TRUE);
- return NULL;
+ hashObj = &SECRawHashObjects[pbe_param->hashType];
+ switch (pbe_param->pbeType) {
+ case NSSPKCS5_PBKDF1:
+ hash = nsspkcs5_PBKDF1Extended(hashObj,pbe_param,pwitem,faulty3DES);
+ if (hash == NULL) {
+ goto loser;
}
-
- hash = PBE_GenerateBits(ctxt);
- PBE_DestroyContext(ctxt);
- } else {
- hash = sec_pkcs5_generate_bits(pbe_param, pwitem, faulty3DES);
+ PORT_Assert(hash->len >= key->len+iv->len);
+ if (getIV) {
+ PORT_Memcpy(iv->data, hash->data+(hash->len - iv->len),iv->len);
+ }
+ break;
+#ifdef PBKDF2
+ case NSSPKCS5_PBKDF2:
+ hash = nsspkcs5_PBKDF2(hashObj,pbe_param,pwitem);
+ PORT_Assert(!getIV);
+ break;
+#endif
+ case NSSPKCS5_PKCS12_V2:
+ if (getIV) {
+ hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem,
+ pbeBitGenCipherIV,iv->len);
+ if (hash == NULL) {
+ goto loser;
+ }
+ PORT_Memcpy(iv->data,hash->data,iv->len);
+ SECITEM_ZfreeItem(hash,PR_TRUE);
+ hash = NULL;
+ }
+ hash = nsspkcs5_PKCS12PBE(hashObj,pbe_param,pwitem,
+ pbeBitGenCipherKey,key->len);
+ default:
+ break;
}
-
- if(!hash) {
- SECITEM_FreeItem(key, PR_TRUE);
- return NULL;
+
+ if (hash == NULL) {
+ goto loser;
}
- if(pbe_param->algorithm ==
- SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC) {
+ if (pbe_param->is2KeyDES) {
PORT_Memcpy(key->data, hash->data, (key->len * 2) / 3);
PORT_Memcpy(&(key->data[(key->len * 2) / 3]), key->data,
key->len / 3);
@@ -848,58 +635,174 @@ sec_pkcs5_compute_key(SEC_PKCS5PBEParameter *pbe_param, SECItem *pwitem,
SECITEM_FreeItem(hash, PR_TRUE);
return key;
+
+loser:
+ if (getIV && iv->data) {
+ PORT_ZFree(iv->data,iv->len);
+ iv->data = NULL;
+ }
+
+ SECITEM_ZfreeItem(key, PR_TRUE);
+ return NULL;
+}
+
+static SECStatus
+nsspkcs5_FillInParam(SECOidTag algorithm, NSSPKCS5PBEParameter *pbe_param)
+{
+ PRBool skipType = PR_FALSE;
+
+ pbe_param->keyLen = 5;
+ pbe_param->ivLen = 8;
+ pbe_param->hashType = HASH_AlgSHA1;
+ pbe_param->pbeType = NSSPKCS5_PBKDF1;
+ pbe_param->encAlg = SEC_OID_RC2_CBC;
+ pbe_param->is2KeyDES = PR_FALSE;
+ switch(algorithm) {
+ /* DES3 Algorithms */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
+ pbe_param->is2KeyDES = PR_TRUE;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ /* fall through */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
+ pbe_param->keyLen = 24;
+ pbe_param->encAlg = SEC_OID_DES_EDE3_CBC;
+ break;
+
+ /* DES Algorithms */
+ case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
+ pbe_param->hashType = HASH_AlgMD2;
+ goto finish_des;
+ case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
+ pbe_param->hashType = HASH_AlgMD5;
+ /* fall through */
+ case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
+finish_des:
+ pbe_param->keyLen = 8;
+ pbe_param->encAlg = SEC_OID_DES_CBC;
+ break;
+
+ /* RC2 Algorithms */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ pbe_param->keyLen = 16;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ break;
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
+ pbe_param->keyLen = 16;
+ /* fall through */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
+ break;
+
+ /* RC4 algorithms */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ skipType = PR_TRUE;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
+ pbe_param->keyLen = 16;
+ /* fall through */
+ case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ if (!skipType) {
+ pbe_param->pbeType = NSSPKCS5_PKCS12_V2;
+ }
+ /* fall through */
+ case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
+ pbe_param->ivLen = 0;
+ pbe_param->encAlg = SEC_OID_RC4;
+ break;
+ default:
+ return SECFailure;
+ }
+
+ return SECSuccess;
}
/* decode the algid and generate a PKCS 5 parameter from it
*/
-static SEC_PKCS5PBEParameter *
-sec_pkcs5_convert_algid(SECAlgorithmID *algid)
+NSSPKCS5PBEParameter *
+nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator)
{
- PRArenaPool *poolp;
- SEC_PKCS5PBEParameter *pbe_param = NULL;
+ PRArenaPool *arena = NULL;
+ NSSPKCS5PBEParameter *pbe_param = NULL;
SECOidTag algorithm;
SECStatus rv = SECFailure;
- if(algid == NULL)
+ arena = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
+ if (arena == NULL)
return NULL;
- algorithm = SECOID_GetAlgorithmTag(algid);
-
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
- return NULL;
+ /* allocate memory for the parameter */
+ pbe_param = (NSSPKCS5PBEParameter *)PORT_ArenaZAlloc(arena,
+ sizeof(NSSPKCS5PBEParameter));
+
+ if (pbe_param == NULL) {
+ goto loser;
+ }
+
+ pbe_param->poolp = arena;
+
+ rv = nsspkcs5_FillInParam(alg, pbe_param);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ pbe_param->iter = iterator;
+ if (salt) {
+ rv = SECITEM_CopyItem(arena,&pbe_param->salt,salt);
+ }
+
+loser:
+ if (rv != SECSuccess) {
+ PORT_FreeArena(arena, PR_TRUE);
+ pbe_param = NULL;
+ }
+
+ return pbe_param;
+}
+
+/* decode the algid and generate a PKCS 5 parameter from it
+ */
+NSSPKCS5PBEParameter *
+nsspkcs5_AlgidToParam(SECAlgorithmID *algid)
+{
+ NSSPKCS5PBEParameter *pbe_param = NULL;
+ SECOidTag algorithm;
+ SECStatus rv = SECFailure;
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(poolp == NULL)
+ if (algid == NULL) {
return NULL;
+ }
- /* allocate memory for the parameter */
- pbe_param = (SEC_PKCS5PBEParameter *)PORT_ArenaZAlloc(poolp,
- sizeof(SEC_PKCS5PBEParameter));
+ algorithm = SECOID_GetAlgorithmTag(algid);
+ if (algorithm == SEC_OID_UNKNOWN) {
+ goto loser;
+ }
+
+ pbe_param = nsspkcs5_NewParam(algorithm, NULL, 1);
+ if (pbe_param == NULL) {
+ goto loser;
+ }
/* decode parameter */
- if(pbe_param && !sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- pbe_param->poolp = poolp;
- rv = SEC_ASN1DecodeItem(poolp, pbe_param,
- SEC_PKCS5PBEParameterTemplate, &algid->parameters);
- if(rv != SECSuccess) {
- goto loser;
- }
- pbe_param->algorithm = algorithm;
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
- } else if(sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- pbe_param->algorithm = algorithm;
- pbe_param->poolp = poolp;
- rv = SEC_ASN1DecodeItem(poolp, pbe_param, SEC_V2PKCS12PBEParameterTemplate,
- &algid->parameters);
- if(rv != SECSuccess) {
- goto loser;
- }
- pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
+ rv = SECFailure;
+ switch (pbe_param->pbeType) {
+ case NSSPKCS5_PBKDF1:
+ rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
+ NSSPKCS5PBEParameterTemplate, &algid->parameters);
+ case NSSPKCS5_PKCS12_V2:
+ rv = SEC_ASN1DecodeItem(pbe_param->poolp, pbe_param,
+ NSSPKCS5PKCS12V2PBEParameterTemplate, &algid->parameters);
+ case NSSPKCS5_PBKDF2:
+ break;
}
loser:
- if((pbe_param == NULL) || (rv != SECSuccess)) {
- PORT_FreeArena(poolp, PR_TRUE);
+ if (rv == SECSuccess) {
+ pbe_param->iter = DER_GetInteger(&pbe_param->iteration);
+ } else {
+ nsspkcs5_DestroyPBEParameter(pbe_param);
pbe_param = NULL;
}
@@ -910,59 +813,22 @@ loser:
* generated using the appropriate create function and therefor
* contains an arena pool.
*/
-static void
-sec_pkcs5_destroy_pbe_param(SEC_PKCS5PBEParameter *pbe_param)
+void
+nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *pbe_param)
{
- if(pbe_param != NULL)
+ if (pbe_param != NULL) {
PORT_FreeArena(pbe_param->poolp, PR_TRUE);
+ }
}
/* crypto routines */
-
-/* function pointer template for crypto functions */
-typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv,
- SECItem *src, PRBool op1, PRBool op2);
-
-/* map PBE algorithm to crypto algorithm */
-static SECOidTag
-sec_pkcs5_encryption_algorithm(SECOidTag algorithm)
-{
- switch(algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- default:
- break;
- }
- return SEC_OID_UNKNOWN;
-}
-
/* perform DES encryption and decryption. these routines are called
- * by SEC_PKCS5CipherData. In the case of an error, NULL is returned.
+ * by nsspkcs5_CipherData. In the case of an error, NULL is returned.
*/
static SECItem *
-sec_pkcs5_des(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool triple_des,
- PRBool encrypt)
+sec_pkcs5_des(SECItem *key, SECItem *iv, SECItem *src, PRBool triple_des,
+ PRBool encrypt)
{
SECItem *dest;
SECItem *dup_src;
@@ -1041,11 +907,8 @@ sec_pkcs5_des(SECItem *key,
/* perform rc2 encryption/decryption if an error occurs, NULL is returned
*/
static SECItem *
-sec_pkcs5_rc2(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool cbc_mode,
- PRBool encrypt)
+sec_pkcs5_rc2(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy,
+ PRBool encrypt)
{
SECItem *dest;
SECItem *dup_src;
@@ -1079,9 +942,8 @@ sec_pkcs5_rc2(SECItem *key,
if(dest->data != NULL) {
RC2Context *ctxt;
- ctxt = RC2_CreateContext(key->data, key->len, iv->data,
- ((cbc_mode != PR_TRUE) ? NSS_RC2 : NSS_RC2_CBC),
- key->len);
+ ctxt = RC2_CreateContext(key->data, key->len, iv->data,
+ NSS_RC2_CBC, key->len);
if(ctxt != NULL) {
rv = ((encrypt != PR_TRUE) ? RC2_Decrypt : RC2_Encrypt)(
@@ -1089,8 +951,7 @@ sec_pkcs5_rc2(SECItem *key,
dup_src->len + 64, dup_src->data, dup_src->len);
/* assumes 8 byte blocks -- remove padding */
- if((rv == SECSuccess) && (encrypt != PR_TRUE) &&
- (cbc_mode == PR_TRUE)) {
+ if((rv == SECSuccess) && (encrypt != PR_TRUE)) {
pad = dest->data[dest->len-1];
if((pad > 0) && (pad <= 8)) {
if(dest->data[dest->len-pad] != pad) {
@@ -1123,11 +984,8 @@ sec_pkcs5_rc2(SECItem *key,
/* perform rc4 encryption and decryption */
static SECItem *
-sec_pkcs5_rc4(SECItem *key,
- SECItem *iv,
- SECItem *src,
- PRBool dummy_op,
- PRBool encrypt)
+sec_pkcs5_rc4(SECItem *key, SECItem *iv, SECItem *src, PRBool dummy_op,
+ PRBool encrypt)
{
SECItem *dest;
SECStatus rv = SECFailure;
@@ -1160,6 +1018,9 @@ sec_pkcs5_rc4(SECItem *key,
return dest;
}
+/* function pointer template for crypto functions */
+typedef SECItem *(* pkcs5_crypto_func)(SECItem *key, SECItem *iv,
+ SECItem *src, PRBool op1, PRBool op2);
/* performs the cipher operation on the src and returns the result.
* if an error occurs, NULL is returned.
@@ -1169,88 +1030,75 @@ sec_pkcs5_rc4(SECItem *key,
*/
/* change this to use PKCS 11? */
SECItem *
-SEC_PKCS5CipherData(SECAlgorithmID *algid,
- SECItem *pwitem,
- SECItem *src,
- PRBool encrypt, PRBool *update)
+nsspkcs5_CipherData(NSSPKCS5PBEParameter *pbe_param, SECItem *pwitem,
+ SECItem *src, PRBool encrypt, PRBool *update)
{
- SEC_PKCS5PBEParameter *pbe_param;
- SECOidTag enc_alg;
- SECItem *key = NULL, *iv = NULL;
+ SECItem *key = NULL, iv;
SECItem *dest = NULL;
- int iv_len;
+ PRBool tripleDES = PR_TRUE;
+ pkcs5_crypto_func cryptof;
+
+ iv.data = NULL;
if (update) {
*update = PR_FALSE;
}
- if((algid == NULL) || (pwitem == NULL) || (src == NULL)) {
+ if ((pwitem == NULL) || (src == NULL)) {
return NULL;
}
- /* convert algid to pbe parameter */
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL) {
+ /* get key, and iv */
+ key = nsspkcs5_ComputeKeyAndIV(pbe_param, pwitem, &iv, PR_FALSE);
+ if(key == NULL) {
return NULL;
}
- /* get algorithm, key, and iv */
- enc_alg = sec_pkcs5_encryption_algorithm(pbe_param->algorithm);
- key = sec_pkcs5_compute_key(pbe_param, pwitem, PR_FALSE);
- if(key != NULL) {
- iv_len = sec_pkcs5_iv_length(pbe_param->algorithm);
- iv = sec_pkcs5_compute_iv(pbe_param, pwitem, PR_FALSE);
-
- if((iv != NULL) || (iv_len == 0)) {
- /*perform encryption / decryption */
- PRBool op1 = PR_TRUE;
- pkcs5_crypto_func cryptof;
-
- switch(enc_alg) {
- case SEC_OID_DES_EDE3_CBC:
- cryptof = sec_pkcs5_des;
- break;
- case SEC_OID_DES_CBC:
- cryptof = sec_pkcs5_des;
- op1 = PR_FALSE;
- break;
- case SEC_OID_RC2_CBC:
- cryptof = sec_pkcs5_rc2;
- break;
- case SEC_OID_RC4:
- cryptof = sec_pkcs5_rc4;
- break;
- default:
- cryptof = NULL;
- break;
- }
-
- if(cryptof) {
- dest = (*cryptof)(key, iv, src, op1, encrypt);
- /*
- * it's possible for some keys and keydb's to claim to
- * be triple des when they're really des. In this case
- * we simply try des. If des works we set the update flag
- * so the key db knows it needs to update all it's entries.
- * The case can only happen on decrypted of a
- * SEC_OID_DES_EDE3_CBD.
- */
- if ((dest == NULL) && (encrypt == PR_FALSE) &&
- (enc_alg == SEC_OID_DES_EDE3_CBC)) {
- dest = (*cryptof)(key, iv, src, PR_FALSE, encrypt);
- if (update && (dest != NULL)) *update = PR_TRUE;
- }
- }
- }
+ switch(pbe_param->encAlg) {
+ case SEC_OID_DES_EDE3_CBC:
+ cryptof = sec_pkcs5_des;
+ tripleDES = PR_TRUE;
+ break;
+ case SEC_OID_DES_CBC:
+ cryptof = sec_pkcs5_des;
+ tripleDES = PR_FALSE;
+ break;
+ case SEC_OID_RC2_CBC:
+ cryptof = sec_pkcs5_rc2;
+ break;
+ case SEC_OID_RC4:
+ cryptof = sec_pkcs5_rc4;
+ break;
+ default:
+ cryptof = NULL;
+ break;
+ }
+
+ if(cryptof) {
+ goto loser;
}
- sec_pkcs5_destroy_pbe_param(pbe_param);
+ dest = (*cryptof)(key, &iv, src, tripleDES, encrypt);
+ /*
+ * it's possible for some keys and keydb's to claim to
+ * be triple des when they're really des. In this case
+ * we simply try des. If des works we set the update flag
+ * so the key db knows it needs to update all it's entries.
+ * The case can only happen on decrypted of a
+ * SEC_OID_DES_EDE3_CBD.
+ */
+ if ((dest == NULL) && (encrypt == PR_FALSE) &&
+ (pbe_param->encAlg == SEC_OID_DES_EDE3_CBC)) {
+ dest = (*cryptof)(key, &iv, src, PR_FALSE, encrypt);
+ if (update && (dest != NULL)) *update = PR_TRUE;
+ }
- if(key != NULL) {
+loser:
+ if (key != NULL) {
SECITEM_ZfreeItem(key, PR_TRUE);
}
- if(iv != NULL) {
- SECITEM_ZfreeItem(iv, PR_TRUE);
+ if (iv.data != NULL) {
+ SECITEM_ZfreeItem(&iv, PR_FALSE);
}
return dest;
@@ -1265,585 +1113,60 @@ SEC_PKCS5CipherData(SECAlgorithmID *algid,
* SECOID_DestroyAlgorithmID
*/
SECAlgorithmID *
-SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
- SECItem *salt,
- int iteration)
+nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
+ NSSPKCS5PBEParameter *pbe_param)
{
- PRArenaPool *poolp = NULL;
SECAlgorithmID *algid, *ret_algid;
SECItem der_param;
SECStatus rv = SECFailure;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN)
- return NULL;
+ void *dummy = NULL;
- if(iteration <= 0) {
+ if (arena == NULL) {
return NULL;
}
der_param.data = NULL;
der_param.len = 0;
- /* generate the parameter */
- pbe_param = sec_pkcs5_create_pbe_parameter(algorithm, salt, iteration);
- if(!pbe_param) {
- return NULL;
- }
-
- poolp = PORT_NewArena(SEC_ASN1_DEFAULT_ARENA_SIZE);
- if(!poolp) {
- sec_pkcs5_destroy_pbe_param(pbe_param);
- return NULL;
- }
-
/* generate the algorithm id */
- algid = (SECAlgorithmID *)PORT_ArenaZAlloc(poolp, sizeof(SECAlgorithmID));
- if(algid != NULL) {
- void *dummy;
- if(!sec_pkcs5_is_algorithm_v2_pkcs12_algorithm(algorithm)) {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_PKCS5PBEParameterTemplate);
- } else {
- dummy = SEC_ASN1EncodeItem(poolp, &der_param, pbe_param,
- SEC_V2PKCS12PBEParameterTemplate);
- }
-
- if(dummy) {
- rv = SECOID_SetAlgorithmID(poolp, algid, algorithm, &der_param);
- }
- }
-
- ret_algid = NULL;
- if(algid != NULL) {
- ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
- if(ret_algid != NULL) {
- rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
- if(rv != SECSuccess) {
- SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
- ret_algid = NULL;
- }
- }
- }
-
- if(poolp != NULL) {
- PORT_FreeArena(poolp, PR_TRUE);
- algid = NULL;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return ret_algid;
-}
-
-/* wrapper for converting the algid to a pbe parameter.
- */
-SEC_PKCS5PBEParameter *
-SEC_PKCS5GetPBEParameter(SECAlgorithmID *algid)
-{
- if(algid) {
- return sec_pkcs5_convert_algid(algid);
- }
-
- return NULL;
-}
-
-/* destroy a pbe parameter */
-void
-SEC_PKCS5DestroyPBEParameter(SEC_PKCS5PBEParameter *pbe_param)
-{
- sec_pkcs5_destroy_pbe_param(pbe_param);
-}
-
-/* return the initialization vector either the preset one if it
- * exists or generated based on pkcs 5.
- *
- * a null length password is allowed...but not a null password
- * secitem.
- */
-SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem *iv;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if((algid == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(!pbe_param) {
- return NULL;
- }
-
- iv = sec_pkcs5_compute_iv(pbe_param, pwitem, faulty3DES);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return iv;
-}
-
-/* generate the key
- * a 0 length password is allowed. corresponds to a key generated
- * from just the salt.
- */
-SECItem *
-SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES)
-{
- SECItem *key;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if((algid == NULL) || (pwitem == NULL)) {
- return NULL;
- }
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL) {
- return NULL;
- }
-
- key = sec_pkcs5_compute_key(pbe_param, pwitem, faulty3DES);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return key;
-}
-
-/* retrieve the salt */
-SECItem *
-SEC_PKCS5GetSalt(SECAlgorithmID *algid)
-{
- SECItem *salt;
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(algid == NULL)
- return NULL;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return NULL;
-
- if(pbe_param->salt.data) {
- salt = SECITEM_DupItem(&pbe_param->salt);
- } else {
- salt = NULL;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return salt;
-}
-
-/* check to see if an oid is a pbe algorithm
- */
-PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid)
-{
- SECOidTag algorithm;
-
- algorithm = SECOID_GetAlgorithmTag(algid);
- if(sec_pkcs5_hash_algorithm(algorithm) == SEC_OID_UNKNOWN) {
- return PR_FALSE;
- }
-
- return PR_TRUE;
-}
-
-int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid)
-{
- SEC_PKCS5PBEParameter *pbe_param;
- int keyLen = -1;
-
- if(algid == NULL)
- return -1;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return -1;
-
- keyLen = sec_pkcs5_key_length(pbe_param->algorithm);
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return keyLen;
-}
-
-/* maps crypto algorithm from PBE algorithm.
- */
-SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid)
-{
- SEC_PKCS5PBEParameter *pbe_param;
-
- if(algid == NULL)
- return SEC_OID_UNKNOWN;
-
- pbe_param = sec_pkcs5_convert_algid(algid);
- if(pbe_param == NULL)
- return SEC_OID_UNKNOWN;
-
- switch(pbe_param->algorithm)
- {
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC:
- return SEC_OID_DES_EDE3_CBC;
- case SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC:
- case SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC:
- return SEC_OID_DES_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC:
- return SEC_OID_RC2_CBC;
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4:
- case SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4:
- case SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4:
- return SEC_OID_RC4;
- default:
- break;
- }
-
- sec_pkcs5_destroy_pbe_param(pbe_param);
-
- return SEC_OID_UNKNOWN;
-}
-
-/* maps PBE algorithm from crypto algorithm, assumes SHA1 hashing.
- */
-SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen)
-{
- switch(algTag)
- {
- case SEC_OID_DES_EDE3_CBC:
- switch(keyLen) {
- case 168:
- case 192:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC;
- case 128:
- case 92:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_DES_CBC:
- return SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC;
- case SEC_OID_RC2_CBC:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC;
- case 128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC;
- default:
- break;
- }
- break;
- case SEC_OID_RC4:
- switch(keyLen) {
- case 40:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4;
- case 128:
- return SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4;
- default:
- break;
- }
- break;
- default:
- break;
- }
-
- return SEC_OID_UNKNOWN;
-}
-
-/* zero length password and salts are allowed. however, the items
- * containing the salt and password must be non-null.
- */
-PBEBitGenContext *
-__PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- PRArenaPool *arena = NULL;
- PBEBitGenContext *pbeCtxt = NULL;
- HASH_HashType pbeHash;
- int vbytes, ubytes;
-
- unsigned int c;
-
- if(!pwitem || !salt) {
- return NULL;
- }
-
- arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
- if(!arena) {
- return NULL;
- }
-
- pbeCtxt = (PBEBitGenContext*)PORT_ArenaZAlloc(arena, sizeof(PBEBitGenContext));
- if(!pbeCtxt) {
+ algid = (SECAlgorithmID *)PORT_ArenaZAlloc(arena, sizeof(SECAlgorithmID));
+ if (algid == NULL) {
goto loser;
}
-
- switch(hashAlgorithm) {
- case SEC_OID_MD2:
- pbeHash = HASH_AlgMD2;
- break;
- case SEC_OID_MD5:
- pbeHash = HASH_AlgMD5;
- break;
- case SEC_OID_SHA1:
- pbeHash = HASH_AlgSHA1;
- break;
- default:
- goto loser;
+ switch (pbe_param->pbeType) {
+ case NSSPKCS5_PBKDF1:
+ dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
+ NSSPKCS5PBEParameterTemplate);
+ break;
+ case NSSPKCS5_PKCS12_V2:
+ dummy = SEC_ASN1EncodeItem(arena, &der_param, pbe_param,
+ NSSPKCS5PKCS12V2PBEParameterTemplate);
+ break;
+ default:
+ break;
}
- pbeCtxt->hashObject = &SECRawHashObjects[pbeHash];
- PORT_Memcpy(&pbeCtxt->pbeParams, &pbeHashAlgorithmParams[pbeHash],
- sizeof(pbeBitGenParameters));
- PORT_Assert(pbeCtxt->pbeParams.hashAlgorithm == hashAlgorithm);
-
- vbytes = pbeCtxt->pbeParams.v / 8;
- ubytes = pbeCtxt->pbeParams.u / 8;
-
- c = (bitsNeeded / pbeCtxt->pbeParams.u);
- c += ((bitsNeeded - (pbeCtxt->pbeParams.u * c)) > 0) ? 1 : 0;
- pbeCtxt->c = c;
- pbeCtxt->n = bitsNeeded;
- pbeCtxt->iterations = iterations;
-
- /* allocate buffers */
- pbeCtxt->D.len = vbytes;
- pbeCtxt->S.len = (((salt->len * 8) / pbeCtxt->pbeParams.v) +
- ((((salt->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) *
- vbytes;
- pbeCtxt->P.len = (((pwitem->len * 8) / pbeCtxt->pbeParams.v) +
- ((((pwitem->len * 8) % pbeCtxt->pbeParams.v) > 0) ? 1 : 0)) *
- vbytes;
- pbeCtxt->I.len = pbeCtxt->S.len + pbeCtxt->P.len;
- pbeCtxt->A.len = c * ubytes;
- pbeCtxt->B.len = pbeCtxt->D.len;
-
- pbeCtxt->D.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->D.len);
- if(pbeCtxt->S.len) {
- pbeCtxt->S.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->S.len);
- }
- if(pbeCtxt->P.len) {
- pbeCtxt->P.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->P.len);
- }
- if(pbeCtxt->I.len) {
- pbeCtxt->I.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->I.len);
- }
- pbeCtxt->A.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->A.len);
- pbeCtxt->B.data = (unsigned char*)PORT_ArenaZAlloc(arena, pbeCtxt->B.len);
-
- if(!pbeCtxt->D.data || !pbeCtxt->A.data || !pbeCtxt->B.data ||
- (!pbeCtxt->S.data && pbeCtxt->S.len) ||
- (!pbeCtxt->P.data && pbeCtxt->P.len) ||
- (!pbeCtxt->I.data && pbeCtxt->I.len)) {
+ if (dummy == NULL) {
goto loser;
}
-
- PORT_Memset(pbeCtxt->D.data, (char)bitGenPurpose, pbeCtxt->D.len);
- if(pbeCtxt->P.len) {
- unsigned int z = 0;
- while(z < pbeCtxt->P.len) {
- PORT_Memcpy(&(pbeCtxt->P.data[z]), pwitem->data,
- ((z + pwitem->len > pbeCtxt->P.len) ? (pbeCtxt->P.len - z) :
- (pwitem->len)));
- z += pwitem->len;
- }
- }
- if(pbeCtxt->S.len) {
- unsigned int z = 0;
- while(z < pbeCtxt->S.len) {
- PORT_Memcpy(&(pbeCtxt->S.data[z]), salt->data,
- ((z + salt->len > pbeCtxt->S.len) ? (pbeCtxt->S.len - z) :
- (salt->len)));
- z += salt->len;
- }
- }
- if(pbeCtxt->I.len) {
- if(pbeCtxt->S.len) {
- PORT_Memcpy(pbeCtxt->I.data, pbeCtxt->S.data, pbeCtxt->S.len);
- }
- if(pbeCtxt->P.len) {
- PORT_Memcpy(&(pbeCtxt->I.data[pbeCtxt->S.len]), pbeCtxt->P.data,
- pbeCtxt->P.len);
- }
- }
-
- pbeCtxt->arena = arena;
-
- return pbeCtxt;
-
-loser:
- if(arena) {
- PORT_FreeArena(arena, PR_TRUE);
- }
-
- return NULL;
-}
-
-PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int iterations)
-{
- return __PBE_CreateContext(hashAlgorithm, bitGenPurpose, pwitem,
- salt, bitsNeeded, iterations);
-}
-
-SECItem *
-__PBE_GenerateBits(PBEBitGenContext *pbeCtxt)
-{
- unsigned int i;
- SECItem *A, *D, *I, *B, *S, *P;
- unsigned int u, v, c, z, hashLen, n, iter;
- unsigned int vbyte, ubyte;
- unsigned char *iterBuf;
- void *hash = NULL;
-
- if(!pbeCtxt) {
- return NULL;
- }
-
- A = &pbeCtxt->A;
- B = &pbeCtxt->B;
- I = &pbeCtxt->I;
- D = &pbeCtxt->D;
- S = &pbeCtxt->S;
- P = &pbeCtxt->P;
- u = pbeCtxt->pbeParams.u;
- v = pbeCtxt->pbeParams.v;
- vbyte = v / 8;
- ubyte = u / 8;
- c = pbeCtxt->c;
- n = pbeCtxt->n;
- z = 0;
-
- iterBuf = (unsigned char*)PORT_Alloc(ubyte);
- if(!iterBuf) {
+
+ rv = SECOID_SetAlgorithmID(arena, algid, algorithm, &der_param);
+ if (rv != SECSuccess) {
goto loser;
}
- for(i = 1; i <= c; i++) {
- unsigned int Bidx;
- unsigned int k, j;
-
-
- for(iter = 1; iter <= pbeCtxt->iterations; iter++) {
- hash = pbeCtxt->hashObject->create();
- if(!hash) {
- goto loser;
- }
-
- pbeCtxt->hashObject->begin(hash);
-
- if(iter == 1) {
- pbeCtxt->hashObject->update(hash, D->data, D->len);
- pbeCtxt->hashObject->update(hash, I->data, I->len);
- } else {
- pbeCtxt->hashObject->update(hash, iterBuf, hashLen);
- }
-
- pbeCtxt->hashObject->end(hash, iterBuf, &hashLen, (ubyte));
- pbeCtxt->hashObject->destroy(hash, PR_TRUE);
- if(hashLen != (ubyte)) {
- goto loser;
- }
- }
-
- PORT_Memcpy(&(A->data[z]), iterBuf, (ubyte));
-
- Bidx = 0;
- while(Bidx < B->len) {
- PORT_Memcpy(&(B->data[Bidx]), &(A->data[z]),
- (((Bidx + (ubyte)) > B->len) ? (B->len - Bidx) :
- (ubyte)));
- Bidx += (ubyte);
- }
-
- k = (S->len / (vbyte)) + (P->len / (vbyte));
- for(j = 0; j < k; j++) {
- unsigned int byteIdx = (vbyte);
- unsigned int q, carryBit = 0;
-
- while(byteIdx > 0) {
- q = (unsigned int)I->data[(j * (vbyte)) + byteIdx - 1];
- q += (unsigned int)B->data[byteIdx - 1];
- q += carryBit;
- if(byteIdx == (vbyte)) {
- q += 1;
- }
-
- carryBit = ((q > 255) ? 1 : 0);
-
- I->data[(j * (vbyte)) + byteIdx - 1] = (unsigned char)(q & 255);
-
- byteIdx--;
- }
- }
-
- z += (ubyte);
- }
-
- A->len = (n / 8);
-
- return SECITEM_DupItem(A);
-
-loser:
- return NULL;
-}
-
-SECItem *
-PBE_GenerateBits(PBEBitGenContext *pbeCtxt)
-{
- return __PBE_GenerateBits(pbeCtxt);
-}
-
-void
-__PBE_DestroyContext(PBEBitGenContext *pbeCtxt)
-{
- if(pbeCtxt) {
- PORT_FreeArena(pbeCtxt->arena, PR_TRUE);
+ ret_algid = (SECAlgorithmID *)PORT_ZAlloc(sizeof(SECAlgorithmID));
+ if (ret_algid == NULL) {
+ goto loser;
}
-}
-
-void
-PBE_DestroyContext(PBEBitGenContext *pbeCtxt)
-{
- __PBE_DestroyContext(pbeCtxt);
-}
-SECStatus
-PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param, PRArenaPool *arena,
- SECAlgorithmID *algId)
-{
- CK_PBE_PARAMS *pbe_param;
- SECItem pbeSalt;
- SECAlgorithmID *pbeAlgID = NULL;
- SECStatus rv;
-
- if(!param || !algId) {
- return SECFailure;
+ rv = SECOID_CopyAlgorithmID(NULL, ret_algid, algid);
+ if (rv != SECSuccess) {
+ SECOID_DestroyAlgorithmID(ret_algid, PR_TRUE);
+ ret_algid = NULL;
}
- pbe_param = (CK_PBE_PARAMS *)param->data;
- pbeSalt.data = (unsigned char *)pbe_param->pSalt;
- pbeSalt.len = pbe_param->ulSaltLen;
- pbeAlgID = SEC_PKCS5CreateAlgorithmID(algTag, &pbeSalt,
- (int)pbe_param->ulIteration);
- if(!pbeAlgID) {
- return SECFailure;
- }
+loser:
- rv = SECOID_CopyAlgorithmID(arena, algId, pbeAlgID);
- SECOID_DestroyAlgorithmID(pbeAlgID, PR_TRUE);
- return rv;
+ return ret_algid;
}
diff --git a/security/nss/lib/softoken/secpkcs5.h b/security/nss/lib/softoken/secpkcs5.h
index d538450dd..8ddee11a6 100644
--- a/security/nss/lib/softoken/secpkcs5.h
+++ b/security/nss/lib/softoken/secpkcs5.h
@@ -50,36 +50,28 @@ typedef enum {
pbeBitGenIntegrityKey = 0x03
} PBEBitGenID;
-typedef struct _pbeBitGenParameters {
- unsigned int u, v;
- SECOidTag hashAlgorithm;
-} pbeBitGenParameters;
-
-typedef struct _PBEBitGenContext {
- PRArenaPool *arena;
-
- /* hash algorithm information */
- pbeBitGenParameters pbeParams;
- const SECHashObject *hashObject;
- void *hash;
-
- /* buffers used in generation of bits */
- SECItem D, S, P, I, A, B;
- unsigned int c, n;
- unsigned int iterations;
-} PBEBitGenContext;
+typedef enum {
+ NSSPKCS5_PBKDF1 = 0,
+ NSSPKCS5_PBKDF2 = 1,
+ NSSPKCS5_PKCS12_V2 = 2
+} NSSPKCS5PBEType;
-extern const SEC_ASN1Template SEC_PKCS5PBEParameterTemplate[];
-typedef struct SEC_PKCS5PBEParameterStr SEC_PKCS5PBEParameter;
+typedef struct NSSPKCS5PBEParameterStr NSSPKCS5PBEParameter;
-struct SEC_PKCS5PBEParameterStr {
+struct NSSPKCS5PBEParameterStr {
PRArenaPool *poolp;
SECItem salt; /* octet string */
SECItem iteration; /* integer */
/* used locally */
- SECOidTag algorithm;
int iter;
+ int keyLen;
+ int ivLen;
+ HASH_HashType hashType;
+ NSSPKCS5PBEType pbeType;
+ PBEBitGenID keyID;
+ SECOidTag encAlg;
+ PRBool is2KeyDES;
};
@@ -87,46 +79,32 @@ SEC_BEGIN_PROTOS
/* Create a PKCS5 Algorithm ID
* The algorithm ID is set up using the PKCS #5 parameter structure
* algorithm is the PBE algorithm ID for the desired algorithm
- * salt can be specified or can be NULL, if salt is NULL then the
- * salt is generated from random bytes
- * iteration is the number of iterations for which to perform the
- * hash prior to key and iv generation.
+ * pbe is a pbe param block with all the info needed to create the
+ * algorithm id.
* If an error occurs or the algorithm specified is not supported
* or is not a password based encryption algorithm, NULL is returned.
* Otherwise, a pointer to the algorithm id is returned.
*/
extern SECAlgorithmID *
-SEC_PKCS5CreateAlgorithmID(SECOidTag algorithm,
- SECItem *salt,
- int iteration);
-
-/* Get the initialization vector. The password is passed in, hashing
- * is performed, and the initialization vector is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the iv is returned in a secitem.
- */
-extern SECItem *
-SEC_PKCS5GetIV(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
-
-/* Get the key. The password is passed in, hashing is performed,
- * and the key is returned.
- * algid is a pointer to a PBE algorithm ID
- * pwitem is the password
- * If an error occurs or the algorithm id is not a PBE algrithm,
- * NULL is returned. Otherwise, the key is returned in a secitem.
+nsspkcs5_CreateAlgorithmID(PRArenaPool *arena, SECOidTag algorithm,
+ NSSPKCS5PBEParameter *pbe);
+
+/*
+ * Convert an Algorithm ID to a PBE Param.
+ * NOTE: this does not suppport PKCS 5 v2 because it's only used for the
+ * keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
*/
-extern SECItem *
-SEC_PKCS5GetKey(SECAlgorithmID *algid, SECItem *pwitem, PRBool faulty3DES);
+NSSPKCS5PBEParameter *
+nsspkcs5_AlgidToParam(SECAlgorithmID *algid);
-/* Get PBE salt. The salt for the password based algorithm is returned.
- * algid is the PBE algorithm identifier
- * If an error occurs NULL is returned, otherwise the salt is returned
- * in a SECItem.
+/*
+ * Convert an Algorithm ID to a PBE Param.
+ * NOTE: this does not suppport PKCS 5 v2 because it's only used for the
+ * keyDB which only support PKCS 5 v1, PFX, and PKCS 12.
*/
-extern SECItem *
-SEC_PKCS5GetSalt(SECAlgorithmID *algid);
+NSSPKCS5PBEParameter *
+nsspkcs5_NewParam(SECOidTag alg, SECItem *salt, int iterator);
+
/* Encrypt/Decrypt data using password based encryption.
* algid is the PBE algorithm identifier,
@@ -138,48 +116,17 @@ SEC_PKCS5GetSalt(SECAlgorithmID *algid);
* is returned, otherwise the ciphered contents is returned.
*/
extern SECItem *
-SEC_PKCS5CipherData(SECAlgorithmID *algid, SECItem *pwitem,
+nsspkcs5_CipherData(NSSPKCS5PBEParameter *, SECItem *pwitem,
SECItem *src, PRBool encrypt, PRBool *update);
-/* Checks to see if algid algorithm is a PBE algorithm. If
- * so, PR_TRUE is returned, otherwise PR_FALSE is returned.
- */
-extern PRBool
-SEC_PKCS5IsAlgorithmPBEAlg(SECAlgorithmID *algid);
+extern SECItem *
+nsspkcs5_ComputeKeyAndIV(NSSPKCS5PBEParameter *, SECItem *pwitem,
+ SECItem *iv, PRBool faulty3DES);
/* Destroys PBE parameter */
extern void
-SEC_PKCS5DestroyPBEParameter(SEC_PKCS5PBEParameter *param);
-
-/* Convert Algorithm ID to PBE parameter */
-extern SEC_PKCS5PBEParameter *
-SEC_PKCS5GetPBEParameter(SECAlgorithmID *algid);
-
-/* Determine how large the key generated is */
-extern int
-SEC_PKCS5GetKeyLength(SECAlgorithmID *algid);
-
-/* map crypto algorithm to pbe algorithm, assume sha 1 hashing for DES
- */
-extern SECOidTag
-SEC_PKCS5GetPBEAlgorithm(SECOidTag algTag, int keyLen);
-
-/* return the underlying crypto algorithm */
-extern SECOidTag
-SEC_PKCS5GetCryptoAlgorithm(SECAlgorithmID *algid);
-
-extern PBEBitGenContext *
-PBE_CreateContext(SECOidTag hashAlgorithm, PBEBitGenID bitGenPurpose,
- SECItem *pwitem, SECItem *salt, unsigned int bitsNeeded,
- unsigned int interations);
-
-extern SECItem *
-PBE_GenerateBits(PBEBitGenContext *pbeCtxt);
-
-extern void PBE_DestroyContext(PBEBitGenContext *pbeCtxt);
+nsspkcs5_DestroyPBEParameter(NSSPKCS5PBEParameter *param);
-extern SECStatus PBE_PK11ParamToAlgid(SECOidTag algTag, SECItem *param,
- PRArenaPool *arena, SECAlgorithmID *algId);
SEC_END_PROTOS
#endif
diff --git a/security/nss/lib/ssl/ssl3con.c b/security/nss/lib/ssl/ssl3con.c
index 98867bb0b..86f5638d9 100644
--- a/security/nss/lib/ssl/ssl3con.c
+++ b/security/nss/lib/ssl/ssl3con.c
@@ -65,7 +65,8 @@
#endif
static PK11SymKey *ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot);
+ PK11SlotInfo * serverKeySlot,
+ PRBool isTls);
static SECStatus ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms);
static SECStatus ssl3_HandshakeFailure( sslSocket *ss);
static SECStatus ssl3_InitState( sslSocket *ss);
@@ -2023,7 +2024,7 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
if (pwSpec->master_secret == NULL) {
/* Generate a faux master secret in the same slot as the old one. */
PK11SlotInfo * slot = PK11_GetSlotFromKey((PK11SymKey *)pms);
- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
+ PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot, isTLS);
PK11_FreeSlot(slot);
if (fpms != NULL) {
@@ -2037,7 +2038,7 @@ ssl3_GenerateSessionKeys(sslSocket *ss, const PK11SymKey *pms)
if (pwSpec->master_secret == NULL) {
/* Generate a faux master secret from the internal slot. */
PK11SlotInfo * slot = PK11_GetInternalSlot();
- PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot);
+ PK11SymKey * fpms = ssl3_GenerateRSAPMS(ss, pwSpec, slot, isTLS);
PK11_FreeSlot(slot);
if (fpms != NULL) {
@@ -3183,7 +3184,7 @@ sendRSAClientKeyExchange(sslSocket * ss, SECKEYPublicKey * svrPubKey)
ssl_GetSpecWriteLock(ss);
isTLS = (PRBool)(ss->ssl3->pwSpec->version > SSL_LIBRARY_VERSION_3_0);
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->pwSpec, NULL);
+ pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->pwSpec, NULL, isTLS);
ssl_ReleaseSpecWriteLock(ss);
if (pms == NULL) {
ssl_MapLowLevelError(SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE);
@@ -4267,7 +4268,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
peerKey->arena = arena;
peerKey->keyType = rsaKey;
peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_KEY;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
if (SECITEM_CopyItem(arena, &peerKey->u.rsa.modulus, &modulus) ||
SECITEM_CopyItem(arena, &peerKey->u.rsa.publicExponent, &exponent))
{
@@ -4349,7 +4350,7 @@ ssl3_HandleServerKeyExchange(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
peerKey->arena = arena;
peerKey->keyType = dhKey;
peerKey->pkcs11Slot = NULL;
- peerKey->pkcs11ID = CK_INVALID_KEY;
+ peerKey->pkcs11ID = CK_INVALID_HANDLE;
if (SECITEM_CopyItem(arena, &peerKey->u.dh.prime, &dh_p) ||
SECITEM_CopyItem(arena, &peerKey->u.dh.base, &dh_g) ||
@@ -6059,7 +6060,7 @@ fortezza_loser:
*/
static PK11SymKey *
ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
- PK11SlotInfo * serverKeySlot)
+ PK11SlotInfo * serverKeySlot, PRBool isTLS)
{
PK11SymKey * pms = NULL;
PK11SlotInfo * slot = serverKeySlot;
@@ -6067,9 +6068,12 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
SECItem param;
CK_VERSION version;
CK_MECHANISM_TYPE mechanism_array[3];
+ CK_MECHANISM_TYPE keygen;
PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
+ keygen = isTLS ? CKM_TLS_PRE_MASTER_KEY_GEN: CKM_SSL3_PRE_MASTER_KEY_GEN;
+
if (slot == NULL) {
SSLCipherAlgorithm calg;
/* The specReadLock would suffice here, but we cannot assert on
@@ -6083,7 +6087,7 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
PORT_Assert(alg2Mech[calg].calg == calg);
/* First get an appropriate slot. */
- mechanism_array[0] = CKM_SSL3_PRE_MASTER_KEY_GEN;
+ mechanism_array[0] = keygen;
mechanism_array[1] = CKM_RSA_PKCS;
mechanism_array[2] = alg2Mech[calg].cmech;
@@ -6105,7 +6109,7 @@ ssl3_GenerateRSAPMS(sslSocket *ss, ssl3CipherSpec *spec,
param.data = (unsigned char *)&version;
param.len = sizeof version;
- pms = PK11_KeyGen(slot, CKM_SSL3_PRE_MASTER_KEY_GEN, &param, 0, pwArg);
+ pms = PK11_KeyGen(slot, keygen, &param, 0, pwArg);
if (!serverKeySlot)
PK11_FreeSlot(slot);
if (pms == NULL) {
@@ -6135,6 +6139,7 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
PK11SymKey * pms;
SECStatus rv;
SECItem enc_pms;
+ PRBool isTLS = PR_FALSE;
PORT_Assert( ssl_HaveRecvBufLock(ss) );
PORT_Assert( ssl_HaveSSL3HandshakeLock(ss) );
@@ -6152,6 +6157,7 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
if ((unsigned)kLen < enc_pms.len) {
enc_pms.len = kLen;
}
+ isTLS = PR_TRUE;
}
/*
* decrypt pms out of the incoming buffer
@@ -6170,7 +6176,7 @@ ssl3_HandleRSAClientKeyExchange(sslSocket *ss,
PK11SlotInfo * slot = PK11_GetSlotFromPrivateKey(serverKey);
ssl_GetSpecWriteLock(ss);
- pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->prSpec, slot);
+ pms = ssl3_GenerateRSAPMS(ss, ss->ssl3->prSpec, slot, isTLS);
ssl_ReleaseSpecWriteLock(ss);
PK11_FreeSlot(slot);
@@ -6447,8 +6453,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
if (rv != SECSuccess)
goto loser; /* fatal alert already sent by ConsumeHandshake. */
- sec->peerCert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
+ sec->peerCert = CERT_DecodeDERCertificate(&certItem, NULL, PR_FALSE);
if (sec->peerCert == NULL) {
/* We should report an alert if the cert was bad, but not if the
* problem was just some local problem, like memory error.
@@ -6486,8 +6491,7 @@ ssl3_HandleCertificate(sslSocket *ss, SSL3Opaque *b, PRUint32 length)
goto loser; /* don't send alerts on memory errors */
}
- c->cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
+ c->cert = CERT_DecodeDERCertificate(&certItem, NULL, PR_FALSE);
if (c->cert == NULL) {
goto ambiguous_err;
}
diff --git a/security/nss/lib/ssl/sslcon.c b/security/nss/lib/ssl/sslcon.c
index cc9d48b09..cf24c1198 100644
--- a/security/nss/lib/ssl/sslcon.c
+++ b/security/nss/lib/ssl/sslcon.c
@@ -1964,8 +1964,7 @@ ssl2_ClientHandleServerCert(sslSocket *ss, PRUint8 *certData, int certLen)
certItem.len = certLen;
/* decode the certificate */
- cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(&certItem, NULL, PR_FALSE);
if (cert == NULL) {
SSL_DBG(("%d: SSL[%d]: decode of server certificate fails",
@@ -2472,8 +2471,7 @@ ssl2_HandleClientCertificate(sslSocket * ss,
certItem.data = cd;
certItem.len = cdLen;
- cert = CERT_NewTempCertificate(ss->dbHandle, &certItem, NULL,
- PR_FALSE, PR_TRUE);
+ cert = CERT_DecodeDERCertificate(&certItem, NULL, PR_FALSE);
if (cert == NULL) {
goto loser;
}
diff --git a/security/nss/lib/ssl/sslsnce.c b/security/nss/lib/ssl/sslsnce.c
index 9eca3b22b..7515a57f8 100644
--- a/security/nss/lib/ssl/sslsnce.c
+++ b/security/nss/lib/ssl/sslsnce.c
@@ -548,8 +548,7 @@ ConvertToSID(sidCacheEntry *from, certCacheEntry *pcce,
derCert.len = pcce->certLength;
derCert.data = pcce->cert;
- to->peerCert = CERT_NewTempCertificate(dbHandle, &derCert, NULL,
- PR_FALSE, PR_TRUE);
+ to->peerCert = CERT_DecodeDERCertificate(&derCert, NULL, PR_FALSE);
if (to->peerCert == NULL)
goto loser;
}
diff --git a/security/nss/lib/util/secitem.c b/security/nss/lib/util/secitem.c
index fd7e83464..ded548a00 100644
--- a/security/nss/lib/util/secitem.c
+++ b/security/nss/lib/util/secitem.c
@@ -240,3 +240,45 @@ SECITEM_ZfreeItem(SECItem *zap, PRBool freeit)
}
}
}
+/* these reroutines were taken from pkix oid.c, which is supposed to
+ * replace this file some day */
+/*
+ * This is the hash function. We simply XOR the encoded form with
+ * itself in sizeof(PLHashNumber)-byte chunks. Improving this
+ * routine is left as an excercise for the more mathematically
+ * inclined student.
+ */
+PLHashNumber PR_CALLBACK
+SECITEM_Hash ( const void *key)
+{
+ const SECItem *item = (const SECItem *)key;
+ PLHashNumber rv = 0;
+
+ PRUint8 *data = (PRUint8 *)item->data;
+ PRUint32 i;
+ PRUint8 *rvc = (PRUint8 *)&rv;
+
+ for( i = 0; i < item->len; i++ ) {
+ rvc[ i % sizeof(rv) ] ^= *data;
+ data++;
+ }
+
+ return rv;
+}
+
+/*
+ * This is the key-compare function. It simply does a lexical
+ * comparison on the item data. This does not result in
+ * quite the same ordering as the "sequence of numbers" order,
+ * but heck it's only used internally by the hash table anyway.
+ */
+PRIntn PR_CALLBACK
+SECITEM_HashCompare ( const void *k1, const void *k2)
+{
+ PRIntn rv;
+
+ const SECItem *i1 = (const SECItem *)k1;
+ const SECItem *i2 = (const SECItem *)k2;
+
+ return SECITEM_ItemsAreEqual(i1,i2);
+}
diff --git a/security/nss/lib/util/secitem.h b/security/nss/lib/util/secitem.h
index 3928cad98..76a5d16fb 100644
--- a/security/nss/lib/util/secitem.h
+++ b/security/nss/lib/util/secitem.h
@@ -41,6 +41,7 @@
*/
#include "plarena.h"
+#include "plhash.h"
#include "seccomon.h"
SEC_BEGIN_PROTOS
@@ -101,6 +102,11 @@ extern void SECITEM_FreeItem(SECItem *zap, PRBool freeit);
*/
extern void SECITEM_ZfreeItem(SECItem *zap, PRBool freeit);
+PLHashNumber PR_CALLBACK SECITEM_Hash ( const void *key);
+
+PRIntn PR_CALLBACK SECITEM_HashCompare ( const void *k1, const void *k2);
+
+
SEC_END_PROTOS
#endif /* _SECITEM_H_ */
diff --git a/security/nss/lib/util/secoid.c b/security/nss/lib/util/secoid.c
index 0044c83f0..baebc5322 100644
--- a/security/nss/lib/util/secoid.c
+++ b/security/nss/lib/util/secoid.c
@@ -32,11 +32,11 @@
*/
#include "secoid.h"
-#include "mcom_db.h"
#include "pkcs11t.h"
#include "secmodt.h"
#include "secitem.h"
#include "secerr.h"
+#include "plhash.h"
/* MISSI Mosaic Object ID space */
#define MISSI 0x60, 0x86, 0x48, 0x01, 0x65, 0x02, 0x01, 0x01
@@ -1222,7 +1222,7 @@ static SECOidData oids[] = {
* and gets modified if the user loads new crypto modules.
*/
-static DB *oid_d_hash = 0;
+static PLHashTable *oid_d_hash = 0;
static SECOidData **secoidDynamicTable = NULL;
static int secoidDynamicTableSize = 0;
static int secoidLastDynamicEntry = 0;
@@ -1231,15 +1231,14 @@ static int secoidLastHashEntry = 0;
static SECStatus
secoid_DynamicRehash(void)
{
- DBT key;
- DBT data;
- int rv;
SECOidData *oid;
+ PLHashEntry *entry;
int i;
int last = secoidLastDynamicEntry;
if (!oid_d_hash) {
- oid_d_hash = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 );
+ oid_d_hash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ PL_CompareValues, NULL, NULL);
}
@@ -1251,18 +1250,8 @@ secoid_DynamicRehash(void)
for ( i = secoidLastHashEntry; i < last; i++ ) {
oid = secoidDynamicTable[i];
- /* invalid assert ... guarrenteed not to be true */
- /* PORT_Assert ( oid->offset == i ); */
-
- key.data = oid->oid.data;
- key.size = oid->oid.len;
-
- data.data = &oid;
- data.size = sizeof(oid);
-
- rv = (* oid_d_hash->put)( oid_d_hash, &key, &data, R_NOOVERWRITE );
- if ( rv ) {
- PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ entry = PL_HashTableAdd( oid_d_hash, &oid->oid.data, oid );
+ if ( entry == NULL ) {
return(SECFailure);
}
}
@@ -1270,24 +1259,29 @@ secoid_DynamicRehash(void)
return(SECSuccess);
}
+
+
/*
* Lookup a Dynamic OID. Dynamic OID's still change slowly, so it's
* cheaper to rehash the table when it changes than it is to do the loop
* each time. Worry: what about thread safety here? Global Static data with
* no locks.... (sigh).
*/
-static SECStatus
-secoid_FindDynamic(DBT *key, DBT *data) {
+static SECOidData *
+secoid_FindDynamic(SECItem *key) {
+ SECOidData *ret = NULL;
if (secoidDynamicTable == NULL) {
- return SECFailure;
+ /* PORT_SetError! */
+ return NULL;
}
if (secoidLastHashEntry != secoidLastDynamicEntry) {
SECStatus rv = secoid_DynamicRehash();
if ( rv != SECSuccess ) {
- return rv;
+ return NULL;
}
}
- return (SECStatus)(* oid_d_hash->get)( oid_d_hash, key, data, 0 );
+ ret = (SECOidData *)PL_HashTableLookup (oid_d_hash, key);
+ return ret;
}
@@ -1364,20 +1358,22 @@ SECOID_AddEntry(SECItem *oid, char *description, unsigned long mech) {
/* normal static table processing */
-static DB *oidhash = NULL;
-static DB *oidmechhash = NULL;
+static PLHashTable *oidhash = NULL;
+static PLHashTable *oidmechhash = NULL;
static SECStatus
InitOIDHash(void)
{
- DBT key;
- DBT data;
+ SECItem key;
+ PLHashEntry *entry;
int rv;
SECOidData *oid;
int i;
- oidhash = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 );
- oidmechhash = dbopen( 0, O_RDWR | O_CREAT, 0600, DB_HASH, 0 );
+ oidhash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ PL_CompareValues, NULL, NULL);
+ oidmechhash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ PL_CompareValues, NULL, NULL);
if ( !oidhash || !oidmechhash) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
@@ -1390,29 +1386,19 @@ InitOIDHash(void)
PORT_Assert ( oid->offset == i );
- key.data = oid->oid.data;
- key.size = oid->oid.len;
-
- data.data = &oid;
- data.size = sizeof(oid);
-
- rv = (* oidhash->put)( oidhash, &key, &data, R_NOOVERWRITE );
- if ( rv ) {
+ entry = PL_HashTableAdd( oidhash, &oid->oid.data, oid );
+ if ( entry == NULL ) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0); /*This function should never fail. */
return(SECFailure);
}
if ( oid->mechanism != CKM_INVALID_MECHANISM ) {
- key.data = &oid->mechanism;
- key.size = sizeof(oid->mechanism);
-
- rv = (* oidmechhash->put)( oidmechhash, &key, &data, R_NOOVERWRITE);
- /* Only error out if the error value returned is not
- * RET_SPECIAL, ie the mechanism already has a registered
- * OID.
- */
- if ( rv && rv != RET_SPECIAL) {
+ key.data = (unsigned char *)&oid->mechanism;
+ key.len = sizeof(oid->mechanism);
+
+ entry = PL_HashTableAdd( oidmechhash, &key, oid );
+ if ( entry ) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
PORT_Assert(0); /* This function should never fail. */
return(SECFailure);
@@ -1428,8 +1414,7 @@ InitOIDHash(void)
SECOidData *
SECOID_FindOIDByMechanism(unsigned long mechanism)
{
- DBT key;
- DBT data;
+ SECItem key;
SECOidData *ret;
int rv;
@@ -1440,15 +1425,13 @@ SECOID_FindOIDByMechanism(unsigned long mechanism)
return NULL;
}
}
- key.data = &mechanism;
- key.size = sizeof(mechanism);
+ key.data = (unsigned char *)&mechanism;
+ key.len = sizeof(mechanism);
- rv = (* oidmechhash->get)( oidmechhash, &key, &data, 0 );
- if ( rv || ( data.size != sizeof(unsigned long) ) ) {
+ ret = PL_HashTableLookup ( oidmechhash, &key);
+ if ( ret == NULL ) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return NULL;
}
- PORT_Memcpy(&ret, data.data, data.size);
return (ret);
}
@@ -1456,8 +1439,6 @@ SECOID_FindOIDByMechanism(unsigned long mechanism)
SECOidData *
SECOID_FindOID(SECItem *oid)
{
- DBT key;
- DBT data;
SECOidData *ret;
int rv;
@@ -1469,20 +1450,14 @@ SECOID_FindOID(SECItem *oid)
}
}
- key.data = oid->data;
- key.size = oid->len;
-
- rv = (* oidhash->get)( oidhash, &key, &data, 0 );
- if ( rv || ( data.size != sizeof(SECOidData*) ) ) {
- rv = secoid_FindDynamic(&key, &data);
- if (rv != SECSuccess) {
+ ret = PL_HashTableLookup ( oidhash, oid );
+ if ( ret == NULL ) {
+ ret = secoid_FindDynamic(oid);
+ if (ret == NULL) {
PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
- return(0);
}
}
- PORT_Memcpy(&ret, data.data, data.size);
-
return(ret);
}
@@ -1538,13 +1513,29 @@ SECOID_FindOIDTagDescription(SECOidTag tagnum)
SECStatus
SECOID_Shutdown(void)
{
+ int i;
+
if (oidhash) {
- (oidhash->close)(oidhash);
+ PL_HashTableDestroy(oidhash);
oidhash = NULL;
}
if (oidmechhash) {
- (oidmechhash->close)(oidmechhash);
+ PL_HashTableDestroy(oidmechhash);
oidmechhash = NULL;
}
+ if (oid_d_hash) {
+ PL_HashTableDestroy(oid_d_hash);
+ oid_d_hash = NULL;
+ }
+ if (secoidDynamicTable) {
+ for (i=0; i < secoidLastDynamicEntry; i++) {
+ PORT_Free(secoidDynamicTable[i]);
+ }
+ PORT_Free(secoidDynamicTable);
+ secoidDynamicTable = NULL;
+ secoidDynamicTableSize = 0;
+ secoidLastDynamicEntry = 0;
+ secoidLastHashEntry = 0;
+ }
return SECSuccess;
}