/* 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,
    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;

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

    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 */
}
