mitm.application.djigzo.james.mailets.RequestSenderCertificateTest.java Source code

Java tutorial

Introduction

Here is the source code for mitm.application.djigzo.james.mailets.RequestSenderCertificateTest.java

Source

/*
 * Copyright (c) 2010-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.application.djigzo.james.mailets;

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

import java.io.File;
import java.io.FileInputStream;
import java.security.KeyStore;
import java.util.Collection;
import java.util.Date;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;

import mitm.application.djigzo.AutoTransactDelegator;
import mitm.application.djigzo.DjigzoTestUtils;
import mitm.application.djigzo.james.mock.MockMail;
import mitm.application.djigzo.james.mock.MockMailetConfig;
import mitm.application.djigzo.service.SystemServices;
import mitm.application.djigzo.workflow.KeyAndCertificateWorkflow.MissingKey;
import mitm.common.hibernate.annotations.StartTransaction;
import mitm.common.mail.EmailAddressUtils;
import mitm.common.mail.MailSession;
import mitm.common.properties.HierarchicalPropertiesException;
import mitm.common.security.KeyEncoderException;
import mitm.common.security.SecurityFactoryFactory;
import mitm.common.security.ca.CASettings;
import mitm.common.security.ca.CertificateRequest;
import mitm.common.security.ca.CertificateRequestStore;
import mitm.common.security.ca.hibernate.CertificateRequestEntity;
import mitm.test.TestUtils;

import org.apache.commons.lang.ObjectUtils.Null;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.LogManager;
import org.apache.mailet.MailAddress;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;

public class RequestSenderCertificateTest {
    private final static File testBase = new File("test/resources/testdata");

    private final static int INITIAL_KEY_STORE_SIZE = 2;

    private static ExtendedAutoTransactDelegator proxy;

    private final static ExecutorService executorService = Executors.newCachedThreadPool();

    @BeforeClass
    public static void setUpBeforeClass() throws Exception {
        DjigzoTestUtils.initialize();

        LogManager.getLogger(RequestSenderCertificate.class).setLevel(org.apache.log4j.Level.DEBUG);

        proxy = ExtendedAutoTransactDelegator.createProxy(ExtendedAutoTransactDelegator.class);

        proxy.addRootCertificate(TestUtils.loadCertificate(new File(testBase, "certificates/mitm-test-root.cer")));
    }

    public static class ExtendedAutoTransactDelegator extends AutoTransactDelegator {
        @StartTransaction
        public void setupCASettings(String cn, int validity, int keyLength, String signatureAlgorithm,
                String crlDistributionPoint, boolean addCRLDistributionPoint, String certificateRequestHandler)
                throws HierarchicalPropertiesException {
            CASettings settings = SystemServices.getCASettingsProvider().getSettings();

            settings.setDefaultCommonName(cn);
            settings.setValidity(validity);
            settings.setKeyLength(keyLength);
            settings.setSignatureAlgorithm(signatureAlgorithm);
            settings.setCRLDistributionPoint(crlDistributionPoint);
            settings.setAddCRLDistributionPoint(addCRLDistributionPoint);
            settings.setCertificateRequestHandler(certificateRequestHandler);

            // use test CA for the signer
            settings.setSignerThumbprint("D6C5DD8B1D2DEEC273E7311924B20F81F9128D32B21C73E163DF14844F3C"
                    + "9CA73767EBE9A9DF725046DB731D20BC277559A58B8B8E91F02C9BBC5E3D1C6C7A4D");
        }

        @StartTransaction
        public void deleteAllPendingCertificateRequests() {
            CertificateRequestStore store = SystemServices.getCertificateRequestStore();

            List<? extends CertificateRequest> all = store.getAllRequests(null, null);

            for (CertificateRequest request : all) {
                store.deleteRequest(request.getID());
            }

            assertEquals(0, store.getSize());
        }

        @StartTransaction
        public int getCertificateRequestStoreSize() {
            return SystemServices.getCertificateRequestStore().getSize();
        }

        @StartTransaction
        public void addCertificateRequest(String email) throws KeyEncoderException {
            CertificateRequestStore store = SystemServices.getCertificateRequestStore();

            CertificateRequestEntity request = new CertificateRequestEntity("non existing handler");

            request.setSubject(null);
            request.setEmail(email);
            request.setNextUpdate(DateUtils.addDays(new Date(), 1));

            store.addRequest(request);
        }
    }

    @Before
    public void setup() throws Exception {
        proxy.deleteAllUsers();
        proxy.cleanKeyAndCertStore();
        proxy.deleteAllPendingCertificateRequests();

        KeyStore keyStore = SecurityFactoryFactory.getSecurityFactory().createKeyStore("PKCS12");

        keyStore.load(new FileInputStream("test/resources/testdata/keys/testCA.p12"), "test".toCharArray());

        SystemServices.getKeyAndCertificateWorkflow().importKeyStore(keyStore, MissingKey.ADD_CERTIFICATE);

        proxy.setupCASettings("test CN", 365, 1024, "SHA1WithRSAEncryption", null, false, null);

        assertEquals(1, proxy.getRootKeyAndCertStoreSize());
        assertEquals(INITIAL_KEY_STORE_SIZE, proxy.getKeyAndCertStoreSize());
    }

    @Test
    public void testRequestCertificateOverrideCertificateRequestHandler() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        // specify an unknown request handler so we can check the queue
        mailetConfig.setInitParameter("certificateRequestHandler", "unknown");

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress("from@example.com"));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress("to@example.com"));

        mail.setRecipients(recipients);

        mail.setSender(new MailAddress("somethingelse@example.com"));

        mailet.service(mail);

        assertEquals(0, proxy.getCertificateRequestStoreSize());
        assertEquals(INITIAL_KEY_STORE_SIZE, proxy.getKeyAndCertStoreSize());
    }

    @Test
    public void testRequestCertificateSigningCertAvailable() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        String from = "test@example.com";
        String to = "to@example.com";

        KeyStore keyStore = SecurityFactoryFactory.getSecurityFactory().createKeyStore("PKCS12");

        keyStore.load(new FileInputStream("test/resources/testdata/keys/testCertificates.p12"),
                "test".toCharArray());

        SystemServices.getKeyAndCertificateWorkflow().importKeyStore(keyStore, MissingKey.ADD_CERTIFICATE);

        assertEquals(22, proxy.getKeyAndCertStoreSize());

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress(from));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress(to));

        mail.setRecipients(recipients);

        mail.setSender(new MailAddress("somethingelse@example.com"));

        assertFalse(proxy.isUser(from));
        assertFalse(proxy.isUser(to));

        mailet.service(mail);

        assertEquals(22, proxy.getKeyAndCertStoreSize());

        assertFalse(proxy.isUser(to));
        assertFalse(proxy.isUser(from));
    }

    @Test
    public void testRequestCertificatePendingAvailableSkipIfAvailableFalse() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        String from = "from@example.com";
        String to = "to@example.com";

        proxy.addCertificateRequest(from);

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailetConfig.setInitParameter("skipIfAvailable", "false");

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress(from));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress(to));

        mail.setRecipients(recipients);

        mail.setSender(new MailAddress("somethingelse@example.com"));

        assertFalse(proxy.isUser(from));
        assertFalse(proxy.isUser(to));

        mailet.service(mail);

        assertEquals(INITIAL_KEY_STORE_SIZE + 1, proxy.getKeyAndCertStoreSize());

        assertFalse(proxy.isUser(to));
        assertTrue(proxy.isUser(from));
    }

    @Test
    public void testRequestCertificatePendingAvailable() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        String from = "from@example.com";
        String to = "to@example.com";

        proxy.addCertificateRequest(from);

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress(from));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress(to));

        mail.setRecipients(recipients);

        mail.setSender(new MailAddress("somethingelse@example.com"));

        assertFalse(proxy.isUser(from));
        assertFalse(proxy.isUser(to));

        mailet.service(mail);

        assertEquals(INITIAL_KEY_STORE_SIZE, proxy.getKeyAndCertStoreSize());

        assertFalse(proxy.isUser(to));
        assertFalse(proxy.isUser(from));
    }

    @Test
    public void testRequestCertificateNotAddUser() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailetConfig.setInitParameter("addUser", "false");

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        String from = "from@example.com";
        String to = "to@example.com";

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress(from));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress(to));

        mail.setRecipients(recipients);

        mail.setSender(new MailAddress("somethingelse@example.com"));

        assertFalse(proxy.isUser(from));
        assertFalse(proxy.isUser(to));

        mailet.service(mail);

        assertEquals(INITIAL_KEY_STORE_SIZE + 1, proxy.getKeyAndCertStoreSize());

        assertFalse(proxy.isUser(to));
        assertFalse(proxy.isUser(from));
    }

    @Test
    public void testRequestCertificate() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress("from@example.com"));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        String from = "from@example.com";
        String to = "to@example.com";

        recipients.add(new MailAddress(to));

        mail.setRecipients(recipients);

        mail.setSender(new MailAddress("somethingelse@example.com"));

        assertFalse(proxy.isUser(from));
        assertFalse(proxy.isUser(to));

        mailet.service(mail);

        assertEquals(INITIAL_KEY_STORE_SIZE + 1, proxy.getKeyAndCertStoreSize());

        assertFalse(proxy.isUser(to));
        assertTrue(proxy.isUser(from));
    }

    @Test
    public void testRequestCertificateInvalidOriginator() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailet.init(mailetConfig);

        MockMail mail = new MockMail();

        MimeMessage message = new MimeMessage(MailSession.getDefaultSession());

        String to = "to@example.com";

        message.setContent("test", "text/plain");
        message.setFrom(new InternetAddress("123"));

        message.saveChanges();

        mail.setMessage(message);

        Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress(to));

        mail.setRecipients(recipients);

        mail.setSender(null);

        assertFalse(proxy.isUser(EmailAddressUtils.INVALID_EMAIL));
        assertFalse(proxy.isUser(to));

        mailet.service(mail);

        assertEquals(INITIAL_KEY_STORE_SIZE, proxy.getKeyAndCertStoreSize());

        assertFalse(proxy.isUser(to));
        assertFalse(proxy.isUser(EmailAddressUtils.INVALID_EMAIL));
    }

    @Test
    public void testRequestCertificateMultiThreaded() throws Exception {
        MockMailetConfig mailetConfig = new MockMailetConfig();

        final RequestSenderCertificate mailet = new RequestSenderCertificate();

        mailet.init(mailetConfig);

        final MimeMessage message1 = new MimeMessage(MailSession.getDefaultSession());

        message1.setContent("test", "text/plain");
        message1.setFrom(new InternetAddress("from@example.com"));

        final Collection<MailAddress> recipients = new LinkedList<MailAddress>();

        recipients.add(new MailAddress("to@example.com"));

        message1.saveChanges();

        final MimeMessage message2 = new MimeMessage(MailSession.getDefaultSession());

        message2.setContent("test", "text/plain");
        message2.setFrom(new InternetAddress("from2@example.com"));

        Callable<Null> callable = new Callable<Null>() {

            @Override
            public Null call() throws Exception {
                MockMail mail1 = new MockMail();

                mail1.setMessage(message1);

                mail1.setRecipients(recipients);

                mail1.setSender(new MailAddress("sender1@example.com"));

                mailet.service(mail1);

                MockMail mail2 = new MockMail();

                mail2.setMessage(message2);

                mail2.setRecipients(recipients);

                mail2.setSender(new MailAddress("sender2@example.com"));

                mailet.service(mail2);

                return null;
            }
        };

        Collection<Future<?>> futures = new LinkedList<Future<?>>();

        for (int i = 0; i < 20; i++) {
            futures.add(executorService.submit(callable));
        }

        for (Future<?> future : futures) {
            future.get();
        }

        assertEquals(INITIAL_KEY_STORE_SIZE + 2, proxy.getKeyAndCertStoreSize());
    }
}