From a7256cf9ec56b84744ee0468f4596b9c1a86dd17 Mon Sep 17 00:00:00 2001 From: "ian.mcgreer%sun.com" Date: Mon, 15 Apr 2002 15:22:11 +0000 Subject: [PATCH] bug 135521, change cert lookups on tokens to be actual finds instead of traversals --- security/nss/lib/certdb/stanpcertdb.c | 72 +- security/nss/lib/dev/ckhelper.c | 14 +- security/nss/lib/dev/ckhelper.h | 10 +- security/nss/lib/dev/dev.h | 118 +-- security/nss/lib/dev/devt.h | 7 +- security/nss/lib/dev/devtoken.c | 138 ++- security/nss/lib/dev/devutil.c | 6 +- security/nss/lib/dev/manifest.mn | 3 +- security/nss/lib/pk11wrap/dev3hack.c | 24 +- security/nss/lib/pk11wrap/pk11cert.c | 513 +++++------ security/nss/lib/pki/certdecode.c | 110 +-- security/nss/lib/pki/certificate.c | 577 +++++++------ security/nss/lib/pki/cryptocontext.c | 266 +++--- security/nss/lib/pki/manifest.mn | 3 +- security/nss/lib/pki/pki.h | 130 ++- security/nss/lib/pki/pki3hack.c | 387 ++++----- security/nss/lib/pki/pki3hack.h | 6 +- security/nss/lib/pki/pkibase.c | 122 ++- security/nss/lib/pki/pkim.h | 614 ++++++++++---- security/nss/lib/pki/pkistore.c | 4 +- security/nss/lib/pki/pkit.h | 48 +- security/nss/lib/pki/pkitm.h | 14 +- security/nss/lib/pki/tdcache.c | 58 +- security/nss/lib/pki/trustdomain.c | 1120 ++++++++++++++----------- 24 files changed, 2390 insertions(+), 1974 deletions(-) diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c index 7b1dd0f82d4b..ef9b04e1a1e2 100644 --- a/security/nss/lib/certdb/stanpcertdb.c +++ b/security/nss/lib/certdb/stanpcertdb.c @@ -135,17 +135,17 @@ SECStatus __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, CERTCertTrust *trust) { - PRStatus nssrv; NSSUTF8 *stanNick; PK11SlotInfo *slot; NSSToken *internal; NSSCryptoContext *context; + nssCryptokiObject *permInstance; NSSCertificate *c = STAN_GetNSSCertificate(cert); context = c->object.cryptoContext; if (!context) { return SECFailure; /* wasn't a temp cert */ } - stanNick = NSSCertificate_GetNickname(c, NULL); + stanNick = nssCertificate_GetNickname(c, NULL); if (stanNick && nickname && strcmp(nickname, stanNick) != 0) { /* take the new nickname */ cert->nickname = NULL; @@ -157,15 +157,23 @@ __CERT_AddTempCertToPerm(CERTCertificate *cert, char *nickname, /* Delete the temp instance */ nssCertificateStore_Remove(context->certStore, c); c->object.cryptoContext = NULL; - /* the perm instance will assume the reference */ - nssList_Clear(c->object.instanceList, NULL); /* Import the perm instance onto the internal token */ slot = PK11_GetInternalKeySlot(); internal = PK11Slot_GetNSSToken(slot); - nssrv = nssToken_ImportCertificate(internal, NULL, c, stanNick, PR_TRUE); - if (nssrv != PR_SUCCESS) { + permInstance = nssToken_ImportCertificate(internal, NULL, + NSSCertificateType_PKIX, + &c->id, + stanNick, + &c->encoding, + &c->issuer, + &c->subject, + &c->serial, + PR_TRUE); + PK11_FreeSlot(slot); + if (!permInstance) { return SECFailure; } + nssPKIObject_AddInstance(&c->object, permInstance); /* reset the CERTCertificate fields */ cert->nssCertificate = NULL; cert = STAN_GetCERTCertificate(c); /* will return same pointer */ @@ -188,11 +196,11 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, { PRStatus nssrv; NSSCertificate *c; - NSSCryptoContext *context; - NSSArena *arena; CERTCertificate *cc; NSSCertificate *tempCert; + nssPKIObject *pkio; NSSCryptoContext *gCC = STAN_GetDefaultCryptoContext(); + NSSTrustDomain *gTD = STAN_GetDefaultTrustDomain(); if (!isperm) { NSSDER encoding; NSSITEM_FROM_SECITEM(&encoding, derCert); @@ -208,27 +216,24 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, return STAN_GetCERTCertificate(c); } } - arena = NSSArena_Create(); - if (!arena) { + pkio = nssPKIObject_Create(NULL, NULL, gTD, gCC); + if (!pkio) { return NULL; } - c = nss_ZNEW(arena, NSSCertificate); + c = nss_ZNEW(pkio->arena, NSSCertificate); if (!c) { - nssArena_Destroy(arena); + nssPKIObject_Destroy(pkio); return NULL; } + c->object = *pkio; NSSITEM_FROM_SECITEM(&c->encoding, derCert); - nssrv = nssPKIObject_Initialize(&c->object, arena, NULL, NULL); - if (nssrv != PR_SUCCESS) { - goto loser; - } /* Forces a decoding of the cert in order to obtain the parts used * below */ cc = STAN_GetCERTCertificate(c); - nssItem_Create(arena, + nssItem_Create(c->object.arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); - nssItem_Create(arena, + nssItem_Create(c->object.arena, &c->subject, cc->derSubject.len, cc->derSubject.data); if (PR_TRUE) { /* CERTCertificate stores serial numbers decoded. I need the DER @@ -237,31 +242,30 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, SECItem derSerial = { 0 }; CERT_SerialNumberFromDERCert(&cc->derCert, &derSerial); if (!derSerial.data) goto loser; - nssItem_Create(arena, &c->serial, derSerial.len, derSerial.data); + nssItem_Create(c->object.arena, &c->serial, derSerial.len, derSerial.data); PORT_Free(derSerial.data); } if (nickname) { - c->object.tempName = nssUTF8_Create(arena, + c->object.tempName = nssUTF8_Create(c->object.arena, nssStringType_UTF8String, (NSSUTF8 *)nickname, PORT_Strlen(nickname)); } if (cc->emailAddr) { - c->email = nssUTF8_Create(arena, + c->email = nssUTF8_Create(c->object.arena, nssStringType_PrintableString, (NSSUTF8 *)cc->emailAddr, PORT_Strlen(cc->emailAddr)); } - context = STAN_GetDefaultCryptoContext(); /* this function cannot detect if the cert exists as a temp cert now, but * didn't when CERT_NewTemp was first called. */ - nssrv = NSSCryptoContext_ImportCertificate(context, c); + nssrv = NSSCryptoContext_ImportCertificate(gCC, c); if (nssrv != PR_SUCCESS) { goto loser; } /* so find the entry in the temp store */ - tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(context, + tempCert = NSSCryptoContext_FindCertificateByIssuerAndSerialNumber(gCC, &c->issuer, &c->serial); /* destroy the copy */ @@ -273,7 +277,6 @@ __CERT_NewTempCertificate(CERTCertDBHandle *handle, SECItem *derCert, } else { return NULL; } - c->object.trustDomain = STAN_GetDefaultTrustDomain(); cc->istemp = PR_TRUE; cc->isperm = PR_FALSE; return cc; @@ -308,17 +311,18 @@ CERT_FindCertByIssuerAndSN(CERTCertDBHandle *handle, CERTIssuerAndSN *issuerAndS static NSSCertificate * get_best_temp_or_perm(NSSCertificate *ct, NSSCertificate *cp) { - nssBestCertificateCB best; NSSUsage usage; + NSSCertificate *arr[3]; + if (!ct) { + return nssCertificate_AddRef(cp); + } else if (!cp) { + return nssCertificate_AddRef(ct); + } + arr[0] = ct; + arr[1] = cp; + arr[2] = NULL; usage.anyUsage = PR_TRUE; - nssBestCertificate_SetArgs(&best, NULL, &usage, NULL); - if (ct) { - nssBestCertificate_Callback(ct, (void *)&best); - } - if (cp) { - nssBestCertificate_Callback(cp, (void *)&best); - } - return best.cert; + return nssCertificateArray_FindBestCertificate(arr, NULL, &usage, NULL); } CERTCertificate * diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c index 2084acc615d6..f43adf4ae15d 100644 --- a/security/nss/lib/dev/ckhelper.c +++ b/security/nss/lib/dev/ckhelper.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.19 $ $Date: 2002/04/09 17:58:00 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: ckhelper.c,v $ $Revision: 1.20 $ $Date: 2002/04/15 15:22:00 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSCKEPV_H @@ -287,7 +287,6 @@ nssCKObject_IsTokenObjectTemplate return PR_FALSE; } -#ifdef PURE_STAN_BUILD static NSSCertificateType nss_cert_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) { @@ -358,10 +357,14 @@ nssCryptokiCertificate_GetAttributes return PR_SUCCESS; } +#ifdef PURE_STAN_BUILD status = nssToken_GetCachedObjectAttributes(certObject->token, arenaOpt, certObject, CKO_CERTIFICATE, cert_template, template_size); if (status != PR_SUCCESS) { +#else + if (PR_TRUE) { +#endif session = sessionOpt ? sessionOpt : @@ -402,6 +405,7 @@ nssCryptokiCertificate_GetAttributes return PR_SUCCESS; } +#ifdef PURE_STAN_BUILD static NSSKeyPairType nss_key_pair_type_from_ck_attrib(CK_ATTRIBUTE_PTR attrib) { @@ -523,6 +527,7 @@ nssCryptokiPublicKey_GetAttributes } return PR_SUCCESS; } +#endif /* PURE_STAN_BUILD */ static nssTrustLevel get_nss_trust @@ -572,11 +577,15 @@ nssCryptokiTrust_GetAttributes NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TRUST_CODE_SIGNING, csTrust); NSS_CK_TEMPLATE_FINISH(trust_template, attr, trust_size); +#ifdef PURE_STAN_BUILD status = nssToken_GetCachedObjectAttributes(trustObject->token, NULL, trustObject, CKO_NETSCAPE_TRUST, trust_template, trust_size); if (status != PR_SUCCESS) { +#else + if (PR_TRUE) { +#endif session = sessionOpt ? sessionOpt : nssToken_GetDefaultSession(trustObject->token); @@ -598,6 +607,7 @@ nssCryptokiTrust_GetAttributes return PR_SUCCESS; } +#ifdef PURE_STAN_BUILD NSS_IMPLEMENT PRStatus nssCryptokiCRL_GetAttributes ( diff --git a/security/nss/lib/dev/ckhelper.h b/security/nss/lib/dev/ckhelper.h index 5a53287f2c29..dbea532623d7 100644 --- a/security/nss/lib/dev/ckhelper.h +++ b/security/nss/lib/dev/ckhelper.h @@ -41,7 +41,7 @@ #define CKHELPER_H #ifdef DEBUG -static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.14 $ $Date: 2002/04/04 20:00:21 $ $Name: $"; +static const char CKHELPER_CVS_ID[] = "@(#) $RCSfile: ckhelper.h,v $ $Revision: 1.15 $ $Date: 2002/04/15 15:22:00 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSCKT_H @@ -86,6 +86,12 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey; (pattr)->ulValueLen = (CK_ULONG)sizeof(var); \ (pattr)++; +#define NSS_CK_SET_ATTRIBUTE_NULL(pattr, kind) \ + (pattr)->type = kind; \ + (pattr)->pValue = (CK_VOID_PTR)NULL; \ + (pattr)->ulValueLen = 0; \ + (pattr)++; + #define NSS_CK_TEMPLATE_FINISH(_template, attr, size) \ size = (attr) - (_template); \ PR_ASSERT(size <= sizeof(_template)/sizeof(_template[0])); @@ -127,7 +133,7 @@ nssCKObject_GetAttributes CK_ULONG count, NSSArena *arenaOpt, nssSession *session, - NSSSlot *slot + NSSSlot *slot ); /* Get a single attribute as an item. */ diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h index a1bec82ff8a6..1c34b00e6666 100644 --- a/security/nss/lib/dev/dev.h +++ b/security/nss/lib/dev/dev.h @@ -41,7 +41,7 @@ */ #ifdef DEBUG -static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.22 $ $Date: 2002/04/04 20:00:21 $ $Name: $"; +static const char DEV_CVS_ID[] = "@(#) $RCSfile: dev.h,v $ $Revision: 1.23 $ $Date: 2002/04/15 15:22:00 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSCKT_H @@ -421,7 +421,6 @@ nssToken_NeedsPINInitialization NSSToken *token ); -#ifdef PURE_STAN_BUILD NSS_EXTERN nssCryptokiObject * nssToken_ImportCertificate ( @@ -603,8 +602,6 @@ nssToken_FindPublicKeyByID NSSItem *keyID ); -#endif /* PURE_STAN_BUILD */ - NSS_EXTERN NSSItem * nssToken_Digest ( @@ -903,26 +900,18 @@ nssSlotList_GetBestSlotForAlgorithmsAndParameters NSSAlgorithmAndParameters **ap ); -#ifndef PURE_STAN_BUILD -/* XXX the following remain while merging new work */ +#ifdef NSS_3_4_CODE -NSS_EXTERN PRStatus -nssToken_ImportCertificate +NSS_EXTERN PRBool +nssToken_IsPresent ( - NSSToken *tok, - nssSession *sessionOpt, - NSSCertificate *cert, - NSSUTF8 *nickname, - PRBool asTokenObject + NSSToken *token ); - -NSS_EXTERN PRStatus -nssToken_ImportTrust + +NSS_EXTERN nssSession * +nssToken_GetDefaultSession ( - NSSToken *tok, - nssSession *sessionOpt, - NSSTrust *trust, - PRBool asTokenObject + NSSToken *token ); NSS_EXTERN PRStatus @@ -949,96 +938,13 @@ nssToken_SetHasCrls NSSToken *tok ); -/* Permanently remove an object from the token. */ NSS_EXTERN PRStatus -nssToken_DeleteStoredObject +nssToken_GetTrustOrder ( - nssCryptokiInstance *instance + NSSToken *tok ); -NSS_EXTERN NSSTrust * -nssToken_FindTrustForCert -( - NSSToken *token, - nssSession *sessionOpt, - NSSCertificate *c, - nssTokenSearchType searchType -); - -NSS_EXTERN PRStatus -nssToken_TraverseCertificates -( - NSSToken *tok, - nssSession *sessionOpt, - nssTokenCertSearch *search -); - -NSS_EXTERN PRStatus -nssToken_TraverseCertificatesBySubject -( - NSSToken *token, - nssSession *sessionOpt, - NSSDER *subject, - nssTokenCertSearch *search -); - -NSS_EXTERN PRStatus -nssToken_TraverseCertificatesByNickname -( - NSSToken *token, - nssSession *sessionOpt, - NSSUTF8 *name, - nssTokenCertSearch *search -); - -NSS_EXTERN PRStatus -nssToken_TraverseCertificatesByEmail -( - NSSToken *token, - nssSession *sessionOpt, - NSSASCII7 *email, - nssTokenCertSearch *search -); - -NSS_EXTERN NSSCertificate * -nssToken_FindCertificateByIssuerAndSerialNumber -( - NSSToken *token, - nssSession *sessionOpt, - NSSDER *issuer, - NSSDER *serial, - nssTokenSearchType searchType -); - -NSS_EXTERN NSSCertificate * -nssToken_FindCertificateByEncodedCertificate -( - NSSToken *token, - nssSession *sessionOpt, - NSSBER *encodedCertificate, - nssTokenSearchType searchType -); - -NSS_EXTERN NSSTrust * -nssToken_FindTrustForCert -( - NSSToken *token, - nssSession *session, - NSSCertificate *c, - nssTokenSearchType searchType -); - -/* exposing this for the smart card cache code */ -NSS_EXTERN nssCryptokiInstance * -nssCryptokiInstance_Create -( - NSSArena *arena, - NSSToken *t, - CK_OBJECT_HANDLE h, - PRBool isTokenObject -); - -#endif /* !PURE_STAN_BUILD */ +#endif PR_END_EXTERN_C diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h index ef2a714432f7..49d2c79dc54e 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.15 $ $Date: 2002/04/05 15:19:37 $ $Name: $"; +static const char DEVT_CVS_ID[] = "@(#) $RCSfile: devt.h,v $ $Revision: 1.16 $ $Date: 2002/04/15 15:22:01 $ $Name: $"; #endif /* DEBUG */ /* @@ -144,7 +144,7 @@ typedef enum { NSSCertificateType_PKIX = 1 } NSSCertificateType; -#ifdef NSS_3_4_CODE +#ifdef nodef /* the current definition of NSSTrust depends on this value being CK_ULONG */ typedef CK_ULONG nssTrustLevel; #else @@ -175,7 +175,8 @@ typedef struct nssTokenCertSearchStr nssTokenCertSearch; typedef enum { nssTokenSearchType_AllObjects = 0, nssTokenSearchType_SessionOnly = 1, - nssTokenSearchType_TokenOnly = 2 + nssTokenSearchType_TokenOnly = 2, + nssTokenSearchType_TokenForced = 3 } nssTokenSearchType; struct nssTokenCertSearchStr diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c index 0f4427f55561..d102056676a7 100644 --- a/security/nss/lib/dev/devtoken.c +++ b/security/nss/lib/dev/devtoken.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.11 $ $Date: 2002/04/04 20:00:22 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.12 $ $Date: 2002/04/15 15:22:01 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSCKEPV_H @@ -48,6 +48,8 @@ static const char CVS_ID[] = "@(#) $RCSfile: devtoken.c,v $ $Revision: 1.11 $ $D #endif /* CKHELPER_H */ #ifdef NSS_3_4_CODE +#include "pk11func.h" +#include "dev3hack.h" #endif /* The number of object handles to grab during each call to C_FindObjects */ @@ -254,7 +256,6 @@ nssToken_NeedsPINInitialization return (!(token->ckFlags & CKF_USER_PIN_INITIALIZED)); } -#ifdef PURE_STAN_BUILD NSS_IMPLEMENT PRStatus nssToken_DeleteStoredObject ( @@ -267,9 +268,11 @@ nssToken_DeleteStoredObject NSSToken *token = instance->token; nssSession *session = NULL; void *epv = nssToken_GetCryptokiEPV(instance->token); +#ifdef PURE_STAN_BUILD if (token->cache) { status = nssTokenObjectCache_RemoveObject(token->cache, instance); } +#endif if (instance->isTokenObject) { if (nssSession_IsReadWrite(token->defaultSession)) { session = token->defaultSession; @@ -304,6 +307,7 @@ import_object { nssSession *session = NULL; PRBool createdSession = PR_FALSE; + nssCryptokiObject *object = NULL; CK_OBJECT_HANDLE handle; CK_RV ckrv; void *epv = nssToken_GetCryptokiEPV(tok); @@ -331,13 +335,13 @@ import_object objectTemplate, otsize, &handle); nssSession_ExitMonitor(session); + if (ckrv == CKR_OK) { + object = nssCryptokiObject_Create(tok, session, handle); + } if (createdSession) { nssSession_Destroy(session); } - if (ckrv != CKR_OK) { - return CK_INVALID_HANDLE; - } - return nssCryptokiObject_Create(tok, session, handle); + return object; } static nssCryptokiObject ** @@ -421,8 +425,11 @@ find_objects } /* bump the number of found objects */ numHandles += count; - if (maximumOpt == 0 || numHandles < arraySize) { - /* either reached maximum, or no more objects to get */ + if (maximumOpt > 0 || numHandles < arraySize) { + /* When a maximum is provided, the search is done all at once, + * so the search is finished. If the number returned was less + * than the number sought, the search is finished. + */ break; } /* the array is filled, double it and continue */ @@ -469,6 +476,7 @@ find_objects_by_template CK_OBJECT_CLASS objclass; nssCryptokiObject **objects = NULL; PRUint32 i; +#ifdef PURE_STAN_BUILD for (i=0; icache) { nssTokenObjectCache_ImportObject(tok->cache, rvObject, CKO_CERTIFICATE, cert_tmpl, ctsize); } +#endif return rvObject; } @@ -909,7 +920,12 @@ static void sha1_hash(NSSItem *input, NSSItem *output) { NSSAlgorithmAndParameters *ap; +#ifdef NSS_3_4_CODE + PK11SlotInfo *internal = PK11_GetInternalSlot(); + NSSToken *token = PK11Slot_GetNSSToken(internal); +#else NSSToken *token = nss_GetDefaultCryptoToken(); +#endif ap = NSSAlgorithmAndParameters_CreateSHA1Digest(NULL); (void)nssToken_Digest(token, NULL, ap, input, output, NULL); #ifdef NSS_3_4_CODE @@ -922,7 +938,12 @@ static void md5_hash(NSSItem *input, NSSItem *output) { NSSAlgorithmAndParameters *ap; +#ifdef NSS_3_4_CODE + PK11SlotInfo *internal = PK11_GetInternalSlot(); + NSSToken *token = PK11Slot_GetNSSToken(internal); +#else NSSToken *token = nss_GetDefaultCryptoToken(); +#endif ap = NSSAlgorithmAndParameters_CreateMD5Digest(NULL); (void)nssToken_Digest(token, NULL, ap, input, output, NULL); #ifdef NSS_3_4_CODE @@ -1001,16 +1022,13 @@ nssToken_ImportTrust NSS_CK_TEMPLATE_FINISH(trust_tmpl, attr, tsize); /* import the trust object onto the token */ object = import_object(tok, sessionOpt, trust_tmpl, tsize); +#ifdef PURE_STAN_BUILD if (object && tok->cache) { nssTokenObjectCache_ImportObject(tok->cache, object, CKO_CERTIFICATE, trust_tmpl, tsize); } - /* XXX - if (object) { - tok->hasNoTrust = PR_FALSE; - } - */ +#endif return object; } @@ -1144,11 +1162,13 @@ nssToken_ImportCRL /* import the crl object onto the token */ object = import_object(token, sessionOpt, crl_tmpl, crlsize); +#ifdef PURE_STAN_BUILD if (object && token->cache) { nssTokenObjectCache_ImportObject(token->cache, object, CKO_CERTIFICATE, crl_tmpl, crlsize); } +#endif return object; } @@ -1191,6 +1211,7 @@ nssToken_FindCRLs return objects; } +#ifdef PURE_STAN_BUILD NSS_IMPLEMENT PRStatus nssToken_GetCachedObjectAttributes ( @@ -1209,7 +1230,7 @@ nssToken_GetCachedObjectAttributes object, objclass, atemplate, atlen); } -#endif /* PURE_STAN_BUILD */ +#endif NSS_IMPLEMENT NSSItem * nssToken_Digest @@ -1370,3 +1391,92 @@ nssToken_FinishDigest return rvItem; } +#ifdef NSS_3_4_CODE + +NSS_IMPLEMENT PRStatus +nssToken_SetTrustCache +( + NSSToken *token +) +{ + CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_TRUST; + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE tobj_template[2]; + CK_ULONG tobj_size; + nssCryptokiObject **objects; + nssSession *session = token->defaultSession; + + NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); + + objects = find_objects_by_template(token, session, + tobj_template, tobj_size, 1, NULL); + token->hasNoTrust = PR_FALSE; + if (objects) { + nssCryptokiObjectArray_Destroy(objects); + } else { + token->hasNoTrust = PR_TRUE; + } + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRStatus +nssToken_SetCrlCache +( + NSSToken *token +) +{ + CK_OBJECT_CLASS tobjc = CKO_NETSCAPE_CRL; + CK_ATTRIBUTE_PTR attr; + CK_ATTRIBUTE tobj_template[2]; + CK_ULONG tobj_size; + nssCryptokiObject **objects; + nssSession *session = token->defaultSession; + + NSS_CK_TEMPLATE_START(tobj_template, attr, tobj_size); + NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, tobjc); + NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true); + NSS_CK_TEMPLATE_FINISH(tobj_template, attr, tobj_size); + + objects = find_objects_by_template(token, session, + tobj_template, tobj_size, 1, NULL); + token->hasNoCrls = PR_TRUE; + if (objects) { + nssCryptokiObjectArray_Destroy(objects); + } else { + token->hasNoCrls = PR_TRUE; + } + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRBool +nssToken_HasCrls +( + NSSToken *tok +) +{ + return !tok->hasNoCrls; +} + +NSS_IMPLEMENT PRStatus +nssToken_SetHasCrls +( + NSSToken *tok +) +{ + tok->hasNoCrls = PR_FALSE; + return PR_SUCCESS; +} + +NSS_IMPLEMENT PRBool +nssToken_IsPresent +( + NSSToken *token +) +{ + return nssSlot_IsTokenPresent(token->slot); +} +#endif + diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c index 302d4e0b6c48..4ce70e2cf777 100644 --- a/security/nss/lib/dev/devutil.c +++ b/security/nss/lib/dev/devutil.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.2 $ $Date: 2002/04/04 20:00:23 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.3 $ $Date: 2002/04/15 15:22:01 $ $Name: $"; #endif /* DEBUG */ #ifndef DEVM_H @@ -43,7 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: devutil.c,v $ $Revision: 1.2 $ $Dat #include "ckhelper.h" #endif /* CKHELPER_H */ -#ifdef PURE_STAN_BUILD NSS_IMPLEMENT nssCryptokiObject * nssCryptokiObject_Create ( @@ -161,6 +160,7 @@ nssSlotArray_Clone return rvSlots; } +#ifdef PURE_STAN_BUILD NSS_IMPLEMENT void nssModuleArray_Destroy ( @@ -175,6 +175,7 @@ nssModuleArray_Destroy nss_ZFreeIf(modules); } } +#endif NSS_IMPLEMENT void nssSlotArray_Destroy @@ -239,6 +240,7 @@ nssCryptokiObjectArray_Destroy } } +#ifdef PURE_STAN_BUILD /* * Slot lists */ diff --git a/security/nss/lib/dev/manifest.mn b/security/nss/lib/dev/manifest.mn index a1f4360f204f..ca1af21ecf9b 100644 --- a/security/nss/lib/dev/manifest.mn +++ b/security/nss/lib/dev/manifest.mn @@ -30,7 +30,7 @@ # may use your version of this file under either the MPL or the # GPL. # -MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.6 $ $Date: 2002/04/04 20:00:23 $ $Name: $" +MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.7 $ $Date: 2002/04/15 15:22:01 $ $Name: $" CORE_DEPTH = ../../.. @@ -50,7 +50,6 @@ MODULE = security CSRCS = \ devmod.c \ devslot.c \ - devobject.c \ devtoken.c \ devutil.c \ ckhelper.c \ diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c index 1f88e99e6081..1c275b731ab3 100644 --- a/security/nss/lib/pk11wrap/dev3hack.c +++ b/security/nss/lib/pk11wrap/dev3hack.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.10 $ $Date: 2002/04/04 20:00:26 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: dev3hack.c,v $ $Revision: 1.11 $ $Date: 2002/04/15 15:22:04 $ $Name: $"; #endif /* DEBUG */ #ifndef NSS_3_4_CODE @@ -173,6 +173,15 @@ nssSlot_IsPermanent return slot->pk11slot->isPerm; } +NSS_IMPLEMENT PRBool +nssSlot_IsFriendly +( + NSSSlot *slot +) +{ + return PK11_IsFriendly(slot->pk11slot); +} + NSS_IMPLEMENT PRStatus nssToken_Refresh(NSSToken *token) { @@ -203,6 +212,19 @@ nssSlot_Refresh return nssToken_Refresh(slot->token); } +NSS_IMPLEMENT PRStatus +nssToken_GetTrustOrder +( + NSSToken *tok +) +{ + PK11SlotInfo *slot; + SECMODModule *module; + slot = tok->pk11slot; + module = PK11_GetModule(slot); + return module->trustOrder; +} + NSSTrustDomain * diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c index 39bbf804fc5e..0addf8e74510 100644 --- a/security/nss/lib/pk11wrap/pk11cert.c +++ b/security/nss/lib/pk11wrap/pk11cert.c @@ -89,50 +89,6 @@ static PRStatus convert_cert(NSSCertificate *c, void *arg) return (secrv) ? PR_FAILURE : PR_SUCCESS; } -static PRStatus convert_and_cache_cert(NSSCertificate *c, void *arg) -{ - PRStatus nssrv; - NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - struct nss3_cert_cbstr *nss3cb = (struct nss3_cert_cbstr *)arg; - NSSCertificate *cp = nssCertificate_AddRef(c); - /* The cert coming in has been retrieved from a token. It was not in - * the cache when the search was begun. But it may be in the cache now, - * and if it isn't, it will be, because it is going to be cracked into - * a CERTCertificate and fed into the callback. - */ - nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1); - /* This is why the hack of copying the cert was done above. The pointer - * c passed to this function is provided by retrieve_cert. That function - * will destroy the pointer once this function returns. Since c is a local - * copy, there is no way to notify retrieve_cert if it has changed. That - * would happen if the above call to add it to the cache found the cert - * already there. In that case, the pointer c passed to the callback - * below will be the cached cert, and the pointer c that retrieve_cert - * has will be the same as the copy made above. Thus, retrieve_cert will - * destroy the reference to the copy, the callback will use the reference - * to the cached entry, and everyone should be happy. - */ - nssrv = convert_cert(c, arg); - /* This function owns a reference to the cert, either from the AddRef - * or by getting it from the cache. - */ - CERT_DestroyCertificate(STAN_GetCERTCertificate(c)); - return nssrv; -} - -/* this is redeclared from trustdomain.c, but this code is just 3.4 glue - * anyway - */ -static void cert_destructor(void *el) -{ - NSSCertificate *c = (NSSCertificate *)el; - CERTCertificate *cert = STAN_GetCERTCertificate(c); - /* It's already been obtained as a CERTCertificate, so it must - * be destroyed as one - */ - CERT_DestroyCertificate(cert); -} - void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst) { @@ -1215,58 +1171,6 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr, return objID; } -static PRStatus -get_newest_cert(NSSCertificate *c, void *arg) -{ - nssDecodedCert *dc, *founddc; - NSSCertificate **cfound = (NSSCertificate **)arg; - if (!*cfound) { - *cfound = nssCertificate_AddRef(c); - return PR_SUCCESS; - } - dc = nssCertificate_GetDecoding(c); - founddc = nssCertificate_GetDecoding(*cfound); - if (!founddc->isNewerThan(founddc, dc)) { - CERT_DestroyCertificate(STAN_GetCERTCertificate(*cfound)); - *cfound = nssCertificate_AddRef(c); - } - return PR_SUCCESS; -} - -struct token_cbstr { - NSSToken *token; - PRStatus (* callback)(NSSCertificate *c, void *arg); - void *cbarg; -}; - -/* This callback matches all certs on a given token. It is used to filter - * cert lists to only those certs on a particular token. - */ -static PRStatus -token_callback(NSSCertificate *c, void *arg) -{ - nssListIterator *instances; - nssCryptokiInstance *instance; - PRBool isToken = PR_FALSE; - struct token_cbstr *token_cb = (struct token_cbstr *)arg; - instances = c->object.instances; - for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); - instance != (nssCryptokiInstance *)NULL; - instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { - if (instance->token == token_cb->token) { - isToken = PR_TRUE; - break; - } - } - nssListIterator_Finish(instances); - if (isToken) { - return (*token_cb->callback)(c, token_cb->cbarg); - } else { - return PR_SUCCESS; - } -} - /* match all token certs with a nickname */ static nssList * filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname) @@ -1286,7 +1190,7 @@ filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname) cert != (NSSCertificate *)NULL; cert = (NSSCertificate *)nssListIterator_Next(certs)) { - NSSUTF8 *tokenNick = NSSCertificate_GetNickname(cert, token); + NSSUTF8 *tokenNick = nssCertificate_GetNickname(cert, token); if (!tokenNick) continue; if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) { nssList_Add(rvList, nssCertificate_AddRef(cert)); @@ -1334,6 +1238,38 @@ filter_token_certs_email(NSSToken *token, NSSASCII7 *email) return rvList; } +static void +transfer_token_certs_to_collection(nssList *certList, NSSToken *token, + nssPKIObjectCollection *collection) +{ + NSSCertificate **certs; + PRUint32 i, count; + NSSToken **tokens, **tp; + count = nssList_Count(certList); + if (count == 0) { + return; + } + certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count); + if (!certs) { + return; + } + nssList_GetArray(certList, (void **)certs, count); + for (i=0; iobject, NULL); + if (tokens) { + for (tp = tokens; *tp; tp++) { + if (*tp == token) { + nssPKIObjectCollection_AddObject(collection, + (nssPKIObject *)certs[i]); + } + } + nssTokenArray_Destroy(tokens); + } + CERT_DestroyCertificate(STAN_GetCERTCertificate(certs[i])); + } + nss_ZFreeIf(certs); +} + CERTCertificate * PK11_FindCertFromNickname(char *nickname, void *wincx) { #ifdef NSS_CLASSIC @@ -1349,8 +1285,10 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { PORT_Free(certID); return cert; #else + PRStatus status; CERTCertificate *rvCert = NULL; NSSCertificate *cert = NULL; + NSSCertificate **certs = NULL; NSSUsage usage; NSSToken *token; PK11SlotInfo *slot = NULL; @@ -1375,111 +1313,89 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) { token = PK11Slot_GetNSSToken(slot); } if (token) { - nssTokenCertSearch search; - struct token_cbstr token_cb; nssList *certList; - + nssCryptokiObject **instances; + nssPKIObjectCollection *collection; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; if (!PK11_IsPresent(slot)) { - return NULL; + goto loser; } if (!PK11_IsFriendly(slot)) { if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { - PK11_FreeSlot(slot); - return NULL; + goto loser; } } - /* find best cert on token */ + collection = nssCertificateCollection_Create(defaultTD, NULL); + if (!collection) { + goto loser; + } if (!nssToken_SearchCerts(token, NULL)) { - /* token certs are in cache, filter the list of token certs to - * match the nickname - */ certList = filter_token_certs_nickname(token, nickname); - if (certList) { - nssCertificateList_DoCallback(certList, - get_newest_cert, - (void *)&cert); - } + transfer_token_certs_to_collection(certList, token, collection); + nssList_Destroy(certList); } else { - /* find matching certs on the token */ certList = nssList_Create(NULL, PR_FALSE); - if (!certList) return NULL; - /* first, get all matching certs from the cache */ + if (!certList) { + nssPKIObjectCollection_Destroy(collection); + goto loser; + } (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, nickname, certList); - /* set the search criteria */ - token_cb.callback = get_newest_cert; - token_cb.cbarg = (void *)&cert; - token_cb.token = token; - search.callback = token_callback; - search.cbarg = &token_cb; - search.cached = certList; - search.searchType = nssTokenSearchType_TokenOnly; - /* now search the token */ - nssToken_TraverseCertificatesByNickname(token, NULL, - (NSSUTF8 *)nickname, - &search); - /* filter the list of cached certs for only those on the token */ - nssCertificateList_DoCallback(certList, - token_callback, - &token_cb); - } - if (certList) { - nssList_Clear(certList, cert_destructor); - nssList_Destroy(certList); + transfer_token_certs_to_collection(certList, token, collection); + instances = nssToken_FindCertificatesByNickname(token, + NULL, + nickname, + tokenOnly, + 0, + &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); } /* if it wasn't found, repeat the process for email address */ - if (!cert) { + if (nssPKIObjectCollection_Count(collection) == 0) { if (!nssToken_SearchCerts(token, NULL)) { certList = filter_token_certs_email(token, nickname); - if (certList) { - nssCertificateList_DoCallback(certList, - get_newest_cert, - (void *)&cert); - } + transfer_token_certs_to_collection(certList, token, collection); + nssList_Destroy(certList); } else { - certList = nssList_Create(NULL, PR_FALSE); - if (!certList) return NULL; - (void)nssTrustDomain_GetCertsForEmailAddressFromCache( - defaultTD, + (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD, nickname, certList); - search.cached = certList; - nssToken_TraverseCertificatesByEmail(token, NULL, - (NSSASCII7 *)nickname, - &search); - nssCertificateList_DoCallback(certList, - token_callback, - &token_cb); - } - if (certList) { - nssList_Clear(certList, cert_destructor); - nssList_Destroy(certList); + transfer_token_certs_to_collection(certList, token, collection); + instances = nssToken_FindCertificatesByEmail(token, + NULL, + nickname, + tokenOnly, + 0, + &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); } } - if (cert) { - (void)nssTrustDomain_AddCertsToCache(defaultTD, &cert, 1); + certs = nssPKIObjectCollection_GetCertificates(collection, + NULL, 0, NULL); + nssPKIObjectCollection_Destroy(collection); + if (certs) { + cert = nssCertificateArray_FindBestCertificate(certs, NULL, + &usage, NULL); rvCert = STAN_GetCERTCertificate(cert); + nssCertificateArray_Destroy(certs); } + nssList_Destroy(certList); } if (slot) { PK11_FreeSlot(slot); } if (nickCopy) PORT_Free(nickCopy); return rvCert; -#endif -} - -static PRStatus -collect_certs(NSSCertificate *c, void *arg) -{ - nssList *list = (nssList *)arg; - /* Add the cert to the return list if not present */ - if (!nssList_Get(list, (void *)c)) { - nssCertificate_AddRef(c); - nssList_Add(list, (void *)c); +loser: + if (slot) { + PK11_FreeSlot(slot); } - return PR_SUCCESS; + if (nickCopy) PORT_Free(nickCopy); + return NULL; +#endif } CERTCertList * @@ -1509,12 +1425,12 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { PORT_Free(certID); return certList; #else - PRStatus nssrv; char *nickCopy; char *delimit = NULL; char *tokenName; int i; CERTCertList *certList = NULL; + nssPKIObjectCollection *collection = NULL; NSSCertificate **foundCerts = NULL; NSSTrustDomain *defaultTD = STAN_GetDefaultTrustDomain(); NSSCertificate *c; @@ -1538,8 +1454,6 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { token = PK11Slot_GetNSSToken(slot); } if (token) { - nssTokenCertSearch search; - PRUint32 count; nssList *nameList; if (!PK11_IsFriendly(slot)) { if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) { @@ -1547,28 +1461,40 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) { return NULL; } } + collection = nssCertificateCollection_Create(defaultTD, NULL); + if (!collection) { + PK11_FreeSlot(slot); + return NULL; + } if (!nssToken_SearchCerts(token, NULL)) { nameList = filter_token_certs_nickname(token, nickname); + transfer_token_certs_to_collection(nameList, token, collection); } else { + PRStatus status; + nssCryptokiObject **instances; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; nameList = nssList_Create(NULL, PR_FALSE); - if (!nameList) return NULL; + if (!nameList) { + PK11_FreeSlot(slot); + return NULL; + } (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD, nickname, nameList); - /* set the search criteria */ - search.callback = collect_certs; - search.cbarg = nameList; - search.cached = nameList; - search.searchType = nssTokenSearchType_TokenOnly; - nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, - nickname, &search); - } - if (nameList) { - count = nssList_Count(nameList); - foundCerts = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); - nssList_GetArray(nameList, (void **)foundCerts, count); - nssList_Destroy(nameList); + transfer_token_certs_to_collection(nameList, token, collection); + instances = nssToken_FindCertificatesByNickname(token, + NULL, + nickname, + tokenOnly, + 0, + &status); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); } + nssList_Destroy(nameList); + foundCerts = nssPKIObjectCollection_GetCertificates(collection, + NULL, 0, NULL); + nssPKIObjectCollection_Destroy(collection); } if (slot) { PK11_FreeSlot(slot); @@ -1815,10 +1741,7 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert, instance->token = slot->nssToken; instance->handle = cert->pkcs11ID; instance->isTokenObject = PR_TRUE; - nssList_Add(c->object.instanceList, instance); - /* XXX Fix this! */ - nssListIterator_Destroy(c->object.instances); - c->object.instances = nssList_CreateIterator(c->object.instanceList); + nssPKIObject_AddInstance(&c->object, instance); } else { cert->nssCertificate = STAN_GetNSSCertificate(cert); } @@ -2629,40 +2552,6 @@ filter_token_certs_subject(NSSToken *token, NSSDER *subject) return rvList; } -/* remove all certs in a list that are not on the given token */ -static void -filter_list_for_token_certs(nssList *certList, NSSToken *token) -{ - nssListIterator *instances, *certs; - nssCryptokiInstance *instance; - NSSCertificate *c; - PRBool isToken = PR_FALSE; - certs = nssList_CreateIterator(certList); - if (!certs) return; - for (c = (NSSCertificate *)nssListIterator_Start(certs); - c != (NSSCertificate *)NULL; - c = (NSSCertificate *)nssListIterator_Next(certs)) { - instances = c->object.instances; - for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); - instance != (nssCryptokiInstance *)NULL; - instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { - if (instance->token == token) { - isToken = PR_TRUE; - break; - } - } - nssListIterator_Finish(instances); - if (!isToken) { - /* safe since iterator is copied */ - nssList_Remove(certList, c); - CERT_DestroyCertificate(STAN_GetCERTCertificate(c)); - } - } - nssListIterator_Finish(certs); - nssListIterator_Destroy(certs); -} - SECStatus PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, SECStatus(* callback)(CERTCertificate*, void *), void *arg) @@ -2695,48 +2584,51 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot, return PK11_TraverseSlot(slot, &callarg); #else - struct nss3_cert_cbstr pk11cb; PRStatus nssrv = PR_SUCCESS; NSSToken *token; NSSDER subject; NSSTrustDomain *td; nssList *subjectList; - nssTokenCertSearch search; - pk11cb.callback = callback; - pk11cb.arg = arg; + nssPKIObjectCollection *collection; + nssCryptokiObject **instances; + NSSCertificate **certs; td = STAN_GetDefaultTrustDomain(); NSSITEM_FROM_SECITEM(&subject, &cert->derSubject); token = PK11Slot_GetNSSToken(slot); + collection = nssCertificateCollection_Create(td, NULL); if (!nssToken_SearchCerts(token, NULL)) { subjectList = filter_token_certs_subject(token, &subject); - if (subjectList) { - nssrv = nssCertificateList_DoCallback(subjectList, - convert_cert, &pk11cb); - } + transfer_token_certs_to_collection(subjectList, token, collection); } else { + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; subjectList = nssList_Create(NULL, PR_FALSE); if (!subjectList) { return SECFailure; } (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject, subjectList); - /* set the search criteria */ - search.callback = convert_and_cache_cert; - search.cbarg = &pk11cb; - search.cached = subjectList; - search.searchType = nssTokenSearchType_TokenOnly; - pk11cb.cached = subjectList; - nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, - &subject, &search); - if (nssrv == PR_SUCCESS) { - filter_list_for_token_certs(subjectList, token); - nssrv = nssCertificateList_DoCallback(subjectList, - convert_cert, &pk11cb); - } + transfer_token_certs_to_collection(subjectList, token, collection); + instances = nssToken_FindCertificatesBySubject(token, NULL, + &subject, + tokenOnly, 0, &nssrv); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); } - if (subjectList) { - nssList_Clear(subjectList, cert_destructor); - nssList_Destroy(subjectList); + nssList_Destroy(subjectList); + certs = nssPKIObjectCollection_GetCertificates(collection, + NULL, 0, NULL); + nssPKIObjectCollection_Destroy(collection); + if (certs) { + CERTCertificate *oldie; + NSSCertificate **cp; + for (cp = certs; *cp; cp++) { + oldie = STAN_GetCERTCertificate(*cp); + if ((*callback)(oldie, arg) != SECSuccess) { + nssrv = PR_FAILURE; + break; + } + } + nssCertificateArray_Destroy(certs); } return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; #endif @@ -2785,7 +2677,9 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, NSSTrustDomain *td; NSSUTF8 *nick; PRBool created = PR_FALSE; - nssTokenCertSearch search; + nssCryptokiObject **instances; + nssPKIObjectCollection *collection; + NSSCertificate **certs; nssList *nameList; pk11cb.callback = callback; pk11cb.arg = arg; @@ -2798,32 +2692,39 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot, } td = STAN_GetDefaultTrustDomain(); token = PK11Slot_GetNSSToken(slot); + collection = nssCertificateCollection_Create(td, NULL); if (!nssToken_SearchCerts(token, NULL)) { nameList = filter_token_certs_nickname(token, nick); - if (nameList) { - nssrv = nssCertificateList_DoCallback(nameList, - convert_cert, &pk11cb); - } + transfer_token_certs_to_collection(nameList, token, collection); } else { + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; nameList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList); - /* set the search criteria */ - search.callback = convert_and_cache_cert; - search.cbarg = &pk11cb; - search.cached = nameList; - search.searchType = nssTokenSearchType_TokenOnly; - pk11cb.cached = nameList; - nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, - nick, &search); - if (nssrv == PR_SUCCESS) { - filter_list_for_token_certs(nameList, token); - nssrv = nssCertificateList_DoCallback(nameList, - convert_cert, &pk11cb); + if (!nameList) { + return SECFailure; } + (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList); + transfer_token_certs_to_collection(nameList, token, collection); + instances = nssToken_FindCertificatesByNickname(token, NULL, + nick, + tokenOnly, 0, &nssrv); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); } - if (nameList) { - nssList_Clear(nameList, cert_destructor); - nssList_Destroy(nameList); + nssList_Destroy(nameList); + certs = nssPKIObjectCollection_GetCertificates(collection, + NULL, 0, NULL); + nssPKIObjectCollection_Destroy(collection); + if (certs) { + CERTCertificate *oldie; + NSSCertificate **cp; + for (cp = certs; *cp; cp++) { + oldie = STAN_GetCERTCertificate(*cp); + if ((*callback)(oldie, arg) != SECSuccess) { + nssrv = PR_FAILURE; + break; + } + } + nssCertificateArray_Destroy(certs); } if (created) nss_ZFreeIf(nick); return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; @@ -2862,36 +2763,47 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot, #else PRStatus nssrv; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - struct nss3_cert_cbstr pk11cb; NSSToken *tok; nssList *certList = NULL; - nssTokenCertSearch search; - pk11cb.callback = callback; - pk11cb.arg = arg; + nssCryptokiObject **instances; + nssPKIObjectCollection *collection; + NSSCertificate **certs; tok = PK11Slot_GetNSSToken(slot); + collection = nssCertificateCollection_Create(td, NULL); + if (!collection) { + return SECFailure; + } if (!nssToken_SearchCerts(tok, NULL)) { - certList = tok->certList; - nssrv = nssCertificateList_DoCallback(certList, convert_cert, &pk11cb); + certList = nssList_Clone(tok->certList); + transfer_token_certs_to_collection(certList, tok, collection); } else { + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; certList = nssList_Create(NULL, PR_FALSE); if (!certList) { return SECFailure; } (void *)nssTrustDomain_GetCertsFromCache(td, certList); - /* set the search criteria */ - search.callback = convert_and_cache_cert; - search.cbarg = &pk11cb; - search.cached = certList; - search.searchType = nssTokenSearchType_TokenOnly; - pk11cb.cached = certList; - nssrv = nssToken_TraverseCertificates(tok, NULL, &search); - if (nssrv == PR_SUCCESS) { - filter_list_for_token_certs(certList, tok); - nssrv = nssCertificateList_DoCallback(certList, - convert_cert, &pk11cb); + transfer_token_certs_to_collection(certList, tok, collection); + instances = nssToken_FindCertificates(tok, NULL, + tokenOnly, 0, &nssrv); + nssPKIObjectCollection_AddInstances(collection, instances, 0); + nss_ZFreeIf(instances); + } + nssList_Destroy(certList); + certs = nssPKIObjectCollection_GetCertificates(collection, + NULL, 0, NULL); + nssPKIObjectCollection_Destroy(collection); + if (certs) { + CERTCertificate *oldie; + NSSCertificate **cp; + for (cp = certs; *cp; cp++) { + oldie = STAN_GetCERTCertificate(*cp); + if ((*callback)(oldie, arg) != SECSuccess) { + nssrv = PR_FAILURE; + break; + } } - nssList_Clear(certList, cert_destructor); - nssList_Destroy(certList); + nssCertificateArray_Destroy(certs); } return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure; #endif @@ -2973,11 +2885,24 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert, if (!nssToken_SearchCerts(tok, NULL)) { c = filter_token_certs_DER(tok, &derCert); } else { - c = nssTrustDomain_GetCertByDERFromCache(td, &derCert); - if (!c) { - c = nssToken_FindCertificateByEncodedCertificate(tok, NULL, - &derCert, - nssTokenSearchType_TokenOnly); + c = NSSTrustDomain_FindCertificateByEncodedCertificate(td, &derCert); + if (c) { + PRBool isToken = PR_FALSE; + NSSToken **tp; + NSSToken **tokens = nssPKIObject_GetTokens(&c->object, NULL); + if (tokens) { + for (tp = tokens; *tp; tp++) { + if (*tp == tok) { + isToken = PR_TRUE; + break; + } + } + if (!isToken) { + NSSCertificate_Destroy(c); + c = NULL; + } + nssTokenArray_Destroy(tokens); + } } } if (c) { diff --git a/security/nss/lib/pki/certdecode.c b/security/nss/lib/pki/certdecode.c index e561fc8cfc62..eb76be828bec 100644 --- a/security/nss/lib/pki/certdecode.c +++ b/security/nss/lib/pki/certdecode.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.11 $ $Date: 2002/02/04 22:34:22 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.12 $ $Date: 2002/04/15 15:22:07 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIT_H @@ -43,78 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile: certdecode.c,v $ $Revision: 1.11 $ #include "pkim.h" #endif /* PKIM_H */ -/* XXX - * move this to a more appropriate location - */ -NSS_IMPLEMENT PRStatus -nssPKIObject_Initialize -( - struct nssPKIObjectBaseStr *object, - NSSArena *arena, - NSSTrustDomain *td, - NSSCryptoContext *cc -) -{ - object->arena = arena; - object->trustDomain = td; - object->cryptoContext = cc; - object->lock = PZ_NewLock(nssILockOther); - if (!object->lock) { - return PR_FAILURE; - } - object->instanceList = nssList_Create(arena, PR_TRUE); - if (!object->instanceList) { - PZ_DestroyLock(object->lock); - return PR_FAILURE; - } - object->instances = nssList_CreateIterator(object->instanceList); - if (!object->instances) { - nssList_Destroy(object->instanceList); - PZ_DestroyLock(object->lock); - return PR_FAILURE; - } - object->refCount = 1; - return PR_SUCCESS; -} - -/* XXX - * move this to a more appropriate location - */ -NSS_IMPLEMENT void -nssPKIObject_AddRef -( - struct nssPKIObjectBaseStr *object -) -{ - PZ_Lock(object->lock); - object->refCount++; - PZ_Unlock(object->lock); -} - -/* XXX - * move this to a more appropriate location - */ -NSS_IMPLEMENT PRBool -nssPKIObject_Destroy -( - struct nssPKIObjectBaseStr *object -) -{ - PRUint32 refCount; - PZ_Lock(object->lock); - PORT_Assert(object->refCount > 0); - refCount = --object->refCount; - PZ_Unlock(object->lock); - if (refCount == 0) { - PZ_DestroyLock(object->lock); - nssListIterator_Destroy(object->instances); - nssList_Destroy(object->instanceList); - nssArena_Destroy(object->arena); - return PR_TRUE; - } - return PR_FALSE; -} - #ifdef NSS_3_4_CODE /* This is defined in nss3hack.c */ NSS_EXTERN nssDecodedCert * @@ -194,39 +122,3 @@ nssDecodedCert_Destroy return PR_FAILURE; } -/* Of course none of this belongs here */ - -/* how bad would it be to have a static now sitting around, updated whenever - * this was called? would avoid repeated allocs... - */ -NSS_IMPLEMENT NSSTime * -NSSTime_Now -( - NSSTime *timeOpt -) -{ - return NSSTime_SetPRTime(timeOpt, PR_Now()); -} - -NSS_IMPLEMENT NSSTime * -NSSTime_SetPRTime -( - NSSTime *timeOpt, - PRTime prTime -) -{ - NSSTime *rvTime; - rvTime = (timeOpt) ? timeOpt : nss_ZNEW(NULL, NSSTime); - rvTime->prTime = prTime; - return rvTime; -} - -NSS_IMPLEMENT PRTime -NSSTime_GetPRTime -( - NSSTime *time -) -{ - return time->prTime; -} - diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c index bca38ed5a9a7..6ed097b36d47 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.33 $ $Date: 2002/03/07 22:07:55 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.34 $ $Date: 2002/04/15 15:22:07 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSPKI_H @@ -61,6 +61,40 @@ static const char CVS_ID[] = "@(#) $RCSfile: certificate.c,v $ $Revision: 1.33 $ extern const NSSError NSS_ERROR_NOT_FOUND; +/* Creates a certificate from a base object */ +NSS_IMPLEMENT NSSCertificate * +nssCertificate_Create +( + nssPKIObject *object +) +{ + PRStatus status; + NSSCertificate *rvCert; + /* mark? */ + NSSArena *arena = object->arena; + PR_ASSERT(object->instances != NULL && object->numInstances > 0); + rvCert = nss_ZNEW(arena, NSSCertificate); + if (!rvCert) { + return (NSSCertificate *)NULL; + } + rvCert->object = *object; + /* XXX should choose instance based on some criteria */ + status = nssCryptokiCertificate_GetAttributes(object->instances[0], + NULL, /* XXX sessionOpt */ + arena, + &rvCert->type, + &rvCert->id, + &rvCert->encoding, + &rvCert->issuer, + &rvCert->serial, + &rvCert->subject, + &rvCert->email); + if (status != PR_SUCCESS) { + return (NSSCertificate *)NULL; + } + return rvCert; +} + NSS_IMPLEMENT NSSCertificate * nssCertificate_AddRef ( @@ -74,7 +108,7 @@ nssCertificate_AddRef } NSS_IMPLEMENT PRStatus -NSSCertificate_Destroy +nssCertificate_Destroy ( NSSCertificate *c ) @@ -92,37 +126,84 @@ NSSCertificate_Destroy return PR_SUCCESS; } +NSS_IMPLEMENT PRStatus +NSSCertificate_Destroy +( + NSSCertificate *c +) +{ + return nssCertificate_Destroy(c); +} + +NSS_IMPLEMENT NSSDER * +nssCertificate_GetEncoding +( + NSSCertificate *c +) +{ + if (c->encoding.size > 0 && c->encoding.data) { + return &c->encoding; + } else { + return (NSSDER *)NULL; + } +} + +NSS_IMPLEMENT NSSDER * +nssCertificate_GetIssuer +( + NSSCertificate *c +) +{ + if (c->issuer.size > 0 && c->issuer.data) { + return &c->issuer; + } else { + return (NSSDER *)NULL; + } +} + +NSS_IMPLEMENT NSSDER * +nssCertificate_GetSerialNumber +( + NSSCertificate *c +) +{ + if (c->serial.size > 0 && c->serial.data) { + return &c->serial; + } else { + return (NSSDER *)NULL; + } +} + +NSS_IMPLEMENT NSSDER * +nssCertificate_GetSubject +( + NSSCertificate *c +) +{ + if (c->subject.size > 0 && c->subject.data) { + return &c->subject; + } else { + return (NSSDER *)NULL; + } +} + NSS_IMPLEMENT NSSUTF8 * -NSSCertificate_GetNickname +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; + return nssPKIObject_GetNicknameForToken(&c->object, tokenOpt); +} + +NSS_IMPLEMENT NSSASCII7 * +nssCertificate_GetEmailAddress +( + NSSCertificate *c +) +{ + return c->email; } NSS_IMPLEMENT PRStatus @@ -132,39 +213,7 @@ NSSCertificate_DeleteStoredObject NSSCallback *uhh ) { - /* this needs more thought on what will happen when there are multiple - * instances - */ - /* XXX use callback to log in if neccessary */ - PRStatus nssrv = PR_SUCCESS; - nssCryptokiInstance *instance; - nssListIterator *instances = c->object.instances; - for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); - instance != (nssCryptokiInstance *)NULL; - instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { - /* XXX this should be fixed to understand read-only tokens, for - * now, to handle the builtins, just make the attempt. - */ - nssrv = nssToken_DeleteStoredObject(instance); - if (nssrv == PR_SUCCESS) { - nssList_Remove(c->object.instanceList, instance); -#ifdef NSS_3_4_CODE - if (instance->token->certList) { - /* If the cert has been cached locally on the token, remove - * that reference - */ - nssList_Remove(instance->token->certList, c); - NSSCertificate_Destroy(c); - } -#endif - } - } - nssListIterator_Finish(instances); - c->object.instances = nssList_CreateIterator(c->object.instanceList); - nssListIterator_Destroy(instances); - /* XXX for now, always success */ - return PR_SUCCESS; + return nssPKIObject_DeleteStoredObject(&c->object, uhh, PR_TRUE); } NSS_IMPLEMENT PRStatus @@ -238,85 +287,171 @@ nssCertificate_GetDecoding return c->decoding; } -static void -nssCertificateArray_Destroy -( - NSSCertificate **certArray -) -{ - NSSCertificate **ci; - ci = certArray; - while (ci && *ci) { - NSSCertificate_Destroy(*ci); - ci++; - } - nss_ZFreeIf(certArray); -} - static NSSCertificate * -filter_subject_certs_for_id(NSSCertificate **subjectCerts, NSSItem *id) +filter_subject_certs_for_id +( + NSSCertificate **subjectCerts, + NSSItem *id +) { NSSCertificate **si; NSSCertificate *rvCert = NULL; nssDecodedCert *dcp; /* walk the subject certs */ - si = subjectCerts; - while (*si) { + for (si = subjectCerts; *si; si++) { dcp = nssCertificate_GetDecoding(*si); if (dcp->matchIdentifier(dcp, id)) { /* this cert has the correct identifier */ rvCert = nssCertificate_AddRef(*si); break; } - si++; } return rvCert; } static NSSCertificate * -find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id) +find_cert_issuer +( + NSSCertificate *c, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) { - NSSCertificate *rvCert = NULL; - NSSCertificate **subjectCerts = NULL; + NSSArena *arena; + NSSCertificate **certs = NULL; + NSSCertificate **ccIssuers = NULL; + NSSCertificate **tdIssuers = NULL; + NSSCertificate *issuer = NULL; NSSTrustDomain *td; NSSCryptoContext *cc; - /* Find all certs with this cert's issuer as the subject */ cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */ + td = NSSCertificate_GetTrustDomain(c); +#ifdef NSS_3_4_CODE + if (!td) { + td = STAN_GetDefaultTrustDomain(); + } +#endif + arena = nssArena_Create(); + if (!arena) { + return (NSSCertificate *)NULL; + } if (cc) { - subjectCerts = NSSCryptoContext_FindCertificatesBySubject(cc, - &c->issuer, - NULL, - 0, - NULL); - if (subjectCerts) { - rvCert = filter_subject_certs_for_id(subjectCerts, id); - nssCertificateArray_Destroy(subjectCerts); - } + ccIssuers = nssCryptoContext_FindCertificatesBySubject(cc, + &c->issuer, + NULL, + 0, + arena); } - if (!rvCert) { - /* The general behavior of NSS <3.4 seems to be that if the search - * turns up empty in the temp db, fall back to the perm db, - * irregardless of whether or not the cert itself is perm or temp. - * This is replicated here. - */ - td = NSSCertificate_GetTrustDomain(c); - subjectCerts = NSSTrustDomain_FindCertificatesBySubject(td, - &c->issuer, - NULL, - 0, - NULL); - if (subjectCerts) { - rvCert = filter_subject_certs_for_id(subjectCerts, id); - nssCertificateArray_Destroy(subjectCerts); + tdIssuers = nssTrustDomain_FindCertificatesBySubject(td, + &c->issuer, + NULL, + 0, + arena); + certs = nssCertificateArray_Join(ccIssuers, tdIssuers); + if (certs) { + nssDecodedCert *dc = NULL; + NSSItem *issuerID = NULL; + dc = nssCertificate_GetDecoding(c); + if (dc) { + issuerID = dc->getIssuerIdentifier(dc); } + if (issuerID) { + issuer = filter_subject_certs_for_id(certs, issuerID); + nssItem_Destroy(issuerID); + } else { + issuer = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + } + nssCertificateArray_Destroy(certs); } - return rvCert; + nssArena_Destroy(arena); + return issuer; } /* XXX review based on CERT_FindCertIssuer * this function is not using the authCertIssuer field as a fallback * if authority key id does not exist */ +NSS_IMPLEMENT NSSCertificate ** +nssCertificate_BuildChain +( + NSSCertificate *c, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt, + NSSCertificate **rvOpt, + PRUint32 rvLimit, + NSSArena *arenaOpt, + PRStatus *statusOpt +) +{ + PRStatus status; + NSSCertificate **rvChain; +#ifdef NSS_3_4_CODE + NSSCertificate *cp; +#endif + NSSTrustDomain *td; + nssPKIObjectCollection *collection; + td = NSSCertificate_GetTrustDomain(c); +#ifdef NSS_3_4_CODE + if (!td) { + td = STAN_GetDefaultTrustDomain(); + } +#endif + if (statusOpt) *statusOpt = PR_SUCCESS; + collection = nssCertificateCollection_Create(td, NULL); + if (!collection) { + if (statusOpt) *statusOpt = PR_FAILURE; + return (NSSCertificate **)NULL; + } + nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c); + if (rvLimit == 1) { + goto finish; + } + while (!nssItem_Equal(&c->subject, &c->issuer, &status)) { +#ifdef NSS_3_4_CODE + cp = c; +#endif + c = find_cert_issuer(c, timeOpt, usage, policiesOpt); +#ifdef NSS_3_4_CODE + if (!c) { + PRBool tmpca = usage->nss3lookingForCA; + usage->nss3lookingForCA = PR_TRUE; + c = find_cert_issuer(cp, timeOpt, usage, policiesOpt); + if (!c && !usage->anyUsage) { + usage->anyUsage = PR_TRUE; + c = find_cert_issuer(cp, timeOpt, usage, policiesOpt); + usage->anyUsage = PR_FALSE; + } + usage->nss3lookingForCA = tmpca; + } +#endif /* NSS_3_4_CODE */ + if (c) { + nssPKIObjectCollection_AddObject(collection, (nssPKIObject *)c); + nssCertificate_Destroy(c); /* collection has it */ + if (rvLimit > 0 && + nssPKIObjectCollection_Count(collection) == rvLimit) + { + break; + } + } else { + nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND); + if (statusOpt) *statusOpt = PR_FAILURE; + break; + } + } +finish: + rvChain = nssPKIObjectCollection_GetCertificates(collection, + rvOpt, + rvLimit, + arenaOpt); + nssPKIObjectCollection_Destroy(collection); + return rvChain; +} + NSS_IMPLEMENT NSSCertificate ** NSSCertificate_BuildChain ( @@ -330,129 +465,26 @@ NSSCertificate_BuildChain PRStatus *statusOpt ) { - PRStatus nssrv; - nssList *chain; - NSSItem *issuerID; - NSSCertificate **rvChain; - NSSTrustDomain *td; - NSSCryptoContext *cc; - nssDecodedCert *dc; - NSSCertificate *ct, *cp; - cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */ - td = NSSCertificate_GetTrustDomain(c); -#ifdef NSS_3_4_CODE - if (!td) { - td = STAN_GetDefaultTrustDomain(); - } -#endif - chain = nssList_Create(NULL, PR_FALSE); - nssList_Add(chain, nssCertificate_AddRef(c)); - if (statusOpt) *statusOpt = PR_SUCCESS; - if (rvLimit == 1) goto finish; - while (!nssItem_Equal(&c->subject, &c->issuer, &nssrv)) { - dc = nssCertificate_GetDecoding(c); - issuerID = dc->getIssuerIdentifier(dc); - if (issuerID) { - c = find_issuer_cert_for_identifier(c, issuerID); - nssItem_Destroy(issuerID); - issuerID = NULL; - if (!c) { - nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND); - if (statusOpt) *statusOpt = PR_FAILURE; - goto finish; - } - } else { - nssBestCertificateCB best; - NSSDER *issuer = &c->issuer; -#ifdef NSS_3_4_CODE - PRBool tmpca = usage->nss3lookingForCA; - usage->nss3lookingForCA = PR_TRUE; -#endif - c = ct = cp = NULL; - if (cc) { - ct = NSSCryptoContext_FindBestCertificateBySubject(cc, - issuer, - timeOpt, - usage, - policiesOpt); - /* Mimic functionality from CERT_FindCertIssuer. If a matching - * cert (based on trust & usage) cannot be found, just take the - * newest cert with the correct subject. - */ - if (!ct && !usage->anyUsage) { - usage->anyUsage = PR_TRUE; - ct = NSSCryptoContext_FindBestCertificateBySubject(cc, - issuer, - timeOpt, - usage, - policiesOpt); - usage->anyUsage = PR_FALSE; - } - } - cp = NSSTrustDomain_FindBestCertificateBySubject(td, - issuer, - timeOpt, - usage, - policiesOpt); - /* Mimic functionality from CERT_FindCertIssuer. If a matching - * cert (based on trust & usage) cannot be found, just take the - * newest cert with the correct subject. - */ - if (!cp && !usage->anyUsage) { - usage->anyUsage = PR_TRUE; - cp = NSSTrustDomain_FindBestCertificateBySubject(td, - issuer, - timeOpt, - usage, - policiesOpt); - usage->anyUsage = PR_FALSE; - } - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - /* Take the better of the best temp and best perm cert, according - * to the given usage - */ - if (ct) { - nssBestCertificate_Callback(ct, (void *)&best); - } - if (cp) { - nssBestCertificate_Callback(cp, (void *)&best); - } - if (!best.cert) { - best.usage->anyUsage = PR_TRUE; - /* Take the newest of the best temp and best perm cert */ - if (ct) { - nssBestCertificate_Callback(ct, (void *)&best); - } - if (cp) { - nssBestCertificate_Callback(cp, (void *)&best); - } - } - if (ct) NSSCertificate_Destroy(ct); - if (cp) NSSCertificate_Destroy(cp); - c = best.cert; -#ifdef NSS_3_4_CODE - usage->nss3lookingForCA = tmpca; -#endif - if (!c) { - nss_SetError(NSS_ERROR_CERTIFICATE_ISSUER_NOT_FOUND); - if (statusOpt) *statusOpt = PR_FAILURE; - goto finish; - } - } - nssList_Add(chain, c); - if (nssList_Count(chain) == rvLimit) goto finish; - } -finish: - if (rvOpt) { - rvChain = rvOpt; - } else { - rvLimit = nssList_Count(chain); - rvChain = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, rvLimit + 1); - } - nssList_GetArray(chain, (void **)rvChain, rvLimit); - nssList_Destroy(chain); - /* XXX now, the question is, cache all certs in the chain? */ - return rvChain; + return nssCertificate_BuildChain(c, timeOpt, usage, policiesOpt, + rvOpt, rvLimit, arenaOpt, statusOpt); +} + +NSS_IMPLEMENT NSSCryptoContext * +nssCertificate_GetCryptoContext +( + NSSCertificate *c +) +{ + return c->object.cryptoContext; +} + +NSS_IMPLEMENT NSSTrustDomain * +nssCertificate_GetTrustDomain +( + NSSCertificate *c +) +{ + return c->object.trustDomain; } NSS_IMPLEMENT NSSTrustDomain * @@ -461,7 +493,7 @@ NSSCertificate_GetTrustDomain NSSCertificate *c ) { - return c->object.trustDomain; + return nssCertificate_GetTrustDomain(c); } NSS_IMPLEMENT NSSToken * @@ -825,22 +857,24 @@ nssSMIMEProfile_Create NSSItem *profileData ) { - PRStatus nssrv; NSSArena *arena; nssSMIMEProfile *rvProfile; + nssPKIObject *object; + NSSTrustDomain *td = nssCertificate_GetTrustDomain(cert); + NSSCryptoContext *cc = nssCertificate_GetCryptoContext(cert); arena = nssArena_Create(); if (!arena) { return NULL; } - rvProfile = nss_ZNEW(arena, nssSMIMEProfile); - if (!rvProfile) { - nssArena_Destroy(arena); - return NULL; - } - nssrv = nssPKIObject_Initialize(&rvProfile->object, arena, NULL, NULL); - if (nssrv != PR_SUCCESS) { + object = nssPKIObject_Create(arena, NULL, td, cc); + if (!object) { goto loser; } + rvProfile = nss_ZNEW(arena, nssSMIMEProfile); + if (!rvProfile) { + goto loser; + } + rvProfile->object = *object; rvProfile->certificate = cert; rvProfile->email = nssUTF8_Duplicate(cert->email, arena); rvProfile->subject = nssItem_Duplicate(&cert->subject, arena, NULL); @@ -852,8 +886,8 @@ nssSMIMEProfile_Create } return rvProfile; loser: - nssPKIObject_Destroy(&rvProfile->object); - return NULL; + nssPKIObject_Destroy(object); + return (nssSMIMEProfile *)NULL; } /* execute a callback function on all members of a cert list */ @@ -895,6 +929,65 @@ nssCertificateList_AddReferences (void)nssCertificateList_DoCallback(certList, add_ref_callback, NULL); } +NSS_IMPLEMENT NSSTrust * +nssTrust_Create +( + nssPKIObject *object +) +{ + PRStatus status; + PRUint32 i; + PRUint32 lastTrustOrder, myTrustOrder; + NSSTrust *rvt; + nssCryptokiObject *instance; + nssTrustLevel serverAuth, clientAuth, codeSigning, emailProtection; + lastTrustOrder = 1<<16; /* just make it big */ + PR_ASSERT(object->instances != NULL && object->numInstances > 0); + rvt = nss_ZNEW(object->arena, NSSTrust); + if (!rvt) { + return (NSSTrust *)NULL; + } + rvt->object = *object; + /* trust has to peek into the base object members */ + PZ_Lock(object->lock); + for (i=0; inumInstances; i++) { + instance = object->instances[i]; + myTrustOrder = nssToken_GetTrustOrder(instance->token); + status = nssCryptokiTrust_GetAttributes(instance, NULL, + &serverAuth, + &clientAuth, + &codeSigning, + &emailProtection); + if (status != PR_SUCCESS) { + PZ_Unlock(object->lock); + return (NSSTrust *)NULL; + } + if (rvt->serverAuth == nssTrustLevel_Unknown || + myTrustOrder < lastTrustOrder) + { + rvt->serverAuth = serverAuth; + } + if (rvt->clientAuth == nssTrustLevel_Unknown || + myTrustOrder < lastTrustOrder) + { + rvt->clientAuth = clientAuth; + } + if (rvt->emailProtection == nssTrustLevel_Unknown || + myTrustOrder < lastTrustOrder) + { + rvt->emailProtection = emailProtection; + } + if (rvt->codeSigning == nssTrustLevel_Unknown || + myTrustOrder < lastTrustOrder) + { + rvt->codeSigning = codeSigning; + } + lastTrustOrder = myTrustOrder; + } + PZ_Unlock(object->lock); + return rvt; +} + NSS_IMPLEMENT NSSTrust * nssTrust_AddRef ( diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c index d6668bc98352..33827c3264b3 100644 --- a/security/nss/lib/pki/cryptocontext.c +++ b/security/nss/lib/pki/cryptocontext.c @@ -32,36 +32,59 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.9 $ $Date: 2002/02/06 19:58:54 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: cryptocontext.c,v $ $Revision: 1.10 $ $Date: 2002/04/15 15:22:08 $ $Name: $"; #endif /* DEBUG */ -#ifndef NSSPKI_H -#include "nsspki.h" -#endif /* NSSPKI_H */ - -#ifndef PKIM_H -#include "pkim.h" -#endif /* PKIM_H */ - -#ifndef PKIT_H -#include "pkit.h" -#endif /* PKIT_H */ - #ifndef DEV_H #include "dev.h" #endif /* DEV_H */ +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + #ifndef PKISTORE_H #include "pkistore.h" #endif /* PKISTORE_H */ -#ifdef NSS_3_4_CODE -#include "pk11func.h" -#include "dev3hack.h" +#include "pki1t.h" + +#ifdef PURE_STAN_BUILD +struct NSSCryptoContextStr +{ + PRInt32 refCount; + NSSArena *arena; + NSSTrustDomain *td; + NSSToken *token; + nssSession *session; + nssCertificateStore *certStore; +}; #endif extern const NSSError NSS_ERROR_NOT_FOUND; +NSS_IMPLEMENT NSSCryptoContext * +nssCryptoContext_Create +( + NSSTrustDomain *td, + NSSCallback *uhhOpt +) +{ + NSSArena *arena; + NSSCryptoContext *rvCC; + arena = NSSArena_Create(); + if (!arena) { + return NULL; + } + rvCC = nss_ZNEW(arena, NSSCryptoContext); + if (!rvCC) { + return NULL; + } + rvCC->td = td; + rvCC->arena = arena; + return rvCC; +} + NSS_IMPLEMENT PRStatus NSSCryptoContext_Destroy ( @@ -177,9 +200,11 @@ nssCryptoContext_ImportTrust } } nssrv = nssCertificateStore_AddTrust(cc->certStore, trust); +#if 0 if (nssrv == PR_SUCCESS) { trust->object.cryptoContext = cc; } +#endif return nssrv; } @@ -198,9 +223,11 @@ nssCryptoContext_ImportSMIMEProfile } } nssrv = nssCertificateStore_AddSMIMEProfile(cc->certStore, profile); +#if 0 if (nssrv == PR_SUCCESS) { profile->object.cryptoContext = cc; } +#endif return nssrv; } @@ -214,36 +241,22 @@ NSSCryptoContext_FindBestCertificateByNickname NSSPolicies *policiesOpt /* NULL for none */ ) { - PRIntn i; - NSSCertificate *c; - NSSCertificate **nickCerts; - nssBestCertificateCB best; + NSSCertificate **certs; + NSSCertificate *rvCert = NULL; if (!cc->certStore) { return NULL; } - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - /* This could be improved by querying the store with a callback */ - nickCerts = nssCertificateStore_FindCertificatesByNickname(cc->certStore, - name, - NULL, - 0, - NULL); - if (nickCerts) { - PRStatus nssrv; - for (i=0, c = *nickCerts; c != NULL; c = nickCerts[++i]) { - nssrv = nssBestCertificate_Callback(c, &best); - NSSCertificate_Destroy(c); - if (nssrv != PR_SUCCESS) { - if (best.cert) { - NSSCertificate_Destroy(best.cert); - best.cert = NULL; - } - break; - } - } - nss_ZFreeIf(nickCerts); + certs = nssCertificateStore_FindCertificatesByNickname(cc->certStore, + name, + NULL, 0, NULL); + if (certs) { + rvCert = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(certs); } - return best.cert; + return rvCert; } NSS_IMPLEMENT NSSCertificate ** @@ -295,39 +308,26 @@ NSSCryptoContext_FindBestCertificateBySubject NSSPolicies *policiesOpt ) { - PRIntn i; - NSSCertificate *c; - NSSCertificate **subjectCerts; - nssBestCertificateCB best; + NSSCertificate **certs; + NSSCertificate *rvCert = NULL; if (!cc->certStore) { return NULL; } - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - subjectCerts = nssCertificateStore_FindCertificatesBySubject(cc->certStore, - subject, - NULL, - 0, - NULL); - if (subjectCerts) { - PRStatus nssrv; - for (i=0, c = *subjectCerts; c != NULL; c = subjectCerts[++i]) { - nssrv = nssBestCertificate_Callback(c, &best); - NSSCertificate_Destroy(c); - if (nssrv != PR_SUCCESS) { - if (best.cert) { - NSSCertificate_Destroy(best.cert); - best.cert = NULL; - } - break; - } - } - nss_ZFreeIf(subjectCerts); + certs = nssCertificateStore_FindCertificatesBySubject(cc->certStore, + subject, + NULL, 0, NULL); + if (certs) { + rvCert = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(certs); } - return best.cert; + return rvCert; } NSS_IMPLEMENT NSSCertificate ** -NSSCryptoContext_FindCertificatesBySubject +nssCryptoContext_FindCertificatesBySubject ( NSSCryptoContext *cc, NSSDER *subject, @@ -348,6 +348,21 @@ NSSCryptoContext_FindCertificatesBySubject return rvCerts; } +NSS_IMPLEMENT NSSCertificate ** +NSSCryptoContext_FindCertificatesBySubject +( + NSSCryptoContext *cc, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +) +{ + return nssCryptoContext_FindCertificatesBySubject(cc, subject, + rvOpt, maximumOpt, + arenaOpt); +} + NSS_IMPLEMENT NSSCertificate * NSSCryptoContext_FindBestCertificateByNameComponents ( @@ -401,35 +416,22 @@ NSSCryptoContext_FindBestCertificateByEmail NSSPolicies *policiesOpt ) { - PRIntn i; - NSSCertificate *c; - NSSCertificate **emailCerts; - nssBestCertificateCB best; + NSSCertificate **certs; + NSSCertificate *rvCert = NULL; if (!cc->certStore) { return NULL; } - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - emailCerts = nssCertificateStore_FindCertificatesByEmail(cc->certStore, - email, - NULL, - 0, - NULL); - if (emailCerts) { - PRStatus nssrv; - for (i=0, c = *emailCerts; c != NULL; c = emailCerts[++i]) { - nssrv = nssBestCertificate_Callback(c, &best); - NSSCertificate_Destroy(c); - if (nssrv != PR_SUCCESS) { - if (best.cert) { - NSSCertificate_Destroy(best.cert); - best.cert = NULL; - } - break; - } - } - nss_ZFreeIf(emailCerts); + certs = nssCertificateStore_FindCertificatesByEmail(cc->certStore, + email, + NULL, 0, NULL); + if (certs) { + rvCert = nssCertificateArray_FindBestCertificate(certs, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(certs); } - return best.cert; + return rvCert; } NSS_IMPLEMENT NSSCertificate ** @@ -649,31 +651,6 @@ struct token_session_str { nssSession *session; }; -#ifdef nodef -static nssSession * -get_token_session(NSSCryptoContext *cc, NSSToken *tok) -{ - struct token_session_str *ts; - for (ts = (struct token_session_str *)nssListIterator_Start(cc->sessions); - ts != (struct token_session_str *)NULL; - ts = (struct token_session_str *)nssListIterator_Next(cc->sessions)) - { - if (ts->token == tok) { /* will this need to be more general? */ - break; - } - } - nssListIterator_Finish(cc->sessions); - if (!ts) { - /* need to create a session for this token. */ - ts = nss_ZNEW(NULL, struct token_session_str); - ts->token = nssToken_AddRef(tok); - ts->session = nssSlot_CreateSession(tok->slot, cc->arena, PR_FALSE); - nssList_AddElement(cc->sessionList, (void *)ts); - } - return ts->session; -} -#endif - NSS_IMPLEMENT NSSItem * NSSCryptoContext_Decrypt ( @@ -685,58 +662,7 @@ NSSCryptoContext_Decrypt NSSArena *arenaOpt ) { -#if 0 - NSSToken *tok; - nssSession *session; - NSSItem *rvData; - PRUint32 dataLen; - NSSAlgorithmAndParameters *ap; - CK_RV ckrv; - ap = (apOpt) ? apOpt : cc->defaultAlgorithm; - /* Get the token for this operation */ - tok = nssTrustDomain_GetCryptoToken(cc->trustDomain, ap); - if (!tok) { - return (NSSItem *)NULL; - } - /* Get the local session for this token */ - session = get_token_session(cc, tok); - /* Get the key needed to decrypt */ - keyHandle = get_decrypt_key(cc, ap); - /* Set up the decrypt operation */ - ckrv = CKAPI(tok)->C_DecryptInit(session->handle, - &ap->mechanism, keyHandle); - if (ckrv != CKR_OK) { - /* handle PKCS#11 error */ - return (NSSItem *)NULL; - } - /* Get the length of the output buffer */ - ckrv = CKAPI(tok)->C_Decrypt(session->handle, - (CK_BYTE_PTR)encryptedData->data, - (CK_ULONG)encryptedData->size, - (CK_BYTE_PTR)NULL, - (CK_ULONG_PTR)&dataLen); - if (ckrv != CKR_OK) { - /* handle PKCS#11 error */ - return (NSSItem *)NULL; - } - /* Alloc return value memory */ - rvData = nssItem_Create(NULL, NULL, dataLen, NULL); - if (!rvItem) { - return (NSSItem *)NULL; - } - /* Do the decryption */ - ckrv = CKAPI(tok)->C_Decrypt(cc->session->handle, - (CK_BYTE_PTR)encryptedData->data, - (CK_ULONG)encryptedData->size, - (CK_BYTE_PTR)rvData->data, - (CK_ULONG_PTR)&dataLen); - if (ckrv != CKR_OK) { - /* handle PKCS#11 error */ - nssItem_ZFreeIf(rvData); - return (NSSItem *)NULL; - } - return rvData; -#endif + nss_SetError(NSS_ERROR_NOT_FOUND); return NULL; } diff --git a/security/nss/lib/pki/manifest.mn b/security/nss/lib/pki/manifest.mn index 94de7843cf6a..91a44a8b743d 100644 --- a/security/nss/lib/pki/manifest.mn +++ b/security/nss/lib/pki/manifest.mn @@ -30,7 +30,7 @@ # may use your version of this file under either the MPL or the # GPL. # -MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.10 $ $Date: 2002/03/14 04:12:25 $ $Name: $" +MANIFEST_CVS_ID = "@(#) $RCSfile: manifest.mn,v $ $Revision: 1.11 $ $Date: 2002/04/15 15:22:08 $ $Name: $" CORE_DEPTH = ../../.. @@ -55,6 +55,7 @@ CSRCS = \ tdcache.c \ certdecode.c \ pkistore.c \ + pkibase.c \ $(NULL) ifndef PURE_STAN_BUILD diff --git a/security/nss/lib/pki/pki.h b/security/nss/lib/pki/pki.h index bba3d23bfe8e..3cd0c9370f28 100644 --- a/security/nss/lib/pki/pki.h +++ b/security/nss/lib/pki/pki.h @@ -35,32 +35,150 @@ #define PKI_H #ifdef DEBUG -static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.10 $ $Date: 2002/03/07 22:07:56 $ $Name: $"; +static const char PKI_CVS_ID[] = "@(#) $RCSfile: pki.h,v $ $Revision: 1.11 $ $Date: 2002/04/15 15:22:09 $ $Name: $"; #endif /* DEBUG */ -#ifndef PKIT_H -#include "pkit.h" -#endif /* PKIT_H */ - #ifndef NSSDEVT_H #include "nssdevt.h" #endif /* NSSDEVT_H */ +#ifndef NSSPKI_H +#include "nsspki.h" +#endif /* NSSPKI_H */ + +#ifndef PKIT_H +#include "pkit.h" +#endif /* PKIT_H */ + PR_BEGIN_EXTERN_C +NSS_EXTERN NSSCallback * +nssTrustDomain_GetDefaultCallback +( + NSSTrustDomain *td, + PRStatus *statusOpt +); + +NSS_EXTERN NSSCertificate ** +nssTrustDomain_FindCertificatesBySubject +( + NSSTrustDomain *td, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSTrust * +nssTrustDomain_FindTrustForCertificate +( + NSSTrustDomain *td, + NSSCertificate *c +); + NSS_EXTERN NSSCertificate * nssCertificate_AddRef ( NSSCertificate *c ); +NSS_EXTERN PRStatus +nssCertificate_Destroy +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetEncoding +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetIssuer +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetSerialNumber +( + NSSCertificate *c +); + +NSS_EXTERN NSSDER * +nssCertificate_GetSubject +( + NSSCertificate *c +); + NSS_EXTERN NSSUTF8 * -NSSCertificate_GetNickname +nssCertificate_GetNickname ( NSSCertificate *c, NSSToken *tokenOpt ); +NSS_EXTERN NSSASCII7 * +nssCertificate_GetEmailAddress +( + NSSCertificate *c +); + +NSS_EXTERN PRBool +nssCertificate_IssuerAndSerialEqual +( + NSSCertificate *c1, + NSSCertificate *c2 +); + +NSS_EXTERN NSSPrivateKey * +nssPrivateKey_AddRef +( + NSSPrivateKey *vk +); + +NSS_EXTERN PRStatus +nssPrivateKey_Destroy +( + NSSPrivateKey *vk +); + +NSS_EXTERN NSSItem * +nssPrivateKey_GetID +( + NSSPrivateKey *vk +); + +NSS_EXTERN NSSUTF8 * +nssPrivateKey_GetNickname +( + NSSPrivateKey *vk, + NSSToken *tokenOpt +); + +NSS_EXTERN PRStatus +nssPublicKey_Destroy +( + NSSPublicKey *bk +); + +NSS_EXTERN NSSItem * +nssPublicKey_GetID +( + NSSPublicKey *vk +); + +NSS_EXTERN NSSCertificate ** +nssCryptoContext_FindCertificatesBySubject +( + NSSCryptoContext *cc, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt +); + /* 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 518d31d1959b..05be46c7a3fa 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.47 $ $Date: 2002/04/04 20:00:28 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: pki3hack.c,v $ $Revision: 1.48 $ $Date: 2002/04/15 15:22:09 $ $Name: $"; #endif /* DEBUG */ /* @@ -124,13 +124,10 @@ cache_token_cert(NSSCertificate *c, void *arg) /* The cert was already in the cache, from another token. Add this * token's instance to the cert. */ - nssCryptokiInstance *tokenInstance, *instance; - nssList_GetArray(cp->object.instanceList, (void **)&tokenInstance, 1); - instance = nssCryptokiInstance_Create(c->object.arena, token, - tokenInstance->handle, PR_TRUE); - nssList_Add(c->object.instanceList, instance); - nssListIterator_Destroy(c->object.instances); - c->object.instances = nssList_CreateIterator(c->object.instanceList); + nssCryptokiObject **instance; + instance = nssPKIObject_GetInstances(&cp->object); + nssPKIObject_AddInstance(&c->object, *instance); + nss_ZFreeIf(instance); } /* This list reference persists with the token */ nssList_Add(token->certList, nssCertificate_AddRef(c)); @@ -142,32 +139,11 @@ cache_token_cert(NSSCertificate *c, void *arg) return PR_SUCCESS; } -static void remove_token_instance(NSSCertificate *c, NSSToken *token) -{ - nssListIterator *instances; - nssCryptokiInstance *instance, *rmInstance = NULL; - instances = c->object.instances; - for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); - instance != (nssCryptokiInstance *)NULL; - instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { - if (instance->token == token) { - rmInstance = instance; - break; - } - } - nssListIterator_Finish(instances); - if (rmInstance) { - nssList_Remove(c->object.instanceList, rmInstance); - nssListIterator_Destroy(instances); - c->object.instances = nssList_CreateIterator(c->object.instanceList); - } -} - static PRBool instance_destructor(NSSCertificate *c, NSSToken *token) { - remove_token_instance(c, token); - if (nssList_Count(c->object.instanceList) == 0) { + nssPKIObject_RemoveInstanceForToken(&c->object, token); + /* XXX cheating, this code to be replaced anyway */ + if (c->object.numInstances == 0) { return PR_TRUE; } return PR_FALSE; @@ -238,6 +214,26 @@ nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances) /* leave the list non-null to prevent it from being searched */ } +static void +add_token_certs_to_list(NSSToken *token) +{ + nssCryptokiObject **objects, **op; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + objects = nssToken_FindCertificates(token, NULL, tokenOnly, 0, NULL); + if (!objects) { + return; + } + for (op = objects; *op; op++) { + nssPKIObject *pkiob = nssPKIObject_Create(NULL, *op, + token->trustDomain, NULL); + if (pkiob) { + NSSCertificate *c = nssCertificate_Create(pkiob); + nssList_Add(token->certList, c); + } + } + nss_ZFreeIf(objects); +} + /* create a list of local cert references for certain tokens */ NSS_IMPLEMENT PRStatus nssToken_LoadCerts(NSSToken *token) @@ -263,7 +259,7 @@ nssToken_LoadCerts(NSSToken *token) return PR_SUCCESS; } /* ignore the rv, just work without the list */ - (void)nssToken_TraverseCertificates(token, NULL, &search); + add_token_certs_to_list(token); (void)nssToken_SetTrustCache(token); (void)nssToken_SetCrlCache(token); @@ -338,8 +334,6 @@ STAN_LoadDefaultNSS3TrustDomain { NSSTrustDomain *td; NSSToken *token; - PK11SlotList *list; - PK11SlotListElement *le; SECMODModuleList *mlp; SECMODListLock *moduleLock = SECMOD_GetDefaultModuleListLock(); int i; @@ -461,6 +455,31 @@ STAN_GetCertIdentifierFromDER(NSSArena *arenaOpt, NSSDER *der) return rvKey; } +NSS_IMPLEMENT PRStatus +nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena, + NSSDER *issuer, NSSDER *serial) +{ + SECStatus secrv; + SECItem derCert; + SECItem derIssuer = { 0 }; + SECItem derSerial = { 0 }; + SECITEM_FROM_NSSITEM(&derCert, der); + secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial); + if (secrv != SECSuccess) { + return PR_FAILURE; + } + (void)nssItem_Create(arena, serial, derSerial.len, derSerial.data); + secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer); + if (secrv != SECSuccess) { + PORT_Free(derSerial.data); + return PR_FAILURE; + } + (void)nssItem_Create(arena, issuer, derIssuer.len, derIssuer.data); + PORT_Free(derSerial.data); + PORT_Free(derIssuer.data); + return PR_SUCCESS; +} + static NSSItem * nss3certificate_getIdentifier(nssDecodedCert *dc) { @@ -476,9 +495,7 @@ nss3certificate_getIssuerIdentifier(nssDecodedCert *dc) CERTCertificate *c = (CERTCertificate *)dc->data; CERTAuthKeyID *cAuthKeyID; PRArenaPool *tmpArena = NULL; - SECItem issuerCertKey; NSSItem *rvID = NULL; - SECStatus secrv; tmpArena = PORT_NewArena(512); cAuthKeyID = CERT_FindAuthKeyIDExten(tmpArena, c); if (cAuthKeyID == NULL) { @@ -690,22 +707,21 @@ PK11_IsUserCert(PK11SlotInfo *, CERTCertificate *, CK_OBJECT_HANDLE); /* see pk11cert.c:pk11_HandleTrustObject */ static unsigned int -get_nss3trust_from_cktrust(CK_TRUST t) +get_nss3trust_from_nss4trust(CK_TRUST t) { unsigned int rt = 0; - if (t == CKT_NETSCAPE_TRUSTED) { + if (t == nssTrustLevel_Trusted) { rt |= CERTDB_VALID_PEER | CERTDB_TRUSTED; } - if (t == CKT_NETSCAPE_TRUSTED_DELEGATOR) { + if (t == nssTrustLevel_TrustedDelegator) { rt |= CERTDB_VALID_CA | CERTDB_TRUSTED_CA /*| CERTDB_NS_TRUSTED_CA*/; } - if (t == CKT_NETSCAPE_VALID) { + if (t == nssTrustLevel_Valid) { rt |= CERTDB_VALID_PEER; } - if (t == CKT_NETSCAPE_VALID_DELEGATOR) { + if (t == nssTrustLevel_ValidDelegator) { rt |= CERTDB_VALID_CA; } - /* user */ return rt; } @@ -719,95 +735,57 @@ cert_trust_from_stan_trust(NSSTrust *t, PRArenaPool *arena) } rvTrust = PORT_ArenaAlloc(arena, sizeof(CERTCertTrust)); if (!rvTrust) return NULL; - rvTrust->sslFlags = get_nss3trust_from_cktrust(t->serverAuth); - client = get_nss3trust_from_cktrust(t->clientAuth); + rvTrust->sslFlags = get_nss3trust_from_nss4trust(t->serverAuth); + client = get_nss3trust_from_nss4trust(t->clientAuth); if (client & (CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA)) { client &= ~(CERTDB_TRUSTED_CA|CERTDB_NS_TRUSTED_CA); rvTrust->sslFlags |= CERTDB_TRUSTED_CLIENT_CA; } rvTrust->sslFlags |= client; - rvTrust->emailFlags = get_nss3trust_from_cktrust(t->emailProtection); - rvTrust->objectSigningFlags = get_nss3trust_from_cktrust(t->codeSigning); + rvTrust->emailFlags = get_nss3trust_from_nss4trust(t->emailProtection); + rvTrust->objectSigningFlags = get_nss3trust_from_nss4trust(t->codeSigning); return rvTrust; } -static int nsstoken_get_trust_order(NSSToken *token) -{ - PK11SlotInfo *slot; - SECMODModule *module; - slot = token->pk11slot; - module = PK11_GetModule(slot); - return module->trustOrder; -} - /* check all cert instances for private key */ static PRBool is_user_cert(NSSCertificate *c, CERTCertificate *cc) { PRBool isUser = PR_FALSE; - nssCryptokiInstance *instance; - nssListIterator *instances = c->object.instances; - for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); - instance != (nssCryptokiInstance *)NULL; - instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { + nssCryptokiObject **ip; + nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object); + for (ip = instances; *ip; ip++) { + nssCryptokiObject *instance = *ip; if (PK11_IsUserCert(instance->token->pk11slot, cc, instance->handle)) { isUser = PR_TRUE; } } - nssListIterator_Finish(instances); + nssCryptokiObjectArray_Destroy(instances); return isUser; } CERTCertTrust * nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) { - CERTCertTrust *rvTrust; + CERTCertTrust *rvTrust = NULL; NSSTrustDomain *td = STAN_GetDefaultTrustDomain(); - NSSToken *tok; - NSSTrust *tokenTrust; - NSSTrust t; - nssListIterator *tokens; - int lastTrustOrder, myTrustOrder; - tokens = nssList_CreateIterator(td->tokenList); - if (!tokens) return NULL; - lastTrustOrder = 1<<16; /* just make it big */ - t.serverAuth = CKT_NETSCAPE_TRUST_UNKNOWN; - t.clientAuth = CKT_NETSCAPE_TRUST_UNKNOWN; - t.emailProtection = CKT_NETSCAPE_TRUST_UNKNOWN; - t.codeSigning = CKT_NETSCAPE_TRUST_UNKNOWN; - for (tok = (NSSToken *)nssListIterator_Start(tokens); - tok != (NSSToken *)NULL; - tok = (NSSToken *)nssListIterator_Next(tokens)) - { - tokenTrust = nssToken_FindTrustForCert(tok, NULL, c, - nssTokenSearchType_TokenOnly); - if (tokenTrust) { - myTrustOrder = nsstoken_get_trust_order(tok); - if (t.serverAuth == CKT_NETSCAPE_TRUST_UNKNOWN || - myTrustOrder < lastTrustOrder) { - t.serverAuth = tokenTrust->serverAuth; - } - if (t.clientAuth == CKT_NETSCAPE_TRUST_UNKNOWN || - myTrustOrder < lastTrustOrder) { - t.clientAuth = tokenTrust->clientAuth; - } - if (t.emailProtection == CKT_NETSCAPE_TRUST_UNKNOWN || - myTrustOrder < lastTrustOrder) { - t.emailProtection = tokenTrust->emailProtection; - } - if (t.codeSigning == CKT_NETSCAPE_TRUST_UNKNOWN || - myTrustOrder < lastTrustOrder) { - t.codeSigning = tokenTrust->codeSigning; - } - (void)nssTrust_Destroy(tokenTrust); - lastTrustOrder = myTrustOrder; + NSSTrust *t; + t = nssTrustDomain_FindTrustForCertificate(td, c); + if (t) { + rvTrust = cert_trust_from_stan_trust(t, cc->arena); + if (!rvTrust) { + nssTrust_Destroy(t); + return NULL; } + nssTrust_Destroy(t); } - nssListIterator_Finish(tokens); - nssListIterator_Destroy(tokens); - rvTrust = cert_trust_from_stan_trust(&t, cc->arena); - if (!rvTrust) return NULL; if (is_user_cert(c, cc)) { + if (!rvTrust) { + rvTrust = PORT_ArenaAlloc(cc->arena, sizeof(CERTCertTrust)); + if (!rvTrust) { + return NULL; + } + memset(rvTrust, 0, sizeof(*rvTrust)); + } rvTrust->sslFlags |= CERTDB_USER; rvTrust->emailFlags |= CERTDB_USER; rvTrust->objectSigningFlags |= CERTDB_USER; @@ -818,15 +796,15 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc) static nssCryptokiInstance * get_cert_instance(NSSCertificate *c) { - nssCryptokiInstance *instance, *ci; - nssListIterator *instances = c->object.instances; + nssCryptokiObject *instance, **ci; + nssCryptokiObject **instances = nssPKIObject_GetInstances(&c->object); + if (!instances) { + return NULL; + } instance = NULL; - for (ci = (nssCryptokiInstance *)nssListIterator_Start(instances); - ci != (nssCryptokiInstance *)NULL; - ci = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { + for (ci = instances; *ci; ci++) { if (!instance) { - instance = ci; + instance = nssCryptokiObject_Clone(*ci); } else { /* This only really works for two instances... But 3.4 can't * handle more anyway. The logic is, if there are multiple @@ -834,11 +812,12 @@ get_cert_instance(NSSCertificate *c) * a hardware device. */ if (PK11_IsInternal(instance->token->pk11slot)) { - instance = ci; + nssCryptokiObject_Destroy(instance); + instance = nssCryptokiObject_Clone(*ci); } } } - nssListIterator_Finish(instances); + nssCryptokiObjectArray_Destroy(instances); return instance; } @@ -888,15 +867,18 @@ fill_CERTCertificateFields(NSSCertificate *c, CERTCertificate *cc, PRBool forced } } else if (instance) { /* slot */ - if (cc->slot) { - PK11_FreeSlot(cc->slot); + if (cc->slot != instance->token->pk11slot) { + if (cc->slot) { + PK11_FreeSlot(cc->slot); + } + cc->slot = PK11_ReferenceSlot(instance->token->pk11slot); } - cc->slot = PK11_ReferenceSlot(instance->token->pk11slot); cc->ownSlot = PR_TRUE; /* pkcs11ID */ cc->pkcs11ID = instance->handle; /* trust */ cc->trust = nssTrust_GetCERTCertTrustForCert(c, cc); + nssCryptokiObject_Destroy(instance); } /* database handle is now the trust domain */ cc->dbhandle = c->object.trustDomain; @@ -947,28 +929,28 @@ STAN_GetCERTCertificate(NSSCertificate *c) return stan_GetCERTCertificate(c, PR_FALSE); } -static CK_TRUST +static nssTrustLevel get_stan_trust(unsigned int t, PRBool isClientAuth) { if (isClientAuth) { if (t & CERTDB_TRUSTED_CLIENT_CA) { - return CKT_NETSCAPE_TRUSTED_DELEGATOR; + return nssTrustLevel_TrustedDelegator; } } else { if (t & CERTDB_TRUSTED_CA || t & CERTDB_NS_TRUSTED_CA) { - return CKT_NETSCAPE_TRUSTED_DELEGATOR; + return nssTrustLevel_TrustedDelegator; } } if (t & CERTDB_TRUSTED) { - return CKT_NETSCAPE_TRUSTED; + return nssTrustLevel_Trusted; } if (t & CERTDB_VALID_CA) { - return CKT_NETSCAPE_VALID_DELEGATOR; + return nssTrustLevel_ValidDelegator; } if (t & CERTDB_VALID_PEER) { - return CKT_NETSCAPE_VALID; + return nssTrustLevel_Valid; } - return CKT_NETSCAPE_UNTRUSTED; + return nssTrustLevel_NotTrusted; } NSS_EXTERN NSSCertificate * @@ -976,8 +958,8 @@ STAN_GetNSSCertificate(CERTCertificate *cc) { NSSCertificate *c; nssCryptokiInstance *instance; + nssPKIObject *pkiob; NSSArena *arena; - PRStatus nssrv; c = cc->nssCertificate; if (c) { return c; @@ -996,10 +978,12 @@ STAN_GetNSSCertificate(CERTCertificate *cc) } NSSITEM_FROM_SECITEM(&c->encoding, &cc->derCert); c->type = NSSCertificateType_PKIX; - nssrv = nssPKIObject_Initialize(&c->object, arena, cc->dbhandle, NULL); - if (nssrv != PR_SUCCESS) { - nssPKIObject_Destroy(&c->object); + pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL); + if (!pkiob) { + nssArena_Destroy(arena); + return NULL; } + c->object = *pkiob; nssItem_Create(arena, &c->issuer, cc->derIssuer.len, cc->derIssuer.data); nssItem_Create(arena, @@ -1021,7 +1005,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc) } if (cc->slot) { instance = nss_ZNEW(arena, nssCryptokiInstance); - instance->token = PK11Slot_GetNSSToken(cc->slot); + instance->token = nssToken_AddRef(PK11Slot_GetNSSToken(cc->slot)); instance->handle = cc->pkcs11ID; instance->isTokenObject = PR_TRUE; if (cc->nickname) { @@ -1030,10 +1014,7 @@ STAN_GetNSSCertificate(CERTCertificate *cc) (NSSUTF8 *)cc->nickname, PORT_Strlen(cc->nickname)); } - nssList_Add(c->object.instanceList, instance); - /* XXX Fix this! */ - nssListIterator_Destroy(c->object.instances); - c->object.instances = nssList_CreateIterator(c->object.instanceList); + nssPKIObject_AddInstance(&c->object, instance); } c->decoding = create_decoded_pkix_cert_from_nss3cert(NULL, cc); cc->nssCertificate = c; @@ -1052,6 +1033,8 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) CERTCertTrust *oldTrust; nssListIterator *tokens; PRBool moving_object; + nssCryptokiObject *newInstance; + nssPKIObject *pkiob; oldTrust = nssTrust_GetCERTCertTrustForCert(c, cc); if (oldTrust) { if (memcmp(oldTrust, trust, sizeof (CERTCertTrust)) == 0) { @@ -1069,11 +1052,12 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) arena = nssArena_Create(); if (!arena) return PR_FAILURE; nssTrust = nss_ZNEW(arena, NSSTrust); - nssrv = nssPKIObject_Initialize(&nssTrust->object, arena, NULL, NULL); - if (nssrv != PR_SUCCESS) { - nssPKIObject_Destroy(&nssTrust->object); + pkiob = nssPKIObject_Create(arena, NULL, cc->dbhandle, NULL); + if (!pkiob) { + nssArena_Destroy(arena); return PR_FAILURE; } + nssTrust->object = *pkiob; nssTrust->certificate = c; nssTrust->serverAuth = get_stan_trust(trust->sslFlags, PR_FALSE); nssTrust->clientAuth = get_stan_trust(trust->sslFlags, PR_TRUE); @@ -1087,7 +1071,7 @@ STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust) nssTrust_Destroy(nssTrust); return nssrv; } - if (nssList_Count(c->object.instanceList) == 0) { + if (c->object.numInstances == 0) { /* The context is the only instance, finished */ return nssrv; } @@ -1115,11 +1099,33 @@ 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 */ - NSSUTF8 *nickname = NSSCertificate_GetNickname(c, NULL); - nssrv = nssToken_ImportCertificate(tok, NULL, c, nickname, PR_TRUE); - if (nssrv != PR_SUCCESS) return nssrv; + NSSUTF8 *nickname = nssCertificate_GetNickname(c, NULL); + newInstance = nssToken_ImportCertificate(tok, NULL, + NSSCertificateType_PKIX, + &c->id, + nickname, + &c->encoding, + &c->issuer, + &c->subject, + &c->serial, + PR_TRUE); + if (!newInstance) { + return PR_FAILURE; + } + nssPKIObject_AddInstance(&c->object, newInstance); + } + newInstance = nssToken_ImportTrust(tok, NULL, &c->encoding, + &c->issuer, &c->serial, + nssTrust->serverAuth, + nssTrust->clientAuth, + nssTrust->codeSigning, + nssTrust->emailProtection, PR_TRUE); + if (newInstance) { + nssCryptokiObject_Destroy(newInstance); + nssrv = PR_SUCCESS; + } else { + nssrv = PR_FAILURE; } - nssrv = nssToken_ImportTrust(tok, NULL, nssTrust, PR_TRUE); } else { nssrv = PR_FAILURE; } @@ -1183,103 +1189,6 @@ nssTrustDomain_TraverseCertificatesByNickname return nssrv; } -/* SEC_TraversePermCerts */ -NSS_IMPLEMENT PRStatus -nssTrustDomain_TraverseCertificates -( - NSSTrustDomain *td, - PRStatus (*callback)(NSSCertificate *c, void *arg), - void *arg -) -{ - PRStatus nssrv = PR_SUCCESS; - NSSToken *token; - nssList *certList; - nssTokenCertSearch search; - /* grab all cache certs (XXX please only do this here...) - * the alternative is to provide a callback through search that allows - * the token to query the cache for the cert during traversal. - */ - certList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsFromCache(td, certList); - /* set the search criteria */ - search.callback = callback; - search.cbarg = arg; - search.cached = certList; - search.searchType = nssTokenSearchType_TokenOnly; - for (token = (NSSToken *)nssListIterator_Start(td->tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(td->tokens)) - { - nssrv = nssToken_TraverseCertificates(token, NULL, &search); - } - nssListIterator_Finish(td->tokens); - nssList_Destroy(certList); - return nssrv; -} - -#if 0 -static CK_CERTIFICATE_TYPE -get_cert_type(NSSCertificateType nssType) -{ - switch (nssType) { - case NSSCertificateType_PKIX: - return CKC_X_509; - default: - return CK_INVALID_HANDLE; /* Not really! CK_INVALID_HANDLE is not a - * type CK_CERTIFICATE_TYPE */ - } -} -#endif - -/* CERT_AddTempCertToPerm */ -NSS_EXTERN PRStatus -nssTrustDomain_AddTempCertToPerm -( - NSSCertificate *c -) -{ -#if 0 - NSSToken *token; - CK_CERTIFICATE_TYPE cert_type; - CK_ATTRIBUTE cert_template[] = - { - { CKA_CLASS, NULL, 0 }, - { CKA_CERTIFICATE_TYPE, NULL, 0 }, - { CKA_ID, NULL, 0 }, - { CKA_VALUE, NULL, 0 }, - { CKA_LABEL, NULL, 0 }, - { CKA_ISSUER, NULL, 0 }, - { CKA_SUBJECT, NULL, 0 }, - { CKA_SERIAL_NUMBER, NULL, 0 } - }; - CK_ULONG ctsize; - ctsize = (CK_ULONG)(sizeof(cert_template) / sizeof(cert_template[0])); - /* XXX sanity checking needed */ - cert_type = get_cert_type(c->type); - /* Set up the certificate object */ - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 0, &g_ck_class_cert); - NSS_CK_SET_ATTRIBUTE_VAR( cert_template, 1, cert_type); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 2, &c->id); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 3, &c->encoding); - NSS_CK_SET_ATTRIBUTE_UTF8(cert_template, 4, c->nickname); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 5, &c->issuer); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 6, &c->subject); - NSS_CK_SET_ATTRIBUTE_ITEM(cert_template, 7, &c->serial); - /* This is a hack, ignoring the 4.0 token ordering scheme */ - token = STAN_GetInternalToken(); - c->handle = nssToken_ImportObject(token, NULL, cert_template, ctsize); - if (c->handle == CK_INVALID_HANDLE) { - return PR_FAILURE; - } - c->token = token; - c->slot = token->slot; - /* Do the trust object */ - return PR_SUCCESS; -#endif - return PR_FAILURE; -} - static void cert_dump_iter(const void *k, void *v, void *a) { NSSCertificate *c = (NSSCertificate *)k; diff --git a/security/nss/lib/pki/pki3hack.h b/security/nss/lib/pki/pki3hack.h index eca8455206f9..140edcab670e 100644 --- a/security/nss/lib/pki/pki3hack.h +++ b/security/nss/lib/pki/pki3hack.h @@ -35,7 +35,7 @@ #define PKINSS3HACK_H #ifdef DEBUG -static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.9 $ $Date: 2002/04/03 19:22:15 $ $Name: $"; +static const char PKINSS3HACK_CVS_ID[] = "@(#) $RCSfile: pki3hack.h,v $ $Revision: 1.10 $ $Date: 2002/04/15 15:22:10 $ $Name: $"; #endif /* DEBUG */ #ifndef NSSDEVT_H @@ -125,6 +125,10 @@ nssTrust_GetCERTCertTrustForCert(NSSCertificate *c, CERTCertificate *cc); NSS_EXTERN PRStatus STAN_ChangeCertTrust(CERTCertificate *cc, CERTCertTrust *trust); +NSS_EXTERN PRStatus +nssPKIX509_GetIssuerAndSerialFromDER(NSSDER *der, NSSArena *arena, + NSSDER *issuer, NSSDER *serial); + /* exposing this */ NSS_EXTERN NSSCertificate * NSSCertificate_Create diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c index 237628a86421..fd891ef10a46 100644 --- a/security/nss/lib/pki/pkibase.c +++ b/security/nss/lib/pki/pkibase.c @@ -32,7 +32,7 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.1 $ $Date: 2002/04/04 21:15:27 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.2 $ $Date: 2002/04/15 15:22:10 $ $Name: $"; #endif /* DEBUG */ #ifndef DEV_H @@ -43,6 +43,10 @@ static const char CVS_ID[] = "@(#) $RCSfile: pkibase.c,v $ $Revision: 1.1 $ $Dat #include "pkim.h" #endif /* PKIM_H */ +#ifdef NSS_3_4_CODE +#include "pki3hack.h" +#endif + NSS_IMPLEMENT nssPKIObject * nssPKIObject_Create ( @@ -100,9 +104,13 @@ nssPKIObject_Destroy nssPKIObject *object ) { + PRUint32 i; PR_ASSERT(object->refCount > 0); PR_AtomicDecrement(&object->refCount); if (object->refCount == 0) { + for (i=0; inumInstances; i++) { + nssCryptokiObject_Destroy(object->instances[i]); + } PZ_DestroyLock(object->lock); nssArena_Destroy(object->arena); return PR_TRUE; @@ -225,6 +233,7 @@ nssPKIObject_DeleteStoredObject PZ_Lock(object->lock); for (i=0; inumInstances; i++) { nssCryptokiObject *instance = object->instances[i]; +#ifndef NSS_3_4_CODE NSSSlot *slot = nssToken_GetSlot(instance->token); /* If both the operation and the slot are friendly, login is * not required. If either or both are not friendly, it is @@ -240,6 +249,9 @@ nssPKIObject_DeleteStoredObject status = nssToken_DeleteStoredObject(instance); } } +#else + status = nssToken_DeleteStoredObject(instance); +#endif object->instances[i] = NULL; if (status == PR_SUCCESS) { nssCryptokiObject_Destroy(instance); @@ -303,6 +315,31 @@ nssPKIObject_GetNicknameForToken return nickname; } +#ifdef NSS_3_4_CODE +NSS_IMPLEMENT nssCryptokiObject ** +nssPKIObject_GetInstances +( + nssPKIObject *object +) +{ + nssCryptokiObject **instances = NULL; + PRUint32 i; + if (object->numInstances == 0) { + return (nssCryptokiObject **)NULL; + } + PZ_Lock(object->lock); + instances = nss_ZNEWARRAY(NULL, nssCryptokiObject *, + object->numInstances + 1); + if (instances) { + for (i=0; inumInstances; i++) { + instances[i] = nssCryptokiObject_Clone(object->instances[i]); + } + } + PZ_Unlock(object->lock); + return instances; +} +#endif + NSS_IMPLEMENT void nssCertificateArray_Destroy ( @@ -312,6 +349,13 @@ nssCertificateArray_Destroy if (certs) { NSSCertificate **certp; for (certp = certs; *certp; certp++) { +#ifdef NSS_3_4_CODE + if ((*certp)->decoding) { + CERTCertificate *cc = STAN_GetCERTCertificate(*certp); + CERT_DestroyCertificate(cc); + continue; + } +#endif nssCertificate_Destroy(*certp); } nss_ZFreeIf(certs); @@ -337,7 +381,7 @@ nssCertificateArray_Join if (certs1 && certs2) { NSSCertificate **certs, **cp; PRUint32 count = 0; - PRUint32 count1; + PRUint32 count1 = 0; cp = certs1; while (*cp++) count1++; count = count1; @@ -349,8 +393,9 @@ nssCertificateArray_Join nss_ZFreeIf(certs2); return (NSSCertificate **)NULL; } - cp = certs2; - while (*cp++) certs[count1++] = *cp; + for (cp = certs2; *cp; cp++, count1++) { + certs[count1] = *cp; + } nss_ZFreeIf(certs2); return certs; } else if (certs1) { @@ -655,36 +700,50 @@ add_object_instance PRUint32 i; PRStatus status; pkiObjectCollectionNode *node; + nssArenaMark *mark = NULL; NSSItem uid[MAX_ITEMS_FOR_UID]; nsslibc_memset(uid, 0, sizeof uid); /* The list is traversed twice, first (here) looking to match the * { token, handle } tuple, and if that is not found, below a search - * for unique identifier is done. Here, a match means this exact - * object instance is already in the collection, and we have nothing to - * do. Later, it means the object exists in the collection, but does - * not have this instance, so the instance needs to be added. + * for unique identifier is done. Here, a match means this exact object + * instance is already in the collection, and we have nothing to do. */ node = find_instance_in_collection(collection, instance); if (node) { + /* The collection is assumed to take over the instance. Since we + * are not using it, it must be destroyed. + */ + nssCryptokiObject_Destroy(instance); return PR_SUCCESS; } + mark = nssArena_Mark(collection->arena); + if (!mark) { + goto loser; + } status = (*collection->getUIDFromInstance)(instance, uid, collection->arena); if (status != PR_SUCCESS) { goto loser; } - /* search for unique identifier */ + /* Search for unique identifier. A match here means the object exists + * in the collection, but does not have this instance, so the instance + * needs to be added. + */ node = find_object_in_collection(collection, uid); if (node) { /* This is a object with multiple instances */ status = nssPKIObject_AddInstance(node->object, instance); } else { + /* This is a completely new object. Create a node for it. */ node = nss_ZNEW(collection->arena, pkiObjectCollectionNode); if (!node) { goto loser; } node->object = nssPKIObject_Create(NULL, instance, collection->td, collection->cc); + if (!node->object) { + goto loser; + } for (i=0; iuid[i] = uid[i]; } @@ -694,8 +753,13 @@ add_object_instance collection->size++; status = PR_SUCCESS; } + nssArena_Unmark(collection->arena, mark); return status; loser: + if (mark) { + nssArena_Release(collection->arena, mark); + } + nssCryptokiObject_Destroy(instance); return PR_FAILURE; } @@ -710,16 +774,26 @@ nssPKIObjectCollection_AddInstances PRStatus status = PR_SUCCESS; PRUint32 i = 0; if (instances) { - for (; *instances; instances++) { - status = add_object_instance(collection, *instances); - if (status != PR_SUCCESS || - (numInstances > 0 && ++i == numInstances)) - { + for (; *instances; instances++, i++) { + if (numInstances > 0 && i == numInstances) { break; } + status = add_object_instance(collection, *instances); + if (status != PR_SUCCESS) { + goto loser; + } } } return status; +loser: + /* free the remaining instances */ + for (; *instances; instances++, i++) { + if (numInstances > 0 && i == numInstances) { + break; + } + nssCryptokiObject_Destroy(*instances); + } + return PR_FAILURE; } static PRStatus @@ -795,6 +869,13 @@ static void cert_destroyObject(nssPKIObject *o) { NSSCertificate *c = (NSSCertificate *)o; +#ifdef NSS_3_4_CODE + if (c->decoding) { + CERTCertificate *cc = STAN_GetCERTCertificate(c); + CERT_DestroyCertificate(cc); + return; + } +#endif nssCertificate_Destroy(c); } @@ -831,6 +912,17 @@ cert_createObject(nssPKIObject *o) { NSSCertificate *cert; cert = nssCertificate_Create(o); +#ifdef NSS_3_4_CODE + (void)STAN_GetCERTCertificate(cert); + /* In 3.4, have to maintain uniqueness of cert pointers by caching all + * certs. Cache the cert here, before returning. If it is already + * cached, take the cached entry. + */ + { + NSSTrustDomain *td = o->trustDomain; + nssTrustDomain_AddCertsToCache(td, &cert, 1); + } +#endif return (nssPKIObject *)cert; } @@ -897,6 +989,7 @@ nssPKIObjectCollection_GetCertificates return rvOpt; } +#ifdef PURE_STAN_BUILD /* * PrivateKey collections */ @@ -1102,6 +1195,7 @@ nssPKIObjectCollection_GetPublicKeys } return rvOpt; } +#endif /* PURE_STAN_BUILD */ /* how bad would it be to have a static now sitting around, updated whenever * this was called? would avoid repeated allocs... diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h index a240ad79773d..cb1baa6f05b6 100644 --- a/security/nss/lib/pki/pkim.h +++ b/security/nss/lib/pki/pkim.h @@ -35,23 +35,458 @@ #define PKIM_H #ifdef DEBUG -static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.16 $ $Date: 2002/02/08 02:51:38 $ $Name: $"; +static const char PKIM_CVS_ID[] = "@(#) $RCSfile: pkim.h,v $ $Revision: 1.17 $ $Date: 2002/04/15 15:22:10 $ $Name: $"; #endif /* DEBUG */ #ifndef BASE_H #include "base.h" #endif /* BASE_H */ +#ifndef PKI_H +#include "pki.h" +#endif /* PKI_H */ + #ifndef PKITM_H #include "pkitm.h" #endif /* PKITM_H */ PR_BEGIN_EXTERN_C -NSS_EXTERN NSSToken * -STAN_GetDefaultCryptoToken +/* nssPKIObject + * + * This is the base object class, common to all PKI objects defined in + * in this module. Each object can be safely 'casted' to an nssPKIObject, + * then passed to these methods. + * + * nssPKIObject_Create + * nssPKIObject_Destroy + * nssPKIObject_AddRef + * nssPKIObject_AddInstance + * nssPKIObject_HasInstance + * nssPKIObject_GetTokens + * nssPKIObject_GetNicknameForToken + * nssPKIObject_RemoveInstanceForToken + * nssPKIObject_DeleteStoredObject + */ + +/* nssPKIObject_Create + * + * A generic PKI object. It must live in a trust domain. It may be + * initialized with a token instance, or alternatively in a crypto context. + */ +NSS_EXTERN nssPKIObject * +nssPKIObject_Create ( - void + NSSArena *arenaOpt, + nssCryptokiObject *instanceOpt, + NSSTrustDomain *td, + NSSCryptoContext *ccOpt +); + +/* nssPKIObject_AddRef + */ +NSS_EXTERN nssPKIObject * +nssPKIObject_AddRef +( + nssPKIObject *object +); + +/* nssPKIObject_Destroy + * + * Returns true if object was destroyed. This notifies the subclass that + * all references are gone and it should delete any members it owns. + */ +NSS_EXTERN PRBool +nssPKIObject_Destroy +( + nssPKIObject *object +); + +/* nssPKIObject_AddInstance + * + * Add a token instance to the object, if it does not have it already. + */ +NSS_EXTERN PRStatus +nssPKIObject_AddInstance +( + nssPKIObject *object, + nssCryptokiObject *instance +); + +/* nssPKIObject_HasInstance + * + * Query the object for a token instance. + */ +NSS_EXTERN PRBool +nssPKIObject_HasInstance +( + nssPKIObject *object, + nssCryptokiObject *instance +); + +/* nssPKIObject_GetTokens + * + * Get all tokens which have an instance of the object. + */ +NSS_EXTERN NSSToken ** +nssPKIObject_GetTokens +( + nssPKIObject *object, + PRStatus *statusOpt +); + +/* nssPKIObject_GetNicknameForToken + * + * tokenOpt == NULL means take the first available, otherwise return the + * nickname for the specified token. + */ +NSS_EXTERN NSSUTF8 * +nssPKIObject_GetNicknameForToken +( + nssPKIObject *object, + NSSToken *tokenOpt +); + +/* nssPKIObject_RemoveInstanceForToken + * + * Remove the instance of the object on the specified token. + */ +NSS_EXTERN PRStatus +nssPKIObject_RemoveInstanceForToken +( + nssPKIObject *object, + NSSToken *token +); + +/* nssPKIObject_DeleteStoredObject + * + * Delete all token instances of the object, as well as any crypto context + * instances (TODO). If any of the instances are read-only, or if the + * removal fails, the object will keep those instances. 'isFriendly' refers + * to the object -- can this object be removed from a friendly token without + * login? For example, certificates are friendly, private keys are not. + * Note that if the token is not friendly, authentication will be required + * regardless of the value of 'isFriendly'. + */ +NSS_EXTERN PRStatus +nssPKIObject_DeleteStoredObject +( + nssPKIObject *object, + NSSCallback *uhh, + PRBool isFriendly +); + +#ifdef NSS_3_4_CODE +NSS_EXTERN nssCryptokiObject ** +nssPKIObject_GetInstances +( + nssPKIObject *object +); +#endif + +NSS_EXTERN NSSCertificate ** +nssTrustDomain_FindCertificatesByID +( + NSSTrustDomain *td, + NSSItem *id, + NSSCertificate **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +/* module-private nsspki methods */ + +NSS_EXTERN NSSCryptoContext * +nssCryptoContext_Create +( + NSSTrustDomain *td, + NSSCallback *uhhOpt +); + +/* XXX for the collection */ +NSS_EXTERN NSSCertificate * +nssCertificate_Create +( + nssPKIObject *object +); + +NSS_EXTERN PRStatus +nssCertificate_SetCertTrust +( + NSSCertificate *c, + NSSTrust *trust +); + +NSS_EXTERN nssDecodedCert * +nssCertificate_GetDecoding +( + NSSCertificate *c +); + +NSS_EXTERN nssDecodedCert * +nssDecodedCert_Create +( + NSSArena *arenaOpt, + NSSDER *encoding, + NSSCertificateType type +); + +NSS_EXTERN PRStatus +nssDecodedCert_Destroy +( + nssDecodedCert *dc +); + +NSS_EXTERN NSSTrust * +nssTrust_Create +( + nssPKIObject *object +); + +NSS_EXTERN NSSPrivateKey * +nssPrivateKey_Create +( + nssPKIObject *o +); + +NSS_EXTERN NSSPublicKey * +nssPublicKey_Create +( + nssPKIObject *object +); + +/* nssCertificateArray + * + * These are being thrown around a lot, might as well group together some + * functionality. + * + * nssCertificateArray_Destroy + * nssCertificateArray_Join + * nssCertificateArray_FindBestCertificate + * nssCertificateArray_Traverse + */ + +/* nssCertificateArray_Destroy + * + * Will destroy the array and the certs within it. If the array was created + * in an arena, will *not* (of course) destroy the arena. However, is safe + * to call this method on an arena-allocated array. + */ +NSS_EXTERN void +nssCertificateArray_Destroy +( + NSSCertificate **certs +); + +/* nssCertificateArray_Join + * + * Join two arrays into one. The two arrays, certs1 and certs2, should + * be considered invalid after a call to this function (they may be destroyed + * as part of the join). certs1 and/or certs2 may be NULL. Safe to + * call with arrays allocated in an arena, the result will also be in the + * arena. + */ +NSS_EXTERN NSSCertificate ** +nssCertificateArray_Join +( + NSSCertificate **certs1, + NSSCertificate **certs2 +); + +/* nssCertificateArray_FindBestCertificate + * + * Use the usual { time, usage, policies } to find the best cert in the + * array. + */ +NSS_EXTERN NSSCertificate * +nssCertificateArray_FindBestCertificate +( + NSSCertificate **certs, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +); + +/* nssCertificateArray_Traverse + * + * Do the callback for each cert, terminate the traversal if the callback + * fails. + */ +NSS_EXTERN PRStatus +nssCertificateArray_Traverse +( + NSSCertificate **certs, + PRStatus (* callback)(NSSCertificate *c, void *arg), + void *arg +); + +/* nssPKIObjectCollection + * + * This is a handy way to group objects together and perform operations + * on them. It can also handle "proto-objects"-- references to + * objects instances on tokens, where the actual object hasn't + * been formed yet. + * + * nssCertificateCollection_Create + * nssPrivateKeyCollection_Create + * nssPublicKeyCollection_Create + * + * If this was a language that provided for inheritance, each type would + * inherit all of the following methods. Instead, there is only one + * type (nssPKIObjectCollection), shared among all. This may cause + * confusion; an alternative would be to define all of the methods + * for each subtype (nssCertificateCollection_Destroy, ...), but that doesn't + * seem worth the code bloat.. It is left up to the caller to remember + * what type of collection he/she is dealing with. + * + * nssPKIObjectCollection_Destroy + * nssPKIObjectCollection_Count + * nssPKIObjectCollection_AddObject + * nssPKIObjectCollection_AddInstances + * nssPKIObjectCollection_Traverse + * + * Back to type-specific methods. + * + * nssPKIObjectCollection_GetCertificates + * nssPKIObjectCollection_GetPrivateKeys + * nssPKIObjectCollection_GetPublicKeys + */ + +/* nssCertificateCollection_Create + * + * Create a collection of certificates in the specified trust domain. + * Optionally provide a starting set of certs. + */ +NSS_EXTERN nssPKIObjectCollection * +nssCertificateCollection_Create +( + NSSTrustDomain *td, + NSSCertificate **certsOpt +); + +/* nssPrivateKeyCollection_Create + * + * Create a collection of private keys in the specified trust domain. + * Optionally provide a starting set of keys. + */ +NSS_EXTERN nssPKIObjectCollection * +nssPrivateKeyCollection_Create +( + NSSTrustDomain *td, + NSSPrivateKey **pvkOpt +); + +/* nssPublicKeyCollection_Create + * + * Create a collection of public keys in the specified trust domain. + * Optionally provide a starting set of keys. + */ +NSS_EXTERN nssPKIObjectCollection * +nssPublicKeyCollection_Create +( + NSSTrustDomain *td, + NSSPublicKey **pvkOpt +); + +/* nssPKIObjectCollection_Destroy + */ +NSS_EXTERN void +nssPKIObjectCollection_Destroy +( + nssPKIObjectCollection *collection +); + +/* nssPKIObjectCollection_Count + */ +NSS_EXTERN PRUint32 +nssPKIObjectCollection_Count +( + nssPKIObjectCollection *collection +); + +NSS_EXTERN PRStatus +nssPKIObjectCollection_AddObject +( + nssPKIObjectCollection *collection, + nssPKIObject *object +); + +/* nssPKIObjectCollection_AddInstances + * + * Add a set of object instances to the collection. The instances + * will be sorted into any existing certs/proto-certs that may be in + * the collection. The instances will be absorbed by the collection, + * the array should not be used after this call (except to free it). + * + * Failure means the collection is in an invalid state. + * + * numInstances = 0 means the array is NULL-terminated + */ +NSS_EXTERN PRStatus +nssPKIObjectCollection_AddInstances +( + nssPKIObjectCollection *collection, + nssCryptokiObject **instances, + PRUint32 numInstances +); + +/* nssPKIObjectCollection_Traverse + */ +NSS_EXTERN PRStatus +nssPKIObjectCollection_Traverse +( + nssPKIObjectCollection *collection, + nssPKIObjectCallback *callback +); + +/* nssPKIObjectCollection_GetCertificates + * + * Get all of the certificates in the collection. + */ +NSS_EXTERN NSSCertificate ** +nssPKIObjectCollection_GetCertificates +( + nssPKIObjectCollection *collection, + NSSCertificate **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSPrivateKey ** +nssPKIObjectCollection_GetPrivateKeys +( + nssPKIObjectCollection *collection, + NSSPrivateKey **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSPublicKey ** +nssPKIObjectCollection_GetPublicKeys +( + nssPKIObjectCollection *collection, + NSSPublicKey **rvOpt, + PRUint32 maximumOpt, + NSSArena *arenaOpt +); + +NSS_EXTERN NSSTime * +NSSTime_Now +( + NSSTime *timeOpt +); + +NSS_EXTERN NSSTime * +NSSTime_SetPRTime +( + NSSTime *timeOpt, + PRTime prTime +); + +NSS_EXTERN PRTime +NSSTime_GetPRTime +( + NSSTime *time ); NSS_EXTERN nssHash * @@ -61,79 +496,15 @@ nssHash_CreateCertificate PRUint32 numBuckets ); -/* Token ordering routines */ +/* 3.4 Certificate cache routines */ -/* - * Given a crypto algorithm, return the preferred token for performing - * the crypto operation. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetCryptoToken +NSS_EXTERN PRStatus +nssTrustDomain_InitializeCache ( NSSTrustDomain *td, - NSSAlgorithmAndParameters *ap + PRUint32 cacheSize ); -/* The following routines are used to obtain the preferred token on which - * to store particular objects. - */ - -/* - * Find the preferred token for storing user certificates. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetUserCertToken -( - NSSTrustDomain *td -); - -/* - * Find the preferred token for storing email certificates. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetEmailCertToken -( - NSSTrustDomain *td -); - -/* - * Find the preferred token for storing SSL certificates. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetSSLCertToken -( - NSSTrustDomain *td -); - -/* - * Find the preferred token for storing root certificates. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetRootCertToken -( - NSSTrustDomain *td -); - -/* - * Find the preferred token for storing private keys. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetPrivateKeyToken -( - NSSTrustDomain *td -); - -/* - * Find the preferred token for storing symmetric keys. - */ -NSS_EXTERN NSSToken * -nssTrustDomain_GetSymmetricKeyToken -( - NSSTrustDomain *td -); - -/* Certificate cache routines */ - NSS_EXTERN PRStatus nssTrustDomain_AddCertsToCache ( @@ -238,54 +609,11 @@ nssTrustDomain_GetCertsFromCache nssList *certListOpt ); -NSS_EXTERN PRStatus -nssCertificate_SetCertTrust +NSS_EXTERN void +nssTrustDomain_DumpCacheInfo ( - NSSCertificate *c, - NSSTrust *trust -); - -NSS_EXTERN nssDecodedCert * -nssCertificate_GetDecoding -( - NSSCertificate *c -); - -NSS_EXTERN nssDecodedCert * -nssDecodedCert_Create -( - NSSArena *arenaOpt, - NSSDER *encoding, - NSSCertificateType type -); - -NSS_EXTERN PRStatus -nssDecodedCert_Destroy -( - nssDecodedCert *dc -); - -NSS_EXTERN void -nssBestCertificate_SetArgs -( - nssBestCertificateCB *best, - NSSTime *timeOpt, - NSSUsage *usage, - NSSPolicies *policies -); - -NSS_EXTERN PRStatus -nssBestCertificate_Callback -( - NSSCertificate *c, - void *arg -); - -NSS_EXTERN PRStatus -nssCertificateList_DoCallback -( - nssList *certList, - PRStatus (* callback)(NSSCertificate *c, void *arg), + NSSTrustDomain *td, + void (* cert_dump_iter)(const void *, void *, void *), void *arg ); @@ -295,54 +623,6 @@ nssCertificateList_AddReferences nssList *certList ); -NSS_EXTERN PRStatus -nssPKIObject_Initialize -( - struct nssPKIObjectBaseStr *object, - NSSArena *arena, - NSSTrustDomain *td, - NSSCryptoContext *cc -); - -NSS_EXTERN void -nssPKIObject_AddRef -( - struct nssPKIObjectBaseStr *object -); - -NSS_EXTERN PRBool -nssPKIObject_Destroy -( - struct nssPKIObjectBaseStr *object -); - -NSS_EXTERN NSSTime * -NSSTime_Now -( - NSSTime *timeOpt -); - -NSS_EXTERN NSSTime * -NSSTime_SetPRTime -( - NSSTime *timeOpt, - PRTime prTime -); - -NSS_EXTERN PRTime -NSSTime_GetPRTime -( - NSSTime *time -); - -NSS_EXTERN void -nssTrustDomain_DumpCacheInfo -( - NSSTrustDomain *td, - void (* cert_dump_iter)(const void *, void *, void *), - void *arg -); - PR_END_EXTERN_C #endif /* PKIM_H */ diff --git a/security/nss/lib/pki/pkistore.c b/security/nss/lib/pki/pkistore.c index fce63d6a2d25..24006560d4f8 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.15 $ $Date: 2002/03/07 22:07:58 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: pkistore.c,v $ $Revision: 1.16 $ $Date: 2002/04/15 15:22:10 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIM_H @@ -435,7 +435,7 @@ static void match_nickname(const void *k, void *v, void *a) 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); + nickname = nssCertificate_GetNickname(c, NULL); if (nssrv == PR_SUCCESS && nssUTF8_Equal(nickname, nt->nickname, &nssrv)) { diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h index 28bccc2bbda3..2923e6cc5ba1 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.11 $ $Date: 2002/03/07 22:07:59 $ $Name: $"; +static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.12 $ $Date: 2002/04/15 15:22:10 $ $Name: $"; #endif /* DEBUG */ /* @@ -71,13 +71,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile: pkit.h,v $ $Revision: 1.11 $ $ PR_BEGIN_EXTERN_C -typedef struct nssDecodedCertStr nssDecodedCert; - -typedef struct nssCertificateStoreStr nssCertificateStore; - -/* How wide is the scope of this? */ -typedef struct nssSMIMEProfileStr nssSMIMEProfile; - /* * A note on ephemeral certs * @@ -93,17 +86,25 @@ typedef struct nssSMIMEProfileStr nssSMIMEProfile; * for each object. */ -/* The common data from which all objects inherit */ -struct nssPKIObjectBaseStr +/* nssPKIObject + * + * This is the base object class, common to all PKI objects defined in + * nsspkit.h + */ +struct nssPKIObjectStr { /* The arena for all object memory */ NSSArena *arena; - /* Thread-safe reference counting */ - PZLock *lock; + /* Atomically incremented/decremented reference counting */ PRInt32 refCount; - /* List of nssCryptokiInstance's of the object */ - nssList *instanceList; - nssListIterator *instances; + /* lock protects the array of nssCryptokiInstance's of the object */ + PZLock *lock; + /* XXX with LRU cache, this cannot be guaranteed up-to-date. It cannot + * be compared against the update level of the trust domain, since it is + * also affected by import/export. Where is this array needed? + */ + nssCryptokiObject **instances; + PRUint32 numInstances; /* The object must live in a trust domain */ NSSTrustDomain *trustDomain; /* The object may live in a crypto context */ @@ -112,9 +113,18 @@ struct nssPKIObjectBaseStr NSSUTF8 *tempName; }; +typedef struct nssDecodedCertStr nssDecodedCert; + +typedef struct nssCertificateStoreStr nssCertificateStore; + +/* How wide is the scope of this? */ +typedef struct nssSMIMEProfileStr nssSMIMEProfile; + +typedef struct nssPKIObjectStr nssPKIObject; + struct NSSTrustStr { - struct nssPKIObjectBaseStr object; + nssPKIObject object; NSSCertificate *certificate; nssTrustLevel serverAuth; nssTrustLevel clientAuth; @@ -124,7 +134,7 @@ struct NSSTrustStr struct nssSMIMEProfileStr { - struct nssPKIObjectBaseStr object; + nssPKIObject object; NSSCertificate *certificate; NSSASCII7 *email; NSSDER *subject; @@ -134,7 +144,7 @@ struct nssSMIMEProfileStr struct NSSCertificateStr { - struct nssPKIObjectBaseStr object; + nssPKIObject object; NSSCertificateType type; NSSItem id; NSSBER encoding; @@ -156,7 +166,7 @@ typedef struct nssTDCertificateCacheStr nssTDCertificateCache; struct NSSTrustDomainStr { PRInt32 refCount; NSSArena *arena; - NSSCallback defaultCallback; + NSSCallback *defaultCallback; nssList *tokenList; nssListIterator *tokens; nssTDCertificateCache *cache; diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h index db56ed9fd0c9..29647ffe5bbb 100644 --- a/security/nss/lib/pki/pkitm.h +++ b/security/nss/lib/pki/pkitm.h @@ -35,7 +35,7 @@ #define PKITM_H #ifdef DEBUG -static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.7 $ $Date: 2002/02/04 22:34:22 $ $Name: $"; +static const char PKITM_CVS_ID[] = "@(#) $RCSfile: pkitm.h,v $ $Revision: 1.8 $ $Date: 2002/04/15 15:22:11 $ $Name: $"; #endif /* DEBUG */ /* @@ -104,6 +104,18 @@ struct nssBestCertificateCBStr { NSSPolicies *policies; }; +typedef struct nssPKIObjectCollectionStr nssPKIObjectCollection; + +typedef struct +{ + union { + PRStatus (* cert)(NSSCertificate *c, void *arg); + PRStatus (* pvkey)(NSSPrivateKey *vk, void *arg); + PRStatus (* pbkey)(NSSPublicKey *bk, void *arg); + } func; + void *arg; +} nssPKIObjectCallback; + PR_END_EXTERN_C #endif /* PKITM_H */ diff --git a/security/nss/lib/pki/tdcache.c b/security/nss/lib/pki/tdcache.c index b3f2de8b514a..ade2e8e3f32e 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.28 $ $Date: 2002/03/07 22:08:00 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: tdcache.c,v $ $Revision: 1.29 $ $Date: 2002/04/15 15:22:11 $ $Name: $"; #endif /* DEBUG */ #ifndef PKIM_H @@ -308,7 +308,7 @@ remove_nickname_entry ) { PRStatus nssrv; - NSSUTF8 *nickname = NSSCertificate_GetNickname(cert, NULL); + NSSUTF8 *nickname = nssCertificate_GetNickname(cert, NULL); if (nickname) { nssHash_Remove(cache->nickname, nickname); nssrv = PR_SUCCESS; @@ -562,7 +562,7 @@ add_nickname_entry ) { PRStatus nssrv = PR_SUCCESS; - NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); + NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL); cache_entry *ce; ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname); if (ce) { @@ -654,7 +654,7 @@ add_email_entry extern const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE; -static PRStatus +static NSSCertificate * add_cert_to_cache ( NSSTrustDomain *td, @@ -665,18 +665,24 @@ add_cert_to_cache nssList *subjectList; PRStatus nssrv; PRUint32 added = 0; + cache_entry *ce; + NSSCertificate *rvCert = NULL; PZ_Lock(td->cache->lock); /* If it exists in the issuer/serial hash, it's already in all */ - if (nssHash_Exists(td->cache->issuerAndSN, cert)) { + ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert); + if (ce) { + ce->hits++; + ce->lastHit = PR_Now(); + rvCert = nssCertificate_AddRef(ce->entry.cert); #ifdef DEBUG_CACHE log_cert_ref("attempted to add cert already in cache", cert); #endif PZ_Unlock(td->cache->lock); - /* collision - most likely, somebody else already added the cert + /* collision - somebody else already added the cert * to the cache before this thread got around to it. */ - nss_SetError(NSS_ERROR_CERTIFICATE_IN_CACHE); - return PR_FAILURE; + nssCertificate_Destroy(cert); + return rvCert; } /* create a new cache entry for this cert within the cert's arena*/ nssrv = add_issuer_and_serial_entry(cert->object.arena, td->cache, cert); @@ -698,7 +704,7 @@ add_cert_to_cache /* If a new subject entry was created, also need nickname and/or email */ if (subjectList != NULL) { PRBool handle = PR_FALSE; - NSSUTF8 *certNickname = NSSCertificate_GetNickname(cert, NULL); + NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL); if (certNickname) { nssrv = add_nickname_entry(arena, td->cache, cert, subjectList); if (nssrv != PR_SUCCESS) { @@ -729,7 +735,7 @@ add_cert_to_cache } nssCertificate_AddRef(cert); PZ_Unlock(td->cache->lock); - return nssrv; + return rvCert; loser: /* Remove any handles that have been created */ subjectList = NULL; @@ -753,7 +759,7 @@ loser: nssArena_Destroy(arena); } PZ_Unlock(td->cache->lock); - return PR_FAILURE; + return NULL; } NSS_IMPLEMENT PRStatus @@ -765,32 +771,14 @@ nssTrustDomain_AddCertsToCache ) { PRUint32 i; - NSSError e; + NSSCertificate *c; for (i=0; iissuer, - &certs[i]->serial); - if (c != certs[i]) { - NSSCertificate_Destroy(certs[i]); - certs[i] = c; - } else { - NSSCertificate_Destroy(c); - } - nss_ClearErrorStack(); - continue; - } + c = add_cert_to_cache(td, certs[i]); + if (c == NULL) { return PR_FAILURE; - } + } else { + certs[i] = c; + } } return PR_SUCCESS; } diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c index 3dadbcb4e170..b249f114662c 100644 --- a/security/nss/lib/pki/trustdomain.c +++ b/security/nss/lib/pki/trustdomain.c @@ -32,44 +32,45 @@ */ #ifdef DEBUG -static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.37 $ $Date: 2002/03/14 17:39:12 $ $Name: $"; +static const char CVS_ID[] = "@(#) $RCSfile: trustdomain.c,v $ $Revision: 1.38 $ $Date: 2002/04/15 15:22:11 $ $Name: $"; #endif /* DEBUG */ -#ifndef NSSPKI_H -#include "nsspki.h" -#endif /* NSSPKI_H */ - -#ifndef PKI_H -#include "pki.h" -#endif /* PKI_H */ - -#ifndef PKIM_H -#include "pkim.h" -#endif /* PKIM_H */ - #ifndef DEV_H #include "dev.h" #endif /* DEV_H */ -#ifndef CKHELPER_H -#include "ckhelper.h" -#endif /* CKHELPER_H */ +#ifndef PKIM_H +#include "pkim.h" +#endif /* PKIM_H */ + +#ifndef PKI1T_H +#include "pki1t.h" +#endif /* PKI1T_H */ #ifdef NSS_3_4_CODE #include "cert.h" #include "pki3hack.h" #endif -extern const NSSError NSS_ERROR_NOT_FOUND; - #define NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE 32 -NSS_EXTERN PRStatus -nssTrustDomain_InitializeCache -( - NSSTrustDomain *td, - PRUint32 cacheSize -); +#ifdef PURE_STAN_BUILD +struct NSSTrustDomainStr { + PRInt32 refCount; + NSSArena *arena; + NSSCallback *defaultCallback; + struct { + nssSlotList *forCerts; + nssSlotList *forCiphers; + nssSlotList *forTrust; + } slots; + nssCertificateCache *cache; +}; +#endif + +extern const NSSError NSS_ERROR_NOT_FOUND; + +typedef PRUint32 nssUpdateLevel; NSS_IMPLEMENT NSSTrustDomain * NSSTrustDomain_Create @@ -90,9 +91,9 @@ NSSTrustDomain_Create if (!rvTD) { goto loser; } + nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE); rvTD->arena = arena; rvTD->refCount = 1; - nssTrustDomain_InitializeCache(rvTD, NSSTRUSTDOMAIN_DEFAULT_CACHE_SIZE); #ifdef NSS_3_4_CODE rvTD->statusConfig = NULL; #endif @@ -106,13 +107,9 @@ static void token_destructor(void *t) { NSSToken *tok = (NSSToken *)t; -#ifdef NSS_3_4_CODE /* in 3.4, also destroy the slot (managed separately) */ (void)nssSlot_Destroy(tok->slot); STAN_DestroyNSSToken(tok); -#else - (void)nssToken_Destroy(tok); -#endif } NSS_IMPLEMENT PRStatus @@ -135,6 +132,48 @@ NSSTrustDomain_Destroy return PR_SUCCESS; } +/* XXX uses tokens until slot list is in place */ +static NSSSlot ** +nssTrustDomain_GetActiveSlots +( + NSSTrustDomain *td, + nssUpdateLevel *updateLevel +) +{ + PRUint32 count; + NSSSlot **slots = NULL; + NSSToken **tp, **tokens; + *updateLevel = 1; + count = nssList_Count(td->tokenList); + tokens = nss_ZNEWARRAY(NULL, NSSToken *, count + 1); + if (!tokens) { + return NULL; + } + slots = nss_ZNEWARRAY(NULL, NSSSlot *, count + 1); + if (!slots) { + nss_ZFreeIf(tokens); + return NULL; + } + nssList_GetArray(td->tokenList, (void **)tokens, count); + count = 0; + for (tp = tokens; *tp; tp++) { + slots[count++] = nssToken_GetSlot(*tp); + } + nss_ZFreeIf(tokens); + return slots; +} + +/* XXX */ +static nssSession * +nssTrustDomain_GetSessionForToken +( + NSSTrustDomain *td, + NSSToken *token +) +{ + return nssToken_GetDefaultSession(token); +} + NSS_IMPLEMENT PRStatus NSSTrustDomain_SetDefaultCallback ( @@ -143,8 +182,24 @@ NSSTrustDomain_SetDefaultCallback NSSCallback **oldCallbackOpt ) { - nss_SetError(NSS_ERROR_NOT_FOUND); - return PR_FAILURE; + if (oldCallbackOpt) { + *oldCallbackOpt = td->defaultCallback; + } + td->defaultCallback = newCallback; + return PR_SUCCESS; +} + +NSS_IMPLEMENT NSSCallback * +nssTrustDomain_GetDefaultCallback +( + NSSTrustDomain *td, + PRStatus *statusOpt +) +{ + if (statusOpt) { + *statusOpt = PR_SUCCESS; + } + return td->defaultCallback; } NSS_IMPLEMENT NSSCallback * @@ -154,8 +209,7 @@ NSSTrustDomain_GetDefaultCallback PRStatus *statusOpt ) { - nss_SetError(NSS_ERROR_NOT_FOUND); - return NULL; + return nssTrustDomain_GetDefaultCallback(td, statusOpt); } NSS_IMPLEMENT PRStatus @@ -366,83 +420,115 @@ NSSTrustDomain_ImportEncodedPublicKey return NULL; } -static void cert_destructor(void *el) +static NSSCertificate ** +get_certs_from_list(nssList *list) { - NSSCertificate *c = (NSSCertificate *)el; - NSSCertificate_Destroy(c); + PRUint32 count = nssList_Count(list); + NSSCertificate **certs = NULL; + if (count > 0) { + certs = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1); + if (certs) { + nssList_GetArray(list, (void **)certs, count); + } + } + return certs; } -struct collect_arg_str { - nssList *list; - PRUint32 maximum; -}; - -extern const NSSError NSS_ERROR_MAXIMUM_FOUND; - -static PRStatus -collect_certs(NSSCertificate *c, void *arg) -{ - struct collect_arg_str *ca = (struct collect_arg_str *)arg; - /* Add the cert to the return list if not present */ - if (!nssList_Get(ca->list, (void *)c)) { - nssCertificate_AddRef(c); - nssList_Add(ca->list, (void *)c); - } - if (ca->maximum > 0 && nssList_Count(ca->list) >= ca->maximum) { - /* signal the end of collection) */ - nss_SetError(NSS_ERROR_MAXIMUM_FOUND); - return PR_FAILURE; - } - return PR_SUCCESS; -} - -NSS_IMPLEMENT NSSCertificate * -NSSTrustDomain_FindBestCertificateByNickname +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_FindCertificatesByNickname ( NSSTrustDomain *td, NSSUTF8 *name, - NSSTime *timeOpt, /* NULL for "now" */ - NSSUsage *usage, - NSSPolicies *policiesOpt /* NULL for none */ + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, /* 0 for no max */ + NSSArena *arenaOpt ) { - PRStatus nssrv; - NSSToken *token; - nssTokenCertSearch search; - nssBestCertificateCB best; + PRStatus status; + PRUint32 numRemaining; + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; + NSSCertificate **rvCerts = NULL; + nssPKIObjectCollection *collection = NULL; + nssUpdateLevel updateLevel; nssList *nameList; - PRBool notPresent; - /* set the criteria for determining the best cert */ - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - /* find all matching certs in the cache */ + /* First, grab from the cache */ nameList = nssList_Create(NULL, PR_FALSE); + if (!nameList) { + return NULL; + } (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList); - /* set the search criteria */ - search.callback = nssBestCertificate_Callback; - search.cbarg = &best; - search.cached = nameList; - search.searchType = nssTokenSearchType_TokenOnly; - /* traverse the tokens */ - for (token = (NSSToken *)nssListIterator_Start(td->tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(token, ¬Present)) { - nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, - name, &search); - } - if (notPresent) { - nssCertificateList_DestroyTokenCerts(nameList, token); - } - } - nssListIterator_Finish(td->tokens); - nssCertificateList_DoCallback(nameList, nssBestCertificate_Callback, &best); - nssList_Clear(nameList, cert_destructor); + rvCerts = get_certs_from_list(nameList); + /* initialize the collection of token certificates with the set of + * cached certs (if any). + */ + collection = nssCertificateCollection_Create(td, rvCerts); + nssCertificateArray_Destroy(rvCerts); nssList_Destroy(nameList); - if (best.cert) { - nssTrustDomain_AddCertsToCache(td, &best.cert, 1); + if (!collection) { + return (NSSCertificate **)NULL; } - return best.cert; + /* obtain the current set of active slots in the trust domain */ + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + /* iterate over the slots */ + numRemaining = maximumOpt; + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssCryptokiObject **instances; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + session = nssTrustDomain_GetSessionForToken(td, token); + if (!session) { + nssToken_Destroy(token); + goto loser; + } + instances = nssToken_FindCertificatesByNickname(token, + session, + name, + tokenOnly, + numRemaining, + &status); + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + goto loser; + } + if (instances) { + status = nssPKIObjectCollection_AddInstances(collection, + instances, 0); + nss_ZFreeIf(instances); + if (status != PR_SUCCESS) { + goto loser; + } + if (maximumOpt > 0) { + PRUint32 count; + count = nssPKIObjectCollection_Count(collection); + numRemaining = maximumOpt - count; + if (numRemaining == 0) break; + } + } + } + } + /* Grab the certs collected in the search. */ + rvCerts = nssPKIObjectCollection_GetCertificates(collection, + rvOpt, maximumOpt, + arenaOpt); + /* clean up */ + nssPKIObjectCollection_Destroy(collection); + nssSlotArray_Destroy(slots); + return rvCerts; +loser: + if (slots) { + nssSlotArray_Destroy(slots); + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + return (NSSCertificate **)NULL; } NSS_IMPLEMENT NSSCertificate ** @@ -455,150 +541,186 @@ NSSTrustDomain_FindCertificatesByNickname NSSArena *arenaOpt ) { - NSSCertificate **rvCerts = NULL; - NSSToken *token; - PRUint32 count; - PRStatus nssrv; - nssList *nameList; - nssTokenCertSearch search; - struct collect_arg_str ca; - PRBool notPresent; - /* set up the collection */ - nameList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsForNicknameFromCache(td, name, nameList); - ca.list = nameList; - ca.maximum = maximumOpt; - /* set the search criteria */ - search.callback = collect_certs; - search.cbarg = &ca; - search.cached = nameList; - search.searchType = nssTokenSearchType_TokenOnly; - /* traverse the tokens */ - for (token = (NSSToken *)nssListIterator_Start(td->tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(token, ¬Present)) { - nssrv = nssToken_TraverseCertificatesByNickname(token, NULL, - name, &search); - } - if (notPresent) { - nssCertificateList_DestroyTokenCerts(nameList, token); - } - } - nssListIterator_Finish(td->tokens); - count = nssList_Count(nameList); - if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt; - if (count > 0) { - if (rvOpt) { - nssList_GetArray(nameList, (void **)rvOpt, count); - rvOpt[count] = NULL; - } else { - rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); - nssList_GetArray(nameList, (void **)rvCerts, count); - } - nssTrustDomain_AddCertsToCache(td, rvCerts, count); - } - nssList_Destroy(nameList); - /* The return array assumes the references from the list */ - return rvCerts; -} - -static PRBool cert_token_not_present(NSSCertificate *c) -{ - nssListIterator *instances; - nssCryptokiInstance *instance; - PRBool freeIt = PR_FALSE; - PRBool notPresent = PR_TRUE; - instances = nssList_CreateIterator(c->object.instanceList); - for (instance = (nssCryptokiInstance *)nssListIterator_Start(instances); - instance != (nssCryptokiInstance *)NULL; - instance = (nssCryptokiInstance *)nssListIterator_Next(instances)) - { - if (!nssToken_IsPresent(instance->token)) { - nssToken_DestroyCertList(instance->token, PR_TRUE); - nssList_Remove(c->object.instanceList, instance); - freeIt = PR_TRUE; - } else { - notPresent = PR_FALSE; - } - } - nssListIterator_Finish(instances); - nssListIterator_Destroy(instances); - if (freeIt) { - nssListIterator_Destroy(c->object.instances); - c->object.instances = nssList_CreateIterator(c->object.instanceList); - } - return notPresent; + return nssTrustDomain_FindCertificatesByNickname(td, + name, + rvOpt, + maximumOpt, + arenaOpt); } NSS_IMPLEMENT NSSCertificate * -NSSTrustDomain_FindCertificateByIssuerAndSerialNumber +nssTrustDomain_FindBestCertificateByNickname ( NSSTrustDomain *td, - NSSDER *issuer, - NSSDER *serialNumber + NSSUTF8 *name, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt ) { + NSSCertificate **nicknameCerts; NSSCertificate *rvCert = NULL; - NSSToken *tok; - /* Try the cache */ - rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, - issuer, - serialNumber); - if (rvCert) { - if (cert_token_not_present(rvCert)) { - CERT_DestroyCertificate(STAN_GetCERTCertificate(rvCert)); - rvCert = NULL; - } - return rvCert; + nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name, + NULL, + 0, + NULL); + if (nicknameCerts) { + rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(nicknameCerts); } - /* Not cached, look for it on tokens */ - for (tok = (NSSToken *)nssListIterator_Start(td->tokens); - tok != (NSSToken *)NULL; - tok = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(tok, NULL)) { - rvCert = nssToken_FindCertificateByIssuerAndSerialNumber(tok, - NULL, - issuer, - serialNumber, - nssTokenSearchType_TokenOnly); - } -#ifdef NSS_3_4_CODE - if (!rvCert) { - /* Some tokens expect a decoded serial number. For compatibility, - * try the search again. - */ - NSSDER decodedSerial; - SECItem ds = { 0 }; - SECItem sn; - SECStatus secrv; - sn.data = serialNumber->data; - sn.len = serialNumber->size; - secrv = SEC_ASN1DecodeItem(NULL, &ds, SEC_IntegerTemplate, &sn); - if (secrv == SECSuccess) { - decodedSerial.data = ds.data; - decodedSerial.size = ds.len; - if (nssToken_SearchCerts(tok, NULL)) { - rvCert = nssToken_FindCertificateByIssuerAndSerialNumber( - tok, - NULL, - issuer, - &decodedSerial, - nssTokenSearchType_TokenOnly); + return rvCert; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestCertificateByNickname +( + NSSTrustDomain *td, + NSSUTF8 *name, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + return nssTrustDomain_FindBestCertificateByNickname(td, + name, + timeOpt, + usage, + policiesOpt); +} + +NSS_IMPLEMENT NSSCertificate ** +nssTrustDomain_FindCertificatesBySubject +( + NSSTrustDomain *td, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + PRStatus status; + PRUint32 numRemaining; + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; + NSSCertificate **rvCerts = NULL; + nssPKIObjectCollection *collection = NULL; + nssUpdateLevel updateLevel; + nssList *subjectList; + /* look in cache */ + subjectList = nssList_Create(NULL, PR_FALSE); + if (!subjectList) { + return NULL; + } + (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); + rvCerts = get_certs_from_list(subjectList); + collection = nssCertificateCollection_Create(td, rvCerts); + nssCertificateArray_Destroy(rvCerts); + nssList_Destroy(subjectList); + if (!collection) { + return (NSSCertificate **)NULL; + } + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + numRemaining = maximumOpt; + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssCryptokiObject **instances; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + session = nssTrustDomain_GetSessionForToken(td, token); + if (!session) { + nssToken_Destroy(token); + goto loser; + } + instances = nssToken_FindCertificatesBySubject(token, + session, + subject, + tokenOnly, + numRemaining, + &status); + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + goto loser; + } + if (instances) { + status = nssPKIObjectCollection_AddInstances(collection, + instances, 0); + nss_ZFreeIf(instances); + if (status != PR_SUCCESS) { + goto loser; + } + if (maximumOpt > 0) { + PRUint32 count; + count = nssPKIObjectCollection_Count(collection); + numRemaining = maximumOpt - count; + if (numRemaining == 0) break; } - PORT_Free(ds.data); } } -#endif - if (rvCert) { - /* cache it */ - nssTrustDomain_AddCertsToCache(td, &rvCert, 1); - break; - } } - nssListIterator_Finish(td->tokens); + rvCerts = nssPKIObjectCollection_GetCertificates(collection, + rvOpt, maximumOpt, + arenaOpt); + nssPKIObjectCollection_Destroy(collection); + nssSlotArray_Destroy(slots); + return rvCerts; +loser: + if (slots) { + nssSlotArray_Destroy(slots); + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + return (NSSCertificate **)NULL; +} + +NSS_IMPLEMENT NSSCertificate ** +NSSTrustDomain_FindCertificatesBySubject +( + NSSTrustDomain *td, + NSSDER *subject, + NSSCertificate *rvOpt[], + PRUint32 maximumOpt, + NSSArena *arenaOpt +) +{ + return nssTrustDomain_FindCertificatesBySubject(td, + subject, + rvOpt, + maximumOpt, + arenaOpt); +} + +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_FindBestCertificateBySubject +( + NSSTrustDomain *td, + NSSDER *subject, + NSSTime *timeOpt, + NSSUsage *usage, + NSSPolicies *policiesOpt +) +{ + NSSCertificate **subjectCerts; + NSSCertificate *rvCert = NULL; + subjectCerts = nssTrustDomain_FindCertificatesBySubject(td, subject, + NULL, + 0, + NULL); + if (subjectCerts) { + rvCert = nssCertificateArray_FindBestCertificate(subjectCerts, + timeOpt, + usage, + policiesOpt); + nssCertificateArray_Destroy(subjectCerts); + } return rvCert; } @@ -612,103 +734,11 @@ NSSTrustDomain_FindBestCertificateBySubject NSSPolicies *policiesOpt ) { - PRStatus nssrv; - NSSToken *token; - nssList *subjectList; - nssBestCertificateCB best; - nssTokenCertSearch search; - PRBool notPresent; - /* set the criteria for determining the best cert */ - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - /* find all matching certs in the cache */ - subjectList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); - /* set the search criteria */ - search.callback = nssBestCertificate_Callback; - search.cbarg = &best; - search.cached = subjectList; - search.searchType = nssTokenSearchType_TokenOnly; - /* traverse the tokens */ - for (token = (NSSToken *)nssListIterator_Start(td->tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(token, ¬Present)) { - nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, - subject, &search); - } - if (notPresent) { - nssCertificateList_DestroyTokenCerts(subjectList, token); - } - } - nssListIterator_Finish(td->tokens); - nssCertificateList_DoCallback(subjectList, - nssBestCertificate_Callback, &best); - nssList_Clear(subjectList, cert_destructor); - nssList_Destroy(subjectList); - if (best.cert) { - nssTrustDomain_AddCertsToCache(td, &best.cert, 1); - } - return best.cert; -} - -NSS_IMPLEMENT NSSCertificate ** -NSSTrustDomain_FindCertificatesBySubject -( - NSSTrustDomain *td, - NSSDER *subject, - NSSCertificate *rvOpt[], - PRUint32 maximumOpt, /* 0 for no max */ - NSSArena *arenaOpt -) -{ - PRStatus nssrv; - NSSCertificate **rvCerts = NULL; - NSSToken *token; - PRUint32 count; - nssList *subjectList; - struct collect_arg_str ca; - nssTokenCertSearch search; - PRBool notPresent; - /* set up the collection */ - subjectList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsForSubjectFromCache(td, subject, subjectList); - ca.list = subjectList; - ca.maximum = maximumOpt; - /* set the search criteria */ - search.callback = collect_certs; - search.cbarg = &ca; - search.cached = subjectList; - search.searchType = nssTokenSearchType_TokenOnly; - /* traverse the tokens */ - for (token = (NSSToken *)nssListIterator_Start(td->tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(token, ¬Present)) { - nssrv = nssToken_TraverseCertificatesBySubject(token, NULL, - subject, &search); - } - if (notPresent) { - nssCertificateList_DestroyTokenCerts(subjectList, token); - } - } - nssListIterator_Finish(td->tokens); - count = nssList_Count(subjectList); - if (maximumOpt > 0 && count > maximumOpt) count = maximumOpt; - if (count > 0) { - if (rvOpt) { - nssList_GetArray(subjectList, (void **)rvOpt, count); - rvOpt[count] = NULL; - } else { - rvCerts = nss_ZNEWARRAY(arenaOpt, NSSCertificate *, count + 1); - nssList_GetArray(subjectList, (void **)rvCerts, count); - } - nssTrustDomain_AddCertsToCache(td, rvCerts, count); - } - nssList_Destroy(subjectList); - /* The return array assumes the references from the list */ - return rvCerts; + return nssTrustDomain_FindBestCertificateBySubject(td, + subject, + timeOpt, + usage, + policiesOpt); } NSS_IMPLEMENT NSSCertificate * @@ -740,45 +770,138 @@ NSSTrustDomain_FindCertificatesByNameComponents } NSS_IMPLEMENT NSSCertificate * -NSSTrustDomain_FindCertificateByEncodedCertificate +nssTrustDomain_FindCertificateByIssuerAndSerialNumber ( NSSTrustDomain *td, - NSSBER *encodedCertificate + NSSDER *issuer, + NSSDER *serial ) { + PRStatus status; + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; NSSCertificate *rvCert = NULL; - NSSToken *tok; - /* Try the cache */ - rvCert = nssTrustDomain_GetCertByDERFromCache(td, encodedCertificate); + nssPKIObjectCollection *collection = NULL; + nssUpdateLevel updateLevel; + /* see if this search is already cached */ + rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, + issuer, + serial); if (rvCert) { - if (cert_token_not_present(rvCert)) { - CERT_DestroyCertificate(STAN_GetCERTCertificate(rvCert)); - rvCert = NULL; - } return rvCert; } - /* Not cached, look for it on tokens */ - for (tok = (NSSToken *)nssListIterator_Start(td->tokens); - tok != (NSSToken *)NULL; - tok = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(tok, NULL)) { - rvCert = nssToken_FindCertificateByEncodedCertificate(tok, NULL, - encodedCertificate, - nssTokenSearchType_TokenOnly); - } - if (rvCert) { - /* cache it */ - nssTrustDomain_AddCertsToCache(td, &rvCert, 1); - break; + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssCryptokiObject *instance; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + session = nssTrustDomain_GetSessionForToken(td, token); + if (!session) { + nssToken_Destroy(token); + goto loser; + } + instance = nssToken_FindCertificateByIssuerAndSerialNumber( + token, + session, + issuer, + serial, + tokenOnly, + &status); + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + goto loser; + } + if (instance) { + if (!collection) { + collection = nssCertificateCollection_Create(td, NULL); + if (!collection) { + goto loser; + } + } + nssPKIObjectCollection_AddInstances(collection, + &instance, 1); + } } } - nssListIterator_Finish(td->tokens); + if (collection) { + (void)nssPKIObjectCollection_GetCertificates(collection, + &rvCert, 1, NULL); + nssPKIObjectCollection_Destroy(collection); + if (!rvCert) { + goto loser; + } + } + nssSlotArray_Destroy(slots); + return rvCert; +loser: + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + if (slots) { + nssSlotArray_Destroy(slots); + } + return (NSSCertificate *)NULL; +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindCertificateByIssuerAndSerialNumber +( + NSSTrustDomain *td, + NSSDER *issuer, + NSSDER *serial +) +{ + return nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, + issuer, + serial); +} + +NSS_IMPLEMENT NSSCertificate * +nssTrustDomain_FindCertificateByEncodedCertificate +( + NSSTrustDomain *td, + NSSBER *ber +) +{ + PRStatus status; + NSSCertificate *rvCert = NULL; + NSSDER issuer = { 0 }; + NSSDER serial = { 0 }; + NSSArena *arena = nssArena_Create(); + if (!arena) { + return (NSSCertificate *)NULL; + } + /* XXX this is not generic... will any cert crack into issuer/serial? */ + status = nssPKIX509_GetIssuerAndSerialFromDER(ber, arena, &issuer, &serial); + if (status != PR_SUCCESS) { + goto finish; + } + rvCert = nssTrustDomain_FindCertificateByIssuerAndSerialNumber(td, + &issuer, + &serial); +finish: + nssArena_Destroy(arena); return rvCert; } NSS_IMPLEMENT NSSCertificate * -NSSTrustDomain_FindCertificateByEmail +NSSTrustDomain_FindCertificateByEncodedCertificate +( + NSSTrustDomain *td, + NSSBER *ber +) +{ + return nssTrustDomain_FindCertificateByEncodedCertificate(td, ber); +} + +NSS_IMPLEMENT NSSCertificate * +NSSTrustDomain_FindBestCertificateByEmail ( NSSTrustDomain *td, NSSASCII7 *email, @@ -787,44 +910,7 @@ NSSTrustDomain_FindCertificateByEmail NSSPolicies *policiesOpt ) { - PRStatus nssrv; - NSSToken *token; - nssBestCertificateCB best; - nssTokenCertSearch search; - nssList *emailList; - PRBool notPresent; - /* set the criteria for determining the best cert */ - nssBestCertificate_SetArgs(&best, timeOpt, usage, policiesOpt); - /* find all matching certs in the cache */ - emailList = nssList_Create(NULL, PR_FALSE); - (void)nssTrustDomain_GetCertsForEmailAddressFromCache(td, email, emailList); - /* set the search criteria */ - search.callback = nssBestCertificate_Callback; - search.cbarg = &best; - search.cached = emailList; - search.searchType = nssTokenSearchType_TokenOnly; - /* traverse the tokens */ - for (token = (NSSToken *)nssListIterator_Start(td->tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(td->tokens)) - { - if (nssToken_SearchCerts(token, ¬Present)) { - nssrv = nssToken_TraverseCertificatesByEmail(token, NULL, - email, &search); - } - if (notPresent) { - nssCertificateList_DestroyTokenCerts(emailList, token); - } - } - nssListIterator_Finish(td->tokens); - nssCertificateList_DoCallback(emailList, - nssBestCertificate_Callback, &best); - nssList_Clear(emailList, cert_destructor); - nssList_Destroy(emailList); - if (best.cert) { - nssTrustDomain_AddCertsToCache(td, &best.cert, 1); - } - return best.cert; + return 0; } NSS_IMPLEMENT NSSCertificate ** @@ -947,61 +1033,6 @@ NSSTrustDomain_FindUserCertificatesForEmailSigning return NULL; } -struct traverse_arg -{ - PRStatus (*callback)(NSSCertificate *c, void *arg); - nssList *cached; - void *arg; -}; - -static PRStatus traverse_callback(NSSCertificate *c, void *arg) -{ - PRStatus nssrv; - struct traverse_arg *ta = (struct traverse_arg *)arg; - NSSCertificate *cp = nssCertificate_AddRef(c); - NSSTrustDomain *td = NSSCertificate_GetTrustDomain(c); - /* The cert coming in has been retrieved from a token. It was not in - * the cache when the search was begun. But it may be in the cache now, - * and if it isn't, it will be, because it is going to be cracked into - * a CERTCertificate and fed into the callback. - */ - nssrv = nssTrustDomain_AddCertsToCache(td, &c, 1); - if (!nssList_Get(ta->cached, c)) { - /* add it to the cached list for this search */ - nssCertificate_AddRef(c); - nssList_Add(ta->cached, c); - } - /* This is why the hack of copying the cert was done above. The pointer - * c passed to this function is provided by retrieve_cert. That function - * will destroy the pointer once this function returns. Since c is a local - * copy, there is no way to notify retrieve_cert if it has changed. That - * would happen if the above call to add it to the cache found the cert - * already there. In that case, the pointer c passed to the callback - * below will be the cached cert, and the pointer c that retrieve_cert - * has will be the same as the copy made above. Thus, retrieve_cert will - * destroy the reference to the copy, the callback will use the reference - * to the cached entry, and everyone should be happy. - */ - nssrv = (*ta->callback)(c, ta->arg); - /* This function owns a reference to the cert, either from the AddRef - * or by getting it from the cache. - */ - CERT_DestroyCertificate(STAN_GetCERTCertificate(c)); - return nssrv; -} - -#ifdef NSS_3_4_CODE -static void cert_destructor_with_cache(void *el) -{ - NSSCertificate *c = (NSSCertificate *)el; - CERTCertificate *cert = STAN_GetCERTCertificate(c); - /* It's already been obtained as a CERTCertificate, so it must - * be destroyed as one - */ - CERT_DestroyCertificate(cert); -} -#endif - NSS_IMPLEMENT PRStatus * NSSTrustDomain_TraverseCertificates ( @@ -1010,63 +1041,138 @@ NSSTrustDomain_TraverseCertificates void *arg ) { - PRStatus nssrv; - NSSToken *token; - nssList *certList, *cacheList; - nssTokenCertSearch search; - struct traverse_arg ta; - nssListIterator *tokens; - PRBool notPresent; + PRStatus status; + NSSToken *token = NULL; + NSSSlot **slots = NULL; + NSSSlot **slotp; + nssPKIObjectCollection *collection = NULL; + nssPKIObjectCallback pkiCallback; + nssUpdateLevel updateLevel; + NSSCertificate **cached = NULL; + nssList *certList; certList = nssList_Create(NULL, PR_FALSE); if (!certList) return NULL; (void *)nssTrustDomain_GetCertsFromCache(td, certList); - cacheList = nssList_Clone(certList); - if (!cacheList) { - goto cleanup; - } - /* set traverse args */ - ta.callback = callback; - ta.cached = certList; - ta.arg = arg; - /* set the search criteria */ - search.callback = traverse_callback; - search.cbarg = &ta; - search.cached = certList; - search.searchType = nssTokenSearchType_TokenOnly; - /* Must create a local copy of the token list, because the callback - * above may want to traverse the tokens as well. - */ - tokens = nssList_CreateIterator(td->tokenList); - if (!tokens) { - goto cleanup; - } - /* traverse the tokens */ - for (token = (NSSToken *)nssListIterator_Start(tokens); - token != (NSSToken *)NULL; - token = (NSSToken *)nssListIterator_Next(tokens)) - { - if (nssToken_SearchCerts(token, ¬Present)) { - nssrv = nssToken_TraverseCertificates(token, NULL, &search); - } - if (notPresent) { - nssCertificateList_RemoveTokenCerts(cacheList, token); - } - } - nssListIterator_Finish(tokens); - nssListIterator_Destroy(tokens); - /* now do the callback on the cached certs, - * sans certs from removed tokens - */ - nssCertificateList_DoCallback(cacheList, callback, arg); - nssList_Destroy(cacheList); -cleanup: -#ifdef NSS_3_4_CODE - nssList_Clear(certList, cert_destructor_with_cache); -#else - nssList_Clear(certList, cert_destructor); -#endif + cached = get_certs_from_list(certList); + collection = nssCertificateCollection_Create(td, cached); + nssCertificateArray_Destroy(cached); nssList_Destroy(certList); + if (!collection) { + return (PRStatus *)NULL; + } + /* obtain the current set of active slots in the trust domain */ + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + goto loser; + } + /* iterate over the slots */ + for (slotp = slots; *slotp; slotp++) { + /* get the token for the slot, if present */ + token = nssSlot_GetToken(*slotp); + if (token) { + nssSession *session; + nssCryptokiObject **instances; + nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly; + /* get a session for the token */ + session = nssTrustDomain_GetSessionForToken(td, token); + if (!session) { + nssToken_Destroy(token); + goto loser; + } + /* perform the traversal */ + instances = nssToken_FindCertificates(token, + session, + tokenOnly, + 0, &status); + nssToken_Destroy(token); + if (status != PR_SUCCESS) { + goto loser; + } + /* add the found certificates to the collection */ + status = nssPKIObjectCollection_AddInstances(collection, + instances, 0); + nss_ZFreeIf(instances); + if (status != PR_SUCCESS) { + goto loser; + } + } + } + /* Traverse the collection */ + pkiCallback.func.cert = callback; + pkiCallback.arg = arg; + status = nssPKIObjectCollection_Traverse(collection, &pkiCallback); + /* clean up */ + nssPKIObjectCollection_Destroy(collection); + nssSlotArray_Destroy(slots); return NULL; +loser: + if (slots) { + nssSlotArray_Destroy(slots); + } + if (collection) { + nssPKIObjectCollection_Destroy(collection); + } + return NULL; +} + +NSS_IMPLEMENT NSSTrust * +nssTrustDomain_FindTrustForCertificate +( + NSSTrustDomain *td, + NSSCertificate *c +) +{ + PRStatus status; + NSSSlot **slots; + NSSSlot **slotp; + NSSToken *token; + nssCryptokiObject *to = NULL; + nssPKIObject *pkio = NULL; + NSSTrust *rvt = NULL; + nssUpdateLevel updateLevel; + slots = nssTrustDomain_GetActiveSlots(td, &updateLevel); + if (!slots) { + return (NSSTrust *)NULL; + } + for (slotp = slots; *slotp; slotp++) { + token = nssSlot_GetToken(*slotp); + to = nssToken_FindTrustForCertificate(token, NULL, + &c->encoding, + &c->issuer, + &c->serial, + nssTokenSearchType_TokenOnly); + if (to) { + if (!pkio) { + pkio = nssPKIObject_Create(NULL, to, td, NULL); + if (!pkio) { + goto loser; + } + } else { + status = nssPKIObject_AddInstance(pkio, to); + if (status != PR_SUCCESS) { + goto loser; + } + } + } + nssToken_Destroy(token); + } + if (pkio) { + rvt = nssTrust_Create(pkio); + if (!rvt) { + goto loser; + } + } + nssSlotArray_Destroy(slots); + return rvt; +loser: + nssSlotArray_Destroy(slots); + if (to) { + nssCryptokiObject_Destroy(to); + } + if (pkio) { + nssPKIObject_Destroy(pkio); + } + return (NSSTrust *)NULL; } NSS_IMPLEMENT PRStatus @@ -1126,6 +1232,16 @@ NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID return NULL; } +NSS_IMPLEMENT NSSCryptoContext * +nssTrustDomain_CreateCryptoContext +( + NSSTrustDomain *td, + NSSCallback *uhhOpt +) +{ + return nssCryptoContext_Create(td, uhhOpt); +} + NSS_IMPLEMENT NSSCryptoContext * NSSTrustDomain_CreateCryptoContext ( @@ -1133,19 +1249,7 @@ NSSTrustDomain_CreateCryptoContext NSSCallback *uhhOpt ) { - NSSArena *arena; - NSSCryptoContext *rvCC; - arena = NSSArena_Create(); - if (!arena) { - return NULL; - } - rvCC = nss_ZNEW(arena, NSSCryptoContext); - if (!rvCC) { - return NULL; - } - rvCC->td = td; - rvCC->arena = arena; - return rvCC; + return nssTrustDomain_CreateCryptoContext(td, uhhOpt); } NSS_IMPLEMENT NSSCryptoContext *