Back to index

lightning-sunbird  0.9+nobinonly
Classes | Typedefs | Functions | Variables
tdcache.c File Reference
#include "pkim.h"
#include "pkit.h"
#include "nsspki.h"
#include "pki.h"
#include "nssbase.h"
#include "base.h"
#include "cert.h"
#include "dev.h"
#include "pki3hack.h"

Go to the source code of this file.

Classes

struct  nssTDCertificateCacheStr
struct  cache_entry_str
struct  token_cert_dtor
union  cache_entry_str.entry

Typedefs

typedef struct cache_entry_str

Functions

static cache_entry * new_cache_entry (NSSArena *arena, void *value, PRBool ownArena)
NSS_IMPLEMENT PRStatus nssTrustDomain_InitializeCache (NSSTrustDomain *td, PRUint32 cacheSize)
NSS_IMPLEMENT PRStatus nssTrustDomain_DestroyCache (NSSTrustDomain *td)
static PRStatus remove_issuer_and_serial_entry (nssTDCertificateCache *cache, NSSCertificate *cert)
static PRStatus remove_subject_entry (nssTDCertificateCache *cache, NSSCertificate *cert, nssList **subjectList, NSSUTF8 **nickname, NSSArena **arena)
static PRStatus remove_nickname_entry (nssTDCertificateCache *cache, NSSUTF8 *nickname, nssList *subjectList)
static PRStatus remove_email_entry (nssTDCertificateCache *cache, NSSCertificate *cert, nssList *subjectList)
NSS_IMPLEMENT void nssTrustDomain_RemoveCertFromCacheLOCKED (NSSTrustDomain *td, NSSCertificate *cert)
NSS_IMPLEMENT void nssTrustDomain_LockCertCache (NSSTrustDomain *td)
NSS_IMPLEMENT void nssTrustDomain_UnlockCertCache (NSSTrustDomain *td)
static void remove_token_certs (const void *k, void *v, void *a)
NSS_IMPLEMENT PRStatus nssTrustDomain_RemoveTokenCertsFromCache (NSSTrustDomain *td, NSSToken *token)
NSS_IMPLEMENT PRStatus nssTrustDomain_UpdateCachedTokenCerts (NSSTrustDomain *td, NSSToken *token)
static PRStatus add_issuer_and_serial_entry (NSSArena *arena, nssTDCertificateCache *cache, NSSCertificate *cert)
static PRStatus add_subject_entry (NSSArena *arena, nssTDCertificateCache *cache, NSSCertificate *cert, NSSUTF8 *nickname, nssList **subjectList)
static PRStatus add_nickname_entry (NSSArena *arena, nssTDCertificateCache *cache, NSSUTF8 *certNickname, nssList *subjectList)
static PRStatus add_email_entry (nssTDCertificateCache *cache, NSSCertificate *cert, nssList *subjectList)
static void remove_object_instances (nssPKIObject *object, nssCryptokiObject **instances, int numInstances)
static SECStatus merge_object_instances (nssPKIObject *to, nssPKIObject *from)
static NSSCertificate * add_cert_to_cache (NSSTrustDomain *td, NSSCertificate *cert)
NSS_IMPLEMENT PRStatus nssTrustDomain_AddCertsToCache (NSSTrustDomain *td, NSSCertificate **certs, PRUint32 numCerts)
static NSSCertificate ** collect_subject_certs (nssList *subjectList, nssList *rvCertListOpt)
NSS_IMPLEMENT NSSCertificate ** nssTrustDomain_GetCertsForSubjectFromCache (NSSTrustDomain *td, NSSDER *subject, nssList *certListOpt)
NSS_IMPLEMENT NSSCertificate ** nssTrustDomain_GetCertsForNicknameFromCache (NSSTrustDomain *td, NSSUTF8 *nickname, nssList *certListOpt)
NSS_IMPLEMENT NSSCertificate ** nssTrustDomain_GetCertsForEmailAddressFromCache (NSSTrustDomain *td, NSSASCII7 *email, nssList *certListOpt)
NSS_IMPLEMENT NSSCertificate * nssTrustDomain_GetCertForIssuerAndSNFromCache (NSSTrustDomain *td, NSSDER *issuer, NSSDER *serial)
static PRStatus issuer_and_serial_from_encoding (NSSBER *encoding, NSSDER *issuer, NSSDER *serial)
NSS_IMPLEMENT NSSCertificate * nssTrustDomain_GetCertByDERFromCache (NSSTrustDomain *td, NSSDER *der)
static void cert_iter (const void *k, void *v, void *a)
NSS_EXTERN NSSCertificate ** nssTrustDomain_GetCertsFromCache (NSSTrustDomain *td, nssList *certListOpt)
NSS_IMPLEMENT void nssTrustDomain_DumpCacheInfo (NSSTrustDomain *td, void(*cert_dump_iter)(const void *, void *, void *), void *arg)

Variables

const NSSError NSS_ERROR_INTERNAL_ERROR
const NSSError NSS_ERROR_BUSY
const NSSError NSS_ERROR_CERTIFICATE_IN_CACHE

Class Documentation

struct nssTDCertificateCacheStr

Definition at line 110 of file tdcache.c.

Class Members
NSSArena * arena
nssHash * email
nssHash * issuerAndSN
PZLock * lock
nssHash * nickname
nssHash * subject
struct cache_entry_str

Definition at line 120 of file tdcache.c.

Collaboration diagram for cache_entry_str:
Class Members
NSSArena * arena
union cache_entry_str entry
union cache_entry_str entry
PRUint32 hits
PRTime lastHit
NSSUTF8 * nickname
struct token_cert_dtor

Definition at line 416 of file tdcache.c.

Class Members
PRUint32 arrSize
nssTDCertificateCache * cache
NSSCertificate ** certs
PRUint32 numCerts
NSSToken * token
union cache_entry_str.entry

Definition at line 122 of file tdcache.c.

Class Members
NSSCertificate * cert
nssList * list
void * value

Typedef Documentation

typedef struct cache_entry_str

Definition at line 133 of file tdcache.c.


Function Documentation

static NSSCertificate* add_cert_to_cache ( NSSTrustDomain *  td,
NSSCertificate *  cert 
) [static]

Definition at line 750 of file tdcache.c.

{
    NSSArena *arena = NULL;
    nssList *subjectList = NULL;
    PRStatus nssrv;
    PRUint32 added = 0;
    cache_entry *ce;
    NSSCertificate *rvCert = NULL;
    NSSUTF8 *certNickname = nssCertificate_GetNickname(cert, NULL);

    PZ_Lock(td->cache->lock);
    /* If it exists in the issuer/serial hash, it's already in all */
    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 - somebody else already added the cert
        * to the cache before this thread got around to it.
        */
       /* merge the instances of the cert */
       if (merge_object_instances(&rvCert->object, &cert->object)
                                                 != SECSuccess) {
           nssCertificate_Destroy(rvCert);
           return NULL;
       }
       STAN_ForceCERTCertificateUpdate(rvCert);
       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);
    if (nssrv != PR_SUCCESS) {
       goto loser;
    }
    added++;
    /* create an arena for the nickname and subject entries */
    arena = nssArena_Create();
    if (!arena) {
       goto loser;
    }
    /* create a new subject list for this cert, or add to existing */
    nssrv = add_subject_entry(arena, td->cache, cert, 
                                          certNickname, &subjectList);
    if (nssrv != PR_SUCCESS) {
       goto loser;
    }
    added++;
    /* If a new subject entry was created, also need nickname and/or email */
    if (subjectList != NULL) {
       PRBool handle = PR_FALSE;
       if (certNickname) {
           nssrv = add_nickname_entry(arena, td->cache, 
                                          certNickname, subjectList);
           if (nssrv != PR_SUCCESS) {
              goto loser;
           }
           handle = PR_TRUE;
           added++;
       }
       if (cert->email) {
           nssrv = add_email_entry(td->cache, cert, subjectList);
           if (nssrv != PR_SUCCESS) {
              goto loser;
           }
           handle = PR_TRUE;
           added += 2;
       }
#ifdef nodef
       /* I think either a nickname or email address must be associated
        * with the cert.  However, certs are passed to NewTemp without
        * either.  This worked in the old code, so it must work now.
        */
       if (!handle) {
           /* Require either nickname or email handle */
           nssrv = PR_FAILURE;
           goto loser;
       }
#endif
    }
    rvCert = cert;
    PZ_Unlock(td->cache->lock);
    return rvCert;
loser:
    /* Remove any handles that have been created */
    subjectList = NULL;
    if (added >= 1) {
       (void)remove_issuer_and_serial_entry(td->cache, cert);
    }
    if (added >= 2) {
       (void)remove_subject_entry(td->cache, cert, &subjectList, 
                                          &certNickname, &arena);
    }
    if (added == 3 || added == 5) {
       (void)remove_nickname_entry(td->cache, certNickname, subjectList);
    }
    if (added >= 4) {
       (void)remove_email_entry(td->cache, cert, subjectList);
    }
    if (subjectList) {
       nssHash_Remove(td->cache->subject, &cert->subject);
       nssList_Destroy(subjectList);
    }
    if (arena) {
       nssArena_Destroy(arena);
    }
    PZ_Unlock(td->cache->lock);
    return NULL;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus add_email_entry ( nssTDCertificateCache *  cache,
NSSCertificate *  cert,
nssList *  subjectList 
) [static]

Definition at line 642 of file tdcache.c.

{
    PRStatus nssrv = PR_SUCCESS;
    nssList *subjects;
    cache_entry *ce;
    ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
    if (ce) {
       /* Already have an entry for this email address, but not subject */
       subjects = ce->entry.list;
       nssrv = nssList_AddUnique(subjects, subjectList);
       ce->hits++;
       ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
       log_cert_ref("added subject to email for", cert);
#endif
    } else {
       NSSASCII7 *email;
       NSSArena *arena;
       arena = nssArena_Create();
       if (!arena) {
           return PR_FAILURE;
       }
       /* Create a new list of subject lists, add this subject */
       subjects = nssList_Create(arena, PR_TRUE);
       if (!subjects) {
           nssArena_Destroy(arena);
           return PR_FAILURE;
       }
       /* Add the new subject to the list */
       nssrv = nssList_AddUnique(subjects, subjectList);
       if (nssrv != PR_SUCCESS) {
           nssArena_Destroy(arena);
           return nssrv;
       }
       /* Add the new entry to the cache */
       ce = new_cache_entry(arena, (void *)subjects, PR_TRUE);
       if (!ce) {
           nssArena_Destroy(arena);
           return PR_FAILURE;
       }
       email = nssUTF8_Duplicate(cert->email, arena);
       if (!email) {
           nssArena_Destroy(arena);
           return PR_FAILURE;
       }
       nssrv = nssHash_Add(cache->email, email, ce);
       if (nssrv != PR_SUCCESS) {
           nssArena_Destroy(arena);
           return nssrv;
       }
#ifdef DEBUG_CACHE
       log_cert_ref("created email for", cert);
#endif
    }
    return nssrv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus add_issuer_and_serial_entry ( NSSArena *  arena,
nssTDCertificateCache *  cache,
NSSCertificate *  cert 
) [static]

Definition at line 533 of file tdcache.c.

{
    cache_entry *ce;
    ce = new_cache_entry(arena, (void *)cert, PR_FALSE);
#ifdef DEBUG_CACHE
    log_cert_ref("added to issuer/sn", cert);
#endif
    return nssHash_Add(cache->issuerAndSN, cert, (void *)ce);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus add_nickname_entry ( NSSArena *  arena,
nssTDCertificateCache *  cache,
NSSUTF8 certNickname,
nssList *  subjectList 
) [static]

Definition at line 607 of file tdcache.c.

{
    PRStatus nssrv = PR_SUCCESS;
    cache_entry *ce;
    ce = (cache_entry *)nssHash_Lookup(cache->nickname, certNickname);
    if (ce) {
       /* This is a collision.  A nickname entry already exists for this
        * subject, but a subject entry didn't.  This would imply there are
        * two subjects using the same nickname, which is not allowed.
        */
       return PR_FAILURE;
    } else {
       NSSUTF8 *nickname;
       ce = new_cache_entry(arena, subjectList, PR_FALSE);
       if (!ce) {
           return PR_FAILURE;
       }
       nickname = nssUTF8_Duplicate(certNickname, arena);
       if (!nickname) {
           return PR_FAILURE;
       }
       nssrv = nssHash_Add(cache->nickname, nickname, ce);
#ifdef DEBUG_CACHE
       log_cert_ref("created nickname for", cert);
#endif
    }
    return nssrv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus add_subject_entry ( NSSArena *  arena,
nssTDCertificateCache *  cache,
NSSCertificate *  cert,
NSSUTF8 nickname,
nssList **  subjectList 
) [static]

Definition at line 548 of file tdcache.c.

{
    PRStatus nssrv;
    nssList *list;
    cache_entry *ce;
    *subjectList = NULL;  /* this is only set if a new one is created */
    ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject);
    if (ce) {
       ce->hits++;
       ce->lastHit = PR_Now();
       /* The subject is already in, add this cert to the list */
       nssrv = nssList_AddUnique(ce->entry.list, cert);
#ifdef DEBUG_CACHE
       log_cert_ref("added to existing subject list", cert);
#endif
    } else {
       NSSDER *subject;
       /* Create a new subject list for the subject */
       list = nssList_Create(arena, PR_FALSE);
       if (!list) {
           return PR_FAILURE;
       }
       ce = new_cache_entry(arena, (void *)list, PR_TRUE);
       if (!ce) {
           return PR_FAILURE;
       }
       if (nickname) {
           ce->nickname = nssUTF8_Duplicate(nickname, arena);
       }
       nssList_SetSortFunction(list, nssCertificate_SubjectListSort);
       /* Add the cert entry to this list of subjects */
       nssrv = nssList_AddUnique(list, cert);
       if (nssrv != PR_SUCCESS) {
           return nssrv;
       }
       /* Add the subject list to the cache */
       subject = nssItem_Duplicate(&cert->subject, arena, NULL);
       if (!subject) {
           return PR_FAILURE;
       }
       nssrv = nssHash_Add(cache->subject, subject, ce);
       if (nssrv != PR_SUCCESS) {
           return nssrv;
       }
       *subjectList = list;
#ifdef DEBUG_CACHE
       log_cert_ref("created subject list", cert);
#endif
    }
    return nssrv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void cert_iter ( const void k,
void v,
void a 
) [static]

Definition at line 1126 of file tdcache.c.

{
    nssList *certList = (nssList *)a;
    NSSCertificate *c = (NSSCertificate *)k;
    nssList_Add(certList, nssCertificate_AddRef(c));
}

Here is the call graph for this function:

Here is the caller graph for this function:

static NSSCertificate** collect_subject_certs ( nssList *  subjectList,
nssList *  rvCertListOpt 
) [static]

Definition at line 888 of file tdcache.c.

{
    NSSCertificate *c;
    NSSCertificate **rvArray = NULL;
    PRUint32 count;
    nssCertificateList_AddReferences(subjectList);
    if (rvCertListOpt) {
       nssListIterator *iter = nssList_CreateIterator(subjectList);
       for (c  = (NSSCertificate *)nssListIterator_Start(iter);
            c != (NSSCertificate *)NULL;
            c  = (NSSCertificate *)nssListIterator_Next(iter)) {
           nssList_Add(rvCertListOpt, c);
       }
       nssListIterator_Finish(iter);
       nssListIterator_Destroy(iter);
    } else {
       count = nssList_Count(subjectList);
       rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
       if (!rvArray) {
           return (NSSCertificate **)NULL;
       }
       nssList_GetArray(subjectList, (void **)rvArray, count);
    }
    return rvArray;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus issuer_and_serial_from_encoding ( NSSBER encoding,
NSSDER issuer,
NSSDER serial 
) [static]

Definition at line 1075 of file tdcache.c.

{
    SECItem derCert, derIssuer, derSerial;
    SECStatus secrv;
    derCert.data = (unsigned char *)encoding->data;
    derCert.len = encoding->size;
    secrv = CERT_IssuerNameFromDERCert(&derCert, &derIssuer);
    if (secrv != SECSuccess) {
       return PR_FAILURE;
    }
    secrv = CERT_SerialNumberFromDERCert(&derCert, &derSerial);
    if (secrv != SECSuccess) {
       return PR_FAILURE;
    }
    issuer->data = derIssuer.data;
    issuer->size = derIssuer.len;
    serial->data = derSerial.data;
    serial->size = derSerial.len;
    return PR_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus merge_object_instances ( nssPKIObject *  to,
nssPKIObject *  from 
) [static]

Definition at line 720 of file tdcache.c.

{
    nssCryptokiObject **instances, **ci;
    int i;
    SECStatus rv = SECSuccess;

    instances = nssPKIObject_GetInstances(from);
    if (instances == NULL) {
       return SECFailure;
    }
    for (ci = instances, i = 0; *ci; ci++, i++) {
       nssCryptokiObject *instance = nssCryptokiObject_Clone(*ci);
       if (instance) {
           if (nssPKIObject_AddInstance(to, instance) == SECSuccess) {
              continue;
           }
           nssCryptokiObject_Destroy(instance);
       }
       remove_object_instances(to, instances, i);
       rv = SECFailure;
       break;
    }
    nssCryptokiObjectArray_Destroy(instances);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static cache_entry* new_cache_entry ( NSSArena *  arena,
void value,
PRBool  ownArena 
) [static]

Definition at line 136 of file tdcache.c.

{
    cache_entry *ce = nss_ZNEW(arena, cache_entry);
    if (ce) {
       ce->entry.value = value;
       ce->hits = 1;
       ce->lastHit = PR_Now();
       if (ownArena) {
           ce->arena = arena;
       }
       ce->nickname = NULL;
    }
    return ce;
}

Here is the call graph for this function:

Here is the caller graph for this function:

NSS_IMPLEMENT PRStatus nssTrustDomain_AddCertsToCache ( NSSTrustDomain *  td,
NSSCertificate **  certs,
PRUint32  numCerts 
)

Definition at line 868 of file tdcache.c.

{
    PRUint32 i;
    NSSCertificate *c;
    for (i=0; i<numCerts && certs[i]; i++) {
       c = add_cert_to_cache(td, certs[i]);
       if (c == NULL) {
           return PR_FAILURE;
       } else {
           certs[i] = c;
       }
    }
    return PR_SUCCESS;
}

Definition at line 228 of file tdcache.c.

{
    if (!td->cache) {
       nss_SetError(NSS_ERROR_INTERNAL_ERROR);
       return PR_FAILURE;
    }
    if (nssHash_Count(td->cache->issuerAndSN) > 0) {
       nss_SetError(NSS_ERROR_BUSY);
       return PR_FAILURE;
    }
    PZ_DestroyLock(td->cache->lock);
    nssHash_Destroy(td->cache->issuerAndSN);
    nssHash_Destroy(td->cache->subject);
    nssHash_Destroy(td->cache->nickname);
    nssHash_Destroy(td->cache->email);
    nssArena_Destroy(td->cache->arena);
    td->cache = NULL;
#ifdef DEBUG_CACHE
    PR_LOG(s_log, PR_LOG_DEBUG, ("Cache destroyed."));
#endif
    return PR_SUCCESS;
}
NSS_IMPLEMENT void nssTrustDomain_DumpCacheInfo ( NSSTrustDomain *  td,
void(*)(const void *, void *, void *)  cert_dump_iter,
void arg 
)

Definition at line 1163 of file tdcache.c.

{
    PZ_Lock(td->cache->lock);
    nssHash_Iterate(td->cache->issuerAndSN, cert_dump_iter, arg);
    PZ_Unlock(td->cache->lock);
}
NSS_IMPLEMENT NSSCertificate* nssTrustDomain_GetCertByDERFromCache ( NSSTrustDomain *  td,
NSSDER der 
)

Definition at line 1104 of file tdcache.c.

{
    PRStatus nssrv = PR_FAILURE;
    NSSDER issuer, serial;
    NSSCertificate *rvCert;
    nssrv = issuer_and_serial_from_encoding(der, &issuer, &serial);
    if (nssrv != PR_SUCCESS) {
       return NULL;
    }
#ifdef DEBUG_CACHE
    log_item_dump("looking for cert by DER", der);
#endif
    rvCert = nssTrustDomain_GetCertForIssuerAndSNFromCache(td, 
                                                           &issuer, &serial);
    PORT_Free(issuer.data);
    PORT_Free(serial.data);
    return rvCert;
}
NSS_IMPLEMENT NSSCertificate* nssTrustDomain_GetCertForIssuerAndSNFromCache ( NSSTrustDomain *  td,
NSSDER issuer,
NSSDER serial 
)

Definition at line 1043 of file tdcache.c.

{
    NSSCertificate certkey;
    NSSCertificate *rvCert = NULL;
    cache_entry *ce;
    certkey.issuer.data = issuer->data;
    certkey.issuer.size = issuer->size;
    certkey.serial.data = serial->data;
    certkey.serial.size = serial->size;
#ifdef DEBUG_CACHE
    log_item_dump("looking for cert by issuer/sn, issuer", issuer);
    log_item_dump("                               serial", serial);
#endif
    PZ_Lock(td->cache->lock);
    ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, &certkey);
    if (ce) {
       ce->hits++;
       ce->lastHit = PR_Now();
       rvCert = nssCertificate_AddRef(ce->entry.cert);
#ifdef DEBUG_CACHE
       PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
    }
    PZ_Unlock(td->cache->lock);
    return rvCert;
}
NSS_IMPLEMENT NSSCertificate** nssTrustDomain_GetCertsForEmailAddressFromCache ( NSSTrustDomain *  td,
NSSASCII7 email,
nssList *  certListOpt 
)

Definition at line 979 of file tdcache.c.

{
    NSSCertificate **rvArray = NULL;
    cache_entry *ce;
    nssList *collectList = NULL;
    nssListIterator *iter = NULL;
    nssList *subjectList;
#ifdef DEBUG_CACHE
    PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by email %s", email));
#endif
    PZ_Lock(td->cache->lock);
    ce = (cache_entry *)nssHash_Lookup(td->cache->email, email);
    if (ce) {
       ce->hits++;
       ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
       PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
       /* loop over subject lists and get refs for certs */
       if (certListOpt) {
           collectList = certListOpt;
       } else {
           collectList = nssList_Create(NULL, PR_FALSE);
           if (!collectList) {
              PZ_Unlock(td->cache->lock);
              return NULL;
           }
       }
       iter = nssList_CreateIterator(ce->entry.list);
       if (!iter) {
           PZ_Unlock(td->cache->lock);
           if (!certListOpt) {
              nssList_Destroy(collectList);
           }
           return NULL;
       }
       for (subjectList  = (nssList *)nssListIterator_Start(iter);
            subjectList != (nssList *)NULL;
            subjectList  = (nssList *)nssListIterator_Next(iter)) {
           (void)collect_subject_certs(subjectList, collectList);
       }
       nssListIterator_Finish(iter);
       nssListIterator_Destroy(iter);
    }
    PZ_Unlock(td->cache->lock);
    if (!certListOpt && collectList) {
       PRUint32 count = nssList_Count(collectList);
       rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
       if (rvArray) {
           nssList_GetArray(collectList, (void **)rvArray, count);
       }
       nssList_Destroy(collectList);
    }
    return rvArray;
}
NSS_IMPLEMENT NSSCertificate** nssTrustDomain_GetCertsForNicknameFromCache ( NSSTrustDomain *  td,
NSSUTF8 nickname,
nssList *  certListOpt 
)

Definition at line 950 of file tdcache.c.

{
    NSSCertificate **rvArray = NULL;
    cache_entry *ce;
#ifdef DEBUG_CACHE
    PR_LOG(s_log, PR_LOG_DEBUG, ("looking for cert by nick %s", nickname));
#endif
    PZ_Lock(td->cache->lock);
    ce = (cache_entry *)nssHash_Lookup(td->cache->nickname, nickname);
    if (ce) {
       ce->hits++;
       ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
       PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
       rvArray = collect_subject_certs(ce->entry.list, certListOpt);
    }
    PZ_Unlock(td->cache->lock);
    return rvArray;
}
NSS_IMPLEMENT NSSCertificate** nssTrustDomain_GetCertsForSubjectFromCache ( NSSTrustDomain *  td,
NSSDER subject,
nssList *  certListOpt 
)

Definition at line 921 of file tdcache.c.

{
    NSSCertificate **rvArray = NULL;
    cache_entry *ce;
#ifdef DEBUG_CACHE
    log_item_dump("looking for cert by subject", subject);
#endif
    PZ_Lock(td->cache->lock);
    ce = (cache_entry *)nssHash_Lookup(td->cache->subject, subject);
    if (ce) {
       ce->hits++;
       ce->lastHit = PR_Now();
#ifdef DEBUG_CACHE
       PR_LOG(s_log, PR_LOG_DEBUG, ("... found, %d hits", ce->hits));
#endif
       rvArray = collect_subject_certs(ce->entry.list, certListOpt);
    }
    PZ_Unlock(td->cache->lock);
    return rvArray;
}
NSS_EXTERN NSSCertificate** nssTrustDomain_GetCertsFromCache ( NSSTrustDomain *  td,
nssList *  certListOpt 
)

Definition at line 1134 of file tdcache.c.

{
    NSSCertificate **rvArray = NULL;
    nssList *certList;
    if (certListOpt) {
       certList = certListOpt;
    } else {
       certList = nssList_Create(NULL, PR_FALSE);
       if (!certList) {
           return NULL;
       }
    }
    PZ_Lock(td->cache->lock);
    nssHash_Iterate(td->cache->issuerAndSN, cert_iter, (void *)certList);
    PZ_Unlock(td->cache->lock);
    if (!certListOpt) {
       PRUint32 count = nssList_Count(certList);
       rvArray = nss_ZNEWARRAY(NULL, NSSCertificate *, count);
       nssList_GetArray(certList, (void **)rvArray, count);
       /* array takes the references */
       nssList_Destroy(certList);
    }
    return rvArray;
}
NSS_IMPLEMENT PRStatus nssTrustDomain_InitializeCache ( NSSTrustDomain *  td,
PRUint32  cacheSize 
)

Definition at line 155 of file tdcache.c.

{
    NSSArena *arena;
    nssTDCertificateCache *cache = td->cache;
#ifdef DEBUG_CACHE
    s_log = PR_NewLogModule("nss_cache");
    PR_ASSERT(s_log);
#endif
    PR_ASSERT(!cache);
    arena = nssArena_Create();
    if (!arena) {
       return PR_FAILURE;
    }
    cache = nss_ZNEW(arena, nssTDCertificateCache);
    if (!cache) {
       nssArena_Destroy(arena);
       return PR_FAILURE;
    }
    cache->lock = PZ_NewLock(nssILockCache);
    if (!cache->lock) {
       nssArena_Destroy(arena);
       return PR_FAILURE;
    }
    /* Create the issuer and serial DER --> certificate hash */
    cache->issuerAndSN = nssHash_CreateCertificate(arena, cacheSize);
    if (!cache->issuerAndSN) {
       goto loser;
    }
    /* Create the subject DER --> subject list hash */
    cache->subject = nssHash_CreateItem(arena, cacheSize);
    if (!cache->subject) {
       goto loser;
    }
    /* Create the nickname --> subject list hash */
    cache->nickname = nssHash_CreateString(arena, cacheSize);
    if (!cache->nickname) {
       goto loser;
    }
    /* Create the email --> list of subject lists hash */
    cache->email = nssHash_CreateString(arena, cacheSize);
    if (!cache->email) {
       goto loser;
    }
    cache->arena = arena;
    td->cache = cache;
#ifdef DEBUG_CACHE
    PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialized."));
#endif
    return PR_SUCCESS;
loser:
    PZ_DestroyLock(cache->lock);
    nssArena_Destroy(arena);
    td->cache = NULL;
#ifdef DEBUG_CACHE
    PR_LOG(s_log, PR_LOG_DEBUG, ("Cache initialization failed."));
#endif
    return PR_FAILURE;
}

Definition at line 401 of file tdcache.c.

{
    PZ_Lock(td->cache->lock);
}
NSS_IMPLEMENT void nssTrustDomain_RemoveCertFromCacheLOCKED ( NSSTrustDomain *  td,
NSSCertificate *  cert 
)

Definition at line 360 of file tdcache.c.

{
    nssList *subjectList;
    cache_entry *ce;
    NSSArena *arena;
    NSSUTF8 *nickname;

#ifdef DEBUG_CACHE
    log_cert_ref("attempt to remove cert", cert);
#endif
    ce = (cache_entry *)nssHash_Lookup(td->cache->issuerAndSN, cert);
    if (!ce || ce->entry.cert != cert) {
       /* If it's not in the cache, or a different cert is (this is really
        * for safety reasons, though it shouldn't happen), do nothing 
        */
#ifdef DEBUG_CACHE
       PR_LOG(s_log, PR_LOG_DEBUG, ("but it wasn't in the cache"));
#endif
       return;
    }
    (void)remove_issuer_and_serial_entry(td->cache, cert);
    (void)remove_subject_entry(td->cache, cert, &subjectList, 
                               &nickname, &arena);
    if (nssList_Count(subjectList) == 0) {
       (void)remove_nickname_entry(td->cache, nickname, subjectList);
       (void)remove_email_entry(td->cache, cert, subjectList);
       (void)nssList_Destroy(subjectList);
       nssHash_Remove(td->cache->subject, &cert->subject);
       /* there are no entries left for this subject, free the space used
        * for both the nickname and subject entries
        */
       if (arena) {
           nssArena_Destroy(arena);
       }
    }
}
NSS_IMPLEMENT PRStatus nssTrustDomain_RemoveTokenCertsFromCache ( NSSTrustDomain *  td,
NSSToken *  token 
)

Definition at line 456 of file tdcache.c.

{
    NSSCertificate **certs;
    PRUint32 i, arrSize = 10;
    struct token_cert_dtor dtor;
    certs = nss_ZNEWARRAY(NULL, NSSCertificate *, arrSize);
    if (!certs) {
       return PR_FAILURE;
    }
    dtor.cache = td->cache;
    dtor.token = token;
    dtor.certs = certs;
    dtor.numCerts = 0;
    dtor.arrSize = arrSize;
    PZ_Lock(td->cache->lock);
    nssHash_Iterate(td->cache->issuerAndSN, remove_token_certs, (void *)&dtor);
    for (i=0; i<dtor.numCerts; i++) {
       if (dtor.certs[i]->object.numInstances == 0) {
           nssTrustDomain_RemoveCertFromCacheLOCKED(td, dtor.certs[i]);
           dtor.certs[i] = NULL;  /* skip this cert in the second for loop */
       }
    }
    PZ_Unlock(td->cache->lock);
    for (i=0; i<dtor.numCerts; i++) {
       if (dtor.certs[i]) {
           STAN_ForceCERTCertificateUpdate(dtor.certs[i]);
       }
    }
    nss_ZFreeIf(dtor.certs);
    return PR_SUCCESS;
}

Definition at line 409 of file tdcache.c.

{
    PZ_Unlock(td->cache->lock);
}
NSS_IMPLEMENT PRStatus nssTrustDomain_UpdateCachedTokenCerts ( NSSTrustDomain *  td,
NSSToken *  token 
)

Definition at line 492 of file tdcache.c.

{
    NSSCertificate **cp, **cached = NULL;
    nssList *certList;
    PRUint32 count;
    certList = nssList_Create(NULL, PR_FALSE);
    if (!certList) return PR_FAILURE;
    (void *)nssTrustDomain_GetCertsFromCache(td, certList);
    count = nssList_Count(certList);
    if (count > 0) {
       cached = nss_ZNEWARRAY(NULL, NSSCertificate *, count + 1);
       if (!cached) {
           return PR_FAILURE;
       }
       nssList_GetArray(certList, (void **)cached, count);
       nssList_Destroy(certList);
       for (cp = cached; *cp; cp++) {
           nssCryptokiObject *instance;
           NSSCertificate *c = *cp;
           nssTokenSearchType tokenOnly = nssTokenSearchType_TokenOnly;
           instance = nssToken_FindCertificateByIssuerAndSerialNumber(
                                                              token,
                                                               NULL,
                                                               &c->issuer,
                                                               &c->serial,
                                                               tokenOnly,
                                                               NULL);
           if (instance) {
              nssPKIObject_AddInstance(&c->object, instance);
              STAN_ForceCERTCertificateUpdate(c);
           }
       }
       nssCertificateArray_Destroy(cached);
    }
    return PR_SUCCESS;
}
static PRStatus remove_email_entry ( nssTDCertificateCache *  cache,
NSSCertificate *  cert,
nssList *  subjectList 
) [static]

Definition at line 320 of file tdcache.c.

{
    PRStatus nssrv = PR_FAILURE;
    cache_entry *ce;
    /* Find the subject list in the email hash */
    if (cert->email) {
       ce = (cache_entry *)nssHash_Lookup(cache->email, cert->email);
       if (ce) {
           nssList *subjects = ce->entry.list;
           /* Remove the subject list from the email hash */
           nssList_Remove(subjects, subjectList);
#ifdef DEBUG_CACHE
           log_item_dump("removed subject list", &cert->subject);
           PR_LOG(s_log, PR_LOG_DEBUG, ("for email %s", cert->email));
#endif
           if (nssList_Count(subjects) == 0) {
              /* No more subject lists for email, delete list and
              * remove hash entry
              */
              (void)nssList_Destroy(subjects);
              nssHash_Remove(cache->email, cert->email);
              /* there are no entries left for this address, free space
               * used for email entries
               */
              nssArena_Destroy(ce->arena);
#ifdef DEBUG_CACHE
              PR_LOG(s_log, PR_LOG_DEBUG, ("removed email %s", cert->email));
#endif
           }
           nssrv = PR_SUCCESS;
       }
    }
    return nssrv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus remove_issuer_and_serial_entry ( nssTDCertificateCache *  cache,
NSSCertificate *  cert 
) [static]

Definition at line 254 of file tdcache.c.

{
    /* Remove the cert from the issuer/serial hash */
    nssHash_Remove(cache->issuerAndSN, cert);
#ifdef DEBUG_CACHE
    log_cert_ref("removed issuer/sn", cert);
#endif
    return PR_SUCCESS;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus remove_nickname_entry ( nssTDCertificateCache *  cache,
NSSUTF8 nickname,
nssList *  subjectList 
) [static]

Definition at line 300 of file tdcache.c.

{
    PRStatus nssrv;
    if (nickname) {
       nssHash_Remove(cache->nickname, nickname);
       nssrv = PR_SUCCESS;
#ifdef DEBUG_CACHE
       PR_LOG(s_log, PR_LOG_DEBUG, ("removed nickname %s", nickname));
#endif
    } else {
       nssrv = PR_FAILURE;
    }
    return nssrv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void remove_object_instances ( nssPKIObject *  object,
nssCryptokiObject **  instances,
int  numInstances 
) [static]

Definition at line 706 of file tdcache.c.

{
    int i;

    for (i = 0; i < numInstances; i++) {
       nssPKIObject_RemoveInstanceForToken(object, instances[i]->token);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRStatus remove_subject_entry ( nssTDCertificateCache *  cache,
NSSCertificate *  cert,
nssList **  subjectList,
NSSUTF8 **  nickname,
NSSArena **  arena 
) [static]

Definition at line 268 of file tdcache.c.

{
    PRStatus nssrv;
    cache_entry *ce;
    *subjectList = NULL;
    *arena = NULL;
    /* Get the subject list for the cert's subject */
    ce = (cache_entry *)nssHash_Lookup(cache->subject, &cert->subject);
    if (ce) {
       /* Remove the cert from the subject hash */
       nssList_Remove(ce->entry.list, cert);
       *subjectList = ce->entry.list;
       *nickname = ce->nickname;
       *arena = ce->arena;
       nssrv = PR_SUCCESS;
#ifdef DEBUG_CACHE
       log_cert_ref("removed cert", cert);
       log_item_dump("from subject list", &cert->subject);
#endif
    } else {
       nssrv = PR_FAILURE;
    }
    return nssrv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void remove_token_certs ( const void k,
void v,
void a 
) [static]

Definition at line 424 of file tdcache.c.

{
    NSSCertificate *c = (NSSCertificate *)k;
    nssPKIObject *object = &c->object;
    struct token_cert_dtor *dtor = a;
    PRUint32 i;
    nssPKIObject_Lock(object);
    for (i=0; i<object->numInstances; i++) {
       if (object->instances[i]->token == dtor->token) {
           nssCryptokiObject_Destroy(object->instances[i]);
           object->instances[i] = object->instances[object->numInstances-1];
           object->instances[object->numInstances-1] = NULL;
           object->numInstances--;
           dtor->certs[dtor->numCerts++] = c;
           if (dtor->numCerts == dtor->arrSize) {
              dtor->arrSize *= 2;
              dtor->certs = nss_ZREALLOCARRAY(dtor->certs, 
                                              NSSCertificate *,
                                              dtor->arrSize);
           }
           break;
       }
    }
    nssPKIObject_Unlock(object);
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

Definition at line 94 of file errorval.c.

Definition at line 89 of file errorval.c.

Definition at line 52 of file errorval.c.