Java tutorial
/* * 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()); } }