summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian.mcgreer%sun.com <devnull@localhost>2002-04-15 15:22:11 +0000
committerian.mcgreer%sun.com <devnull@localhost>2002-04-15 15:22:11 +0000
commit46632f2256d6e706f8c3403a5e37a90216266bd9 (patch)
tree424bf6579cec5cd2e22141327851d693f1a20ccb
parent2bab8ee7cbd377ea5fcef1da434e8424fe475c6e (diff)
downloadnss-hg-46632f2256d6e706f8c3403a5e37a90216266bd9.tar.gz
bug 135521, change cert lookups on tokens to be actual finds instead of traversals
-rw-r--r--security/nss/lib/certdb/stanpcertdb.c72
-rw-r--r--security/nss/lib/dev/ckhelper.c12
-rw-r--r--security/nss/lib/dev/ckhelper.h8
-rw-r--r--security/nss/lib/dev/dev.h116
-rw-r--r--security/nss/lib/dev/devt.h5
-rw-r--r--security/nss/lib/dev/devtoken.c136
-rw-r--r--security/nss/lib/dev/devutil.c4
-rw-r--r--security/nss/lib/dev/manifest.mn1
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c22
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c519
-rw-r--r--security/nss/lib/pki/certdecode.c108
-rw-r--r--security/nss/lib/pki/certificate.c531
-rw-r--r--security/nss/lib/pki/cryptocontext.c262
-rw-r--r--security/nss/lib/pki/manifest.mn1
-rw-r--r--security/nss/lib/pki/pki.h128
-rw-r--r--security/nss/lib/pki/pki3hack.c385
-rw-r--r--security/nss/lib/pki/pki3hack.h4
-rw-r--r--security/nss/lib/pki/pkibase.c120
-rw-r--r--security/nss/lib/pki/pkim.h562
-rw-r--r--security/nss/lib/pki/pkistore.c2
-rw-r--r--security/nss/lib/pki/pkit.h46
-rw-r--r--security/nss/lib/pki/pkitm.h12
-rw-r--r--security/nss/lib/pki/tdcache.c56
-rw-r--r--security/nss/lib/pki/trustdomain.c1080
24 files changed, 2304 insertions, 1888 deletions
diff --git a/security/nss/lib/certdb/stanpcertdb.c b/security/nss/lib/certdb/stanpcertdb.c
index 7b1dd0f82..ef9b04e1a 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;
- usage.anyUsage = PR_TRUE;
- nssBestCertificate_SetArgs(&best, NULL, &usage, NULL);
- if (ct) {
- nssBestCertificate_Callback(ct, (void *)&best);
- }
- if (cp) {
- nssBestCertificate_Callback(cp, (void *)&best);
+ NSSCertificate *arr[3];
+ if (!ct) {
+ return nssCertificate_AddRef(cp);
+ } else if (!cp) {
+ return nssCertificate_AddRef(ct);
}
- return best.cert;
+ arr[0] = ct;
+ arr[1] = cp;
+ arr[2] = NULL;
+ usage.anyUsage = PR_TRUE;
+ 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 6092128c6..c07afd649 100644
--- a/security/nss/lib/dev/ckhelper.c
+++ b/security/nss/lib/dev/ckhelper.c
@@ -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 f09088041..fc64ea9b7 100644
--- a/security/nss/lib/dev/ckhelper.h
+++ b/security/nss/lib/dev/ckhelper.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 ccce63c8a..2e7bc4cdd 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.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
-(
- nssCryptokiInstance *instance
-);
-
-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_GetTrustOrder
(
- 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
+ NSSToken *tok
);
-#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 b712f644e..4d7b2feaf 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -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 5da32851f..52c3b9c4c 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -48,6 +48,8 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#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; i<otsize; i++) {
if (obj_template[i].type == CKA_CLASS) {
objclass = *(CK_OBJECT_CLASS *)obj_template[i].pValue;
@@ -487,6 +495,7 @@ find_objects_by_template
maximumOpt);
if (statusOpt) *statusOpt = PR_SUCCESS;
}
+#endif /* PURE_STAN_BUILD */
/* Either they are not cached, or cache failed; look on token. */
if (!objects) {
objects = find_objects(token, sessionOpt,
@@ -538,11 +547,13 @@ nssToken_ImportCertificate
NSS_CK_TEMPLATE_FINISH(cert_tmpl, attr, ctsize);
/* Import the certificate onto the token */
rvObject = import_object(tok, sessionOpt, cert_tmpl, ctsize);
+#ifdef PURE_STAN_BUILD
if (rvObject && tok->cache) {
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 955b79b28..083c898ab 100644
--- a/security/nss/lib/dev/devutil.c
+++ b/security/nss/lib/dev/devutil.c
@@ -43,7 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#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 7f7ac0101..df0151ef2 100644
--- a/security/nss/lib/dev/manifest.mn
+++ b/security/nss/lib/dev/manifest.mn
@@ -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 45e5a9d74..9994cb65b 100644
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -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 39bbf804f..0addf8e74 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; i<count; i++) {
+ tokens = nssPKIObject_GetTokens(&certs[i]->object, 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);
- }
- }
- if (subjectList) {
- nssList_Clear(subjectList, cert_destructor);
- nssList_Destroy(subjectList);
+ 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);
+ }
+ 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);
+ if (!nameList) {
+ return SECFailure;
+ }
(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) {
- nssList_Clear(nameList, cert_destructor);
- nssList_Destroy(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);
+ }
+ 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);
- }
- nssList_Clear(certList, cert_destructor);
- nssList_Destroy(certList);
+ 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;
+ }
+ }
+ 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 fbf0c1d67..cac766496 100644
--- a/security/nss/lib/pki/certdecode.c
+++ b/security/nss/lib/pki/certdecode.c
@@ -43,78 +43,6 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#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 f9dc9a7e3..049c8ddcb 100644
--- a/security/nss/lib/pki/certificate.c
+++ b/security/nss/lib/pki/certificate.c
@@ -61,6 +61,40 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
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,79 +287,88 @@ nssCertificate_GetDecoding
return c->decoding;
}
-static void
-nssCertificateArray_Destroy
+static NSSCertificate *
+filter_subject_certs_for_id
(
- NSSCertificate **certArray
+ NSSCertificate **subjectCerts,
+ NSSItem *id
)
{
- 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)
-{
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
@@ -318,145 +376,110 @@ find_issuer_cert_for_identifier(NSSCertificate *c, NSSItem *id)
* if authority key id does not exist
*/
NSS_IMPLEMENT NSSCertificate **
-NSSCertificate_BuildChain
+nssCertificate_BuildChain
(
NSSCertificate *c,
NSSTime *timeOpt,
NSSUsage *usage,
NSSPolicies *policiesOpt,
NSSCertificate **rvOpt,
- PRUint32 rvLimit, /* zero for no limit */
+ PRUint32 rvLimit,
NSSArena *arenaOpt,
PRStatus *statusOpt
)
{
- PRStatus nssrv;
- nssList *chain;
- NSSItem *issuerID;
+ PRStatus status;
NSSCertificate **rvChain;
+#ifdef NSS_3_4_CODE
+ NSSCertificate *cp;
+#endif
NSSTrustDomain *td;
- NSSCryptoContext *cc;
- nssDecodedCert *dc;
- NSSCertificate *ct, *cp;
- cc = c->object.cryptoContext; /* NSSCertificate_GetCryptoContext(c); */
+ nssPKIObjectCollection *collection;
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;
+ 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;
-#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) {
+ c = find_cert_issuer(cp, timeOpt, usage, policiesOpt);
+ if (!c && !usage->anyUsage) {
usage->anyUsage = PR_TRUE;
- cp = NSSTrustDomain_FindBestCertificateBySubject(td,
- issuer,
- timeOpt,
- usage,
- policiesOpt);
+ c = find_cert_issuer(cp, 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;
+ }
+#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;
}
- 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? */
+ rvChain = nssPKIObjectCollection_GetCertificates(collection,
+ rvOpt,
+ rvLimit,
+ arenaOpt);
+ nssPKIObjectCollection_Destroy(collection);
return rvChain;
}
+NSS_IMPLEMENT NSSCertificate **
+NSSCertificate_BuildChain
+(
+ NSSCertificate *c,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt,
+ NSSCertificate **rvOpt,
+ PRUint32 rvLimit, /* zero for no limit */
+ NSSArena *arenaOpt,
+ PRStatus *statusOpt
+)
+{
+ 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_GetTrustDomain
(
NSSCertificate *c
)
@@ -464,6 +487,15 @@ NSSCertificate_GetTrustDomain
return c->object.trustDomain;
}
+NSS_IMPLEMENT NSSTrustDomain *
+NSSCertificate_GetTrustDomain
+(
+ NSSCertificate *c
+)
+{
+ return nssCertificate_GetTrustDomain(c);
+}
+
NSS_IMPLEMENT NSSToken *
NSSCertificate_GetToken
(
@@ -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;
}
+ object = nssPKIObject_Create(arena, NULL, td, cc);
+ if (!object) {
+ goto loser;
+ }
rvProfile = nss_ZNEW(arena, nssSMIMEProfile);
if (!rvProfile) {
- nssArena_Destroy(arena);
- return NULL;
- }
- nssrv = nssPKIObject_Initialize(&rvProfile->object, arena, NULL, NULL);
- if (nssrv != PR_SUCCESS) {
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 */
@@ -896,6 +930,65 @@ nssCertificateList_AddReferences
}
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; i<object->numInstances; 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
(
NSSTrust *trust
diff --git a/security/nss/lib/pki/cryptocontext.c b/security/nss/lib/pki/cryptocontext.c
index f713bcb10..21d524072 100644
--- a/security/nss/lib/pki/cryptocontext.c
+++ b/security/nss/lib/pki/cryptocontext.c
@@ -35,33 +35,56 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
+#ifndef DEV_H
+#include "dev.h"
+#endif /* DEV_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 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 2367cf8e4..c4bf70b24 100644
--- a/security/nss/lib/pki/manifest.mn
+++ b/security/nss/lib/pki/manifest.mn
@@ -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 4460b52be..d9af582b0 100644
--- a/security/nss/lib/pki/pki.h
+++ b/security/nss/lib/pki/pki.h
@@ -38,29 +38,147 @@
static const char PKI_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $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 df4259495..b9aa12ac5 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -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 be146e99d..222dfdaf7 100644
--- a/security/nss/lib/pki/pki3hack.h
+++ b/security/nss/lib/pki/pki3hack.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 42915126d..3a20ae96f 100644
--- a/security/nss/lib/pki/pkibase.c
+++ b/security/nss/lib/pki/pkibase.c
@@ -43,6 +43,10 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#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; i<object->numInstances; 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; i<object->numInstances; 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; i<object->numInstances; 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; i<MAX_ITEMS_FOR_UID; i++) {
node->uid[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 566381055..d928d24e5 100644
--- a/security/nss/lib/pki/pkim.h
+++ b/security/nss/lib/pki/pkim.h
@@ -42,97 +42,468 @@ static const char PKIM_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#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
);
-NSS_EXTERN nssHash *
-nssHash_CreateCertificate
+/* 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,
- PRUint32 numBuckets
+ NSSDER *encoding,
+ NSSCertificateType type
+);
+
+NSS_EXTERN PRStatus
+nssDecodedCert_Destroy
+(
+ nssDecodedCert *dc
);
-/* Token ordering routines */
+NSS_EXTERN NSSTrust *
+nssTrust_Create
+(
+ nssPKIObject *object
+);
-/*
- * Given a crypto algorithm, return the preferred token for performing
- * the crypto operation.
+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 NSSToken *
-nssTrustDomain_GetCryptoToken
+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,
- NSSAlgorithmAndParameters *ap
+ NSSCertificate **certsOpt
);
-/* The following routines are used to obtain the preferred token on which
- * to store particular objects.
+/* 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
+);
-/*
- * Find the preferred token for storing user certificates.
+/* nssPublicKeyCollection_Create
+ *
+ * Create a collection of public keys in the specified trust domain.
+ * Optionally provide a starting set of keys.
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetUserCertToken
+NSS_EXTERN nssPKIObjectCollection *
+nssPublicKeyCollection_Create
(
- NSSTrustDomain *td
+ NSSTrustDomain *td,
+ NSSPublicKey **pvkOpt
);
-/*
- * Find the preferred token for storing email certificates.
+/* nssPKIObjectCollection_Destroy
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetEmailCertToken
+NSS_EXTERN void
+nssPKIObjectCollection_Destroy
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection
);
-/*
- * Find the preferred token for storing SSL certificates.
+/* nssPKIObjectCollection_Count
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetSSLCertToken
+NSS_EXTERN PRUint32
+nssPKIObjectCollection_Count
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection
);
-/*
- * Find the preferred token for storing root certificates.
+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 NSSToken *
-nssTrustDomain_GetRootCertToken
+NSS_EXTERN PRStatus
+nssPKIObjectCollection_AddInstances
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection,
+ nssCryptokiObject **instances,
+ PRUint32 numInstances
);
-/*
- * Find the preferred token for storing private keys.
+/* nssPKIObjectCollection_Traverse
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetPrivateKeyToken
+NSS_EXTERN PRStatus
+nssPKIObjectCollection_Traverse
(
- NSSTrustDomain *td
+ nssPKIObjectCollection *collection,
+ nssPKIObjectCallback *callback
);
-/*
- * Find the preferred token for storing symmetric keys.
+/* nssPKIObjectCollection_GetCertificates
+ *
+ * Get all of the certificates in the collection.
*/
-NSS_EXTERN NSSToken *
-nssTrustDomain_GetSymmetricKeyToken
+NSS_EXTERN NSSCertificate **
+nssPKIObjectCollection_GetCertificates
(
- NSSTrustDomain *td
+ 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
);
-/* Certificate cache routines */
+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 *
+nssHash_CreateCertificate
+(
+ NSSArena *arenaOpt,
+ PRUint32 numBuckets
+);
+
+/* 3.4 Certificate cache routines */
+
+NSS_EXTERN PRStatus
+nssTrustDomain_InitializeCache
+(
+ NSSTrustDomain *td,
+ PRUint32 cacheSize
+);
NSS_EXTERN PRStatus
nssTrustDomain_AddCertsToCache
@@ -238,54 +609,11 @@ nssTrustDomain_GetCertsFromCache
nssList *certListOpt
);
-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 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
+NSS_EXTERN void
+nssTrustDomain_DumpCacheInfo
(
- 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 0b1463fcb..d5192a16a 100644
--- a/security/nss/lib/pki/pkistore.c
+++ b/security/nss/lib/pki/pkistore.c
@@ -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 1e0f98a4f..23008d352 100644
--- a/security/nss/lib/pki/pkit.h
+++ b/security/nss/lib/pki/pkit.h
@@ -71,13 +71,6 @@ static const char PKIT_CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
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 a943fd834..699a1b91c 100644
--- a/security/nss/lib/pki/pkitm.h
+++ b/security/nss/lib/pki/pkitm.h
@@ -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 e34c6403a..e1ddc7169 100644
--- a/security/nss/lib/pki/tdcache.c
+++ b/security/nss/lib/pki/tdcache.c
@@ -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; i<numCerts && certs[i]; i++) {
- if (add_cert_to_cache(td, certs[i]) != PR_SUCCESS) {
- if ((e = NSS_GetError()) == NSS_ERROR_CERTIFICATE_IN_CACHE) {
- /* collision - delete and replace the cert here in favor
- * of the already cached entry. This is safe as long as
- * the cert being added here only has a single reference.
- * This should be the case as this function is only called
- * immediately following a traversal and before any certs
- * are returned to the caller.
- */
- NSSCertificate *c;
- c = nssTrustDomain_GetCertForIssuerAndSNFromCache(td,
- &certs[i]->issuer,
- &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 f3ebc5125..2fc2dedfc 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -35,41 +35,42 @@
static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#endif /* DEBUG */
-#ifndef NSSPKI_H
-#include "nsspki.h"
-#endif /* NSSPKI_H */
-
-#ifndef PKI_H
-#include "pki.h"
-#endif /* PKI_H */
+#ifndef DEV_H
+#include "dev.h"
+#endif /* DEV_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 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);
-}
-
-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;
+ 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 PR_SUCCESS;
+ return certs;
}
-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, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesByNickname(token, NULL,
- name, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(nameList, token);
+ 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 (!collection) {
+ return (NSSCertificate **)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 */
+ 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;
+ }
+ }
}
}
- nssListIterator_Finish(td->tokens);
- nssCertificateList_DoCallback(nameList, nssBestCertificate_Callback, &best);
- nssList_Clear(nameList, cert_destructor);
- nssList_Destroy(nameList);
- if (best.cert) {
- nssTrustDomain_AddCertsToCache(td, &best.cert, 1);
+ /* 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);
}
- return best.cert;
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
+ }
+ return (NSSCertificate **)NULL;
}
NSS_IMPLEMENT NSSCertificate **
@@ -455,260 +541,204 @@ 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, &notPresent)) {
- 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;
- }
- /* 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);
- }
- PORT_Free(ds.data);
- }
- }
-#endif
- if (rvCert) {
- /* cache it */
- nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
- break;
- }
+ nicknameCerts = nssTrustDomain_FindCertificatesByNickname(td, name,
+ NULL,
+ 0,
+ NULL);
+ if (nicknameCerts) {
+ rvCert = nssCertificateArray_FindBestCertificate(nicknameCerts,
+ timeOpt,
+ usage,
+ policiesOpt);
+ nssCertificateArray_Destroy(nicknameCerts);
}
- nssListIterator_Finish(td->tokens);
return rvCert;
}
NSS_IMPLEMENT NSSCertificate *
-NSSTrustDomain_FindBestCertificateBySubject
+NSSTrustDomain_FindBestCertificateByNickname
(
NSSTrustDomain *td,
- NSSDER *subject,
+ NSSUTF8 *name,
NSSTime *timeOpt,
NSSUsage *usage,
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, &notPresent)) {
- 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;
+ return nssTrustDomain_FindBestCertificateByNickname(td,
+ name,
+ timeOpt,
+ usage,
+ policiesOpt);
}
NSS_IMPLEMENT NSSCertificate **
-NSSTrustDomain_FindCertificatesBySubject
+nssTrustDomain_FindCertificatesBySubject
(
NSSTrustDomain *td,
NSSDER *subject,
NSSCertificate *rvOpt[],
- PRUint32 maximumOpt, /* 0 for no max */
+ PRUint32 maximumOpt,
NSSArena *arenaOpt
)
{
- PRStatus nssrv;
+ PRStatus status;
+ PRUint32 numRemaining;
+ NSSToken *token = NULL;
+ NSSSlot **slots = NULL;
+ NSSSlot **slotp;
NSSCertificate **rvCerts = NULL;
- NSSToken *token;
- PRUint32 count;
+ nssPKIObjectCollection *collection = NULL;
+ nssUpdateLevel updateLevel;
nssList *subjectList;
- struct collect_arg_str ca;
- nssTokenCertSearch search;
- PRBool notPresent;
- /* set up the collection */
+ /* look in cache */
subjectList = nssList_Create(NULL, PR_FALSE);
+ if (!subjectList) {
+ return NULL;
+ }
(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, &notPresent)) {
- nssrv = nssToken_TraverseCertificatesBySubject(token, NULL,
- subject, &search);
- }
- if (notPresent) {
- nssCertificateList_DestroyTokenCerts(subjectList, token);
- }
+ rvCerts = get_certs_from_list(subjectList);
+ collection = nssCertificateCollection_Create(td, rvCerts);
+ nssCertificateArray_Destroy(rvCerts);
+ nssList_Destroy(subjectList);
+ if (!collection) {
+ return (NSSCertificate **)NULL;
}
- 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);
+ 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;
+ }
+ }
}
- nssTrustDomain_AddCertsToCache(td, rvCerts, count);
}
- nssList_Destroy(subjectList);
- /* The return array assumes the references from the list */
+ 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;
+}
+
+NSS_IMPLEMENT NSSCertificate *
+NSSTrustDomain_FindBestCertificateBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject,
+ NSSTime *timeOpt,
+ NSSUsage *usage,
+ NSSPolicies *policiesOpt
+)
+{
+ 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);
+ 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);
+ }
}
- if (rvCert) {
- /* cache it */
- nssTrustDomain_AddCertsToCache(td, &rvCert, 1);
- break;
+ }
+ if (collection) {
+ (void)nssPKIObjectCollection_GetCertificates(collection,
+ &rvCert, 1, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ if (!rvCert) {
+ goto loser;
}
}
- nssListIterator_Finish(td->tokens);
+ 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, &notPresent)) {
- 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;
+ cached = get_certs_from_list(certList);
+ collection = nssCertificateCollection_Create(td, cached);
+ nssCertificateArray_Destroy(cached);
+ nssList_Destroy(certList);
+ if (!collection) {
+ return (PRStatus *)NULL;
}
- /* 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;
+ /* obtain the current set of active slots in the trust domain */
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
}
- /* traverse the tokens */
- for (token = (NSSToken *)nssListIterator_Start(tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(tokens))
- {
- if (nssToken_SearchCerts(token, &notPresent)) {
- nssrv = nssToken_TraverseCertificates(token, NULL, &search);
- }
- if (notPresent) {
- nssCertificateList_RemoveTokenCerts(cacheList, token);
+ /* 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;
+ }
}
}
- 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
- nssList_Destroy(certList);
+ /* 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
@@ -1127,25 +1233,23 @@ NSSTrustDomain_FindSymmetricKeyByAlgorithmAndKeyID
}
NSS_IMPLEMENT NSSCryptoContext *
+nssTrustDomain_CreateCryptoContext
+(
+ NSSTrustDomain *td,
+ NSSCallback *uhhOpt
+)
+{
+ return nssCryptoContext_Create(td, uhhOpt);
+}
+
+NSS_IMPLEMENT NSSCryptoContext *
NSSTrustDomain_CreateCryptoContext
(
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;
+ return nssTrustDomain_CreateCryptoContext(td, uhhOpt);
}
NSS_IMPLEMENT NSSCryptoContext *