Java tutorial
/* * 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.smime; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.junit.Assert.fail; import java.io.ByteArrayOutputStream; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.io.StringReader; import java.security.KeyStore; import java.security.KeyStore.PrivateKeyEntry; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.PrivateKey; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.util.Enumeration; import java.util.LinkedList; import java.util.List; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import mitm.common.mail.MailSession; import mitm.common.mail.MailUtils; import mitm.common.mail.SkipHeadersOutputStream; import mitm.common.security.SecurityFactory; import mitm.common.security.SecurityFactoryFactory; import mitm.common.security.bouncycastle.InitializeBouncycastle; import mitm.common.security.certificate.CertificateUtils; import mitm.common.security.certificate.X509CertificateInspector; import mitm.common.security.cms.SignerIdentifier; import mitm.common.security.cms.SignerInfo; import mitm.common.tools.OpenSSLWrapper; import mitm.common.util.ClassLoaderUtils; import mitm.common.util.HexUtils; import mitm.test.TestUtils; import org.apache.commons.io.IOUtils; import org.apache.commons.io.LineIterator; import org.apache.log4j.PropertyConfigurator; import org.bouncycastle.asn1.ASN1ObjectIdentifier; import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder; import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator; import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator; import org.junit.BeforeClass; import org.junit.Test; /** * Test for SMIMEBuilderImpl. This test requires openssl to be installed and in the path because * openssl is used for interoperability testing and testing whether the build s/mime messages * are correct. * * @author Martijn Brinkers * */ public class SMIMEBuilderImplTest { private static final File testDir = new File("test/resources/testdata/mail"); private static final File tempDir = new File("test/tmp"); private static SecurityFactory securityFactory; private static KeyStore keyStore; private static X509Certificate rootCertificate; private static X509Certificate encryptionCertificate; private static KeyStore.PasswordProtection passwd; private static PrivateKeyEntry privateKeyEntry; @BeforeClass public static void setUpBeforeClass() throws Exception { // add the root to the system classloader to make sure the CharsetAliasProvider // is found. This is only required for testing. ClassLoaderUtils.addFile(new File(".")); PropertyConfigurator.configure("conf/log4j.properties"); InitializeBouncycastle.initialize(); securityFactory = SecurityFactoryFactory.getSecurityFactory(); keyStore = loadKeyStore(new File("test/resources/testdata/keys/testCertificates.p12"), "test"); rootCertificate = (X509Certificate) keyStore.getCertificate("root"); encryptionCertificate = (X509Certificate) keyStore.getCertificate("ValidCertificate"); passwd = new KeyStore.PasswordProtection("test".toCharArray()); privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry("ValidCertificate", passwd); } private static KeyStore loadKeyStore(File file, String password) throws KeyStoreException { try { KeyStore keyStore = securityFactory.createKeyStore("PKCS12"); // initialize key store keyStore.load(new FileInputStream(file), password.toCharArray()); return keyStore; } catch (NoSuchProviderException e) { throw new KeyStoreException(e); } catch (NoSuchAlgorithmException e) { throw new KeyStoreException(e); } catch (CertificateException e) { throw new KeyStoreException(e); } catch (FileNotFoundException e) { throw new KeyStoreException(e); } catch (IOException e) { throw new KeyStoreException(e); } } private static MimeMessage loadMessage(String filename) throws FileNotFoundException, MessagingException { File mail = new File(testDir, filename); MimeMessage message = MailUtils.loadMessage(mail); return message; } /* * verify the message using openssl */ private static void verifyMessage(File messageFile, X509Certificate rootCertificate, File outputFile) throws IOException { OpenSSLWrapper wrapper = new OpenSSLWrapper(); wrapper.setCertificateAuthorities(rootCertificate); Process p = wrapper.verify(messageFile); InputStream result = p.getInputStream(); FileOutputStream output = new FileOutputStream(outputFile); IOUtils.copy(result, output); output.close(); String error = IOUtils.toString(p.getErrorStream(), "US-ASCII"); assertTrue("Error message: " + error, error.startsWith("Verification successful")); } /* * verify the message using openssl */ private static void decryptMessage(File messageFile, PrivateKey privateKey, File outputFile) throws IOException { OpenSSLWrapper wrapper = new OpenSSLWrapper(); wrapper.setPrivateKey(privateKey); Process p = wrapper.decrypt(messageFile); InputStream result = p.getInputStream(); FileOutputStream output = new FileOutputStream(outputFile); IOUtils.copy(result, output); output.close(); String error = IOUtils.toString(p.getErrorStream(), "US-ASCII"); assertEquals("", error.trim()); } /* * Check for some headers which should exist because they were added to the signed or encrypted blob. */ private static void checkForEmbeddedHeaders(MimeMessage message) throws MessagingException { // the message should contain the signed from, to and subject assertEquals("<test@example.com>", message.getHeader("from", ",")); assertEquals("<test@example.com>", message.getHeader("to", ",")); assertEquals("normal message with attachment", message.getHeader("subject", ",")); } /* * Check for some headers which should exist because they also exist on the source message. */ private static void checkForSourceHeaders(MimeMessage message) throws MessagingException { // the message should contain the signed from, to and subject assertEquals("<test@example.com>", message.getHeader("from", ",")); assertEquals("<test@example.com>", message.getHeader("to", ",")); assertEquals("normal message with attachment", message.getHeader("subject", ",")); assertEquals("1.0", message.getHeader("MIME-Version", ",")); assertEquals("3", message.getHeader("X-Priority", ",")); assertEquals("Normal", message.getHeader("X-MSMail-Priority", ",")); assertEquals("Produced By Microsoft MimeOLE V6.00.2800.1896", message.getHeader("X-MimeOLE", ",")); assertEquals("test 1,test 2", message.getHeader("X-Test", ",")); assertEquals("test 3", message.getHeader("X-Test-a", ",")); assertEquals("test 4", message.getHeader("X-Test-b", ",")); } @Test public void testClearSignExtraCRLFPreamble() throws Exception { MimeMessage message = loadMessage("extra-cr-lf-preamble.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "extra-cr-lf-preamble-signed.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.DETACHED_SIGNATURE_TYPE, SMIMEUtils.dissectSigned((Multipart) newMessage.getContent())[1].getContentType()); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "extra-cr-lf-preamble-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals("Martijn Brinkers <martijn@djigzo.com>", newMessage.getHeader("from", ",")); assertEquals("Martijn Brinkers <martijn@djigzo.com>", newMessage.getHeader("to", ",")); assertEquals("test multiple attachments extra CR/LF preamble", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); } @Test public void testEncryptReceivedHeadersOrder() throws Exception { MimeMessage message = loadMessage("text-message-with-received-headers.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "text-message-with-received-headers-encrypted.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); String[] returnPaths = newMessage.getHeader("Return-Path"); assertEquals(2, returnPaths.length); assertEquals("<return1@example.com>", returnPaths[0]); assertEquals("<return2@example.com>", returnPaths[1]); String[] received = newMessage.getHeader("Received"); assertEquals(7, received.length); assertEquals("from secure.example.com (unknown [192.168.0.6])\r\n\tby example.com (Postfix) " + "with ESMTP id 0183D43843\r\n\tfor <martijn@example.com>; Sat, 22 Aug 2009 18:30:27 +0200 (CEST)", received[0]); assertEquals( "from test (desktop.box [192.168.178.20])\r\n\tby host.example.com (Postfix) with " + "SMTP id 9883623F5\r\n\tfor <martijn@example.com>; Sat, 22 Aug 2009 12:30:24 -0400 (EDT)", received[6]); } /* * Create an S/MIME compressed message. * This is not supported by Openssl, evolution and Outlook. */ @Test public void testCompressDeprecatedHeaders() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.setUseDeprecatedContentTypes(true); builder.compress(); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testCompressDeprecatedHeaders.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.DEPRECATED_COMPRESSED_CONTENT_TYPE, newMessage.getContentType()); assertEquals(SMIMEHeader.Type.COMPRESSED, SMIMEHeader.getSMIMEContentType(newMessage)); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); } @Test public void testEncryptDeprecatedHeaders() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.setUseDeprecatedContentTypes(true); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptDeprecatedHeaders.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.DEPRECATED_ENCRYPTED_CONTENT_TYPE, newMessage.getContentType()); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); File opensslOutputFileSigned = new File(tempDir, "testEncryptDeprecatedHeaders-openssl.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } @Test public void testOpaqueSignDeprecatedHeaders() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.setUseDeprecatedContentTypes(true); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.OPAQUE); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testOpaqueSignDeprecatedHeaders.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.DEPRECATED_ENCAPSULATED_SIGNED_CONTENT_TYPE, newMessage.getContentType()); assertEquals(SMIMEHeader.Type.OPAQUE_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "testOpaqueSignDeprecatedHeaders-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } @Test public void testClearSignDeprecatedHeaders() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.setUseDeprecatedContentTypes(true); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testClearSignDeprecatedHeaders.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); SMIMEUtils.dissectSigned((Multipart) newMessage.getContent()); assertEquals(SMIMEHeader.DEPRECATED_DETACHED_SIGNATURE_TYPE, SMIMEUtils.dissectSigned((Multipart) newMessage.getContent())[1].getContentType()); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "testClearSignDeprecatedHeaders-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } @Test public void testClearSignSimpleTextMessageLF() throws Exception { File mail = new File(testDir, "simple-text-message-LF.eml"); /* * check to make sure the file does not contain CR */ String body = IOUtils.toString(new FileInputStream(mail)); assertFalse(body.contains("\r")); MimeMessage message = MailUtils.loadMessage(mail); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "test-simple-text-message-signed-lf.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-simple-text-message-lf-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } @Test public void testClearSignKeyUsageNotForSigning() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry("KeyUsageNotForSigning", passwd); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "clear-sign-key-usage-not-for-signing.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); } @Test public void testClearSignMissingSMIMEExtKeyUsage() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); PrivateKeyEntry privateKeyEntry = (PrivateKeyEntry) keyStore.getEntry("NoSMIMEExtKeyUsage", passwd); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "clear-sign-missing-smime-ext-key-usage.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); } @Test public void testClearSignUnknownCharset() throws Exception { // unknown-charset.eml contains a non-valid charset. We need to test if signing still works if // we use CharsetAliasProvider which will provide support for this character set MimeMessage message = loadMessage("unknown-charset.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA, (X509Certificate) privateKeyEntry.getCertificate()); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); MailUtils.validateMessage(newMessage); File file = new File(tempDir, "test-signed-unknown-charset.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-signed-unknown-charset-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); } @Test public void testClearSignUnknownCharsetFallback() throws Exception { // unknown-charset.eml contains a non-valid charset. We need to test if signing still works if // we use CharsetAliasProvider which will provide support for this character set MimeMessage message = loadMessage("unknown-charset-xxx.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA, (X509Certificate) privateKeyEntry.getCertificate()); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); MailUtils.validateMessage(newMessage); File file = new File(tempDir, "test-signed-unknown-charset.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-signed-unknown-charset-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); } @Test public void testClearSignUnknownContentType() throws Exception { MimeMessage message = loadMessage("unknown-content-type.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA, (X509Certificate) privateKeyEntry.getCertificate()); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); MailUtils.validateMessage(newMessage); File file = new File(tempDir, "test-signed-unknown-content-type.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-signed-unknown-content-type-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("application/xxx")); } @Test public void testClearSignUnknownContentTypeMultipart() throws Exception { MimeMessage message = loadMessage("unknown-content-type-multipart.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA, (X509Certificate) privateKeyEntry.getCertificate()); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); MailUtils.validateMessage(newMessage); File file = new File(tempDir, "test-signed-unknown-content-type-multipart.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-signed-unknown-content-type-multipart-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); } @Test public void testClearSignNoCertificates() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA, (X509Certificate) privateKeyEntry.getCertificate()); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "test-signed-no-certificates.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); } @Test public void testClearSignAddEncryptionKeyPreference() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA, (X509Certificate) privateKeyEntry.getCertificate()); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "test-signed-encryptionkeypreference-signed.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-signed-encryptionkeypreference-signed-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } @Test public void testClearSignSimpleTextMessage() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "test-simple-text-message-signed.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.DETACHED_SIGNATURE_TYPE, SMIMEUtils.dissectSigned((Multipart) newMessage.getContent())[1].getContentType()); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-simple-text-message-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } @Test public void testOpaqueSignSimpleTextMessage() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.OPAQUE); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "test-simple-text-message-opaque-signed.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.ENCAPSULATED_SIGNED_CONTENT_TYPE, newMessage.getContentType()); assertEquals(SMIMEHeader.Type.OPAQUE_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "test-simple-text-message-opaque-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } /* * Check whether quoted printable soft breaks inside an already signed message are * not changed by Javamail. * * @throws Exception */ @Test public void testEncryptSignedQuotedPrintableSoftBreaks() throws Exception { MimeMessage message = loadMessage("qp-soft-breaks-signed.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptSignedQuotedPrintableSoftBreaks.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFileSigned = new File(tempDir, "testEncryptSignedQuotedPrintableSoftBreaks-openssl-signed.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertTrue(newMessage.isMimeType("multipart/signed")); File opensslOutputFile = new File(tempDir, "testEncryptSignedQuotedPrintableSoftBreaks-openssl.eml"); verifyMessage(opensslOutputFileSigned, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); } /* * Check whether quoted printable soft breaks inside an already signed message are * not changed by Javamail. Now using SMIMEEnvelopedGenerator directly and not * using our own makeContentBodyPart. */ @Test public void testEncryptSignedQuotedPrintableSoftBreaksDirectBC() throws Exception { MimeMessage message = loadMessage("qp-soft-breaks-signed.eml"); SMIMEEnvelopedGenerator envelopedGenerator = new SMIMEEnvelopedGenerator(); JceKeyTransRecipientInfoGenerator infoGenerator = new JceKeyTransRecipientInfoGenerator( encryptionCertificate); envelopedGenerator.addRecipientInfoGenerator(infoGenerator); JceCMSContentEncryptorBuilder encryptorBuilder = new JceCMSContentEncryptorBuilder( new ASN1ObjectIdentifier("1.2.840.113549.3.7"), 0).setProvider("BC"); MimeBodyPart bodyPart = envelopedGenerator.generate(message, encryptorBuilder.build()); MimeMessage newMessage = new MimeMessage(MailSession.getDefaultSession()); newMessage.setContent(bodyPart.getContent(), bodyPart.getContentType()); newMessage.saveChanges(); File file = new File(tempDir, "testEncryptSignedQuotedPrintableSoftBreaksDirectBC.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFileSigned = new File(tempDir, "testEncryptSignedQuotedPrintableSoftBreaksDirectBC-openssl-signed.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertTrue(newMessage.isMimeType("multipart/signed")); File opensslOutputFile = new File(tempDir, "testEncryptSignedQuotedPrintableSoftBreaksDirectBC-openssl.eml"); verifyMessage(opensslOutputFileSigned, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("text/plain")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); } /* * Clear sign a multipart mixed message */ @Test public void testClearSign() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testClearSign.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testClearSign-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * Clear sign a multipart mixed message */ @Test public void testClearSignNoFromProtectedHeader() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "subject", "to"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testClearSignNoFromProtectedHeader.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testClearSignNoFromProtectedHeader-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the subject assertEquals("normal message with attachment", newMessage.getHeader("subject", ",")); assertEquals("<test@example.com>", message.getHeader("to", ",")); assertNull(newMessage.getHeader("from")); } /* * Clear sign a multipart mixed message */ @Test public void testClearSignNoProtectedHeader() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, ""); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testClearSignNoProtectedHeader.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testClearSignNoProtectedHeader-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); assertNull(newMessage.getHeader("subject", ",")); assertEquals("<test@example.com>", message.getHeader("to", ",")); assertNull(newMessage.getHeader("from")); } /* * Clear sign a multipart mixed message */ @Test public void testClearSignDefaultProtectedHeader() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testClearSignDefaultProtectedHeader.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testClearSignDefaultProtectedHeader-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); assertEquals("normal message with attachment", newMessage.getHeader("subject", ",")); assertEquals("<test@example.com>", message.getHeader("to", ",")); assertNull(newMessage.getHeader("from")); } /* * Clear sign a multipart mixed message using multiple signers. */ @Test public void testClearSignMultipleSigners() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); PrivateKeyEntry md5Entry = (PrivateKeyEntry) keyStore.getEntry("md5Hash", passwd); builder.addSigner(md5Entry.getPrivateKey(), (X509Certificate) md5Entry.getCertificate(), SMIMESigningAlgorithm.MD5WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(md5Entry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testClearSignMultipleSigners.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testClearSignMultipleSigners-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * Opaque sign a multipart/mixed message. */ @Test public void testOpaqueSign() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.OPAQUE); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testOpaqueSign.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.OPAQUE_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testOpaqueSign-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * Opaque sign a multipart/mixed message signed by multiple signers. */ @Test public void testOpaqueSignMultipleSigners() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); PrivateKeyEntry md5Entry = (PrivateKeyEntry) keyStore.getEntry("md5Hash", passwd); builder.addSigner(md5Entry.getPrivateKey(), (X509Certificate) md5Entry.getCertificate(), SMIMESigningAlgorithm.MD5WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(md5Entry.getCertificateChain())); builder.sign(SMIMESignMode.OPAQUE); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testOpaqueSignMultipleSigners.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.OPAQUE_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFile = new File(tempDir, "testOpaqueSignMultipleSigners-openssl.eml"); verifyMessage(file, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * Create an S/MIME compressed message. * This is not supported by Openssl, evolution and Outlook. */ @Test public void testCompressed() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.compress(); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testCompressed.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.COMPRESSED_CONTENT_TYPE, newMessage.getContentType()); assertEquals(SMIMEHeader.Type.COMPRESSED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); } /* * Create an S/MIME compressed message. * This is not supported by Openssl, evolution and Outlook. */ @Test public void testSimpleMessageCompress() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.compress(); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "test-simple-text-message-compressed.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.COMPRESSED, SMIMEHeader.getSMIMEContentType(newMessage)); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); } /* * 3-DES Encrypt a multipart/mixed message using the issuerAndSerialNumber RecipientIdentifier. */ @Test public void testEncryptIssuerSerialRecipientId() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptIssuerSerialRecipientId.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileSigned = new File(tempDir, "testEncryptIssuerSerialRecipientId-openssl.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); checkForEmbeddedHeaders(newMessage); } @Test public void testSimpleMessageEncrypt() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "simple-text-message-encrypted.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.ENCRYPTED_CONTENT_TYPE, newMessage.getContentType()); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); File opensslOutputFileSigned = new File(tempDir, "simple-text-message-encrypted-openssl.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); assertTrue(newMessage.isMimeType("text/plain")); assertEquals("test@example.com", newMessage.getHeader("from", ",")); assertEquals("test@example.com", newMessage.getHeader("to", ",")); assertEquals("test simple message", newMessage.getHeader("subject", ",")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); String content = (String) newMessage.getContent(); assertEquals("test", content.trim()); } /* * Encrypt a multipart/mixed message with multiple recipients */ @Test public void testEncryptMultipleRecipients() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); Enumeration<String> aliases = keyStore.aliases(); int i = 15; while (aliases.hasMoreElements() && i != 0) { String alias = aliases.nextElement(); if (keyStore.isKeyEntry(alias)) { X509Certificate certificate = (X509Certificate) keyStore.getCertificate(alias); builder.addRecipient(certificate, SMIMERecipientMode.ISSUER_SERIAL); i--; } } builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptMultipleRecipients.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileSigned = new File(tempDir, "testEncryptMultipleRecipients-openssl.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); checkForEmbeddedHeaders(newMessage); } /* * AES Encrypt a multipart/mixed message using the issuerAndSerialNumber RecipientIdentifier. * * Outlook does not support AES encrypted email. */ @Test public void testEncryptIssuerSerialRecipientIdAES() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.AES128_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptIssuerSerialRecipientIdAES.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileSigned = new File(tempDir, "testEncryptIssuerSerialRecipientIdAES-openssl.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); checkForEmbeddedHeaders(newMessage); } /* * RC2 Encrypt a multipart/mixed message using the issuerAndSerialNumber RecipientIdentifier. */ @Test public void testEncryptIssuerSerialRecipientIdRC2() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.RC2_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptIssuerSerialRecipientIdRC2.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileSigned = new File(tempDir, "testEncryptIssuerSerialRecipientIdRC2-openssl.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); checkForEmbeddedHeaders(newMessage); } /* * Creates a message with subject key identifier as the public key identifier. * * This is not supported by Openssl and evolution (only issuer/serial number recipient id). * It is supported by Outlook. */ @Test public void testEncryptSubjectKeyIdRecipientId() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.SUBJECT_KEY_ID_IF_AVAILABLE); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptSubjectKeyIdRecipientId.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); } /* * Creates a message with subject key identifier and issuer/serial number as the public key identifier. * * This is not supported by Openssl and evolution (only issuer/serial number recipient id). * It is supported by Outlook. */ @Test public void testEncryptBothRecipientId() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.BOTH); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptBothRecipientId.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); } /* * First sign a multipart/mixed message, then encrypt it. */ @Test public void testSignEncrypt() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testSignEncrypt.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileSigned = new File(tempDir, "testSignEncrypt-openssl-signed.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "testSignEncrypt-openssl.eml"); verifyMessage(opensslOutputFileSigned, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * First sign a multipart/mixed message, then encrypt it and again sign it. */ @Test public void testSignEncryptSign() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testSignEncryptSign.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileEncrypted = new File(tempDir, "testSignEncryptSign-openssl-signed-encrypted.eml"); verifyMessage(file, rootCertificate, opensslOutputFileEncrypted); newMessage = MailUtils.loadMessage(opensslOutputFileEncrypted); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFileSigned = new File(tempDir, "testSignEncryptSign-openssl-signed.eml"); decryptMessage(opensslOutputFileEncrypted, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "testSignEncryptSign-openssl.eml"); verifyMessage(opensslOutputFileSigned, rootCertificate, opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * First encrypt a message and then sign it. */ @Test public void testEncryptSign() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptSign.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileEncrypted = new File(tempDir, "testEncryptSign-openssl-encrypted.eml"); verifyMessage(file, rootCertificate, opensslOutputFileEncrypted); newMessage = MailUtils.loadMessage(opensslOutputFileEncrypted); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "testSignEncryptSign-openssl.eml"); decryptMessage(opensslOutputFileEncrypted, privateKeyEntry.getPrivateKey(), opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertTrue(newMessage.isMimeType("multipart/mixed")); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } /* * Encrypt message, then sign and again encrypt. */ @Test public void testEncryptSignEncrypt() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); builder.addRecipient(encryptionCertificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testEncryptSignEncrypt.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); File opensslOutputFileSigned = new File(tempDir, "testEncryptSignEncrypt-openssl-signed.eml"); decryptMessage(file, privateKeyEntry.getPrivateKey(), opensslOutputFileSigned); newMessage = MailUtils.loadMessage(opensslOutputFileSigned); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFileEncrypted = new File(tempDir, "testEncryptSignEncrypt-openssl-encrypted.eml"); verifyMessage(opensslOutputFileSigned, rootCertificate, opensslOutputFileEncrypted); newMessage = MailUtils.loadMessage(opensslOutputFileEncrypted); assertEquals(SMIMEHeader.Type.ENCRYPTED, SMIMEHeader.getSMIMEContentType(newMessage)); File opensslOutputFile = new File(tempDir, "testEncryptSignEncrypt-openssl.eml"); decryptMessage(opensslOutputFileEncrypted, privateKeyEntry.getPrivateKey(), opensslOutputFile); newMessage = MailUtils.loadMessage(opensslOutputFile); assertEquals(SMIMEHeader.Type.NO_SMIME, SMIMEHeader.getSMIMEContentType(newMessage)); assertTrue(newMessage.isMimeType("multipart/mixed")); // the message should contain the signed from, to and subject checkForEmbeddedHeaders(newMessage); } @Test public void testEncryptSignEncryptRepeat() throws Exception { for (int i = 0; i < 200; i++) { testEncryptSignEncrypt(); } } /* * Opaque sign a multipart/mixed message. */ @Test public void testOpaqueSignNullCertificates() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates((X509Certificate) null); builder.sign(SMIMESignMode.OPAQUE); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testOpaqueSignNullCertificates.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.OPAQUE_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); } /* * Opaque sign a multipart/mixed message. */ @Test public void testOpaqueSignEmptyCertificateArray() throws Exception { MimeMessage message = loadMessage("normal-message-with-attach.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), (X509Certificate) privateKeyEntry.getCertificate(), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(new X509Certificate[] {}); builder.addCertificates(new LinkedList<X509Certificate>()); builder.sign(SMIMESignMode.OPAQUE); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testOpaqueSignEmptyCertificateArray.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.OPAQUE_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); checkForSourceHeaders(newMessage); } @Test public void testBuildMultiLayer() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "subject"); /* * ValidCertificate is for test@example.com * multipleEmail is for test@example.com, test2@example.com and test3@example.com * NoEmail contains no email */ builder.addRecipient((X509Certificate) keyStore.getCertificate("NoEmail"), SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.AES128_CBC); builder.addRecipient((X509Certificate) keyStore.getCertificate("ValidCertificate"), SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); builder.addRecipient((X509Certificate) keyStore.getCertificate("multipleEmail"), SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.RC2_CBC); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "testBuildMultiLayer.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); } /* * Test for bug APPLIANCE-2 */ @Test public void testEncryptBase64EncodeBug() throws Exception { MimeMessage message = new MimeMessage(MailSession.getDefaultSession()); message.setSubject("test"); message.setContent("test", "text/plain"); SMIMEBuilder builder = new SMIMEBuilderImpl(message, "to", "subject", "from"); X509Certificate certificate = TestUtils .loadCertificate("test/resources/testdata/certificates/certificate-base64-encode-bug.cer"); builder.addRecipient(certificate, SMIMERecipientMode.ISSUER_SERIAL); builder.encrypt(SMIMEEncryptionAlgorithm.DES_EDE3_CBC); MimeMessage newMessage = builder.buildMessage(); newMessage.saveChanges(); File file = new File(tempDir, "testEncryptBase64EncodeBug.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); ByteArrayOutputStream bos = new ByteArrayOutputStream(); newMessage.writeTo(new SkipHeadersOutputStream(bos)); String blob = new String(bos.toByteArray(), "us-ascii"); // check if all lines are not longer than 76 characters LineIterator it = IOUtils.lineIterator(new StringReader(blob)); while (it.hasNext()) { String next = it.nextLine(); if (next.length() > 76) { fail("Line length exceeds 76: " + next); } } } /* * Clear sign a multipart mixed message with subject key id instead of issuer/serial */ @Test public void testClearSignSubjectKeyIdentifier() throws Exception { MimeMessage message = loadMessage("simple-text-message.eml"); SMIMEBuilder builder = new SMIMEBuilderImpl(message); builder.addSigner(privateKeyEntry.getPrivateKey(), X509CertificateInspector.getSubjectKeyIdentifier( (X509Certificate) privateKeyEntry.getCertificate()), SMIMESigningAlgorithm.SHA1WITHRSA); builder.addCertificates(CertificateUtils.getX509Certificates(privateKeyEntry.getCertificateChain())); builder.sign(SMIMESignMode.CLEAR); MimeMessage newMessage = builder.buildMessage(); File file = new File(tempDir, "sign-subject-key-id.eml"); FileOutputStream output = new FileOutputStream(file); MailUtils.writeMessage(newMessage, output); newMessage = MailUtils.loadMessage(file); assertEquals(SMIMEHeader.Type.CLEAR_SIGNED, SMIMEHeader.getSMIMEContentType(newMessage)); /* * Note: openssl in Ubuntu 10.04 does not support subject key identifier so we cannot validate it */ SMIMESignedInspector inspector = new SMIMESignedInspectorImpl(newMessage, "BC", "BC"); List<SignerInfo> signers = inspector.getSigners(); assertEquals(1, signers.size()); SignerIdentifier signerId = signers.get(0).getSignerId(); assertNull(signerId.getIssuer()); assertNull(signerId.getSerialNumber()); assertEquals("9C82DE52944798337B05036A187DED41632EFBFF", HexUtils.hexEncode(signerId.getSubjectKeyIdentifier())); } }