static void
test_KeyUsages(void)
{
    PKIX_ComCertSelParams *goodParams = NULL;
    PKIX_PL_OID *ekuOid = NULL;
    PKIX_List *setExtKeyUsage = NULL;
    PKIX_List *getExtKeyUsage = NULL;
    PKIX_UInt32 getKeyUsage = 0;
    PKIX_UInt32 setKeyUsage = 0x1FF;
    PKIX_Boolean isEqual = PKIX_FALSE;

    PKIX_TEST_STD_VARS();

    subTest("PKIX_ComCertSelParams_Create");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));

    subTest("PKIX_ComCertSelParams_SetKeyUsage");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetKeyUsage(goodParams, setKeyUsage, plContext));

    subTest("PKIX_ComCertSelParams_GetKeyUsage");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetKeyUsage(goodParams, &getKeyUsage, plContext));

    if (setKeyUsage != getKeyUsage) {
        testError("unexpected KeyUsage mismatch <expect equal>");
    }

    subTest("PKIX_PL_OID List create and append");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setExtKeyUsage, plContext));
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.3.6.1.5.5.7.3.1", &ekuOid, plContext));
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setExtKeyUsage, (PKIX_PL_Object *)ekuOid, plContext));
    PKIX_TEST_DECREF_BC(ekuOid);

    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.3.6.1.5.5.7.3.8", &ekuOid, plContext));
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(setExtKeyUsage, (PKIX_PL_Object *)ekuOid, plContext));
    PKIX_TEST_DECREF_BC(ekuOid);

    subTest("PKIX_ComCertSelParams_SetExtendedKeyUsage");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetExtendedKeyUsage(goodParams, setExtKeyUsage, plContext));

    subTest("PKIX_ComCertSelParams_GetExtendedKeyUsage");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetExtendedKeyUsage(goodParams, &getExtKeyUsage, plContext));

    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setExtKeyUsage,
                                                    (PKIX_PL_Object *)getExtKeyUsage,
                                                    &isEqual,
                                                    plContext));

    if (isEqual == PKIX_FALSE) {
        testError("unexpected ExtKeyUsage mismatch <expect equal>");
    }

cleanup:

    PKIX_TEST_DECREF_AC(ekuOid);
    PKIX_TEST_DECREF_AC(setExtKeyUsage);
    PKIX_TEST_DECREF_AC(getExtKeyUsage);
    PKIX_TEST_DECREF_AC(goodParams);

    PKIX_TEST_RETURN();
}
/*
 * FUNCTION: pkix_pl_CRL_GetSignatureAlgId
 *
 * DESCRIPTION:
 *  Retrieves a pointer to the OID that represents the signature algorithm of
 *  the CRL pointed to by "crl" and stores it at "pSignatureAlgId".
 *
 *  AlgorithmIdentifier  ::=  SEQUENCE  {
 *      algorithm               OBJECT IDENTIFIER,
 *      parameters              ANY DEFINED BY algorithm OPTIONAL  }
 *
 * PARAMETERS:
 *  "crl"
 *      Address of CRL whose signature algorithm OID is to be stored.
 *      Must be non-NULL.
 *  "pSignatureAlgId"
 *      Address where object pointer will be stored. Must be non-NULL.
 *  "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 CRL Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_pl_CRL_GetSignatureAlgId(
    PKIX_PL_CRL *crl,
    PKIX_PL_OID **pSignatureAlgId,
    void *plContext)
{
    CERTCrl *nssCrl = NULL;
    PKIX_PL_OID *signatureAlgId = NULL;
    SECAlgorithmID algorithm;
    SECItem algBytes;
    char *asciiOID = NULL;

    PKIX_ENTER(CRL, "pkix_pl_CRL_GetSignatureAlgId");
    PKIX_NULLCHECK_THREE(crl, crl->nssSignedCrl, pSignatureAlgId);

    /* if we don't have a cached copy from before, we create one */
    if (crl->signatureAlgId == NULL) {

        PKIX_OBJECT_LOCK(crl);

        if (crl->signatureAlgId == NULL) {

            nssCrl = &(crl->nssSignedCrl->crl);
            algorithm = nssCrl->signatureAlg;
            algBytes = algorithm.algorithm;

            PKIX_NULLCHECK_ONE(algBytes.data);
            if (algBytes.len == 0) {
                PKIX_ERROR_FATAL(PKIX_OIDBYTESLENGTH0);
            }

            PKIX_CHECK(pkix_pl_oidBytes2Ascii
                       (&algBytes, &asciiOID, plContext),
                       PKIX_OIDBYTES2ASCIIFAILED);

            PKIX_CHECK(PKIX_PL_OID_Create
                       (asciiOID, &signatureAlgId, plContext),
                       PKIX_OIDCREATEFAILED);

            /* save a cached copy in case it is asked for again */
            crl->signatureAlgId = signatureAlgId;
        }

        PKIX_OBJECT_UNLOCK(crl);

    }

    PKIX_INCREF(crl->signatureAlgId);
    *pSignatureAlgId = crl->signatureAlgId;

cleanup:

    PKIX_FREE(asciiOID);

    PKIX_RETURN(CRL);
}
static
void testGetSetInitialPolicies(
        PKIX_ProcessingParams *goodObject,
        char *asciiPolicyOID)
{
        PKIX_PL_OID *policyOID = NULL;
        PKIX_List* setPolicyList = NULL;
        PKIX_List* getPolicyList = NULL;

        PKIX_TEST_STD_VARS();
        subTest("PKIX_ProcessingParams_Get/SetInitialPolicies");

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (asciiPolicyOID, &policyOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&setPolicyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (setPolicyList, (PKIX_PL_Object *)policyOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_SetImmutable(setPolicyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetInitialPolicies
                (goodObject, setPolicyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_GetInitialPolicies
                (goodObject, &getPolicyList, plContext));

        testEqualsHelper
                ((PKIX_PL_Object *)setPolicyList,
                (PKIX_PL_Object *)getPolicyList,
                PKIX_TRUE,
                plContext);

cleanup:
        PKIX_TEST_DECREF_AC(policyOID);
        PKIX_TEST_DECREF_AC(setPolicyList);
        PKIX_TEST_DECREF_AC(getPolicyList);

        PKIX_TEST_RETURN();
}
/*
 * FUNCTION: pkix_NameConstraintsCheckerState_Create
 *
 * DESCRIPTION:
 *  Allocate and initialize NameConstraintsChecker state data.
 *
 * PARAMETERS
 *  "nameConstraints"
 *      Address of NameConstraints to be stored in state. May be NULL.
 *  "numCerts"
 *      Number of certificates in the validation chain. This data is used
 *      to identify end-entity.
 *  "pCheckerState"
 *      Address of NameConstraintsCheckerState that is returned. Must be
 *      non-NULL.
 *  "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 CERTNAMECONSTRAINTSCHECKERSTATE Error if the function fails in
 *  a non-fatal way.
 *  Returns a Fatal Error
 */
static PKIX_Error *
pkix_NameConstraintsCheckerState_Create(
    PKIX_PL_CertNameConstraints *nameConstraints,
    PKIX_UInt32 numCerts,
    pkix_NameConstraintsCheckerState **pCheckerState,
    void *plContext)
{
        pkix_NameConstraintsCheckerState *state = NULL;

        PKIX_ENTER(CERTNAMECONSTRAINTSCHECKERSTATE,
                    "pkix_NameConstraintsCheckerState_Create");
        PKIX_NULLCHECK_ONE(pCheckerState);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_CERTNAMECONSTRAINTSCHECKERSTATE_TYPE,
                    sizeof (pkix_NameConstraintsCheckerState),
                    (PKIX_PL_Object **)&state,
                    plContext),
                    PKIX_COULDNOTCREATENAMECONSTRAINTSCHECKERSTATEOBJECT);

        /* Initialize fields */

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_NAMECONSTRAINTS_OID,
                    &state->nameConstraintsOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        PKIX_INCREF(nameConstraints);

        state->nameConstraints = nameConstraints;
        state->certsRemaining = numCerts;

        *pCheckerState = state;
        state = NULL;

cleanup:

        PKIX_DECREF(state);

        PKIX_RETURN(CERTNAMECONSTRAINTSCHECKERSTATE);
}
int test_certchainchecker(int argc, char *argv[]) {

        PKIX_UInt32 actualMinorVersion;
        PKIX_PL_OID *bcOID = NULL;
        PKIX_PL_OID *ncOID = NULL;
        PKIX_PL_OID *cpOID = NULL;
        PKIX_PL_OID *pmOID = NULL;
        PKIX_PL_OID *pcOID = NULL;
        PKIX_PL_OID *iaOID = NULL;
        PKIX_CertChainChecker *dummyChecker = NULL;
        PKIX_List *supportedExtensions = NULL;
        PKIX_PL_Object *initialState = NULL;
        PKIX_UInt32 j = 0;

        PKIX_TEST_STD_VARS();

        startTests("CertChainChecker");

        PKIX_TEST_EXPECT_NO_ERROR(
            PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create
                (&supportedExtensions, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (PKIX_BASICCONSTRAINTS_OID, &bcOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (supportedExtensions, (PKIX_PL_Object *)bcOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (PKIX_NAMECONSTRAINTS_OID, &ncOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (supportedExtensions, (PKIX_PL_Object *)ncOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (PKIX_CERTIFICATEPOLICIES_OID, &cpOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (supportedExtensions, (PKIX_PL_Object *)cpOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (PKIX_POLICYMAPPINGS_OID, &pmOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (supportedExtensions, (PKIX_PL_Object *)pmOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (PKIX_POLICYCONSTRAINTS_OID, &pcOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (supportedExtensions, (PKIX_PL_Object *)pcOID, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (PKIX_INHIBITANYPOLICY_OID, &iaOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (supportedExtensions, (PKIX_PL_Object *)iaOID, plContext));

        PKIX_TEST_DECREF_BC(bcOID);
        PKIX_TEST_DECREF_BC(ncOID);
        PKIX_TEST_DECREF_BC(cpOID);
        PKIX_TEST_DECREF_BC(pmOID);
        PKIX_TEST_DECREF_BC(pcOID);
        PKIX_TEST_DECREF_BC(iaOID);

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_IncRef
                ((PKIX_PL_Object *)supportedExtensions, plContext));

        initialState = (PKIX_PL_Object *)supportedExtensions;

        subTest("CertChainChecker_Create");
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_Create
                (dummyChecker_Check, /* PKIX_CertChainChecker_CheckCallback */
                PKIX_FALSE,          /* forwardCheckingSupported */
                PKIX_FALSE,          /* forwardDirectionExpected */
                supportedExtensions,
                NULL,                /* PKIX_PL_Object *initialState */
                &dummyChecker,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_CertChainChecker_SetCertChainCheckerState
                (dummyChecker, initialState, plContext));

        test_CertChainChecker_Duplicate(dummyChecker);

        subTest("CertChainChecker_Destroy");
        PKIX_TEST_DECREF_BC(dummyChecker);

cleanup:

        PKIX_TEST_DECREF_AC(dummyChecker);
        PKIX_TEST_DECREF_AC(initialState);
        PKIX_TEST_DECREF_AC(supportedExtensions);

        PKIX_Shutdown(plContext);

        PKIX_TEST_RETURN();

        endTests("CertChainChecker");

        return (0);
}
static
PKIX_List *policySetParse(char *policyString)
{
        char *p = NULL;
        char *oid = NULL;
        char c = '\0';
        PKIX_Boolean validString = PKIX_FALSE;
        PKIX_PL_OID *plOID = NULL;
        PKIX_List *policySet = NULL;

        PKIX_TEST_STD_VARS();

        p = policyString;

        /*
         * There may or may not be quotes around the initial-policy-set
         * string. If they are omitted, dbx will strip off the curly braces.
         * If they are included, dbx will strip off the quotes, but if you
         * are running directly from a script, without dbx, the quotes will
         * not be stripped. We need to be able to handle both cases.
         */
        if (*p == '"') {
                p++;
        }

        if ('{' != *p++) {
                return (NULL);
        }
        oid = p;

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&policySet, plContext));

        /* scan to the end of policyString */
        while (!validString) {
                /* scan to the end of the current OID string */
                c = *oid;
                while ((c != '\0') && (c != ':') && (c != '}')) {
                        c = *++oid;
                }

                if ((c != ':') || (c != '}')) {
                        *oid = '\0'; /* store a null terminator */
                        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                                (p, &plOID, plContext));

                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_List_AppendItem
                                (policySet,
                                (PKIX_PL_Object *)plOID,
                                plContext));

                        PKIX_TEST_DECREF_BC(plOID);
                        plOID = NULL;
                        if (c == '}') {
                                /*
                                * Any exit but this one means
                                * we were given a badly-formed string.
                                */
                                validString = PKIX_TRUE;
                        }
                        p = ++oid;
                }
        }


cleanup:
        if (!validString) {
                PKIX_TEST_DECREF_AC(plOID);
                PKIX_TEST_DECREF_AC(policySet);
                policySet = NULL;
        }

        PKIX_TEST_RETURN();

        return (policySet);
}
static
void testNistTest2(char *dirName)
{
#define PKIX_TEST_NUM_CERTS     2
        char *trustAnchor =
                "TrustAnchorRootCertificate.crt";
        char *intermediateCert =
                "GoodCACert.crt";
        char *endEntityCert =
                "ValidCertificatePathTest1EE.crt";
        char *certNames[PKIX_TEST_NUM_CERTS];
        char *asciiNist1Policy = "2.16.840.1.101.3.2.1.48.1";
        PKIX_PL_Cert *certs[PKIX_TEST_NUM_CERTS] = { NULL, NULL };

        PKIX_ValidateParams *valParams = NULL;
        PKIX_ValidateResult *valResult = NULL;
        PKIX_List *chain = NULL;
        PKIX_PL_OID *Nist1PolicyOID = NULL;
        PKIX_List *initialPolicies = NULL;
        char *anchorName = NULL;

        PKIX_TEST_STD_VARS();

        subTest("testNistTest2: Creating the cert chain");
        /*
         * Create a chain, but don't include the first certName.
         * That's the anchor, and is supplied separately from
         * the chain.
         */
        certNames[0] = intermediateCert;
        certNames[1] = endEntityCert;
        chain = createCertChainPlus
                (dirName, certNames, certs, PKIX_TEST_NUM_CERTS, plContext);

        subTest("testNistTest2: Creating the Validate Parameters");
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (asciiNist1Policy, &Nist1PolicyOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_Create(&initialPolicies, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (initialPolicies, (PKIX_PL_Object *)Nist1PolicyOID, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetImmutable
                (initialPolicies, plContext));

        valParams = createValidateParams
                (dirName,
                trustAnchor,
                NULL,
                NULL,
                initialPolicies,
                PKIX_FALSE,
                PKIX_FALSE,
                PKIX_FALSE,
                PKIX_FALSE,
                chain,
                plContext);

        subTest("testNistTest2: Validating the chain");
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateChain
                (valParams, &valResult, NULL, plContext));


cleanup:

        PKIX_PL_Free(anchorName, plContext);

        PKIX_TEST_DECREF_AC(Nist1PolicyOID);
        PKIX_TEST_DECREF_AC(initialPolicies);
        PKIX_TEST_DECREF_AC(valParams);
        PKIX_TEST_DECREF_AC(valResult);
        PKIX_TEST_DECREF_AC(chain);

        PKIX_TEST_RETURN();
}
int test_buildchain_uchecker(int argc, char *argv[])
{
        PKIX_BuildResult *buildResult = NULL;
        PKIX_ComCertSelParams *certSelParams = NULL;
        PKIX_CertSelector *certSelector = NULL;
        PKIX_TrustAnchor *anchor = NULL;
        PKIX_List *anchors = NULL;
        PKIX_List *certs = NULL;
        PKIX_PL_Cert *cert = NULL;
        PKIX_ProcessingParams *procParams = NULL;
        PKIX_CertChainChecker *checker = NULL;
        char *dirName = NULL;
        PKIX_PL_String *dirNameString = NULL;
        PKIX_PL_Cert *trustedCert = NULL;
        PKIX_PL_Cert *targetCert = NULL;
        PKIX_UInt32 numCerts = 0;
        PKIX_UInt32 i = 0;
        PKIX_UInt32 j = 0;
        PKIX_UInt32 k = 0;
        PKIX_UInt32 chainLength = 0;
        PKIX_CertStore *certStore = NULL;
        PKIX_List *certStores = NULL;
        char * asciiResult = NULL;
        PKIX_Boolean result;
        PKIX_Boolean testValid = PKIX_TRUE;
        PKIX_Boolean supportForward = PKIX_FALSE;
        PKIX_List *expectedCerts = NULL;
        PKIX_List *userOIDs = NULL;
        PKIX_PL_OID *oid = NULL;
        PKIX_PL_Cert *dirCert = NULL;
        PKIX_PL_String *actualCertsString = NULL;
        PKIX_PL_String *expectedCertsString = NULL;
        char *actualCertsAscii = NULL;
        char *expectedCertsAscii = NULL;
        char *oidString = NULL;
        void *buildState = NULL; /* needed by pkix_build for non-blocking I/O */
        void *nbioContext = NULL; /* needed by pkix_build for non-blocking I/O */

        PKIX_TEST_STD_VARS();

        if (argc < 5){
                printUsage();
                return (0);
        }

        startTests("BuildChain_UserChecker");

        PKIX_TEST_EXPECT_NO_ERROR(
            PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));

        /* ENE = expect no error; EE = expect error */
        if (PORT_Strcmp(argv[2+j], "ENE") == 0) {
                testValid = PKIX_TRUE;
        } else if (PORT_Strcmp(argv[2+j], "EE") == 0) {
                testValid = PKIX_FALSE;
        } else {
                printUsage();
                return (0);
        }

        /* OID specified at argv[3+j] */

        if (*argv[3+j] != '-') {

                if (*argv[3+j] == 'F') {
                        supportForward = PKIX_TRUE;
                        oidString = argv[3+j]+1;
                } else {
                        oidString = argv[3+j];
                }

                PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create
                                (&userOIDs, plContext));
                PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                                (oidString, &oid, plContext));
                PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                                (userOIDs, (PKIX_PL_Object *)oid, plContext));
                PKIX_TEST_DECREF_BC(oid);
        }

        subTest(argv[1+j]);

        dirName = argv[4+j];

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&expectedCerts, plContext));

        chainLength = argc - j - 5;

        for (k = 0; k < chainLength; k++){

                dirCert = createCert(dirName, argv[5+k+j], plContext);

                if (k == (chainLength - 1)){
                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_PL_Object_IncRef
                                ((PKIX_PL_Object *)dirCert, plContext));
                        trustedCert = dirCert;
                } else {

                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_List_AppendItem
                                (expectedCerts,
                                (PKIX_PL_Object *)dirCert,
                                plContext));

                        if (k == 0){
                                PKIX_TEST_EXPECT_NO_ERROR
                                        (PKIX_PL_Object_IncRef
                                        ((PKIX_PL_Object *)dirCert,
                                        plContext));
                                targetCert = dirCert;
                        }
                }

                PKIX_TEST_DECREF_BC(dirCert);
        }

        /* create processing params with list of trust anchors */

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_TrustAnchor_CreateWithCert
                                    (trustedCert, &anchor, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&anchors, plContext));
        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_AppendItem
                (anchors, (PKIX_PL_Object *)anchor, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_Create
                                    (anchors, &procParams, plContext));

        /* create CertSelector with target certificate in params */

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_ComCertSelParams_Create(&certSelParams, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_ComCertSelParams_SetCertificate
                (certSelParams, targetCert, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_CertSelector_Create
                (NULL, NULL, &certSelector, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams
                                (certSelector, certSelParams, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_ProcessingParams_SetTargetCertConstraints
                (procParams, certSelector, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertChainChecker_Create
                                    (testUserChecker,
                                    supportForward,
                                    PKIX_FALSE,
                                    userOIDs,
                                    NULL,
                                    &checker,
                                    plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_AddCertChainChecker
                                  (procParams, checker, plContext));


        /* create CertStores */

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_String_Create
                                    (PKIX_ESCASCII,
                                    dirName,
                                    0,
                                    &dirNameString,
                                    plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CollectionCertStore_Create
                                    (dirNameString, &certStore, plContext));

#if 0
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Pk11CertStore_Create
                                    (&certStore, plContext));
#endif


        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&certStores, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_AppendItem
                (certStores, (PKIX_PL_Object *)certStore, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetCertStores
                                    (procParams, certStores, plContext));

        /* build cert chain using processing params and return buildResult */

        pkixTestErrorResult = PKIX_BuildChain
                (procParams,
                &nbioContext,
                &buildState,
                &buildResult,
                NULL,
                plContext);

        if (testValid == PKIX_TRUE) { /* ENE */
                if (pkixTestErrorResult){
                        (void) printf("UNEXPECTED RESULT RECEIVED!\n");
                } else {
                        (void) printf("EXPECTED RESULT RECEIVED!\n");
                        PKIX_TEST_DECREF_BC(pkixTestErrorResult);
                }
        } else { /* EE */
                if (pkixTestErrorResult){
                        (void) printf("EXPECTED RESULT RECEIVED!\n");
                        PKIX_TEST_DECREF_BC(pkixTestErrorResult);
                } else {
                        testError("UNEXPECTED RESULT RECEIVED");
                }
        }

        if (buildResult){

                PKIX_TEST_EXPECT_NO_ERROR
                        (PKIX_BuildResult_GetCertChain
                        (buildResult, &certs, NULL));

                PKIX_TEST_EXPECT_NO_ERROR
                        (PKIX_List_GetLength(certs, &numCerts, plContext));

                printf("\n");

                for (i = 0; i < numCerts; i++){
                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_List_GetItem
                                (certs,
                                i,
                                (PKIX_PL_Object**)&cert,
                                plContext));

                        asciiResult = PKIX_Cert2ASCII(cert);

                        printf("CERT[%d]:\n%s\n", i, asciiResult);

                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_PL_Free(asciiResult, plContext));
                        asciiResult = NULL;

                        PKIX_TEST_DECREF_BC(cert);
                }

                PKIX_TEST_EXPECT_NO_ERROR
                        (PKIX_PL_Object_Equals
                        ((PKIX_PL_Object*)certs,
                        (PKIX_PL_Object*)expectedCerts,
                        &result,
                        plContext));

                if (!result){
                        testError("BUILT CERTCHAIN IS "
                                    "NOT THE ONE THAT WAS EXPECTED");

                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_PL_Object_ToString
                                ((PKIX_PL_Object *)certs,
                                &actualCertsString,
                                plContext));

                        actualCertsAscii = PKIX_String2ASCII
                                (actualCertsString, plContext);
                        if (actualCertsAscii == NULL){
                                pkixTestErrorMsg = "PKIX_String2ASCII Failed";
                                goto cleanup;
                        }

                        PKIX_TEST_EXPECT_NO_ERROR
                                (PKIX_PL_Object_ToString
                                ((PKIX_PL_Object *)expectedCerts,
                                &expectedCertsString,
                                plContext));

                        expectedCertsAscii = PKIX_String2ASCII
                                (expectedCertsString, plContext);
                        if (expectedCertsAscii == NULL){
                                pkixTestErrorMsg = "PKIX_String2ASCII Failed";
                                goto cleanup;
                        }

                        (void) printf("Actual value:\t%s\n", actualCertsAscii);
                        (void) printf("Expected value:\t%s\n",
                                        expectedCertsAscii);

                        if (chainLength - 1 != numUserCheckerCalled) {
                                pkixTestErrorMsg =
                                    "PKIX user defined checker not called";
                        }

                        goto cleanup;
                }

        }

cleanup:
        PKIX_PL_Free(asciiResult, plContext);
        PKIX_PL_Free(actualCertsAscii, plContext);
        PKIX_PL_Free(expectedCertsAscii, plContext);

        PKIX_TEST_DECREF_AC(actualCertsString);
        PKIX_TEST_DECREF_AC(expectedCertsString);
        PKIX_TEST_DECREF_AC(expectedCerts);
        PKIX_TEST_DECREF_AC(certs);
        PKIX_TEST_DECREF_AC(cert);
        PKIX_TEST_DECREF_AC(certStore);
        PKIX_TEST_DECREF_AC(certStores);
        PKIX_TEST_DECREF_AC(dirNameString);
        PKIX_TEST_DECREF_AC(trustedCert);
        PKIX_TEST_DECREF_AC(targetCert);
        PKIX_TEST_DECREF_AC(anchor);
        PKIX_TEST_DECREF_AC(anchors);
        PKIX_TEST_DECREF_AC(procParams);
        PKIX_TEST_DECREF_AC(certSelParams);
        PKIX_TEST_DECREF_AC(certSelector);
        PKIX_TEST_DECREF_AC(buildResult);
        PKIX_TEST_DECREF_AC(procParams);
        PKIX_TEST_DECREF_AC(userOIDs);
        PKIX_TEST_DECREF_AC(checker);

        PKIX_TEST_RETURN();

        PKIX_Shutdown(plContext);

        endTests("BuildChain_UserChecker");

        return (0);

}
static void
test_SubjAlgId_SubjPublicKey(char *dirName)
{
    PKIX_ComCertSelParams *goodParams = NULL;
    PKIX_PL_OID *setAlgId = NULL;
    PKIX_PL_OID *getAlgId = NULL;
    PKIX_PL_Cert *goodCert = NULL;
    PKIX_PL_PublicKey *setPublicKey = NULL;
    PKIX_PL_PublicKey *getPublicKey = NULL;
    PKIX_Boolean isEqual = PKIX_FALSE;

    PKIX_TEST_STD_VARS();

    /* Subject Algorithm Identifier */
    subTest("PKIX_PL_OID_Create");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create("1.1.2.3", &setAlgId, plContext));

    subTest("PKIX_ComCertSelParams_Create");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create(&goodParams, plContext));

    subTest("PKIX_ComCertSelParams_SetSubjPKAlgId");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjPKAlgId(goodParams, setAlgId, plContext));

    subTest("PKIX_ComCertSelParams_GetSubjPKAlgId");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjPKAlgId(goodParams, &getAlgId, plContext));

    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setAlgId,
                                                    (PKIX_PL_Object *)getAlgId,
                                                    &isEqual,
                                                    plContext));

    if (isEqual == PKIX_FALSE) {
        testError("unexpected Subject Public Key Alg mismatch "
                  "<expect equal>");
    }

    /* Subject Public Key */
    subTest("Getting Cert for Subject Public Key");

    goodCert = createCert(dirName, "nameConstraintsDN2CACert.crt", plContext);

    subTest("PKIX_PL_Cert_GetSubjectPublicKey");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetSubjectPublicKey(goodCert, &setPublicKey, plContext));

    subTest("PKIX_ComCertSelParams_SetSubjPubKey");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetSubjPubKey(goodParams, setPublicKey, plContext));

    subTest("PKIX_ComCertSelParams_GetSubjPubKey");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_GetSubjPubKey(goodParams, &getPublicKey, plContext));

    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Equals((PKIX_PL_Object *)setPublicKey,
                                                    (PKIX_PL_Object *)getPublicKey,
                                                    &isEqual,
                                                    plContext));

    if (isEqual == PKIX_FALSE) {
        testError("unexpected Subject Public Key mismatch "
                  "<expect equal>");
    }

cleanup:

    PKIX_TEST_DECREF_AC(setAlgId);
    PKIX_TEST_DECREF_AC(getAlgId);
    PKIX_TEST_DECREF_AC(goodParams);
    PKIX_TEST_DECREF_AC(goodCert);
    PKIX_TEST_DECREF_AC(setPublicKey);
    PKIX_TEST_DECREF_AC(getPublicKey);

    PKIX_TEST_RETURN();
}
Example #10
0
int
test_list2(int argc, char *argv[])
{

    PKIX_List *list;
    char *temp;
    PKIX_UInt32 i = 0;
    PKIX_UInt32 j = 0;
    PKIX_Int32 cmpResult;
    PKIX_PL_OID *testOID;
    PKIX_PL_String *testString;
    PKIX_PL_Object *obj, *obj2;
    PKIX_UInt32 size = 10;
    char *testOIDString[10] = {
        "2.9.999.1.20",
        "1.2.3.4.5.6.7",
        "0.1",
        "1.2.3.5",
        "0.39",
        "1.2.3.4.7",
        "1.2.3.4.6",
        "0.39.1",
        "1.2.3.4.5",
        "0.39.1.300"
    };
    PKIX_UInt32 actualMinorVersion;

    PKIX_TEST_STD_VARS();

    startTests("List Sorting");

    PKIX_TEST_EXPECT_NO_ERROR(
        PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));

    subTest("Creating Unsorted Lists");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&list, plContext));
    for (i = 0; i < size; i++) {
        /* Create a new OID object */
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create(
            testOIDString[i],
            &testOID,
            plContext));
        /* Insert it into the list */
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem(list, (PKIX_PL_Object *)testOID, plContext));
        /* Decref the string object */
        PKIX_TEST_DECREF_BC(testOID);
    }

    subTest("Outputting Unsorted List");

    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
                                                      &testString,
                                                      plContext));
    temp = PKIX_String2ASCII(testString, plContext);
    if (temp) {
        (void)printf("%s \n", temp);
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
    }
    PKIX_TEST_DECREF_BC(testString);

    subTest("Performing Bubble Sort");

    for (i = 0; i < size; i++)
        for (j = 9; j > i; j--) {
            PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j, &obj, plContext));
            PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem(list, j -
                                                                  1,
                                                        &obj2, plContext));

            PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_Compare(obj, obj2, &cmpResult, plContext));
            if (cmpResult < 0) {
                /* Exchange the items */
                PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j, obj2, plContext));
                PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_SetItem(list, j -
                                                                      1,
                                                            obj, plContext));
            }
            /* DecRef objects */
            PKIX_TEST_DECREF_BC(obj);
            PKIX_TEST_DECREF_BC(obj2);
        }

    subTest("Outputting Sorted List");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString((PKIX_PL_Object *)list,
                                                      &testString,
                                                      plContext));
    temp = PKIX_String2ASCII(testString, plContext);
    if (temp) {
        (void)printf("%s \n", temp);
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Free(temp, plContext));
    }

cleanup:

    PKIX_TEST_DECREF_AC(testString);
    PKIX_TEST_DECREF_AC(list);

    PKIX_Shutdown(plContext);

    PKIX_TEST_RETURN();

    endTests("List Sorting");

    return (0);
}
Example #11
0
static PKIX_Error *
testEkuSetup(
    PKIX_ValidateParams *valParams,
    char *ekuOidString,
    PKIX_Boolean *only4EE)
{
    PKIX_ProcessingParams *procParams = NULL;
    PKIX_List *ekuList = NULL;
    PKIX_PL_OID *ekuOid = NULL;
    PKIX_ComCertSelParams *selParams = NULL;
    PKIX_CertSelector *certSelector = NULL;
    PKIX_Boolean last_token = PKIX_FALSE;
    PKIX_UInt32 i, tokeni;

    PKIX_TEST_STD_VARS();

    subTest("PKIX_ValidateParams_GetProcessingParams");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ValidateParams_GetProcessingParams
                              (valParams, &procParams, plContext));

    /* Get extended key usage OID(s) from command line, separated by ","  */

    if (ekuOidString[0] == '"') {
        /* erase doble quotes, if any */
        i = 1;
        while (ekuOidString[i] != '"' && ekuOidString[i] != '\0') {
            ekuOidString[i-1] = ekuOidString[i];
            i++;
        }
        ekuOidString[i-1] = '\0';
    }

    if (ekuOidString[0] == '\0') {
        ekuList = NULL;
    } else {

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create
                                  (&ekuList, plContext));

        /* if OID string start with E, only check for last cert */
        if (ekuOidString[0] == 'E') {
            *only4EE = PKIX_TRUE;
            tokeni = 2;
            i = 1;
        } else {
            *only4EE = PKIX_FALSE;
            tokeni = 1;
            i = 0;
        }

        while (last_token != PKIX_TRUE) {
            while (ekuOidString[tokeni] != ',' &&
                    ekuOidString[tokeni] != '\0') {
                tokeni++;
            }
            if (ekuOidString[tokeni] == '\0') {
                last_token = PKIX_TRUE;
            } else {
                ekuOidString[tokeni] = '\0';
                tokeni++;
            }

            PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                                      (&ekuOidString[i], &ekuOid, plContext));

            PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                                      (ekuList, (PKIX_PL_Object *)ekuOid, plContext));

            PKIX_TEST_DECREF_BC(ekuOid);
            i = tokeni;

        }

    }

    /* Set extended key usage link to processing params */

    subTest("PKIX_ComCertSelParams_Create");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_Create
                              (&selParams, plContext));

    subTest("PKIX_ComCertSelParams_SetExtendedKeyUsage");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ComCertSelParams_SetExtendedKeyUsage
                              (selParams, ekuList, plContext));

    subTest("PKIX_CertSelector_Create");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_Create
                              (testCertSelectorMatchCallback,
                               NULL,
                               &certSelector,
                               plContext));

    subTest("PKIX_CertSelector_SetCommonCertSelectorParams");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_CertSelector_SetCommonCertSelectorParams
                              (certSelector, selParams, plContext));

    subTest("PKIX_ProcessingParams_SetTargetCertConstraints");
    PKIX_TEST_EXPECT_NO_ERROR(PKIX_ProcessingParams_SetTargetCertConstraints
                              (procParams, certSelector, plContext));

cleanup:

    PKIX_TEST_DECREF_AC(selParams);
    PKIX_TEST_DECREF_AC(certSelector);
    PKIX_TEST_DECREF_AC(procParams);
    PKIX_TEST_DECREF_AC(ekuOid);
    PKIX_TEST_DECREF_AC(ekuList);

    PKIX_TEST_RETURN();

    return (0);
}
Example #12
0
/*
 * FUNCTION: pkix_EkuChecker_Create
 * DESCRIPTION:
 *
 *  Creates a new Extend Key Usage CheckerState using "params" to retrieve
 *  application specified EKU for verification and stores it at "pState".
 *
 * PARAMETERS:
 *  "params"
 *      a PKIX_ProcessingParams links to PKIX_ComCertSelParams where a list of
 *      Extended Key Usage OIDs specified by application can be retrieved for
 *      verification.
 *  "pState"
 *      Address where state pointer will be stored. Must be non-NULL.
 *  "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 UserDefinedModules Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
static PKIX_Error *
pkix_EkuChecker_Create(
        PKIX_ProcessingParams *params,
        pkix_EkuChecker **pState,
        void *plContext)
{
        pkix_EkuChecker *state = NULL;
        PKIX_CertSelector *certSelector = NULL;
        PKIX_ComCertSelParams *comCertSelParams = NULL;
        PKIX_List *requiredOids = NULL;

        PKIX_ENTER(EKUCHECKER, "pkix_EkuChecker_Create");
        PKIX_NULLCHECK_TWO(params, pState);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_EKUCHECKER_TYPE,
                    sizeof (pkix_EkuChecker),
                    (PKIX_PL_Object **)&state,
                    plContext),
                    PKIX_COULDNOTCREATEEKUCHECKERSTATEOBJECT);


        PKIX_CHECK(PKIX_ProcessingParams_GetTargetCertConstraints
                    (params, &certSelector, plContext),
                    PKIX_PROCESSINGPARAMSGETTARGETCERTCONSTRAINTSFAILED);

        if (certSelector != NULL) {

            /* Get initial EKU OIDs from ComCertSelParams, if set */
            PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
                       (certSelector, &comCertSelParams, plContext),
                       PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMSFAILED);

            if (comCertSelParams != NULL) {
                PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
                           (comCertSelParams, &requiredOids, plContext),
                           PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);

            }
        }

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_EXTENDEDKEYUSAGE_OID,
                    &state->ekuOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        state->requiredExtKeyUsageOids = requiredOids;
        requiredOids = NULL;
        *pState = state;
        state = NULL;

cleanup:

        PKIX_DECREF(certSelector);
        PKIX_DECREF(comCertSelParams);
        PKIX_DECREF(requiredOids);
        PKIX_DECREF(state);

        PKIX_RETURN(EKUCHECKER);
}
Example #13
0
/*
 * FUNCTION: pkix_pl_GeneralName_Create
 * DESCRIPTION:
 *
 *  Creates new GeneralName which represents the CERTGeneralName pointed to by
 *  "nssAltName" and stores it at "pGenName".
 *
 * PARAMETERS:
 *  "nssAltName"
 *      Address of CERTGeneralName. Must be non-NULL.
 *  "pGenName"
 *      Address where object pointer will be stored. Must be non-NULL.
 *  "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 GeneralName Error if the function fails in a non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_pl_GeneralName_Create(
        CERTGeneralName *nssAltName,
        PKIX_PL_GeneralName **pGenName,
        void *plContext)
{
        PKIX_PL_GeneralName *genName = NULL;
        PKIX_PL_X500Name *pkixDN = NULL;
        PKIX_PL_OID *pkixOID = NULL;
        OtherName *otherName = NULL;
        CERTGeneralNameList *nssGenNameList = NULL;
        CERTGeneralNameType nameType;
        SECItem *secItem = NULL;
        char *asciiName = NULL;
        SECStatus rv;

        PKIX_ENTER(GENERALNAME, "pkix_pl_GeneralName_Create");
        PKIX_NULLCHECK_TWO(nssAltName, pGenName);

        /* create a PKIX_PL_GeneralName object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_GENERALNAME_TYPE,
                    sizeof (PKIX_PL_GeneralName),
                    (PKIX_PL_Object **)&genName,
                    plContext),
                    PKIX_COULDNOTCREATEOBJECT);

        nameType = nssAltName->type;

        /*
         * We use CERT_CreateGeneralNameList to create just one CERTGeneralName
         * item for memory allocation reason. If we want to just create one
         * item, we have to use the calling path CERT_NewGeneralName, then
         * CERT_CopyOneGeneralName. With this calling path, if we pass
         * the arena argument as NULL, in CERT_CopyOneGeneralName's subsequent
         * call to CERT_CopyName, it assumes arena should be valid, hence
         * segmentation error (not sure this is a NSS bug, certainly it is
         * not consistent). But on the other hand, we don't want to keep an
         * arena record here explicitely for every PKIX_PL_GeneralName.
         * So I concluded it is better to use CERT_CreateGeneralNameList,
         * which keeps an arena pointer in its data structure and also masks
         * out details calls from this libpkix level.
         */

        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
        nssGenNameList = CERT_CreateGeneralNameList(nssAltName);

        if (nssGenNameList == NULL) {
                PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
        }

        genName->nssGeneralNameList = nssGenNameList;

        /* initialize fields */
        genName->type = nameType;
        genName->directoryName = NULL;
        genName->OthName = NULL;
        genName->other = NULL;
        genName->oid = NULL;

        switch (nameType){
        case certOtherName:

                PKIX_CHECK(pkix_pl_OtherName_Create
                            (nssAltName, &otherName, plContext),
                            PKIX_OTHERNAMECREATEFAILED);

                genName->OthName = otherName;
                break;

        case certDirectoryName:

                PKIX_CHECK(pkix_pl_DirectoryName_Create
                            (nssAltName, &pkixDN, plContext),
                            PKIX_DIRECTORYNAMECREATEFAILED);

                genName->directoryName = pkixDN;
                break;
        case certRegisterID:

                PKIX_CHECK(pkix_pl_oidBytes2Ascii
                            (&nssAltName->name.other, &asciiName, plContext),
                            PKIX_OIDBYTES2ASCIIFAILED);

                PKIX_CHECK(PKIX_PL_OID_Create(asciiName, &pkixOID, plContext),
                            PKIX_OIDCREATEFAILED);

                genName->oid = pkixOID;
                break;
        case certDNSName:
        case certEDIPartyName:
        case certIPAddress:
        case certRFC822Name:
        case certX400Address:
        case certURI:

                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
                secItem = SECITEM_AllocItem(NULL, NULL, 0);
                if (secItem == NULL){
                        PKIX_ERROR(PKIX_OUTOFMEMORY);
                }

                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_CopyItem).\n");
                rv = SECITEM_CopyItem(NULL, secItem, &nssAltName->name.other);
                if (rv != SECSuccess) {
                        PKIX_ERROR(PKIX_OUTOFMEMORY);
                }

                genName->other = secItem;
                break;
        default:
                PKIX_ERROR(PKIX_NAMETYPENOTSUPPORTED);
        }

        *pGenName = genName;
cleanup:

        PKIX_FREE(asciiName);

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(genName);
                if (secItem){
                        PKIX_GENERALNAME_DEBUG
                                ("\t\tCalling SECITEM_FreeItem).\n");
                        SECITEM_FreeItem(secItem, PR_TRUE);
                        secItem = NULL;
                }
        }

        PKIX_RETURN(GENERALNAME);
}
/*
 * FUNCTION: pkix_TargetCertCheckerState_Create
 * DESCRIPTION:
 *
 *  Creates a new TargetCertCheckerState using the CertSelector pointed to
 *  by "certSelector" and the number of certs represented by "certsRemaining"
 *  and stores it at "pState".
 *
 * PARAMETERS:
 *  "certSelector"
 *      Address of CertSelector representing the criteria against which the
 *      final certificate in a chain is to be matched. Must be non-NULL.
 *  "certsRemaining"
 *      Number of certificates remaining in the chain.
 *  "pState"
 *      Address where object pointer will be stored. Must be non-NULL.
 *  "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 TargetCertCheckerState Error if the function fails in a
 *      non-fatal way.
 *  Returns a Fatal Error if the function fails in an unrecoverable way.
 */
PKIX_Error *
pkix_TargetCertCheckerState_Create(
    PKIX_CertSelector *certSelector,
    PKIX_UInt32 certsRemaining,
    pkix_TargetCertCheckerState **pState,
    void *plContext)
{
        pkix_TargetCertCheckerState *state = NULL;
        PKIX_ComCertSelParams *certSelectorParams = NULL;
        PKIX_List *pathToNameList = NULL;
        PKIX_List *extKeyUsageList = NULL;
        PKIX_List *subjAltNameList = NULL;
        PKIX_PL_OID *extKeyUsageOID = NULL;
        PKIX_PL_OID *subjAltNameOID = NULL;
        PKIX_Boolean subjAltNameMatchAll = PKIX_TRUE;

        PKIX_ENTER(TARGETCERTCHECKERSTATE,
                    "pkix_TargetCertCheckerState_Create");
        PKIX_NULLCHECK_ONE(pState);

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_EXTENDEDKEYUSAGE_OID,
                    &extKeyUsageOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_CERTSUBJALTNAME_OID,
                    &subjAltNameOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_TARGETCERTCHECKERSTATE_TYPE,
                    sizeof (pkix_TargetCertCheckerState),
                    (PKIX_PL_Object **)&state,
                    plContext),
                    PKIX_COULDNOTCREATETARGETCERTCHECKERSTATEOBJECT);

        /* initialize fields */

        if (certSelector != NULL) {

                PKIX_CHECK(PKIX_CertSelector_GetCommonCertSelectorParams
                        (certSelector, &certSelectorParams, plContext),
                        PKIX_CERTSELECTORGETCOMMONCERTSELECTORPARAMFAILED);

                if (certSelectorParams != NULL) {

                        PKIX_CHECK(PKIX_ComCertSelParams_GetPathToNames
                            (certSelectorParams,
                            &pathToNameList,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETPATHTONAMESFAILED);

                        PKIX_CHECK(PKIX_ComCertSelParams_GetExtendedKeyUsage
                            (certSelectorParams,
                            &extKeyUsageList,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETEXTENDEDKEYUSAGEFAILED);

                        PKIX_CHECK(PKIX_ComCertSelParams_GetSubjAltNames
                            (certSelectorParams,
                            &subjAltNameList,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);

                        PKIX_CHECK(PKIX_ComCertSelParams_GetMatchAllSubjAltNames
                            (certSelectorParams,
                            &subjAltNameMatchAll,
                            plContext),
                            PKIX_COMCERTSELPARAMSGETSUBJALTNAMESFAILED);
                }
        }

        state->certsRemaining = certsRemaining;
        state->subjAltNameMatchAll = subjAltNameMatchAll;

        PKIX_INCREF(certSelector);
        state->certSelector = certSelector;

        state->pathToNameList = pathToNameList;
        pathToNameList = NULL;

        state->extKeyUsageList = extKeyUsageList;
        extKeyUsageList = NULL;

        state->subjAltNameList = subjAltNameList;
        subjAltNameList = NULL;

        state->extKeyUsageOID = extKeyUsageOID;
        extKeyUsageOID = NULL;

        state->subjAltNameOID = subjAltNameOID;
        subjAltNameOID = NULL;

        *pState = state;
        state = NULL;

cleanup:
        
        PKIX_DECREF(extKeyUsageOID);
        PKIX_DECREF(subjAltNameOID);
        PKIX_DECREF(pathToNameList);
        PKIX_DECREF(extKeyUsageList);
        PKIX_DECREF(subjAltNameList);
        PKIX_DECREF(state);

        PKIX_DECREF(certSelectorParams);

        PKIX_RETURN(TARGETCERTCHECKERSTATE);

}
int test_policynode(int argc, char *argv[]) {

        /*
         * Create a tree with parent = anyPolicy,
         * child1 with Nist1+Nist2, child2 with Nist1.
         * Give each child another child, with policies Nist2
         * and Nist1, respectively. Pruning with a depth of two
         * should have no effect. Give one of the children
         * another child. Then pruning with a depth of three
         * should reduce the tree to a single strand, as child1
         * and child3 are removed.
         *
         *              parent (anyPolicy)
         *          /                   \
         *      child1(Nist1+Nist2)     child2(Nist1)
         *          |                       |
         *      child3(Nist2)           child4(Nist1)
         *                                  |
         *                              child5(Nist1)
         *
         */
        char *asciiAnyPolicy = "2.5.29.32.0";
        PKIX_PL_Cert *cert = NULL;
        PKIX_PL_CertPolicyInfo *nist1Policy = NULL;
        PKIX_PL_CertPolicyInfo *nist2Policy = NULL;
        PKIX_List *policyQualifierList = NULL;
        PKIX_PL_OID *oidAnyPolicy = NULL;
        PKIX_PL_OID *oidNist1Policy = NULL;
        PKIX_PL_OID *oidNist2Policy = NULL;
        PKIX_List *expectedAnyList = NULL;
        PKIX_List *expectedNist1List = NULL;
        PKIX_List *expectedNist2List = NULL;
        PKIX_List *expectedNist1Nist2List = NULL;
        PKIX_List *emptyList = NULL;
        PKIX_PolicyNode *parentNode = NULL;
        PKIX_PolicyNode *childNode1 = NULL;
        PKIX_PolicyNode *childNode2 = NULL;
        PKIX_PolicyNode *childNode3 = NULL;
        PKIX_PolicyNode *childNode4 = NULL;
        PKIX_PolicyNode *childNode5 = NULL;
        PKIX_PL_String *parentString = NULL;
        PKIX_Boolean pDelete = PKIX_FALSE;
        char *expectedParentAscii =
                "{2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30 5C "
                "1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 65"
                " 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D 2"
                "0 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 69 "
                "73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 66"
                " 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20 6"
                "F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1[(1.3"
                ".6.1.5.5.7.2.2:[30 5C 1A 5A 71 31 3A 20 20 54 68 69 7"
                "3 20 69 73 20 74 68 65 20 75 73 65 72 20 6E 6F 74 69 "
                "63 65 20 66 72 6F 6D 20 71 75 61 6C 69 66 69 65 72 20"
                " 31 2E 20 20 54 68 69 73 20 63 65 72 74 69 66 69 63 6"
                "1 74 65 20 69 73 20 66 6F 72 20 74 65 73 74 20 70 75 "
                "72 70 6F 73 65 73 20 6F 6E 6C 79])], 2.16.840.1.101.3"
                ".2.1.48.2[(1.3.6.1.5.5.7.2.2:[30 5A 1A 58 71 32 3A 20"
                " 20 54 68 69 73 20 69 73 20 74 68 65 20 75 73 65 72 2"
                "0 6E 6F 74 69 63 65 20 66 72 6F 6D 20 71 75 61 6C 69 "
                "66 69 65 72 20 32 2E 20 20 54 68 69 73 20 75 73 65 72"
                " 20 6E 6F 74 69 63 65 20 73 68 6F 75 6C 64 20 6E 6F 7"
                "4 20 62 65 20 64 69 73 70 6C 61 79 65 64])]),1}\n"
                ". {2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30 5"
                "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
                "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
                " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
                "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
                "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
                " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.2),2}";
        char *expectedValidAscii =
                "2.16.840.1.101.3.2.1.48.2";
        char *expectedQualifiersAscii =
                /* "(1.3.6.1.5.5.7.2.2)"; */
                "(1.3.6.1.5.5.7.2.2:[30 5C 1A 5A 71 31 3A 20 20 54 68 "
                "69 73 20 69 73 20 74 68 65 20 75 73 65 72 20 6E 6F 74"
                " 69 63 65 20 66 72 6F 6D 20 71 75 61 6C 69 66 69 65 7"
                "2 20 31 2E 20 20 54 68 69 73 20 63 65 72 74 69 66 69 "
                "63 61 74 65 20 69 73 20 66 6F 72 20 74 65 73 74 20 70"
                " 75 72 70 6F 73 65 73 20 6F 6E 6C 79])";
        char *expectedPoliciesAscii =
                "(2.16.840.1.101.3.2.1.48.1)";
        char *expectedTree =
                "{2.5.29.32.0,{},Critical,(2.5.29.32.0),0}\n"
                ". {2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30 5"
                "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
                "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
                " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
                "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
                "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
                " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1[(1"
                ".3.6.1.5.5.7.2.2:[30 5C 1A 5A 71 31 3A 20 20 54 68 69"
                " 73 20 69 73 20 74 68 65 20 75 73 65 72 20 6E 6F 74 6"
                "9 63 65 20 66 72 6F 6D 20 71 75 61 6C 69 66 69 65 72 "
                "20 31 2E 20 20 54 68 69 73 20 63 65 72 74 69 66 69 63"
                " 61 74 65 20 69 73 20 66 6F 72 20 74 65 73 74 20 70 7"
                "5 72 70 6F 73 65 73 20 6F 6E 6C 79])], 2.16.840.1.101"
                ".3.2.1.48.2[(1.3.6.1.5.5.7.2.2:[30 5A 1A 58 71 32 3A "
                "20 20 54 68 69 73 20 69 73 20 74 68 65 20 75 73 65 72"
                " 20 6E 6F 74 69 63 65 20 66 72 6F 6D 20 71 75 61 6C 6"
                "9 66 69 65 72 20 32 2E 20 20 54 68 69 73 20 75 73 65 "
                "72 20 6E 6F 74 69 63 65 20 73 68 6F 75 6C 64 20 6E 6F"
                " 74 20 62 65 20 64 69 73 70 6C 61 79 65 64])]"
                "),1}\n"
                ". . {2.16.840.1.101.3.2.1.48.2,(1.3.6.1.5.5.7.2.2:[30"
                " 5C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 6"
                "8 65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F "
                "6D 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68"
                " 69 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 2"
                "0 66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 "
                "20 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.2)"
                ",2}\n"
                ". {2.16.840.1.101.3.2.1.48.1,(1.3.6.1.5.5.7.2.2:[30 5"
                "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
                "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
                " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
                "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
                "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
                " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1),1}\n"
                ". . {2.16.840.1.101.3.2.1.48.1,(EMPTY),Not Critical,"
                "(2.16.840.1.101.3.2.1.48.1),2}\n"
                ". . . {2.16.840.1.101.3.2.1.48.1,{},Critical,(2.16.84"
                "0.1.101.3.2.1.48.1),3}";
        char *expectedPrunedTree =
                "{2.5.29.32.0,{},Critical,(2.5.29.32.0),0}\n"
                ". {2.16.840.1.101.3.2.1.48.1,(1.3.6.1.5.5.7.2.2:[30 5"
                "C 1A 5A 71 31 3A 20 20 54 68 69 73 20 69 73 20 74 68 "
                "65 20 75 73 65 72 20 6E 6F 74 69 63 65 20 66 72 6F 6D"
                " 20 71 75 61 6C 69 66 69 65 72 20 31 2E 20 20 54 68 6"
                "9 73 20 63 65 72 74 69 66 69 63 61 74 65 20 69 73 20 "
                "66 6F 72 20 74 65 73 74 20 70 75 72 70 6F 73 65 73 20"
                " 6F 6E 6C 79]),Critical,(2.16.840.1.101.3.2.1.48.1),1}\n"
                ". . {2.16.840.1.101.3.2.1.48.1,(EMPTY),Not Critical,"
                "(2.16.840.1.101.3.2.1.48.1),2}\n"
                ". . . {2.16.840.1.101.3.2.1.48.1,{},Critical,(2.16.84"
                "0.1.101.3.2.1.48.1),3}";

        PKIX_UInt32 actualMinorVersion;
        PKIX_UInt32 j = 0;
        char *dirName = NULL;

        PKIX_TEST_STD_VARS();

        if (argc < 2) {
                printUsage();
                return (0);
        }

        startTests("PolicyNode");

        PKIX_TEST_EXPECT_NO_ERROR(
            PKIX_PL_NssContext_Create(0, PKIX_FALSE, NULL, &plContext));

        dirName = argv[j+1];

        subTest("Creating OID objects");
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_OID_Create
                (asciiAnyPolicy, &oidAnyPolicy, plContext));

        /* Read certificates to get real policies, qualifiers */

        cert = createCert
                (dirName, "UserNoticeQualifierTest16EE.crt", plContext);

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Cert_GetPolicyInformation
                (cert, &expectedNist1Nist2List, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem
                (expectedNist1Nist2List,
                0,
                (PKIX_PL_Object **)&nist1Policy,
                plContext));
        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_GetItem
                (expectedNist1Nist2List,
                1,
                (PKIX_PL_Object **)&nist2Policy,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolQualifiers
                (nist1Policy, &policyQualifierList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId
                (nist1Policy, &oidNist1Policy, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_CertPolicyInfo_GetPolicyId
                (nist2Policy, &oidNist2Policy, plContext));

        subTest("Creating expectedPolicy List objects");

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_Create(&expectedAnyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_Create(&expectedNist1List, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_Create(&expectedNist2List, plContext));


        subTest("Populating expectedPolicy List objects");

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                (expectedAnyList, (PKIX_PL_Object *)oidAnyPolicy, plContext));

        PKIX_TEST_EXPECT_NO_ERROR
                (PKIX_List_AppendItem
                (expectedNist1List,
                (PKIX_PL_Object *)oidNist1Policy,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_AppendItem
                                    (expectedNist2List,
                                    (PKIX_PL_Object *)oidNist2Policy,
                                    plContext));

        subTest("Creating PolicyNode objects");

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_List_Create(&emptyList, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create
                (oidAnyPolicy,
                NULL,
                PKIX_TRUE,
                expectedAnyList,
                &parentNode,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create
                (oidNist2Policy,
                policyQualifierList,
                PKIX_TRUE,
                expectedNist1Nist2List,
                &childNode1,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create
                (oidNist1Policy,
                policyQualifierList,
                PKIX_TRUE,
                expectedNist1List,
                &childNode2,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create
                (oidNist2Policy,
                policyQualifierList,
                PKIX_TRUE,
                expectedNist2List,
                &childNode3,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create
                (oidNist1Policy,
                emptyList,
                PKIX_FALSE,
                expectedNist1List,
                &childNode4,
                plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Create
                (oidNist1Policy,
                NULL,
                PKIX_TRUE,
                expectedNist1List,
                &childNode5,
                plContext));

        subTest("Creating the PolicyNode tree");

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent
                (parentNode, childNode1, plContext));
        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent
                (parentNode, childNode2, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent
                (childNode1, childNode3, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent
                (childNode2, childNode4, plContext));

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_AddToParent
                (childNode4, childNode5, plContext));

        subTest("Displaying PolicyNode objects");

        PKIX_TEST_EXPECT_NO_ERROR(PKIX_PL_Object_ToString
                ((PKIX_PL_Object*)parentNode, &parentString, plContext));
        (void) printf("parentNode is\n\t%s\n", parentString->escAsciiString);

        testToStringHelper
                ((PKIX_PL_Object*)parentNode, expectedTree, plContext);

        test_DuplicateHelper(parentNode, plContext);

        test_GetParent(childNode3, childNode3, childNode4, expectedParentAscii);
        test_GetValidPolicy
                (childNode1, childNode3, parentNode, expectedValidAscii);
        test_GetPolicyQualifiers
                (childNode1, childNode3, childNode4, expectedQualifiersAscii);
        test_GetExpectedPolicies
                (childNode2, childNode4, childNode3, expectedPoliciesAscii);
        test_IsCritical(childNode1, childNode2, childNode4);
        test_GetDepth(childNode2, childNode4, childNode5);

        subTest("pkix_PolicyNode_Prune");

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Prune
                (parentNode, 2, &pDelete, plContext));

        testToStringHelper
                ((PKIX_PL_Object*)parentNode, expectedTree, plContext);

        PKIX_TEST_EXPECT_NO_ERROR(pkix_PolicyNode_Prune
                (parentNode, 3, &pDelete, plContext));

        testToStringHelper
                ((PKIX_PL_Object*)parentNode, expectedPrunedTree, plContext);

        test_GetChildren(parentNode, parentNode, childNode2);

cleanup:

        PKIX_TEST_DECREF_AC(cert);
        PKIX_TEST_DECREF_AC(nist1Policy);
        PKIX_TEST_DECREF_AC(nist2Policy);
        PKIX_TEST_DECREF_AC(policyQualifierList);
        PKIX_TEST_DECREF_AC(oidAnyPolicy);
        PKIX_TEST_DECREF_AC(oidNist1Policy);
        PKIX_TEST_DECREF_AC(oidNist2Policy);
        PKIX_TEST_DECREF_AC(expectedAnyList);
        PKIX_TEST_DECREF_AC(expectedNist1List);
        PKIX_TEST_DECREF_AC(expectedNist2List);
        PKIX_TEST_DECREF_AC(expectedNist1Nist2List);
        PKIX_TEST_DECREF_AC(emptyList);
        PKIX_TEST_DECREF_AC(parentNode);
        PKIX_TEST_DECREF_AC(childNode1);
        PKIX_TEST_DECREF_AC(childNode2);
        PKIX_TEST_DECREF_AC(childNode3);
        PKIX_TEST_DECREF_AC(childNode4);
        PKIX_TEST_DECREF_AC(childNode5);
        PKIX_TEST_DECREF_AC(parentString);

        PKIX_Shutdown(plContext);

        PKIX_TEST_RETURN();

        endTests("PolicyNode");

        return (0);
}
/*
 * FUNCTION: pkix_DefaultCRLCheckerState_Create
 *
 * DESCRIPTION:
 *  Allocate and initialize DefaultCRLChecker state data.
 *
 * PARAMETERS
 *  "certStores"
 *      Address of CertStore List to be stored in state. Must be non-NULL.
 *  "testDate"
 *      Address of PKIX_PL_Date to be checked. May be NULL.
 *  "trustedPubKey"
 *      Trusted Anchor Public Key for verifying first Cert in the chain.
 *      Must be non-NULL.
 *  "certsRemaining"
 *      Number of certificates remaining in the chain.
 *  "nistCRLPolicyEnabled"
 *      If enabled, enforce nist crl policy.
 *  "pCheckerState"
 *      Address of DefaultCRLCheckerState that is returned. Must be non-NULL.
 *  "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 DefaultCrlCheckerState Error if the function fails in a
 *  non-fatal way.
 *  Returns a Fatal Error
 */
static PKIX_Error *
pkix_DefaultCRLCheckerState_Create(
    PKIX_List *certStores,
    PKIX_PL_Date *testDate,
    PKIX_PL_PublicKey *trustedPubKey,
    PKIX_UInt32 certsRemaining,
    PKIX_Boolean nistCRLPolicyEnabled,
    pkix_DefaultCRLCheckerState **pCheckerState,
    void *plContext)
{
        pkix_DefaultCRLCheckerState *state = NULL;

        PKIX_ENTER(DEFAULTCRLCHECKERSTATE,
                    "pkix_DefaultCRLCheckerState_Create");
        PKIX_NULLCHECK_TWO(certStores, pCheckerState);

        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_DEFAULTCRLCHECKERSTATE_TYPE,
                    sizeof (pkix_DefaultCRLCheckerState),
                    (PKIX_PL_Object **)&state,
                    plContext),
                    PKIX_COULDNOTCREATEDEFAULTCRLCHECKERSTATEOBJECT);

        /* Initialize fields */

        PKIX_INCREF(certStores);
        state->certStores = certStores;

        PKIX_INCREF(testDate);
        state->testDate = testDate;

        PKIX_INCREF(trustedPubKey);
        state->prevPublicKey = trustedPubKey;

        state->certHasValidCrl = PKIX_FALSE;
        state->nistCRLPolicyEnabled = nistCRLPolicyEnabled;
        state->prevCertCrlSign = PKIX_TRUE;
        state->prevPublicKeyList = NULL;
        state->reasonCodeMask = 0;
        state->certsRemaining = certsRemaining;

        PKIX_CHECK(PKIX_PL_OID_Create
                    (PKIX_CRLREASONCODE_OID,
                    &state->crlReasonCodeOID,
                    plContext),
                    PKIX_OIDCREATEFAILED);

        state->certIssuer = NULL;
        state->certSerialNumber = NULL;
        state->crlSelector = NULL;
        state->crlStoreIndex = 0;
        state->numCrlStores = 0;

        *pCheckerState = state;
        state = NULL;

cleanup:

        PKIX_DECREF(state);

        PKIX_RETURN(DEFAULTCRLCHECKERSTATE);
}
/*
 * FUNCTION: PKIX_PL_GeneralName_Create (see comments in pkix_pl_pki.h)
 */
PKIX_Error *
PKIX_PL_GeneralName_Create(
        PKIX_UInt32 nameType,
        PKIX_PL_String *stringRep,
        PKIX_PL_GeneralName **pGName,
        void *plContext)
{
        PKIX_PL_X500Name *pkixDN = NULL;
        PKIX_PL_OID *pkixOID = NULL;
        SECItem *secItem = NULL;
        char *asciiString = NULL;
        PKIX_UInt32 length = 0;
        PKIX_PL_GeneralName *genName = NULL;
        CERTGeneralName *nssGenName = NULL;
        CERTGeneralNameList *nssGenNameList = NULL;
        CERTName *nssCertName = NULL;
        PLArenaPool *arena = NULL;

        PKIX_ENTER(GENERALNAME, "PKIX_PL_GeneralName_Create");
        PKIX_NULLCHECK_TWO(pGName, stringRep);

        PKIX_CHECK(PKIX_PL_String_GetEncoded
                    (stringRep,
                    PKIX_ESCASCII,
                    (void **)&asciiString,
                    &length,
                    plContext),
                    PKIX_STRINGGETENCODEDFAILED);

        /* Create a temporary CERTGeneralName */
        PKIX_GENERALNAME_DEBUG("\t\tCalling PL_strlen).\n");
        length = PL_strlen(asciiString);
        PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_AllocItem).\n");
        secItem = SECITEM_AllocItem(NULL, NULL, length);
        PKIX_GENERALNAME_DEBUG("\t\tCalling PORT_Memcpy).\n");
        (void) PORT_Memcpy(secItem->data, asciiString, length);
        PKIX_CERT_DEBUG("\t\tCalling PORT_NewArena).\n");
        arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
        if (arena == NULL) {
                PKIX_ERROR(PKIX_OUTOFMEMORY);
        }
        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_NewGeneralName).\n");
        nssGenName = CERT_NewGeneralName(arena, nameType);
        if (nssGenName == NULL) {
                PKIX_ERROR(PKIX_ALLOCATENEWCERTGENERALNAMEFAILED);
        }

        switch (nameType) {
        case certRFC822Name:
        case certDNSName:
        case certURI:
                nssGenName->name.other = *secItem;
                break;

        case certDirectoryName:

                PKIX_CHECK(PKIX_PL_X500Name_Create
                            (stringRep, &pkixDN, plContext),
                            PKIX_X500NAMECREATEFAILED);

                PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_AsciiToName).\n");
                nssCertName = CERT_AsciiToName(asciiString);
                nssGenName->name.directoryName = *nssCertName;
                break;

        case certRegisterID:
                PKIX_CHECK(PKIX_PL_OID_Create
                            (asciiString, &pkixOID, plContext),
                            PKIX_OIDCREATEFAILED);
                nssGenName->name.other = *secItem;
                break;
        default:
                /* including IPAddress, EDIPartyName, OtherName, X400Address */
                PKIX_ERROR(PKIX_UNABLETOCREATEGENERALNAMEOFTHISTYPE);
        }

        /* create a PKIX_PL_GeneralName object */
        PKIX_CHECK(PKIX_PL_Object_Alloc
                    (PKIX_GENERALNAME_TYPE,
                    sizeof (PKIX_PL_GeneralName),
                    (PKIX_PL_Object **)&genName,
                    plContext),
                    PKIX_COULDNOTCREATEOBJECT);

        /* create a CERTGeneralNameList */
        nssGenName->type = nameType;
        PKIX_GENERALNAME_DEBUG("\t\tCalling CERT_CreateGeneralNameList).\n");
        nssGenNameList = CERT_CreateGeneralNameList(nssGenName);
        if (nssGenNameList == NULL) {
                PKIX_ERROR(PKIX_CERTCREATEGENERALNAMELISTFAILED);
        }
        genName->nssGeneralNameList = nssGenNameList;

        /* initialize fields */
        genName->type = nameType;
        genName->directoryName = pkixDN;
        genName->OthName = NULL;
        genName->other = secItem;
        genName->oid = pkixOID;

        *pGName = genName;
cleanup:

        PKIX_FREE(asciiString);

        if (nssCertName != NULL) {
                PKIX_CERT_DEBUG("\t\tCalling CERT_DestroyName).\n");
                CERT_DestroyName(nssCertName);
        }

        if (arena){ /* will free nssGenName */
                PKIX_CERT_DEBUG("\t\tCalling PORT_FreeArena).\n");
                PORT_FreeArena(arena, PR_FALSE);
        }

        if (PKIX_ERROR_RECEIVED){
                PKIX_DECREF(pkixDN);
                PKIX_DECREF(pkixOID);

                PKIX_GENERALNAME_DEBUG("\t\tCalling SECITEM_FreeItem).\n");
                if (secItem){
                        SECITEM_FreeItem(secItem, PR_TRUE);
                        secItem = NULL;
                }
        }

        PKIX_RETURN(GENERALNAME);
}