package org.bouncycastle.mail.smime.test; import java.io.ByteArrayOutputStream; import java.io.InputStream; import java.security.KeyPair; import java.security.Security; import java.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collection; import java.util.Iterator; import java.util.List; import javax.mail.Session; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import junit.framework.Test; import junit.framework.TestCase; import junit.framework.TestSuite; import org.bouncycastle.asn1.ASN1EncodableVector; import org.bouncycastle.asn1.cms.AttributeTable; import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute; import org.bouncycastle.asn1.smime.SMIMECapability; import org.bouncycastle.asn1.smime.SMIMECapabilityVector; import org.bouncycastle.cert.X509CertificateHolder; import org.bouncycastle.cert.jcajce.JcaCertStore; import org.bouncycastle.cms.SignerInformation; import org.bouncycastle.cms.SignerInformationStore; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder; import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder; import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter; import org.bouncycastle.cms.jcajce.ZlibCompressor; import org.bouncycastle.cms.jcajce.ZlibExpanderProvider; import org.bouncycastle.jce.provider.BouncyCastleProvider; import org.bouncycastle.mail.smime.SMIMECompressed; import org.bouncycastle.mail.smime.SMIMECompressedGenerator; import org.bouncycastle.mail.smime.SMIMECompressedParser; import org.bouncycastle.mail.smime.SMIMESigned; import org.bouncycastle.mail.smime.SMIMESignedGenerator; import org.bouncycastle.mail.smime.SMIMEUtil; import org.bouncycastle.util.Arrays; import org.bouncycastle.util.Store; public class SMIMECompressedTest extends TestCase { private static final String COMPRESSED_CONTENT_TYPE = "application/pkcs7-mime; name=\"smime.p7z\"; smime-type=compressed-data"; private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter(); private static MimeBodyPart msg; private static String signDN; private static KeyPair signKP; private static X509Certificate signCert; private static String origDN; private static KeyPair origKP; private static X509Certificate origCert; static { try { if (Security.getProvider("BC") == null) { Security.addProvider(new BouncyCastleProvider()); } msg = SMIMETestUtil.makeMimeBodyPart("Hello world!"); signDN = "O=Bouncy Castle, C=AU"; signKP = CMSTestUtil.makeKeyPair(); signCert = CMSTestUtil.makeCertificate(signKP, signDN, signKP, signDN); origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU"; origKP = CMSTestUtil.makeKeyPair(); origCert = CMSTestUtil.makeCertificate(origKP, origDN, signKP, signDN); } catch (Exception e) { throw new RuntimeException("problem setting up signed test class: " + e); } } /* * * INFRASTRUCTURE * */ public SMIMECompressedTest(String name) throws Exception { super(name); } public static void main(String args[]) { junit.textui.TestRunner.run(SMIMECompressedTest.class); } public static Test suite() { return new SMIMETestSetup(new TestSuite(SMIMECompressedTest.class)); } public void testHeaders() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); MimeBodyPart cbp = cgen.generate(msg, new ZlibCompressor()); assertEquals(COMPRESSED_CONTENT_TYPE, cbp.getHeader("Content-Type")[0]); assertEquals("attachment; filename=\"smime.p7z\"", cbp.getHeader("Content-Disposition")[0]); assertEquals("S/MIME Compressed Message", cbp.getHeader("Content-Description")[0]); } public void testBasic() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); ByteArrayOutputStream bOut = new ByteArrayOutputStream(); MimeBodyPart cbp = cgen.generate(msg, new ZlibCompressor()); SMIMECompressed sc = new SMIMECompressed(cbp); msg.writeTo(bOut); assertTrue(Arrays.areEqual(bOut.toByteArray(), sc.getContent(new ZlibExpanderProvider()))); } public void testParser() throws Exception { SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); ByteArrayOutputStream bOut1 = new ByteArrayOutputStream(); ByteArrayOutputStream bOut2 = new ByteArrayOutputStream(); MimeBodyPart cbp = cgen.generate(msg, new ZlibCompressor()); SMIMECompressedParser sc = new SMIMECompressedParser(cbp); msg.writeTo(bOut1); InputStream in = sc.getContent(new ZlibExpanderProvider()).getContentStream(); int ch; while ((ch = in.read()) >= 0) { bOut2.write(ch); } assertTrue(Arrays.areEqual(bOut1.toByteArray(), bOut2.toByteArray())); } /* * test compressing and uncompressing of a multipart-signed message. */ public void testCompressedSHA1WithRSA() throws Exception { List certList = new ArrayList(); certList.add(origCert); certList.add(signCert); Store certs = new JcaCertStore(certList); ASN1EncodableVector signedAttrs = new ASN1EncodableVector(); SMIMECapabilityVector caps = new SMIMECapabilityVector(); caps.addCapability(SMIMECapability.dES_EDE3_CBC); caps.addCapability(SMIMECapability.rC2_CBC, 128); caps.addCapability(SMIMECapability.dES_CBC); signedAttrs.add(new SMIMECapabilitiesAttribute(caps)); SMIMESignedGenerator gen = new SMIMESignedGenerator(); gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA1withRSA", origKP.getPrivate(), origCert)); gen.addCertificates(certs); MimeMultipart smp = gen.generate(msg); MimeMessage bp2 = new MimeMessage((Session)null); bp2.setContent(smp); bp2.saveChanges(); SMIMECompressedGenerator cgen = new SMIMECompressedGenerator(); MimeBodyPart cbp = cgen.generate(bp2, new ZlibCompressor()); SMIMECompressed cm = new SMIMECompressed(cbp); MimeMultipart mm = (MimeMultipart)SMIMEUtil.toMimeBodyPart(cm.getContent(new ZlibExpanderProvider())).getContent(); SMIMESigned s = new SMIMESigned(mm); ByteArrayOutputStream _baos = new ByteArrayOutputStream(); msg.writeTo(_baos); _baos.close(); byte[] _msgBytes = _baos.toByteArray(); _baos = new ByteArrayOutputStream(); s.getContent().writeTo(_baos); _baos.close(); byte[] _resBytes = _baos.toByteArray(); assertEquals(true, Arrays.areEqual(_msgBytes, _resBytes)); certs = s.getCertificates(); SignerInformationStore signers = s.getSignerInfos(); Collection c = signers.getSigners(); Iterator it = c.iterator(); while (it.hasNext()) { SignerInformation signer = (SignerInformation)it.next(); Collection certCollection = certs.getMatches(signer.getSID()); Iterator certIt = certCollection.iterator(); X509CertificateHolder cert = (X509CertificateHolder)certIt.next(); assertEquals(true, signer.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(cert))); } } }