diff options
author | ian.mcgreer%sun.com <devnull@localhost> | 2001-11-08 20:46:11 +0000 |
---|---|---|
committer | ian.mcgreer%sun.com <devnull@localhost> | 2001-11-08 20:46:11 +0000 |
commit | 229af7bdf3830ce03921539445bb77e14dcd924c (patch) | |
tree | 78b9bdabe5b759a28892bacff397cbabac5dc017 | |
parent | 61e1b79e87696807d87915d308a6da84d47fe8ba (diff) | |
download | nss-hg-229af7bdf3830ce03921539445bb77e14dcd924c.tar.gz |
a plethora of changes for handling S/MIME certs
-rw-r--r-- | security/nss/lib/certdb/certt.h | 6 | ||||
-rw-r--r-- | security/nss/lib/certdb/manifest.mn | 2 | ||||
-rw-r--r-- | security/nss/lib/certdb/stanpcertdb.c | 3 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certhigh.c | 2 | ||||
-rw-r--r-- | security/nss/lib/certhigh/certvfy.c | 8 | ||||
-rw-r--r-- | security/nss/lib/pk11wrap/pk11cert.c | 37 | ||||
-rw-r--r-- | security/nss/lib/pki/certificate.c | 26 | ||||
-rw-r--r-- | security/nss/lib/pki/pki3hack.c | 20 | ||||
-rw-r--r-- | security/nss/lib/pki/pkitm.h | 2 | ||||
-rw-r--r-- | security/nss/lib/pki/tdcache.c | 2 | ||||
-rw-r--r-- | security/nss/lib/pki/trustdomain.c | 12 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11.c | 97 | ||||
-rw-r--r-- | security/nss/lib/softoken/pkcs11u.c | 2 |
13 files changed, 158 insertions, 61 deletions
diff --git a/security/nss/lib/certdb/certt.h b/security/nss/lib/certdb/certt.h index 5b208acd6..1feb34479 100644 --- a/security/nss/lib/certdb/certt.h +++ b/security/nss/lib/certdb/certt.h @@ -60,10 +60,10 @@ typedef struct CERTAttributeStr CERTAttribute; typedef struct CERTAuthInfoAccessStr CERTAuthInfoAccess; typedef struct CERTAuthKeyIDStr CERTAuthKeyID; typedef struct CERTBasicConstraintsStr CERTBasicConstraints; -#ifdef STAN_CERT_DB -typedef NSSTrustDomain CERTCertDBHandle; -#else +#ifdef NSS_CLASSIC typedef struct CERTCertDBHandleStr CERTCertDBHandle; +#else +typedef NSSTrustDomain CERTCertDBHandle; #endif typedef struct CERTCertExtensionStr CERTCertExtension; typedef struct CERTCertKeyStr CERTCertKey; diff --git a/security/nss/lib/certdb/manifest.mn b/security/nss/lib/certdb/manifest.mn index a9b5f3d8c..33b3fb612 100644 --- a/security/nss/lib/certdb/manifest.mn +++ b/security/nss/lib/certdb/manifest.mn @@ -46,8 +46,6 @@ PRIVATE_EXPORTS = \ MODULE = security -DEFINES=-DSTAN_CERT_DB - CSRCS = \ alg1485.c \ certdb.c \ diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index 69a1df7e5..6d68473e2 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -566,8 +566,9 @@ loser: SECItem * CERT_FindSMimeProfile(CERTCertificate *cert) { + PK11SlotInfo *slot = NULL; return - PK11_FindSMimeProfile(NULL, cert->emailAddr, &cert->derSubject, NULL); + PK11_FindSMimeProfile(&slot, cert->emailAddr, &cert->derSubject, NULL); } /* diff --git a/security/nss/lib/certhigh/certhigh.c b/security/nss/lib/certhigh/certhigh.c index 62f2b1d88..cce2b0115 100644 --- a/security/nss/lib/certhigh/certhigh.c +++ b/security/nss/lib/certhigh/certhigh.c @@ -925,7 +925,7 @@ CERTCertificateList * CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage, PRBool includeRoot) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC CERTCertificateList *chain = NULL; CERTCertificate *c; SECItem *p; diff --git a/security/nss/lib/certhigh/certvfy.c b/security/nss/lib/certhigh/certvfy.c index c23adced7..c68132020 100644 --- a/security/nss/lib/certhigh/certvfy.c +++ b/security/nss/lib/certhigh/certvfy.c @@ -317,7 +317,7 @@ done: CERTCertificate * CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC CERTAuthKeyID * authorityKeyID = NULL; CERTCertificate * issuerCert = NULL; SECItem * caName; @@ -404,7 +404,7 @@ loser: NSSCertificate *me; NSSTime *nssTime; NSSUsage nssUsage; - NSSCertificate *issuer; + NSSCertificate *chain[2]; PRStatus status; me = STAN_GetNSSCertificate(cert); nssTime = NSSTime_SetPRTime(NULL, validTime); @@ -412,10 +412,10 @@ loser: nssUsage.nss3usage = usage; nssUsage.nss3lookingForCA = PR_TRUE; (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, - &issuer, 1, NULL, &status); + chain, 2, NULL, &status); nss_ZFreeIf(nssTime); if (status == PR_SUCCESS) { - CERTCertificate *rvc = STAN_GetCERTCertificate(issuer); + CERTCertificate *rvc = STAN_GetCERTCertificate(chain[1]); return rvc; } return NULL; diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index e150a94b5..b2844201d 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -119,13 +119,13 @@ pk11_buildNickname(PK11SlotInfo *slot,CK_ATTRIBUTE *cert_label, char buildNew[sizeof(DEFAULT_STRING)+MAX_CERT_ID*2]; char *next,*nickname; - if ((cert_label) && (cert_label->pValue)) { + if (cert_label && (cert_label->ulValueLen)) { suffixLen = cert_label->ulValueLen; suffix = (char*)cert_label->pValue; - } else if (key_label && (key_label->pValue)) { + } else if (key_label && (key_label->ulValueLen)) { suffixLen = key_label->ulValueLen; suffix = (char*)key_label->pValue; - } else if ((cert_id) && cert_id->pValue) { + } else if (cert_id && cert_id->ulValueLen > 0) { int i,first = cert_id->ulValueLen - MAX_CERT_ID; int offset = sizeof(DEFAULT_STRING); char *idValue = (char *)cert_id->pValue; @@ -1138,7 +1138,7 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr, CERTCertificate * PK11_FindCertFromNickname(char *nickname, void *wincx) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC PK11SlotInfo *slot; int count=0; CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot, @@ -1197,7 +1197,7 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { CERTCertList * PK11_FindCertsFromNickname(char *nickname, void *wincx) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC PK11SlotInfo *slot; int i,count = 0; CK_OBJECT_HANDLE *certID = PK11_FindObjectsFromNickname(nickname,&slot, @@ -2016,7 +2016,7 @@ CERTCertificate * PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN, void *wincx) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC CK_OBJECT_HANDLE certHandle; CERTCertificate *cert = NULL; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; @@ -2060,7 +2060,7 @@ PK11_FindCertByIssuerAndSN(PK11SlotInfo **slotPtr, CERTIssuerAndSN *issuerSN, &serial); if (cert) { rvCert = STAN_GetCERTCertificate(cert); - /* XXX *slotPtr = cert->slot; */ + if (slotPtr) *slotPtr = rvCert->slot; } return rvCert; #endif @@ -2220,7 +2220,7 @@ SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, SECStatus(* callback)(CERTCertificate*, void *), void *arg) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC pk11DoCertCallback caller; pk11TraverseSlot callarg; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; @@ -2281,7 +2281,7 @@ SECStatus PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, SECStatus(* callback)(CERTCertificate*, void *), void *arg) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC pk11DoCertCallback caller; pk11TraverseSlot callarg; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; @@ -2347,7 +2347,7 @@ SECStatus PK11_TraverseCertsInSlot(PK11SlotInfo *slot, SECStatus(* callback)(CERTCertificate*, void *), void *arg) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC pk11DoCertCallback caller; pk11TraverseSlot callarg; CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; @@ -2394,7 +2394,7 @@ CERTCertificate * PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert, void *wincx) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC CK_OBJECT_CLASS certClass = CKO_CERTIFICATE; CK_ATTRIBUTE theTemplate[] = { { CKA_VALUE, NULL, 0 }, @@ -2861,7 +2861,7 @@ pk11ListCertCallback(CERTCertificate *cert, SECItem *derCert, void *arg) CERTCertList * PK11_ListCerts(PK11CertListType type, void *pwarg) { -#ifndef NSS_SOFTOKEN_MODULE +#ifdef NSS_CLASSIC CERTCertList *certList = NULL; struct listCertsStr listCerts; @@ -3282,10 +3282,12 @@ SECStatus PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, SECItem *emailProfile, SECItem *profileTime) { - CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_CRL; + CK_OBJECT_CLASS smimeClass = CKO_NETSCAPE_SMIME; + CK_BBOOL ck_true = CK_TRUE; CK_ATTRIBUTE theTemplate[] = { - { CKA_SUBJECT, NULL, 0 }, { CKA_CLASS, NULL, 0 }, + { CKA_TOKEN, NULL, 0 }, + { CKA_SUBJECT, NULL, 0 }, { CKA_NETSCAPE_EMAIL, NULL, 0 }, { CKA_NETSCAPE_SMIME_TIMESTAMP, NULL, 0 }, { CKA_VALUE, NULL, 0 } @@ -3297,8 +3299,9 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, CK_SESSION_HANDLE rwsession; CK_RV crv; - PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++; PK11_SETATTRS(attrs, CKA_CLASS, &smimeClass, sizeof(smimeClass)); attrs++; + PK11_SETATTRS(attrs, CKA_TOKEN, &ck_true, sizeof(ck_true)); attrs++; + PK11_SETATTRS(attrs, CKA_SUBJECT, derSubj->data, derSubj->len); attrs++; PK11_SETATTRS(attrs, CKA_NETSCAPE_EMAIL, emailAddr, PORT_Strlen(emailAddr)+1); attrs++; if (profileTime) { @@ -3306,6 +3309,8 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, profileTime->len); attrs++; PK11_SETATTRS(attrs, CKA_VALUE,emailProfile->data, emailProfile->len); attrs++; + } else { + tsize -= 2; } if (slot == NULL) { @@ -3320,7 +3325,7 @@ PK11_SaveSMimeProfile(PK11SlotInfo *slot, char *emailAddr, SECItem *derSubj, } crv = PK11_GETTAB(slot)-> - C_CreateObject(rwsession,attrs,tsize,&smimeh); + C_CreateObject(rwsession,theTemplate,tsize,&smimeh); if (crv != CKR_OK) { PORT_SetError( PK11_MapError(crv) ); } diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 16f9291e3..5fcb31c93 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -57,6 +57,7 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$"; #ifndef CKT_H #ifdef NSS_3_4_CODE +#include "pki3hack.h" #define NSSCKT_H #endif #include "ckt.h" @@ -105,7 +106,12 @@ nssCertificate_AddRef NSSCertificate *c ) { +#ifdef NSS_3_4_CODE + CERTCertificate *cc = STAN_GetCERTCertificate(c); + CERT_DupCertificate(cc); +#else c->refCount++; +#endif return c; } @@ -230,7 +236,8 @@ static void make_nss3_nickname(NSSCertificate *c) char *fullname; PRUint32 len, tlen; tokenName = nssToken_GetName(c->token); - label = c->nickname; + label = c->nickname ? c->nickname : c->email; + if (!label) return; tlen = nssUTF8_Length(tokenName, &utf8rv); /* token name */ tlen += 1; /* : */ len = nssUTF8_Length(label, &utf8rv); /* label */ @@ -267,7 +274,8 @@ nssCertificate_CreateFromHandle { CKA_LABEL, NULL, 0 }, { CKA_ISSUER, NULL, 0 }, { CKA_SUBJECT, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0 } + { CKA_SERIAL_NUMBER, NULL, 0 }, + { CKA_NETSCAPE_EMAIL, NULL, 0 } }; template_size = sizeof(cert_template) / sizeof(cert_template[0]); rvCert = NSSCertificate_Create(arenaOpt); @@ -294,11 +302,19 @@ nssCertificate_CreateFromHandle NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->issuer); NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject); NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->serial); - /* get the email from an attrib */ + NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email); + nssCertificate_GetCertTrust(rvCert, session); #ifdef NSS_3_4_CODE + /* nss 3.4 database doesn't associate email address with cert */ + if (!rvCert->email) { + nssDecodedCert *dc; + NSSASCII7 *email; + dc = nssCertificate_GetDecoding(rvCert); + email = dc->getEmailAddress(dc); + if (email) rvCert->email = nssUTF8_Duplicate(email, rvCert->arena); + } make_nss3_nickname(rvCert); #endif - nssCertificate_GetCertTrust(rvCert, session); return rvCert; loser: NSSCertificate_Destroy(rvCert); @@ -568,6 +584,7 @@ NSSCertificate_BuildChain nssDecodedCert *dc; chain = nssList_Create(NULL, PR_FALSE); nssList_Add(chain, c); + if (statusOpt) *statusOpt = PR_SUCCESS; if (rvLimit == 1) goto finish; while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) { dc = nssCertificate_GetDecoding(c); @@ -602,7 +619,6 @@ NSSCertificate_BuildChain nssList_Add(chain, c); if (nssList_Count(chain) == rvLimit) goto finish; } - if (statusOpt) *statusOpt = PR_SUCCESS; finish: if (rvOpt) { rvChain = rvOpt; diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index 87fb6263d..52170ce40 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -242,7 +242,7 @@ nss3certificate_matchUsage(nssDecodedCert *dc, NSSUsage *usage) unsigned int requiredKeyUsage; unsigned int requiredCertType; unsigned int certType; - PRBool bad; + PRBool match; CERTCertificate *cc = (CERTCertificate *)dc->data; SECCertUsage secUsage = usage->nss3usage; PRBool ca = usage->nss3lookingForCA; @@ -252,10 +252,10 @@ nss3certificate_matchUsage(nssDecodedCert *dc, NSSUsage *usage) if (secrv != SECSuccess) { return PR_FALSE; } - bad = PR_FALSE; + match = PR_TRUE; secrv = CERT_CheckKeyUsage(cc, requiredKeyUsage); if (secrv != SECSuccess) { - bad = PR_TRUE; + match = PR_FALSE; } if (ca) { (void)CERT_IsCACert(cc, &certType); @@ -263,9 +263,16 @@ nss3certificate_matchUsage(nssDecodedCert *dc, NSSUsage *usage) certType = cc->nsCertType; } if (!(certType & requiredCertType)) { - bad = PR_TRUE; + match = PR_FALSE; } - return bad; + return match; +} + +static NSSASCII7 * +nss3certificate_getEmailAddress(nssDecodedCert *dc) +{ + CERTCertificate *cc = (CERTCertificate *)dc->data; + return (NSSASCII7 *)cc->emailAddr; } NSS_IMPLEMENT nssDecodedCert * @@ -288,6 +295,7 @@ nssDecodedPKIXCertificate_Create rvDC->isValidAtTime = nss3certificate_isValidAtTime; rvDC->isNewerThan = nss3certificate_isNewerThan; rvDC->matchUsage = nss3certificate_matchUsage; + rvDC->getEmailAddress = nss3certificate_getEmailAddress; return rvDC; } @@ -367,6 +375,8 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc) /* subjectList ? */ /* pkcs11ID */ cc->pkcs11ID = c->handle; + /* database handle is now the trust domain */ + cc->dbhandle = c->trustDomain; /* pointer back */ cc->nssCertificate = c; } diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h index 7365ecbe4..991054c2a 100644 --- a/security/nss/lib/pki/pkitm.h +++ b/security/nss/lib/pki/pkitm.h @@ -79,6 +79,8 @@ struct nssDecodedCertStr { PRBool (*isNewerThan)(nssDecodedCert *dc, nssDecodedCert *cmpdc); /* does the usage for this cert match the requested usage? */ PRBool (*matchUsage)(nssDecodedCert *dc, NSSUsage *usage); + /* extract the email address */ + NSSASCII7 *(*getEmailAddress)(nssDecodedCert *dc); }; struct NSSUsageStr { diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index 6c01694dc..05bebd844 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -271,7 +271,7 @@ nssTrustDomain_AddCertsToCache for (i=0; i<numCerts && certs[i]; i++) { if (add_cert_to_cache(td, certs[i]) != PR_SUCCESS) { return PR_FAILURE; - } + } } return PR_SUCCESS; } diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c index f8ae11d54..f6ab4a9ee 100644 --- a/security/nss/lib/pki/trustdomain.c +++ b/security/nss/lib/pki/trustdomain.c @@ -704,8 +704,8 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber ctsize = sizeof(cert_template) / sizeof(cert_template[0]); /* Set the unique id */ NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, issuer); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, serialNumber); + NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 1, issuer); + NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, serialNumber); /* Try the cache */ rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, issuer, @@ -721,7 +721,8 @@ NSSTrustDomain_FindCertificateByIssuerAndSerialNumber if (object != CK_INVALID_HANDLE) { /* Could not find cert, so create it */ rvCert = nssCertificate_CreateFromHandle(NULL, object, - NULL, tok->slot); + tok->defaultSession, + tok->slot); if (rvCert) { /* cache it */ nssTrustDomain_AddCertsToCache(td, &rvCert, 1); @@ -862,9 +863,10 @@ NSSTrustDomain_FindCertificateByEncodedCertificate object = nssToken_FindObjectByTemplate(tok, NULL, cert_template, ctsize); if (object != CK_INVALID_HANDLE) { - /* Could not find cert, so create it */ + /* found it */ rvCert = nssCertificate_CreateFromHandle(NULL, object, - NULL, tok->slot); + tok->defaultSession, + tok->slot); if (rvCert) { /* cache it */ nssTrustDomain_AddCertsToCache(td, &rvCert, 1); diff --git a/security/nss/lib/softoken/pkcs11.c b/security/nss/lib/softoken/pkcs11.c index 75328ccb1..88d2cb0d2 100644 --- a/security/nss/lib/softoken/pkcs11.c +++ b/security/nss/lib/softoken/pkcs11.c @@ -802,19 +802,15 @@ pk11_handleSMimeObject(PK11Session *session,PK11Object *object) if ( !pk11_hasAttribute(object,CKA_SUBJECT) ) { return CKR_TEMPLATE_INCOMPLETE; } - if ( !pk11_hasAttribute(object,CKA_NETSCAPE_SMIME_TIMESTAMP) ) { - return CKR_TEMPLATE_INCOMPLETE; - } if ( !pk11_hasAttribute(object,CKA_NETSCAPE_EMAIL) ) { return CKR_TEMPLATE_INCOMPLETE; } - if ( !pk11_hasAttribute(object,CKA_VALUE) ) { - return CKR_TEMPLATE_INCOMPLETE; - } if (pk11_isTrue(object,CKA_TOKEN)) { PK11Slot *slot = session->slot; SECItem derSubj,rawProfile,rawTime,emailKey; + SECItem *pRawProfile = NULL; + SECItem *pRawTime = NULL; char *email = NULL; PK11Attribute *subject,*profile,*time; SECStatus rv; @@ -832,26 +828,30 @@ pk11_handleSMimeObject(PK11Session *session,PK11Object *object) /* lookup VALUE */ profile = pk11_FindAttribute(object,CKA_VALUE); - PORT_Assert(profile); - rawProfile.data = (unsigned char *)profile->attrib.pValue; - rawProfile.len = profile->attrib.ulValueLen ; + if (profile) { + rawProfile.data = (unsigned char *)profile->attrib.pValue; + rawProfile.len = profile->attrib.ulValueLen ; + pRawProfile = &rawProfile; + } /* lookup Time */ time = pk11_FindAttribute(object,CKA_NETSCAPE_SMIME_TIMESTAMP); - PORT_Assert(time); - rawTime.data = (unsigned char *)time->attrib.pValue; - rawTime.len = time->attrib.ulValueLen ; + if (time) { + rawTime.data = (unsigned char *)time->attrib.pValue; + rawTime.len = time->attrib.ulValueLen ; + pRawTime = &rawTime; + } email = pk11_getString(object,CKA_NETSCAPE_EMAIL); /* Store CRL by SUBJECT */ rv = nsslowcert_SaveSMimeProfile(slot->certDB, email, &derSubj, - &rawProfile,&rawTime); + pRawProfile,pRawTime); - pk11_FreeAttribute(profile); pk11_FreeAttribute(subject); - pk11_FreeAttribute(time); + if (profile) pk11_FreeAttribute(profile); + if (time) pk11_FreeAttribute(time); if (rv != SECSuccess) { PORT_Free(email); return CKR_DEVICE_ERROR; @@ -3089,6 +3089,7 @@ CK_RV NSC_SetAttributeValue (CK_SESSION_HANDLE hSession, #define NSC_PRIVATE 0x00000010 #define NSC_PUBLIC 0x00000020 #define NSC_KEY 0x00000040 +#define NSC_SMIME_CERT 0x00000080 /* * structure to collect key handles. @@ -3496,6 +3497,63 @@ pk11_searchSMime(PK11Slot *slot, SECItem *email, PK11SearchResults *handles, return; } +static void +pk11_searchSMimeForCert(PK11Slot *slot, SECItem *email, + unsigned long classFlags, + PK11SearchResults *handles, + CK_ATTRIBUTE *pTemplate, CK_LONG ulCount) +{ + NSSLOWCERTCertDBHandle *certHandle = NULL; + certDBEntrySMime *entry; + int i; + + certHandle = slot->certDB; + if (certHandle == NULL) return; + + if (email->data != NULL) { + char *tmp_name = (char*)PORT_Alloc(email->len+1); + + if (tmp_name == NULL) { + return; + } + PORT_Memcpy(tmp_name,email->data,email->len); + tmp_name[email->len] = 0; + + entry = nsslowcert_ReadDBSMimeEntry(certHandle,tmp_name); + if (entry) { + int count; + pk11CertData certData; + 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; + count = nsslowcert_NumPermCertsForSubject(certHandle,&entry->subjectName); + pk11_CertSetupData(&certData,count); + nsslowcert_TraversePermCertsForSubject(certHandle,&entry->subjectName, + pk11_cert_collect, &certData); + + /* + * build the handles + */ + for (i=0 ; i < certData.cert_count ; i++) { + NSSLOWCERTCertificate *cert = certData.certs[i]; + pk11_addHandle(handles, + pk11_mkHandle(slot,&cert->certKey,PK11_TOKEN_TYPE_CERT)); + nsslowcert_DestroyCertificate(cert); + } + + nsslowcert_DestroyDBEntry((certDBEntry *)entry); + if (certData.certs) PORT_Free(certData.certs); + } + PORT_Free(tmp_name); + } + return; +} + static CK_RV pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search, @@ -3517,7 +3575,7 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search, }; SECItem *copy = NULL; unsigned long classFlags = - NSC_CERT|NSC_TRUST|NSC_PRIVATE|NSC_PUBLIC|NSC_KEY|NSC_SMIME ; + NSC_CERT|NSC_TRUST|NSC_PRIVATE|NSC_PUBLIC|NSC_KEY|NSC_SMIME|NSC_SMIME_CERT ; /* if we aren't logged in, don't look for private or secret keys */ if (!isLoggedIn) { @@ -3555,6 +3613,7 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search, break; case CKA_NETSCAPE_EMAIL: copy = &email; + classFlags &= NSC_SMIME_CERT; break; case CKA_NETSCAPE_SMIME_TIMESTAMP: classFlags &= NSC_SMIME; @@ -3566,7 +3625,7 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search, } switch (*((CK_OBJECT_CLASS *)pTemplate[i].pValue)) { case CKO_CERTIFICATE: - classFlags &= NSC_CERT; + classFlags &= NSC_CERT|NSC_SMIME_CERT; break; case CKO_NETSCAPE_TRUST: classFlags &= NSC_TRUST; @@ -3708,6 +3767,10 @@ pk11_searchTokenList(PK11Slot *slot, PK11SearchResults *search, if (classFlags & NSC_SMIME) { pk11_searchSMime(slot, &email, search, pTemplate, ulCount); } + /* special case - use the S/MIME entry to obtain a certificate */ + if (classFlags & NSC_SMIME_CERT) { + pk11_searchSMimeForCert(slot, &email, classFlags, search, pTemplate, ulCount); + } return CKR_OK; } diff --git a/security/nss/lib/softoken/pkcs11u.c b/security/nss/lib/softoken/pkcs11u.c index 22384d677..710cd2c84 100644 --- a/security/nss/lib/softoken/pkcs11u.c +++ b/security/nss/lib/softoken/pkcs11u.c @@ -1040,7 +1040,7 @@ pk11_FindTokenAttribute(PK11TokenObject *object,CK_ATTRIBUTE_TYPE type) return (PK11Attribute *) &pk11_StaticTrueAttr; case CKA_LABEL: if ((object->obj.objclass == CKO_CERTIFICATE) - && (object->obj.objclass == CKO_PRIVATE_KEY)) { + || (object->obj.objclass == CKO_PRIVATE_KEY)) { break; } return (PK11Attribute *) &pk11_StaticNullAttr; |