diff options
author | relyea%netscape.com <devnull@localhost> | 2002-08-14 20:42:40 +0000 |
---|---|---|
committer | relyea%netscape.com <devnull@localhost> | 2002-08-14 20:42:40 +0000 |
commit | 1cb2645faa330598fcc31ebb2f125944ea53bec8 (patch) | |
tree | b4f6f0aa33a43fe48f9abafe98109c31acd72fb7 | |
parent | fee364aaab5a29cdfb1bdc17fa12812834d1c16a (diff) | |
download | nss-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.c | 4 | ||||
-rw-r--r-- | security/nss/lib/dev/devtoken.c | 19 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 282 |
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 * |