org.cesecore.certificates.ca.internal.CaCertificateCacheTest.java Source code

Java tutorial

Introduction

Here is the source code for org.cesecore.certificates.ca.internal.CaCertificateCacheTest.java

Source

/*************************************************************************
 *                                                                       *
 *  CESeCore: CE Security Core                                           *
 *                                                                       *
 *  This software is free software; you can redistribute it and/or       *
 *  modify it under the terms of the GNU Lesser General Public           *
 *  License as published by the Free Software Foundation; either         *
 *  version 2.1 of the License, or any later version.                    *
 *                                                                       *
 *  See terms of license at gnu.org.                                     *
 *                                                                       *
 *************************************************************************/
package org.cesecore.certificates.ca.internal;

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.fail;

import java.security.SignatureException;
import java.security.cert.Certificate;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Date;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.cesecore.certificates.certificate.HashID;
import org.cesecore.util.Base64;
import org.cesecore.util.CertTools;
import org.cesecore.util.CryptoProviderTools;
import org.junit.BeforeClass;
import org.junit.Test;

/**
 * @version $Id$
 */
public class CaCertificateCacheTest {
    private static final Logger log = Logger.getLogger(CaCertificateCacheTest.class);

    private static byte[] testroot = Base64
            .decode(("MIICPDCCAaWgAwIBAgIIV++ss+Mrw5MwDQYJKoZIhvcNAQEFBQAwLjERMA8GA1UE"
                    + "AwwIVGVzdFJvb3QxDDAKBgNVBAoMA0ZvbzELMAkGA1UEBhMCU0UwHhcNMDgwOTI5"
                    + "MTM0MjQwWhcNMTYxMjE2MTM0MjQwWjAuMREwDwYDVQQDDAhUZXN0Um9vdDEMMAoG"
                    + "A1UECgwDRm9vMQswCQYDVQQGEwJTRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC"
                    + "gYEAwdqYTCu31Xklrx2isHXUIpSrjD0mGyzPW/qPzolnEsSKAkLW+X8UJ8KcN9ky"
                    + "tsJ9sUSHGGmQFtKP4gyhqJymqHKGVjEIxri223svJ5K8gQezC6XDemxXSRR71Yc4"
                    + "9OM8kpNNVlFU8rZLMNz+xgY9AtAfIczOzqM16DgBmXBUsrECAwEAAaNjMGEwHQYD"
                    + "VR0OBBYEFPPHQ/qJU5mliblHt5kq39l0C82SMA8GA1UdEwEB/wQFMAMBAf8wHwYD"
                    + "VR0jBBgwFoAU88dD+olTmaWJuUe3mSrf2XQLzZIwDgYDVR0PAQH/BAQDAgGGMA0G"
                    + "CSqGSIb3DQEBBQUAA4GBABbKUK1KKofZ3w0a15HIsT6MK/3qKZp/pE0l8GWplk2t"
                    + "YEE1fkAbWolreKHG79HP4a0X/FOxd11qDeGzoGjFsLxrLNlxZCH8GyI/mILTNpba"
                    + "5/b9Xrjqj2rTYQOIXeakxCsMbMT+tg7ZHdUPmgcWxtqXlEhOdtZFJd8+u8tDgbsn").getBytes());

    private static byte[] testrootnew = Base64
            .decode(("MIICPDCCAaWgAwIBAgIIC662hmhBnZowDQYJKoZIhvcNAQEFBQAwLjERMA8GA1UE"
                    + "AwwIVGVzdFJvb3QxDDAKBgNVBAoMA0ZvbzELMAkGA1UEBhMCU0UwHhcNMDgwOTI5"
                    + "MTM0MzM3WhcNMTYxMjE2MTM0MzM3WjAuMREwDwYDVQQDDAhUZXN0Um9vdDEMMAoG"
                    + "A1UECgwDRm9vMQswCQYDVQQGEwJTRTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkC"
                    + "gYEAtIDhCc+3/BvugFO1n30V3g9GfrLstMeEq3kNvEF5saymdPTrHfrFR5uPo5Oq"
                    + "NAt7EoxTkfQLBhBHI8hpame/84MMbedynxhzLOiQ2XYLo8VKYghC7lJhx3oW0ksV"
                    + "EpNv5R7hVJvfiYkHry9k9I/uQuA2W1VIDTIHj4HSl2rk65cCAwEAAaNjMGEwHQYD"
                    + "VR0OBBYEFNrpYRScm6wyswfE29bOIKcBXTw1MA8GA1UdEwEB/wQFMAMBAf8wHwYD"
                    + "VR0jBBgwFoAU2ulhFJybrDKzB8Tb1s4gpwFdPDUwDgYDVR0PAQH/BAQDAgGGMA0G"
                    + "CSqGSIb3DQEBBQUAA4GBAEmNfSwgrUZlSLWcOWNcLgUKK1ownvxAZevCAlxgpLIV"
                    + "PqbpBmgoCYjvAB1O1kuEg52VT+mGSpnZi4LjylDmNosu60E3jI/FsP6e6d2hH7ZY"
                    + "BMvj/m5uhSQArLo5R2NRIkmR34tXqOjTsL+3+n3sT2H5++9D1+ZqpAP2Sn1Ba8GB").getBytes());

    private static byte[] testsub = Base64
            .decode(("MIICOzCCAaSgAwIBAgIIFUunDyPOxAIwDQYJKoZIhvcNAQEFBQAwLjERMA8GA1UE"
                    + "AwwIVGVzdFJvb3QxDDAKBgNVBAoMA0ZvbzELMAkGA1UEBhMCU0UwHhcNMDgwOTI5"
                    + "MTM0MzA5WhcNMTYxMjE2MTM0MjQwWjAtMRAwDgYDVQQDDAdUZXN0U3ViMQwwCgYD"
                    + "VQQKDANGb28xCzAJBgNVBAYTAlNFMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKB"
                    + "gQCX+ZIrBqpeTILZZZPVBPB07+De19a0857G5zU7BAtpxIDULX1OsMiGdVBtX/5W"
                    + "4Cm9/G2Eo1Eqm+xiP06HlFmfU58XlkUR9v3OLXZ3Rza3n//HcPXsDnLvkcPrUFcs"
                    + "LNSg4b2bPPiFtBkghD796+8ltJrNhJfR64AUWfSx/ttLIQIDAQABo2MwYTAdBgNV"
                    + "HQ4EFgQUwt1LdwXjTeZ0yldTclKlDA+eHWQwDwYDVR0TAQH/BAUwAwEB/zAfBgNV"
                    + "HSMEGDAWgBTzx0P6iVOZpYm5R7eZKt/ZdAvNkjAOBgNVHQ8BAf8EBAMCAYYwDQYJ"
                    + "KoZIhvcNAQEFBQADgYEAHG6JVMk/hQN8OdCnGvricq7deGlbWA7WEf5sxY1RekuN"
                    + "QTDenb5DWcN6XcuSHZsXJUGn3yEDjYpY6KL95XCw8mzTjmYN0sbIM3QEN0G3euir"
                    + "dAOftW06blL0zNiQ6/z4MrGmZgTf9Agf5W6uhsx2BwVCMN7bVWVIm9MlU+SW6YM=").getBytes());

    private static byte[] testcvc = Base64
            .decode(("fyGCAWh/ToHgXykBAEIOU0VDVkNUZXN0MDAwMDF/SYGUBgoEAH8ABwICAgEBgYGA"
                    + "h2uvpDVvYQygDCpZ91ln37I2UcEAPFSjgsNGRq1tJ6Xl+SueIbdR8zfc62+8yNBH"
                    + "3PsI/Ogt48NehSI2Z4CAXMbE4coyB7iQHlXUKpb+oBgXU+7LsDxvgDXtcypZwxJ2"
                    + "PePOnkXUL7HY384skrwxqUDU/xrTvD/5M0yEIHcoAn+CAwEAAV8gDlNFQ1ZDVGVz"
                    + "dDAwMDAxf0wOBgkEAH8ABwMBAgFTAcNfJQYACAAJAglfJAYBAQEAAQVfN4GANzKf"
                    + "g4ItaN47UZDTMHiJ3ZVyPl+kHSKqUKH7HaKOblfGoNjAj80iAm9Igk+c8A7IzGpI"
                    + "z17COVI1WexxFk25cOoxcMloCKwWCSXHR5NNvDOGiVlszjv4f5xQ1dw6nQmzy8q/"
                    + "aO1xupXZzGSTeMxs3Ex1LYsZGJnHCa/xDf017n4=").getBytes());

    private static byte[] testscepca = Base64
            .decode(("MIICzjCCAbagAwIBAgIILbZXprQLU6EwDQYJKoZIhvcNAQEFBQAwNzERMA8GA1UE"
                    + "AwwIQWRtaW5DQTExFTATBgNVBAoMDEVKQkNBIFNhbXBsZTELMAkGA1UEBhMCU0Uw"
                    + "HhcNMDgwOTI0MTQ0OTE5WhcNMDkwMTEzMTQ0OTE5WjA2MRAwDgYDVQQDDAdTY2Vw"
                    + "IENBMRUwEwYDVQQKDAxFSkJDQSBTYW1wbGUxCzAJBgNVBAYTAlNFMIGfMA0GCSqG"
                    + "SIb3DQEBAQUAA4GNADCBiQKBgQCh6H9flRL2prEjZDr9sDjmoT7kckILiW6cJ4VG"
                    + "aPh2B8IHct+2QUlZ0Bjk0c7Jdq0USaItDl9V3yQRweCrl+WHMAiAwWRJIQAXi1B5"
                    + "8xbZJPIvJ0SpPeM9fNGoqlIYZRWoHblOAdCFiUHA/yKgPuH7AN5sYAppm/iP8BEa"
                    + "/o9nawIDAQABo2MwYTAdBgNVHQ4EFgQU5J8drR5lZGK1p12hfq2Z+PgWz+4wDwYD"
                    + "VR0TAQH/BAUwAwEB/zAfBgNVHSMEGDAWgBSSeB41+0/rZ+2/qiX7X4bvrVKjWDAO"
                    + "BgNVHQ8BAf8EBAMCAYYwDQYJKoZIhvcNAQEFBQADggEBADjUPxvEEijoIJ+/93+0"
                    + "3zASkDQoI9vPOh7AIRya9KF5EeiTXNJghTs078n7TGPP21y7TDnE1CU218B6QPMd"
                    + "+L0c+WMUtr/6i4lI2Nh/wvKbBLEPKutrnFQbZY4MlTXS3Iu15VqawppFf+tVVuZQ"
                    + "KHx0ynzxToAJRCuryOBl/iRrBaXNyoMOYcooJhHTO/g/0/0enAPnWz39bl4CAgCi"
                    + "NfseeJcdbQFcjCyruIf2NL+8l8AuZXyLuMQE6/yqxUdNv7gZvrpk5Z+c9ZcseLTl"
                    + "3GHFTxIySlmZCblZbJzQxO5pRz27B2vPJqicA0cmoBxUQK3NHGO+WyQ+ZpZX5vl/" + "+xc=").getBytes());

    @BeforeClass
    public static void beforeClass() throws Exception {
        CryptoProviderTools.installBCProvider();
    }

    @Test
    public void test01CACertificates() throws Exception {
        // Prepare the certificate cache with some test certificates
        Collection<Certificate> certs = new ArrayList<Certificate>();
        X509Certificate testrootcert = CertTools.getCertfromByteArray(testroot, X509Certificate.class);
        certs.add(testrootcert);
        X509Certificate testrootnewcert = CertTools.getCertfromByteArray(testrootnew, X509Certificate.class);
        certs.add(testrootnewcert);
        X509Certificate testsubcert = CertTools.getCertfromByteArray(testsub, X509Certificate.class);
        certs.add(testsubcert);
        Certificate testcvccert = CertTools.getCertfromByteArray(testcvc, Certificate.class);
        certs.add(testcvccert);
        X509Certificate testscepcert = CertTools.getCertfromByteArray(testscepca, X509Certificate.class);
        certs.add(testscepcert);
        CaCertificateCache cache = CaCertificateCache.INSTANCE;
        cache.loadCertificates(certs);

        // Test lookup of not existing cert
        X509Certificate cert = cache.findLatestBySubjectDN(HashID.getFromDNString("CN=Foo,C=SE"));
        assertNull(cert);
        // Old root cert should not be found, we only store the latest to be found by subjectDN
        X509Certificate rootcert = cache.findLatestBySubjectDN(HashID.getFromSubjectDN(testrootnewcert));
        assertNotNull(rootcert);
        X509Certificate subcert = cache.findLatestBySubjectDN(HashID.getFromSubjectDN(testsubcert));
        // This old subcert should not be possible to verify with the new root cert
        try {
            subcert.verify(rootcert.getPublicKey());
            fail("verification should have failed");
        } catch (SignatureException e) {
        } // NOPMD: BC 1.47
        // CVC certificate should not be part of OCSP certificate cache
        cert = cache.findLatestBySubjectDN(HashID.getFromDNString(CertTools.getSubjectDN(testcvccert)));
        assertNull(cert);
        cert = cache.findLatestBySubjectDN(HashID.getFromSubjectDN(testscepcert));
        assertEquals(CertTools.getSubjectDN(testscepcert), CertTools.getSubjectDN(cert));

    }

    public static Throwable threadException = null;

    @Test
    public void test02loadCertificates() throws Exception {
        Collection<Certificate> certs = new ArrayList<Certificate>();
        X509Certificate testrootcert = CertTools.getCertfromByteArray(testroot, X509Certificate.class);
        certs.add(testrootcert);
        X509Certificate testrootnewcert = CertTools.getCertfromByteArray(testrootnew, X509Certificate.class);
        certs.add(testrootnewcert);
        X509Certificate testsubcert = CertTools.getCertfromByteArray(testsub, X509Certificate.class);
        certs.add(testsubcert);
        Certificate testcvccert = CertTools.getCertfromByteArray(testcvc, Certificate.class);
        certs.add(testcvccert);
        X509Certificate testscepcert = CertTools.getCertfromByteArray(testscepca, X509Certificate.class);
        certs.add(testscepcert);
        CaCertificateCache cache = CaCertificateCache.INSTANCE;
        cache.loadCertificates(certs);

        Thread no1 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testscepcert)), "no1"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no2 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testrootcert)), "no2"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no3 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testrootnewcert)), "no3"); // NOPMD we want to use thread here, it's not a JEE app
        // No4 uses CV Certificates, and it will never return anything from the cache because this cache (OCSP) only handles X.509 certificates
        Thread no4 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testcvccert)), "no4"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no5 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testscepcert)), "no5"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no11 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testscepcert)), "no1"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no22 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testrootcert)), "no2"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no33 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testrootnewcert)), "no3"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no44 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testcvccert)), "no4"); // NOPMD we want to use thread here, it's not a JEE app
        Thread no55 = new Thread(new CacheTester(cache, CertTools.getSubjectDN(testscepcert)), "no5"); // NOPMD we want to use thread here, it's not a JEE app
        CacheExceptionHandler handler = new CacheExceptionHandler();
        no1.setUncaughtExceptionHandler(handler);
        no2.setUncaughtExceptionHandler(handler);
        no3.setUncaughtExceptionHandler(handler);
        no4.setUncaughtExceptionHandler(handler);
        no5.setUncaughtExceptionHandler(handler);
        no11.setUncaughtExceptionHandler(handler);
        no22.setUncaughtExceptionHandler(handler);
        no33.setUncaughtExceptionHandler(handler);
        no44.setUncaughtExceptionHandler(handler);
        no55.setUncaughtExceptionHandler(handler);
        long start = new Date().getTime();
        no1.start();
        log.info("Started no1");
        no2.start();
        log.info("Started no2");
        no3.start();
        log.info("Started no3");
        no4.start();
        log.info("Started no4");
        no5.start();
        log.info("Started no5");
        no11.start();
        log.info("Started no11");
        no22.start();
        log.info("Started no22");
        no33.start();
        log.info("Started no33");
        no44.start();
        log.info("Started no44");
        no55.start();
        log.info("Started no55");
        no1.join();
        no2.join();
        no3.join();
        no4.join();
        no5.join();
        no11.join();
        no22.join();
        no33.join();
        no44.join();
        no55.join();
        long end = new Date().getTime();
        log.info("Time consumed: " + (end - start));
        assertNull(threadException != null ? threadException.getMessage() : "null", threadException);
    }

    private static class CacheTester implements Runnable { // NOPMD, this is not a JEE app, only a test
        private CaCertificateCache cache = null;
        private String dn;

        public CacheTester(CaCertificateCache cache, String lookfor) {
            this.cache = cache;
            this.dn = lookfor;
        }

        public void run() {
            for (int i = 0; i < 1000; i++) {
                X509Certificate cert = cache.findLatestBySubjectDN(HashID.getFromDNString(dn));
                // The cache tests will not return any CV Certificates because this OCSP cache 
                // only handles X.509 Certificates.
                if (!StringUtils.contains(dn, "CVCTest")) {
                    cert.getSubjectDN(); // just to see that we did receive a cert, will throw NPE if no cert was returned              
                }
            }
        }
    }

    private static class CacheExceptionHandler implements Thread.UncaughtExceptionHandler {
        public void uncaughtException(Thread t, Throwable e) { // NOPMD, this is not a JEE app, only a test
            CaCertificateCacheTest.threadException = e;
        }
    }

}