summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorrelyea%netscape.com <devnull@localhost>2002-08-14 20:42:40 +0000
committerrelyea%netscape.com <devnull@localhost>2002-08-14 20:42:40 +0000
commit1cb2645faa330598fcc31ebb2f125944ea53bec8 (patch)
treeb4f6f0aa33a43fe48f9abafe98109c31acd72fb7
parentfee364aaab5a29cdfb1bdc17fa12812834d1c16a (diff)
downloadnss-hg-1cb2645faa330598fcc31ebb2f125944ea53bec8.tar.gz
bug 161552: Make the recipient list traversal functions call the internal
nsstoken_FindCertByIssuerAndSN() function to gain the benefit of the fixed Searching code.
-rw-r--r--security/nss/lib/certdb/certdb.c4
-rw-r--r--security/nss/lib/dev/devtoken.c19
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c282
3 files changed, 160 insertions, 145 deletions
diff --git a/security/nss/lib/certdb/certdb.c b/security/nss/lib/certdb/certdb.c
index 007747be6..b014b39f1 100644
--- a/security/nss/lib/certdb/certdb.c
+++ b/security/nss/lib/certdb/certdb.c
@@ -222,6 +222,10 @@ CERT_KeyFromIssuerAndSN(PRArenaPool *arena, SECItem *issuer, SECItem *sn,
SECItem *key)
{
key->len = sn->len + issuer->len;
+
+ if ((sn->data == NULL) || (issuer->data == NULL)) {
+ goto loser;
+ }
key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
if ( !key->data ) {
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index 46c420560..8069e2284 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -883,7 +883,8 @@ nssToken_FindCertificateByIssuerAndSerialNumber
/* Set the search to token/session only if provided */
if (searchType == nssTokenSearchType_SessionOnly) {
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
- } else if (searchType == nssTokenSearchType_TokenOnly) {
+ } else if ((searchType == nssTokenSearchType_TokenOnly) ||
+ (searchType == nssTokenSearchType_TokenForced)) {
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
}
/* Set the unique id */
@@ -893,9 +894,15 @@ nssToken_FindCertificateByIssuerAndSerialNumber
NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SERIAL_NUMBER, serial);
NSS_CK_TEMPLATE_FINISH(cert_template, attr, ctsize);
/* get the object handle */
- objects = find_objects_by_template(token, sessionOpt,
+ if (searchType == nssTokenSearchType_TokenForced) {
+ objects = find_objects(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
+ } else {
+ objects = find_objects_by_template(token, sessionOpt,
cert_template, ctsize,
1, statusOpt);
+ }
if (objects) {
rvObject = objects[0];
nss_ZFreeIf(objects);
@@ -914,9 +921,15 @@ nssToken_FindCertificateByIssuerAndSerialNumber
return NULL;
}
NSS_CK_SET_ATTRIBUTE_ITEM(serialAttr,CKA_SERIAL_NUMBER,&serialDecode);
- objects = find_objects_by_template(token, sessionOpt,
+ if (searchType == nssTokenSearchType_TokenForced) {
+ objects = find_objects(token, sessionOpt,
+ cert_template, ctsize,
+ 1, statusOpt);
+ } else {
+ objects = find_objects_by_template(token, sessionOpt,
cert_template, ctsize,
1, statusOpt);
+ }
if (objects) {
rvObject = objects[0];
nss_ZFreeIf(objects);
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index 45bf5cd7f..54d122cc1 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -64,6 +64,7 @@
#include "pkim.h"
#include "pkitm.h"
#include "pkistore.h" /* to remove temp cert */
+#include "devt.h"
#define PK11_SEARCH_CHUNKSIZE 10
@@ -2014,6 +2015,84 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
return certHandle;
}
+CERTCertificate *
+PK11_FindCertByIssuerAndSNOnToken(PK11SlotInfo *slot,
+ CERTIssuerAndSN *issuerSN, void *wincx)
+{
+ CERTCertificate *rvCert = NULL;
+ NSSCertificate *cert = NULL;
+ NSSDER issuer, serial;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
+ NSSToken *token = slot->nssToken;
+ nssSession *session;
+ nssCryptokiObject *instance = NULL;
+ nssPKIObject *object = NULL;
+ SECItem *derSerial;
+ PRStatus status;
+
+ /* Paranoia */
+ if (token == NULL) {
+ PORT_SetError(SEC_ERROR_NO_TOKEN);
+ return NULL;
+ }
+
+
+ /* PKCS#11 needs to use DER-encoded serial numbers. Create a
+ * CERTIssuerAndSN that actually has the encoded value and pass that
+ * to PKCS#11 (and the crypto context).
+ */
+ derSerial = SEC_ASN1EncodeItem(NULL, NULL,
+ &issuerSN->serialNumber,
+ SEC_IntegerTemplate);
+ if (!derSerial) {
+ return NULL;
+ }
+
+ NSSITEM_FROM_SECITEM(&issuer, &issuerSN->derIssuer);
+ NSSITEM_FROM_SECITEM(&serial, derSerial);
+
+ session = nssToken_GetDefaultSession(token);
+ if (!session) {
+ goto loser;
+ }
+
+ instance = nssToken_FindCertificateByIssuerAndSerialNumber(token,session,
+ &issuer, &serial, nssTokenSearchType_TokenForced, &status);
+
+ SECITEM_FreeItem(derSerial, PR_TRUE);
+
+ if (!instance) {
+ goto loser;
+ }
+ object = nssPKIObject_Create(NULL, instance, td, NULL);
+ if (!object) {
+ goto loser;
+ }
+ instance = NULL; /* adopted by the previous call */
+ cert = nssCertificate_Create(object);
+ if (!cert) {
+ goto loser;
+ }
+ object = NULL; /* adopted by the previous call */
+ nssTrustDomain_AddCertsToCache(td, &cert,1);
+ rvCert = STAN_GetCERTCertificate(cert);
+ if (!rvCert) {
+ goto loser;
+ }
+ return rvCert;
+
+loser:
+ if (instance) {
+ nssCryptokiObject_Destroy(instance);
+ }
+ if (object) {
+ nssPKIObject_Destroy(object);
+ }
+ if (cert) {
+ nssCertificate_Destroy(cert);
+ }
+ return NULL;
+}
/*
* We're looking for a cert which we have the private key for that's on the
@@ -2022,57 +2101,28 @@ pk11_FindCertObjectByTemplate(PK11SlotInfo **slotPtr,
* this stuff should REALLY be in the SMIME code, but some things in here are not public
* (they should be!)
*/
-static CK_OBJECT_HANDLE
-pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist, int *rlIndex)
+static CERTCertificate *
+pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipientlist, int *rlIndex, void *pwarg)
{
- CK_OBJECT_HANDLE certHandle;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_OBJECT_CLASS peerClass ;
- CK_ATTRIBUTE searchTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0}
- };
- int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE);
NSSCMSRecipient *ri = NULL;
- CK_ATTRIBUTE *attrs;
int i;
- peerClass = CKO_PRIVATE_KEY;
- if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) {
- peerClass = CKO_PUBLIC_KEY;
- }
-
for (i=0; (ri = recipientlist[i]) != NULL; i++) {
+ CERTCertificate *cert = NULL;
/* XXXXX fixme - not yet implemented! */
if (ri->kind == RLSubjKeyID)
continue;
-
- attrs = searchTemplate;
-
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass,sizeof(certClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_ISSUER, ri->id.issuerAndSN->derIssuer.data,
- ri->id.issuerAndSN->derIssuer.len); attrs++;
- PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER,
- ri->id.issuerAndSN->serialNumber.data,ri->id.issuerAndSN->serialNumber.len);
-
- certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count);
- 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
- * associated with it... */
- ri->slot = PK11_ReferenceSlot(slot);
- *rlIndex = i;
-
- CERT_DestroyCertificate(cert);
- return certHandle;
- }
- CERT_DestroyCertificate(cert);
+ cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->id.issuerAndSN,
+ pwarg);
+ if (cert) {
+ ri->slot = PK11_ReferenceSlot(slot);
+ *rlIndex = i;
+ return cert;
}
+
}
*rlIndex = -1;
- return CK_INVALID_HANDLE;
+ return NULL;
}
/*
@@ -2081,12 +2131,12 @@ pk11_FindCertObjectByRecipientNew(PK11SlotInfo *slot, NSSCMSRecipient **recipien
* this stuff should REALLY be in the SMIME code, but some things in here are not public
* (they should be!)
*/
-static CK_OBJECT_HANDLE
+static CERTCertificate *
pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *wincx, int *rlIndex)
{
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
+ CERTCertificate *cert = NULL;
SECStatus rv;
/* get them all! */
@@ -2103,80 +2153,54 @@ pk11_AllFindCertObjectByRecipientNew(NSSCMSRecipient **recipientlist, void *winc
if (rv != SECSuccess) continue;
}
- certHandle = pk11_FindCertObjectByRecipientNew(le->slot, recipientlist, rlIndex);
- if (certHandle != CK_INVALID_HANDLE)
+ cert = pk11_FindCertObjectByRecipientNew(le->slot,
+ recipientlist, rlIndex, wincx);
+ if (cert)
break;
}
PK11_FreeSlotList(list);
- return (le == NULL) ? CK_INVALID_HANDLE : certHandle;
+ return cert;
}
/*
* We're looking for a cert which we have the private key for that's on the
* list of recipients. This searches one slot.
*/
-static CK_OBJECT_HANDLE
+static CERTCertificate *
pk11_FindCertObjectByRecipient(PK11SlotInfo *slot,
- SEC_PKCS7RecipientInfo **recipientArray,SEC_PKCS7RecipientInfo **rip)
+ SEC_PKCS7RecipientInfo **recipientArray,
+ SEC_PKCS7RecipientInfo **rip, void *pwarg)
{
- CK_OBJECT_HANDLE certHandle;
- CK_OBJECT_CLASS certClass = CKO_CERTIFICATE;
- CK_OBJECT_CLASS peerClass ;
- CK_ATTRIBUTE searchTemplate[] = {
- { CKA_CLASS, NULL, 0 },
- { CKA_ISSUER, NULL, 0 },
- { CKA_SERIAL_NUMBER, NULL, 0}
- };
- int count = sizeof(searchTemplate)/sizeof(CK_ATTRIBUTE);
SEC_PKCS7RecipientInfo *ri = NULL;
- CK_ATTRIBUTE *attrs;
int i;
-
- peerClass = CKO_PRIVATE_KEY;
- if (!PK11_IsLoggedIn(slot,NULL) && PK11_NeedLogin(slot)) {
- peerClass = CKO_PUBLIC_KEY;
- }
-
for (i=0; (ri = recipientArray[i]) != NULL; i++) {
- attrs = searchTemplate;
+ CERTCertificate *cert;
- PK11_SETATTRS(attrs, CKA_CLASS, &certClass,sizeof(certClass)); attrs++;
- PK11_SETATTRS(attrs, CKA_ISSUER, ri->issuerAndSN->derIssuer.data,
- ri->issuerAndSN->derIssuer.len); attrs++;
- PK11_SETATTRS(attrs, CKA_SERIAL_NUMBER,
- ri->issuerAndSN->serialNumber.data,ri->issuerAndSN->serialNumber.len);
-
- certHandle = pk11_FindObjectByTemplate(slot,searchTemplate,count);
- 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
- * associated with it... */
- *rip = ri;
-
- CERT_DestroyCertificate(cert);
- return certHandle;
- }
- CERT_DestroyCertificate(cert);
+ cert = PK11_FindCertByIssuerAndSNOnToken(slot, ri->issuerAndSN,
+ pwarg);
+ if (cert) {
+ *rip = ri;
+ return cert;
}
+
}
*rip = NULL;
- return CK_INVALID_HANDLE;
+ return NULL;
}
/*
* This function is the same as above, but it searches all the slots.
*/
-static CK_OBJECT_HANDLE
+static CERTCertificate *
pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
SEC_PKCS7RecipientInfo **recipientArray,SEC_PKCS7RecipientInfo **rip,
void *wincx) {
PK11SlotList *list;
PK11SlotListElement *le;
- CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
+ CERTCertificate * cert;
PK11SlotInfo *slot = NULL;
SECStatus rv;
@@ -2198,9 +2222,9 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
if (rv != SECSuccess) continue;
}
- certHandle = pk11_FindCertObjectByRecipient(le->slot,
- recipientArray,rip);
- if (certHandle != CK_INVALID_HANDLE) {
+ cert = pk11_FindCertObjectByRecipient(le->slot, recipientArray,
+ rip, wincx);
+ if (cert) {
slot = PK11_ReferenceSlot(le->slot);
break;
}
@@ -2209,10 +2233,10 @@ pk11_AllFindCertObjectByRecipient(PK11SlotInfo **slotPtr,
PK11_FreeSlotList(list);
if (slot == NULL) {
- return CK_INVALID_HANDLE;
+ return NULL;
}
*slotPtr = slot;
- return certHandle;
+ return cert;
}
/*
@@ -2233,40 +2257,28 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
SECStatus rv;
*privKey = NULL;
- certHandle = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx);
- if (certHandle == CK_INVALID_HANDLE) {
+ *slotPtr = NULL;
+ cert = pk11_AllFindCertObjectByRecipient(slotPtr,array,rip,wincx);
+ if (!cert) {
return NULL;
}
rv = PK11_Authenticate(*slotPtr,PR_TRUE,wincx);
if (rv != SECSuccess) {
- PK11_FreeSlot(*slotPtr);
- *slotPtr = NULL;
- return NULL;
- }
-
- keyHandle = PK11_MatchItem(*slotPtr,certHandle,CKO_PRIVATE_KEY);
- if (keyHandle == CK_INVALID_HANDLE) {
- PK11_FreeSlot(*slotPtr);
- *slotPtr = NULL;
- return NULL;
+ goto loser;
}
- *privKey = PK11_MakePrivKey(*slotPtr, nullKey, PR_TRUE, keyHandle, wincx);
+ *privKey = PK11_FindKeyByAnyCert(cert, wincx);
if (*privKey == NULL) {
- PK11_FreeSlot(*slotPtr);
- *slotPtr = NULL;
- return NULL;
- }
- cert = PK11_MakeCertFromHandle(*slotPtr,certHandle,NULL);
- if (cert == NULL) {
- PK11_FreeSlot(*slotPtr);
- SECKEY_DestroyPrivateKey(*privKey);
- *slotPtr = NULL;
- *privKey = NULL;
- return NULL;
+ goto loser;
}
+
return cert;
+loser:
+ if (cert) CERT_DestroyCertificate(cert);
+ if (*slotPtr) PK11_FreeSlot(*slotPtr);
+ *slotPtr = NULL;
+ return NULL;
}
/*
@@ -2277,13 +2289,12 @@ PK11_FindCertAndKeyByRecipientList(PK11SlotInfo **slotPtr,
int
PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *wincx)
{
- CK_OBJECT_HANDLE certHandle = CK_INVALID_HANDLE;
- CK_OBJECT_HANDLE keyHandle = CK_INVALID_HANDLE;
+ CERTCertificate *cert;
NSSCMSRecipient *rl;
int rlIndex;
- certHandle = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
- if (certHandle == CK_INVALID_HANDLE) {
+ cert = pk11_AllFindCertObjectByRecipientNew(recipientlist, wincx, &rlIndex);
+ if (!cert) {
return -1;
}
@@ -2293,36 +2304,23 @@ PK11_FindCertAndKeyByRecipientListNew(NSSCMSRecipient **recipientlist, void *win
/* authenticate to the token */
if (PK11_Authenticate(rl->slot, PR_TRUE, wincx) != SECSuccess) {
- PK11_FreeSlot(rl->slot);
- rl->slot = NULL;
- return -1;
- }
-
- /* 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_HANDLE) {
- PK11_FreeSlot(rl->slot);
- rl->slot = NULL;
- return -1;
+ goto loser;
}
- /* make a private key out of the handle */
- rl->privkey = PK11_MakePrivKey(rl->slot, nullKey, PR_TRUE, keyHandle, wincx);
+ rl->privkey = PK11_FindKeyByAnyCert(cert, wincx);
if (rl->privkey == NULL) {
- PK11_FreeSlot(rl->slot);
- rl->slot = NULL;
- return -1;
+ goto loser;
}
+
/* make a cert from the cert handle */
- rl->cert = PK11_MakeCertFromHandle(rl->slot, certHandle, NULL);
- if (rl->cert == NULL) {
- PK11_FreeSlot(rl->slot);
- SECKEY_DestroyPrivateKey(rl->privkey);
- rl->slot = NULL;
- rl->privkey = NULL;
- return -1;
- }
+ rl->cert = cert;
return rlIndex;
+
+loser:
+ if (cert) CERT_DestroyCertificate(cert);
+ if (rl->slot) PK11_FreeSlot(rl->slot);
+ rl->slot = NULL;
+ return -1;
}
CERTCertificate *