mitm.common.security.crl.PKITSTest.java Source code

Java tutorial

Introduction

Here is the source code for mitm.common.security.crl.PKITSTest.java

Source

/*
 * Copyright (c) 2008-2011, Martijn Brinkers, Djigzo.
 * 
 * This file is part of Djigzo email encryption.
 *
 * Djigzo is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License 
 * version 3, 19 November 2007 as published by the Free Software 
 * Foundation.
 *
 * Djigzo is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
 * GNU Affero General Public License for more details.
 *
 * You should have received a copy of the GNU Affero General Public 
 * License along with Djigzo. If not, see <http://www.gnu.org/licenses/>
 *
 * Additional permission under GNU AGPL version 3 section 7
 * 
 * If you modify this Program, or any covered work, by linking or 
 * combining it with aspectjrt.jar, aspectjweaver.jar, tyrex-1.0.3.jar, 
 * freemarker.jar, dom4j.jar, mx4j-jmx.jar, mx4j-tools.jar, 
 * spice-classman-1.0.jar, spice-loggerstore-0.5.jar, spice-salt-0.8.jar, 
 * spice-xmlpolicy-1.0.jar, saaj-api-1.3.jar, saaj-impl-1.3.jar, 
 * wsdl4j-1.6.1.jar (or modified versions of these libraries), 
 * containing parts covered by the terms of Eclipse Public License, 
 * tyrex license, freemarker license, dom4j license, mx4j license,
 * Spice Software License, Common Development and Distribution License
 * (CDDL), Common Public License (CPL) the licensors of this Program grant 
 * you additional permission to convey the resulting work.
 */
package mitm.common.security.crl;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.math.BigInteger;
import java.security.NoSuchProviderException;
import java.security.cert.CRLException;
import java.security.cert.CertPath;
import java.security.cert.CertPathBuilderException;
import java.security.cert.CertPathBuilderResult;
import java.security.cert.CertStore;
import java.security.cert.CertStoreException;
import java.security.cert.Certificate;
import java.security.cert.CertificateException;
import java.security.cert.PKIXCertPathBuilderResult;
import java.security.cert.TrustAnchor;
import java.security.cert.X509CRL;
import java.security.cert.X509CertSelector;
import java.security.cert.X509Certificate;
import java.text.ParseException;
import java.util.Collection;
import java.util.Date;

import mitm.common.hibernate.HibernateSessionSource;
import mitm.common.hibernate.SessionManager;
import mitm.common.hibernate.SessionManagerImpl;
import mitm.common.hibernate.StandardHibernateSessionSourceImpl;
import mitm.common.security.SecurityFactoryFactoryException;
import mitm.common.security.bouncycastle.InitializeBouncycastle;
import mitm.common.security.certificate.CertificateUtils;
import mitm.common.security.certpath.CertStoreTrustAnchorBuilder;
import mitm.common.security.certpath.CertificatePathBuilder;
import mitm.common.security.certpath.SMIMEExtendedKeyUsageCertPathChecker;
import mitm.common.security.certpath.TrustAnchorBuilder;
import mitm.common.security.certpath.TrustAnchorBuilderPKIXCertificatePathBuilder;
import mitm.common.security.certstore.X509CertStoreExt;
import mitm.common.security.certstore.hibernate.X509CertStoreExtAutoCommitFactory;
import mitm.common.security.certstore.jce.X509CertStoreParameters;
import mitm.common.security.crlstore.CRLStoreException;
import mitm.common.security.crlstore.X509CRLStoreExt;
import mitm.common.security.crlstore.hibernate.X509CRLStoreExtAutoCommitFactory;
import mitm.common.security.provider.MITMProvider;
import mitm.common.util.BigIntegerUtils;
import mitm.test.TestUtils;

import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.PropertyConfigurator;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * Some test cases for the CRL tests of PKITS
 * @author Martijn Brinkers
 *
 */
public class PKITSTest {
    private static final File hibernateConfig = new File("test/resources/hibernate.cfg.xml");

    private static final File testBase = new File("test/resources/testdata/PKITS");

    private static HibernateSessionSource sessionSource;
    private static CertStore certStore;
    private static X509CertStoreParameters certStoreParams;
    private static X509CertStoreParameters rootStoreParams;
    private static TrustAnchorBuilder trustAnchorBuilder;
    private static Date testDate;

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        PropertyConfigurator.configure("conf/log4j.properties");

        InitializeBouncycastle.initialize();

        sessionSource = new StandardHibernateSessionSourceImpl(hibernateConfig);

        SessionManager sessionManager = new SessionManagerImpl(sessionSource);

        MITMProvider.initialize(sessionManager);

        certStoreParams = new X509CertStoreParameters(
                new X509CertStoreExtAutoCommitFactory(sessionSource, "certificates").create(),
                new X509CRLStoreExtAutoCommitFactory(sessionSource, "certificates").create());

        certStore = CertStore.getInstance(MITMProvider.DATABASE_CERTSTORE, certStoreParams, "mitm");

        rootStoreParams = new X509CertStoreParameters(
                new X509CertStoreExtAutoCommitFactory(sessionSource, "roots").create());

        trustAnchorBuilder = new CertStoreTrustAnchorBuilder(rootStoreParams.getCertStore(), 0 /* seconds */);

        testDate = TestUtils.parseDate("01-Dec-2007 16:38:35 GMT");
    }

    @Before
    public void setup() throws Exception {
        certStoreParams.getCertStore().removeAllEntries();
        certStoreParams.getCRLStore().removeAllEntries();

        rootStoreParams.getCertStore().removeAllEntries();

        addCertificates(new File(testBase, "certs/TrustAnchorRootCertificate.crt"), rootStoreParams.getCertStore());
    }

    private static void addCRL(File crlFile, X509CRLStoreExt crlStore) throws CRLException {
        try {
            X509CRL crl = TestUtils.loadX509CRL(crlFile);

            crlStore.addCRL(crl);
        } catch (CRLStoreException e) {
            throw new CRLException(e);
        } catch (CertificateException e) {
            throw new CRLException(e);
        } catch (NoSuchProviderException e) {
            throw new CRLException(e);
        } catch (SecurityFactoryFactoryException e) {
            throw new CRLException(e);
        } catch (FileNotFoundException e) {
            throw new CRLException(e);
        }
    }

    private static void addCertificates(File file, X509CertStoreExt certStore)
            throws CertificateException, NoSuchProviderException, CertStoreException, IOException {
        Collection<? extends Certificate> certificates = CertificateUtils.readCertificates(file);

        for (Certificate certificate : certificates) {
            if (certificate instanceof X509Certificate) {
                if (!certStore.contains((X509Certificate) certificate)) {
                    certStore.addCertificate((X509Certificate) certificate);
                }
            }
        }
    }

    private PKIXCertPathBuilderResult getCertPathBuilderResult(X509CertSelector selector)
            throws CertPathBuilderException, ParseException {
        CertificatePathBuilder builder = new TrustAnchorBuilderPKIXCertificatePathBuilder(trustAnchorBuilder);

        builder.addCertPathChecker(new SMIMEExtendedKeyUsageCertPathChecker());
        builder.addCertStore(certStore);
        builder.setRevocationEnabled(false);

        /*
         * Since the certificates under test expired on 19/04/2011 we need to set 
         * the date explicitly
         */
        builder.setDate(TestUtils.parseDate("24-Mar-2008 16:38:35 GMT"));

        CertPathBuilderResult result = builder.buildPath(selector);

        assertTrue(result instanceof PKIXCertPathBuilderResult);

        return (PKIXCertPathBuilderResult) result;
    }

    @Test
    public void test_4_4_1_Missing_CRL_Test1() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/NoCRLCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidMissingCRLTest1EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(new BigInteger("1"));
        selector.setIssuer("CN=No CRL CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_2_Invalid_Revoked_CA_Test2() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/GoodCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/RevokedsubCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidRevokedCATest2EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/GoodCACRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/RevokedsubCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(new BigInteger("1"));
        selector.setIssuer("CN=Revoked subCA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 3);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.REVOKED, detail[1].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[2].getStatus());
    }

    @Test
    public void test_4_4_3_Invalid_Revoked_EE_Test3() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/GoodCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidRevokedEETest3EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/GoodCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("F"));
        selector.setIssuer("CN=Good CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_4_4_Invalid_Bad_CRL_Signature_Test4() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/BadCRLSignatureCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidBadCRLSignatureTest4EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/BadCRLSignatureCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Bad CRL Signature CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        // unknown because the CRLs signature was invalid and therefore not included in the search
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_5_Invalid_Bad_CRL_Issuer_Name_Test5() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/BadCRLIssuerNameCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidBadCRLIssuerNameTest5EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/BadCRLIssuerNameCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Bad CRL Issuer Name CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_6_Invalid_Wrong_CRL_Test6() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/WrongCRLCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidWrongCRLTest6EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        // This test wants us to add "WrongCRLCACRL.crl" but it's the exact same crl as "TrustAnchorRootCRL.crl"
        // so we will not add it again because we can only add a crl just once (thumbprint must be unique)

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Wrong CRL CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_7_Valid_Two_CRLs_Test7() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/TwoCRLsCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidTwoCRLsTest7EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/TwoCRLsCAGoodCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/TwoCRLsCABadCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Two CRLs CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_8_Invalid_Unknown_CRL_Entry_Extension_Test8() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/UnknownCRLEntryExtensionCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidUnknownCRLEntryExtensionTest8EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/UnknownCRLEntryExtensionCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Unknown CRL Entry Extension CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_4_9_Invalid_Unknown_CRL_Extension_Test9() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/UnknownCRLExtensionCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidUnknownCRLExtensionTest9EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/UnknownCRLExtensionCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Unknown CRL Extension CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_4_10_Invalid_Unknown_CRL_Extension_Test10() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/UnknownCRLExtensionCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidUnknownCRLExtensionTest10EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/UnknownCRLExtensionCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("CN=Unknown CRL Extension CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNSUPPORTED_CRITICAL_EXTENSION, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNSUPPORTED_CRITICAL_EXTENSION, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_11_Invalid_Old_CRL_nextUpdate_Test11() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/OldCRLnextUpdateCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidOldCRLnextUpdateTest11EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/OldCRLnextUpdateCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=Old CRL nextUpdate CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        Date now = TestUtils.parseDate("02-Jan-2002 16:38:35 GMT");

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, now);

        assertEquals(RevocationStatus.EXPIRED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.EXPIRED, detail[0].getStatus());
        assertTrue(DateUtils.addDays(detail[0].getNextUpdate(), 2).after(now));
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_12_Invalid_pre2000_CRL_nextUpdate_Test12() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/pre2000CRLnextUpdateCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/Invalidpre2000CRLnextUpdateTest12EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/pre2000CRLnextUpdateCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=pre2000 CRL nextUpdate CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.EXPIRED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.EXPIRED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_13_Valid_GeneralizedTime_CRL_nextUpdate_Test13() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/GeneralizedTimeCRLnextUpdateCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidGeneralizedTimeCRLnextUpdateTest13EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/GeneralizedTimeCRLnextUpdateCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=GenerizedTime CRL nextUpdate CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_14_Valid_Negative_Serial_Number_Test14() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/NegativeSerialNumberCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidNegativeSerialNumberTest14EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/NegativeSerialNumberCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("FF"));
        selector.setIssuer("CN=Negative Serial Number CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_15_Invalid_Negative_Serial_Number_Test15() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/NegativeSerialNumberCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidNegativeSerialNumberTest15EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/NegativeSerialNumberCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(new BigInteger("-1"));
        selector.setIssuer("CN=Negative Serial Number CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_4_16_Valid_Long_Serial_Number_Test16() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/LongSerialNumberCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidLongSerialNumberTest16EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/LongSerialNumberCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("7F0102030405060708090A0B0C0D0E0F10111212"));
        selector.setIssuer("CN=Long Serial Number CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_17_Valid_Long_Serial_Number_Test17() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/LongSerialNumberCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidLongSerialNumberTest17EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/LongSerialNumberCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("7E0102030405060708090A0B0C0D0E0F10111213"));
        selector.setIssuer("CN=Long Serial Number CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_4_18_Invalid_Long_Serial_Number_Test18() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/LongSerialNumberCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidLongSerialNumberTest18EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/LongSerialNumberCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("7F0102030405060708090A0B0C0D0E0F10111213"));
        selector.setIssuer("CN=Long Serial Number CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    // TODO: Add support for multiple signing keys for tests 4.4.19 - 4.4.21. 

    @Test
    public void test_4_7_4_Invalid_keyUsage_Critical_cRLSign_False_Test4() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/keyUsageCriticalcRLSignFalseCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidkeyUsageCriticalcRLSignFalseTest4EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/keyUsageCriticalcRLSignFalseCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=keyUsage Critical cRLSign False CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
    }

    @Test
    public void test_4_7_5_Invalid_keyUsage_Not_Critical_cRLSign_False_Test5() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/keyUsageNotCriticalcRLSignFalseCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidkeyUsageNotCriticalcRLSignFalseTest5EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/keyUsageNotCriticalcRLSignFalseCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=keyUsage Not Critical cRLSign False CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
    }

    @Test
    public void test_4_15_1_Invalid_deltaCRLIndicator_No_Base_Test1() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLIndicatorNoBaseCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddeltaCRLIndicatorNoBaseTest1EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLIndicatorNoBaseCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=deltaCRLIndicator No Base CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_15_2_Valid_delta_CRL_Test2() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA1Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValiddeltaCRLTest2EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=deltaCRL CA1, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_15_3_Invalid_delta_CRL_Test3() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA1Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddeltaCRLTest3EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("CN=deltaCRL CA1, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_15_4_Invalid_delta_CRL_Test4() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA1Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddeltaCRLTest4EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("3"));
        selector.setIssuer("CN=deltaCRL CA1, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    // TODO: Support 4.15.5 Valid delta-CRL Test5. Whoever came up with the stupid idea of onHold and removed 
    // from CRL probably never built any systems him/her-self.

    @Test
    public void test_4_15_6_Invalid_delta_CRL_Test6() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA1Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddeltaCRLTest6EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA1deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("5"));
        selector.setIssuer("CN=deltaCRL CA1, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    // TODO: Support 4.15.7 Valid delta-CRL Test7

    @Test
    public void test_4_15_8_Valid_delta_CRL_Test8() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA2Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValiddeltaCRLTest8EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA2CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA2deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=deltaCRL CA2, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_15_9_Invalid_delta_CRL_Test9() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA2Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddeltaCRLTest9EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA2CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA2deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("CN=deltaCRL CA2, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_15_10_Invalid_delta_CRL_Test10() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/deltaCRLCA3Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddeltaCRLTest10EE.crt"), certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA3CRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/deltaCRLCA3deltaCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=deltaCRL CA3, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.EXPIRED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.EXPIRED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_1_Valid_distributionPoint_Test1() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint1CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValiddistributionPointTest1EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint1CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("OU=distributionPoint1 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_2_Invalid_distributionPoint_Test2() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint1CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddistributionPointTest2EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint1CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("OU=distributionPoint1 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_14_3_Invalid_distributionPoint_Test3() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint1CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddistributionPointTest3EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint1CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("3"));
        selector.setIssuer("OU=distributionPoint1 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_4_Valid_distributionPoint_Test4() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint1CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValiddistributionPointTest4EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint1CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("4"));
        selector.setIssuer("OU=distributionPoint1 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_5_Valid_distributionPoint_Test5() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint2CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValiddistributionPointTest5EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint2CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("OU=distributionPoint2 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_6_Invalid_distributionPoint_Test6() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint2CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddistributionPointTest6EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint2CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("OU=distributionPoint2 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_14_7_Valid_distributionPoint_Test7() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint2CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValiddistributionPointTest7EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint2CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("3"));
        selector.setIssuer("OU=distributionPoint2 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_8_Invalid_distributionPoint_Test8() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint2CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddistributionPointTest8EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint2CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("4"));
        selector.setIssuer("OU=distributionPoint2 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_9_Invalid_distributionPoint_Test9() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/distributionPoint2CACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvaliddistributionPointTest9EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/distributionPoint2CACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("5"));
        selector.setIssuer("OU=distributionPoint2 CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_10_Valid_No_issuingDistributionPoint_Test10() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/NoissuingDistributionPointCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidNoissuingDistributionPointTest10EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/NoissuingDistributionPointCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("OU=No issuingDistributionPoint CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_11_Invalid_onlyContainsUserCerts_CRL_Test11() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlyContainsUserCertsCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlyContainsUserCertsTest11EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlyContainsUserCertsCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=onlyContainsUserCerts CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_12_Invalid_onlyContainsCACerts_CRL_Test12() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlyContainsCACertsCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlyContainsCACertsTest12EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlyContainsCACertsCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=onlyContainsCACerts CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_13_Valid_onlyContainsCACerts_CRL_Test13() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlyContainsCACertsCACert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidonlyContainsCACertsTest13EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlyContainsCACertsCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("CN=onlyContainsCACerts CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_14_Invalid_onlyContainsAttributeCerts_Test14() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlyContainsAttributeCertsCACert.crt"),
                certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlyContainsAttributeCertsTest14EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlyContainsAttributeCertsCACRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=onlyContainsAttributeCerts CA, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);
        assertEquals("CN=Trust Anchor, O=Test Certificates, C=US",
                trustAnchor.getTrustedCert().getSubjectX500Principal().toString());

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_15_Invalid_onlySomeReasons_Test15() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA1Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlySomeReasonsTest15EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA1compromiseCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA1otherreasonsCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=onlySomeReasons CA1, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_14_16_Invalid_onlySomeReasons_Test16() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA1Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlySomeReasonsTest16EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA1compromiseCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA1otherreasonsCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("CN=onlySomeReasons CA1, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.CERTIFICATE_HOLD, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_14_17_Invalid_onlySomeReasons_Test17() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA2Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlySomeReasonsTest17EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA2CRL1.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA2CRL2.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("CN=onlySomeReasons CA2, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.UNKNOWN, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.UNKNOWN, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_18_Valid_onlySomeReasons_Test18() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA3Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidonlySomeReasonsTest18EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA3compromiseCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA3otherreasonsCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("OU=onlySomeReasons CA3, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_19_Valid_onlySomeReasons_Test19() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA4Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/ValidonlySomeReasonsTest19EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA4compromiseCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA4otherreasonsCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("1"));
        selector.setIssuer("OU=onlySomeReasons CA4, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.NOT_REVOKED, revocationResult.getStatus());
        assertEquals(null, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.NOT_REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.NOT_REVOKED, detail[1].getStatus());
    }

    @Test
    public void test_4_14_20_Invalid_onlySomeReasons_Test20() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA4Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlySomeReasonsTest20EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA4compromiseCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA4otherreasonsCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("2"));
        selector.setIssuer("OU=onlySomeReasons CA4, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.KEY_COMPROMISE, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    @Test
    public void test_4_14_21_Invalid_onlySomeReasons_Test21() throws Exception {
        // add certificates
        addCertificates(new File(testBase, "certs/onlySomeReasonsCA4Cert.crt"), certStoreParams.getCertStore());
        addCertificates(new File(testBase, "certs/InvalidonlySomeReasonsTest21EE.crt"),
                certStoreParams.getCertStore());

        // add crls
        addCRL(new File(testBase, "crls/TrustAnchorRootCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA4compromiseCRL.crl"), certStoreParams.getCRLStore());
        addCRL(new File(testBase, "crls/onlySomeReasonsCA4otherreasonsCRL.crl"), certStoreParams.getCRLStore());

        X509CertSelector selector = new X509CertSelector();

        selector.setSerialNumber(BigIntegerUtils.hexDecode("3"));
        selector.setIssuer("OU=onlySomeReasons CA4, O=Test Certificates, C=US");

        PKIXCertPathBuilderResult result = getCertPathBuilderResult(selector);

        CertPath certPath = result.getCertPath();

        TrustAnchor trustAnchor = result.getTrustAnchor();

        assertNotNull(trustAnchor);

        PKIXRevocationChecker revocationChecker = new PKIXRevocationChecker(certStoreParams.getCRLStore());

        RevocationResult revocationResult = revocationChecker.getRevocationStatus(certPath, trustAnchor, testDate);

        assertEquals(RevocationStatus.REVOKED, revocationResult.getStatus());
        assertEquals(RevocationReason.AFFILIATION_CHANGED, revocationResult.getReason());

        RevocationDetail[] detail = revocationResult.getDetails();

        assertEquals(detail.length, 2);
        assertEquals(RevocationStatus.REVOKED, detail[0].getStatus());
        assertEquals(RevocationStatus.UNKNOWN, detail[1].getStatus());
    }

    // TODO: support indirect CRLs 

}