/* 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/. */
/*
 * nss_pkix_proxy.h
 *
 * PKIX - NSS proxy functions
 *
 * NOTE: All structures, functions, data types are parts of library private
 * api and are subjects to change in any following releases.
 *
 */
#include "prerror.h"
#include "prprf.h"

#include "nspr.h"
#include "pk11func.h"
#include "certdb.h"
#include "cert.h"
#include "secerr.h"
#include "nssb64.h"
#include "secasn1.h"
#include "secder.h"
#include "pkit.h"

#ifndef NSS_DISABLE_LIBPKIX
#include "pkix_pl_common.h"

extern PRLogModuleInfo *pkixLog;

#ifdef PKIX_OBJECT_LEAK_TEST

extern PKIX_UInt32
pkix_pl_lifecycle_ObjectLeakCheck(int *);

extern SECStatus
pkix_pl_lifecycle_ObjectTableUpdate(int *objCountTable);

PRInt32 parallelFnInvocationCount;
#endif /* PKIX_OBJECT_LEAK_TEST */

static PRBool usePKIXValidationEngine = PR_FALSE;
#endif /* NSS_DISABLE_LIBPKIX */

/*
 * FUNCTION: CERT_SetUsePKIXForValidation
 * DESCRIPTION:
 *
 * Enables or disables use of libpkix for certificate validation
 *
 * PARAMETERS:
 *  "enable"
 *      PR_TRUE: enables use of libpkix for cert validation.
 *      PR_FALSE: disables.
 * THREAD SAFETY:
 *  NOT Thread Safe.
 * RETURNS:
 *  Returns SECSuccess if successfully enabled
 */
SECStatus
CERT_SetUsePKIXForValidation(PRBool enable)
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
#else
    usePKIXValidationEngine = (enable > 0) ? PR_TRUE : PR_FALSE;
    return SECSuccess;
#endif /* NSS_DISABLE_LIBPKIX */
}

/*
 * FUNCTION: CERT_GetUsePKIXForValidation
 * DESCRIPTION:
 *
 * Checks if libpkix building function should be use for certificate
 * chain building.
 *
 * PARAMETERS:
 *  NONE
 * THREAD SAFETY:
 *  NOT Thread Safe
 * RETURNS:
 *  Returns PR_TRUE if libpkix should be used. PR_FALSE otherwise.
 */
PRBool
CERT_GetUsePKIXForValidation()
{
#ifdef NSS_DISABLE_LIBPKIX
    return PR_FALSE;
#else
    return usePKIXValidationEngine;
#endif /* NSS_DISABLE_LIBPKIX */
}

#ifndef NSS_DISABLE_LIBPKIX
#ifdef NOTDEF
/*
 * FUNCTION: cert_NssKeyUsagesToPkix
 * DESCRIPTION:
 *
 * Converts nss key usage bit field(PRUint32) to pkix key usage
 * bit field.
 *
 * PARAMETERS:
 *  "nssKeyUsage"
 *      Nss key usage bit field.
 *  "pkixKeyUsage"
 *      Pkix key usage big field.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_NssKeyUsagesToPkix(
    PRUint32 nssKeyUsage,
    PKIX_UInt32 *pPkixKeyUsage,
    void *plContext)
{
    PKIX_UInt32 pkixKeyUsage = 0;

    PKIX_ENTER(CERTVFYPKIX, "cert_NssKeyUsagesToPkix");
    PKIX_NULLCHECK_ONE(pPkixKeyUsage);

    *pPkixKeyUsage = 0;

    if (nssKeyUsage & KU_DIGITAL_SIGNATURE) {
        pkixKeyUsage |= PKIX_DIGITAL_SIGNATURE;
    }

    if (nssKeyUsage & KU_NON_REPUDIATION) {
        pkixKeyUsage |= PKIX_NON_REPUDIATION;
    }

    if (nssKeyUsage & KU_KEY_ENCIPHERMENT) {
        pkixKeyUsage |= PKIX_KEY_ENCIPHERMENT;
    }

    if (nssKeyUsage & KU_DATA_ENCIPHERMENT) {
        pkixKeyUsage |= PKIX_DATA_ENCIPHERMENT;
    }

    if (nssKeyUsage & KU_KEY_AGREEMENT) {
        pkixKeyUsage |= PKIX_KEY_AGREEMENT;
    }

    if (nssKeyUsage & KU_KEY_CERT_SIGN) {
        pkixKeyUsage |= PKIX_KEY_CERT_SIGN;
    }

    if (nssKeyUsage & KU_CRL_SIGN) {
        pkixKeyUsage |= PKIX_CRL_SIGN;
    }

    if (nssKeyUsage & KU_ENCIPHER_ONLY) {
        pkixKeyUsage |= PKIX_ENCIPHER_ONLY;
    }

    /* Not supported. XXX we should support this once it is
     * fixed in NSS */
    /* pkixKeyUsage |= PKIX_DECIPHER_ONLY; */

    *pPkixKeyUsage = pkixKeyUsage;

    PKIX_RETURN(CERTVFYPKIX);
}

extern SECOidTag ekuOidStrings[];

enum {
    ekuIndexSSLServer = 0,
    ekuIndexSSLClient,
    ekuIndexCodeSigner,
    ekuIndexEmail,
    ekuIndexTimeStamp,
    ekuIndexStatusResponder,
    ekuIndexUnknown
} ekuIndex;

typedef struct {
    SECCertUsage certUsage;
    PRUint32 ekuStringIndex;
} SECCertUsageToEku;

const SECCertUsageToEku certUsageEkuStringMap[] = {
    { certUsageSSLClient, ekuIndexSSLClient },
    { certUsageSSLServer, ekuIndexSSLServer },
    { certUsageSSLCA, ekuIndexSSLServer },
    { certUsageEmailSigner, ekuIndexEmail },
    { certUsageEmailRecipient, ekuIndexEmail },
    { certUsageObjectSigner, ekuIndexCodeSigner },
    { certUsageUserCertImport, ekuIndexUnknown },
    { certUsageVerifyCA, ekuIndexUnknown },
    { certUsageProtectedObjectSigner, ekuIndexUnknown },
    { certUsageStatusResponder, ekuIndexStatusResponder },
    { certUsageAnyCA, ekuIndexUnknown },
};

/*
 * FUNCTION: cert_NssCertificateUsageToPkixKUAndEKU
 * DESCRIPTION:
 *
 * Converts nss CERTCertificateUsage bit field to pkix key and
 * extended key usages.
 *
 * PARAMETERS:
 *  "cert"
 *      Pointer to CERTCertificate structure of validating cert.
 *  "requiredCertUsages"
 *      Required usage that will be converted to pkix eku and ku.
 *  "requiredKeyUsage",
 *      Additional key usages impose to cert.
 *  "isCA",
 *      it true, convert usages for cert that is a CA cert.
 *  "ppkixEKUList"
 *      Returned address of a list of pkix extended key usages.
 *  "ppkixKU"
 *      Returned address of pkix required key usages bit field.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_NssCertificateUsageToPkixKUAndEKU(
    CERTCertificate *cert,
    SECCertUsage requiredCertUsage,
    PRUint32 requiredKeyUsages,
    PRBool isCA,
    PKIX_List **ppkixEKUList,
    PKIX_UInt32 *ppkixKU,
    void *plContext)
{
    PKIX_List *ekuOidsList = NULL;
    PKIX_PL_OID *ekuOid = NULL;
    int i = 0;
    int ekuIndex = ekuIndexUnknown;

    PKIX_ENTER(CERTVFYPKIX, "cert_NssCertificateUsageToPkixEku");
    PKIX_NULLCHECK_TWO(ppkixEKUList, ppkixKU);

    PKIX_CHECK(
        PKIX_List_Create(&ekuOidsList, plContext),
        PKIX_LISTCREATEFAILED);

    for (; i < PR_ARRAY_SIZE(certUsageEkuStringMap); i++) {
        const SECCertUsageToEku *usageToEkuElem =
            &certUsageEkuStringMap[i];
        if (usageToEkuElem->certUsage == requiredCertUsage) {
            ekuIndex = usageToEkuElem->ekuStringIndex;
            break;
        }
    }
    if (ekuIndex != ekuIndexUnknown) {
        PRUint32 reqKeyUsage = 0;
        PRUint32 reqCertType = 0;

        CERT_KeyUsageAndTypeForCertUsage(requiredCertUsage, isCA,
                                         &reqKeyUsage,
                                         &reqCertType);

        requiredKeyUsages |= reqKeyUsage;

        PKIX_CHECK(
            PKIX_PL_OID_Create(ekuOidStrings[ekuIndex], &ekuOid,
                               plContext),
            PKIX_OIDCREATEFAILED);

        PKIX_CHECK(
            PKIX_List_AppendItem(ekuOidsList, (PKIX_PL_Object *)ekuOid,
                                 plContext),
            PKIX_LISTAPPENDITEMFAILED);

        PKIX_DECREF(ekuOid);
    }

    PKIX_CHECK(
        cert_NssKeyUsagesToPkix(requiredKeyUsages, ppkixKU, plContext),
        PKIX_NSSCERTIFICATEUSAGETOPKIXKUANDEKUFAILED);

    *ppkixEKUList = ekuOidsList;
    ekuOidsList = NULL;

cleanup:

    PKIX_DECREF(ekuOid);
    PKIX_DECREF(ekuOidsList);

    PKIX_RETURN(CERTVFYPKIX);
}

#endif

/*
 * FUNCTION: cert_ProcessingParamsSetKeyAndCertUsage
 * DESCRIPTION:
 *
 * Converts cert usage to pkix KU type and sets
 * converted data into PKIX_ProcessingParams object. It also sets
 * proper cert usage into nsscontext object.
 *
 * PARAMETERS:
 *  "procParams"
 *      Pointer to PKIX_ProcessingParams used during validation.
 *  "requiredCertUsage"
 *      Required certificate usages the certificate and chain is built and
 *      validated for.
 *  "requiredKeyUsage"
 *      Request additional key usages the certificate should be validated for.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_ProcessingParamsSetKeyAndCertUsage(
    PKIX_ProcessingParams *procParams,
    SECCertUsage requiredCertUsage,
    PRUint32 requiredKeyUsages,
    void *plContext)
{
    PKIX_CertSelector *certSelector = NULL;
    PKIX_ComCertSelParams *certSelParams = NULL;
    PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;

    PKIX_ENTER(CERTVFYPKIX, "cert_ProcessingParamsSetKeyAndCertUsage");
    PKIX_NULLCHECK_TWO(procParams, nssContext);

    PKIX_CHECK(
        pkix_pl_NssContext_SetCertUsage(
            ((SECCertificateUsage)1) << requiredCertUsage, nssContext),
        PKIX_NSSCONTEXTSETCERTUSAGEFAILED);

    if (requiredKeyUsages) {
        PKIX_CHECK(
            PKIX_ProcessingParams_GetTargetCertConstraints(procParams,
                                                           &certSelector, plContext),
            PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);

        PKIX_CHECK(
            PKIX_CertSelector_GetCommonCertSelectorParams(certSelector,
                                                          &certSelParams, plContext),
            PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);

        PKIX_CHECK(
            PKIX_ComCertSelParams_SetKeyUsage(certSelParams, requiredKeyUsages,
                                              plContext),
            PKIX_COMCERTSELPARAMSSETKEYUSAGEFAILED);
    }
cleanup:
    PKIX_DECREF(certSelector);
    PKIX_DECREF(certSelParams);

    PKIX_RETURN(CERTVFYPKIX);
}

/*
 * Unused parameters:
 *
 *  CERTCertList *initialChain,
 *  CERTCertStores certStores,
 *  CERTCertRevCheckers certRevCheckers,
 *  CERTCertChainCheckers certChainCheckers,
 *  SECItem *initPolicies,
 *  PRBool policyQualifierRejected,
 *  PRBool anyPolicyInhibited,
 *  PRBool reqExplicitPolicy,
 *  PRBool policyMappingInhibited,
 *  PKIX_CertSelector certConstraints,
 */

/*
 * FUNCTION: cert_CreatePkixProcessingParams
 * DESCRIPTION:
 *
 * Creates and fills in PKIX_ProcessingParams structure to be used
 * for certificate chain building.
 *
 * PARAMETERS:
 *  "cert"
 *      Pointer to the CERTCertificate: the leaf certificate of a chain.
 *  "time"
 *      Validity time.
 *  "wincx"
 *      Nss db password token.
 *  "useArena"
 *      Flags to use arena for data allocation during chain building process.
 *  "pprocParams"
 *      Address to return created processing parameters.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_CreatePkixProcessingParams(
    CERTCertificate *cert,
    PRBool checkSig, /* not used yet. See bug 391476 */
    PRTime time,
    void *wincx,
    PRBool useArena,
    PRBool disableOCSPRemoteFetching,
    PKIX_ProcessingParams **pprocParams,
    void **pplContext)
{
    PKIX_List *anchors = NULL;
    PKIX_PL_Cert *targetCert = NULL;
    PKIX_PL_Date *date = NULL;
    PKIX_ProcessingParams *procParams = NULL;
    PKIX_CertSelector *certSelector = NULL;
    PKIX_ComCertSelParams *certSelParams = NULL;
    PKIX_CertStore *certStore = NULL;
    PKIX_List *certStores = NULL;
    PKIX_RevocationChecker *revChecker = NULL;
    PKIX_UInt32 methodFlags = 0;
    void *plContext = NULL;
    CERTStatusConfig *statusConfig = NULL;

    PKIX_ENTER(CERTVFYPKIX, "cert_CreatePkixProcessingParams");
    PKIX_NULLCHECK_TWO(cert, pprocParams);

    PKIX_CHECK(
        PKIX_PL_NssContext_Create(0, useArena, wincx, &plContext),
        PKIX_NSSCONTEXTCREATEFAILED);

    *pplContext = plContext;

#ifdef PKIX_NOTDEF
    /* Functions should be implemented in patch for 390532 */
    PKIX_CHECK(
        pkix_pl_NssContext_SetCertSignatureCheck(checkSig,
                                                 (PKIX_PL_NssContext *)plContext),
        PKIX_NSSCONTEXTSETCERTSIGNCHECKFAILED);

#endif /* PKIX_NOTDEF */

    PKIX_CHECK(
        PKIX_ProcessingParams_Create(&procParams, plContext),
        PKIX_PROCESSINGPARAMSCREATEFAILED);

    PKIX_CHECK(
        PKIX_ComCertSelParams_Create(&certSelParams, plContext),
        PKIX_COMCERTSELPARAMSCREATEFAILED);

    PKIX_CHECK(
        PKIX_PL_Cert_CreateFromCERTCertificate(cert, &targetCert, plContext),
        PKIX_CERTCREATEWITHNSSCERTFAILED);

    PKIX_CHECK(
        PKIX_ComCertSelParams_SetCertificate(certSelParams,
                                             targetCert, plContext),
        PKIX_COMCERTSELPARAMSSETCERTIFICATEFAILED);

    PKIX_CHECK(
        PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext),
        PKIX_COULDNOTCREATECERTSELECTOROBJECT);

    PKIX_CHECK(
        PKIX_CertSelector_SetCommonCertSelectorParams(certSelector,
                                                      certSelParams, plContext),
        PKIX_CERTSELECTORSETCOMMONCERTSELECTORPARAMSFAILED);

    PKIX_CHECK(
        PKIX_ProcessingParams_SetTargetCertConstraints(procParams,
                                                       certSelector, plContext),
        PKIX_PROCESSINGPARAMSSETTARGETCERTCONSTRAINTSFAILED);

    /* Turn off quialification of target cert since leaf cert is
     * already check for date validity, key usages and extended
     * key usages. */
    PKIX_CHECK(
        PKIX_ProcessingParams_SetQualifyTargetCert(procParams, PKIX_FALSE,
                                                   plContext),
        PKIX_PROCESSINGPARAMSSETQUALIFYTARGETCERTFLAGFAILED);

    PKIX_CHECK(
        PKIX_PL_Pk11CertStore_Create(&certStore, plContext),
        PKIX_PK11CERTSTORECREATEFAILED);

    PKIX_CHECK(
        PKIX_List_Create(&certStores, plContext),
        PKIX_UNABLETOCREATELIST);

    PKIX_CHECK(
        PKIX_List_AppendItem(certStores, (PKIX_PL_Object *)certStore,
                             plContext),
        PKIX_LISTAPPENDITEMFAILED);

    PKIX_CHECK(
        PKIX_ProcessingParams_SetCertStores(procParams, certStores,
                                            plContext),
        PKIX_PROCESSINGPARAMSADDCERTSTOREFAILED);

    PKIX_CHECK(
        PKIX_PL_Date_CreateFromPRTime(time, &date, plContext),
        PKIX_DATECREATEFROMPRTIMEFAILED);

    PKIX_CHECK(
        PKIX_ProcessingParams_SetDate(procParams, date, plContext),
        PKIX_PROCESSINGPARAMSSETDATEFAILED);

    PKIX_CHECK(
        PKIX_RevocationChecker_Create(
            PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
                PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
            PKIX_REV_MI_TEST_ALL_LOCAL_INFORMATION_FIRST |
                PKIX_REV_MI_NO_OVERALL_INFO_REQUIREMENT,
            &revChecker, plContext),
        PKIX_REVOCATIONCHECKERCREATEFAILED);

    PKIX_CHECK(
        PKIX_ProcessingParams_SetRevocationChecker(procParams, revChecker,
                                                   plContext),
        PKIX_PROCESSINGPARAMSSETREVOCATIONCHECKERFAILED);

    /* CRL method flags */
    methodFlags =
        PKIX_REV_M_TEST_USING_THIS_METHOD |
        PKIX_REV_M_FORBID_NETWORK_FETCHING |
        PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE | /* 0 */
        PKIX_REV_M_IGNORE_MISSING_FRESH_INFO |   /* 0 */
        PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;

    /* add CRL revocation method to check the leaf certificate */
    PKIX_CHECK(
        PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
                                                  PKIX_RevocationMethod_CRL, methodFlags,
                                                  0, NULL, PKIX_TRUE, plContext),
        PKIX_REVOCATIONCHECKERADDMETHODFAILED);

    /* add CRL revocation method for other certs in the chain. */
    PKIX_CHECK(
        PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
                                                  PKIX_RevocationMethod_CRL, methodFlags,
                                                  0, NULL, PKIX_FALSE, plContext),
        PKIX_REVOCATIONCHECKERADDMETHODFAILED);

    /* For compatibility with the old code, need to check that
     * statusConfig is set in the db handle and status checker
     * is defined befor allow ocsp status check on the leaf cert.*/
    statusConfig = CERT_GetStatusConfig(CERT_GetDefaultCertDB());
    if (statusConfig != NULL && statusConfig->statusChecker != NULL) {

        /* Enable OCSP revocation checking for the leaf cert. */
        /* OCSP method flags */
        methodFlags =
            PKIX_REV_M_TEST_USING_THIS_METHOD |
            PKIX_REV_M_ALLOW_NETWORK_FETCHING |        /* 0 */
            PKIX_REV_M_ALLOW_IMPLICIT_DEFAULT_SOURCE | /* 0 */
            PKIX_REV_M_SKIP_TEST_ON_MISSING_SOURCE |   /* 0 */
            PKIX_REV_M_IGNORE_MISSING_FRESH_INFO |     /* 0 */
            PKIX_REV_M_CONTINUE_TESTING_ON_FRESH_INFO;

        /* Disabling ocsp fetching when checking the status
         * of ocsp response signer. Here and in the next if,
         * adjust flags for ocsp signer cert validation case. */
        if (disableOCSPRemoteFetching) {
            methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
        }

        if (ocsp_FetchingFailureIsVerificationFailure() &&
            !disableOCSPRemoteFetching) {
            methodFlags |=
                PKIX_REV_M_FAIL_ON_MISSING_FRESH_INFO;
        }

        /* add OCSP revocation method to check only the leaf certificate.*/
        PKIX_CHECK(
            PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
                                                      PKIX_RevocationMethod_OCSP, methodFlags,
                                                      1, NULL, PKIX_TRUE, plContext),
            PKIX_REVOCATIONCHECKERADDMETHODFAILED);
    }

    PKIX_CHECK(
        PKIX_ProcessingParams_SetAnyPolicyInhibited(procParams, PR_FALSE,
                                                    plContext),
        PKIX_PROCESSINGPARAMSSETANYPOLICYINHIBITED);

    PKIX_CHECK(
        PKIX_ProcessingParams_SetExplicitPolicyRequired(procParams, PR_FALSE,
                                                        plContext),
        PKIX_PROCESSINGPARAMSSETEXPLICITPOLICYREQUIRED);

    PKIX_CHECK(
        PKIX_ProcessingParams_SetPolicyMappingInhibited(procParams, PR_FALSE,
                                                        plContext),
        PKIX_PROCESSINGPARAMSSETPOLICYMAPPINGINHIBITED);

    *pprocParams = procParams;
    procParams = NULL;

cleanup:
    PKIX_DECREF(anchors);
    PKIX_DECREF(targetCert);
    PKIX_DECREF(date);
    PKIX_DECREF(certSelector);
    PKIX_DECREF(certSelParams);
    PKIX_DECREF(certStore);
    PKIX_DECREF(certStores);
    PKIX_DECREF(procParams);
    PKIX_DECREF(revChecker);

    PKIX_RETURN(CERTVFYPKIX);
}

/*
 * FUNCTION: cert_PkixToNssCertsChain
 * DESCRIPTION:
 *
 * Converts pkix cert list into nss cert list.
 *
 * PARAMETERS:
 *  "pkixCertChain"
 *      Pkix certificate list.
 *  "pvalidChain"
 *      An address of returned nss certificate list.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_PkixToNssCertsChain(
    PKIX_List *pkixCertChain,
    CERTCertList **pvalidChain,
    void *plContext)
{
    PLArenaPool *arena = NULL;
    CERTCertificate *nssCert = NULL;
    CERTCertList *validChain = NULL;
    PKIX_PL_Object *certItem = NULL;
    PKIX_UInt32 length = 0;
    PKIX_UInt32 i = 0;

    PKIX_ENTER(CERTVFYPKIX, "cert_PkixToNssCertsChain");
    PKIX_NULLCHECK_ONE(pvalidChain);

    if (pkixCertChain == NULL) {
        goto cleanup;
    }
    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
    if (arena == NULL) {
        PKIX_ERROR(PKIX_OUTOFMEMORY);
    }
    validChain = (CERTCertList *)PORT_ArenaZAlloc(arena, sizeof(CERTCertList));
    if (validChain == NULL) {
        PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
    }
    PR_INIT_CLIST(&validChain->list);
    validChain->arena = arena;
    arena = NULL;

    PKIX_CHECK(
        PKIX_List_GetLength(pkixCertChain, &length, plContext),
        PKIX_LISTGETLENGTHFAILED);

    for (i = 0; i < length; i++) {
        CERTCertListNode *node = NULL;

        PKIX_CHECK(
            PKIX_List_GetItem(pkixCertChain, i, &certItem, plContext),
            PKIX_LISTGETITEMFAILED);

        PKIX_CHECK(
            PKIX_PL_Cert_GetCERTCertificate((PKIX_PL_Cert *)certItem, &nssCert,
                                            plContext),
            PKIX_CERTGETCERTCERTIFICATEFAILED);

        node =
            (CERTCertListNode *)PORT_ArenaZAlloc(validChain->arena,
                                                 sizeof(CERTCertListNode));
        if (node == NULL) {
            PKIX_ERROR(PKIX_PORTARENAALLOCFAILED);
        }

        PR_INSERT_BEFORE(&node->links, &validChain->list);

        node->cert = nssCert;
        nssCert = NULL;

        PKIX_DECREF(certItem);
    }

    *pvalidChain = validChain;

cleanup:
    if (PKIX_ERROR_RECEIVED) {
        if (validChain) {
            CERT_DestroyCertList(validChain);
        } else if (arena) {
            PORT_FreeArena(arena, PR_FALSE);
        }
        if (nssCert) {
            CERT_DestroyCertificate(nssCert);
        }
    }
    PKIX_DECREF(certItem);

    PKIX_RETURN(CERTVFYPKIX);
}

/*
 * FUNCTION: cert_BuildAndValidateChain
 * DESCRIPTION:
 *
 * The function builds and validates a cert chain based on certificate
 * selection criterias from procParams. This function call PKIX_BuildChain
 * to accomplish chain building. If PKIX_BuildChain returns with incomplete
 * IO, the function waits with PR_Poll until the blocking IO is finished and
 * return control back to PKIX_BuildChain.
 *
 * PARAMETERS:
 *  "procParams"
 *      Processing parameters to be used during chain building.
 *  "pResult"
 *      Returned build result.
 *  "pVerifyNode"
 *      Returned pointed to verify node structure: the tree-like structure
 *      that reports points of chain building failures.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_BuildAndValidateChain(
    PKIX_ProcessingParams *procParams,
    PKIX_BuildResult **pResult,
    PKIX_VerifyNode **pVerifyNode,
    void *plContext)
{
    PKIX_BuildResult *result = NULL;
    PKIX_VerifyNode *verifyNode = NULL;
    void *nbioContext = NULL;
    void *state = NULL;

    PKIX_ENTER(CERTVFYPKIX, "cert_BuildAndVerifyChain");
    PKIX_NULLCHECK_TWO(procParams, pResult);

    do {
        if (nbioContext && state) {
            /* PKIX-XXX: need to test functionality of NBIO handling in libPkix.
             * See bug 391180 */
            PRInt32 filesReady = 0;
            PRPollDesc *pollDesc = (PRPollDesc *)nbioContext;
            filesReady = PR_Poll(pollDesc, 1, PR_INTERVAL_NO_TIMEOUT);
            if (filesReady <= 0) {
                PKIX_ERROR(PKIX_PRPOLLRETBADFILENUM);
            }
        }

        PKIX_CHECK(
            PKIX_BuildChain(procParams, &nbioContext, &state,
                            &result, &verifyNode, plContext),
            PKIX_UNABLETOBUILDCHAIN);

    } while (nbioContext && state);

    *pResult = result;

cleanup:
    if (pVerifyNode) {
        *pVerifyNode = verifyNode;
    }

    PKIX_RETURN(CERTVFYPKIX);
}

/*
 * FUNCTION: cert_PkixErrorToNssCode
 * DESCRIPTION:
 *
 * Converts pkix error(PKIX_Error) structure to PR error codes.
 *
 * PKIX-XXX to be implemented. See 391183.
 *
 * PARAMETERS:
 *  "error"
 *      Pkix error that will be converted.
 *  "nssCode"
 *      Corresponding nss error code.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_PkixErrorToNssCode(
    PKIX_Error *error,
    SECErrorCodes *pNssErr,
    void *plContext)
{
    int errLevel = 0;
    PKIX_Int32 nssErr = 0;
    PKIX_Error *errPtr = error;

    PKIX_ENTER(CERTVFYPKIX, "cert_PkixErrorToNssCode");
    PKIX_NULLCHECK_TWO(error, pNssErr);

    /* Loop until we find at least one error with non-null
     * plErr code, that is going to be nss error code. */
    while (errPtr) {
        if (errPtr->plErr && !nssErr) {
            nssErr = errPtr->plErr;
            if (!pkixLog)
                break;
        }
        if (pkixLog) {
#ifdef PKIX_ERROR_DESCRIPTION
            PR_LOG(pkixLog, 2, ("Error at level %d: %s\n", errLevel,
                                PKIX_ErrorText[errPtr->errCode]));
#else
            PR_LOG(pkixLog, 2, ("Error at level %d: Error code %d\n", errLevel,
                                errPtr->errCode));
#endif /* PKIX_ERROR_DESCRIPTION */
        }
        errPtr = errPtr->cause;
        errLevel += 1;
    }
    PORT_Assert(nssErr);
    if (!nssErr) {
        *pNssErr = SEC_ERROR_LIBPKIX_INTERNAL;
    } else {
        *pNssErr = nssErr;
    }

    PKIX_RETURN(CERTVFYPKIX);
}

/*
 * FUNCTION: cert_GetLogFromVerifyNode
 * DESCRIPTION:
 *
 * Recursive function that converts verify node tree-like set of structures
 * to CERTVerifyLog.
 *
 * PARAMETERS:
 *  "log"
 *      Pointed to already allocated CERTVerifyLog structure.
 *  "node"
 *      A node of PKIX_VerifyNode tree.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_GetLogFromVerifyNode(
    CERTVerifyLog *log,
    PKIX_VerifyNode *node,
    void *plContext)
{
    PKIX_List *children = NULL;
    PKIX_VerifyNode *childNode = NULL;

    PKIX_ENTER(CERTVFYPKIX, "cert_GetLogFromVerifyNode");

    children = node->children;

    if (children == NULL) {
        PKIX_ERRORCODE errCode = PKIX_ANCHORDIDNOTCHAINTOCERT;
        if (node->error && node->error->errCode != errCode) {
            if (log != NULL) {
                SECErrorCodes nssErrorCode = 0;
                CERTCertificate *cert = NULL;

                cert = node->verifyCert->nssCert;

                PKIX_CHECK(
                    cert_PkixErrorToNssCode(node->error, &nssErrorCode,
                                            plContext),
                    PKIX_GETPKIXERRORCODEFAILED);

                cert_AddToVerifyLog(log, cert, nssErrorCode, node->depth, NULL);
            }
        }
        PKIX_RETURN(CERTVFYPKIX);
    } else {
        PRUint32 i = 0;
        PKIX_UInt32 length = 0;

        PKIX_CHECK(
            PKIX_List_GetLength(children, &length, plContext),
            PKIX_LISTGETLENGTHFAILED);

        for (i = 0; i < length; i++) {

            PKIX_CHECK(
                PKIX_List_GetItem(children, i, (PKIX_PL_Object **)&childNode,
                                  plContext),
                PKIX_LISTGETITEMFAILED);

            PKIX_CHECK(
                cert_GetLogFromVerifyNode(log, childNode, plContext),
                PKIX_ERRORINRECURSIVEEQUALSCALL);

            PKIX_DECREF(childNode);
        }
    }

cleanup:
    PKIX_DECREF(childNode);

    PKIX_RETURN(CERTVFYPKIX);
}

/*
 * FUNCTION: cert_GetBuildResults
 * DESCRIPTION:
 *
 * Converts pkix build results to nss results. This function is called
 * regardless of build result.
 *
 * If it called after chain was successfully constructed, then it will
 * convert:
 *   * pkix cert list that represent the chain to nss cert list
 *   * trusted root the chain was anchored to nss certificate.
 *
 * In case of failure it will convert:
 *   * pkix error to PR error code(will set it with PORT_SetError)
 *   * pkix validation log to nss CERTVerifyLog
 *
 * PARAMETERS:
 *  "buildResult"
 *      Build results returned by PKIX_BuildChain.
 *  "verifyNode"
 *      Tree-like structure of chain building/validation failures
 *      returned by PKIX_BuildChain. Ignored in case of success.
 *  "error"
 *      Final error returned by PKIX_BuildChain. Should be NULL in
 *      case of success.
 *  "log"
 *      Address of pre-allocated(if not NULL) CERTVerifyLog structure.
 *  "ptrustedRoot"
 *      Address of returned trusted root the chain was anchored to.
 *  "pvalidChain"
 *      Address of returned valid chain.
 *  "plContext"
 *      Platform-specific context pointer.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  Returns NULL if the function succeeds.
 *  Returns a Cert Verify Error if the function fails in an unrecoverable way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
cert_GetBuildResults(
    PKIX_BuildResult *buildResult,
    PKIX_VerifyNode *verifyNode,
    PKIX_Error *error,
    CERTVerifyLog *log,
    CERTCertificate **ptrustedRoot,
    CERTCertList **pvalidChain,
    void *plContext)
{
    PKIX_ValidateResult *validResult = NULL;
    CERTCertList *validChain = NULL;
    CERTCertificate *trustedRoot = NULL;
    PKIX_TrustAnchor *trustAnchor = NULL;
    PKIX_PL_Cert *trustedCert = NULL;
    PKIX_List *pkixCertChain = NULL;

    PKIX_ENTER(CERTVFYPKIX, "cert_GetBuildResults");
    if (buildResult == NULL && error == NULL) {
        PKIX_ERROR(PKIX_NULLARGUMENT);
    }

    if (error) {
        SECErrorCodes nssErrorCode = 0;
        if (verifyNode) {
            PKIX_Error *tmpError =
                cert_GetLogFromVerifyNode(log, verifyNode, plContext);
            if (tmpError) {
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
            }
        }
        cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
        PORT_SetError(nssErrorCode);
        goto cleanup;
    }

    if (pvalidChain) {
        PKIX_CHECK(
            PKIX_BuildResult_GetCertChain(buildResult, &pkixCertChain,
                                          plContext),
            PKIX_BUILDRESULTGETCERTCHAINFAILED);

        PKIX_CHECK(
            cert_PkixToNssCertsChain(pkixCertChain, &validChain, plContext),
            PKIX_CERTCHAINTONSSCHAINFAILED);
    }

    if (ptrustedRoot) {
        PKIX_CHECK(
            PKIX_BuildResult_GetValidateResult(buildResult, &validResult,
                                               plContext),
            PKIX_BUILDRESULTGETVALIDATERESULTFAILED);

        PKIX_CHECK(
            PKIX_ValidateResult_GetTrustAnchor(validResult, &trustAnchor,
                                               plContext),
            PKIX_VALIDATERESULTGETTRUSTANCHORFAILED);

        PKIX_CHECK(
            PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustedCert,
                                            plContext),
            PKIX_TRUSTANCHORGETTRUSTEDCERTFAILED);

        PKIX_CHECK(
            PKIX_PL_Cert_GetCERTCertificate(trustedCert, &trustedRoot,
                                            plContext),
            PKIX_CERTGETCERTCERTIFICATEFAILED);
    }

    PORT_Assert(!PKIX_ERROR_RECEIVED);

    if (trustedRoot) {
        *ptrustedRoot = trustedRoot;
    }
    if (validChain) {
        *pvalidChain = validChain;
    }

cleanup:
    if (PKIX_ERROR_RECEIVED) {
        if (trustedRoot) {
            CERT_DestroyCertificate(trustedRoot);
        }
        if (validChain) {
            CERT_DestroyCertList(validChain);
        }
    }
    PKIX_DECREF(trustAnchor);
    PKIX_DECREF(trustedCert);
    PKIX_DECREF(pkixCertChain);
    PKIX_DECREF(validResult);
    PKIX_DECREF(error);
    PKIX_DECREF(verifyNode);
    PKIX_DECREF(buildResult);

    PKIX_RETURN(CERTVFYPKIX);
}
#endif /* NSS_DISABLE_LIBPKIX */

/*
 * FUNCTION: cert_VerifyCertChainPkix
 * DESCRIPTION:
 *
 * The main wrapper function that is called from CERT_VerifyCert and
 * CERT_VerifyCACertForUsage functions to validate cert with libpkix.
 *
 * PARAMETERS:
 *  "cert"
 *      Leaf certificate of a chain we want to build.
 *  "checkSig"
 *      Certificate signatures will not be verified if this
 *      flag is set to PR_FALSE.
 *  "requiredUsage"
 *      Required usage for certificate and chain.
 *  "time"
 *      Validity time.
 *  "wincx"
 *      Nss database password token.
 *  "log"
 *      Address of already allocated CERTVerifyLog structure. Not
 *      used if NULL;
 *  "pSigerror"
 *      Address of PRBool. If not NULL, returns true is cert chain
 *      was invalidated because of bad certificate signature.
 *  "pRevoked"
 *      Address of PRBool. If not NULL, returns true is cert chain
 *      was invalidated because a revoked certificate was found in
 *      the chain.
 * THREAD SAFETY:
 *  Thread Safe (see Thread Safety Definitions in Programmer's Guide)
 * RETURNS:
 *  SECFailure is chain building process has failed. SECSuccess otherwise.
 */
SECStatus
cert_VerifyCertChainPkix(
    CERTCertificate *cert,
    PRBool checkSig,
    SECCertUsage requiredUsage,
    PRTime time,
    void *wincx,
    CERTVerifyLog *log,
    PRBool *pSigerror,
    PRBool *pRevoked)
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
#else
    PKIX_ProcessingParams *procParams = NULL;
    PKIX_BuildResult *result = NULL;
    PKIX_VerifyNode *verifyNode = NULL;
    PKIX_Error *error = NULL;

    SECStatus rv = SECFailure;
    void *plContext = NULL;

#ifdef PKIX_OBJECT_LEAK_TEST
    int leakedObjNum = 0;
    int memLeakLoopCount = 0;
    int objCountTable[PKIX_NUMTYPES];
    int fnInvLocalCount = 0;
    PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;

    if (usePKIXValidationEngine) {
        /* current memory leak testing implementation does not allow
         * to run simultaneous tests one the same or a different threads.
         * Setting the variable to false, to make additional chain
         * validations be handled by old nss. */
        usePKIXValidationEngine = PR_FALSE;
    }
    testStartFnStackPosition = 2;
    fnStackNameArr[0] = "cert_VerifyCertChainPkix";
    fnStackInvCountArr[0] = 0;
    PKIX_Boolean abortOnLeak =
        (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE
                                                                         : PKIX_TRUE;
    runningLeakTest = PKIX_TRUE;

    /* Prevent multi-threaded run of object leak test */
    fnInvLocalCount = PR_ATOMIC_INCREMENT(&parallelFnInvocationCount);
    PORT_Assert(fnInvLocalCount == 1);

    do {
        rv = SECFailure;
        plContext = NULL;
        procParams = NULL;
        result = NULL;
        verifyNode = NULL;
        error = NULL;
        errorGenerated = PKIX_FALSE;
        stackPosition = 0;

        if (leakedObjNum) {
            pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
        }
        memLeakLoopCount += 1;
#endif /* PKIX_OBJECT_LEAK_TEST */

        error =
            cert_CreatePkixProcessingParams(cert, checkSig, time, wincx,
                                            PR_FALSE /*use arena*/,
                                            requiredUsage == certUsageStatusResponder,
                                            &procParams, &plContext);
        if (error) {
            goto cleanup;
        }

        error =
            cert_ProcessingParamsSetKeyAndCertUsage(procParams, requiredUsage, 0,
                                                    plContext);
        if (error) {
            goto cleanup;
        }

        error =
            cert_BuildAndValidateChain(procParams, &result, &verifyNode, plContext);
        if (error) {
            goto cleanup;
        }

        if (pRevoked) {
            /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
            *pRevoked = PR_FALSE;
        }
        if (pSigerror) {
            /* Currently always PR_FALSE. Will be fixed as a part of 394077 */
            *pSigerror = PR_FALSE;
        }
        rv = SECSuccess;

    cleanup:
        error = cert_GetBuildResults(result, verifyNode, error, log, NULL, NULL,
                                     plContext);
        if (error) {
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
        }
        if (procParams) {
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);
        }
        if (plContext) {
            PKIX_PL_NssContext_Destroy(plContext);
        }

#ifdef PKIX_OBJECT_LEAK_TEST
        leakedObjNum =
            pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);

        if (pkixLog && leakedObjNum) {
            PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
                                "Stack %s\n",
                                memLeakLoopCount, errorFnStackString));
        }
        PR_Free(errorFnStackString);
        errorFnStackString = NULL;
        if (abortOnLeak) {
            PORT_Assert(leakedObjNum == 0);
        }

    } while (errorGenerated);

    runningLeakTest = PKIX_FALSE;
    PR_ATOMIC_DECREMENT(&parallelFnInvocationCount);
    usePKIXValidationEngine = savedUsePkixEngFlag;
#endif /* PKIX_OBJECT_LEAK_TEST */

    return rv;
#endif /* NSS_DISABLE_LIBPKIX */
}

#ifndef NSS_DISABLE_LIBPKIX
PKIX_CertSelector *
cert_GetTargetCertConstraints(CERTCertificate *target, void *plContext)
{
    PKIX_ComCertSelParams *certSelParams = NULL;
    PKIX_CertSelector *certSelector = NULL;
    PKIX_CertSelector *r = NULL;
    PKIX_PL_Cert *eeCert = NULL;
    PKIX_Error *error = NULL;

    error = PKIX_PL_Cert_CreateFromCERTCertificate(target, &eeCert, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_CertSelector_Create(NULL, NULL, &certSelector, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_ComCertSelParams_Create(&certSelParams, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_ComCertSelParams_SetCertificate(
        certSelParams, eeCert, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_CertSelector_SetCommonCertSelectorParams(certSelector, certSelParams, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certSelector, plContext);
    if (error == NULL)
        r = certSelector;

cleanup:
    if (certSelParams != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelParams, plContext);

    if (eeCert != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)eeCert, plContext);

    if (certSelector != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);

    if (error != NULL) {
        SECErrorCodes nssErr;

        cert_PkixErrorToNssCode(error, &nssErr, plContext);
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
        PORT_SetError(nssErr);
    }

    return r;
}

static PKIX_List *
cert_GetCertStores(void *plContext)
{
    PKIX_CertStore *certStore = NULL;
    PKIX_List *certStores = NULL;
    PKIX_List *r = NULL;
    PKIX_Error *error = NULL;

    error = PKIX_PL_Pk11CertStore_Create(&certStore, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_List_Create(&certStores, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_List_AppendItem(certStores,
                                 (PKIX_PL_Object *)certStore, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)certStores, plContext);
    if (error == NULL)
        r = certStores;

cleanup:
    if (certStores != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);

    if (certStore != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStore, plContext);

    if (error != NULL) {
        SECErrorCodes nssErr;

        cert_PkixErrorToNssCode(error, &nssErr, plContext);
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
        PORT_SetError(nssErr);
    }

    return r;
}

struct fake_PKIX_PL_CertStruct {
    CERTCertificate *nssCert;
};

/* This needs to be part of the PKIX_PL_* */
/* This definitely needs to go away, and be replaced with
   a real accessor function in PKIX */
static CERTCertificate *
cert_NSSCertFromPKIXCert(const PKIX_PL_Cert *pkix_cert)
{
    struct fake_PKIX_PL_CertStruct *fcert = NULL;

    fcert = (struct fake_PKIX_PL_CertStruct *)pkix_cert;

    return CERT_DupCertificate(fcert->nssCert);
}

PKIX_List *
cert_PKIXMakeOIDList(const SECOidTag *oids, int oidCount, void *plContext)
{
    PKIX_List *r = NULL;
    PKIX_List *policyList = NULL;
    PKIX_PL_OID *policyOID = NULL;
    PKIX_Error *error = NULL;
    int i;

    error = PKIX_List_Create(&policyList, plContext);
    if (error != NULL) {
        goto cleanup;
    }

    for (i = 0; i < oidCount; i++) {
        error = PKIX_PL_OID_Create(oids[i], &policyOID, plContext);
        if (error) {
            goto cleanup;
        }
        error = PKIX_List_AppendItem(policyList,
                                     (PKIX_PL_Object *)policyOID, plContext);
        if (error != NULL) {
            goto cleanup;
        }
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
        policyOID = NULL;
    }

    error = PKIX_List_SetImmutable(policyList, plContext);
    if (error != NULL)
        goto cleanup;

    error = PKIX_PL_Object_IncRef((PKIX_PL_Object *)policyList, plContext);
    if (error == NULL)
        r = policyList;

cleanup:
    if (policyOID != NULL) {
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOID, plContext);
    }
    if (policyList != NULL) {
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyList, plContext);
    }
    if (error != NULL) {
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
    }

    return r;
}

CERTValOutParam *
cert_pkix_FindOutputParam(CERTValOutParam *params, const CERTValParamOutType t)
{
    CERTValOutParam *i;
    if (params == NULL) {
        return NULL;
    }
    for (i = params; i->type != cert_po_end; i++) {
        if (i->type == t) {
            return i;
        }
    }
    return NULL;
}

static PKIX_Error *
setRevocationMethod(PKIX_RevocationChecker *revChecker,
                    PKIX_ProcessingParams *procParams,
                    const CERTRevocationTests *revTest,
                    CERTRevocationMethodIndex certRevMethod,
                    PKIX_RevocationMethodType pkixRevMethod,
                    PKIX_Boolean verifyResponderUsages,
                    PKIX_Boolean isLeafTest,
                    void *plContext)
{
    PKIX_UInt32 methodFlags = 0;
    PKIX_Error *error = NULL;
    PKIX_UInt32 priority = 0;

    if (revTest->number_of_defined_methods <= (PRUint32)certRevMethod) {
        return NULL;
    }
    if (revTest->preferred_methods) {
        unsigned int i = 0;
        for (; i < revTest->number_of_preferred_methods; i++) {
            if (revTest->preferred_methods[i] == certRevMethod)
                break;
        }
        priority = i;
    }
    methodFlags = revTest->cert_rev_flags_per_method[certRevMethod];
    if (verifyResponderUsages &&
        pkixRevMethod == PKIX_RevocationMethod_OCSP) {
        methodFlags |= PKIX_REV_M_FORBID_NETWORK_FETCHING;
    }
    error =
        PKIX_RevocationChecker_CreateAndAddMethod(revChecker, procParams,
                                                  pkixRevMethod, methodFlags,
                                                  priority, NULL,
                                                  isLeafTest, plContext);
    return error;
}

SECStatus
cert_pkixSetParam(PKIX_ProcessingParams *procParams,
                  const CERTValInParam *param, void *plContext)
{
    PKIX_Error *error = NULL;
    SECStatus r = SECSuccess;
    PKIX_PL_Date *date = NULL;
    PKIX_List *policyOIDList = NULL;
    PKIX_List *certListPkix = NULL;
    const CERTRevocationFlags *flags;
    SECErrorCodes errCode = SEC_ERROR_INVALID_ARGS;
    const CERTCertList *certList = NULL;
    CERTCertListNode *node;
    PKIX_PL_Cert *certPkix = NULL;
    PKIX_TrustAnchor *trustAnchor = NULL;
    PKIX_RevocationChecker *revChecker = NULL;
    PKIX_PL_NssContext *nssContext = (PKIX_PL_NssContext *)plContext;

    /* XXX we need a way to map generic PKIX error to generic NSS errors */

    switch (param->type) {

        case cert_pi_policyOID:

            /* needed? */
            error = PKIX_ProcessingParams_SetExplicitPolicyRequired(
                procParams, PKIX_TRUE, plContext);

            if (error != NULL) {
                break;
            }

            policyOIDList = cert_PKIXMakeOIDList(param->value.array.oids,
                                                 param->value.arraySize, plContext);
            if (policyOIDList == NULL) {
                r = SECFailure;
                PORT_SetError(SEC_ERROR_INVALID_ARGS);
                break;
            }

            error = PKIX_ProcessingParams_SetInitialPolicies(
                procParams, policyOIDList, plContext);
            break;

        case cert_pi_date:
            if (param->value.scalar.time == 0) {
                error = PKIX_PL_Date_Create_UTCTime(NULL, &date, plContext);
                if (error != NULL) {
                    errCode = SEC_ERROR_INVALID_TIME;
                    break;
                }
            } else {
                error = pkix_pl_Date_CreateFromPRTime(param->value.scalar.time,
                                                      &date, plContext);
                if (error != NULL) {
                    errCode = SEC_ERROR_INVALID_TIME;
                    break;
                }
            }

            error = PKIX_ProcessingParams_SetDate(procParams, date, plContext);
            if (error != NULL) {
                errCode = SEC_ERROR_INVALID_TIME;
            }
            break;

        case cert_pi_revocationFlags: {
            PKIX_UInt32 leafIMFlags = 0;
            PKIX_UInt32 chainIMFlags = 0;
            PKIX_Boolean validatingResponderCert = PKIX_FALSE;

            flags = param->value.pointer.revocation;
            if (!flags) {
                PORT_SetError(errCode);
                r = SECFailure;
                break;
            }

            leafIMFlags =
                flags->leafTests.cert_rev_method_independent_flags;
            chainIMFlags =
                flags->chainTests.cert_rev_method_independent_flags;

            error =
                PKIX_RevocationChecker_Create(leafIMFlags, chainIMFlags,
                                              &revChecker, plContext);
            if (error) {
                break;
            }

            error =
                PKIX_ProcessingParams_SetRevocationChecker(procParams,
                                                           revChecker, plContext);
            if (error) {
                break;
            }

            if (((PKIX_PL_NssContext *)plContext)->certificateUsage &
                certificateUsageStatusResponder) {
                validatingResponderCert = PKIX_TRUE;
            }

            error = setRevocationMethod(revChecker,
                                        procParams, &flags->leafTests,
                                        cert_revocation_method_crl,
                                        PKIX_RevocationMethod_CRL,
                                        validatingResponderCert,
                                        PKIX_TRUE, plContext);
            if (error) {
                break;
            }

            error = setRevocationMethod(revChecker,
                                        procParams, &flags->leafTests,
                                        cert_revocation_method_ocsp,
                                        PKIX_RevocationMethod_OCSP,
                                        validatingResponderCert,
                                        PKIX_TRUE, plContext);
            if (error) {
                break;
            }

            error = setRevocationMethod(revChecker,
                                        procParams, &flags->chainTests,
                                        cert_revocation_method_crl,
                                        PKIX_RevocationMethod_CRL,
                                        validatingResponderCert,
                                        PKIX_FALSE, plContext);
            if (error) {
                break;
            }

            error = setRevocationMethod(revChecker,
                                        procParams, &flags->chainTests,
                                        cert_revocation_method_ocsp,
                                        PKIX_RevocationMethod_OCSP,
                                        validatingResponderCert,
                                        PKIX_FALSE, plContext);
            if (error) {
                break;
            }

        } break;

        case cert_pi_trustAnchors:
            certList = param->value.pointer.chain;
            if (!certList) {
                PORT_SetError(errCode);
                r = SECFailure;
                break;
            }
            error = PKIX_List_Create(&certListPkix, plContext);
            if (error != NULL) {
                break;
            }
            for (node = CERT_LIST_HEAD(certList); !CERT_LIST_END(node, certList);
                 node = CERT_LIST_NEXT(node)) {
                error = PKIX_PL_Cert_CreateFromCERTCertificate(node->cert,
                                                               &certPkix, plContext);
                if (error) {
                    break;
                }
                error = PKIX_TrustAnchor_CreateWithCert(certPkix, &trustAnchor,
                                                        plContext);
                if (error) {
                    break;
                }
                error = PKIX_List_AppendItem(certListPkix,
                                             (PKIX_PL_Object *)trustAnchor, plContext);
                if (error) {
                    break;
                }
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);
                trustAnchor = NULL;
                PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);
                certPkix = NULL;
            }
            error =
                PKIX_ProcessingParams_SetTrustAnchors(procParams, certListPkix,
                                                      plContext);
            break;

        case cert_pi_useAIACertFetch:
            error =
                PKIX_ProcessingParams_SetUseAIAForCertFetching(procParams,
                                                               (PRBool)(param->value.scalar.b !=
                                                                        0),
                                                               plContext);
            break;

        case cert_pi_chainVerifyCallback: {
            const CERTChainVerifyCallback *chainVerifyCallback =
                param->value.pointer.chainVerifyCallback;
            if (!chainVerifyCallback || !chainVerifyCallback->isChainValid) {
                PORT_SetError(errCode);
                r = SECFailure;
                break;
            }

            nssContext->chainVerifyCallback = *chainVerifyCallback;
        } break;

        case cert_pi_useOnlyTrustAnchors:
            error =
                PKIX_ProcessingParams_SetUseOnlyTrustAnchors(procParams,
                                                             (PRBool)(param->value.scalar.b !=
                                                                      0),
                                                             plContext);
            break;

        default:
            PORT_SetError(errCode);
            r = SECFailure;
            break;
    }

    if (policyOIDList != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)policyOIDList, plContext);

    if (date != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)date, plContext);

    if (revChecker != NULL)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)revChecker, plContext);

    if (certListPkix)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)certListPkix, plContext);

    if (trustAnchor)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);

    if (certPkix)
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)certPkix, plContext);

    if (error != NULL) {
        PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
        PORT_SetError(errCode);
        r = SECFailure;
    }

    return r;
}

void
cert_pkixDestroyValOutParam(CERTValOutParam *params)
{
    CERTValOutParam *i;

    if (params == NULL) {
        return;
    }
    for (i = params; i->type != cert_po_end; i++) {
        switch (i->type) {
            case cert_po_trustAnchor:
                if (i->value.pointer.cert) {
                    CERT_DestroyCertificate(i->value.pointer.cert);
                    i->value.pointer.cert = NULL;
                }
                break;

            case cert_po_certList:
                if (i->value.pointer.chain) {
                    CERT_DestroyCertList(i->value.pointer.chain);
                    i->value.pointer.chain = NULL;
                }
                break;

            default:
                break;
        }
    }
}

static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FORBID_NETWORK_FETCHING |
        CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
    /* ocsp */
    CERT_REV_M_TEST_USING_THIS_METHOD
};

static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FORBID_NETWORK_FETCHING |
        CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
    /* ocsp */
    0
};

static CERTRevocationMethodIndex
    certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference = {
        cert_revocation_method_crl
    };

static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy = {
    { /* leafTests */
      2,
      certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_LeafFlags,
      1,
      &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_Method_Preference,
      0 },
    { /* chainTests */
      2,
      certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy_ChainFlags,
      0,
      0,
      0 }
};
#endif /* NSS_DISABLE_LIBPKIX */

extern const CERTRevocationFlags *
CERT_GetClassicOCSPEnabledSoftFailurePolicy()
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return NULL;
#else
    return &certRev_NSS_3_11_Ocsp_Enabled_Soft_Policy;
#endif /* NSS_DISABLE_LIBPKIX */
}

#ifndef NSS_DISABLE_LIBPKIX
static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FORBID_NETWORK_FETCHING |
        CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
    /* ocsp */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO
};

static PRUint64 certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FORBID_NETWORK_FETCHING |
        CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
    /* ocsp */
    0
};

static CERTRevocationMethodIndex
    certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference = {
        cert_revocation_method_crl
    };

static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy = {
    { /* leafTests */
      2,
      certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_LeafFlags,
      1,
      &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_Method_Preference,
      0 },
    { /* chainTests */
      2,
      certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy_ChainFlags,
      0,
      0,
      0 }
};
#endif /* NSS_DISABLE_LIBPKIX */

extern const CERTRevocationFlags *
CERT_GetClassicOCSPEnabledHardFailurePolicy()
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return NULL;
#else
    return &certRev_NSS_3_11_Ocsp_Enabled_Hard_Policy;
#endif /* NSS_DISABLE_LIBPKIX */
}

#ifndef NSS_DISABLE_LIBPKIX
static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FORBID_NETWORK_FETCHING |
        CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
    /* ocsp */
    0
};

static PRUint64 certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FORBID_NETWORK_FETCHING |
        CERT_REV_M_CONTINUE_TESTING_ON_FRESH_INFO,
    /* ocsp */
    0
};

static const CERTRevocationFlags certRev_NSS_3_11_Ocsp_Disabled_Policy = {
    { /* leafTests */
      2,
      certRev_NSS_3_11_Ocsp_Disabled_Policy_LeafFlags,
      0,
      0,
      0 },
    { /* chainTests */
      2,
      certRev_NSS_3_11_Ocsp_Disabled_Policy_ChainFlags,
      0,
      0,
      0 }
};
#endif /* NSS_DISABLE_LIBPKIX */

extern const CERTRevocationFlags *
CERT_GetClassicOCSPDisabledPolicy()
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return NULL;
#else
    return &certRev_NSS_3_11_Ocsp_Disabled_Policy;
#endif /* NSS_DISABLE_LIBPKIX */
}

#ifndef NSS_DISABLE_LIBPKIX
static PRUint64 certRev_PKIX_Verify_Nist_Policy_LeafFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
        CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
    /* ocsp */
    0
};

static PRUint64 certRev_PKIX_Verify_Nist_Policy_ChainFlags[2] = {
    /* crl */
    CERT_REV_M_TEST_USING_THIS_METHOD |
        CERT_REV_M_FAIL_ON_MISSING_FRESH_INFO |
        CERT_REV_M_REQUIRE_INFO_ON_MISSING_SOURCE,
    /* ocsp */
    0
};

static const CERTRevocationFlags certRev_PKIX_Verify_Nist_Policy = {
    { /* leafTests */
      2,
      certRev_PKIX_Verify_Nist_Policy_LeafFlags,
      0,
      0,
      0 },
    { /* chainTests */
      2,
      certRev_PKIX_Verify_Nist_Policy_ChainFlags,
      0,
      0,
      0 }
};
#endif /* NSS_DISABLE_LIBPKIX */

extern const CERTRevocationFlags *
CERT_GetPKIXVerifyNistRevocationPolicy()
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return NULL;
#else
    return &certRev_PKIX_Verify_Nist_Policy;
#endif /* NSS_DISABLE_LIBPKIX */
}

CERTRevocationFlags *
CERT_AllocCERTRevocationFlags(
    PRUint32 number_leaf_methods, PRUint32 number_leaf_pref_methods,
    PRUint32 number_chain_methods, PRUint32 number_chain_pref_methods)
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return NULL;
#else
    CERTRevocationFlags *flags;

    flags = PORT_New(CERTRevocationFlags);
    if (!flags)
        return (NULL);

    flags->leafTests.number_of_defined_methods = number_leaf_methods;
    flags->leafTests.cert_rev_flags_per_method =
        PORT_NewArray(PRUint64, number_leaf_methods);

    flags->leafTests.number_of_preferred_methods = number_leaf_pref_methods;
    flags->leafTests.preferred_methods =
        PORT_NewArray(CERTRevocationMethodIndex, number_leaf_pref_methods);

    flags->chainTests.number_of_defined_methods = number_chain_methods;
    flags->chainTests.cert_rev_flags_per_method =
        PORT_NewArray(PRUint64, number_chain_methods);

    flags->chainTests.number_of_preferred_methods = number_chain_pref_methods;
    flags->chainTests.preferred_methods =
        PORT_NewArray(CERTRevocationMethodIndex, number_chain_pref_methods);

    if (!flags->leafTests.cert_rev_flags_per_method ||
        !flags->leafTests.preferred_methods ||
        !flags->chainTests.cert_rev_flags_per_method ||
        !flags->chainTests.preferred_methods) {
        CERT_DestroyCERTRevocationFlags(flags);
        return (NULL);
    }

    return flags;
#endif /* NSS_DISABLE_LIBPKIX */
}

void
CERT_DestroyCERTRevocationFlags(CERTRevocationFlags *flags)
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return;
#else
    if (!flags)
        return;

    if (flags->leafTests.cert_rev_flags_per_method)
        PORT_Free(flags->leafTests.cert_rev_flags_per_method);

    if (flags->leafTests.preferred_methods)
        PORT_Free(flags->leafTests.preferred_methods);

    if (flags->chainTests.cert_rev_flags_per_method)
        PORT_Free(flags->chainTests.cert_rev_flags_per_method);

    if (flags->chainTests.preferred_methods)
        PORT_Free(flags->chainTests.preferred_methods);

    PORT_Free(flags);
#endif /* NSS_DISABLE_LIBPKIX */
}

/*
 * CERT_PKIXVerifyCert
 *
 * Verify a Certificate using the PKIX library.
 *
 * Parameters:
 *  cert    - the target certificate to verify. Must be non-null
 *  params  - an array of type/value parameters which can be
 *            used to modify the behavior of the validation
 *            algorithm, or supply additional constraints.
 *
 *  outputTrustAnchor - the trust anchor which the certificate
 *                      chains to. The caller is responsible
 *                      for freeing this.
 *
 * Example Usage:
 *    CERTValParam args[3];
 *    args[0].type = cvpt_policyOID;
 *    args[0].value.si = oid;
 *    args[1].type = revCheckRequired;
 *    args[1].value.b = PR_TRUE;
 *    args[2].type = cvpt_end;
 *
 *    CERT_PKIXVerifyCert(cert, &output, args
 */
SECStatus
CERT_PKIXVerifyCert(
    CERTCertificate *cert,
    SECCertificateUsage usages,
    CERTValInParam *paramsIn,
    CERTValOutParam *paramsOut,
    void *wincx)
{
#ifdef NSS_DISABLE_LIBPKIX
    PORT_SetError(PR_NOT_IMPLEMENTED_ERROR);
    return SECFailure;
#else
    SECStatus r = SECFailure;
    PKIX_Error *error = NULL;
    PKIX_ProcessingParams *procParams = NULL;
    PKIX_BuildResult *buildResult = NULL;
    void *nbioContext = NULL; /* for non-blocking IO */
    void *buildState = NULL;  /* for non-blocking IO */
    PKIX_CertSelector *certSelector = NULL;
    PKIX_List *certStores = NULL;
    PKIX_ValidateResult *valResult = NULL;
    PKIX_VerifyNode *verifyNode = NULL;
    PKIX_TrustAnchor *trustAnchor = NULL;
    PKIX_PL_Cert *trustAnchorCert = NULL;
    PKIX_List *builtCertList = NULL;
    CERTValOutParam *oparam = NULL;
    int i = 0;

    void *plContext = NULL;

#ifdef PKIX_OBJECT_LEAK_TEST
    int leakedObjNum = 0;
    int memLeakLoopCount = 0;
    int objCountTable[PKIX_NUMTYPES];
    int fnInvLocalCount = 0;
    PKIX_Boolean savedUsePkixEngFlag = usePKIXValidationEngine;

    if (usePKIXValidationEngine) {
        /* current memory leak testing implementation does not allow
         * to run simultaneous tests one the same or a different threads.
         * Setting the variable to false, to make additional chain
         * validations be handled by old nss. */
        usePKIXValidationEngine = PR_FALSE;
    }
    testStartFnStackPosition = 1;
    fnStackNameArr[0] = "CERT_PKIXVerifyCert";
    fnStackInvCountArr[0] = 0;
    PKIX_Boolean abortOnLeak =
        (PR_GetEnvSecure("PKIX_OBJECT_LEAK_TEST_ABORT_ON_LEAK") == NULL) ? PKIX_FALSE
                                                                         : PKIX_TRUE;
    runningLeakTest = PKIX_TRUE;

    /* Prevent multi-threaded run of object leak test */
    fnInvLocalCount = PR_ATOMIC_INCREMENT(&parallelFnInvocationCount);
    PORT_Assert(fnInvLocalCount == 1);

    do {
        r = SECFailure;
        error = NULL;
        procParams = NULL;
        buildResult = NULL;
        nbioContext = NULL; /* for non-blocking IO */
        buildState = NULL;  /* for non-blocking IO */
        certSelector = NULL;
        certStores = NULL;
        valResult = NULL;
        verifyNode = NULL;
        trustAnchor = NULL;
        trustAnchorCert = NULL;
        builtCertList = NULL;
        oparam = NULL;
        i = 0;
        errorGenerated = PKIX_FALSE;
        stackPosition = 0;

        if (leakedObjNum) {
            pkix_pl_lifecycle_ObjectTableUpdate(objCountTable);
        }
        memLeakLoopCount += 1;
#endif /* PKIX_OBJECT_LEAK_TEST */

        error = PKIX_PL_NssContext_Create(
            0, PR_FALSE /*use arena*/, wincx, &plContext);
        if (error != NULL) { /* need pkix->nss error map */
            PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
            goto cleanup;
        }

        error = pkix_pl_NssContext_SetCertUsage(usages, plContext);
        if (error != NULL) {
            PORT_SetError(SEC_ERROR_INVALID_ARGS);
            goto cleanup;
        }

        error = PKIX_ProcessingParams_Create(&procParams, plContext);
        if (error != NULL) { /* need pkix->nss error map */
            PORT_SetError(SEC_ERROR_CERT_NOT_VALID);
            goto cleanup;
        }

        /* local cert store should be set into procParams before
         * filling in revocation settings. */
        certStores = cert_GetCertStores(plContext);
        if (certStores == NULL) {
            goto cleanup;
        }
        error = PKIX_ProcessingParams_SetCertStores(procParams, certStores, plContext);
        if (error != NULL) {
            goto cleanup;
        }

        /* now process the extensible input parameters structure */
        if (paramsIn != NULL) {
            i = 0;
            while (paramsIn[i].type != cert_pi_end) {
                if (paramsIn[i].type >= cert_pi_max) {
                    PORT_SetError(SEC_ERROR_INVALID_ARGS);
                    goto cleanup;
                }
                if (cert_pkixSetParam(procParams,
                                      &paramsIn[i], plContext) !=
                    SECSuccess) {
                    PORT_SetError(SEC_ERROR_INVALID_ARGS);
                    goto cleanup;
                }
                i++;
            }
        }

        certSelector = cert_GetTargetCertConstraints(cert, plContext);
        if (certSelector == NULL) {
            goto cleanup;
        }
        error = PKIX_ProcessingParams_SetTargetCertConstraints(procParams, certSelector, plContext);
        if (error != NULL) {
            goto cleanup;
        }

        error = PKIX_BuildChain(procParams, &nbioContext,
                                &buildState, &buildResult, &verifyNode,
                                plContext);
        if (error != NULL) {
            goto cleanup;
        }

        error = PKIX_BuildResult_GetValidateResult(buildResult, &valResult,
                                                   plContext);
        if (error != NULL) {
            goto cleanup;
        }

        error = PKIX_ValidateResult_GetTrustAnchor(valResult, &trustAnchor,
                                                   plContext);
        if (error != NULL) {
            goto cleanup;
        }

        if (trustAnchor != NULL) {
            error = PKIX_TrustAnchor_GetTrustedCert(trustAnchor, &trustAnchorCert,
                                                    plContext);
            if (error != NULL) {
                goto cleanup;
            }
        }

#ifdef PKIX_OBJECT_LEAK_TEST
        /* Can not continue if error was generated but not returned.
         * Jumping to cleanup. */
        if (errorGenerated)
            goto cleanup;
#endif /* PKIX_OBJECT_LEAK_TEST */

        oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_trustAnchor);
        if (oparam != NULL) {
            if (trustAnchorCert != NULL) {
                oparam->value.pointer.cert =
                    cert_NSSCertFromPKIXCert(trustAnchorCert);
            } else {
                oparam->value.pointer.cert = NULL;
            }
        }

        error = PKIX_BuildResult_GetCertChain(buildResult, &builtCertList,
                                              plContext);
        if (error != NULL) {
            goto cleanup;
        }

        oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_certList);
        if (oparam != NULL) {
            error = cert_PkixToNssCertsChain(builtCertList,
                                             &oparam->value.pointer.chain,
                                             plContext);
            if (error)
                goto cleanup;
        }

        r = SECSuccess;

    cleanup:
        if (verifyNode) {
            /* Return validation log only upon error. */
            oparam = cert_pkix_FindOutputParam(paramsOut, cert_po_errorLog);
#ifdef PKIX_OBJECT_LEAK_TEST
            if (!errorGenerated)
#endif /* PKIX_OBJECT_LEAK_TEST */
                if (r && oparam != NULL) {
                    PKIX_Error *tmpError =
                        cert_GetLogFromVerifyNode(oparam->value.pointer.log,
                                                  verifyNode, plContext);
                    if (tmpError) {
                        PKIX_PL_Object_DecRef((PKIX_PL_Object *)tmpError, plContext);
                    }
                }
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)verifyNode, plContext);
        }

        if (procParams != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)procParams, plContext);

        if (trustAnchorCert != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchorCert, plContext);

        if (trustAnchor != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)trustAnchor, plContext);

        if (valResult != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)valResult, plContext);

        if (buildResult != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)buildResult, plContext);

        if (certStores != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)certStores, plContext);

        if (certSelector != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)certSelector, plContext);

        if (builtCertList != NULL)
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)builtCertList, plContext);

        if (error != NULL) {
            SECErrorCodes nssErrorCode = 0;

            cert_PkixErrorToNssCode(error, &nssErrorCode, plContext);
            cert_pkixDestroyValOutParam(paramsOut);
            PORT_SetError(nssErrorCode);
            PKIX_PL_Object_DecRef((PKIX_PL_Object *)error, plContext);
        }

        PKIX_PL_NssContext_Destroy(plContext);

#ifdef PKIX_OBJECT_LEAK_TEST
        leakedObjNum =
            pkix_pl_lifecycle_ObjectLeakCheck(leakedObjNum ? objCountTable : NULL);

        if (pkixLog && leakedObjNum) {
            PR_LOG(pkixLog, 1, ("The generated error caused an object leaks. Loop %d."
                                "Stack %s\n",
                                memLeakLoopCount, errorFnStackString));
        }
        PR_Free(errorFnStackString);
        errorFnStackString = NULL;
        if (abortOnLeak) {
            PORT_Assert(leakedObjNum == 0);
        }

    } while (errorGenerated);

    runningLeakTest = PKIX_FALSE;
    PR_ATOMIC_DECREMENT(&parallelFnInvocationCount);
    usePKIXValidationEngine = savedUsePkixEngFlag;
#endif /* PKIX_OBJECT_LEAK_TEST */

    return r;
#endif /* NSS_DISABLE_LIBPKIX */
}
