Back to index

lightning-sunbird  0.9+nobinonly
Defines | Functions | Variables
certdb.c File Reference
#include "nssilock.h"
#include "prmon.h"
#include "prtime.h"
#include "cert.h"
#include "certi.h"
#include "secder.h"
#include "secoid.h"
#include "secasn1.h"
#include "genname.h"
#include "keyhi.h"
#include "secitem.h"
#include "mcom_db.h"
#include "certdb.h"
#include "prprf.h"
#include "sechash.h"
#include "prlong.h"
#include "certxutl.h"
#include "portreg.h"
#include "secerr.h"
#include "sslerr.h"
#include "nsslocks.h"
#include "pk11func.h"
#include "xconst.h"
#include "pki.h"
#include "pki3hack.h"

Go to the source code of this file.

Defines

#define NSS_3_4_CODE
#define PENDING_SLOP   (24L*60L*60L) /* seconds per day */

Functions

SECStatus CERT_KeyFromIssuerAndSN (PRArenaPool *arena, SECItem *issuer, SECItem *sn, SECItem *key)
SECStatus CERT_NameFromDERCert (SECItem *derCert, SECItem *derName)
SECStatus CERT_IssuerNameFromDERCert (SECItem *derCert, SECItem *derName)
SECStatus CERT_SerialNumberFromDERCert (SECItem *derCert, SECItem *derName)
SECStatus CERT_KeyFromDERCert (PRArenaPool *arena, SECItem *derCert, SECItem *key)
static SECStatus GetKeyUsage (CERTCertificate *cert)
static PRBool fortezzaIsCA (CERTCertificate *cert)
static SECStatus findOIDinOIDSeqByTagNum (CERTOidSequence *seq, SECOidTag tagnum)
SECStatus cert_GetCertType (CERTCertificate *cert)
SECStatus cert_GetKeyID (CERTCertificate *cert)
static PRBool cert_IsRootCert (CERTCertificate *cert)
CERTCertificate * CERT_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname)
CERTCertificate * __CERT_DecodeDERCertificate (SECItem *derSignedCert, PRBool copyDER, char *nickname)
PRInt32 CERT_GetSlopTime (void)
SECStatus CERT_SetSlopTime (PRInt32 slop)
SECStatus CERT_GetCertTimes (CERTCertificate *c, PRTime *notBefore, PRTime *notAfter)
SECCertTimeValidity CERT_CheckCertValidTimes (CERTCertificate *c, PRTime t, PRBool allowOverride)
SECStatus SEC_GetCrlTimes (CERTCrl *date, PRTime *notBefore, PRTime *notAfter)
SECCertTimeValidity SEC_CheckCrlTimes (CERTCrl *crl, PRTime t)
PRBool SEC_CrlIsNewer (CERTCrl *inNew, CERTCrl *old)
SECStatus CERT_KeyUsageAndTypeForCertUsage (SECCertUsage usage, PRBool ca, unsigned int *retKeyUsage, unsigned int *retCertType)
SECStatus CERT_CheckKeyUsage (CERTCertificate *cert, unsigned int requiredUsage)
CERTCertificate * CERT_DupCertificate (CERTCertificate *c)
void CERT_SetDefaultCertDB (CERTCertDBHandle *handle)
CERTCertDBHandle * CERT_GetDefaultCertDB (void)
static void sec_lower_string (char *s)
SECStatus CERT_AddOKDomainName (CERTCertificate *cert, const char *hn)
static SECStatus cert_TestHostName (char *cn, const char *hn)
SECStatus cert_VerifySubjectAltName (CERTCertificate *cert, const char *hn)
SECStatus CERT_VerifyCertName (CERTCertificate *cert, const char *hn)
PRBool CERT_CompareCerts (CERTCertificate *c1, CERTCertificate *c2)
static SECStatus StringsEqual (char *s1, char *s2)
PRBool CERT_CompareCertsForRedirection (CERTCertificate *c1, CERTCertificate *c2)
CERTIssuerAndSN * CERT_GetCertIssuerAndSN (PRArenaPool *arena, CERTCertificate *cert)
char * CERT_MakeCANickname (CERTCertificate *cert)
void CERT_DestroyCrl (CERTSignedCrl *crl)
PRBool CERT_IsCACert (CERTCertificate *cert, unsigned int *rettype)
PRBool CERT_IsCADERCert (SECItem *derCert, unsigned int *type)
PRBool CERT_IsRootDERCert (SECItem *derCert)
CERTCompareValidityStatus CERT_CompareValidityTimes (CERTValidity *val_a, CERTValidity *val_b)
PRBool CERT_IsNewer (CERTCertificate *certa, CERTCertificate *certb)
void CERT_DestroyCertArray (CERTCertificate **certs, unsigned int ncerts)
char * CERT_FixupEmailAddr (char *emailAddr)
SECStatus CERT_DecodeTrustString (CERTCertTrust *trust, char *trusts)
static void EncodeFlags (char *trusts, unsigned int flags)
char * CERT_EncodeTrustString (CERTCertTrust *trust)
SECStatus CERT_SaveImportedCert (CERTCertificate *cert, SECCertUsage usage, PRBool caOnly, char *nickname)
SECStatus CERT_ImportCerts (CERTCertDBHandle *certdb, SECCertUsage usage, unsigned int ncerts, SECItem **derCerts, CERTCertificate ***retCerts, PRBool keepCerts, PRBool caOnly, char *nickname)
CERTCertList * CERT_NewCertList (void)
void CERT_DestroyCertList (CERTCertList *certs)
void CERT_RemoveCertListNode (CERTCertListNode *node)
SECStatus CERT_AddCertToListTailWithData (CERTCertList *certs, CERTCertificate *cert, void *appData)
SECStatus CERT_AddCertToListTail (CERTCertList *certs, CERTCertificate *cert)
SECStatus CERT_AddCertToListHeadWithData (CERTCertList *certs, CERTCertificate *cert, void *appData)
SECStatus CERT_AddCertToListHead (CERTCertList *certs, CERTCertificate *cert)
PRBool CERT_SortCBValidity (CERTCertificate *certa, CERTCertificate *certb, void *arg)
SECStatus CERT_AddCertToListSorted (CERTCertList *certs, CERTCertificate *cert, CERTSortCallback f, void *arg)
SECStatus CERT_FilterCertListByUsage (CERTCertList *certList, SECCertUsage usage, PRBool ca)
PRBool CERT_IsUserCert (CERTCertificate *cert)
SECStatus CERT_FilterCertListForUserCerts (CERTCertList *certList)
void CERT_LockCertRefCount (CERTCertificate *cert)
void CERT_UnlockCertRefCount (CERTCertificate *cert)
void CERT_LockCertTrust (CERTCertificate *cert)
void CERT_UnlockCertTrust (CERTCertificate *cert)
CERTStatusConfig * CERT_GetStatusConfig (CERTCertDBHandle *handle)
void CERT_SetStatusConfig (CERTCertDBHandle *handle, CERTStatusConfig *statusConfig)
static voidcert_AllocTable (void *pool, PRSize size)
static void cert_FreeTable (void *pool, void *item)
static PLHashEntrycert_AllocEntry (void *pool, const void *key)
static void cert_FreeEntry (void *pool, PLHashEntry *he, PRUintn flag)
SECStatus cert_CreateSubjectKeyIDHashTable (void)
SECStatus cert_AddSubjectKeyIDMapping (SECItem *subjKeyID, CERTCertificate *cert)
SECStatus cert_RemoveSubjectKeyIDMapping (SECItem *subjKeyID)
SECStatus cert_DestroySubjectKeyIDHashTable (void)
SECItem * cert_FindDERCertBySubjectKeyID (SECItem *subjKeyID)
CERTCertificate * CERT_FindCertBySubjectKeyID (CERTCertDBHandle *handle, SECItem *subjKeyID)

Variables

const SEC_ASN1Template CERT_CertExtensionTemplate []
const SEC_ASN1Template CERT_SequenceOfCertExtensionTemplate []
const SEC_ASN1Template CERT_CertificateTemplate []
const SEC_ASN1Template SEC_SignedCertificateTemplate []
const SEC_ASN1Template SEC_CertSubjectTemplate []
const SEC_ASN1Template SEC_CertIssuerTemplate []
const SEC_ASN1Template SEC_CertSerialNumberTemplate []
const SEC_ASN1Template CERT_CertKeyTemplate []
static PRInt32 pendingSlop = PENDING_SLOP
static CERTCertDBHandle * default_cert_db_handle = 0
static PZLockcertRefCountLock = NULL
static PZLockcertTrustLock = NULL
static PLHashTablegSubjKeyIDHash = NULL
static PRLockgSubjKeyIDLock = NULL
static PLHashAllocOps cert_AllocOps

Define Documentation

Definition at line 69 of file certdb.c.

#define PENDING_SLOP   (24L*60L*60L) /* seconds per day */

Definition at line 957 of file certdb.c.


Function Documentation

CERTCertificate* __CERT_DecodeDERCertificate ( SECItem *  derSignedCert,
PRBool  copyDER,
char *  nickname 
)

Definition at line 944 of file certdb.c.

{
    return CERT_DecodeDERCertificate(derSignedCert, copyDER, nickname);
}
SECStatus CERT_AddCertToListHead ( CERTCertList *  certs,
CERTCertificate *  cert 
)

Definition at line 2494 of file certdb.c.

Here is the call graph for this function:

SECStatus CERT_AddCertToListHeadWithData ( CERTCertList *  certs,
CERTCertificate *  cert,
void appData 
)

Definition at line 2467 of file certdb.c.

{
    CERTCertListNode *node;
    CERTCertListNode *head;
    
    head = CERT_LIST_HEAD(certs);

    if (head == NULL) return CERT_AddCertToListTail(certs,cert);

    node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
                                          sizeof(CERTCertListNode));
    if ( node == NULL ) {
       goto loser;
    }
    
    PR_INSERT_BEFORE(&node->links, &head->links);
    /* certs->count++; */
    node->cert = cert;
    node->appData = appData;
    return(SECSuccess);
    
loser:
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_AddCertToListSorted ( CERTCertList *  certs,
CERTCertificate *  cert,
CERTSortCallback  f,
void arg 
)

Definition at line 2576 of file certdb.c.

{
    CERTCertListNode *node;
    CERTCertListNode *head;
    PRBool ret;
    
    node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
                                          sizeof(CERTCertListNode));
    if ( node == NULL ) {
       goto loser;
    }
    
    head = CERT_LIST_HEAD(certs);
    
    while ( !CERT_LIST_END(head, certs) ) {

       /* if cert is already in the list, then don't add it again */
       if ( cert == head->cert ) {
           /*XXX*/
           /* don't keep a reference */
           CERT_DestroyCertificate(cert);
           goto done;
       }
       
       ret = (* f)(cert, head->cert, arg);
       /* if sort function succeeds, then insert before current node */
       if ( ret ) {
           PR_INSERT_BEFORE(&node->links, &head->links);
           goto done;
       }

       head = CERT_LIST_NEXT(head);
    }
    /* if we get to the end, then just insert it at the tail */
    PR_INSERT_BEFORE(&node->links, &certs->list);

done:    
    /* certs->count++; */
    node->cert = cert;
    return(SECSuccess);
    
loser:
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_AddCertToListTail ( CERTCertList *  certs,
CERTCertificate *  cert 
)

Definition at line 2461 of file certdb.c.

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_AddCertToListTailWithData ( CERTCertList *  certs,
CERTCertificate *  cert,
void appData 
)

Definition at line 2439 of file certdb.c.

{
    CERTCertListNode *node;
    
    node = (CERTCertListNode *)PORT_ArenaZAlloc(certs->arena,
                                          sizeof(CERTCertListNode));
    if ( node == NULL ) {
       goto loser;
    }
    
    PR_INSERT_BEFORE(&node->links, &certs->list);
    /* certs->count++; */
    node->cert = cert;
    node->appData = appData;
    return(SECSuccess);
    
loser:
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_AddOKDomainName ( CERTCertificate *  cert,
const char *  hn 
)

Definition at line 1338 of file certdb.c.

{
    CERTOKDomainName *domainOK;
    int              newNameLen;

    if (!hn || !(newNameLen = strlen(hn))) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    domainOK = (CERTOKDomainName *)PORT_ArenaZAlloc(cert->arena, 
                              (sizeof *domainOK) + newNameLen);
    if (!domainOK) 
       return SECFailure;   /* error code is already set. */

    PORT_Strcpy(domainOK->name, hn);
    sec_lower_string(domainOK->name);

    /* put at head of list. */
    domainOK->next = cert->domainOK;
    cert->domainOK = domainOK;
    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus cert_AddSubjectKeyIDMapping ( SECItem *  subjKeyID,
CERTCertificate *  cert 
)

Definition at line 2884 of file certdb.c.

{
    SECItem *newKeyID, *oldVal, *newVal;
    SECStatus rv = SECFailure;

    if (!gSubjKeyIDLock) {
       /* If one is created, then both are there.  So only check for one. */
       return SECFailure;
    }

    newVal = SECITEM_DupItem(&cert->derCert);
    if (!newVal) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto done;
    }
    newKeyID = SECITEM_DupItem(subjKeyID);
    if (!newKeyID) {
        SECITEM_FreeItem(newVal, PR_TRUE);
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        goto done;
    }

    PR_Lock(gSubjKeyIDLock);
    /* The hash table implementation does not free up the memory 
     * associated with the key of an already existing entry if we add a 
     * duplicate, so we would wind up leaking the previously allocated 
     * key if we don't remove before adding.
     */
    oldVal = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
    if (oldVal) {
        PL_HashTableRemove(gSubjKeyIDHash, subjKeyID);
    }

    rv = (PL_HashTableAdd(gSubjKeyIDHash, newKeyID, newVal)) ? SECSuccess :
                                                               SECFailure;
    PR_Unlock(gSubjKeyIDLock);
done:
    return rv;
}

Here is the call graph for this function:

static PLHashEntry* cert_AllocEntry ( void pool,
const void key 
) [static]

Definition at line 2844 of file certdb.c.

{
    return PORT_New(PLHashEntry);
}
static void* cert_AllocTable ( void pool,
PRSize  size 
) [static]

Definition at line 2834 of file certdb.c.

{
    return PORT_Alloc(size);
}

Here is the call graph for this function:

SECCertTimeValidity CERT_CheckCertValidTimes ( CERTCertificate *  c,
PRTime  t,
PRBool  allowOverride 
)

Definition at line 1004 of file certdb.c.

{
    PRTime notBefore, notAfter, llPendingSlop, tmp1;
    SECStatus rv;

    if (!c) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return(secCertTimeUndetermined);
    }
    /* if cert is already marked OK, then don't bother to check */
    if ( allowOverride && c->timeOK ) {
       return(secCertTimeValid);
    }

    rv = CERT_GetCertTimes(c, &notBefore, &notAfter);
    
    if (rv) {
       return(secCertTimeExpired); /*XXX is this the right thing to do here?*/
    }
    
    LL_I2L(llPendingSlop, pendingSlop);
    /* convert to micro seconds */
    LL_UI2L(tmp1, PR_USEC_PER_SEC);
    LL_MUL(llPendingSlop, llPendingSlop, tmp1);
    LL_SUB(notBefore, notBefore, llPendingSlop);
    if ( LL_CMP( t, <, notBefore ) ) {
       PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
       return(secCertTimeNotValidYet);
    }
    if ( LL_CMP( t, >, notAfter) ) {
       PORT_SetError(SEC_ERROR_EXPIRED_CERTIFICATE);
       return(secCertTimeExpired);
    }

    return(secCertTimeValid);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_CheckKeyUsage ( CERTCertificate *  cert,
unsigned int  requiredUsage 
)

Definition at line 1231 of file certdb.c.

{
    unsigned int certKeyUsage;

    if (!cert) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    /* choose between key agreement or key encipherment based on key
     * type in cert
     */
    if ( requiredUsage & KU_KEY_AGREEMENT_OR_ENCIPHERMENT ) {
       KeyType keyType = CERT_GetCertKeyType(&cert->subjectPublicKeyInfo);
       /* turn off the special bit */
       requiredUsage &= (~KU_KEY_AGREEMENT_OR_ENCIPHERMENT);

       switch (keyType) {
       case rsaKey:
           requiredUsage |= KU_KEY_ENCIPHERMENT;
           break;
       case dsaKey:
           requiredUsage |= KU_DIGITAL_SIGNATURE;
           break;
       case fortezzaKey:
       case keaKey:
       case dhKey:
           requiredUsage |= KU_KEY_AGREEMENT;
           break;
       case ecKey:
           /* Accept either signature or agreement. */
           if (!(cert->keyUsage & (KU_DIGITAL_SIGNATURE | KU_KEY_AGREEMENT)))
               goto loser;
           break;
       default:
           goto loser;
       }
    }

    certKeyUsage = cert->keyUsage;
    if (certKeyUsage & KU_NON_REPUDIATION)
        certKeyUsage |= KU_DIGITAL_SIGNATURE;
    if ( (certKeyUsage & requiredUsage) == requiredUsage ) 
       return SECSuccess;

loser:
    PORT_SetError(SEC_ERROR_INADEQUATE_KEY_USAGE);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_CompareCerts ( CERTCertificate *  c1,
CERTCertificate *  c2 
)

Definition at line 1564 of file certdb.c.

{
    SECComparison comp;
    
    comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
    if ( comp == SECEqual ) { /* certs are the same */
       return(PR_TRUE);
    } else {
       return(PR_FALSE);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_CompareCertsForRedirection ( CERTCertificate *  c1,
CERTCertificate *  c2 
)

Definition at line 1594 of file certdb.c.

{
    SECComparison comp;
    char *c1str, *c2str;
    SECStatus eq;
    
    comp = SECITEM_CompareItem(&c1->derCert, &c2->derCert);
    if ( comp == SECEqual ) { /* certs are the same */
       return(PR_TRUE);
    }
       
    /* check if they are issued by the same CA */
    comp = SECITEM_CompareItem(&c1->derIssuer, &c2->derIssuer);
    if ( comp != SECEqual ) { /* different issuer */
       return(PR_FALSE);
    }

    /* check country name */
    c1str = CERT_GetCountryName(&c1->subject);
    c2str = CERT_GetCountryName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if ( eq != SECSuccess ) {
       return(PR_FALSE);
    }

    /* check locality name */
    c1str = CERT_GetLocalityName(&c1->subject);
    c2str = CERT_GetLocalityName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if ( eq != SECSuccess ) {
       return(PR_FALSE);
    }
       
    /* check state name */
    c1str = CERT_GetStateName(&c1->subject);
    c2str = CERT_GetStateName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if ( eq != SECSuccess ) {
       return(PR_FALSE);
    }

    /* check org name */
    c1str = CERT_GetOrgName(&c1->subject);
    c2str = CERT_GetOrgName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if ( eq != SECSuccess ) {
       return(PR_FALSE);
    }

#ifdef NOTDEF 
    /* check orgUnit name */
    /*
     * We need to revisit this and decide which fields should be allowed to be
     * different
     */
    c1str = CERT_GetOrgUnitName(&c1->subject);
    c2str = CERT_GetOrgUnitName(&c2->subject);
    eq = StringsEqual(c1str, c2str);
    PORT_Free(c1str);
    PORT_Free(c2str);
    if ( eq != SECSuccess ) {
       return(PR_FALSE);
    }
#endif

    return(PR_TRUE); /* all fields but common name are the same */
}

Here is the call graph for this function:

CERTCompareValidityStatus CERT_CompareValidityTimes ( CERTValidity *  val_a,
CERTValidity *  val_b 
)

Definition at line 1916 of file certdb.c.

{
    PRTime notBeforeA, notBeforeB, notAfterA, notAfterB;

    if (!val_a || !val_b)
    {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return certValidityUndetermined;
    }

    if ( SECSuccess != DER_DecodeTimeChoice(&notBeforeA, &val_a->notBefore) ||
         SECSuccess != DER_DecodeTimeChoice(&notBeforeB, &val_b->notBefore) ||
         SECSuccess != DER_DecodeTimeChoice(&notAfterA, &val_a->notAfter) ||
         SECSuccess != DER_DecodeTimeChoice(&notAfterB, &val_b->notAfter) ) {
        return certValidityUndetermined;
    }

    /* sanity check */
    if (LL_CMP(notBeforeA,>,notAfterA) || LL_CMP(notBeforeB,>,notAfterB)) {
        PORT_SetError(SEC_ERROR_INVALID_TIME);
        return certValidityUndetermined;
    }

    if (LL_CMP(notAfterA,!=,notAfterB)) {
        /* one cert validity goes farther into the future, select it */
        return LL_CMP(notAfterA,<,notAfterB) ?
            certValidityChooseB : certValidityChooseA;
    }
    /* the two certs have the same expiration date */
    PORT_Assert(LL_CMP(notAfterA, == , notAfterB));
    /* do they also have the same start date ? */
    if (LL_CMP(notBeforeA,==,notBeforeB)) {
       return certValidityEqual;
    }
    /* choose cert with the later start date */
    return LL_CMP(notBeforeA,<,notBeforeB) ?
        certValidityChooseB : certValidityChooseA;
}

Here is the call graph for this function:

CERTCertificate* CERT_DecodeDERCertificate ( SECItem *  derSignedCert,
PRBool  copyDER,
char *  nickname 
)

Definition at line 818 of file certdb.c.

{
    CERTCertificate *cert;
    PRArenaPool *arena;
    void *data;
    int rv;
    int len;
    char *tmpname;
    
    /* make a new arena */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    
    if ( !arena ) {
       return 0;
    }

    /* allocate the certificate structure */
    cert = (CERTCertificate *)PORT_ArenaZAlloc(arena, sizeof(CERTCertificate));
    
    if ( !cert ) {
       goto loser;
    }
    
    cert->arena = arena;
    
    if ( copyDER ) {
       /* copy the DER data for the cert into this arena */
       data = (void *)PORT_ArenaAlloc(arena, derSignedCert->len);
       if ( !data ) {
           goto loser;
       }
       cert->derCert.data = (unsigned char *)data;
       cert->derCert.len = derSignedCert->len;
       PORT_Memcpy(data, derSignedCert->data, derSignedCert->len);
    } else {
       /* point to passed in DER data */
       cert->derCert = *derSignedCert;
    }

    /* decode the certificate info */
    rv = SEC_QuickDERDecodeItem(arena, cert, SEC_SignedCertificateTemplate,
                  &cert->derCert);

    if ( rv ) {
       goto loser;
    }

    if (cert_HasUnknownCriticalExten (cert->extensions) == PR_TRUE) {
        cert->options.bits.hasUnsupportedCriticalExt = PR_TRUE;
    }

    /* generate and save the database key for the cert */
    rv = CERT_KeyFromIssuerAndSN(arena, &cert->derIssuer, &cert->serialNumber,
                     &cert->certKey);
    if ( rv ) {
       goto loser;
    }

    /* set the nickname */
    if ( nickname == NULL ) {
       cert->nickname = NULL;
    } else {
       /* copy and install the nickname */
       len = PORT_Strlen(nickname) + 1;
       cert->nickname = (char*)PORT_ArenaAlloc(arena, len);
       if ( cert->nickname == NULL ) {
           goto loser;
       }

       PORT_Memcpy(cert->nickname, nickname, len);
    }

    /* set the email address */
    cert->emailAddr = cert_GetCertificateEmailAddresses(cert);
    
    /* initialize the subjectKeyID */
    rv = cert_GetKeyID(cert);
    if ( rv != SECSuccess ) {
       goto loser;
    }

    /* initialize keyUsage */
    rv = GetKeyUsage(cert);
    if ( rv != SECSuccess ) {
       goto loser;
    }

    /* initialize the certType */
    rv = cert_GetCertType(cert);
    if ( rv != SECSuccess ) {
       goto loser;
    }

    /* determine if this is a root cert */
    cert->isRoot = cert_IsRootCert(cert);

    tmpname = CERT_NameToAscii(&cert->subject);
    if ( tmpname != NULL ) {
       cert->subjectName = PORT_ArenaStrdup(cert->arena, tmpname);
       PORT_Free(tmpname);
    }
    
    tmpname = CERT_NameToAscii(&cert->issuer);
    if ( tmpname != NULL ) {
       cert->issuerName = PORT_ArenaStrdup(cert->arena, tmpname);
       PORT_Free(tmpname);
    }
    
    cert->referenceCount = 1;
    cert->slot = NULL;
    cert->pkcs11ID = CK_INVALID_HANDLE;
    cert->dbnickname = NULL;
    
    return(cert);
    
loser:

    if ( arena ) {
       PORT_FreeArena(arena, PR_FALSE);
    }
    
    return(0);
}

Here is the call graph for this function:

SECStatus CERT_DecodeTrustString ( CERTCertTrust *  trust,
char *  trusts 
)

Definition at line 2060 of file certdb.c.

{
    unsigned int i;
    unsigned int *pflags;
    
    if (!trust) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }
    trust->sslFlags = 0;
    trust->emailFlags = 0;
    trust->objectSigningFlags = 0;
    if (!trusts) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    pflags = &trust->sslFlags;
    
    for (i=0; i < PORT_Strlen(trusts); i++) {
       switch (trusts[i]) {
         case 'p':
             *pflags = *pflags | CERTDB_VALID_PEER;
             break;

         case 'P':
             *pflags = *pflags | CERTDB_TRUSTED | CERTDB_VALID_PEER;
             break;

         case 'w':
             *pflags = *pflags | CERTDB_SEND_WARN;
             break;

         case 'c':
             *pflags = *pflags | CERTDB_VALID_CA;
             break;

         case 'T':
             *pflags = *pflags | CERTDB_TRUSTED_CLIENT_CA | CERTDB_VALID_CA;
             break;

         case 'C' :
             *pflags = *pflags | CERTDB_TRUSTED_CA | CERTDB_VALID_CA;
             break;

         case 'u':
             *pflags = *pflags | CERTDB_USER;
             break;

         case 'i':
             *pflags = *pflags | CERTDB_INVISIBLE_CA;
             break;
         case 'g':
             *pflags = *pflags | CERTDB_GOVT_APPROVED_CA;
             break;

         case ',':
             if ( pflags == &trust->sslFlags ) {
                pflags = &trust->emailFlags;
             } else {
                pflags = &trust->objectSigningFlags;
             }
             break;
         default:
             return SECFailure;
       }
    }

    return SECSuccess;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CERT_DestroyCertArray ( CERTCertificate **  certs,
unsigned int  ncerts 
)

Definition at line 2014 of file certdb.c.

{
    unsigned int i;
    
    if ( certs ) {
       for ( i = 0; i < ncerts; i++ ) {
           if ( certs[i] ) {
              CERT_DestroyCertificate(certs[i]);
           }
       }

       PORT_Free(certs);
    }
    
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CERT_DestroyCertList ( CERTCertList *  certs)

Definition at line 2414 of file certdb.c.

{
    PRCList *node;

    while( !PR_CLIST_IS_EMPTY(&certs->list) ) {
       node = PR_LIST_HEAD(&certs->list);
       CERT_DestroyCertificate(((CERTCertListNode *)node)->cert);
       PR_REMOVE_LINK(node);
    }
    
    PORT_FreeArena(certs->arena, PR_FALSE);
    
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CERT_DestroyCrl ( CERTSignedCrl *  crl)

Definition at line 1802 of file certdb.c.

{
    SEC_DestroyCrl (crl);
}

Here is the call graph for this function:

Definition at line 2939 of file certdb.c.

Here is the call graph for this function:

CERTCertificate* CERT_DupCertificate ( CERTCertificate *  c)

Definition at line 1282 of file certdb.c.

{
    if (c) {
#ifdef NSS_CLASSIC
       CERT_LockCertRefCount(c);
       ++c->referenceCount;
       CERT_UnlockCertRefCount(c);
#else
       NSSCertificate *tmp = STAN_GetNSSCertificate(c);
       nssCertificate_AddRef(tmp);
#endif
    }
    return c;
}

Here is the call graph for this function:

char* CERT_EncodeTrustString ( CERTCertTrust *  trust)

Definition at line 2159 of file certdb.c.

{
    char tmpTrustSSL[32];
    char tmpTrustEmail[32];
    char tmpTrustSigning[32];
    char *retstr = NULL;

    if ( trust ) {
       tmpTrustSSL[0] = '\0';
       tmpTrustEmail[0] = '\0';
       tmpTrustSigning[0] = '\0';
    
       EncodeFlags(tmpTrustSSL, trust->sslFlags);
       EncodeFlags(tmpTrustEmail, trust->emailFlags);
       EncodeFlags(tmpTrustSigning, trust->objectSigningFlags);
    
       retstr = PR_smprintf("%s,%s,%s", tmpTrustSSL, tmpTrustEmail,
                          tmpTrustSigning);
    }
    
    return(retstr);
}

Here is the call graph for this function:

SECStatus CERT_FilterCertListByUsage ( CERTCertList *  certList,
SECCertUsage  usage,
PRBool  ca 
)

Definition at line 2633 of file certdb.c.

{
    unsigned int requiredKeyUsage;
    unsigned int requiredCertType;
    CERTCertListNode *node, *savenode;
    SECStatus rv;
    
    if (certList == NULL) goto loser;

    rv = CERT_KeyUsageAndTypeForCertUsage(usage, ca, &requiredKeyUsage,
                                     &requiredCertType);
    if ( rv != SECSuccess ) {
       goto loser;
    }

    node = CERT_LIST_HEAD(certList);
       
    while ( !CERT_LIST_END(node, certList) ) {

       PRBool bad = (PRBool)(!node->cert);

       /* bad key usage ? */
       if ( !bad && 
            CERT_CheckKeyUsage(node->cert, requiredKeyUsage) != SECSuccess ) {
           bad = PR_TRUE;
       }
       /* bad cert type ? */
       if ( !bad ) {
           unsigned int certType = 0;
           if ( ca ) {
              /* This function returns a more comprehensive cert type that
               * takes trust flags into consideration.  Should probably
               * fix the cert decoding code to do this.
               */
              (void)CERT_IsCACert(node->cert, &certType);
           } else {
              certType = node->cert->nsCertType;
           }
           if ( !( certType & requiredCertType ) ) {
              bad = PR_TRUE;
           }
       }

       if ( bad ) {
           /* remove the node if it is bad */
           savenode = CERT_LIST_NEXT(node);
           CERT_RemoveCertListNode(node);
           node = savenode;
       } else {
           node = CERT_LIST_NEXT(node);
       }
    }
    return(SECSuccess);
    
loser:
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_FilterCertListForUserCerts ( CERTCertList *  certList)

Definition at line 2705 of file certdb.c.

{
    CERTCertListNode *node, *freenode;
    CERTCertificate *cert;

    if (!certList) {
        return SECFailure;
    }

    node = CERT_LIST_HEAD(certList);
    
    while ( ! CERT_LIST_END(node, certList) ) {
       cert = node->cert;
       if ( PR_TRUE != CERT_IsUserCert(cert) ) {
           /* Not a User Cert, so remove this cert from the list */
           freenode = node;
           node = CERT_LIST_NEXT(node);
           CERT_RemoveCertListNode(freenode);
       } else {
           /* Is a User cert, so leave it in the list */
           node = CERT_LIST_NEXT(node);
       }
    }

    return(SECSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CERTCertificate* CERT_FindCertBySubjectKeyID ( CERTCertDBHandle *  handle,
SECItem *  subjKeyID 
)

Definition at line 2970 of file certdb.c.

{
    CERTCertificate *cert = NULL;
    SECItem *derCert;

    derCert = cert_FindDERCertBySubjectKeyID(subjKeyID);
    if (derCert) {
        cert = CERT_FindCertByDERCert(handle, derCert);
        SECITEM_FreeItem(derCert, PR_TRUE);
    }
    return cert;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECItem* cert_FindDERCertBySubjectKeyID ( SECItem *  subjKeyID)

Definition at line 2953 of file certdb.c.

{
    SECItem   *val;
 
    if (!gSubjKeyIDLock)
        return NULL;

    PR_Lock(gSubjKeyIDLock);
    val = (SECItem*)PL_HashTableLookup(gSubjKeyIDHash, subjKeyID);
    if (val) {
        val = SECITEM_DupItem(val);
    }
    PR_Unlock(gSubjKeyIDLock);
    return val;
}

Here is the call graph for this function:

char* CERT_FixupEmailAddr ( char *  emailAddr)

Definition at line 2032 of file certdb.c.

{
    char *retaddr;
    char *str;

    if ( emailAddr == NULL ) {
       return(NULL);
    }
    
    /* copy the string */
    str = retaddr = PORT_Strdup(emailAddr);
    if ( str == NULL ) {
       return(NULL);
    }
    
    /* make it lower case */
    while ( *str ) {
       *str = tolower( *str );
       str++;
    }
    
    return(retaddr);
}

Here is the call graph for this function:

Here is the caller graph for this function:

static void cert_FreeEntry ( void pool,
PLHashEntry he,
PRUintn  flag 
) [static]

Definition at line 2849 of file certdb.c.

{
    SECITEM_FreeItem((SECItem*)(he->value), PR_TRUE);
    if (flag == HT_FREE_ENTRY) {
        SECITEM_FreeItem((SECItem*)(he->key), PR_TRUE);
        PORT_Free(he);
    }
}

Here is the call graph for this function:

static void cert_FreeTable ( void pool,
void item 
) [static]

Definition at line 2839 of file certdb.c.

{
    PORT_Free(item);
}

Here is the call graph for this function:

CERTIssuerAndSN* CERT_GetCertIssuerAndSN ( PRArenaPool arena,
CERTCertificate *  cert 
)

Definition at line 1676 of file certdb.c.

{
    CERTIssuerAndSN *result;
    SECStatus rv;

    if ( arena == NULL ) {
       arena = cert->arena;
    }
    
    result = (CERTIssuerAndSN*)PORT_ArenaZAlloc(arena, sizeof(*result));
    if (result == NULL) {
       PORT_SetError (SEC_ERROR_NO_MEMORY);
       return NULL;
    }

    rv = SECITEM_CopyItem(arena, &result->derIssuer, &cert->derIssuer);
    if (rv != SECSuccess)
       return NULL;

    rv = CERT_CopyName(arena, &result->issuer, &cert->issuer);
    if (rv != SECSuccess)
       return NULL;

    rv = SECITEM_CopyItem(arena, &result->serialNumber, &cert->serialNumber);
    if (rv != SECSuccess)
       return NULL;

    return result;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_GetCertTimes ( CERTCertificate *  c,
PRTime notBefore,
PRTime notAfter 
)

Definition at line 976 of file certdb.c.

{
    SECStatus rv;

    if (!c || !notBefore || !notAfter) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return SECFailure;
    }
    
    /* convert DER not-before time */
    rv = DER_DecodeTimeChoice(notBefore, &c->validity.notBefore);
    if (rv) {
       return(SECFailure);
    }
    
    /* convert DER not-after time */
    rv = DER_DecodeTimeChoice(notAfter, &c->validity.notAfter);
    if (rv) {
       return(SECFailure);
    }

    return(SECSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus cert_GetCertType ( CERTCertificate *  cert)

Definition at line 531 of file certdb.c.

{
    SECStatus rv;
    SECItem tmpitem;
    SECItem encodedExtKeyUsage;
    CERTOidSequence *extKeyUsage = NULL;
    PRBool basicConstraintPresent = PR_FALSE;
    CERTBasicConstraints basicConstraint;
    unsigned int nsCertType = 0;

    if (cert->nsCertType) {
        /* once set, no need to recalculate */
        return SECSuccess;
    }

    tmpitem.data = NULL;
    CERT_FindNSCertTypeExtension(cert, &tmpitem);
    encodedExtKeyUsage.data = NULL;
    rv = CERT_FindCertExtension(cert, SEC_OID_X509_EXT_KEY_USAGE, 
                            &encodedExtKeyUsage);
    if (rv == SECSuccess) {
       extKeyUsage = CERT_DecodeOidSequence(&encodedExtKeyUsage);
    }
    rv = CERT_FindBasicConstraintExten(cert, &basicConstraint);
    if (rv == SECSuccess) {
       basicConstraintPresent = PR_TRUE;
    }
    if (tmpitem.data != NULL || extKeyUsage != NULL) {
       if (tmpitem.data == NULL) {
           nsCertType = 0;
       } else {
           nsCertType = tmpitem.data[0];
       }

       /* free tmpitem data pointer to avoid memory leak */
       PORT_Free(tmpitem.data);
       tmpitem.data = NULL;
       
       /*
        * for this release, we will allow SSL certs with an email address
        * to be used for email
        */
       if ( ( nsCertType & NS_CERT_TYPE_SSL_CLIENT ) &&
           cert->emailAddr && cert->emailAddr[0]) {
           nsCertType |= NS_CERT_TYPE_EMAIL;
       }
       /*
        * for this release, we will allow SSL intermediate CAs to be
        * email intermediate CAs too.
        */
       if ( nsCertType & NS_CERT_TYPE_SSL_CA ) {
           nsCertType |= NS_CERT_TYPE_EMAIL_CA;
       }
       /*
        * allow a cert with the extended key usage of EMail Protect
        * to be used for email or as an email CA, if basic constraints
        * indicates that it is a CA.
        */
       if (findOIDinOIDSeqByTagNum(extKeyUsage, 
                                SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT) ==
           SECSuccess) {
           if (basicConstraintPresent == PR_TRUE &&
              (basicConstraint.isCA)) {
              nsCertType |= NS_CERT_TYPE_EMAIL_CA;
           } else {
              nsCertType |= NS_CERT_TYPE_EMAIL;
           }
       }
       if (findOIDinOIDSeqByTagNum(extKeyUsage, 
                                SEC_OID_EXT_KEY_USAGE_SERVER_AUTH) ==
           SECSuccess){
           if (basicConstraintPresent == PR_TRUE &&
              (basicConstraint.isCA)) {
              nsCertType |= NS_CERT_TYPE_SSL_CA;
           } else {
              nsCertType |= NS_CERT_TYPE_SSL_SERVER;
           }
       }
       /* Treat certs with step-up OID as also having SSL server type. */
       if (findOIDinOIDSeqByTagNum(extKeyUsage, 
                                SEC_OID_NS_KEY_USAGE_GOVT_APPROVED) ==
           SECSuccess){
           if (basicConstraintPresent == PR_TRUE &&
              (basicConstraint.isCA)) {
              nsCertType |= NS_CERT_TYPE_SSL_CA;
           } else {
              nsCertType |= NS_CERT_TYPE_SSL_SERVER;
           }
       }
       if (findOIDinOIDSeqByTagNum(extKeyUsage,
                                SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH) ==
           SECSuccess){
           if (basicConstraintPresent == PR_TRUE &&
              (basicConstraint.isCA)) {
              nsCertType |= NS_CERT_TYPE_SSL_CA;
           } else {
              nsCertType |= NS_CERT_TYPE_SSL_CLIENT;
           }
       }
       if (findOIDinOIDSeqByTagNum(extKeyUsage,
                                SEC_OID_EXT_KEY_USAGE_CODE_SIGN) ==
           SECSuccess) {
           if (basicConstraintPresent == PR_TRUE &&
              (basicConstraint.isCA)) {
              nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
           } else {
              nsCertType |= NS_CERT_TYPE_OBJECT_SIGNING;
           }
       }
       if (findOIDinOIDSeqByTagNum(extKeyUsage,
                                SEC_OID_EXT_KEY_USAGE_TIME_STAMP) ==
           SECSuccess) {
           nsCertType |= EXT_KEY_USAGE_TIME_STAMP;
       }
       if (findOIDinOIDSeqByTagNum(extKeyUsage,
                                SEC_OID_OCSP_RESPONDER) == 
           SECSuccess) {
           nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
       }
    } else {
       /* if no extension, then allow any ssl or email (no ca or object
        * signing)
        */
       nsCertType = NS_CERT_TYPE_SSL_CLIENT | NS_CERT_TYPE_SSL_SERVER |
           NS_CERT_TYPE_EMAIL;

       /* if the basic constraint extension says the cert is a CA, then
          allow SSL CA and EMAIL CA and Status Responder */
       if ((basicConstraintPresent == PR_TRUE)
           && (basicConstraint.isCA)) {
              nsCertType |= NS_CERT_TYPE_SSL_CA;
              nsCertType |= NS_CERT_TYPE_EMAIL_CA;
              nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
       } else if (CERT_IsCACert(cert, NULL) == PR_TRUE) {
              nsCertType |= EXT_KEY_USAGE_STATUS_RESPONDER;
       }

       /* if the cert is a fortezza CA cert, then allow SSL CA and EMAIL CA */
       if (fortezzaIsCA(cert)) {
              nsCertType |= NS_CERT_TYPE_SSL_CA;
              nsCertType |= NS_CERT_TYPE_EMAIL_CA;
       }
    }

    if (encodedExtKeyUsage.data != NULL) {
       PORT_Free(encodedExtKeyUsage.data);
    }
    if (extKeyUsage != NULL) {
       CERT_DestroyOidSequence(extKeyUsage);
    }
    /* Assert that it is safe to cast &cert->nsCertType to "PRInt32 *" */
    PORT_Assert(sizeof(cert->nsCertType) == sizeof(PRInt32));
    PR_AtomicSet((PRInt32 *)&cert->nsCertType, nsCertType);
    return(SECSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CERTCertDBHandle* CERT_GetDefaultCertDB ( void  )

Definition at line 1312 of file certdb.c.

SECStatus cert_GetKeyID ( CERTCertificate *  cert)

Definition at line 691 of file certdb.c.

{
    SECItem tmpitem;
    SECStatus rv;
    SECKEYPublicKey *key;
    
    cert->subjectKeyID.len = 0;

    /* see of the cert has a key identifier extension */
    rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem);
    if ( rv == SECSuccess ) {
       cert->subjectKeyID.data = (unsigned char*) PORT_ArenaAlloc(cert->arena, tmpitem.len);
       if ( cert->subjectKeyID.data != NULL ) {
           PORT_Memcpy(cert->subjectKeyID.data, tmpitem.data, tmpitem.len);
           cert->subjectKeyID.len = tmpitem.len;
           cert->keyIDGenerated = PR_FALSE;
       }
       
       PORT_Free(tmpitem.data);
    }
    
    /* if the cert doesn't have a key identifier extension and the cert is
     * a V1 fortezza certificate, use the cert's 8 byte KMID as the
     * key identifier.  */
    key = CERT_KMIDPublicKey(cert);

    if (key != NULL) {
       
       if (key->keyType == fortezzaKey) {

           cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, 8);
           if ( cert->subjectKeyID.data != NULL ) {
              PORT_Memcpy(cert->subjectKeyID.data, key->u.fortezza.KMID, 8);
              cert->subjectKeyID.len = 8;
              cert->keyIDGenerated = PR_FALSE;
           }
       }
              
       SECKEY_DestroyPublicKey(key);
    }

    /* if the cert doesn't have a key identifier extension, then generate one*/
    if ( cert->subjectKeyID.len == 0 ) {
       /*
        * pkix says that if the subjectKeyID is not present, then we should
        * use the SHA-1 hash of the DER-encoded publicKeyInfo from the cert
        */
       cert->subjectKeyID.data = (unsigned char *)PORT_ArenaAlloc(cert->arena, SHA1_LENGTH);
       if ( cert->subjectKeyID.data != NULL ) {
           rv = PK11_HashBuf(SEC_OID_SHA1,cert->subjectKeyID.data,
                           cert->derPublicKey.data,
                           cert->derPublicKey.len);
           if ( rv == SECSuccess ) {
              cert->subjectKeyID.len = SHA1_LENGTH;
           }
       }
    }

    if ( cert->subjectKeyID.len == 0 ) {
       return(SECFailure);
    }
    return(SECSuccess);

}

Here is the call graph for this function:

Definition at line 961 of file certdb.c.

{
    return pendingSlop;                   /* seconds */
}
CERTStatusConfig* CERT_GetStatusConfig ( CERTCertDBHandle *  handle)

Definition at line 2811 of file certdb.c.

{
  return handle->statusConfig;
}

Here is the caller graph for this function:

SECStatus CERT_ImportCerts ( CERTCertDBHandle *  certdb,
SECCertUsage  usage,
unsigned int  ncerts,
SECItem **  derCerts,
CERTCertificate ***  retCerts,
PRBool  keepCerts,
PRBool  caOnly,
char *  nickname 
)

Definition at line 2304 of file certdb.c.

{
    unsigned int i;
    CERTCertificate **certs = NULL;
    SECStatus rv;
    unsigned int fcerts = 0;

    if ( ncerts ) {
       certs = PORT_ZNewArray(CERTCertificate*, ncerts);
       if ( certs == NULL ) {
           return(SECFailure);
       }
    
       /* decode all of the certs into the temporary DB */
       for ( i = 0, fcerts= 0; i < ncerts; i++) {
           certs[fcerts] = CERT_NewTempCertificate(certdb,
                                                   derCerts[i],
                                                   NULL,
                                                   PR_FALSE,
                                                   PR_TRUE);
           if (certs[fcerts]) fcerts++;
       }

       if ( keepCerts ) {
           for ( i = 0; i < fcerts; i++ ) {
                char* canickname = NULL;
                PRBool freeNickname = PR_FALSE;

              SECKEY_UpdateCertPQG(certs[i]);
                
                if ( CERT_IsCACert(certs[i], NULL) ) {
                    canickname = CERT_MakeCANickname(certs[i]);
                    if ( canickname != NULL ) {
                        freeNickname = PR_TRUE;
                    }
                }

              if(CERT_IsCACert(certs[i], NULL) && (fcerts > 1)) {
                  /* if we are importing only a single cert and specifying
                   * a nickname, we want to use that nickname if it a CA,
                   * otherwise if there are more than one cert, we don't
                   * know which cert it belongs to. But we still may try
                     * the individual canickname from the cert itself.
                   */
                  rv = CERT_AddTempCertToPerm(certs[i], canickname, NULL);
              } else {
                  rv = CERT_AddTempCertToPerm(certs[i],
                                                nickname?nickname:canickname, NULL);
              }
              if (rv == SECSuccess) {
                  CERT_SaveImportedCert(certs[i], usage, caOnly, NULL);
              }

                if (PR_TRUE == freeNickname) {
                    PORT_Free(canickname);
                }
              /* don't care if it fails - keep going */
           }
       }
    }

    if ( retCerts ) {
       *retCerts = certs;
    } else {
       if (certs) {
           CERT_DestroyCertArray(certs, fcerts);
       }
    }

    return ((fcerts || !ncerts) ? SECSuccess : SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_IsCACert ( CERTCertificate *  cert,
unsigned int rettype 
)

Definition at line 1814 of file certdb.c.

{
    CERTCertTrust *trust;
    SECStatus rv;
    unsigned int type;
    PRBool ret;

    ret = PR_FALSE;
    type = 0;

    if ( cert->trust && (cert->trust->sslFlags|cert->trust->emailFlags|
                            cert->trust->objectSigningFlags)) {
       trust = cert->trust;
       if ( ( ( trust->sslFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) ||
          ( ( trust->sslFlags & CERTDB_TRUSTED_CA ) == CERTDB_TRUSTED_CA ) ) {
           ret = PR_TRUE;
           type |= NS_CERT_TYPE_SSL_CA;
       }
       
       if ( ( ( trust->emailFlags & CERTDB_VALID_CA ) == CERTDB_VALID_CA ) ||
         ( ( trust->emailFlags & CERTDB_TRUSTED_CA ) == CERTDB_TRUSTED_CA ) ) {
           ret = PR_TRUE;
           type |= NS_CERT_TYPE_EMAIL_CA;
       }
       
       if ( ( ( trust->objectSigningFlags & CERTDB_VALID_CA ) 
                                          == CERTDB_VALID_CA ) ||
          ( ( trust->objectSigningFlags & CERTDB_TRUSTED_CA ) 
                                          == CERTDB_TRUSTED_CA ) ) {
           ret = PR_TRUE;
           type |= NS_CERT_TYPE_OBJECT_SIGNING_CA;
       }
    } else {
       if ( cert->nsCertType &
           ( NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA |
            NS_CERT_TYPE_OBJECT_SIGNING_CA ) ) {
           ret = PR_TRUE;
           type = (cert->nsCertType & NS_CERT_TYPE_CA);
       } else {
           CERTBasicConstraints constraints;
           rv = CERT_FindBasicConstraintExten(cert, &constraints);
           if ( rv == SECSuccess ) {
              if ( constraints.isCA ) {
                  ret = PR_TRUE;
                  type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
              }
           } 
       } 

       /* finally check if it's a FORTEZZA V1 CA */
       if (ret == PR_FALSE) {
           if (fortezzaIsCA(cert)) {
              ret = PR_TRUE;
              type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
           }
       }
    }

    /* the isRoot flag trumps all */
    if (cert->isRoot) {
       ret = PR_TRUE;
       /* set only these by default, same as above */
       type = (NS_CERT_TYPE_SSL_CA | NS_CERT_TYPE_EMAIL_CA);
    }

    if ( rettype != NULL ) {
       *rettype = type;
    }
    
    return(ret);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_IsCADERCert ( SECItem *  derCert,
unsigned int type 
)

Definition at line 1887 of file certdb.c.

                                                       {
    CERTCertificate *cert;
    PRBool isCA;

    /* This is okay -- only looks at extensions */
    cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
    if (cert == NULL) return PR_FALSE;

    isCA = CERT_IsCACert(cert,type);
    CERT_DestroyCertificate (cert);
    return isCA;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_IsNewer ( CERTCertificate *  certa,
CERTCertificate *  certb 
)

Definition at line 1959 of file certdb.c.

{
    PRTime notBeforeA, notAfterA, notBeforeB, notAfterB, now;
    SECStatus rv;
    PRBool newerbefore, newerafter;
    
    rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
    if ( rv != SECSuccess ) {
       return(PR_FALSE);
    }
    
    rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
    if ( rv != SECSuccess ) {
       return(PR_TRUE);
    }

    newerbefore = PR_FALSE;
    if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
       newerbefore = PR_TRUE;
    }

    newerafter = PR_FALSE;
    if ( LL_CMP(notAfterA, >, notAfterB) ) {
       newerafter = PR_TRUE;
    }
    
    if ( newerbefore && newerafter ) {
       return(PR_TRUE);
    }
    
    if ( ( !newerbefore ) && ( !newerafter ) ) {
       return(PR_FALSE);
    }

    /* get current time */
    now = PR_Now();

    if ( newerbefore ) {
       /* cert A was issued after cert B, but expires sooner */
       /* if A is expired, then pick B */
       if ( LL_CMP(notAfterA, <, now ) ) {
           return(PR_FALSE);
       }
       return(PR_TRUE);
    } else {
       /* cert B was issued after cert A, but expires sooner */
       /* if B is expired, then pick A */
       if ( LL_CMP(notAfterB, <, now ) ) {
           return(PR_TRUE);
       }
       return(PR_FALSE);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool cert_IsRootCert ( CERTCertificate *  cert) [static]

Definition at line 757 of file certdb.c.

{
    SECStatus rv;
    SECItem tmpitem;

    /* cache the authKeyID extension, if present */
    cert->authKeyID = CERT_FindAuthKeyIDExten(cert->arena, cert);

    /* it MUST be self-issued to be a root */
    if (cert->derIssuer.len == 0 ||
        !SECITEM_ItemsAreEqual(&cert->derIssuer, &cert->derSubject))
    {
       return PR_FALSE;
    }

    /* check the authKeyID extension */
    if (cert->authKeyID) {
       /* authority key identifier is present */
       if (cert->authKeyID->keyID.len > 0) {
           /* the keyIdentifier field is set, look for subjectKeyID */
           rv = CERT_FindSubjectKeyIDExtension(cert, &tmpitem);
           if (rv == SECSuccess) {
              PRBool match;
              /* also present, they MUST match for it to be a root */
              match = SECITEM_ItemsAreEqual(&cert->authKeyID->keyID,
                                            &tmpitem);
              PORT_Free(tmpitem.data);
              if (!match) return PR_FALSE; /* else fall through */
           } else {
              /* the subject key ID is required when AKI is present */
              return PR_FALSE;
           }
       }
       if (cert->authKeyID->authCertIssuer) {
           SECItem *caName;
           caName = (SECItem *)CERT_GetGeneralNameByType(
                                         cert->authKeyID->authCertIssuer,
                                         certDirectoryName, PR_TRUE);
           if (caName) {
              if (!SECITEM_ItemsAreEqual(&cert->derIssuer, caName)) {
                  return PR_FALSE;
              } /* else fall through */
           } /* else ??? could not get general name as directory name? */
       }
       if (cert->authKeyID->authCertSerialNumber.len > 0) {
           if (!SECITEM_ItemsAreEqual(&cert->serialNumber,
                                &cert->authKeyID->authCertSerialNumber)) {
              return PR_FALSE;
           } /* else fall through */
       }
       /* all of the AKI fields that were present passed the test */
       return PR_TRUE;
    }
    /* else the AKI was not present, so this is a root */
    return PR_TRUE;
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_IsRootDERCert ( SECItem *  derCert)

Definition at line 1901 of file certdb.c.

{
    CERTCertificate *cert;
    PRBool isRoot;

    /* This is okay -- only looks at extensions */
    cert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
    if (cert == NULL) return PR_FALSE;

    isRoot = cert->isRoot;
    CERT_DestroyCertificate (cert);
    return isRoot;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_IssuerNameFromDERCert ( SECItem *  derCert,
SECItem *  derName 
)

Definition at line 301 of file certdb.c.

{
    int rv;
    PRArenaPool *arena;
    CERTSignedData sd;
    void *tmpptr;
    
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    
    if ( ! arena ) {
       return(SECFailure);
    }
   
    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
    
    if ( rv ) {
       goto loser;
    }
    
    PORT_Memset(derName, 0, sizeof(SECItem));
    rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertIssuerTemplate, &sd.data);

    if ( rv ) {
       goto loser;
    }

    tmpptr = derName->data;
    derName->data = (unsigned char*)PORT_Alloc(derName->len);
    if ( derName->data == NULL ) {
       goto loser;
    }
    
    PORT_Memcpy(derName->data, tmpptr, derName->len);
    
    PORT_FreeArena(arena, PR_FALSE);
    return(SECSuccess);

loser:
    PORT_FreeArena(arena, PR_FALSE);
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

PRBool CERT_IsUserCert ( CERTCertificate *  cert)

Definition at line 2692 of file certdb.c.

{
    if ( cert->trust &&
        ((cert->trust->sslFlags & CERTDB_USER ) ||
         (cert->trust->emailFlags & CERTDB_USER ) ||
         (cert->trust->objectSigningFlags & CERTDB_USER )) ) {
        return PR_TRUE;
    } else {
        return PR_FALSE;
    }
}

Here is the caller graph for this function:

SECStatus CERT_KeyFromDERCert ( PRArenaPool arena,
SECItem *  derCert,
SECItem *  key 
)

Definition at line 393 of file certdb.c.

{
    int rv;
    CERTSignedData sd;
    CERTCertKey certkey;

    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_ASN1DecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
    
    if ( rv ) {
       goto loser;
    }
    
    PORT_Memset(&certkey, 0, sizeof(CERTCertKey));
    rv = SEC_ASN1DecodeItem(arena, &certkey, CERT_CertKeyTemplate, &sd.data);

    if ( rv ) {
       goto loser;
    }

    return(CERT_KeyFromIssuerAndSN(arena, &certkey.derIssuer,
                               &certkey.serialNumber, key));
loser:
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_KeyFromIssuerAndSN ( PRArenaPool arena,
SECItem *  issuer,
SECItem *  sn,
SECItem *  key 
)

Definition at line 226 of file certdb.c.

{
    key->len = sn->len + issuer->len;

    if ((sn->data == NULL) || (issuer->data == NULL)) {
       goto loser;
    }
    
    key->data = (unsigned char*)PORT_ArenaAlloc(arena, key->len);
    if ( !key->data ) {
       goto loser;
    }

    /* copy the serialNumber */
    PORT_Memcpy(key->data, sn->data, sn->len);

    /* copy the issuer */
    PORT_Memcpy(&key->data[sn->len], issuer->data, issuer->len);

    return(SECSuccess);

loser:
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_KeyUsageAndTypeForCertUsage ( SECCertUsage  usage,
PRBool  ca,
unsigned int retKeyUsage,
unsigned int retCertType 
)

Definition at line 1124 of file certdb.c.

{
    unsigned int requiredKeyUsage = 0;
    unsigned int requiredCertType = 0;
    
    if ( ca ) {
       switch ( usage ) {
         case certUsageSSLServerWithStepUp:
           requiredKeyUsage = KU_NS_GOVT_APPROVED | KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_SSL_CA;
           break;
         case certUsageSSLClient:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_SSL_CA;
           break;
         case certUsageSSLServer:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_SSL_CA;
           break;
         case certUsageSSLCA:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_SSL_CA;
           break;
         case certUsageEmailSigner:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_EMAIL_CA;
           break;
         case certUsageEmailRecipient:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_EMAIL_CA;
           break;
         case certUsageObjectSigner:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA;
           break;
         case certUsageAnyCA:
         case certUsageVerifyCA:
         case certUsageStatusResponder:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING_CA |
              NS_CERT_TYPE_EMAIL_CA |
                  NS_CERT_TYPE_SSL_CA;
           break;
         default:
           PORT_Assert(0);
           goto loser;
       }
    } else {
       switch ( usage ) {
         case certUsageSSLClient:
           requiredKeyUsage = KU_DIGITAL_SIGNATURE;
           requiredCertType = NS_CERT_TYPE_SSL_CLIENT;
           break;
         case certUsageSSLServer:
           requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
           requiredCertType = NS_CERT_TYPE_SSL_SERVER;
           break;
         case certUsageSSLServerWithStepUp:
           requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT |
              KU_NS_GOVT_APPROVED;
           requiredCertType = NS_CERT_TYPE_SSL_SERVER;
           break;
         case certUsageSSLCA:
           requiredKeyUsage = KU_KEY_CERT_SIGN;
           requiredCertType = NS_CERT_TYPE_SSL_CA;
           break;
         case certUsageEmailSigner:
           requiredKeyUsage = KU_DIGITAL_SIGNATURE;
           requiredCertType = NS_CERT_TYPE_EMAIL;
           break;
         case certUsageEmailRecipient:
           requiredKeyUsage = KU_KEY_AGREEMENT_OR_ENCIPHERMENT;
           requiredCertType = NS_CERT_TYPE_EMAIL;
           break;
         case certUsageObjectSigner:
           requiredKeyUsage = KU_DIGITAL_SIGNATURE;
           requiredCertType = NS_CERT_TYPE_OBJECT_SIGNING;
           break;
         case certUsageStatusResponder:
           requiredKeyUsage = KU_DIGITAL_SIGNATURE;
           requiredCertType = EXT_KEY_USAGE_STATUS_RESPONDER;
           break;
         default:
           PORT_Assert(0);
           goto loser;
       }
    }

    if ( retKeyUsage != NULL ) {
       *retKeyUsage = requiredKeyUsage;
    }
    if ( retCertType != NULL ) {
       *retCertType = requiredCertType;
    }

    return(SECSuccess);
loser:
    return(SECFailure);
}

Here is the caller graph for this function:

void CERT_LockCertRefCount ( CERTCertificate *  cert)

Definition at line 2741 of file certdb.c.

Here is the caller graph for this function:

void CERT_LockCertTrust ( CERTCertificate *  cert)

Definition at line 2778 of file certdb.c.

Here is the caller graph for this function:

char* CERT_MakeCANickname ( CERTCertificate *  cert)

Definition at line 1707 of file certdb.c.

{
    char *firstname = NULL;
    char *org = NULL;
    char *nickname = NULL;
    int count;
    CERTCertificate *dummycert;
    CERTCertDBHandle *handle;
    
    handle = cert->dbhandle;
    
    nickname = CERT_GetNickName(cert, handle, cert->arena);
    if (nickname == NULL) {
       firstname = CERT_GetCommonName(&cert->subject);
       if ( firstname == NULL ) {
           firstname = CERT_GetOrgUnitName(&cert->subject);
       }

       org = CERT_GetOrgName(&cert->issuer);
       if (org == NULL) {
           org = CERT_GetDomainComponentName(&cert->issuer);
           if (org == NULL) {
              if (firstname) {
                  org = firstname;
                  firstname = NULL;
              } else {
                  org = PORT_Strdup("Unknown CA");
              }
           }
       }

       /* can only fail if PORT_Strdup fails, in which case
        * we're having memory problems. */
       if (org == NULL) {
           goto loser;
       }

    
       count = 1;
       while ( 1 ) {

           if ( firstname ) {
              if ( count == 1 ) {
                  nickname = PR_smprintf("%s - %s", firstname, org);
              } else {
                  nickname = PR_smprintf("%s - %s #%d", firstname, org, count);
              }
           } else {
              if ( count == 1 ) {
                  nickname = PR_smprintf("%s", org);
              } else {
                  nickname = PR_smprintf("%s #%d", org, count);
              }
           }
           if ( nickname == NULL ) {
              goto loser;
           }

           /* look up the nickname to make sure it isn't in use already */
           dummycert = CERT_FindCertByNickname(handle, nickname);

           if ( dummycert == NULL ) {
              goto done;
           }
       
           /* found a cert, destroy it and loop */
           CERT_DestroyCertificate(dummycert);

           /* free the nickname */
           PORT_Free(nickname);

           count++;
       }
    }
loser:
    if ( nickname ) {
       PORT_Free(nickname);
    }

    nickname = "";
    
done:
    if ( firstname ) {
       PORT_Free(firstname);
    }
    if ( org ) {
       PORT_Free(org);
    }
    
    return(nickname);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_NameFromDERCert ( SECItem *  derCert,
SECItem *  derName 
)

Definition at line 257 of file certdb.c.

{
    int rv;
    PRArenaPool *arena;
    CERTSignedData sd;
    void *tmpptr;
    
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    
    if ( ! arena ) {
       return(SECFailure);
    }
   
    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
    
    if ( rv ) {
       goto loser;
    }
    
    PORT_Memset(derName, 0, sizeof(SECItem));
    rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSubjectTemplate, &sd.data);

    if ( rv ) {
       goto loser;
    }

    tmpptr = derName->data;
    derName->data = (unsigned char*)PORT_Alloc(derName->len);
    if ( derName->data == NULL ) {
       goto loser;
    }
    
    PORT_Memcpy(derName->data, tmpptr, derName->len);
    
    PORT_FreeArena(arena, PR_FALSE);
    return(SECSuccess);

loser:
    PORT_FreeArena(arena, PR_FALSE);
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

CERTCertList* CERT_NewCertList ( void  )

Definition at line 2384 of file certdb.c.

{
    PRArenaPool *arena = NULL;
    CERTCertList *ret = NULL;
    
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if ( arena == NULL ) {
       goto loser;
    }
    
    ret = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
    if ( ret == NULL ) {
       goto loser;
    }
    
    ret->arena = arena;
    
    PR_INIT_CLIST(&ret->list);
    
    return(ret);

loser:
    if ( arena != NULL ) {
       PORT_FreeArena(arena, PR_FALSE);
    }
    
    return(NULL);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CERT_RemoveCertListNode ( CERTCertListNode *  node)

Definition at line 2430 of file certdb.c.

{
    CERT_DestroyCertificate(node->cert);
    PR_REMOVE_LINK(&node->links);
    return;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus cert_RemoveSubjectKeyIDMapping ( SECItem *  subjKeyID)

Definition at line 2925 of file certdb.c.

Here is the call graph for this function:

SECStatus CERT_SaveImportedCert ( CERTCertificate *  cert,
SECCertUsage  usage,
PRBool  caOnly,
char *  nickname 
)

Definition at line 2184 of file certdb.c.

{
    SECStatus rv;
    PRBool saveit;
    CERTCertTrust trust;
    PRBool isCA;
    unsigned int certtype;
    
    isCA = CERT_IsCACert(cert, NULL);
    if ( caOnly && ( !isCA ) ) {
       return(SECSuccess);
    }
    /* In NSS 3.4, certs are given zero trust upon import.  However, this
    * function needs to set up default CA trust (CERTDB_VALID_CA), or
    * PKCS#12 imported certs will not show up correctly.  In the case of a
    * CA cert with zero trust, continue with this function.  But if the cert
    * does already have some trust bits, exit and do not change them.
    */
    if (isCA && cert->trust && 
        (cert->trust->sslFlags |
         cert->trust->emailFlags |
         cert->trust->objectSigningFlags)) {
       return(SECSuccess);
    }

    saveit = PR_TRUE;
    
    PORT_Memset((void *)&trust, 0, sizeof(trust));

    certtype = cert->nsCertType;

    /* if no CA bits in cert type, then set all CA bits */
    if ( isCA && ( ! ( certtype & NS_CERT_TYPE_CA ) ) ) {
       certtype |= NS_CERT_TYPE_CA;
    }

    /* if no app bits in cert type, then set all app bits */
    if ( ( !isCA ) && ( ! ( certtype & NS_CERT_TYPE_APP ) ) ) {
       certtype |= NS_CERT_TYPE_APP;
    }

    switch ( usage ) {
      case certUsageEmailSigner:
      case certUsageEmailRecipient:
       if ( isCA ) {
           if ( certtype & NS_CERT_TYPE_EMAIL_CA ) {
              trust.emailFlags = CERTDB_VALID_CA;
           }
       } else {
           if ( !cert->emailAddr || !cert->emailAddr[0] ) {
              saveit = PR_FALSE;
           }
           
           if ( certtype & NS_CERT_TYPE_EMAIL ) {
              trust.emailFlags = CERTDB_VALID_PEER;
              if ( ! ( cert->rawKeyUsage & KU_KEY_ENCIPHERMENT ) ) {
                  /* don't save it if KeyEncipherment is not allowed */
                  saveit = PR_FALSE;
              }
           }
       }
       break;
      case certUsageUserCertImport:
       if ( isCA ) {
           if ( certtype & NS_CERT_TYPE_SSL_CA ) {
              trust.sslFlags = CERTDB_VALID_CA;
           }
           
           if ( certtype & NS_CERT_TYPE_EMAIL_CA ) {
              trust.emailFlags = CERTDB_VALID_CA;
           }
           
           if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA ) {
              trust.objectSigningFlags = CERTDB_VALID_CA;
           }
           
       } else {
           if ( certtype & NS_CERT_TYPE_SSL_CLIENT ) {
              trust.sslFlags = CERTDB_VALID_PEER;
           }
           
           if ( certtype & NS_CERT_TYPE_EMAIL ) {
              trust.emailFlags = CERTDB_VALID_PEER;
           }
           
           if ( certtype & NS_CERT_TYPE_OBJECT_SIGNING ) {
              trust.objectSigningFlags = CERTDB_VALID_PEER;
           }
       }
       break;
      case certUsageAnyCA:
       trust.sslFlags = CERTDB_VALID_CA;
       break;
      case certUsageSSLCA:
       trust.sslFlags = CERTDB_VALID_CA | 
                     CERTDB_TRUSTED_CA | CERTDB_TRUSTED_CLIENT_CA;
       break;
      default:       /* XXX added to quiet warnings; no other cases needed? */
       break;
    }

    if ( saveit ) {
       rv = CERT_ChangeCertTrust(cert->dbhandle, cert, &trust);
       if ( rv != SECSuccess ) {
           goto loser;
       }
    }

    rv = SECSuccess;
    goto done;

loser:
    rv = SECFailure;
done:

    return(rv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus CERT_SerialNumberFromDERCert ( SECItem *  derCert,
SECItem *  derName 
)

Definition at line 345 of file certdb.c.

{
    int rv;
    PRArenaPool *arena;
    CERTSignedData sd;
    void *tmpptr;
    
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    
    if ( ! arena ) {
       return(SECFailure);
    }
   
    PORT_Memset(&sd, 0, sizeof(CERTSignedData));
    rv = SEC_QuickDERDecodeItem(arena, &sd, CERT_SignedDataTemplate, derCert);
    
    if ( rv ) {
       goto loser;
    }
    
    PORT_Memset(derName, 0, sizeof(SECItem));
    rv = SEC_QuickDERDecodeItem(arena, derName, SEC_CertSerialNumberTemplate, &sd.data);

    if ( rv ) {
       goto loser;
    }

    tmpptr = derName->data;
    derName->data = (unsigned char*)PORT_Alloc(derName->len);
    if ( derName->data == NULL ) {
       goto loser;
    }
    
    PORT_Memcpy(derName->data, tmpptr, derName->len);
    
    PORT_FreeArena(arena, PR_FALSE);
    return(SECSuccess);

loser:
    PORT_FreeArena(arena, PR_FALSE);
    return(SECFailure);
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CERT_SetDefaultCertDB ( CERTCertDBHandle *  handle)

Definition at line 1304 of file certdb.c.

Here is the caller graph for this function:

Definition at line 967 of file certdb.c.

{
    if (slop < 0)
       return SECFailure;
    pendingSlop = slop;
    return SECSuccess;
}
void CERT_SetStatusConfig ( CERTCertDBHandle *  handle,
CERTStatusConfig *  statusConfig 
)

Definition at line 2821 of file certdb.c.

{
  PORT_Assert(handle->statusConfig == NULL);
  handle->statusConfig = statusConfig;
}

Here is the caller graph for this function:

PRBool CERT_SortCBValidity ( CERTCertificate *  certa,
CERTCertificate *  certb,
void arg 
)

Definition at line 2504 of file certdb.c.

{
    PRTime sorttime;
    PRTime notBeforeA, notAfterA, notBeforeB, notAfterB;
    SECStatus rv;
    PRBool newerbefore, newerafter;
    PRBool aNotValid = PR_FALSE, bNotValid = PR_FALSE;

    sorttime = *(PRTime *)arg;
    
    rv = CERT_GetCertTimes(certa, &notBeforeA, &notAfterA);
    if ( rv != SECSuccess ) {
       return(PR_FALSE);
    }
    
    rv = CERT_GetCertTimes(certb, &notBeforeB, &notAfterB);
    if ( rv != SECSuccess ) {
       return(PR_TRUE);
    }
    newerbefore = PR_FALSE;
    if ( LL_CMP(notBeforeA, >, notBeforeB) ) {
       newerbefore = PR_TRUE;
    }
    newerafter = PR_FALSE;
    if ( LL_CMP(notAfterA, >, notAfterB) ) {
       newerafter = PR_TRUE;
    }

    /* check if A is valid at sorttime */
    if ( CERT_CheckCertValidTimes(certa, sorttime, PR_FALSE)
       != secCertTimeValid ) {
       aNotValid = PR_TRUE;
    }

    /* check if B is valid at sorttime */
    if ( CERT_CheckCertValidTimes(certb, sorttime, PR_FALSE)
       != secCertTimeValid ) {
       bNotValid = PR_TRUE;
    }

    /* a is valid, b is not */
    if ( bNotValid && ( ! aNotValid ) ) {
       return(PR_TRUE);
    }

    /* b is valid, a is not */
    if ( aNotValid && ( ! bNotValid ) ) {
       return(PR_FALSE);
    }
    
    /* a and b are either valid or not valid */
    if ( newerbefore && newerafter ) {
       return(PR_TRUE);
    }
    
    if ( ( !newerbefore ) && ( !newerafter ) ) {
       return(PR_FALSE);
    }

    if ( newerbefore ) {
       /* cert A was issued after cert B, but expires sooner */
       return(PR_TRUE);
    } else {
       /* cert B was issued after cert A, but expires sooner */
       return(PR_FALSE);
    }
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus cert_TestHostName ( char *  cn,
const char *  hn 
) [static]

Definition at line 1368 of file certdb.c.

{
    int regvalid = PORT_RegExpValid(cn);
    if (regvalid != NON_SXP) {
       SECStatus rv;
       /* cn is a regular expression, try to match the shexp */
       int match = PORT_RegExpCaseSearch(hn, cn);

       if ( match == 0 ) {
           rv = SECSuccess;
       } else {
           PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
           rv = SECFailure;
       }
       return rv;
    } 
    /* cn is not a regular expression */

    /* compare entire hn with cert name */
    if (PORT_Strcasecmp(hn, cn) == 0) {
       return SECSuccess;
    }
           
    PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
    return SECFailure;
}

Here is the call graph for this function:

Here is the caller graph for this function:

void CERT_UnlockCertRefCount ( CERTCertificate *  cert)

Definition at line 2756 of file certdb.c.

Here is the caller graph for this function:

void CERT_UnlockCertTrust ( CERTCertificate *  cert)

Definition at line 2793 of file certdb.c.

{
    PRStatus prstat;

    PORT_Assert(certTrustLock != NULL);
    
    prstat = PZ_Unlock(certTrustLock);
    
    PORT_Assert(prstat == PR_SUCCESS);

    return;
}

Here is the caller graph for this function:

SECStatus CERT_VerifyCertName ( CERTCertificate *  cert,
const char *  hn 
)

Definition at line 1525 of file certdb.c.

{
    char *    cn;
    SECStatus rv;
    CERTOKDomainName *domainOK;

    if (!hn || !strlen(hn)) {
       PORT_SetError(SEC_ERROR_INVALID_ARGS);
       return SECFailure;
    }

    /* if the name is one that the user has already approved, it's OK. */
    for (domainOK = cert->domainOK; domainOK; domainOK = domainOK->next) {
       if (0 == PORT_Strcasecmp(hn, domainOK->name)) {
           return SECSuccess;
       }
    }

    /* Per RFC 2818, if the SubjectAltName extension is present, it must
    ** be used as the cert's identity.
    */
    rv = cert_VerifySubjectAltName(cert, hn);
    if (rv == SECSuccess || PORT_GetError() != SEC_ERROR_EXTENSION_NOT_FOUND)
       return rv;

    /* try the cert extension first, then the common name */
    cn = CERT_FindNSStringExtension(cert, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME);
    if ( !cn ) {
       cn = CERT_GetCommonName(&cert->subject);
    }
    if ( cn ) {
       rv = cert_TestHostName(cn, hn);
       PORT_Free(cn);
    } else 
       PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECStatus cert_VerifySubjectAltName ( CERTCertificate *  cert,
const char *  hn 
)

Definition at line 1397 of file certdb.c.

{
    PRArenaPool *     arena          = NULL;
    CERTGeneralName * nameList       = NULL;
    CERTGeneralName * current;
    char *            cn;
    int               cnBufLen;
    unsigned int      hnLen;
    int               DNSextCount    = 0;
    int               IPextCount     = 0;
    PRBool            isIPaddr;
    SECStatus         rv             = SECFailure;
    SECItem           subAltName;
    PRNetAddr         netAddr;
    char              cnbuf[128];

    subAltName.data = NULL;
    hnLen    = strlen(hn);
    cn       = cnbuf;
    cnBufLen = sizeof cnbuf;

    rv = CERT_FindCertExtension(cert, SEC_OID_X509_SUBJECT_ALT_NAME, 
                            &subAltName);
    if (rv != SECSuccess) {
       goto finish;
    }
    isIPaddr = (PR_SUCCESS == PR_StringToNetAddr(hn, &netAddr));
    rv = SECFailure;
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (!arena) 
       goto finish;

    nameList = current = CERT_DecodeAltNameExtension(arena, &subAltName);
    if (!current)
       goto finish;

    do {
       switch (current->type) {
       case certDNSName:
           if (!isIPaddr) {
              /* DNS name current->name.other.data is not null terminated.
              ** so must copy it.  
              */
              int cnLen = current->name.other.len;
              if (cnLen + 1 > cnBufLen) {
                  cnBufLen = cnLen + 1;
                  cn = (char *)PORT_ArenaAlloc(arena, cnBufLen);
                  if (!cn)
                     goto finish;
              }
              PORT_Memcpy(cn, current->name.other.data, cnLen);
              cn[cnLen] = 0;
              rv = cert_TestHostName(cn ,hn);
              if (rv == SECSuccess)
                  goto finish;
           }
           DNSextCount++;
           break;
       case certIPAddress:
           if (isIPaddr) {
              int match = 0;
              PRIPv6Addr v6Addr;
              if (current->name.other.len == 4 &&         /* IP v4 address */
                  netAddr.inet.family == PR_AF_INET) {
                  match = !memcmp(&netAddr.inet.ip, 
                                  current->name.other.data, 4);
              } else if (current->name.other.len == 16 && /* IP v6 address */
                  netAddr.ipv6.family == PR_AF_INET6) {
                  match = !memcmp(&netAddr.ipv6.ip,
                                   current->name.other.data, 16);
              } else if (current->name.other.len == 16 && /* IP v6 address */
                  netAddr.inet.family == PR_AF_INET) {
                  /* convert netAddr to ipv6, then compare. */
                  /* ipv4 must be in Network Byte Order on input. */
                  PR_ConvertIPv4AddrToIPv6(netAddr.inet.ip, &v6Addr);
                  match = !memcmp(&v6Addr, current->name.other.data, 16);
              } else if (current->name.other.len == 4 &&  /* IP v4 address */
                  netAddr.inet.family == PR_AF_INET6) {
                  /* convert netAddr to ipv6, then compare. */
                  PRUint32 ipv4 = (current->name.other.data[0] << 24) |
                                  (current->name.other.data[1] << 16) |
                                (current->name.other.data[2] <<  8) |
                                 current->name.other.data[3];
                  /* ipv4 must be in Network Byte Order on input. */
                  PR_ConvertIPv4AddrToIPv6(PR_htonl(ipv4), &v6Addr);
                  match = !memcmp(&netAddr.ipv6.ip, &v6Addr, 16);
              } 
              if (match) {
                  rv = SECSuccess;
                  goto finish;
              }
           }
           IPextCount++;
           break;
       default:
           break;
       }
       current = CERT_GetNextGeneralName(current);
    } while (current != nameList);

    if ((!isIPaddr && !DNSextCount) || (isIPaddr && !IPextCount)) {
       /* no relevant value in the extension was found. */
       PORT_SetError(SEC_ERROR_EXTENSION_NOT_FOUND);
    } else {
       PORT_SetError(SSL_ERROR_BAD_CERT_DOMAIN);
    }
    rv = SECFailure;

finish:

    /* Don't free nameList, it's part of the arena. */
    if (arena) {
       PORT_FreeArena(arena, PR_FALSE);
    }

    if (subAltName.data) {
       SECITEM_FreeItem(&subAltName, PR_FALSE);
    }

    return rv;
}

Here is the call graph for this function:

static void EncodeFlags ( char *  trusts,
unsigned int  flags 
) [static]

Definition at line 2132 of file certdb.c.

{
    if (flags & CERTDB_VALID_CA)
       if (!(flags & CERTDB_TRUSTED_CA) &&
           !(flags & CERTDB_TRUSTED_CLIENT_CA))
           PORT_Strcat(trusts, "c");
    if (flags & CERTDB_VALID_PEER)
       if (!(flags & CERTDB_TRUSTED))
           PORT_Strcat(trusts, "p");
    if (flags & CERTDB_TRUSTED_CA)
       PORT_Strcat(trusts, "C");
    if (flags & CERTDB_TRUSTED_CLIENT_CA)
       PORT_Strcat(trusts, "T");
    if (flags & CERTDB_TRUSTED)
       PORT_Strcat(trusts, "P");
    if (flags & CERTDB_USER)
       PORT_Strcat(trusts, "u");
    if (flags & CERTDB_SEND_WARN)
       PORT_Strcat(trusts, "w");
    if (flags & CERTDB_INVISIBLE_CA)
       PORT_Strcat(trusts, "I");
    if (flags & CERTDB_GOVT_APPROVED_CA)
       PORT_Strcat(trusts, "G");
    return;
}

Here is the caller graph for this function:

static SECStatus findOIDinOIDSeqByTagNum ( CERTOidSequence seq,
SECOidTag  tagnum 
) [static]

Definition at line 507 of file certdb.c.

{
    SECItem **oids;
    SECItem *oid;
    SECStatus rv = SECFailure;
    
    if (seq != NULL) {
       oids = seq->oids;
       while (oids != NULL && *oids != NULL) {
           oid = *oids;
           if (SECOID_FindOIDTag(oid) == tagnum) {
              rv = SECSuccess;
              break;
           }
           oids++;
       }
    }
    return rv;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static PRBool fortezzaIsCA ( CERTCertificate *  cert) [static]

Definition at line 459 of file certdb.c.

                                     {
    PRBool isCA = PR_FALSE;
    CERTSubjectPublicKeyInfo *spki = &cert->subjectPublicKeyInfo;
    int tag;

    tag = SECOID_GetAlgorithmTag(&spki->algorithm);
    if ((tag == SEC_OID_MISSI_KEA_DSS_OLD) ||
       (tag == SEC_OID_MISSI_KEA_DSS) ||
       (tag == SEC_OID_MISSI_DSS_OLD) ||
       (tag == SEC_OID_MISSI_DSS) ) {
       SECItem rawkey;
       unsigned char *rawptr;
       unsigned char *end;
       int len;

       rawkey = spki->subjectPublicKey;
       DER_ConvertBitString(&rawkey);
       rawptr = rawkey.data;
       end = rawkey.data + rawkey.len;

       /* version */ 
       rawptr += sizeof(((SECKEYPublicKey*)0)->u.fortezza.KMID)+2;

       /* clearance (the string up to the first byte with the hi-bit on */
       while ((rawptr < end) && (*rawptr++ & 0x80));
       if (rawptr >= end) { return PR_FALSE; }

       /* KEAPrivilege (the string up to the first byte with the hi-bit on */
       while ((rawptr < end) && (*rawptr++ & 0x80));
       if (rawptr >= end) { return PR_FALSE; }

       /* skip the key */
       len = (*rawptr << 8) | rawptr[1];
       rawptr += 2 + len;

       /* shared key */
       if (rawptr >= end) { return PR_FALSE; }
       /* DSS Version is next */
       rawptr += 2;

       /* DSSPrivilege (the string up to the first byte with the hi-bit on */
       if (*rawptr & 0x30) isCA = PR_TRUE;
       
   }
   return isCA;
}

Here is the call graph for this function:

Here is the caller graph for this function:

static SECStatus GetKeyUsage ( CERTCertificate *  cert) [static]

Definition at line 424 of file certdb.c.

{
    SECStatus rv;
    SECItem tmpitem;
    
    rv = CERT_FindKeyUsageExtension(cert, &tmpitem);
    if ( rv == SECSuccess ) {
       /* remember the actual value of the extension */
       cert->rawKeyUsage = tmpitem.data[0];
       cert->keyUsagePresent = PR_TRUE;
       cert->keyUsage = tmpitem.data[0];

       PORT_Free(tmpitem.data);
       tmpitem.data = NULL;
       
    } else {
       /* if the extension is not present, then we allow all uses */
       cert->keyUsage = KU_ALL;
       cert->rawKeyUsage = KU_ALL;
       cert->keyUsagePresent = PR_FALSE;
    }

    if ( CERT_GovtApprovedBitSet(cert) ) {
       cert->keyUsage |= KU_NS_GOVT_APPROVED;
       cert->rawKeyUsage |= KU_NS_GOVT_APPROVED;
    }
    
    return(SECSuccess);
}

Here is the call graph for this function:

Here is the caller graph for this function:

SECCertTimeValidity SEC_CheckCrlTimes ( CERTCrl *  crl,
PRTime  t 
)

Definition at line 1069 of file certdb.c.

                                          {
    PRTime notBefore, notAfter, llPendingSlop, tmp1;
    SECStatus rv;

    rv = SEC_GetCrlTimes(crl, &notBefore, &notAfter);
    
    if (rv) {
       return(secCertTimeExpired); 
    }

    LL_I2L(llPendingSlop, pendingSlop);
    /* convert to micro seconds */
    LL_I2L(tmp1, PR_USEC_PER_SEC);
    LL_MUL(llPendingSlop, llPendingSlop, tmp1);
    LL_SUB(notBefore, notBefore, llPendingSlop);
    if ( LL_CMP( t, <, notBefore ) ) {
       return(secCertTimeNotValidYet);
    }

    /* If next update is omitted and the test for notBefore passes, then
       we assume that the crl is up to date.
     */
    if ( LL_IS_ZERO(notAfter) ) {
       return(secCertTimeValid);
    }

    if ( LL_CMP( t, >, notAfter) ) {
       return(secCertTimeExpired);
    }

    return(secCertTimeValid);
}

Here is the call graph for this function:

PRBool SEC_CrlIsNewer ( CERTCrl *  inNew,
CERTCrl *  old 
)

Definition at line 1103 of file certdb.c.

                                             {
    PRTime newNotBefore, newNotAfter;
    PRTime oldNotBefore, oldNotAfter;
    SECStatus rv;

    /* problems with the new CRL? reject it */
    rv = SEC_GetCrlTimes(inNew, &newNotBefore, &newNotAfter);
    if (rv) return PR_FALSE;

    /* problems with the old CRL? replace it */
    rv = SEC_GetCrlTimes(old, &oldNotBefore, &oldNotAfter);
    if (rv) return PR_TRUE;

    /* Question: what about the notAfter's? */
    return ((PRBool)LL_CMP(oldNotBefore, <, newNotBefore));
}

Here is the call graph for this function:

SECStatus SEC_GetCrlTimes ( CERTCrl *  date,
PRTime notBefore,
PRTime notAfter 
)

Definition at line 1042 of file certdb.c.

{
    int rv;
    
    /* convert DER not-before time */
    rv = DER_DecodeTimeChoice(notBefore, &date->lastUpdate);
    if (rv) {
       return(SECFailure);
    }
    
    /* convert DER not-after time */
    if (date->nextUpdate.data) {
       rv = DER_DecodeTimeChoice(notAfter, &date->nextUpdate);
       if (rv) {
           return(SECFailure);
       }
    }
    else {
       LL_I2L(*notAfter, 0L);
    }
    return(SECSuccess);
}

Here is the call graph for this function:

static void sec_lower_string ( char *  s) [static]

Definition at line 1319 of file certdb.c.

{
    if ( s == NULL ) {
       return;
    }
    
    while ( *s ) {
       *s = PORT_Tolower(*s);
       s++;
    }
    
    return;
}

Here is the caller graph for this function:

static SECStatus StringsEqual ( char *  s1,
char *  s2 
) [static]

Definition at line 1577 of file certdb.c.

                                 {
    if ( ( s1 == NULL ) || ( s2 == NULL ) ) {
       if ( s1 != s2 ) { /* only one is null */
           return(SECFailure);
       }
       return(SECSuccess); /* both are null */
    }
       
    if ( PORT_Strcmp( s1, s2 ) != 0 ) {
       return(SECFailure); /* not equal */
    }

    return(SECSuccess); /* strings are equal */
}

Here is the caller graph for this function:


Variable Documentation

Initial value:

Definition at line 2858 of file certdb.c.

Initial value:
 {
    { SEC_ASN1_SEQUENCE,
         0, NULL, sizeof(CERTCertExtension) },
    { SEC_ASN1_OBJECT_ID,
         offsetof(CERTCertExtension,id) },
    { SEC_ASN1_OPTIONAL | SEC_ASN1_BOOLEAN,             
         offsetof(CERTCertExtension,critical) },
    { SEC_ASN1_OCTET_STRING,
         offsetof(CERTCertExtension,value) },
    { 0, }
}

Definition at line 79 of file certdb.c.

Definition at line 95 of file certdb.c.

Initial value:
 {
    { SEC_ASN1_SEQUENCE,
         0, NULL, sizeof(CERTCertKey) },
    { SEC_ASN1_EXPLICIT | SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | 
         SEC_ASN1_CONTEXT_SPECIFIC | 0,
         0, SEC_SkipTemplate },     
    { SEC_ASN1_INTEGER,
         offsetof(CERTCertKey,serialNumber) },
    { SEC_ASN1_SKIP },             
    { SEC_ASN1_ANY,
         offsetof(CERTCertKey,derIssuer) },
    { SEC_ASN1_SKIP_REST },
    { 0 }
}

Definition at line 206 of file certdb.c.

Initial value:

Definition at line 91 of file certdb.c.

Definition at line 2732 of file certdb.c.

PZLock* certTrustLock = NULL [static]

Definition at line 2769 of file certdb.c.

CERTCertDBHandle* default_cert_db_handle = 0 [static]

Definition at line 1301 of file certdb.c.

Definition at line 2831 of file certdb.c.

PRLock* gSubjKeyIDLock = NULL [static]

Definition at line 2832 of file certdb.c.

Definition at line 958 of file certdb.c.

Initial value:

Definition at line 175 of file certdb.c.

Initial value:

Definition at line 190 of file certdb.c.

Initial value:

Definition at line 157 of file certdb.c.

Initial value:
{
    { SEC_ASN1_SEQUENCE,
         0, NULL, sizeof(CERTCertificate) },
    { SEC_ASN1_SAVE, 
         offsetof(CERTCertificate,signatureWrap.data) },
    { SEC_ASN1_INLINE, 
         0, CERT_CertificateTemplate },
    { SEC_ASN1_INLINE,
         offsetof(CERTCertificate,signatureWrap.signatureAlgorithm),
         SECOID_AlgorithmIDTemplate },
    { SEC_ASN1_BIT_STRING,
         offsetof(CERTCertificate,signatureWrap.signature) },
    { 0 }
}

Definition at line 138 of file certdb.c.