summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorian.mcgreer%sun.com <devnull@localhost>2002-04-18 17:30:05 +0000
committerian.mcgreer%sun.com <devnull@localhost>2002-04-18 17:30:05 +0000
commite32e0c4d5cb51c5d0bab4d576d5204b15bf4a0ad (patch)
treef2a89821e8a62c949cadbcf3feeeec7cdf36624e
parentc8f6e9bea58634c1eca5e72b021c0f11fd8fe36b (diff)
downloadnss-hg-e32e0c4d5cb51c5d0bab4d576d5204b15bf4a0ad.tar.gz
landing new smart card cache, bug 135429
-rw-r--r--security/nss/lib/dev/ckhelper.c95
-rw-r--r--security/nss/lib/dev/ckhelper.h9
-rw-r--r--security/nss/lib/dev/dev.h56
-rw-r--r--security/nss/lib/dev/devm.h72
-rw-r--r--security/nss/lib/dev/devslot.c12
-rw-r--r--security/nss/lib/dev/devt.h7
-rw-r--r--security/nss/lib/dev/devtm.h2
-rw-r--r--security/nss/lib/dev/devtoken.c139
-rw-r--r--security/nss/lib/dev/devutil.c769
-rw-r--r--security/nss/lib/dev/manifest.mn1
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.c48
-rw-r--r--security/nss/lib/pk11wrap/dev3hack.h6
-rw-r--r--security/nss/lib/pk11wrap/pk11cert.c552
-rw-r--r--security/nss/lib/pk11wrap/pk11slot.c9
-rw-r--r--security/nss/lib/pki/certificate.c75
-rw-r--r--security/nss/lib/pki/pki3hack.c251
-rw-r--r--security/nss/lib/pki/pki3hack.h23
-rw-r--r--security/nss/lib/pki/pkibase.c128
-rw-r--r--security/nss/lib/pki/pkim.h66
-rw-r--r--security/nss/lib/pki/pkit.h9
-rw-r--r--security/nss/lib/pki/pkitm.h1
-rw-r--r--security/nss/lib/pki/trustdomain.c92
22 files changed, 1686 insertions, 736 deletions
diff --git a/security/nss/lib/dev/ckhelper.c b/security/nss/lib/dev/ckhelper.c
index c07afd649..3e3c41ce3 100644
--- a/security/nss/lib/dev/ckhelper.c
+++ b/security/nss/lib/dev/ckhelper.c
@@ -357,14 +357,10 @@ 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 :
@@ -577,15 +573,11 @@ 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);
@@ -607,16 +599,15 @@ nssCryptokiTrust_GetAttributes
return PR_SUCCESS;
}
-#ifdef PURE_STAN_BUILD
NSS_IMPLEMENT PRStatus
nssCryptokiCRL_GetAttributes
(
nssCryptokiObject *crlObject,
nssSession *sessionOpt,
NSSArena *arenaOpt,
- NSSItem *crl,
- NSSItem *krl,
- NSSItem *url
+ NSSItem *encodingOpt,
+ NSSUTF8 **urlOpt,
+ PRBool *isKRLOpt
)
{
PRStatus status;
@@ -626,12 +617,19 @@ nssCryptokiCRL_GetAttributes
CK_ATTRIBUTE_PTR attr;
CK_ATTRIBUTE crl_template[5];
CK_ULONG crl_size;
+ PRUint32 i;
NSS_CK_TEMPLATE_START(crl_template, attr, crl_size);
NSS_CK_SET_ATTRIBUTE_VAR(attr, CKA_TOKEN, isToken);
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
- NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_URL);
+ if (encodingOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_VALUE);
+ }
+ if (urlOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_URL);
+ }
+ if (isKRLOpt) {
+ NSS_CK_SET_ATTRIBUTE_NULL(attr, CKA_NETSCAPE_KRL);
+ }
NSS_CK_TEMPLATE_FINISH(crl_template, attr, crl_size);
status = nssToken_GetCachedObjectAttributes(crlObject->token, NULL,
@@ -653,10 +651,69 @@ nssCryptokiCRL_GetAttributes
}
}
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[0], crl);
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[1], krl);
- NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[2], url);
+ i=0;
+ if (encodingOpt) {
+ NSS_CK_ATTRIBUTE_TO_ITEM(&crl_template[i], encodingOpt); i++;
+ }
+ if (urlOpt) {
+ NSS_CK_ATTRIBUTE_TO_UTF8(&crl_template[i], *urlOpt); i++;
+ }
+ if (isKRLOpt) {
+ NSS_CK_ATTRIBUTE_TO_BOOL(&crl_template[i], *isKRLOpt); i++;
+ }
return PR_SUCCESS;
}
-#endif /* PURE_STAN_BUILD */
+
+NSS_IMPLEMENT PRStatus
+nssCryptokiPrivateKey_SetCertificate
+(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ NSSUTF8 *nickname,
+ NSSItem *id,
+ NSSDER *subject
+)
+{
+ CK_RV ckrv;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE key_template[3];
+ CK_ULONG key_size;
+ void *epv = nssToken_GetCryptokiEPV(keyObject->token);
+ nssSession *session;
+ NSSToken *token = keyObject->token;
+ nssSession *defaultSession = nssToken_GetDefaultSession(token);
+ PRBool createdSession = PR_FALSE;
+
+ NSS_CK_TEMPLATE_START(key_template, attr, key_size);
+ NSS_CK_SET_ATTRIBUTE_UTF8(attr, CKA_LABEL, nickname);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_ID, id);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_TEMPLATE_FINISH(key_template, attr, key_size);
+
+ if (sessionOpt) {
+ if (!nssSession_IsReadWrite(sessionOpt)) {
+ return PR_FAILURE;
+ } else {
+ session = sessionOpt;
+ }
+ } else if (nssSession_IsReadWrite(defaultSession)) {
+ session = defaultSession;
+ } else {
+ NSSSlot *slot = nssToken_GetSlot(token);
+ session = nssSlot_CreateSession(token->slot, NULL, PR_TRUE);
+ createdSession = PR_TRUE;
+ nssSlot_Destroy(slot);
+ }
+
+ ckrv = CKAPI(epv)->C_SetAttributeValue(session->handle,
+ keyObject->handle,
+ key_template,
+ key_size);
+
+ if (createdSession) {
+ nssSession_Destroy(session);
+ }
+
+ return (ckrv == CKR_OK) ? PR_SUCCESS : PR_FAILURE;
+}
diff --git a/security/nss/lib/dev/ckhelper.h b/security/nss/lib/dev/ckhelper.h
index fc64ea9b7..9beab920d 100644
--- a/security/nss/lib/dev/ckhelper.h
+++ b/security/nss/lib/dev/ckhelper.h
@@ -109,6 +109,15 @@ NSS_EXTERN_DATA const NSSItem g_ck_class_privkey;
(item)->size = 0; \
}
+#define NSS_CK_ATTRIBUTE_TO_BOOL(attrib, boolvar) \
+ if ((attrib)->ulValueLen > 0) { \
+ if (*((CK_BBOOL*)(attrib)->pValue) == CK_TRUE) { \
+ boolvar = PR_TRUE; \
+ } else { \
+ boolvar = PR_FALSE; \
+ } \
+ }
+
/* NSS_CK_ATTRIBUTE_TO_UTF8(attrib, str)
*
* Convert a CK_ATTRIBUTE to a string.
diff --git a/security/nss/lib/dev/dev.h b/security/nss/lib/dev/dev.h
index 2e7bc4cdd..612c0c018 100644
--- a/security/nss/lib/dev/dev.h
+++ b/security/nss/lib/dev/dev.h
@@ -377,6 +377,7 @@ nssSlot_CreateSession
* nssToken_FindTrustObjects
* nssToken_FindTrustForCertificate
* nssToken_FindCRLs
+ * nssToken_FindCRLsBySubject
* nssToken_FindPrivateKeys
* nssToken_FindPrivateKeyByID
* nssToken_Digest
@@ -577,6 +578,17 @@ nssToken_FindCRLs
);
NSS_EXTERN nssCryptokiObject **
+nssToken_FindCRLsBySubject
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+);
+
+NSS_EXTERN nssCryptokiObject **
nssToken_FindPrivateKeys
(
NSSToken *token,
@@ -740,9 +752,23 @@ nssCryptokiCRL_GetAttributes
nssCryptokiObject *crlObject,
nssSession *sessionOpt,
NSSArena *arenaOpt,
- NSSItem *crl,
- NSSItem *krl,
- NSSItem *url
+ NSSItem *encodingOpt,
+ NSSUTF8 **urlOpt,
+ PRBool *isKRLOpt
+);
+
+/* I'm including this to handle import of certificates in NSS 3.5. This
+ * function will set the cert-related attributes of a key, in order to
+ * associate it with a cert. Does it stay like this for 4.0?
+ */
+NSS_EXTERN PRStatus
+nssCryptokiPrivateKey_SetCertificate
+(
+ nssCryptokiObject *keyObject,
+ nssSession *sessionOpt,
+ NSSUTF8 *nickname,
+ NSSItem *id,
+ NSSDER *subject
);
NSS_EXTERN void
@@ -915,30 +941,6 @@ nssToken_GetDefaultSession
);
NSS_EXTERN PRStatus
-nssToken_SetTrustCache
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRStatus
-nssToken_SetCrlCache
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRBool
-nssToken_HasCrls
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRStatus
-nssToken_SetHasCrls
-(
- NSSToken *tok
-);
-
-NSS_EXTERN PRStatus
nssToken_GetTrustOrder
(
NSSToken *tok
diff --git a/security/nss/lib/dev/devm.h b/security/nss/lib/dev/devm.h
index 9b2bf6c8c..9e62df1a1 100644
--- a/security/nss/lib/dev/devm.h
+++ b/security/nss/lib/dev/devm.h
@@ -142,6 +142,78 @@ nssCryptokiObject_Create
CK_OBJECT_HANDLE h
);
+NSS_EXTERN nssTokenObjectCache *
+nssTokenObjectCache_Create
+(
+ NSSToken *token,
+ PRBool cacheCerts,
+ PRBool cacheTrust,
+ PRBool cacheCRLs
+);
+
+NSS_EXTERN void
+nssTokenObjectCache_Destroy
+(
+ nssTokenObjectCache *cache
+);
+
+NSS_EXTERN PRBool
+nssTokenObjectCache_HaveObjectClass
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass
+);
+
+NSS_EXTERN nssCryptokiObject **
+nssTokenObjectCache_FindObjectsByTemplate
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR otemplate,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt
+);
+
+NSS_EXTERN PRStatus
+nssTokenObjectCache_GetObjectAttributes
+(
+ nssTokenObjectCache *cache,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
+);
+
+NSS_EXTERN PRStatus
+nssTokenObjectCache_ImportObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen
+);
+
+NSS_EXTERN PRStatus
+nssTokenObjectCache_RemoveObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object
+);
+
+/* XXX allows peek back into token */
+NSS_EXTERN PRStatus
+nssToken_GetCachedObjectAttributes
+(
+ NSSToken *token,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
+);
+
/* PKCS#11 stores strings in a fixed-length buffer padded with spaces. This
* function gets the length of the actual string.
*/
diff --git a/security/nss/lib/dev/devslot.c b/security/nss/lib/dev/devslot.c
index 9ee9e4e1f..6950256ad 100644
--- a/security/nss/lib/dev/devslot.c
+++ b/security/nss/lib/dev/devslot.c
@@ -177,11 +177,13 @@ nssSlot_Destroy
)
{
#ifdef PURE_STAN_BUILD
- PR_AtomicDecrement(&slot->base.refCount);
- if (slot->base.refCount == 0) {
- nssToken_Destroy(slot->token);
- nssModule_DestroyFromSlot(slot->module, slot);
- return nssArena_Destroy(slot->base.arena);
+ if (slot) {
+ PR_AtomicDecrement(&slot->base.refCount);
+ if (slot->base.refCount == 0) {
+ nssToken_Destroy(slot->token);
+ nssModule_DestroyFromSlot(slot->module, slot);
+ return nssArena_Destroy(slot->base.arena);
+ }
}
#endif
return PR_SUCCESS;
diff --git a/security/nss/lib/dev/devt.h b/security/nss/lib/dev/devt.h
index 4d7b2feaf..10a7978c3 100644
--- a/security/nss/lib/dev/devt.h
+++ b/security/nss/lib/dev/devt.h
@@ -82,6 +82,8 @@ struct nssDeviceBaseStr
PRUint32 flags;
};
+typedef struct nssTokenObjectCacheStr nssTokenObjectCache;
+
/* XXX until devobject.c goes away */
struct NSSTokenStr
{
@@ -93,12 +95,9 @@ struct NSSTokenStr
nssSession *defaultSession;
NSSTrustDomain *trustDomain;
PRIntervalTime lastTime;
- PRBool hasNoTrust;
- PRBool hasNoCrls;
+ nssTokenObjectCache *cache;
#ifdef NSS_3_4_CODE
PK11SlotInfo *pk11slot;
- nssList *certList; /* local cache of certs for slow tokens */
- PRBool loggedIn;
#endif
};
diff --git a/security/nss/lib/dev/devtm.h b/security/nss/lib/dev/devtm.h
index c2f5df580..5e48c5d80 100644
--- a/security/nss/lib/dev/devtm.h
+++ b/security/nss/lib/dev/devtm.h
@@ -53,8 +53,6 @@ PR_BEGIN_EXTERN_C
#define MAX_LOCAL_CACHE_OBJECTS 10
-typedef struct nssTokenObjectCacheStr nssTokenObjectCache;
-
PR_END_EXTERN_C
#endif /* DEVTM_H */
diff --git a/security/nss/lib/dev/devtoken.c b/security/nss/lib/dev/devtoken.c
index 52c3b9c4c..44a577f45 100644
--- a/security/nss/lib/dev/devtoken.c
+++ b/security/nss/lib/dev/devtoken.c
@@ -150,13 +150,13 @@ nssToken_Destroy
NSSToken *tok
)
{
-#ifdef PURE_STAN_BUILD
- PR_AtomicDecrement(&tok->base.refCount);
- if (tok->base.refCount == 0) {
- nssTokenObjectCache_Destroy(tok->cache);
- return nssArena_Destroy(tok->base.arena);
+ if (tok) {
+ PR_AtomicDecrement(&tok->base.refCount);
+ if (tok->base.refCount == 0) {
+ nssTokenObjectCache_Destroy(tok->cache);
+ return nssArena_Destroy(tok->base.arena);
+ }
}
-#endif
return PR_SUCCESS;
}
@@ -268,11 +268,9 @@ 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;
@@ -476,7 +474,6 @@ 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;
@@ -495,7 +492,6 @@ 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,
@@ -547,13 +543,11 @@ 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;
}
@@ -1022,13 +1016,11 @@ 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);
}
-#endif
return object;
}
@@ -1162,13 +1154,11 @@ 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;
}
@@ -1211,7 +1201,41 @@ nssToken_FindCRLs
return objects;
}
-#ifdef PURE_STAN_BUILD
+NSS_IMPLEMENT nssCryptokiObject **
+nssToken_FindCRLsBySubject
+(
+ NSSToken *token,
+ nssSession *sessionOpt,
+ NSSDER *subject,
+ nssTokenSearchType searchType,
+ PRUint32 maximumOpt,
+ PRStatus *statusOpt
+)
+{
+ CK_OBJECT_CLASS crlobjc = CKO_NETSCAPE_CRL;
+ CK_ATTRIBUTE_PTR attr;
+ CK_ATTRIBUTE crlobj_template[3];
+ CK_ULONG crlobj_size;
+ nssCryptokiObject **objects;
+ nssSession *session = sessionOpt ? sessionOpt : token->defaultSession;
+
+ NSS_CK_TEMPLATE_START(crlobj_template, attr, crlobj_size);
+ if (searchType == nssTokenSearchType_SessionOnly) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_false);
+ } else if (searchType == nssTokenSearchType_TokenOnly ||
+ searchType == nssTokenSearchType_TokenForced) {
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_TOKEN, &g_ck_true);
+ }
+ NSS_CK_SET_ATTRIBUTE_VAR( attr, CKA_CLASS, crlobjc);
+ NSS_CK_SET_ATTRIBUTE_ITEM(attr, CKA_SUBJECT, subject);
+ NSS_CK_TEMPLATE_FINISH(crlobj_template, attr, crlobj_size);
+
+ objects = find_objects_by_template(token, session,
+ crlobj_template, crlobj_size,
+ maximumOpt, statusOpt);
+ return objects;
+}
+
NSS_IMPLEMENT PRStatus
nssToken_GetCachedObjectAttributes
(
@@ -1230,7 +1254,6 @@ nssToken_GetCachedObjectAttributes
object, objclass,
atemplate, atlen);
}
-#endif
NSS_IMPLEMENT NSSItem *
nssToken_Digest
@@ -1391,85 +1414,6 @@ 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
(
@@ -1478,5 +1422,4 @@ nssToken_IsPresent
{
return nssSlot_IsTokenPresent(token->slot);
}
-#endif
diff --git a/security/nss/lib/dev/devutil.c b/security/nss/lib/dev/devutil.c
index fb97287e3..45ea9883d 100644
--- a/security/nss/lib/dev/devutil.c
+++ b/security/nss/lib/dev/devutil.c
@@ -539,9 +539,776 @@ nssSlotList_FindTokenByName
PZ_Unlock(slotList->lock);
return rvToken;
}
-
#endif /* PURE_STAN_BUILD */
+/* object cache for token */
+
+typedef struct
+{
+ NSSArena *arena;
+ nssCryptokiObject *object;
+ CK_ATTRIBUTE_PTR attributes;
+ CK_ULONG numAttributes;
+}
+nssCryptokiObjectAndAttributes;
+
+enum {
+ cachedCerts = 0,
+ cachedTrust = 1,
+ cachedCRLs = 2
+} cachedObjectType;
+
+struct nssTokenObjectCacheStr
+{
+ NSSToken *token;
+ PZLock *lock;
+ PRBool loggedIn;
+ PRBool doObjectType[3];
+ PRBool searchedObjectType[3];
+ nssCryptokiObjectAndAttributes **objects[3];
+};
+
+NSS_IMPLEMENT nssTokenObjectCache *
+nssTokenObjectCache_Create
+(
+ NSSToken *token,
+ PRBool cacheCerts,
+ PRBool cacheTrust,
+ PRBool cacheCRLs
+)
+{
+ nssTokenObjectCache *rvCache;
+ rvCache = nss_ZNEW(NULL, nssTokenObjectCache);
+ if (!rvCache) {
+ goto loser;
+ }
+ rvCache->lock = PZ_NewLock(nssILockOther); /* XXX */
+ if (!rvCache->lock) {
+ goto loser;
+ }
+ rvCache->doObjectType[cachedCerts] = cacheCerts;
+ rvCache->doObjectType[cachedTrust] = cacheTrust;
+ rvCache->doObjectType[cachedCRLs] = cacheCRLs;
+ rvCache->token = token; /* cache goes away with token */
+ return rvCache;
+loser:
+ return (nssTokenObjectCache *)NULL;
+}
+
+static void
+clear_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ nssCryptokiObjectAndAttributes **oa;
+ PRUint32 objectType;
+ for (objectType = cachedCerts; objectType <= cachedCRLs; objectType++) {
+ if (!cache->objects[objectType]) {
+ continue;
+ }
+ for (oa = cache->objects[objectType]; *oa; oa++) {
+ /* prevent the token from being destroyed */
+ (*oa)->object->token = NULL;
+ nssCryptokiObject_Destroy((*oa)->object);
+ nssArena_Destroy((*oa)->arena);
+ }
+ nss_ZFreeIf(cache->objects[objectType]);
+ cache->objects[objectType] = NULL;
+ cache->searchedObjectType[objectType] = PR_FALSE;
+ }
+}
+
+NSS_IMPLEMENT void
+nssTokenObjectCache_Destroy
+(
+ nssTokenObjectCache *cache
+)
+{
+ if (cache) {
+ clear_cache(cache);
+ PZ_DestroyLock(cache->lock);
+ nss_ZFreeIf(cache);
+ }
+}
+
+NSS_IMPLEMENT PRBool
+nssTokenObjectCache_HaveObjectClass
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass
+)
+{
+ PRBool haveIt;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE: haveIt = cache->doObjectType[cachedCerts]; break;
+ case CKO_NETSCAPE_TRUST: haveIt = cache->doObjectType[cachedTrust]; break;
+ case CKO_NETSCAPE_CRL: haveIt = cache->doObjectType[cachedCRLs]; break;
+ default: haveIt = PR_FALSE;
+ }
+ PZ_Unlock(cache->lock);
+ return haveIt;
+}
+
+static nssCryptokiObjectAndAttributes **
+get_object_and_attributes
+(
+ nssCryptokiObject **objects,
+ CK_ATTRIBUTE_TYPE *types,
+ PRUint32 numTypes,
+ PRBool *doObjects,
+ PRStatus *status
+)
+{
+ PRUint32 i, j, numObjects = 0;
+ nssCryptokiObject **op = objects;
+ nssCryptokiObjectAndAttributes **rvOandA = NULL;
+ NSSSlot *slot = NULL;
+ nssSession *session = NULL;
+ if (!objects) {
+ return (nssCryptokiObjectAndAttributes **)NULL;
+ }
+ while (*op++) numObjects++;
+ if (numObjects == MAX_LOCAL_CACHE_OBJECTS) {
+ /* Hit the maximum allowed, so don't use a cache (there are
+ * too many objects to make caching worthwhile, presumably, if
+ * the token can handle that many objects, it can handle searching.
+ */
+ *doObjects = PR_FALSE;
+ *status = PR_FAILURE;
+ } else {
+ if (numObjects == 0) {
+ /* The fact that there are no objects is cached, done */
+ return (nssCryptokiObjectAndAttributes **)NULL;
+ }
+ rvOandA = nss_ZNEWARRAY(NULL,
+ nssCryptokiObjectAndAttributes *,
+ numObjects + 1);
+ if (!rvOandA) {
+ goto loser;
+ }
+ slot = nssToken_GetSlot(objects[0]->token);
+ session = nssToken_GetDefaultSession(objects[0]->token);
+ for (i=0; i<numObjects; i++) {
+ NSSArena *arena;
+ arena = nssArena_Create();
+ if (!arena) {
+ goto loser;
+ }
+ rvOandA[i] = nss_ZNEW(arena, nssCryptokiObjectAndAttributes);
+ if (!rvOandA[i]) {
+ goto loser;
+ }
+ rvOandA[i]->arena = arena;
+ /* The cache is tied to the token, and therefore the objects
+ * in it should not hold references to the token.
+ */
+ nssToken_Destroy(objects[i]->token);
+ rvOandA[i]->object = objects[i];
+ rvOandA[i]->attributes = nss_ZNEWARRAY(arena,
+ CK_ATTRIBUTE, numTypes);
+ if (!rvOandA[i]->attributes) {
+ goto loser;
+ }
+ for (j=0; j<numTypes; j++) {
+ rvOandA[i]->attributes[j].type = types[j];
+ }
+ *status = nssCKObject_GetAttributes(objects[i]->handle,
+ rvOandA[i]->attributes,
+ numTypes,
+ arena,
+ session,
+ slot);
+ if (*status != PR_SUCCESS) {
+ goto loser;
+ }
+ rvOandA[i]->numAttributes = numTypes;
+ }
+ }
+ *status = PR_SUCCESS;
+ if (slot) {
+ nssSlot_Destroy(slot);
+ }
+ return rvOandA;
+loser:
+ *status = PR_FAILURE;
+ if (slot) {
+ nssSlot_Destroy(slot);
+ }
+ if (rvOandA) {
+ for (i=0; i<numObjects; i++) {
+ if (rvOandA[i]) {
+ nssArena_Destroy(rvOandA[i]->arena);
+ }
+ }
+ }
+ return (nssCryptokiObjectAndAttributes **)NULL;
+}
+
+/*
+ *
+ * State diagram for cache:
+ *
+ * token !present token removed
+ * +-------------------------+<----------------------+
+ * | ^ |
+ * v | |
+ * +----------+ slot friendly | token present +----------+
+ * | cache | -----------------> % ---------------> | cache |
+ * | unloaded | | loaded |
+ * +----------+ +----------+
+ * ^ | ^ |
+ * | | slot !friendly slot logged in | |
+ * | +-----------------------> % ----------------------+ |
+ * | | |
+ * | slot logged out v slot !friendly |
+ * +-----------------------------+<--------------------------+
+ *
+ */
+static PRBool
+search_for_objects
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRBool doSearch = PR_FALSE;
+ NSSSlot *slot = nssToken_GetSlot(cache->token);
+ if (!nssSlot_IsTokenPresent(slot)) {
+ /* The token is no longer present, destroy any cached objects */
+ clear_cache(cache);
+ nssSlot_Destroy(slot);
+ return PR_FALSE;
+ }
+ /* Handle non-friendly slots (slots which require login for objects) */
+ if (!nssSlot_IsFriendly(slot)) {
+ if (nssSlot_IsLoggedIn(slot)) {
+ /* Either no state change, or went from !logged in -> logged in */
+ cache->loggedIn = PR_TRUE;
+ doSearch = PR_TRUE;
+ } else {
+ if (cache->loggedIn) {
+ /* went from logged in -> !logged in, destroy cached objects */
+ clear_cache(cache);
+ cache->loggedIn = PR_FALSE;
+ } /* else no state change, still not logged in, so exit */
+ }
+ } else {
+ /* slot is friendly, thus always available for search */
+ doSearch = PR_TRUE;
+ }
+ nssSlot_Destroy(slot);
+ return doSearch;
+}
+
+static PRStatus
+get_token_certs_for_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRStatus status;
+ nssCryptokiObject **objects;
+ CK_ATTRIBUTE_TYPE certAttr[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_LABEL,
+ CKA_CERTIFICATE_TYPE,
+ CKA_ID,
+ CKA_VALUE,
+ CKA_ISSUER,
+ CKA_SERIAL_NUMBER,
+ CKA_SUBJECT,
+ CKA_NETSCAPE_EMAIL
+ };
+ PRUint32 numCertAttr = sizeof(certAttr) / sizeof(certAttr[0]);
+ if (!search_for_objects(cache) ||
+ cache->searchedObjectType[cachedCerts] ||
+ !cache->doObjectType[cachedCerts])
+ {
+ /* Either there was a state change that prevents a search
+ * (token removed or logged out), or the search was already done,
+ * or certs are not being cached.
+ */
+ return PR_SUCCESS;
+ }
+ objects = nssToken_FindCertificates(cache->token, NULL,
+ nssTokenSearchType_TokenForced,
+ MAX_LOCAL_CACHE_OBJECTS, &status);
+ if (status == PR_SUCCESS) {
+ PRBool *doIt = &cache->doObjectType[cachedCerts];
+ cache->objects[cachedCerts] = get_object_and_attributes(objects,
+ certAttr,
+ numCertAttr,
+ doIt,
+ &status);
+ if (status == PR_SUCCESS) {
+ nss_ZFreeIf(objects);
+ } else {
+ nssCryptokiObjectArray_Destroy(objects);
+ }
+ } else {
+ return status;
+ }
+ cache->searchedObjectType[cachedCerts] = PR_TRUE;
+ return PR_SUCCESS;
+}
+
+static PRStatus
+get_token_trust_for_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRStatus status;
+ nssCryptokiObject **objects;
+ CK_ATTRIBUTE_TYPE trustAttr[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_LABEL,
+ CKA_CERT_SHA1_HASH,
+ CKA_CERT_MD5_HASH,
+ CKA_ISSUER,
+ CKA_SUBJECT,
+ CKA_TRUST_SERVER_AUTH,
+ CKA_TRUST_CLIENT_AUTH,
+ CKA_TRUST_EMAIL_PROTECTION,
+ CKA_TRUST_CODE_SIGNING
+ };
+ PRUint32 numTrustAttr = sizeof(trustAttr) / sizeof(trustAttr[0]);
+ if (!search_for_objects(cache) ||
+ cache->searchedObjectType[cachedTrust] ||
+ !cache->doObjectType[cachedTrust])
+ {
+ /* Either there was a state change that prevents a search
+ * (token removed or logged out), or the search was already done,
+ * or trust is not being cached.
+ */
+ return PR_SUCCESS;
+ }
+ objects = nssToken_FindTrustObjects(cache->token, NULL,
+ nssTokenSearchType_TokenForced,
+ MAX_LOCAL_CACHE_OBJECTS, &status);
+ if (status == PR_SUCCESS) {
+ PRBool *doIt = &cache->doObjectType[cachedTrust];
+ cache->objects[cachedTrust] = get_object_and_attributes(objects,
+ trustAttr,
+ numTrustAttr,
+ doIt,
+ &status);
+ if (status == PR_SUCCESS) {
+ nss_ZFreeIf(objects);
+ } else {
+ nssCryptokiObjectArray_Destroy(objects);
+ }
+ } else {
+ return status;
+ }
+ cache->searchedObjectType[cachedTrust] = PR_TRUE;
+ return PR_SUCCESS;
+}
+
+static PRStatus
+get_token_crls_for_cache
+(
+ nssTokenObjectCache *cache
+)
+{
+ PRStatus status;
+ nssCryptokiObject **objects;
+ CK_ATTRIBUTE_TYPE crlAttr[] = {
+ CKA_CLASS,
+ CKA_TOKEN,
+ CKA_LABEL,
+ CKA_VALUE,
+ CKA_SUBJECT,
+ CKA_NETSCAPE_KRL,
+ CKA_NETSCAPE_URL
+ };
+ PRUint32 numCRLAttr = sizeof(crlAttr) / sizeof(crlAttr[0]);
+ if (!search_for_objects(cache) ||
+ cache->searchedObjectType[cachedCRLs] ||
+ !cache->doObjectType[cachedCRLs])
+ {
+ /* Either there was a state change that prevents a search
+ * (token removed or logged out), or the search was already done,
+ * or CRLs are not being cached.
+ */
+ return PR_SUCCESS;
+ }
+ objects = nssToken_FindCRLs(cache->token, NULL,
+ nssTokenSearchType_TokenForced,
+ MAX_LOCAL_CACHE_OBJECTS, &status);
+ if (status == PR_SUCCESS) {
+ PRBool *doIt = &cache->doObjectType[cachedCRLs];
+ cache->objects[cachedCRLs] = get_object_and_attributes(objects,
+ crlAttr,
+ numCRLAttr,
+ doIt,
+ &status);
+ if (status == PR_SUCCESS) {
+ nss_ZFreeIf(objects);
+ } else {
+ nssCryptokiObjectArray_Destroy(objects);
+ }
+ } else {
+ return status;
+ }
+ cache->searchedObjectType[cachedCRLs] = PR_TRUE;
+ return PR_SUCCESS;
+}
+
+static nssCryptokiObject **
+find_objects_in_array
+(
+ nssCryptokiObjectAndAttributes **objArray,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt
+)
+{
+ PRIntn oi;
+ PRUint32 i, j;
+ PRBool match;
+ NSSArena *arena;
+ PRUint32 size = 8;
+ PRUint32 numMatches = 0;
+ nssCryptokiObject **objects = NULL;
+ nssCryptokiObjectAndAttributes **matches = NULL;
+ if (!objArray) {
+ return (nssCryptokiObject **)NULL;
+ }
+ arena = nssArena_Create();
+ if (!arena) {
+ return (nssCryptokiObject **)NULL;
+ }
+ matches = nss_ZNEWARRAY(arena, nssCryptokiObjectAndAttributes *, size);
+ if (!matches) {
+ goto loser;
+ }
+ if (maximumOpt == 0) maximumOpt = ~0;
+ for (; *objArray && numMatches < maximumOpt; objArray++) {
+ nssCryptokiObjectAndAttributes *obj = *objArray;
+ for (i=0; i<otlen; i++) {
+ for (j=0; j<obj->numAttributes; j++) {
+ if (ot[i].type == obj->attributes[j].type) {
+ if (ot[i].ulValueLen == obj->attributes[j].ulValueLen &&
+ nsslibc_memequal(ot[i].pValue,
+ obj->attributes[j].pValue,
+ ot[i].ulValueLen, NULL))
+ {
+ match = PR_TRUE;
+ } else {
+ match = PR_FALSE;
+ }
+ break;
+ }
+ }
+ if (j == obj->numAttributes || !match) {
+ break;
+ }
+ }
+ if (match) {
+ matches[numMatches++] = obj;
+ if (numMatches == size) {
+ size *= 2;
+ matches = nss_ZREALLOCARRAY(matches,
+ nssCryptokiObjectAndAttributes *,
+ size);
+ if (!matches) {
+ goto loser;
+ }
+ }
+ }
+ }
+ if (numMatches > 0) {
+ objects = nss_ZNEWARRAY(NULL, nssCryptokiObject *, numMatches + 1);
+ if (!objects) {
+ goto loser;
+ }
+ for (oi=0; oi<(PRIntn)numMatches; oi++) {
+ objects[oi] = nssCryptokiObject_Clone(matches[oi]->object);
+ if (!objects[oi]) {
+ goto loser;
+ }
+ }
+ }
+ nssArena_Destroy(arena);
+ return objects;
+loser:
+ if (objects) {
+ for (--oi; oi>=0; --oi) {
+ nssCryptokiObject_Destroy(objects[oi]);
+ }
+ }
+ nssArena_Destroy(arena);
+ return (nssCryptokiObject **)NULL;
+}
+
+NSS_IMPLEMENT nssCryptokiObject **
+nssTokenObjectCache_FindObjectsByTemplate
+(
+ nssTokenObjectCache *cache,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR otemplate,
+ CK_ULONG otlen,
+ PRUint32 maximumOpt
+)
+{
+ PRStatus status = PR_FAILURE;
+ nssCryptokiObject **rvObjects = NULL;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE:
+ if (cache->doObjectType[cachedCerts]) {
+ status = get_token_certs_for_cache(cache);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvObjects = find_objects_in_array(cache->objects[cachedCerts],
+ otemplate, otlen, maximumOpt);
+ }
+ break;
+ case CKO_NETSCAPE_TRUST:
+ if (cache->doObjectType[cachedTrust]) {
+ status = get_token_trust_for_cache(cache);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvObjects = find_objects_in_array(cache->objects[cachedTrust],
+ otemplate, otlen, maximumOpt);
+ }
+ break;
+ case CKO_NETSCAPE_CRL:
+ if (cache->doObjectType[cachedCRLs]) {
+ status = get_token_crls_for_cache(cache);
+ if (status != PR_SUCCESS) {
+ goto finish;
+ }
+ rvObjects = find_objects_in_array(cache->objects[cachedCRLs],
+ otemplate, otlen, maximumOpt);
+ }
+ break;
+ default: break;
+ }
+finish:
+ PZ_Unlock(cache->lock);
+ return rvObjects;
+}
+
+NSS_IMPLEMENT PRStatus
+nssTokenObjectCache_GetObjectAttributes
+(
+ nssTokenObjectCache *cache,
+ NSSArena *arenaOpt,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR atemplate,
+ CK_ULONG atlen
+)
+{
+ PRUint32 i, j;
+ NSSArena *arena = NULL;
+ nssArenaMark *mark = NULL;
+ nssCryptokiObjectAndAttributes *cachedOA = NULL;
+ nssCryptokiObjectAndAttributes **oa = NULL;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE: oa = cache->objects[cachedCerts]; break;
+ case CKO_NETSCAPE_TRUST: oa = cache->objects[cachedTrust]; break;
+ case CKO_NETSCAPE_CRL: oa = cache->objects[cachedCRLs]; break;
+ default: goto loser;
+ }
+ if (!oa) {
+ goto loser;
+ }
+ for (; *oa; oa++) {
+ if (nssCryptokiObject_Equal((*oa)->object, object)) {
+ cachedOA = *oa;
+ break;
+ }
+ }
+ if (!cachedOA) {
+ goto loser; /* don't have this object */
+ }
+ if (arenaOpt) {
+ arena = arenaOpt;
+ mark = nssArena_Mark(arena);
+ }
+ for (i=0; i<atlen; i++) {
+ for (j=0; j<cachedOA->numAttributes; j++) {
+ if (atemplate[i].type == cachedOA->attributes[j].type) {
+ CK_ATTRIBUTE_PTR attr = &cachedOA->attributes[j];
+ if (cachedOA->attributes[j].ulValueLen == 0 ||
+ cachedOA->attributes[j].ulValueLen == (CK_ULONG)-1)
+ {
+ break; /* invalid attribute */
+ }
+ if (atemplate[i].ulValueLen > 0) {
+ if (atemplate[i].pValue == NULL ||
+ atemplate[i].ulValueLen < attr->ulValueLen)
+ {
+ goto loser;
+ }
+ } else {
+ atemplate[i].pValue = nss_ZAlloc(arena, attr->ulValueLen);
+ if (!atemplate[i].pValue) {
+ goto loser;
+ }
+ }
+ nsslibc_memcpy(atemplate[i].pValue,
+ attr->pValue, attr->ulValueLen);
+ atemplate[i].ulValueLen = attr->ulValueLen;
+ break;
+ }
+ }
+ if (j == cachedOA->numAttributes) {
+ atemplate[i].ulValueLen = (CK_ULONG)-1;
+ }
+ }
+ PZ_Unlock(cache->lock);
+ if (mark) {
+ nssArena_Unmark(arena, mark);
+ }
+ return PR_SUCCESS;
+loser:
+ PZ_Unlock(cache->lock);
+ if (mark) {
+ nssArena_Release(arena, mark);
+ }
+ return PR_FAILURE;
+}
+
+static nssCryptokiObjectAndAttributes *
+make_object_and_attr
+(
+ nssCryptokiObject *object,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen
+)
+{
+ PRUint32 i;
+ NSSArena *arena;
+ nssCryptokiObjectAndAttributes *oa;
+ arena = nssArena_Create();
+ if (!arena) {
+ return (nssCryptokiObjectAndAttributes *)NULL;
+ }
+ oa = nss_ZNEW(arena, nssCryptokiObjectAndAttributes);
+ if (!oa) {
+ goto loser;
+ }
+ oa->object = object;
+ oa->arena = arena;
+ nssToken_Destroy(object->token);
+ oa->attributes = nss_ZNEWARRAY(arena, CK_ATTRIBUTE, otlen);
+ if (!oa->attributes) {
+ goto loser;
+ }
+ for (i=0; i<otlen; i++) {
+ oa->attributes[i].pValue = nss_ZAlloc(arena, ot[i].ulValueLen);
+ if (!oa->attributes[i].pValue) {
+ goto loser;
+ }
+ nsslibc_memcpy(oa->attributes[i].pValue, ot[i].pValue,
+ ot[i].ulValueLen);
+ oa->attributes[i].ulValueLen = ot[i].ulValueLen;
+ }
+ oa->numAttributes = otlen;
+ return oa;
+loser:
+ nssArena_Destroy(arena);
+ return (nssCryptokiObjectAndAttributes *)NULL;
+}
+
+NSS_IMPLEMENT PRStatus
+nssTokenObjectCache_ImportObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object,
+ CK_OBJECT_CLASS objclass,
+ CK_ATTRIBUTE_PTR ot,
+ CK_ULONG otlen
+)
+{
+ PRStatus status = PR_SUCCESS;
+ PRUint32 count;
+ nssCryptokiObjectAndAttributes **oa, ***otype;
+ PRUint32 objectType;
+ PZ_Lock(cache->lock);
+ switch (objclass) {
+ case CKO_CERTIFICATE: objectType = cachedCerts; break;
+ case CKO_NETSCAPE_TRUST: objectType = cachedTrust; break;
+ case CKO_NETSCAPE_CRL: objectType = cachedCRLs; break;
+ default: status = PR_FAILURE;
+ }
+ if (status != PR_SUCCESS || /* failed */
+ !cache->doObjectType[objectType] || /* not caching this kind */
+ !cache->searchedObjectType[objectType]) /* not cached yet anyway */
+ {
+ PZ_Unlock(cache->lock);
+ return status;
+ }
+ count = 0;
+ otype = &cache->objects[objectType]; /* index into array of types */
+ oa = *otype; /* the array of objects for this type */
+ while (oa && *oa++) count++;
+ if (count > 0) {
+ *otype = nss_ZREALLOCARRAY(*otype,
+ nssCryptokiObjectAndAttributes *,
+ count + 2);
+ } else {
+ *otype = nss_ZNEWARRAY(NULL, nssCryptokiObjectAndAttributes *, 2);
+ }
+ if (*otype) {
+ nssCryptokiObject *copyObject = nssCryptokiObject_Clone(object);
+ (*otype)[count] = make_object_and_attr(copyObject, ot, otlen);
+ status = ((*otype)[count] != NULL) ? PR_SUCCESS : PR_FAILURE;
+ } else {
+ status = PR_FAILURE;
+ }
+ PZ_Unlock(cache->lock);
+ return status;
+}
+
+NSS_IMPLEMENT PRStatus
+nssTokenObjectCache_RemoveObject
+(
+ nssTokenObjectCache *cache,
+ nssCryptokiObject *object
+)
+{
+ PRUint32 oType;
+ nssCryptokiObjectAndAttributes **oa, **swp = NULL;
+ PZ_Lock(cache->lock);
+ for (oType=0; oType<3; oType++) {
+ if (!cache->objects[oType]) {
+ continue;
+ }
+ for (oa = cache->objects[oType]; *oa; oa++) {
+ if (nssCryptokiObject_Equal((*oa)->object, object)) {
+ swp = oa; /* the entry to remove */
+ while (oa[1]) oa++; /* go to the tail */
+ (*swp)->object->token = NULL;
+ nssCryptokiObject_Destroy((*swp)->object);
+ nssArena_Destroy((*swp)->arena); /* destroy it */
+ *swp = *oa; /* swap the last with the removed */
+ *oa = NULL; /* null-terminate the array */
+ break;
+ }
+ }
+ if (swp) {
+ break;
+ }
+ }
+ PZ_Unlock(cache->lock);
+ if (swp && *swp == NULL) {
+ nss_ZFreeIf(swp); /* the only entry */
+ cache->objects[oType] = NULL;
+ }
+ return PR_SUCCESS;
+}
+
/* XXX of course this doesn't belong here */
NSS_IMPLEMENT NSSAlgorithmAndParameters *
NSSAlgorithmAndParameters_CreateSHA1Digest
diff --git a/security/nss/lib/dev/manifest.mn b/security/nss/lib/dev/manifest.mn
index df0151ef2..effab4805 100644
--- a/security/nss/lib/dev/manifest.mn
+++ b/security/nss/lib/dev/manifest.mn
@@ -58,6 +58,7 @@ CSRCS = \
# here is where the 3.4 glue code is added
ifndef PURE_STAN_BUILD
DEFINES = -DNSS_3_4_CODE
+PRIVATE_EXPORTS += devm.h devtm.h
endif
REQUIRES = security nspr
diff --git a/security/nss/lib/pk11wrap/dev3hack.c b/security/nss/lib/pk11wrap/dev3hack.c
index 9994cb65b..06b279f95 100644
--- a/security/nss/lib/pk11wrap/dev3hack.c
+++ b/security/nss/lib/pk11wrap/dev3hack.c
@@ -43,9 +43,9 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pkit.h"
#endif /* PKIT_H */
-#ifndef DEVT_H
-#include "devt.h"
-#endif /* DEVT_H */
+#ifndef DEVM_H
+#include "devm.h"
+#endif /* DEVM_H */
#include "pki3hack.h"
#include "dev3hack.h"
@@ -117,11 +117,19 @@ static NSSSlot *
nssSlot_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
NSSSlot *rvSlot;
- rvSlot = nss_ZNEW(td->arena, NSSSlot);
+ NSSArena *arena;
+ arena = nssArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ rvSlot = nss_ZNEW(arena, NSSSlot);
if (!rvSlot) {
+ nssArena_Destroy(arena);
return NULL;
}
rvSlot->base.refCount = 1;
+ rvSlot->base.lock = PZ_NewLock(nssILockOther);
+ rvSlot->base.arena = arena;
rvSlot->pk11slot = nss3slot;
rvSlot->epv = nss3slot->functionList;
rvSlot->slotID = nss3slot->slotID;
@@ -134,24 +142,41 @@ NSS_IMPLEMENT NSSToken *
nssToken_CreateFromPK11SlotInfo(NSSTrustDomain *td, PK11SlotInfo *nss3slot)
{
NSSToken *rvToken;
- rvToken = nss_ZNEW(td->arena, NSSToken);
+ NSSArena *arena;
+ arena = nssArena_Create();
+ if (!arena) {
+ return NULL;
+ }
+ rvToken = nss_ZNEW(arena, NSSToken);
if (!rvToken) {
+ nssArena_Destroy(arena);
return NULL;
}
rvToken->base.refCount = 1;
+ rvToken->base.lock = PZ_NewLock(nssILockOther);
+ rvToken->base.arena = arena;
rvToken->pk11slot = nss3slot;
rvToken->epv = nss3slot->functionList;
rvToken->defaultSession = nssSession_ImportNSS3Session(td->arena,
nss3slot->session,
nss3slot->sessionLock,
nss3slot->defRWSession);
+ /* if (!PK11_IsInternal(nss3slot) && PK11_IsHW(nss3slot)) */
+ /* The above test was used in 3.4, for this cache have it always on */
+ if (PR_TRUE) {
+ rvToken->cache = nssTokenObjectCache_Create(rvToken,
+ PR_TRUE, PR_TRUE, PR_TRUE);
+ if (!rvToken->cache) {
+ nssArena_Destroy(arena);
+ return (NSSToken *)NULL;
+ }
+ }
rvToken->trustDomain = td;
/* Grab the token name from the PKCS#11 fixed-length buffer */
rvToken->base.name = nssUTF8_Duplicate(nss3slot->token_name,td->arena);
rvToken->slot = nssSlot_CreateFromPK11SlotInfo(td, nss3slot);
rvToken->slot->token = rvToken;
rvToken->defaultSession->slot = rvToken->slot;
- rvToken->base.arena = td->arena;
return rvToken;
}
@@ -195,8 +220,7 @@ nssToken_Refresh(NSSToken *token)
nss3slot->session,
nss3slot->sessionLock,
nss3slot->defRWSession);
- nssToken_DestroyCertList(token, PR_TRUE);
- return nssToken_LoadCerts(token);
+ return PR_SUCCESS;
}
NSS_IMPLEMENT PRStatus
@@ -225,6 +249,14 @@ nssToken_GetTrustOrder
return module->trustOrder;
}
+NSS_IMPLEMENT PRBool
+nssSlot_IsLoggedIn
+(
+ NSSSlot *slot
+)
+{
+ return PK11_IsLoggedIn(slot->pk11slot, NULL);
+}
NSSTrustDomain *
diff --git a/security/nss/lib/pk11wrap/dev3hack.h b/security/nss/lib/pk11wrap/dev3hack.h
index 19f9bbb8b..d2e3ab4e1 100644
--- a/security/nss/lib/pk11wrap/dev3hack.h
+++ b/security/nss/lib/pk11wrap/dev3hack.h
@@ -58,12 +58,6 @@ void PK11Slot_SetNSSToken(PK11SlotInfo *sl, NSSToken *nsst);
NSSToken * PK11Slot_GetNSSToken(PK11SlotInfo *sl);
-NSS_EXTERN PRStatus
-nssToken_LoadCerts(NSSToken *token);
-
-NSS_EXTERN void
-nssToken_UpdateTrustForCerts(NSSToken *token);
-
PR_END_EXTERN_C
#endif /* DEVNSS3HACK_H */
diff --git a/security/nss/lib/pk11wrap/pk11cert.c b/security/nss/lib/pk11wrap/pk11cert.c
index c4cdca5c2..629940a96 100644
--- a/security/nss/lib/pk11wrap/pk11cert.c
+++ b/security/nss/lib/pk11wrap/pk11cert.c
@@ -1171,73 +1171,6 @@ PK11_FindObjectsFromNickname(char *nickname,PK11SlotInfo **slotptr,
return objID;
}
-/* match all token certs with a nickname */
-static nssList *
-filter_token_certs_nickname(NSSToken *token, NSSUTF8 *nickname)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- nssList *rvList;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvList = nssList_Create(NULL, PR_FALSE);
- if (!rvList) {
- nssListIterator_Destroy(certs);
- return NULL;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- NSSUTF8 *tokenNick = nssCertificate_GetNickname(cert, token);
- if (!tokenNick) continue;
- if (nssUTF8_Equal(tokenNick, nickname, &nssrv)) {
- nssList_Add(rvList, nssCertificate_AddRef(cert));
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- if (nssList_Count(rvList) == 0) {
- nssList_Destroy(rvList);
- rvList = NULL;
- }
- return rvList;
-}
-
-/* match all token certs with an email address */
-static nssList *
-filter_token_certs_email(NSSToken *token, NSSASCII7 *email)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- nssList *rvList;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvList = nssList_Create(NULL, PR_FALSE);
- if (!rvList) {
- nssListIterator_Destroy(certs);
- return NULL;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- if (!cert->email) continue;
- if (nssUTF8_Equal(cert->email, email, &nssrv)) {
- nssList_Add(rvList, nssCertificate_AddRef(cert));
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- if (nssList_Count(rvList) == 0) {
- nssList_Destroy(rvList);
- rvList = NULL;
- }
- return rvList;
-}
-
static void
transfer_token_certs_to_collection(nssList *certList, NSSToken *token,
nssPKIObjectCollection *collection)
@@ -1329,49 +1262,37 @@ PK11_FindCertFromNickname(char *nickname, void *wincx) {
if (!collection) {
goto loser;
}
- if (!nssToken_SearchCerts(token, NULL)) {
- certList = filter_token_certs_nickname(token, nickname);
- transfer_token_certs_to_collection(certList, token, collection);
- nssList_Destroy(certList);
- } else {
- certList = nssList_Create(NULL, PR_FALSE);
- if (!certList) {
- nssPKIObjectCollection_Destroy(collection);
- goto loser;
- }
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- 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);
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) {
+ nssPKIObjectCollection_Destroy(collection);
+ goto loser;
}
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
+ nickname,
+ 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 (nssPKIObjectCollection_Count(collection) == 0) {
- if (!nssToken_SearchCerts(token, NULL)) {
- certList = filter_token_certs_email(token, nickname);
- transfer_token_certs_to_collection(certList, token, collection);
- nssList_Destroy(certList);
- } else {
- (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
+ (void)nssTrustDomain_GetCertsForEmailAddressFromCache(defaultTD,
nickname,
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);
- }
+ 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);
}
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
@@ -1454,7 +1375,10 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
token = PK11Slot_GetNSSToken(slot);
}
if (token) {
+ PRStatus status;
nssList *nameList;
+ nssCryptokiObject **instances;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
if (!PK11_IsFriendly(slot)) {
if (PK11_Authenticate(slot, PR_TRUE, wincx) != SECSuccess) {
PK11_FreeSlot(slot);
@@ -1466,31 +1390,23 @@ PK11_FindCertsFromNickname(char *nickname, void *wincx) {
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) {
- PK11_FreeSlot(slot);
- return NULL;
- }
- (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
- nickname,
- 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);
+ nameList = nssList_Create(NULL, PR_FALSE);
+ if (!nameList) {
+ PK11_FreeSlot(slot);
+ return NULL;
}
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(defaultTD,
+ nickname,
+ 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);
@@ -1618,6 +1534,7 @@ PK11_MakeIDFromPubKey(SECItem *pubKeyData) {
SECStatus
PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
CK_OBJECT_HANDLE key, char *nickname, PRBool includeTrust) {
+#ifdef NSS_CLASSIC
int len = 0;
SECItem *keyID = pk11_mkcertKeyID(cert);
CK_ATTRIBUTE keyAttrs[] = {
@@ -1748,14 +1665,6 @@ PK11_ImportCert(PK11SlotInfo *slot, CERTCertificate *cert,
}
cert->trust = nssTrust_GetCERTCertTrustForCert(cert->nssCertificate, cert);
token = PK11Slot_GetNSSToken(slot);
- if (token->certList) {
- /* create a persistent reference for the token */
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- nssCertificate_AddRef(cert->nssCertificate);
- nssList_Add(token->certList, cert->nssCertificate);
- /* and add the cert to the cache */
- nssTrustDomain_AddCertsToCache(td, &cert->nssCertificate, 1);
- }
done:
if (derSerial.data) PORT_Free(derSerial.data);
@@ -1765,7 +1674,74 @@ done:
PORT_Free(certUsage);
}
return rv;
+#else
+ PRStatus status;
+ NSSCertificate *c;
+ nssCryptokiObject *keyobj, *certobj;
+ NSSToken *token = PK11Slot_GetNSSToken(slot);
+ SECItem *keyID = pk11_mkcertKeyID(cert);
+
+ if (keyID == NULL) {
+ goto loser;
+ }
+
+ /* need to get the cert as a stan cert */
+ if (cert->nssCertificate) {
+ c = cert->nssCertificate;
+ } else {
+ c = STAN_GetNSSCertificate(cert);
+ }
+ /* set the id for the cert */
+ nssItem_Create(c->object.arena, &c->id, keyID->len, keyID->data);
+ if (!c->id.data) {
+ goto loser;
+ }
+
+ if (key != CK_INVALID_HANDLE) {
+ /* create an object for the key, ... */
+ keyobj = nss_ZNEW(NULL, nssCryptokiObject);
+ if (!keyobj) {
+ goto loser;
+ }
+ keyobj->token = nssToken_AddRef(token);
+ keyobj->handle = key;
+ keyobj->isTokenObject = PR_TRUE;
+
+ /* ... in order to set matching attributes for the key */
+ status = nssCryptokiPrivateKey_SetCertificate(keyobj, NULL, nickname,
+ &c->id, &c->subject);
+ nssCryptokiObject_Destroy(keyobj);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ }
+
+ /* do the token import */
+ certobj = nssToken_ImportCertificate(token, NULL,
+ NSSCertificateType_PKIX,
+ &c->id,
+ nickname,
+ &c->encoding,
+ &c->issuer,
+ &c->subject,
+ &c->serial,
+ PR_TRUE);
+ if (!certobj) {
+ goto loser;
+ }
+ /* add the new instance to the cert, force an update of the
+ * CERTCertificate, and finish
+ */
+ nssPKIObject_AddInstance(&c->object, certobj);
+ (void)STAN_ForceCERTCertificateUpdate(c);
+ SECITEM_FreeItem(keyID,PR_TRUE);
+ return SECSuccess;
+loser:
+ SECITEM_FreeItem(keyID,PR_TRUE);
+ PORT_SetError(SEC_ERROR_ADDING_CERT);
+ return SECFailure;
+#endif
}
/*
@@ -2520,38 +2496,6 @@ PK11_TraverseCertsForSubject(CERTCertificate *cert,
return PK11_TraverseCertsForSubjectInSlot(cert, cert->slot, callback, arg);
}
-/* Find all certs with a given subject in the list of token certs */
-static nssList *
-filter_token_certs_subject(NSSToken *token, NSSDER *subject)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRStatus nssrv;
- nssList *rvList;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvList = nssList_Create(NULL, PR_FALSE);
- if (!rvList) {
- nssListIterator_Destroy(certs);
- return NULL;
- }
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- if (nssItem_Equal(&cert->subject, subject, &nssrv)) {
- nssList_Add(rvList, nssCertificate_AddRef(cert));
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- if (nssList_Count(rvList) == 0) {
- nssList_Destroy(rvList);
- rvList = NULL;
- }
- return rvList;
-}
-
SECStatus
PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
SECStatus(* callback)(CERTCertificate*, void *), void *arg)
@@ -2592,28 +2536,27 @@ PK11_TraverseCertsForSubjectInSlot(CERTCertificate *cert, PK11SlotInfo *slot,
nssPKIObjectCollection *collection;
nssCryptokiObject **instances;
NSSCertificate **certs;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
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);
- 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);
- transfer_token_certs_to_collection(subjectList, token, collection);
- instances = nssToken_FindCertificatesBySubject(token, NULL,
- &subject,
- tokenOnly, 0, &nssrv);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
+ if (!collection) {
+ return SECFailure;
}
+ subjectList = nssList_Create(NULL, PR_FALSE);
+ if (!subjectList) {
+ nssPKIObjectCollection_Destroy(collection);
+ return SECFailure;
+ }
+ (void)nssTrustDomain_GetCertsForSubjectFromCache(td, &subject,
+ 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);
@@ -2678,9 +2621,10 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
NSSUTF8 *nick;
PRBool created = PR_FALSE;
nssCryptokiObject **instances;
- nssPKIObjectCollection *collection;
+ nssPKIObjectCollection *collection = NULL;
NSSCertificate **certs;
- nssList *nameList;
+ nssList *nameList = NULL;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
pk11cb.callback = callback;
pk11cb.arg = arg;
if (nickname->data[nickname->len-1] != '\0') {
@@ -2693,23 +2637,20 @@ 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);
- 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);
- transfer_token_certs_to_collection(nameList, token, collection);
- instances = nssToken_FindCertificatesByNickname(token, NULL,
- nick,
- tokenOnly, 0, &nssrv);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
+ if (!collection) {
+ goto loser;
+ }
+ nameList = nssList_Create(NULL, PR_FALSE);
+ if (!nameList) {
+ goto loser;
}
+ (void)nssTrustDomain_GetCertsForNicknameFromCache(td, nick, nameList);
+ transfer_token_certs_to_collection(nameList, token, collection);
+ instances = nssToken_FindCertificatesByNickname(token, NULL,
+ nick,
+ tokenOnly, 0, &nssrv);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
nssList_Destroy(nameList);
certs = nssPKIObjectCollection_GetCertificates(collection,
NULL, 0, NULL);
@@ -2728,6 +2669,17 @@ PK11_TraverseCertsForNicknameInSlot(SECItem *nickname, PK11SlotInfo *slot,
}
if (created) nss_ZFreeIf(nick);
return (nssrv == PR_SUCCESS) ? SECSuccess : SECFailure;
+loser:
+ if (created) {
+ nss_ZFreeIf(nick);
+ }
+ if (collection) {
+ nssPKIObjectCollection_Destroy(collection);
+ }
+ if (nameList) {
+ nssList_Destroy(nameList);
+ }
+ return SECFailure;
#endif
}
@@ -2768,27 +2720,23 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
nssCryptokiObject **instances;
nssPKIObjectCollection *collection;
NSSCertificate **certs;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
tok = PK11Slot_GetNSSToken(slot);
collection = nssCertificateCollection_Create(td, NULL);
if (!collection) {
return SECFailure;
}
- if (!nssToken_SearchCerts(tok, NULL)) {
- 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);
- transfer_token_certs_to_collection(certList, tok, collection);
- instances = nssToken_FindCertificates(tok, NULL,
- tokenOnly, 0, &nssrv);
- nssPKIObjectCollection_AddInstances(collection, instances, 0);
- nss_ZFreeIf(instances);
+ certList = nssList_Create(NULL, PR_FALSE);
+ if (!certList) {
+ nssPKIObjectCollection_Destroy(collection);
+ return SECFailure;
}
+ (void *)nssTrustDomain_GetCertsFromCache(td, 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);
@@ -2809,29 +2757,6 @@ PK11_TraverseCertsInSlot(PK11SlotInfo *slot,
#endif
}
-static NSSCertificate *
-filter_token_certs_DER(NSSToken *token, NSSDER *der)
-{
- nssListIterator *certs;
- NSSCertificate *cert, *rvCert;
- PRStatus nssrv;
- certs = nssList_CreateIterator(token->certList);
- if (!certs) return NULL;
- rvCert = NULL;
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- if (nssItem_Equal(&cert->encoding, der, &nssrv)) {
- rvCert = nssCertificate_AddRef(cert);
- break;
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
- return rvCert;
-}
-
/*
* return the certificate associated with a derCert
*/
@@ -2882,27 +2807,23 @@ PK11_FindCertFromDERCert(PK11SlotInfo *slot, CERTCertificate *cert,
return NULL;
}
}
- if (!nssToken_SearchCerts(tok, NULL)) {
- c = filter_token_certs_DER(tok, &derCert);
- } else {
- 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;
+ 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;
}
- nssTokenArray_Destroy(tokens);
}
+ if (!isToken) {
+ NSSCertificate_Destroy(c);
+ c = NULL;
+ }
+ nssTokenArray_Destroy(tokens);
}
}
if (c) {
@@ -3602,6 +3523,7 @@ SECItem *
PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
SECItem *name, int type, char **url)
{
+#ifdef NSS_CLASSIC
CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_SUBJECT, NULL, 0 },
@@ -3635,9 +3557,6 @@ PK11_FindCrlByName(PK11SlotInfo **slot, CK_OBJECT_HANDLE *crlHandle,
/* loop through all the fortezza tokens */
for (le = list->head; le; le = le->next) {
- if (le->slot->nssToken && !nssToken_HasCrls(le->slot->nssToken)) {
- continue;
- }
crlh = pk11_FindObjectByTemplate(le->slot,theTemplate,tsize);
if (crlh != CK_INVALID_HANDLE) {
*slot = PK11_ReferenceSlot(le->slot);
@@ -3684,12 +3603,68 @@ loser:
}
if (crlData[1].pValue) PORT_Free(crlData[1].pValue);
return derCrl;
+#else
+ NSSCRL **crls, **crlp, *crl;
+ NSSDER subject;
+ SECItem *rvItem;
+ NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
+ NSSITEM_FROM_SECITEM(&subject, name);
+ if (*slot) {
+ nssCryptokiObject **instances;
+ nssPKIObjectCollection *collection;
+ nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
+ NSSToken *token = PK11Slot_GetNSSToken(*slot);
+ collection = nssCRLCollection_Create(td, NULL);
+ if (!collection) {
+ return NULL;
+ }
+ instances = nssToken_FindCRLsBySubject(token, NULL, &subject,
+ tokenOnly, 0, NULL);
+ nssPKIObjectCollection_AddInstances(collection, instances, 0);
+ nss_ZFreeIf(instances);
+ crls = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ } else {
+ crls = nssTrustDomain_FindCRLsBySubject(td, &subject);
+ }
+ if (!crls) {
+ return NULL;
+ }
+ crl = NULL;
+ for (crlp = crls; *crlp; crlp++) {
+ if ((!(*crlp)->isKRL && type == SEC_CRL_TYPE) ||
+ ((*crlp)->isKRL && type != SEC_CRL_TYPE))
+ {
+ crl = nssCRL_AddRef(*crlp);
+ break;
+ }
+ }
+ nssCRLArray_Destroy(crls);
+ if (!crl) {
+ return NULL;
+ }
+ *slot = PK11_ReferenceSlot(crl->object.instances[0]->token->pk11slot);
+ *crlHandle = crl->object.instances[0]->handle;
+ if (crl->url) {
+ *url = PORT_Strdup(crl->url);
+ }
+ rvItem = SECITEM_AllocItem(NULL, NULL, crl->encoding.size);
+ if (!rvItem) {
+ PORT_Free(*url);
+ nssCRL_Destroy(crl);
+ return NULL;
+ }
+ memcpy(rvItem->data, crl->encoding.data, crl->encoding.size);
+ nssCRL_Destroy(crl);
+ return rvItem;
+#endif
}
CK_OBJECT_HANDLE
PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
char *url, int type)
{
+#ifdef NSS_CLASSIC
CK_OBJECT_CLASS crlClass = CKO_NETSCAPE_CRL;
CK_ATTRIBUTE theTemplate[] = {
{ CKA_SUBJECT, NULL, 0 },
@@ -3735,12 +3710,29 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
PK11_RestoreROSession(slot,rwsession);
- if (slot->nssToken) {
- nssToken_SetHasCrls(slot->nssToken);
- }
return crlh;
-}
+#else
+ NSSItem derCRL, derSubject;
+ NSSToken *token = PK11Slot_GetNSSToken(slot);
+ nssCryptokiObject *object;
+ PRBool isKRL = (type == SEC_CRL_TYPE) ? PR_FALSE : PR_TRUE;
+ CK_OBJECT_HANDLE rvH;
+ NSSITEM_FROM_SECITEM(&derSubject, name);
+ NSSITEM_FROM_SECITEM(&derCRL, crl);
+
+ object = nssToken_ImportCRL(token, NULL,
+ &derSubject, &derCRL, isKRL, url, PR_TRUE);
+
+ if (object) {
+ rvH = object->handle;
+ nssCryptokiObject_Destroy(object);
+ } else {
+ rvH = CK_INVALID_HANDLE;
+ }
+ return rvH;
+#endif
+}
/*
@@ -3749,6 +3741,7 @@ PK11_PutCrl(PK11SlotInfo *slot, SECItem *crl, SECItem *name,
SECStatus
SEC_DeletePermCRL(CERTSignedCrl *crl)
{
+#ifdef NSS_CLASSIC
PK11SlotInfo *slot = crl->slot;
CK_RV crv;
@@ -3766,6 +3759,29 @@ SEC_DeletePermCRL(CERTSignedCrl *crl)
crl->slot = NULL;
PK11_FreeSlot(slot);
return SECSuccess;
+#else
+ PRStatus status;
+ NSSToken *token;
+ nssCryptokiObject *object;
+ PK11SlotInfo *slot = crl->slot;
+
+ if (slot == NULL) {
+ /* shouldn't happen */
+ PORT_SetError( SEC_ERROR_CRL_INVALID);
+ return SECFailure;
+ }
+ token = PK11Slot_GetNSSToken(slot);
+
+ object = nss_ZNEW(NULL, nssCryptokiObject);
+ object->token = nssToken_AddRef(token);
+ object->handle = crl->pkcs11ID;
+ object->isTokenObject = PR_TRUE;
+
+ status = nssToken_DeleteStoredObject(object);
+
+ nssCryptokiObject_Destroy(object);
+ return (status == PR_SUCCESS) ? SECSuccess : SECFailure;
+#endif
}
/*
diff --git a/security/nss/lib/pk11wrap/pk11slot.c b/security/nss/lib/pk11wrap/pk11slot.c
index edbbd9e4e..326ef8c99 100644
--- a/security/nss/lib/pk11wrap/pk11slot.c
+++ b/security/nss/lib/pk11wrap/pk11slot.c
@@ -727,10 +727,6 @@ PK11_Logout(PK11SlotInfo *slot)
PK11_EnterSlotMonitor(slot);
crv = PK11_GETTAB(slot)->C_Logout(slot->session);
PK11_ExitSlotMonitor(slot);
- if (slot->nssToken && !PK11_IsFriendly(slot)) {
- /* If the slot certs are not public readable, destroy them */
- nssToken_DestroyCertList(slot->nssToken, PR_TRUE);
- }
if (crv != CKR_OK) {
PORT_SetError(PK11_MapError(crv));
return SECFailure;
@@ -1146,11 +1142,6 @@ PK11_DoPassword(PK11SlotInfo *slot, PRBool loadCerts, void *wincx)
}
if (rv == SECSuccess) {
rv = pk11_CheckVerifyTest(slot);
- if (rv == SECSuccess && slot->nssToken && !PK11_IsFriendly(slot)) {
- /* notify stan about the login if certs are not public readable */
- nssToken_LoadCerts(slot->nssToken);
- nssToken_UpdateTrustForCerts(slot->nssToken);
- }
} else if (!attempt) PORT_SetError(SEC_ERROR_BAD_PASSWORD);
return rv;
}
diff --git a/security/nss/lib/pki/certificate.c b/security/nss/lib/pki/certificate.c
index 049c8ddcb..a7041830a 100644
--- a/security/nss/lib/pki/certificate.c
+++ b/security/nss/lib/pki/certificate.c
@@ -1036,3 +1036,78 @@ nssSMIMEProfile_Destroy
return PR_SUCCESS;
}
+NSS_IMPLEMENT NSSCRL *
+nssCRL_Create
+(
+ nssPKIObject *object
+)
+{
+ PRStatus status;
+ NSSCRL *rvCRL;
+ NSSArena *arena = object->arena;
+ PR_ASSERT(object->instances != NULL && object->numInstances > 0);
+ rvCRL = nss_ZNEW(arena, NSSCRL);
+ if (!rvCRL) {
+ return (NSSCRL *)NULL;
+ }
+ rvCRL->object = *object;
+ /* XXX should choose instance based on some criteria */
+ status = nssCryptokiCRL_GetAttributes(object->instances[0],
+ NULL, /* XXX sessionOpt */
+ arena,
+ &rvCRL->encoding,
+ &rvCRL->url,
+ &rvCRL->isKRL);
+ if (status != PR_SUCCESS) {
+ return (NSSCRL *)NULL;
+ }
+ return rvCRL;
+}
+
+NSS_IMPLEMENT NSSCRL *
+nssCRL_AddRef
+(
+ NSSCRL *crl
+)
+{
+ if (crl) {
+ nssPKIObject_AddRef(&crl->object);
+ }
+ return crl;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCRL_Destroy
+(
+ NSSCRL *crl
+)
+{
+ if (crl) {
+ (void)nssPKIObject_Destroy(&crl->object);
+ }
+ return PR_SUCCESS;
+}
+
+NSS_IMPLEMENT PRStatus
+nssCRL_DeleteStoredObject
+(
+ NSSCRL *crl,
+ NSSCallback *uhh
+)
+{
+ return nssPKIObject_DeleteStoredObject(&crl->object, uhh, PR_TRUE);
+}
+
+NSS_IMPLEMENT NSSDER *
+nssCRL_GetEncoding
+(
+ NSSCRL *crl
+)
+{
+ if (crl->encoding.data != NULL && crl->encoding.size > 0) {
+ return &crl->encoding;
+ } else {
+ return (NSSDER *)NULL;
+ }
+}
+
diff --git a/security/nss/lib/pki/pki3hack.c b/security/nss/lib/pki/pki3hack.c
index b9aa12ac5..fe770b179 100644
--- a/security/nss/lib/pki/pki3hack.c
+++ b/security/nss/lib/pki/pki3hack.c
@@ -71,9 +71,6 @@ static const char CVS_ID[] = "@(#) $RCSfile$ $Revision$ $Date$ $Name$";
#include "pkistore.h"
#include "secmod.h"
-/* if it's got more than 10 certs, it better handle traversal well */
-#define NSSTOKEN_MAX_LOCAL_CERTS 10
-
NSSTrustDomain *g_default_trust_domain = NULL;
NSSCryptoContext *g_default_crypto_context = NULL;
@@ -100,232 +97,6 @@ STAN_GetDefaultCryptoToken
return PK11Slot_GetNSSToken(pk11slot);
}
-static CERTCertificate *
-stan_GetCERTCertificate(NSSCertificate *c, PRBool forceUpdate);
-
-/* stuff the cert in the global trust domain cache, and then add a reference
- * to remain with the token in a list.
- */
-static PRStatus
-cache_token_cert(NSSCertificate *c, void *arg)
-{
- NSSToken *token = (NSSToken *)arg;
- NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
- NSSCertificate *cp = nssCertificate_AddRef(c);
- if (nssList_Count(token->certList) > NSSTOKEN_MAX_LOCAL_CERTS) {
- nssToken_DestroyCertList(token, PR_TRUE);
- /* terminate the traversal */
- return PR_FAILURE;
- }
- nssTrustDomain_AddCertsToCache(td, &c, 1);
- if (cp == c) {
- NSSCertificate_Destroy(cp);
- } else {
- /* The cert was already in the cache, from another token. Add this
- * token's instance to the cert.
- */
- 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));
- /* The cert needs to become external (made into a CERTCertificate)
- * in order for it to be properly released.
- * Force an update of the nickname and slot fields.
- */
- (void)stan_GetCERTCertificate(c, PR_TRUE);
- return PR_SUCCESS;
-}
-
-static PRBool instance_destructor(NSSCertificate *c, NSSToken *token)
-{
- nssPKIObject_RemoveInstanceForToken(&c->object, token);
- /* XXX cheating, this code to be replaced anyway */
- if (c->object.numInstances == 0) {
- return PR_TRUE;
- }
- return PR_FALSE;
-}
-
-NSS_IMPLEMENT void
-destroy_token_certs(nssList *certList, NSSToken *token, PRBool renewInstances)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRBool removeIt;
- certs = nssList_CreateIterator(certList);
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- removeIt = instance_destructor(cert, token);
- if (removeIt) {
- nssList_Remove(certList, cert);
- CERT_DestroyCertificate(STAN_GetCERTCertificate(cert));
- } else if (renewInstances) {
- /* force an update of the nickname and slot fields of the cert */
- (void)stan_GetCERTCertificate(cert, PR_TRUE);
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
-NSS_IMPLEMENT void
-nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token)
-{
- destroy_token_certs(certList, token, PR_TRUE);
-}
-
-NSS_IMPLEMENT void
-nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- PRBool removeIt;
- certs = nssList_CreateIterator(certList);
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- removeIt = instance_destructor(cert, token);
- if (removeIt) {
- nssList_Remove(certList, cert);
- } else {
- /* force an update of the nickname and slot fields of the cert */
- (void)stan_GetCERTCertificate(cert, PR_TRUE);
- }
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
-/* destroy the list of certs on a token */
-NSS_IMPLEMENT void
-nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances)
-{
- if (!token->certList) {
- return;
- }
- destroy_token_certs(token->certList, token, renewInstances);
- nssList_Clear(token->certList, NULL);
- /* 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)
-{
- PRStatus nssrv = PR_SUCCESS;
- nssTokenCertSearch search;
- if (!PK11_IsInternal(token->pk11slot) && PK11_IsHW(token->pk11slot)) {
- /* Hardware token certs will be immediately cached, and no searches
- * will be performed on the token (the certs will be discovered by
- * cache lookups)
- */
- search.callback = cache_token_cert;
- search.cbarg = token;
- search.cached = NULL;
- search.searchType = nssTokenSearchType_TokenOnly;
- if (!token->certList) {
- token->certList = nssList_Create(token->base.arena, PR_FALSE);
- if (!token->certList) {
- return PR_FAILURE;
- }
- } else if (nssList_Count(token->certList) > 0) {
- /* already been done */
- return PR_SUCCESS;
- }
- /* ignore the rv, just work without the list */
- add_token_certs_to_list(token);
- (void)nssToken_SetTrustCache(token);
- (void)nssToken_SetCrlCache(token);
-
- /* even if there are no certs, leave a valid list pointer should
- * any be imported. Having the pointer will also prevent searches,
- * see below.
- */
- if (nssList_Count(token->certList) == 0 &&
- !PK11_IsLoggedIn(token->pk11slot, NULL)) {
- /* If the token is not logged in, that may be the reason no
- * certs were found.
- */
- token->loggedIn = PR_FALSE;
- }
- }
- return nssrv;
-}
-
-NSS_IMPLEMENT void
-nssToken_UpdateTrustForCerts(NSSToken *token)
-{
- nssListIterator *certs;
- NSSCertificate *cert;
- certs = nssList_CreateIterator(token->certList);
- for (cert = (NSSCertificate *)nssListIterator_Start(certs);
- cert != (NSSCertificate *)NULL;
- cert = (NSSCertificate *)nssListIterator_Next(certs))
- {
- CERTCertificate *cc = STAN_GetCERTCertificate(cert);
- cc->trust = NULL;
- /* force an update of the trust fields of the CERTCertificate */
- (void)stan_GetCERTCertificate(cert, PR_FALSE);
- }
- nssListIterator_Finish(certs);
- nssListIterator_Destroy(certs);
-}
-
-NSS_IMPLEMENT PRBool
-nssToken_SearchCerts
-(
- NSSToken *token,
- PRBool *notPresentOpt
-)
-{
- if (notPresentOpt) {
- *notPresentOpt = PR_FALSE;
- }
- if (!nssToken_IsPresent(token)) {
- nssToken_DestroyCertList(token, PR_TRUE); /* will free cached certs */
- if (notPresentOpt) {
- *notPresentOpt = PR_TRUE;
- }
- } else if (token->certList &&
- nssList_Count(token->certList) == 0 &&
- !token->loggedIn) {
- /* If the token has no cached certs, but wasn't logged in, check
- * to see if it is logged in now and retry
- */
- if (PK11_IsLoggedIn(token->pk11slot, NULL)) {
- token->loggedIn = PR_TRUE;
- nssToken_LoadCerts(token);
- }
- }
- return (PRBool) (token->certList == NULL);
-}
-
NSS_IMPLEMENT PRStatus
STAN_LoadDefaultNSS3TrustDomain
(
@@ -352,17 +123,9 @@ STAN_LoadDefaultNSS3TrustDomain
}
}
SECMOD_ReleaseReadLock(moduleLock);
+ td->tokens = nssList_CreateIterator(td->tokenList);
g_default_trust_domain = td;
g_default_crypto_context = NSSTrustDomain_CreateCryptoContext(td, NULL);
- /* Cache hardware token certs with the token to make them persistent */
- td->tokens = nssList_CreateIterator(td->tokenList);
- for (token = (NSSToken *)nssListIterator_Start(td->tokens);
- token != (NSSToken *)NULL;
- token = (NSSToken *)nssListIterator_Next(td->tokens))
- {
- nssToken_LoadCerts(token);
- }
- nssListIterator_Finish(td->tokens);
return PR_SUCCESS;
}
@@ -379,7 +142,6 @@ STAN_AddModuleToDefaultTrustDomain
for (i=0; i<module->slotCount; i++) {
token = nssToken_CreateFromPK11SlotInfo(td, module->slots[i]);
PK11Slot_SetNSSToken(module->slots[i], token);
- nssToken_LoadCerts(token);
nssList_Add(td->tokenList, token);
}
nssListIterator_Destroy(td->tokens);
@@ -387,15 +149,6 @@ STAN_AddModuleToDefaultTrustDomain
return SECSuccess;
}
-NSS_IMPLEMENT void
-STAN_DestroyNSSToken(NSSToken *token)
-{
- if (token->certList) {
- nssToken_DestroyCertList(token, PR_FALSE);
- }
- nssToken_Destroy(token);
-}
-
NSS_IMPLEMENT SECStatus
STAN_RemoveModuleFromDefaultTrustDomain
(
@@ -410,7 +163,7 @@ STAN_RemoveModuleFromDefaultTrustDomain
token = PK11Slot_GetNSSToken(module->slots[i]);
if (token) {
nssList_Remove(td->tokenList, token);
- STAN_DestroyNSSToken(token);
+ nssToken_Destroy(token);
}
}
nssListIterator_Destroy(td->tokens);
diff --git a/security/nss/lib/pki/pki3hack.h b/security/nss/lib/pki/pki3hack.h
index 222dfdaf7..529c81e2b 100644
--- a/security/nss/lib/pki/pki3hack.h
+++ b/security/nss/lib/pki/pki3hack.h
@@ -75,29 +75,6 @@ STAN_LoadDefaultNSS3TrustDomain
NSS_EXTERN void
STAN_Shutdown();
-NSS_EXTERN void
-STAN_DestroyNSSToken(NSSToken *token);
-
-NSS_EXTERN PRBool
-nssToken_SearchCerts
-(
- NSSToken *token,
- PRBool *notPresentOpt
-);
-
-/* renewInstances -- if the cached token certs have multiple instances,
- * don't destroy them. If this parameter is false, they will be destroyed
- * anyway (used for clean shutdown).
- */
-NSS_EXTERN void
-nssToken_DestroyCertList(NSSToken *token, PRBool renewInstances);
-
-NSS_EXTERN void
-nssCertificateList_DestroyTokenCerts(nssList *certList, NSSToken *token);
-
-NSS_EXTERN void
-nssCertificateList_RemoveTokenCerts(nssList *certList, NSSToken *token);
-
NSS_EXTERN SECStatus
STAN_AddModuleToDefaultTrustDomain
(
diff --git a/security/nss/lib/pki/pkibase.c b/security/nss/lib/pki/pkibase.c
index 3a20ae96f..75e3c77e0 100644
--- a/security/nss/lib/pki/pkibase.c
+++ b/security/nss/lib/pki/pkibase.c
@@ -506,6 +506,22 @@ nssCertificateArray_Traverse
return status;
}
+
+NSS_IMPLEMENT void
+nssCRLArray_Destroy
+(
+ NSSCRL **crls
+)
+{
+ if (crls) {
+ NSSCRL **crlp;
+ for (crlp = crls; *crlp; crlp++) {
+ nssCRL_Destroy(*crlp);
+ }
+ nss_ZFreeIf(crls);
+ }
+}
+
/*
* Object collections
*/
@@ -513,8 +529,9 @@ nssCertificateArray_Traverse
typedef enum
{
pkiObjectType_Certificate = 0,
- pkiObjectType_PrivateKey = 1,
- pkiObjectType_PublicKey = 2
+ pkiObjectType_CRL = 1,
+ pkiObjectType_PrivateKey = 2,
+ pkiObjectType_PublicKey = 3
} pkiObjectType;
/* Each object is defined by a set of items that uniquely identify it.
@@ -847,6 +864,10 @@ nssPKIObjectCollection_Traverse
status = (*callback->func.cert)((NSSCertificate *)node->object,
callback->arg);
break;
+ case pkiObjectType_CRL:
+ status = (*callback->func.crl)((NSSCRL *)node->object,
+ callback->arg);
+ break;
case pkiObjectType_PrivateKey:
status = (*callback->func.pvkey)((NSSPrivateKey *)node->object,
callback->arg);
@@ -989,6 +1010,109 @@ nssPKIObjectCollection_GetCertificates
return rvOpt;
}
+/*
+ * CRL/KRL collections
+ */
+
+static void
+crl_destroyObject(nssPKIObject *o)
+{
+ NSSCRL *crl = (NSSCRL *)o;
+ nssCRL_Destroy(crl);
+}
+
+static PRStatus
+crl_getUIDFromObject(nssPKIObject *o, NSSItem *uid)
+{
+ NSSCRL *crl = (NSSCRL *)o;
+ NSSDER *encoding;
+ encoding = nssCRL_GetEncoding(crl);
+ uid[0] = *encoding;
+ uid[1].data = NULL; uid[1].size = 0;
+ return PR_SUCCESS;
+}
+
+static PRStatus
+crl_getUIDFromInstance(nssCryptokiObject *instance, NSSItem *uid,
+ NSSArena *arena)
+{
+ return nssCryptokiCRL_GetAttributes(instance,
+ NULL, /* XXX sessionOpt */
+ arena, /* arena */
+ &uid[0], /* encoding */
+ NULL, /* url */
+ NULL); /* isKRL */
+}
+
+static nssPKIObject *
+crl_createObject(nssPKIObject *o)
+{
+ return (nssPKIObject *)nssCRL_Create(o);
+}
+
+NSS_IMPLEMENT nssPKIObjectCollection *
+nssCRLCollection_Create
+(
+ NSSTrustDomain *td,
+ NSSCRL **crlsOpt
+)
+{
+ PRStatus status;
+ nssPKIObjectCollection *collection;
+ collection = nssPKIObjectCollection_Create(td, NULL);
+ collection->objectType = pkiObjectType_CRL;
+ collection->destroyObject = crl_destroyObject;
+ collection->getUIDFromObject = crl_getUIDFromObject;
+ collection->getUIDFromInstance = crl_getUIDFromInstance;
+ collection->createObject = crl_createObject;
+ if (crlsOpt) {
+ for (; *crlsOpt; crlsOpt++) {
+ nssPKIObject *object = (nssPKIObject *)(*crlsOpt);
+ status = nssPKIObjectCollection_AddObject(collection, object);
+ }
+ }
+ return collection;
+}
+
+NSS_IMPLEMENT NSSCRL **
+nssPKIObjectCollection_GetCRLs
+(
+ nssPKIObjectCollection *collection,
+ NSSCRL **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+)
+{
+ PRStatus status;
+ PRUint32 rvSize;
+ PRBool allocated = PR_FALSE;
+ if (collection->size == 0) {
+ return (NSSCRL **)NULL;
+ }
+ if (maximumOpt == 0) {
+ rvSize = collection->size;
+ } else {
+ rvSize = PR_MIN(collection->size, maximumOpt);
+ }
+ if (!rvOpt) {
+ rvOpt = nss_ZNEWARRAY(arenaOpt, NSSCRL *, rvSize + 1);
+ if (!rvOpt) {
+ return (NSSCRL **)NULL;
+ }
+ allocated = PR_TRUE;
+ }
+ status = nssPKIObjectCollection_GetObjects(collection,
+ (nssPKIObject **)rvOpt,
+ rvSize);
+ if (status != PR_SUCCESS) {
+ if (allocated) {
+ nss_ZFreeIf(rvOpt);
+ }
+ return (NSSCRL **)NULL;
+ }
+ return rvOpt;
+}
+
#ifdef PURE_STAN_BUILD
/*
* PrivateKey collections
diff --git a/security/nss/lib/pki/pkim.h b/security/nss/lib/pki/pkim.h
index d928d24e5..16ac87f3c 100644
--- a/security/nss/lib/pki/pkim.h
+++ b/security/nss/lib/pki/pkim.h
@@ -194,6 +194,13 @@ nssTrustDomain_FindCertificatesByID
NSSArena *arenaOpt
);
+NSS_EXTERN NSSCRL **
+nssTrustDomain_FindCRLsBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject
+);
+
/* module-private nsspki methods */
NSS_EXTERN NSSCryptoContext *
@@ -243,12 +250,43 @@ nssTrust_Create
nssPKIObject *object
);
+NSS_EXTERN NSSCRL *
+nssCRL_Create
+(
+ nssPKIObject *object
+);
+
+NSS_EXTERN NSSCRL *
+nssCRL_AddRef
+(
+ NSSCRL *crl
+);
+
+NSS_EXTERN PRStatus
+nssCRL_Destroy
+(
+ NSSCRL *crl
+);
+
+NSS_EXTERN PRStatus
+nssCRL_DeleteStoredObject
+(
+ NSSCRL *crl,
+ NSSCallback *uhh
+);
+
NSS_EXTERN NSSPrivateKey *
nssPrivateKey_Create
(
nssPKIObject *o
);
+NSS_EXTERN NSSDER *
+nssCRL_GetEncoding
+(
+ NSSCRL *crl
+);
+
NSS_EXTERN NSSPublicKey *
nssPublicKey_Create
(
@@ -320,6 +358,12 @@ nssCertificateArray_Traverse
void *arg
);
+NSS_EXTERN void
+nssCRLArray_Destroy
+(
+ NSSCRL **crls
+);
+
/* nssPKIObjectCollection
*
* This is a handy way to group objects together and perform operations
@@ -348,6 +392,7 @@ nssCertificateArray_Traverse
* Back to type-specific methods.
*
* nssPKIObjectCollection_GetCertificates
+ * nssPKIObjectCollection_GetCRLs
* nssPKIObjectCollection_GetPrivateKeys
* nssPKIObjectCollection_GetPublicKeys
*/
@@ -364,6 +409,18 @@ nssCertificateCollection_Create
NSSCertificate **certsOpt
);
+/* nssCRLCollection_Create
+ *
+ * Create a collection of CRLs/KRLs in the specified trust domain.
+ * Optionally provide a starting set of CRLs.
+ */
+NSS_EXTERN nssPKIObjectCollection *
+nssCRLCollection_Create
+(
+ NSSTrustDomain *td,
+ NSSCRL **crlsOpt
+);
+
/* nssPrivateKeyCollection_Create
*
* Create a collection of private keys in the specified trust domain.
@@ -452,6 +509,15 @@ nssPKIObjectCollection_GetCertificates
NSSArena *arenaOpt
);
+NSS_EXTERN NSSCRL **
+nssPKIObjectCollection_GetCRLs
+(
+ nssPKIObjectCollection *collection,
+ NSSCRL **rvOpt,
+ PRUint32 maximumOpt,
+ NSSArena *arenaOpt
+);
+
NSS_EXTERN NSSPrivateKey **
nssPKIObjectCollection_GetPrivateKeys
(
diff --git a/security/nss/lib/pki/pkit.h b/security/nss/lib/pki/pkit.h
index 23008d352..f8bd067b9 100644
--- a/security/nss/lib/pki/pkit.h
+++ b/security/nss/lib/pki/pkit.h
@@ -190,6 +190,15 @@ struct NSSTimeStr {
PRTime prTime;
};
+struct NSSCRLStr {
+ nssPKIObject object;
+ NSSDER encoding;
+ NSSUTF8 *url;
+ PRBool isKRL;
+};
+
+typedef struct NSSCRLStr NSSCRL;
+
struct NSSPoliciesStr;
struct NSSAlgorithmAndParametersStr;
diff --git a/security/nss/lib/pki/pkitm.h b/security/nss/lib/pki/pkitm.h
index 699a1b91c..d163923e6 100644
--- a/security/nss/lib/pki/pkitm.h
+++ b/security/nss/lib/pki/pkitm.h
@@ -110,6 +110,7 @@ typedef struct
{
union {
PRStatus (* cert)(NSSCertificate *c, void *arg);
+ PRStatus (* crl)(NSSCRL *crl, void *arg);
PRStatus (* pvkey)(NSSPrivateKey *vk, void *arg);
PRStatus (* pbkey)(NSSPublicKey *bk, void *arg);
} func;
diff --git a/security/nss/lib/pki/trustdomain.c b/security/nss/lib/pki/trustdomain.c
index 2fc2dedfc..1f3488186 100644
--- a/security/nss/lib/pki/trustdomain.c
+++ b/security/nss/lib/pki/trustdomain.c
@@ -109,7 +109,7 @@ token_destructor(void *t)
NSSToken *tok = (NSSToken *)t;
/* in 3.4, also destroy the slot (managed separately) */
(void)nssSlot_Destroy(tok->slot);
- STAN_DestroyNSSToken(tok);
+ nssToken_Destroy(tok);
}
NSS_IMPLEMENT PRStatus
@@ -1136,25 +1136,27 @@ nssTrustDomain_FindTrustForCertificate
}
for (slotp = slots; *slotp; slotp++) {
token = nssSlot_GetToken(*slotp);
- to = nssToken_FindTrustForCertificate(token, NULL,
- &c->encoding,
- &c->issuer,
- &c->serial,
+ if (token) {
+ 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 (to) {
if (!pkio) {
- goto loser;
- }
- } else {
- status = nssPKIObject_AddInstance(pkio, to);
- if (status != PR_SUCCESS) {
- goto loser;
+ 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);
}
- nssToken_Destroy(token);
}
if (pkio) {
rvt = nssTrust_Create(pkio);
@@ -1175,6 +1177,66 @@ loser:
return (NSSTrust *)NULL;
}
+NSS_IMPLEMENT NSSCRL **
+nssTrustDomain_FindCRLsBySubject
+(
+ NSSTrustDomain *td,
+ NSSDER *subject
+)
+{
+ PRStatus status;
+ NSSSlot **slots;
+ NSSSlot **slotp;
+ NSSToken *token;
+ nssUpdateLevel updateLevel;
+ nssPKIObjectCollection *collection;
+ NSSCRL **rvCRLs = NULL;
+ collection = nssCRLCollection_Create(td, NULL);
+ if (!collection) {
+ return (NSSCRL **)NULL;
+ }
+ slots = nssTrustDomain_GetActiveSlots(td, &updateLevel);
+ if (!slots) {
+ goto loser;
+ }
+ for (slotp = slots; *slotp; slotp++) {
+ 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_FindCRLsBySubject(token, session, subject,
+ tokenOnly, 0, &status);
+ nssToken_Destroy(token);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ /* add the found CRL's to the collection */
+ status = nssPKIObjectCollection_AddInstances(collection,
+ instances, 0);
+ nss_ZFreeIf(instances);
+ if (status != PR_SUCCESS) {
+ goto loser;
+ }
+ }
+ }
+ rvCRLs = nssPKIObjectCollection_GetCRLs(collection, NULL, 0, NULL);
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return rvCRLs;
+loser:
+ nssPKIObjectCollection_Destroy(collection);
+ nssSlotArray_Destroy(slots);
+ return (NSSCRL **)NULL;
+}
+
NSS_IMPLEMENT PRStatus
NSSTrustDomain_GenerateKeyPair
(