mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 17:24:29 +00:00
bug 161552: Make the recipient list traversal functions call the internal
nsstoken_FindCertByIssuerAndSN() function to gain the benefit of the fixed Searching code.
This commit is contained in:
parent
0b69c36802
commit
0fb6e546c6
@ -34,7 +34,7 @@
|
||||
/*
|
||||
* Certificate handling code
|
||||
*
|
||||
* $Id: certdb.c,v 1.38 2002/08/02 00:53:15 jpierre%netscape.com Exp $
|
||||
* $Id: certdb.c,v 1.39 2002/08/14 20:42:34 relyea%netscape.com Exp $
|
||||
*/
|
||||
|
||||
#include "nssilock.h"
|
||||
@ -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 ) {
|
||||
|
@ -32,7 +32,7 @@
|
||||
*/
|
||||
|
||||
#ifdef DEBUG
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.27 $ $Date: 2002/08/09 18:48:31 $ $Name: $";
|
||||
static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.28 $ $Date: 2002/08/14 20:42:38 $ $Name: $";
|
||||
#endif /* DEBUG */
|
||||
|
||||
#ifndef NSSCKEPV_H
|
||||
@ -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);
|
||||
|
@ -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;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
keyHandle = PK11_MatchItem(*slotPtr,certHandle,CKO_PRIVATE_KEY);
|
||||
if (keyHandle == CK_INVALID_HANDLE) {
|
||||
PK11_FreeSlot(*slotPtr);
|
||||
*slotPtr = NULL;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*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;
|
||||
goto loser;
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
|
||||
/* 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 *
|
||||
|
Loading…
x
Reference in New Issue
Block a user