/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nspr.h"
#include "secerr.h"
#include "secasn1.h"
#include "seccomon.h"
#include "pk11func.h"
#include "certdb.h"
#include "certt.h"
#include "cert.h"
#include "certxutl.h"

#include "certi.h"
#include "nsspki.h"
#include "pki.h"
#include "pkit.h"
#include "pkitm.h"
#include "pki3hack.h"

PRBool
CERT_MatchNickname(char *name1, char *name2)
{
    char *nickname1 = NULL;
    char *nickname2 = NULL;
    char *token1;
    char *token2;

    /* first deal with the straight comparison */
    if (PORT_Strcmp(name1, name2) == 0) {
        return PR_TRUE;
    }
    /* we need to handle the case where one name has an explicit token and the other
     * doesn't */
    token1 = PORT_Strchr(name1, ':');
    token2 = PORT_Strchr(name2, ':');
    if ((token1 && token2) || (!token1 && !token2)) {
        /* either both token names are specified or neither are, not match */
        return PR_FALSE;
    }
    if (token1) {
        nickname1 = token1;
        nickname2 = name2;
    } else {
        nickname1 = token2;
        nickname2 = name1;
    }
    nickname1++;
    if (PORT_Strcmp(nickname1, nickname2) != 0) {
        return PR_FALSE;
    }
    /* Bug 1192443 - compare the other token with the internal slot here */
    return PR_TRUE;
}

/*
 * Find all user certificates that match the given criteria.
 *
 *      "handle" - database to search
 *      "usage" - certificate usage to match
 *      "oneCertPerName" - if set then only return the "best" cert per
 *                      name
 *      "validOnly" - only return certs that are curently valid
 *      "proto_win" - window handle passed to pkcs11
 */
CERTCertList *
CERT_FindUserCertsByUsage(CERTCertDBHandle *handle,
                          SECCertUsage usage,
                          PRBool oneCertPerName,
                          PRBool validOnly,
                          void *proto_win)
{
    CERTCertNicknames *nicknames = NULL;
    char **nnptr;
    int nn;
    CERTCertificate *cert = NULL;
    CERTCertList *certList = NULL;
    SECStatus rv;
    PRTime time;
    CERTCertListNode *node = NULL;
    CERTCertListNode *freenode = NULL;
    int n;

    time = PR_Now();

    nicknames = CERT_GetCertNicknames(handle, SEC_CERT_NICKNAMES_USER,
                                      proto_win);

    if ((nicknames == NULL) || (nicknames->numnicknames == 0)) {
        goto loser;
    }

    nnptr = nicknames->nicknames;
    nn = nicknames->numnicknames;

    while (nn > 0) {
        cert = NULL;
        /* use the pk11 call so that we pick up any certs on tokens,
         * which may require login
         */
        if (proto_win != NULL) {
            cert = PK11_FindCertFromNickname(*nnptr, proto_win);
        }

        /* Sigh, It turns out if the cert is already in the temp db, because
         * it's in the perm db, then the nickname lookup doesn't work.
         * since we already have the cert here, though, than we can just call
         * CERT_CreateSubjectCertList directly. For those cases where we didn't
         * find the cert in pkcs #11 (because we didn't have a password arg,
         * or because the nickname is for a peer, server, or CA cert, then we
         * go look the cert up.
         */
        if (cert == NULL) {
            cert = CERT_FindCertByNickname(handle, *nnptr);
        }

        if (cert != NULL) {
            /* collect certs for this nickname, sorting them into the list */
            certList = CERT_CreateSubjectCertList(certList, handle,
                                                  &cert->derSubject, time, validOnly);

            CERT_FilterCertListForUserCerts(certList);

            /* drop the extra reference */
            CERT_DestroyCertificate(cert);
        }

        nnptr++;
        nn--;
    }

    /* remove certs with incorrect usage */
    rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);

    if (rv != SECSuccess) {
        goto loser;
    }

    /* remove any extra certs for each name */
    if (oneCertPerName) {
        PRBool *flags;

        nn = nicknames->numnicknames;
        nnptr = nicknames->nicknames;

        if (!certList) {
            goto loser;
        }

        flags = (PRBool *)PORT_ZAlloc(sizeof(PRBool) * nn);
        if (flags == NULL) {
            goto loser;
        }

        node = CERT_LIST_HEAD(certList);

        /* treverse all certs in the list */
        while (!CERT_LIST_END(node, certList)) {

            /* find matching nickname index */
            for (n = 0; n < nn; n++) {
                if (CERT_MatchNickname(nnptr[n], node->cert->nickname)) {
                    /* We found a match.  If this is the first one, then
                     * set the flag and move on to the next cert.  If this
                     * is not the first one then delete it from the list.
                     */
                    if (flags[n]) {
                        /* We have already seen a cert with this nickname,
                         * so delete this one.
                         */
                        freenode = node;
                        node = CERT_LIST_NEXT(node);
                        CERT_RemoveCertListNode(freenode);
                    } else {
                        /* keep the first cert for each nickname, but set the
                         * flag so we know to delete any others with the same
                         * nickname.
                         */
                        flags[n] = PR_TRUE;
                        node = CERT_LIST_NEXT(node);
                    }
                    break;
                }
            }
            if (n == nn) {
                /* if we get here it means that we didn't find a matching
                 * nickname, which should not happen.
                 */
                PORT_Assert(0);
                node = CERT_LIST_NEXT(node);
            }
        }
        PORT_Free(flags);
    }

    goto done;

loser:
    if (certList != NULL) {
        CERT_DestroyCertList(certList);
        certList = NULL;
    }

done:
    if (nicknames != NULL) {
        CERT_FreeNicknames(nicknames);
    }

    return (certList);
}

/*
 * Find a user certificate that matchs the given criteria.
 *
 *      "handle" - database to search
 *      "nickname" - nickname to match
 *      "usage" - certificate usage to match
 *      "validOnly" - only return certs that are curently valid
 *      "proto_win" - window handle passed to pkcs11
 */
CERTCertificate *
CERT_FindUserCertByUsage(CERTCertDBHandle *handle,
                         const char *nickname,
                         SECCertUsage usage,
                         PRBool validOnly,
                         void *proto_win)
{
    CERTCertificate *cert = NULL;
    CERTCertList *certList = NULL;
    SECStatus rv;
    PRTime time;

    time = PR_Now();

    /* use the pk11 call so that we pick up any certs on tokens,
     * which may require login
     */
    /* XXX - why is this restricted? */
    if (proto_win != NULL) {
        cert = PK11_FindCertFromNickname(nickname, proto_win);
    }

    /* sigh, There are still problems find smart cards from the temp
     * db. This will get smart cards working again. The real fix
     * is to make sure we can search the temp db by their token nickname.
     */
    if (cert == NULL) {
        cert = CERT_FindCertByNickname(handle, nickname);
    }

    if (cert != NULL) {
        unsigned int requiredKeyUsage;
        unsigned int requiredCertType;

        rv = CERT_KeyUsageAndTypeForCertUsage(usage, PR_FALSE,
                                              &requiredKeyUsage, &requiredCertType);
        if (rv != SECSuccess) {
            /* drop the extra reference */
            CERT_DestroyCertificate(cert);
            cert = NULL;
            goto loser;
        }
        /* If we already found the right cert, just return it */
        if ((!validOnly || CERT_CheckCertValidTimes(cert, time, PR_FALSE) == secCertTimeValid) &&
            (CERT_CheckKeyUsage(cert, requiredKeyUsage) == SECSuccess) &&
            (cert->nsCertType & requiredCertType) &&
            CERT_IsUserCert(cert)) {
            return (cert);
        }

        /* collect certs for this nickname, sorting them into the list */
        certList = CERT_CreateSubjectCertList(certList, handle,
                                              &cert->derSubject, time, validOnly);

        CERT_FilterCertListForUserCerts(certList);

        /* drop the extra reference */
        CERT_DestroyCertificate(cert);
        cert = NULL;
    }

    if (certList == NULL) {
        goto loser;
    }

    /* remove certs with incorrect usage */
    rv = CERT_FilterCertListByUsage(certList, usage, PR_FALSE);

    if (rv != SECSuccess) {
        goto loser;
    }

    if (!CERT_LIST_EMPTY(certList)) {
        cert = CERT_DupCertificate(CERT_LIST_HEAD(certList)->cert);
    }

loser:
    if (certList != NULL) {
        CERT_DestroyCertList(certList);
    }

    return (cert);
}

CERTCertList *
CERT_MatchUserCert(CERTCertDBHandle *handle,
                   SECCertUsage usage,
                   int nCANames, char **caNames,
                   void *proto_win)
{
    CERTCertList *certList = NULL;
    SECStatus rv;

    certList = CERT_FindUserCertsByUsage(handle, usage, PR_TRUE, PR_TRUE,
                                         proto_win);
    if (certList == NULL) {
        goto loser;
    }

    rv = CERT_FilterCertListByCANames(certList, nCANames, caNames, usage);
    if (rv != SECSuccess) {
        goto loser;
    }

    goto done;

loser:
    if (certList != NULL) {
        CERT_DestroyCertList(certList);
        certList = NULL;
    }

done:

    return (certList);
}

typedef struct stringNode {
    struct stringNode *next;
    char *string;
} stringNode;

static PRStatus
CollectNicknames(NSSCertificate *c, void *data)
{
    CERTCertNicknames *names;
    PRBool saveit = PR_FALSE;
    stringNode *node;
    int len;
#ifdef notdef
    NSSTrustDomain *td;
    NSSTrust *trust;
#endif
    char *stanNickname;
    char *nickname = NULL;

    names = (CERTCertNicknames *)data;

    stanNickname = nssCertificate_GetNickname(c, NULL);

    if (stanNickname) {
        nss_ZFreeIf(stanNickname);
        stanNickname = NULL;
        if (names->what == SEC_CERT_NICKNAMES_USER) {
            saveit = NSSCertificate_IsPrivateKeyAvailable(c, NULL, NULL);
        }
#ifdef notdef
        else {
            td = NSSCertificate_GetTrustDomain(c);
            if (!td) {
                return PR_SUCCESS;
            }
            trust = nssTrustDomain_FindTrustForCertificate(td, c);

            switch (names->what) {
                case SEC_CERT_NICKNAMES_ALL:
                    if ((trust->sslFlags & (CERTDB_VALID_CA | CERTDB_VALID_PEER)) ||
                        (trust->emailFlags & (CERTDB_VALID_CA | CERTDB_VALID_PEER)) ||
                        (trust->objectSigningFlags &
                         (CERTDB_VALID_CA | CERTDB_VALID_PEER))) {
                        saveit = PR_TRUE;
                    }

                    break;
                case SEC_CERT_NICKNAMES_SERVER:
                    if (trust->sslFlags & CERTDB_VALID_PEER) {
                        saveit = PR_TRUE;
                    }

                    break;
                case SEC_CERT_NICKNAMES_CA:
                    if (((trust->sslFlags & CERTDB_VALID_CA) == CERTDB_VALID_CA) ||
                        ((trust->emailFlags & CERTDB_VALID_CA) == CERTDB_VALID_CA) ||
                        ((trust->objectSigningFlags & CERTDB_VALID_CA) ==
                         CERTDB_VALID_CA)) {
                        saveit = PR_TRUE;
                    }
                    break;
            }
        }
#endif
    }

    /* traverse the list of collected nicknames and make sure we don't make
     * a duplicate
     */
    if (saveit) {
        nickname = STAN_GetCERTCertificateName(NULL, c);
        /* nickname can only be NULL here if we are having memory
         * alloc problems */
        if (nickname == NULL) {
            return PR_FAILURE;
        }
        node = (stringNode *)names->head;
        while (node != NULL) {
            if (PORT_Strcmp(nickname, node->string) == 0) {
                /* if the string matches, then don't save this one */
                saveit = PR_FALSE;
                break;
            }
            node = node->next;
        }
    }

    if (saveit) {

        /* allocate the node */
        node = (stringNode *)PORT_ArenaAlloc(names->arena, sizeof(stringNode));
        if (node == NULL) {
            PORT_Free(nickname);
            return PR_FAILURE;
        }

        /* copy the string */
        len = PORT_Strlen(nickname) + 1;
        node->string = (char *)PORT_ArenaAlloc(names->arena, len);
        if (node->string == NULL) {
            PORT_Free(nickname);
            return PR_FAILURE;
        }
        PORT_Memcpy(node->string, nickname, len);

        /* link it into the list */
        node->next = (stringNode *)names->head;
        names->head = (void *)node;

        /* bump the count */
        names->numnicknames++;
    }

    if (nickname)
        PORT_Free(nickname);
    return (PR_SUCCESS);
}

CERTCertNicknames *
CERT_GetCertNicknames(CERTCertDBHandle *handle, int what, void *wincx)
{
    PLArenaPool *arena;
    CERTCertNicknames *names;
    int i;
    stringNode *node;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return (NULL);
    }

    names = (CERTCertNicknames *)PORT_ArenaAlloc(arena, sizeof(CERTCertNicknames));
    if (names == NULL) {
        goto loser;
    }

    names->arena = arena;
    names->head = NULL;
    names->numnicknames = 0;
    names->nicknames = NULL;
    names->what = what;
    names->totallen = 0;

    /* make sure we are logged in */
    (void)pk11_TraverseAllSlots(NULL, NULL, PR_TRUE, wincx);

    NSSTrustDomain_TraverseCertificates(handle,
                                        CollectNicknames, (void *)names);
    if (names->numnicknames) {
        names->nicknames = (char **)PORT_ArenaAlloc(arena,
                                                    names->numnicknames *
                                                        sizeof(char *));

        if (names->nicknames == NULL) {
            goto loser;
        }

        node = (stringNode *)names->head;

        for (i = 0; i < names->numnicknames; i++) {
            PORT_Assert(node != NULL);

            names->nicknames[i] = node->string;
            names->totallen += PORT_Strlen(node->string);
            node = node->next;
        }

        PORT_Assert(node == NULL);
    }

    return (names);

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

void
CERT_FreeNicknames(CERTCertNicknames *nicknames)
{
    PORT_FreeArena(nicknames->arena, PR_FALSE);

    return;
}

/* [ FROM pcertdb.c ] */

typedef struct dnameNode {
    struct dnameNode *next;
    SECItem name;
} dnameNode;

void
CERT_FreeDistNames(CERTDistNames *names)
{
    PORT_FreeArena(names->arena, PR_FALSE);

    return;
}

static SECStatus
CollectDistNames(CERTCertificate *cert, SECItem *k, void *data)
{
    CERTDistNames *names;
    PRBool saveit = PR_FALSE;
    CERTCertTrust trust;
    dnameNode *node;
    int len;

    names = (CERTDistNames *)data;

    if (CERT_GetCertTrust(cert, &trust) == SECSuccess) {
        /* only collect names of CAs trusted for issuing SSL clients */
        if (trust.sslFlags & CERTDB_TRUSTED_CLIENT_CA) {
            saveit = PR_TRUE;
        }
    }

    if (saveit) {
        /* allocate the node */
        node = (dnameNode *)PORT_ArenaAlloc(names->arena, sizeof(dnameNode));
        if (node == NULL) {
            return (SECFailure);
        }

        /* copy the name */
        node->name.len = len = cert->derSubject.len;
        node->name.type = siBuffer;
        node->name.data = (unsigned char *)PORT_ArenaAlloc(names->arena, len);
        if (node->name.data == NULL) {
            return (SECFailure);
        }
        PORT_Memcpy(node->name.data, cert->derSubject.data, len);

        /* link it into the list */
        node->next = (dnameNode *)names->head;
        names->head = (void *)node;

        /* bump the count */
        names->nnames++;
    }

    return (SECSuccess);
}

/*
 * Return all of the CAs that are "trusted" for SSL.
 */
CERTDistNames *
CERT_DupDistNames(CERTDistNames *orig)
{
    PLArenaPool *arena;
    CERTDistNames *names;
    int i;
    SECStatus rv;

    /* allocate an arena to use */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return (NULL);
    }

    /* allocate the header structure */
    names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));
    if (names == NULL) {
        goto loser;
    }

    /* initialize the header struct */
    names->arena = arena;
    names->head = NULL;
    names->nnames = orig->nnames;
    names->names = NULL;

    /* construct the array from the list */
    if (orig->nnames) {
        names->names = (SECItem *)PORT_ArenaNewArray(arena, SECItem,
                                                     orig->nnames);
        if (names->names == NULL) {
            goto loser;
        }
        for (i = 0; i < orig->nnames; i++) {
            rv = SECITEM_CopyItem(arena, &names->names[i], &orig->names[i]);
            if (rv != SECSuccess) {
                goto loser;
            }
        }
    }
    return (names);

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

CERTDistNames *
CERT_GetSSLCACerts(CERTCertDBHandle *handle)
{
    PLArenaPool *arena;
    CERTDistNames *names;
    int i;
    SECStatus rv;
    dnameNode *node;

    /* allocate an arena to use */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PORT_SetError(SEC_ERROR_NO_MEMORY);
        return (NULL);
    }

    /* allocate the header structure */
    names = (CERTDistNames *)PORT_ArenaAlloc(arena, sizeof(CERTDistNames));
    if (names == NULL) {
        goto loser;
    }

    /* initialize the header struct */
    names->arena = arena;
    names->head = NULL;
    names->nnames = 0;
    names->names = NULL;

    /* collect the names from the database */
    rv = PK11_TraverseSlotCerts(CollectDistNames, (void *)names, NULL);
    if (rv) {
        goto loser;
    }

    /* construct the array from the list */
    if (names->nnames) {
        names->names = (SECItem *)PORT_ArenaAlloc(arena, names->nnames * sizeof(SECItem));

        if (names->names == NULL) {
            goto loser;
        }

        node = (dnameNode *)names->head;

        for (i = 0; i < names->nnames; i++) {
            PORT_Assert(node != NULL);

            names->names[i] = node->name;
            node = node->next;
        }

        PORT_Assert(node == NULL);
    }

    return (names);

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

CERTDistNames *
CERT_DistNamesFromCertList(CERTCertList *certList)
{
    CERTDistNames *dnames = NULL;
    PLArenaPool *arena;
    CERTCertListNode *node = NULL;
    SECItem *names = NULL;
    int listLen = 0, i = 0;

    if (certList == NULL) {
        PORT_SetError(SEC_ERROR_INVALID_ARGS);
        return NULL;
    }

    node = CERT_LIST_HEAD(certList);
    while (!CERT_LIST_END(node, certList)) {
        listLen += 1;
        node = CERT_LIST_NEXT(node);
    }

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
        goto loser;
    dnames = PORT_ArenaZNew(arena, CERTDistNames);
    if (dnames == NULL)
        goto loser;

    dnames->arena = arena;
    dnames->nnames = listLen;
    dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, listLen);
    if (names == NULL)
        goto loser;

    node = CERT_LIST_HEAD(certList);
    while (!CERT_LIST_END(node, certList)) {
        CERTCertificate *cert = node->cert;
        SECStatus rv = SECITEM_CopyItem(arena, &names[i++], &cert->derSubject);
        if (rv == SECFailure) {
            goto loser;
        }
        node = CERT_LIST_NEXT(node);
    }
    return dnames;
loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return NULL;
}

CERTDistNames *
CERT_DistNamesFromNicknames(CERTCertDBHandle *handle, char **nicknames,
                            int nnames)
{
    CERTDistNames *dnames = NULL;
    PLArenaPool *arena;
    int i, rv;
    SECItem *names = NULL;
    CERTCertificate *cert = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
        goto loser;
    dnames = PORT_ArenaZNew(arena, CERTDistNames);
    if (dnames == NULL)
        goto loser;

    dnames->arena = arena;
    dnames->nnames = nnames;
    dnames->names = names = PORT_ArenaZNewArray(arena, SECItem, nnames);
    if (names == NULL)
        goto loser;

    for (i = 0; i < nnames; i++) {
        cert = CERT_FindCertByNicknameOrEmailAddr(handle, nicknames[i]);
        if (cert == NULL)
            goto loser;
        rv = SECITEM_CopyItem(arena, &names[i], &cert->derSubject);
        if (rv == SECFailure)
            goto loser;
        CERT_DestroyCertificate(cert);
    }
    return dnames;

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

/* [ from pcertdb.c - calls Ascii to Name ] */
/*
 * Lookup a certificate in the database by name
 */
CERTCertificate *
CERT_FindCertByNameString(CERTCertDBHandle *handle, char *nameStr)
{
    CERTName *name;
    SECItem *nameItem;
    CERTCertificate *cert = NULL;
    PLArenaPool *arena = NULL;

    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);

    if (arena == NULL) {
        goto loser;
    }

    name = CERT_AsciiToName(nameStr);

    if (name) {
        nameItem = SEC_ASN1EncodeItem(arena, NULL, (void *)name,
                                      CERT_NameTemplate);
        if (nameItem != NULL) {
            cert = CERT_FindCertByName(handle, nameItem);
        }
        CERT_DestroyName(name);
    }

loser:
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }

    return (cert);
}

/* From certv3.c */

CERTCrlDistributionPoints *
CERT_FindCRLDistributionPoints(CERTCertificate *cert)
{
    SECItem encodedExtenValue;
    SECStatus rv;
    CERTCrlDistributionPoints *dps;

    encodedExtenValue.data = NULL;
    encodedExtenValue.len = 0;

    rv = cert_FindExtension(cert->extensions, SEC_OID_X509_CRL_DIST_POINTS,
                            &encodedExtenValue);
    if (rv != SECSuccess) {
        return (NULL);
    }

    dps = CERT_DecodeCRLDistributionPoints(cert->arena, &encodedExtenValue);

    PORT_Free(encodedExtenValue.data);

    return dps;
}

/* From crl.c */
CERTSignedCrl *
CERT_ImportCRL(CERTCertDBHandle *handle, SECItem *derCRL, char *url, int type, void *wincx)
{
    CERTSignedCrl *retCrl = NULL;
    PK11SlotInfo *slot = PK11_GetInternalKeySlot();
    retCrl = PK11_ImportCRL(slot, derCRL, url, type, wincx,
                            CRL_IMPORT_DEFAULT_OPTIONS, NULL, CRL_DECODE_DEFAULT_OPTIONS);
    PK11_FreeSlot(slot);

    return retCrl;
}

/* From certdb.c */
static SECStatus
cert_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage, PRBool trusted)
{
    SECStatus rv;
    SECItem *derCert;
    CERTCertificate *cert = NULL;
    CERTCertificate *newcert = NULL;
    CERTCertDBHandle *handle;
    CERTCertTrust trust;
    PRBool isca;
    char *nickname;
    unsigned int certtype;
    PRBool istemp = PR_FALSE;

    handle = CERT_GetDefaultCertDB();

    while (numcerts--) {
        derCert = certs;
        certs++;

        /* decode my certificate */
        /* This use is ok -- only looks at decoded parts, calls NewTemp later */
        newcert = CERT_DecodeDERCertificate(derCert, PR_FALSE, NULL);
        if (newcert == NULL) {
            goto loser;
        }

        if (!trusted) {
            /* make sure that cert is valid */
            rv = CERT_CertTimesValid(newcert);
            if (rv == SECFailure) {
                goto endloop;
            }
        }

        /* does it have the CA extension */

        /*
         * Make sure that if this is an intermediate CA in the chain that
         * it was given permission by its signer to be a CA.
         */
        isca = CERT_IsCACert(newcert, &certtype);

        if (!isca) {
            if (!trusted) {
                goto endloop;
            }
            trust.sslFlags = CERTDB_VALID_CA;
            trust.emailFlags = CERTDB_VALID_CA;
            trust.objectSigningFlags = CERTDB_VALID_CA;
        } else {
            /* SSL ca's must have the ssl bit set */
            if ((certUsage == certUsageSSLCA) &&
                ((certtype & NS_CERT_TYPE_SSL_CA) != NS_CERT_TYPE_SSL_CA)) {
                goto endloop;
            }

            /* it passed all of the tests, so lets add it to the database */
            /* mark it as a CA */
            PORT_Memset((void *)&trust, 0, sizeof(trust));
            switch (certUsage) {
                case certUsageSSLCA:
                    trust.sslFlags = CERTDB_VALID_CA;
                    break;
                case certUsageUserCertImport:
                    if ((certtype & NS_CERT_TYPE_SSL_CA) == NS_CERT_TYPE_SSL_CA) {
                        trust.sslFlags = CERTDB_VALID_CA;
                    }
                    if ((certtype & NS_CERT_TYPE_EMAIL_CA) ==
                        NS_CERT_TYPE_EMAIL_CA) {
                        trust.emailFlags = CERTDB_VALID_CA;
                    }
                    if ((certtype & NS_CERT_TYPE_OBJECT_SIGNING_CA) ==
                        NS_CERT_TYPE_OBJECT_SIGNING_CA) {
                        trust.objectSigningFlags = CERTDB_VALID_CA;
                    }
                    break;
                default:
                    PORT_Assert(0);
                    break;
            }
        }

        cert = CERT_NewTempCertificate(handle, derCert, NULL,
                                       PR_FALSE, PR_FALSE);
        if (cert == NULL) {
            goto loser;
        }

        /* if the cert is temp, make it perm; otherwise we're done */
        rv = CERT_GetCertIsTemp(cert, &istemp);
        if (rv != SECSuccess) {
            goto loser;
        }
        if (istemp) {
            /* get a default nickname for it */
            nickname = CERT_MakeCANickname(cert);

            rv = CERT_AddTempCertToPerm(cert, nickname, &trust);

            /* free the nickname */
            if (nickname) {
                PORT_Free(nickname);
            }
        } else {
            rv = SECSuccess;
        }

        if (rv != SECSuccess) {
            goto loser;
        }

    endloop:
        if (newcert) {
            CERT_DestroyCertificate(newcert);
            newcert = NULL;
        }
    }

    rv = SECSuccess;
    goto done;
loser:
    rv = SECFailure;
done:

    if (newcert) {
        CERT_DestroyCertificate(newcert);
        newcert = NULL;
    }

    if (cert) {
        CERT_DestroyCertificate(cert);
        cert = NULL;
    }

    return (rv);
}

SECStatus
CERT_ImportCAChain(SECItem *certs, int numcerts, SECCertUsage certUsage)
{
    return cert_ImportCAChain(certs, numcerts, certUsage, PR_FALSE);
}

SECStatus
CERT_ImportCAChainTrusted(SECItem *certs, int numcerts, SECCertUsage certUsage)
{
    return cert_ImportCAChain(certs, numcerts, certUsage, PR_TRUE);
}

/* Moved from certdb.c */
/*
** CERT_CertChainFromCert
**
** Construct a CERTCertificateList consisting of the given certificate and all
** of the issuer certs until we either get to a self-signed cert or can't find
** an issuer.  Since we don't know how many certs are in the chain we have to
** build a linked list first as we count them.
*/

typedef struct certNode {
    struct certNode *next;
    CERTCertificate *cert;
} certNode;

CERTCertificateList *
CERT_CertChainFromCert(CERTCertificate *cert, SECCertUsage usage,
                       PRBool includeRoot)
{
    CERTCertificateList *chain = NULL;
    NSSCertificate **stanChain;
    NSSCertificate *stanCert;
    PLArenaPool *arena;
    NSSUsage nssUsage;
    int i, len;
    NSSTrustDomain *td = STAN_GetDefaultTrustDomain();
    NSSCryptoContext *cc = STAN_GetDefaultCryptoContext();

    stanCert = STAN_GetNSSCertificate(cert);
    if (!stanCert) {
        /* error code is set */
        return NULL;
    }
    nssUsage.anyUsage = PR_FALSE;
    nssUsage.nss3usage = usage;
    nssUsage.nss3lookingForCA = PR_FALSE;
    stanChain = NSSCertificate_BuildChain(stanCert, NULL, &nssUsage, NULL, NULL,
                                          CERT_MAX_CERT_CHAIN, NULL, NULL, td, cc);
    if (!stanChain) {
        PORT_SetError(SEC_ERROR_UNKNOWN_ISSUER);
        return NULL;
    }

    len = 0;
    stanCert = stanChain[0];
    while (stanCert) {
        stanCert = stanChain[++len];
    }

    arena = PORT_NewArena(4096);
    if (arena == NULL) {
        goto loser;
    }

    chain = (CERTCertificateList *)PORT_ArenaAlloc(arena,
                                                   sizeof(CERTCertificateList));
    if (!chain)
        goto loser;
    chain->certs = (SECItem *)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
    if (!chain->certs)
        goto loser;
    i = 0;
    stanCert = stanChain[i];
    while (stanCert) {
        SECItem derCert;
        CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
        if (!cCert) {
            goto loser;
        }
        derCert.len = (unsigned int)stanCert->encoding.size;
        derCert.data = (unsigned char *)stanCert->encoding.data;
        derCert.type = siBuffer;
        if (SECITEM_CopyItem(arena, &chain->certs[i], &derCert) != SECSuccess) {
            CERT_DestroyCertificate(cCert);
            goto loser;
        }
        stanCert = stanChain[++i];
        if (!stanCert && !cCert->isRoot) {
            /* reached the end of the chain, but the final cert is
             * not a root.  Don't discard it.
             */
            includeRoot = PR_TRUE;
        }
        CERT_DestroyCertificate(cCert);
    }
    if (!includeRoot && len > 1) {
        chain->len = len - 1;
    } else {
        chain->len = len;
    }

    chain->arena = arena;
    nss_ZFreeIf(stanChain);
    return chain;
loser:
    i = 0;
    stanCert = stanChain[i];
    while (stanCert) {
        CERTCertificate *cCert = STAN_GetCERTCertificate(stanCert);
        if (cCert) {
            CERT_DestroyCertificate(cCert);
        }
        stanCert = stanChain[++i];
    }
    nss_ZFreeIf(stanChain);
    if (arena) {
        PORT_FreeArena(arena, PR_FALSE);
    }
    return NULL;
}

/* Builds a CERTCertificateList holding just one DER-encoded cert, namely
** the one for the cert passed as an argument.
*/
CERTCertificateList *
CERT_CertListFromCert(CERTCertificate *cert)
{
    CERTCertificateList *chain = NULL;
    int rv;
    PLArenaPool *arena;

    /* arena for SecCertificateList */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
        goto no_memory;

    /* build the CERTCertificateList */
    chain = (CERTCertificateList *)PORT_ArenaAlloc(arena, sizeof(CERTCertificateList));
    if (chain == NULL)
        goto no_memory;
    chain->certs = (SECItem *)PORT_ArenaAlloc(arena, 1 * sizeof(SECItem));
    if (chain->certs == NULL)
        goto no_memory;
    rv = SECITEM_CopyItem(arena, chain->certs, &(cert->derCert));
    if (rv < 0)
        goto loser;
    chain->len = 1;
    chain->arena = arena;

    return chain;

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

CERTCertificateList *
CERT_DupCertList(const CERTCertificateList *oldList)
{
    CERTCertificateList *newList = NULL;
    PLArenaPool *arena = NULL;
    SECItem *newItem;
    SECItem *oldItem;
    int len = oldList->len;
    int rv;

    /* arena for SecCertificateList */
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL)
        goto no_memory;

    /* now build the CERTCertificateList */
    newList = PORT_ArenaNew(arena, CERTCertificateList);
    if (newList == NULL)
        goto no_memory;
    newList->arena = arena;
    newItem = (SECItem *)PORT_ArenaAlloc(arena, len * sizeof(SECItem));
    if (newItem == NULL)
        goto no_memory;
    newList->certs = newItem;
    newList->len = len;

    for (oldItem = oldList->certs; len > 0; --len, ++newItem, ++oldItem) {
        rv = SECITEM_CopyItem(arena, newItem, oldItem);
        if (rv < 0)
            goto loser;
    }
    return newList;

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

void
CERT_DestroyCertificateList(CERTCertificateList *list)
{
    PORT_FreeArena(list->arena, PR_FALSE);
}
