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

Java tutorial

Introduction

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

Source

/*
 * Copyright (c) 2008-2012, 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.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.cert.X509CRL;
import java.security.cert.X509Certificate;
import java.security.spec.KeySpec;
import java.security.spec.PKCS8EncodedKeySpec;
import java.util.Date;

import mitm.common.security.KeyAndCertificateImpl;
import mitm.common.security.SecurityFactory;
import mitm.common.security.SecurityFactoryFactory;
import mitm.test.TestUtils;

import org.apache.commons.codec.binary.Hex;
import org.apache.commons.io.IOUtils;
import org.apache.log4j.PropertyConfigurator;
import org.bouncycastle.asn1.x509.CRLReason;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.junit.BeforeClass;
import org.junit.Test;

public class GenerateTestCRLs {
    private static SecurityFactory securityFactory;

    private static X509Certificate caCertificate;
    private static PrivateKey caPrivateKey;
    private static X509Certificate rootCertificate;
    private static PrivateKey rootPrivateKey;

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

        securityFactory = SecurityFactoryFactory.getSecurityFactory();

        loadCA();
    }

    private static void loadCA() throws Exception {
        KeyStore caKeyStore = securityFactory.createKeyStore("PKCS12");

        File file = new File("test/resources/testdata/keys/testCA.p12");

        FileInputStream input = new FileInputStream(file);

        caKeyStore.load(input, "test".toCharArray());

        caCertificate = (X509Certificate) caKeyStore.getCertificate("ca");
        caPrivateKey = (PrivateKey) caKeyStore.getKey("ca", null);

        rootCertificate = (X509Certificate) caKeyStore.getCertificate("root");
        rootPrivateKey = (PrivateKey) caKeyStore.getKey("root", null);

        assertNotNull(caCertificate);
        assertNotNull(caPrivateKey);
    }

    private PrivateKey decodePrivateKey(String encoded) throws Exception {
        byte[] rawKey = Hex.decodeHex(encoded.toCharArray());

        KeySpec keySpec = new PKCS8EncodedKeySpec(rawKey);

        KeyFactory keyFactory = securityFactory.createKeyFactory("RSA");

        return keyFactory.generatePrivate(keySpec);
    }

    private X509CRLBuilder createX509CRLBuilder() {
        return new X509CRLBuilderImpl(BouncyCastleProvider.PROVIDER_NAME, BouncyCastleProvider.PROVIDER_NAME);
    }

    @Test
    public void testGenerateCACRL() throws Exception {
        X509CRLBuilder crlGenerator = createX509CRLBuilder();

        Date thisDate = TestUtils.parseDate("30-Nov-2007 11:38:35 GMT");

        Date nextDate = TestUtils.parseDate("30-Nov-2027 11:38:35 GMT");

        crlGenerator.setThisUpdate(thisDate);
        crlGenerator.setNextUpdate(nextDate);
        crlGenerator.setSignatureAlgorithm("SHA256WithRSAEncryption");

        X509Certificate certificate = TestUtils
                .loadCertificate("test/resources/testdata/certificates/" + "valid_certificate_mitm_test_ca.cer");
        assertNotNull(certificate);

        crlGenerator.addCRLEntry(certificate.getSerialNumber(), thisDate, CRLReason.privilegeWithdrawn);

        X509CRL crl = crlGenerator.generateCRL(new KeyAndCertificateImpl(caPrivateKey, caCertificate));

        assertEquals("EMAILADDRESS=ca@example.com, CN=MITM Test CA, L=Amsterdam, ST=NH, C=NL",
                crl.getIssuerX500Principal().toString());
        assertEquals(thisDate, crl.getThisUpdate());
        assertEquals(nextDate, crl.getNextUpdate());
        assertEquals(1, crl.getRevokedCertificates().size());
        assertTrue(crl.isRevoked(certificate));

        File crlFile = new File("test/tmp/test-generate-ca.crl");

        FileOutputStream fos = new FileOutputStream(crlFile);

        IOUtils.write(crl.getEncoded(), fos);

        fos.close();
    }

    @Test
    public void testGenerateCACRLThisUpdateInFarFuture() throws Exception {
        X509CRLBuilder crlGenerator = createX509CRLBuilder();

        Date thisDate = TestUtils.parseDate("30-Nov-2030 11:38:35 GMT");

        Date nextDate = TestUtils.parseDate("30-Nov-2040 11:38:35 GMT");

        crlGenerator.setThisUpdate(thisDate);
        crlGenerator.setNextUpdate(nextDate);
        crlGenerator.setSignatureAlgorithm("SHA256WithRSAEncryption");

        X509Certificate certificate = TestUtils
                .loadCertificate("test/resources/testdata/certificates/" + "valid_certificate_mitm_test_ca.cer");
        assertNotNull(certificate);

        Date revocationDate = TestUtils.parseDate("30-Nov-2006 11:38:35 GMT");

        crlGenerator.addCRLEntry(certificate.getSerialNumber(), revocationDate, CRLReason.keyCompromise);

        X509CRL crl = crlGenerator.generateCRL(new KeyAndCertificateImpl(caPrivateKey, caCertificate));

        assertEquals("EMAILADDRESS=ca@example.com, CN=MITM Test CA, L=Amsterdam, ST=NH, C=NL",
                crl.getIssuerX500Principal().toString());
        assertEquals(thisDate, crl.getThisUpdate());
        assertEquals(nextDate, crl.getNextUpdate());
        assertEquals(1, crl.getRevokedCertificates().size());
        assertTrue(crl.isRevoked(certificate));

        File crlFile = new File("test/tmp/testgeneratecacrlthisupdateinfarfuture.crl");

        FileOutputStream fos = new FileOutputStream(crlFile);

        IOUtils.write(crl.getEncoded(), fos);

        fos.close();
    }

    @Test
    public void testGenerateCACRLSignedByIncorrectKey() throws Exception {
        X509CRLBuilder crlGenerator = createX509CRLBuilder();

        Date thisDate = TestUtils.parseDate("30-Nov-2007 11:38:35 GMT");

        Date nextDate = TestUtils.parseDate("30-Nov-2027 11:38:35 GMT");

        crlGenerator.setThisUpdate(thisDate);
        crlGenerator.setNextUpdate(nextDate);
        crlGenerator.setSignatureAlgorithm("SHA256WithRSAEncryption");

        X509Certificate certificate = TestUtils
                .loadCertificate("test/resources/testdata/certificates/" + "valid_certificate_mitm_test_ca.cer");
        assertNotNull(certificate);

        crlGenerator.addCRLEntry(certificate.getSerialNumber(), thisDate, CRLReason.privilegeWithdrawn);

        String encodedPrivateKey = "30820276020100300d06092a864886f70d0101010500048202603082025c"
                + "02010002818100a9fee3017954c99b248d1486830c71b2e0ea3f9b7a2763"
                + "1bed8a731f5bd7e1edf856bc3fb7c63dedbeb5bb0de474e7792b3aa7e7b2"
                + "274c03a47c7d89b1935eaef172c6395f2322f1ed9e61ae46d716b4b4394c"
                + "1a802db05a2d7c3d1d41a3e8afc65ff8dada7414744f1ee1540e50ee7fb8"
                + "db437b20c5ee33a82b9d575cfbc951020301000102818004f84ab2b45562"
                + "3f82e60cff91bd3f65b765a1ce6dd7d0f1f413e421ba91a92d47e161478b"
                + "9be41b9b43bce03f199bdad304b7fbf21d6bff7f439477fe150ce38c312f"
                + "c015f3c89291aaa42c4c106f623dfd9f76acad2f1c77b590f038ffbb25f9"
                + "14b6f7ead769808ddd0e2d648442620b50518d9b7fb132b2fa1fa3e9d628"
                + "41024100e69ab3765120d0e0ba5dc21bf384b2f553211b4b1902175454c6"
                + "2f1b0f8ad385d78490539308c9fd5145ae36cc2a6d364fdd97d83d9b6623"
                + "a987db239e716055024100bcb77acf1e9829ab5b2c9a5e73d343db857474"
                + "a529ba52ca256655eb7d760e85d3c68eec9500e3db0494c8f77cb8058593"
                + "6e52a9290149367392d74ecdc3510d024100bd15723b7cb024b56ffabad3"
                + "c26c3774f2b1bdb8690c0ee7060feec6088b737f56450b368be4740332e5"
                + "a8c0a3cdd1f8eba9adfd101ee0b43329036584604075024055465b9a27ea"
                + "fe394e33b375a6c4fa4ec1d943b4364cd9883aaa297d05ee48d5b4426ee6"
                + "fcd5b02091cb619c63a10bedb6170e071e5e5464e4889ffe1e007a290240"
                + "7b60d23994a2ec38db909678446ed56d32455bf684141b9ee0aec68b2025"
                + "1d4d94fd2beebf02074559b811ae1130d2e2aa3bec2e9bccb06969104856" + "00c70759";

        PrivateKey privateKey = decodePrivateKey(encodedPrivateKey);

        // sign not by the caPrivateKey but by some other key
        X509CRL crl = crlGenerator.generateCRL(new KeyAndCertificateImpl(privateKey, caCertificate));

        assertEquals("EMAILADDRESS=ca@example.com, CN=MITM Test CA, L=Amsterdam, ST=NH, C=NL",
                crl.getIssuerX500Principal().toString());
        assertEquals(thisDate, crl.getThisUpdate());
        assertEquals(nextDate, crl.getNextUpdate());
        assertEquals(1, crl.getRevokedCertificates().size());
        assertTrue(crl.isRevoked(certificate));

        File crlFile = new File("test/tmp/test-generate-ca-signed-incorrect-key.crl");

        FileOutputStream fos = new FileOutputStream(crlFile);

        IOUtils.write(crl.getEncoded(), fos);

        fos.close();
    }

    @Test
    public void testGenerateCACRLNoNextUpdate() throws Exception {
        X509CRLBuilder crlGenerator = createX509CRLBuilder();

        Date thisDate = TestUtils.parseDate("30-Nov-2007 11:38:35 GMT");

        crlGenerator.setThisUpdate(thisDate);
        crlGenerator.setSignatureAlgorithm("SHA256WithRSAEncryption");

        X509Certificate certificate = TestUtils
                .loadCertificate("test/resources/testdata/certificates/" + "valid_certificate_mitm_test_ca.cer");
        assertNotNull(certificate);

        crlGenerator.addCRLEntry(certificate.getSerialNumber(), thisDate, CRLReason.privilegeWithdrawn);

        X509CRL crl = crlGenerator.generateCRL(new KeyAndCertificateImpl(caPrivateKey, caCertificate));

        assertEquals("EMAILADDRESS=ca@example.com, CN=MITM Test CA, L=Amsterdam, ST=NH, C=NL",
                crl.getIssuerX500Principal().toString());
        assertEquals(thisDate, crl.getThisUpdate());
        assertEquals(null, crl.getNextUpdate());
        assertEquals(1, crl.getRevokedCertificates().size());
        assertTrue(crl.isRevoked(certificate));

        File crlFile = new File("test/tmp/test-generate-ca-no-next-update.crl");

        FileOutputStream fos = new FileOutputStream(crlFile);

        IOUtils.write(crl.getEncoded(), fos);

        fos.close();
    }

    @Test
    public void testGenerateRootEmptyCRL() throws Exception {
        X509CRLBuilder crlGenerator = createX509CRLBuilder();

        Date thisDate = TestUtils.parseDate("30-Nov-2007 11:38:35 GMT");

        Date nextDate = TestUtils.parseDate("30-Nov-2027 11:38:35 GMT");

        crlGenerator.setThisUpdate(thisDate);
        crlGenerator.setNextUpdate(nextDate);
        crlGenerator.setSignatureAlgorithm("SHA256WithRSAEncryption");

        X509CRL crl = crlGenerator.generateCRL(new KeyAndCertificateImpl(rootPrivateKey, rootCertificate));

        assertEquals("EMAILADDRESS=root@example.com, CN=MITM Test Root, L=Amsterdam, ST=NH, C=NL",
                crl.getIssuerX500Principal().toString());
        assertEquals(thisDate, crl.getThisUpdate());
        assertEquals(nextDate, crl.getNextUpdate());
        assertNull(crl.getRevokedCertificates());
        assertFalse(crl.isRevoked(caCertificate));

        File crlFile = new File("test/tmp/test-generate-root-empty.crl");

        FileOutputStream fos = new FileOutputStream(crlFile);

        IOUtils.write(crl.getEncoded(), fos);

        fos.close();
    }

    @Test
    public void testGenerateRootRevokedCRL() throws Exception {
        X509CRLBuilder crlGenerator = createX509CRLBuilder();

        Date thisDate = TestUtils.parseDate("30-Nov-2007 11:38:35 GMT");

        Date nextDate = TestUtils.parseDate("30-Nov-2027 11:38:35 GMT");

        crlGenerator.setThisUpdate(thisDate);
        crlGenerator.setNextUpdate(nextDate);
        crlGenerator.setSignatureAlgorithm("SHA256WithRSAEncryption");

        crlGenerator.addCRLEntry(caCertificate.getSerialNumber(), thisDate, CRLReason.cACompromise);

        X509CRL crl = crlGenerator.generateCRL(new KeyAndCertificateImpl(rootPrivateKey, rootCertificate));

        assertEquals("EMAILADDRESS=root@example.com, CN=MITM Test Root, L=Amsterdam, ST=NH, C=NL",
                crl.getIssuerX500Principal().toString());
        assertEquals(thisDate, crl.getThisUpdate());
        assertEquals(nextDate, crl.getNextUpdate());
        assertEquals(1, crl.getRevokedCertificates().size());
        assertTrue(crl.isRevoked(caCertificate));

        File crlFile = new File("test/tmp/test-generate-root-ca-revoked.crl");

        FileOutputStream fos = new FileOutputStream(crlFile);

        IOUtils.write(crl.getEncoded(), fos);

        fos.close();
    }
}