From ab7d7da30fbb4459ccc13df7bb9d5e81f27955f8 Mon Sep 17 00:00:00 2001 From: "ian.mcgreer%sun.com" Date: Thu, 7 Mar 2002 22:08:00 +0000 Subject: [PATCH] bug 129298, handle different nicknames across tokens r=relyea/a=wtc --- security/nss/lib/certdb/stanpcertdb.c | 22 +++++++++-------- security/nss/lib/dev/dev.h | 3 ++- security/nss/lib/dev/devobject.c | 20 ++++++++++----- security/nss/lib/dev/devt.h | 3 ++- security/nss/lib/pk11wrap/pk11cert.c | 5 ++-- security/nss/lib/pki/certificate.c | 35 ++++++++++++++++++++++++++- security/nss/lib/pki/pki.h | 9 ++++++- security/nss/lib/pki/pki3hack.c | 29 +++++++++++++--------- security/nss/lib/pki/pkistore.c | 6 +++-- security/nss/lib/pki/pkit.h | 5 ++-- security/nss/lib/pki/tdcache.c | 17 +++++++------ 11 files changed, 110 insertions(+), 44 deletions(-) diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index 121268e3771d..20d9ffa73a58 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -136,6 +136,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERTCertTrust *trust) { PRStatus nssrv; + NSSUTF8 *stanNick; PK11SlotInfo *slot; NSSToken *internal; NSSCryptoContext *context; @@ -144,13 +145,14 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, if (!context) { return PR_FAILURE; /* wasn't a temp cert */ } - if (c->nickname && strcmp(nickname, c->nickname) != 0) { - nss_ZFreeIf(c->nickname); + stanNick = NSSCertificate_GetNickname(c, NULL); + if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { + /* take the new nickname */ PORT_Free(cert->nickname); - c->nickname = NULL; + stanNick = NULL; } - if (!c->nickname) { - c->nickname = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); + if (!stanNick && nickname) { + stanNick = nssUTF8_Duplicate((NSSUTF8 *)nickname, c->object.arena); cert->nickname = PORT_Strdup(nickname); } /* Delete the temp instance */ @@ -161,7 +163,7 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); internal = PK11Slot_GetNSSToken(slot); - nssrv = nssToken_ImportCertificate(internal, NULL, c, PR_TRUE); + nssrv = nssToken_ImportCertificate(internal, NULL, c, stanNick, PR_TRUE); if (nssrv != PR_SUCCESS) { return SECFailure; } @@ -240,10 +242,10 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, PORT_Free(derSerial.data); } if (nickname) { - c->nickname = nssUTF8_Create(arena, - nssStringType_UTF8String, - (NSSUTF8 *)nickname, - PORT_Strlen(nickname)); + c->object.tempName = nssUTF8_Create(arena, + nssStringType_UTF8String, + (NSSUTF8 *)nickname, + PORT_Strlen(nickname)); } if (cc->emailAddr) { c->email = nssUTF8_Create(arena, diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h index 13104c514d66..24645236e289 100644 --- a/security/nss/lib/dev/dev.h +++ b/security/nss/lib/dev/dev.h @@ -35,7 +35,7 @@ #define DEV_H #ifdef DEBUG -static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.19 $ $Date: 2002/03/04 17:17:47 $ $Name: $"; +static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.20 $ $Date: 2002/03/07 22:07:48 $ $Name: $"; #endif /* DEBUG */ #ifndef DEVT_H @@ -268,6 +268,7 @@ nssToken_ImportCertificate NSSToken *tok, nssSession *sessionOpt, NSSCertificate *cert, + NSSUTF8 *nickname, PRBool asTokenObject ); diff --git a/security/nss/lib/dev/devobject.c b/security/nss/lib/dev/devobject.c index 7b05943e81f3..7b751a697c92 100644 --- a/security/nss/lib/dev/devobject.c +++ b/security/nss/lib/dev/devobject.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.19 $ $Date: 2002/03/04 17:13:52 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: devobject.c,v $ $Revision: 1.20 $ $Date: 2002/03/07 22:07:49 $ $Name: $"; #endif /* DEBUG */ #ifndef DEV_H @@ -291,7 +291,15 @@ create_cryptoki_instance PRBool isTokenObject ) { + PRStatus nssrv; nssCryptokiInstance *instance; + CK_ATTRIBUTE cert_template = { CKA_LABEL, NULL, 0 }; + nssrv = nssCKObject_GetAttributes(h, &cert_template, 1, + arena, t->defaultSession, t->slot); + if (nssrv != PR_SUCCESS) { + /* a failure here indicates a device error */ + return NULL; + } instance = nss_ZNEW(arena, nssCryptokiInstance); if (!instance) { return NULL; @@ -299,6 +307,7 @@ create_cryptoki_instance instance->handle = h; instance->token = t; instance->isTokenObject = isTokenObject; + NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template, instance->label); return instance; } @@ -355,7 +364,6 @@ get_token_cert { CKA_VALUE, NULL, 0 }, { CKA_ISSUER, NULL, 0 }, { CKA_SERIAL_NUMBER, NULL, 0 }, - { CKA_LABEL, NULL, 0 }, { CKA_SUBJECT, NULL, 0 }, { CKA_NETSCAPE_EMAIL, NULL, 0 } }; @@ -386,9 +394,8 @@ get_token_cert NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[2], &rvCert->encoding); NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[3], &rvCert->issuer); NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[4], &rvCert->serial); - NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[5], rvCert->nickname); - NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[6], &rvCert->subject); - NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[7], rvCert->email); + NSS_CK_ATTRIBUTE_TO_ITEM(&cert_template[5], &rvCert->subject); + NSS_CK_ATTRIBUTE_TO_UTF8(&cert_template[6], rvCert->email); /* XXX this would be better accomplished by dividing attributes to * retrieve into "required" and "optional" */ @@ -444,6 +451,7 @@ nssToken_ImportCertificate NSSToken *tok, nssSession *sessionOpt, NSSCertificate *cert, + NSSUTF8 *nickname, PRBool asTokenObject ) { @@ -462,7 +470,7 @@ nssToken_ImportCertificate NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_CLASS, &g_ck_class_cert); NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CERTIFICATE_TYPE, cert_type); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, &cert->id); - NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, cert->nickname); + NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_VALUE, &cert->encoding); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ISSUER, &cert->issuer); NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, &cert->subject); diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h index a33c153c8bcc..020a2aa4d372 100644 --- a/security/nss/lib/dev/devt.h +++ b/security/nss/lib/dev/devt.h @@ -35,7 +35,7 @@ #define DEVT_H #ifdef DEBUG -static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.11 $ $Date: 2002/02/27 21:36:19 $ $Name: $"; +static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.12 $ $Date: 2002/03/07 22:07:50 $ $Name: $"; #endif /* DEBUG */ /* @@ -171,6 +171,7 @@ struct nssCryptokiInstanceStr CK_OBJECT_HANDLE handle; NSSToken *token; PRBool isTokenObject; + NSSUTF8 *label; }; typedef struct nssTokenCertSearchStr nssTokenCertSearch; diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 361376c70566..42c7d4c4eff2 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -1286,8 +1286,9 @@ filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname) cert != (NSSCertificate *)NULL; cert = (NSSCertificate *)nssListIterator_Next(certs)) { - if (!cert->nickname) continue; - if (nssUTF8_Equal(cert->nickname, nickname, &nssrv)) { + NSSUTF8 *tokenNick = NSSCertificate_GetNickname(cert, token); + if (!tokenNick) continue; + if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) { nssList_Add(rvList, nssCertificate_AddRef(cert)); } } diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index 9b4c922a5f60..bca38ed5a9a7 100644 --- a/security/nss/lib/pki/certificate.c +++ b/security/nss/lib/pki/certificate.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.32 $ $Date: 2002/03/07 20:42:39 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.33 $ $Date: 2002/03/07 22:07:55 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -92,6 +92,39 @@ NSSCertificate_Destroy return PR_SUCCESS; } +NSS_IMPLEMENT NSSUTF8 * +NSSCertificate_GetNickname +( + NSSCertificate *c, + NSSToken *tokenOpt +) +{ + NSSUTF8 *rvNick = NULL; + nssCryptokiInstance *instance; + nssListIterator *instances = c->object.instances; + if (c->object.cryptoContext) { + return c->object.tempName; + } + for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); + instance != (nssCryptokiInstance *)NULL; + instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) + { + if (tokenOpt) { + if (instance->token == tokenOpt) { + /* take the nickname on the given token */ + rvNick = instance->label; + break; + } + } else { + /* take the first one */ + rvNick = instance->label; + break; + } + } + nssListIterator_Finish(instances); + return rvNick; +} + NSS_IMPLEMENT PRStatus NSSCertificate_DeleteStoredObject ( diff --git a/security/nss/lib/pki/pki.h b/security/nss/lib/pki/pki.h index fd505a2244a3..bba3d23bfe8e 100644 --- a/security/nss/lib/pki/pki.h +++ b/security/nss/lib/pki/pki.h @@ -35,7 +35,7 @@ #define PKI_H #ifdef DEBUG -static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.9 $ $Date: 2002/03/07 20:42:40 $ $Name: $"; +static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.10 $ $Date: 2002/03/07 22:07:56 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIT_H @@ -54,6 +54,13 @@ nssCertificate_AddRef NSSCertificate *c ); +NSS_EXTERN NSSUTF8 * +NSSCertificate_GetNickname +( + NSSCertificate *c, + NSSToken *tokenOpt +); + /* putting here for now, needs more thought */ NSS_EXTERN PRStatus nssCryptoContext_ImportTrust diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c index 755d71fc4036..998ed3c00d39 100644 --- a/security/nss/lib/pki/pki3hack.c +++ b/security/nss/lib/pki/pki3hack.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.40 $ $Date: 2002/03/07 20:42:40 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.41 $ $Date: 2002/03/07 22:07:58 $ $Name: $"; #endif /* DEBUG */ /* @@ -826,13 +826,19 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced NSSTrust *nssTrust; NSSCryptoContext *context = c->object.cryptoContext; nssCryptokiInstance *instance = get_cert_instance(c); + NSSUTF8 *stanNick; + if (instance) { + stanNick = instance->label; + } else if (context) { + stanNick = c->object.tempName; + } /* fill other fields needed by NSS3 functions using CERTCertificate */ - if ((!cc->nickname && c->nickname) || forced) { + if ((!cc->nickname && stanNick) || forced) { PRStatus nssrv; int nicklen, tokenlen, len; NSSUTF8 *tokenName = NULL; char *nick; - nicklen = nssUTF8_Size(c->nickname, &nssrv); + nicklen = nssUTF8_Size(stanNick, &nssrv); if (instance && !PK11_IsInternal(instance->token->pk11slot)) { tokenName = nssToken_GetName(instance->token); tokenlen = nssUTF8_Size(tokenName, &nssrv); @@ -848,7 +854,7 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced nick += tokenlen-1; *nick++ = ':'; } - memcpy(nick, c->nickname, nicklen-1); + memcpy(nick, stanNick, nicklen-1); cc->nickname[len-1] = '\0'; } if (context) { @@ -976,12 +982,6 @@ STAN_GetNSSCertificate(CERTCertificate *cc) nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); } - if (cc->nickname) { - c->nickname = nssUTF8_Create(arena, - nssStringType_UTF8String, - (NSSUTF8 *)cc->nickname, - PORT_Strlen(cc->nickname)); - } if (cc->emailAddr) { c->email = nssUTF8_Create(arena, nssStringType_PrintableString, @@ -993,6 +993,12 @@ STAN_GetNSSCertificate(CERTCertificate *cc) instance->token = PK11Slot_GetNSSToken(cc->slot); instance->handle = cc->pkcs11ID; instance->isTokenObject = PR_TRUE; + if (cc->nickname) { + instance->label = nssUTF8_Create(arena, + nssStringType_UTF8String, + (NSSUTF8 *)cc->nickname, + PORT_Strlen(cc->nickname)); + } nssList_Add(c->object.instanceList, instance); /* XXX Fix this! */ nssListIterator_Destroy(c->object.instances); @@ -1078,7 +1084,8 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) /* this is kind of hacky. the softoken needs the cert * object in order to store trust. forcing it to be perm */ - nssrv = nssToken_ImportCertificate(tok, NULL, c, PR_TRUE); + NSSUTF8 *nickname = NSSCertificate_GetNickname(c, NULL); + nssrv = nssToken_ImportCertificate(tok, NULL, c, nickname, PR_TRUE); if (nssrv != PR_SUCCESS) return nssrv; } nssrv = nssToken_ImportTrust(tok, NULL, nssTrust, PR_TRUE); diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c index 8775ff6fe108..fce63d6a2d25 100644 --- a/security/nss/lib/pki/pkistore.c +++ b/security/nss/lib/pki/pkistore.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.14 $ $Date: 2002/03/07 20:42:40 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.15 $ $Date: 2002/03/07 22:07:58 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIM_H @@ -431,11 +431,13 @@ static void match_nickname(const void *k, void *v, void *a) { PRStatus nssrv; NSSCertificate *c; + NSSUTF8 *nickname; nssList *subjectList = (nssList *)v; struct nickname_template_str *nt = (struct nickname_template_str *)a; nssrv = nssList_GetArray(subjectList, (void **)&c, 1); + nickname = NSSCertificate_GetNickname(c, NULL); if (nssrv == PR_SUCCESS && - nssUTF8_Equal(c->nickname, nt->nickname, &nssrv)) + nssUTF8_Equal(nickname, nt->nickname, &nssrv)) { nt->subjectList = subjectList; } diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h index c5d3c00e0ca1..28bccc2bbda3 100644 --- a/security/nss/lib/pki/pkit.h +++ b/security/nss/lib/pki/pkit.h @@ -35,7 +35,7 @@ #define PKIT_H #ifdef DEBUG -static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.10 $ $Date: 2002/02/04 22:34:22 $ $Name: $"; +static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.11 $ $Date: 2002/03/07 22:07:59 $ $Name: $"; #endif /* DEBUG */ /* @@ -108,6 +108,8 @@ struct nssPKIObjectBaseStr NSSTrustDomain *trustDomain; /* The object may live in a crypto context */ NSSCryptoContext *cryptoContext; + /* XXX added so temp certs can have nickname, think more ... */ + NSSUTF8 *tempName; }; struct NSSTrustStr @@ -139,7 +141,6 @@ struct NSSCertificateStr NSSDER issuer; NSSDER subject; NSSDER serial; - NSSUTF8 *nickname; NSSASCII7 *email; nssDecodedCert *decoding; }; diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index cde0068d8d15..b3f2de8b514a 100644 --- a/security/nss/lib/pki/tdcache.c +++ b/security/nss/lib/pki/tdcache.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.27 $ $Date: 2002/03/04 21:06:10 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.28 $ $Date: 2002/03/07 22:08:00 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIM_H @@ -308,11 +308,12 @@ remove_nickname_entry ) { PRStatus nssrv; - if (cert->nickname) { - nssHash_Remove(cache->nickname, cert->nickname); + NSSUTF8 *nickname = NSSCertificate_GetNickname(cert, NULL); + if (nickname) { + nssHash_Remove(cache->nickname, nickname); nssrv = PR_SUCCESS; #ifdef DEBUG_CACHE - PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", cert->nickname)); + PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname)); #endif } else { nssrv = PR_FAILURE; @@ -561,8 +562,9 @@ add_nickname_entry ) { PRStatus nssrv = PR_SUCCESS; + NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); cache_entry *ce; - ce = (cache_entry *)nssHash_Lookup(cache->nickname, cert->nickname); + ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname); if (ce) { /* This is a collision. A nickname entry already exists for this * subject, but a subject entry didn't. This would imply there are @@ -575,7 +577,7 @@ add_nickname_entry if (!ce) { return PR_FAILURE; } - nickname = nssUTF8_Duplicate(cert->nickname, arena); + nickname = nssUTF8_Duplicate(certNickname, arena); if (!nickname) { return PR_FAILURE; } @@ -696,7 +698,8 @@ add_cert_to_cache /* If a new subject entry was created, also need nickname and/or email */ if (subjectList != NULL) { PRBool handle = PR_FALSE; - if (cert->nickname) { + NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); + if (certNickname) { nssrv = add_nickname_entry(arena, td->cache, cert, subjectList); if (nssrv != PR_SUCCESS) { goto loser;