Add spongy castle sources to libraries folder
This commit is contained in:
@@ -0,0 +1,26 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
public class AllTests
|
||||
{
|
||||
public static void main (String[] args)
|
||||
throws Exception
|
||||
{
|
||||
junit.textui.TestRunner.run (suite());
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
throws Exception
|
||||
{
|
||||
TestSuite suite= new TestSuite("SMIME tests");
|
||||
|
||||
suite.addTest(NewSMIMESignedTest.suite());
|
||||
suite.addTest(SignedMailValidatorTest.suite());
|
||||
suite.addTest(NewSMIMEEnvelopedTest.suite());
|
||||
suite.addTest(SMIMECompressedTest.suite());
|
||||
suite.addTest(SMIMEMiscTest.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import org.bouncycastle.x509.PKIXCertPathReviewer;
|
||||
|
||||
public class DummyCertPathReviewer extends PKIXCertPathReviewer
|
||||
{
|
||||
|
||||
}
|
||||
@@ -0,0 +1,511 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.security.KeyPair;
|
||||
import java.security.MessageDigest;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import java.security.PrivateKey;
|
||||
import java.security.cert.CertificateEncodingException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.Arrays;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.MimeBodyPart;
|
||||
import javax.mail.internet.MimeMessage;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestCase;
|
||||
import junit.framework.TestSuite;
|
||||
import org.bouncycastle.asn1.ASN1ObjectIdentifier;
|
||||
import org.bouncycastle.asn1.x509.SubjectPublicKeyInfo;
|
||||
import org.bouncycastle.cms.CMSAlgorithm;
|
||||
import org.bouncycastle.cms.KeyTransRecipientId;
|
||||
import org.bouncycastle.cms.RecipientId;
|
||||
import org.bouncycastle.cms.RecipientInformation;
|
||||
import org.bouncycastle.cms.RecipientInformationStore;
|
||||
import org.bouncycastle.cms.jcajce.JceCMSContentEncryptorBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientId;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
|
||||
import org.bouncycastle.cms.test.CMSTestUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnveloped;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnvelopedParser;
|
||||
import org.bouncycastle.mail.smime.SMIMEUtil;
|
||||
import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart;
|
||||
import org.bouncycastle.openssl.PEMKeyPair;
|
||||
import org.bouncycastle.openssl.PEMParser;
|
||||
import org.bouncycastle.openssl.jcajce.JcaPEMKeyConverter;
|
||||
import org.bouncycastle.util.encoders.Base64;
|
||||
|
||||
public class NewSMIMEEnvelopedTest
|
||||
extends TestCase
|
||||
{
|
||||
private static final String BC = BouncyCastleProvider.PROVIDER_NAME;
|
||||
|
||||
private static String _signDN;
|
||||
private static KeyPair _signKP;
|
||||
|
||||
private static String _reciDN;
|
||||
private static KeyPair _reciKP;
|
||||
private static X509Certificate _reciCert;
|
||||
|
||||
private static String _reciDN2;
|
||||
private static KeyPair _reciKP2;
|
||||
private static X509Certificate _reciCert2;
|
||||
|
||||
private static boolean _initialised = false;
|
||||
|
||||
private static final byte[] testMessage = Base64.decode(
|
||||
"TUlNRS1WZXJzaW9uOiAxLjANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyANCglib3VuZGFye" +
|
||||
"T0iLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyIg0KQ29udGVudC1MYW5ndWFnZTogZW" +
|
||||
"4NCkNvbnRlbnQtRGVzY3JpcHRpb246IEEgbWFpbCBmb2xsb3dpbmcgdGhlIERJUkVDVCBwcm9qZWN0IHN" +
|
||||
"wZWNpZmljYXRpb25zDQoNCi0tLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyDQpDb250" +
|
||||
"ZW50LVR5cGU6IHRleHQvcGxhaW47IG5hbWU9bnVsbDsgY2hhcnNldD11cy1hc2NpaQ0KQ29udGVudC1Uc" +
|
||||
"mFuc2Zlci1FbmNvZGluZzogN2JpdA0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5lOyBmaWxlbmFtZT" +
|
||||
"1udWxsDQoNCkNpYW8gZnJvbSB2aWVubmENCi0tLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzU" +
|
||||
"wMTMyLS0NCg==");
|
||||
|
||||
private static void init()
|
||||
throws Exception
|
||||
{
|
||||
if (!_initialised)
|
||||
{
|
||||
_initialised = true;
|
||||
|
||||
_signDN = "O=Bouncy Castle, C=AU";
|
||||
_signKP = CMSTestUtil.makeKeyPair();
|
||||
|
||||
_reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
|
||||
_reciKP = CMSTestUtil.makeKeyPair();
|
||||
_reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN);
|
||||
|
||||
_reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU";
|
||||
_reciKP2 = CMSTestUtil.makeKeyPair();
|
||||
_reciCert2 = CMSTestUtil.makeCertificate(_reciKP2, _reciDN2, _signKP, _signDN);
|
||||
}
|
||||
}
|
||||
|
||||
public NewSMIMEEnvelopedTest(
|
||||
String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static void main(
|
||||
String args[])
|
||||
{
|
||||
junit.textui.TestRunner.run(NewSMIMEEnvelopedTest.class);
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
throws Exception
|
||||
{
|
||||
return new SMIMETestSetup(new TestSuite(NewSMIMEEnvelopedTest.class));
|
||||
}
|
||||
|
||||
public void setUp()
|
||||
throws Exception
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
private MimeMessage loadMessage(String name)
|
||||
throws MessagingException, FileNotFoundException
|
||||
{
|
||||
Session session = Session.getDefaultInstance(System.getProperties(), null);
|
||||
|
||||
return new MimeMessage(session, getClass().getResourceAsStream(name));
|
||||
}
|
||||
|
||||
private X509Certificate loadCert(String name)
|
||||
throws Exception
|
||||
{
|
||||
return (X509Certificate)CertificateFactory.getInstance("X.509", BC).generateCertificate(getClass().getResourceAsStream(name));
|
||||
}
|
||||
|
||||
private PrivateKey loadKey(String name)
|
||||
throws Exception
|
||||
{
|
||||
return new JcaPEMKeyConverter().setProvider("BC").getKeyPair((PEMKeyPair)(new PEMParser(new InputStreamReader(getClass().getResourceAsStream(name)))).readObject()).getPrivate();
|
||||
}
|
||||
|
||||
public void testHeaders()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
|
||||
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC));
|
||||
|
||||
//
|
||||
// generate a MimeBodyPart object which encapsulates the content
|
||||
// we want encrypted.
|
||||
//
|
||||
|
||||
MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build());
|
||||
|
||||
assertEquals("application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data", mp.getHeader("Content-Type")[0]);
|
||||
assertEquals("attachment; filename=\"smime.p7m\"", mp.getHeader("Content-Disposition")[0]);
|
||||
assertEquals("S/MIME Encrypted Message", mp.getHeader("Content-Description")[0]);
|
||||
}
|
||||
|
||||
public void testDESEDE3Encrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testParserDESEDE3Encrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC;
|
||||
|
||||
verifyParserAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testIDEAEncrypted()
|
||||
throws Exception
|
||||
{
|
||||
if (isPresent("IDEA"))
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.IDEA_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isPresent(String algorithm)
|
||||
throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
Cipher.getInstance(algorithm, BC);
|
||||
|
||||
return true;
|
||||
}
|
||||
catch (NoSuchAlgorithmException e)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public void testRC2Encrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.RC2_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testCASTEncrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.CAST5_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testAES128Encrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.AES128_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testAES192Encrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.AES192_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testAES256Encrypted()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
String algorithm = SMIMEEnvelopedGenerator.AES256_CBC;
|
||||
|
||||
verifyAlgorithm(algorithm, msg);
|
||||
}
|
||||
|
||||
public void testSubKeyId()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
|
||||
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
//
|
||||
// create a subject key id - this has to be done the same way as
|
||||
// it is done in the certificate associated with the private key
|
||||
//
|
||||
MessageDigest dig = MessageDigest.getInstance("SHA1", BC);
|
||||
dig.update(SubjectPublicKeyInfo.getInstance(_reciCert.getPublicKey().getEncoded()).getPublicKeyData().getBytes());
|
||||
|
||||
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(dig.digest(), _reciCert.getPublicKey()).setProvider(BC));
|
||||
|
||||
//
|
||||
// generate a MimeBodyPart object which encapsulates the content
|
||||
// we want encrypted.
|
||||
//
|
||||
|
||||
MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.DES_EDE3_CBC).setProvider(BC).build());
|
||||
|
||||
SMIMEEnveloped m = new SMIMEEnveloped(mp);
|
||||
|
||||
dig.update(SubjectPublicKeyInfo.getInstance(_reciCert.getPublicKey().getEncoded()).getPublicKeyData().getBytes());
|
||||
|
||||
RecipientId recId = new KeyTransRecipientId(dig.digest());
|
||||
|
||||
RecipientInformationStore recipients = m.getRecipientInfos();
|
||||
RecipientInformation recipient = recipients.get(recId);
|
||||
|
||||
MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)));
|
||||
|
||||
verifyMessageBytes(msg, res);
|
||||
}
|
||||
|
||||
public void testDotNetEncMailMatch()
|
||||
throws Exception
|
||||
{
|
||||
MimeMessage message = loadMessage("dotnet_encrypted_mail.eml");
|
||||
|
||||
SMIMEEnveloped env = new SMIMEEnveloped(message);
|
||||
|
||||
RecipientInformationStore store = env.getRecipientInfos();
|
||||
|
||||
assertNotNull(store.get(new JceKeyTransRecipientId(loadCert("dotnet_enc_cert.pem"))));
|
||||
}
|
||||
|
||||
public void testAES128()
|
||||
throws Exception
|
||||
{
|
||||
MimeMessage message = loadMessage("test128.message");
|
||||
|
||||
SMIMEEnveloped env = new SMIMEEnveloped(message);
|
||||
|
||||
RecipientInformationStore store = env.getRecipientInfos();
|
||||
|
||||
RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem")));
|
||||
|
||||
assertNotNull(recipInfo);
|
||||
|
||||
byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem")));
|
||||
|
||||
assertTrue(org.bouncycastle.util.Arrays.areEqual(testMessage, content));
|
||||
}
|
||||
|
||||
public void testAES192()
|
||||
throws Exception
|
||||
{
|
||||
MimeMessage message = loadMessage("test192.message");
|
||||
|
||||
SMIMEEnveloped env = new SMIMEEnveloped(message);
|
||||
|
||||
RecipientInformationStore store = env.getRecipientInfos();
|
||||
|
||||
RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem")));
|
||||
|
||||
assertNotNull(recipInfo);
|
||||
|
||||
byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem")));
|
||||
|
||||
assertTrue(org.bouncycastle.util.Arrays.areEqual(testMessage, content));
|
||||
}
|
||||
|
||||
public void testAES256()
|
||||
throws Exception
|
||||
{
|
||||
MimeMessage message = loadMessage("test256.message");
|
||||
|
||||
SMIMEEnveloped env = new SMIMEEnveloped(message);
|
||||
|
||||
RecipientInformationStore store = env.getRecipientInfos();
|
||||
|
||||
RecipientInformation recipInfo = store.get(new JceKeyTransRecipientId(loadCert("cert.pem")));
|
||||
|
||||
assertNotNull(recipInfo);
|
||||
|
||||
byte[] content = recipInfo.getContent(new JceKeyTransEnvelopedRecipient(loadKey("key.pem")));
|
||||
|
||||
assertTrue(org.bouncycastle.util.Arrays.areEqual(testMessage, content));
|
||||
}
|
||||
|
||||
public void testCapEncrypt()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
|
||||
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
//
|
||||
// create a subject key id - this has to be done the same way as
|
||||
// it is done in the certificate associated with the private key
|
||||
//
|
||||
MessageDigest dig = MessageDigest.getInstance("SHA1", BC);
|
||||
|
||||
dig.update(_reciCert.getPublicKey().getEncoded());
|
||||
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(dig.digest(), _reciCert.getPublicKey()).setProvider(BC));
|
||||
|
||||
//
|
||||
// generate a MimeBodyPart object which encapsulates the content
|
||||
// we want encrypted.
|
||||
//
|
||||
MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider(BC).build());
|
||||
|
||||
SMIMEEnveloped m = new SMIMEEnveloped(mp);
|
||||
|
||||
dig.update(_reciCert.getPublicKey().getEncoded());
|
||||
|
||||
RecipientId recId = new KeyTransRecipientId(dig.digest());
|
||||
|
||||
RecipientInformationStore recipients = m.getRecipientInfos();
|
||||
RecipientInformation recipient = recipients.get(recId);
|
||||
|
||||
MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)));
|
||||
|
||||
verifyMessageBytes(msg, res);
|
||||
}
|
||||
|
||||
public void testTwoRecipients()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart _msg = SMIMETestUtil.makeMimeBodyPart("WallaWallaWashington");
|
||||
|
||||
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC));
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert2).setProvider(BC));
|
||||
|
||||
//
|
||||
// generate a MimeBodyPart object which encapsulates the content
|
||||
// we want encrypted.
|
||||
//
|
||||
MimeBodyPart mp = gen.generate(_msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.RC2_CBC, 40).setProvider(BC).build());
|
||||
|
||||
SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp);
|
||||
|
||||
RecipientId recId = getRecipientId(_reciCert2);
|
||||
|
||||
RecipientInformationStore recipients = m.getRecipientInfos();
|
||||
RecipientInformation recipient = recipients.get(recId);
|
||||
|
||||
FileBackedMimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP2.getPrivate()).setProvider(BC)));
|
||||
|
||||
verifyMessageBytes(_msg, res);
|
||||
|
||||
m = new SMIMEEnvelopedParser(mp);
|
||||
|
||||
res.dispose();
|
||||
|
||||
recId = getRecipientId(_reciCert);
|
||||
|
||||
recipients = m.getRecipientInfos();
|
||||
recipient = recipients.get(recId);
|
||||
|
||||
res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)));
|
||||
|
||||
verifyMessageBytes(_msg, res);
|
||||
|
||||
res.dispose();
|
||||
}
|
||||
|
||||
private void verifyAlgorithm(
|
||||
String algorithmOid,
|
||||
MimeBodyPart msg)
|
||||
throws Exception
|
||||
{
|
||||
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC));
|
||||
|
||||
//
|
||||
// generate a MimeBodyPart object which encapsulates the content
|
||||
// we want encrypted.
|
||||
//
|
||||
|
||||
MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(algorithmOid)).setProvider(BC).build());
|
||||
SMIMEEnveloped m = new SMIMEEnveloped(mp);
|
||||
RecipientId recId = getRecipientId(_reciCert);
|
||||
|
||||
RecipientInformationStore recipients = m.getRecipientInfos();
|
||||
RecipientInformation recipient = recipients.get(recId);
|
||||
|
||||
MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)));
|
||||
|
||||
verifyMessageBytes(msg, res);
|
||||
}
|
||||
|
||||
private void verifyParserAlgorithm(
|
||||
String algorithmOid,
|
||||
MimeBodyPart msg)
|
||||
throws Exception
|
||||
{
|
||||
SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
gen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(_reciCert).setProvider(BC));
|
||||
|
||||
//
|
||||
// generate a MimeBodyPart object which encapsulates the content
|
||||
// we want encrypted.
|
||||
//
|
||||
|
||||
MimeBodyPart mp = gen.generate(msg, new JceCMSContentEncryptorBuilder(new ASN1ObjectIdentifier(algorithmOid)).setProvider(BC).build());
|
||||
SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp);
|
||||
RecipientId recId = getRecipientId(_reciCert);
|
||||
|
||||
RecipientInformationStore recipients = m.getRecipientInfos();
|
||||
RecipientInformation recipient = recipients.get(recId);
|
||||
|
||||
MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient.getContent(new JceKeyTransEnvelopedRecipient(_reciKP.getPrivate()).setProvider(BC)));
|
||||
|
||||
verifyMessageBytes(msg, res);
|
||||
}
|
||||
|
||||
private RecipientId getRecipientId(
|
||||
X509Certificate cert)
|
||||
throws IOException, CertificateEncodingException
|
||||
{
|
||||
RecipientId recId = new JceKeyTransRecipientId(cert);
|
||||
|
||||
return recId;
|
||||
}
|
||||
|
||||
|
||||
private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b)
|
||||
throws IOException, MessagingException
|
||||
{
|
||||
ByteArrayOutputStream _baos = new ByteArrayOutputStream();
|
||||
a.writeTo(_baos);
|
||||
_baos.close();
|
||||
byte[] _msgBytes = _baos.toByteArray();
|
||||
_baos = new ByteArrayOutputStream();
|
||||
b.writeTo(_baos);
|
||||
_baos.close();
|
||||
byte[] _resBytes = _baos.toByteArray();
|
||||
|
||||
assertEquals(true, Arrays.equals(_msgBytes, _resBytes));
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,228 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyPair;
|
||||
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.cms.test.CMSTestUtil;
|
||||
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();
|
||||
|
||||
boolean DEBUG = true;
|
||||
|
||||
MimeBodyPart msg;
|
||||
|
||||
String signDN;
|
||||
KeyPair signKP;
|
||||
X509Certificate signCert;
|
||||
|
||||
String origDN;
|
||||
KeyPair origKP;
|
||||
X509Certificate origCert;
|
||||
|
||||
String reciDN;
|
||||
KeyPair reciKP;
|
||||
X509Certificate reciCert;
|
||||
|
||||
KeyPair dsaSignKP;
|
||||
X509Certificate dsaSignCert;
|
||||
|
||||
KeyPair dsaOrigKP;
|
||||
X509Certificate dsaOrigCert;
|
||||
|
||||
/*
|
||||
*
|
||||
* INFRASTRUCTURE
|
||||
*
|
||||
*/
|
||||
|
||||
public SMIMECompressedTest(
|
||||
String name)
|
||||
throws Exception
|
||||
{
|
||||
super(name);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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)));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,367 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
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.CMSAlgorithm;
|
||||
import org.bouncycastle.cms.CMSException;
|
||||
import org.bouncycastle.cms.RecipientInformation;
|
||||
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.JceCMSContentEncryptorBuilder;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient;
|
||||
import org.bouncycastle.cms.jcajce.JceKeyTransRecipientInfoGenerator;
|
||||
import org.bouncycastle.cms.jcajce.ZlibCompressor;
|
||||
import org.bouncycastle.cms.test.CMSTestUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.mail.smime.SMIMECompressedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnveloped;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMESigned;
|
||||
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMESignedParser;
|
||||
import org.bouncycastle.mail.smime.SMIMEUtil;
|
||||
import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart;
|
||||
import org.bouncycastle.operator.jcajce.JcaDigestCalculatorProviderBuilder;
|
||||
import org.bouncycastle.util.Store;
|
||||
|
||||
public class SMIMEMiscTest
|
||||
extends TestCase
|
||||
{
|
||||
static MimeBodyPart msg;
|
||||
|
||||
static String signDN;
|
||||
static KeyPair signKP;
|
||||
static X509Certificate signCert;
|
||||
|
||||
static String origDN;
|
||||
static KeyPair origKP;
|
||||
static X509Certificate origCert;
|
||||
|
||||
static String reciDN;
|
||||
static KeyPair reciKP;
|
||||
static X509Certificate reciCert;
|
||||
|
||||
private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter();
|
||||
|
||||
KeyPair dsaSignKP;
|
||||
X509Certificate dsaSignCert;
|
||||
|
||||
KeyPair dsaOrigKP;
|
||||
X509Certificate dsaOrigCert;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n");
|
||||
|
||||
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 SMIMEMiscTest(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static void main(String args[])
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
junit.textui.TestRunner.run(SMIMEMiscTest.class);
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
{
|
||||
return new SMIMETestSetup(new TestSuite(SMIMEMiscTest.class));
|
||||
}
|
||||
|
||||
public void testSHA256WithRSAParserEncryptedWithAES()
|
||||
throws Exception
|
||||
{
|
||||
List certList = new ArrayList();
|
||||
|
||||
certList.add(origCert);
|
||||
certList.add(signCert);
|
||||
|
||||
Store certs = new JcaCertStore(certList);
|
||||
|
||||
SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
encGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(origCert).setProvider("BC"));
|
||||
|
||||
MimeBodyPart mp = encGen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build());
|
||||
ASN1EncodableVector signedAttrs = generateSignedAttributes();
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA256withRSA", origKP.getPrivate(), origCert));
|
||||
gen.addCertificates(certs);
|
||||
|
||||
MimeMultipart smm = gen.generate(mp);
|
||||
File tmpFile = File.createTempFile("bcTest", ".mime");
|
||||
|
||||
MimeMessage msg = createMimeMessage(tmpFile, smm);
|
||||
|
||||
SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), (MimeMultipart)msg.getContent());
|
||||
|
||||
certs = s.getCertificates();
|
||||
|
||||
verifyMessageBytes(mp, s.getContent());
|
||||
|
||||
verifySigners(certs, s.getSignerInfos());
|
||||
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
public void testSHA256WithRSACompressed()
|
||||
throws Exception
|
||||
{
|
||||
List certList = new ArrayList();
|
||||
|
||||
certList.add(origCert);
|
||||
certList.add(signCert);
|
||||
|
||||
Store certs = new JcaCertStore(certList);
|
||||
|
||||
SMIMECompressedGenerator cGen = new SMIMECompressedGenerator();
|
||||
|
||||
MimeBodyPart mp = cGen.generate(msg, new ZlibCompressor());
|
||||
|
||||
ASN1EncodableVector signedAttrs = generateSignedAttributes();
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA256withRSA", origKP.getPrivate(), origCert));
|
||||
gen.addCertificates(certs);
|
||||
|
||||
MimeMultipart smm = gen.generate(mp);
|
||||
File tmpFile = File.createTempFile("bcTest", ".mime");
|
||||
|
||||
MimeMessage msg = createMimeMessage(tmpFile, smm);
|
||||
|
||||
SMIMESigned s = new SMIMESigned((MimeMultipart)msg.getContent());
|
||||
|
||||
certs = s.getCertificates();
|
||||
|
||||
verifyMessageBytes(mp, s.getContent());
|
||||
|
||||
verifySigners(certs, s.getSignerInfos());
|
||||
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
public void testQuotePrintableSigPreservation()
|
||||
throws Exception
|
||||
{
|
||||
MimeMessage msg = new MimeMessage((Session)null, getClass().getResourceAsStream("qp-soft-break.eml"));
|
||||
|
||||
SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
encGen.addRecipientInfoGenerator(new JceKeyTransRecipientInfoGenerator(origCert).setProvider("BC"));
|
||||
|
||||
MimeBodyPart mp = encGen.generate(msg, new JceCMSContentEncryptorBuilder(CMSAlgorithm.AES128_CBC).setProvider("BC").build());
|
||||
|
||||
SMIMEEnveloped env = new SMIMEEnveloped(mp);
|
||||
RecipientInformation ri = (RecipientInformation)env.getRecipientInfos().getRecipients().iterator().next();
|
||||
MimeBodyPart mm = SMIMEUtil.toMimeBodyPart(ri.getContentStream(new JceKeyTransEnvelopedRecipient(origKP.getPrivate()).setProvider("BC")));
|
||||
SMIMESigned s = new SMIMESigned((MimeMultipart)mm.getContent());
|
||||
Collection c = s.getSignerInfos().getSigners();
|
||||
Iterator it = c.iterator();
|
||||
Store certs = s.getCertificates();
|
||||
|
||||
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)));
|
||||
}
|
||||
|
||||
((FileBackedMimeBodyPart)mm).dispose();
|
||||
}
|
||||
|
||||
public void testSHA256WithRSAParserCompressed()
|
||||
throws Exception
|
||||
{
|
||||
List certList = new ArrayList();
|
||||
|
||||
certList.add(origCert);
|
||||
certList.add(signCert);
|
||||
|
||||
Store certs = new JcaCertStore(certList);
|
||||
|
||||
SMIMECompressedGenerator cGen = new SMIMECompressedGenerator();
|
||||
|
||||
MimeBodyPart mp = cGen.generate(msg, new ZlibCompressor());
|
||||
|
||||
ASN1EncodableVector signedAttrs = generateSignedAttributes();
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").setSignedAttributeGenerator(new AttributeTable(signedAttrs)).build("SHA256withRSA", origKP.getPrivate(), origCert));
|
||||
gen.addCertificates(certs);
|
||||
|
||||
MimeMultipart smm = gen.generate(mp);
|
||||
File tmpFile = File.createTempFile("bcTest", ".mime");
|
||||
|
||||
MimeMessage msg = createMimeMessage(tmpFile, smm);
|
||||
|
||||
SMIMESignedParser s = new SMIMESignedParser(new JcaDigestCalculatorProviderBuilder().setProvider("BC").build(), (MimeMultipart)msg.getContent());
|
||||
|
||||
certs = s.getCertificates();
|
||||
|
||||
verifyMessageBytes(mp, s.getContent());
|
||||
|
||||
verifySigners(certs, s.getSignerInfos());
|
||||
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
public void testBrokenEnvelope()
|
||||
throws Exception
|
||||
{
|
||||
Session session = Session.getDefaultInstance(System.getProperties(), null);
|
||||
MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("brokenEnv.message"));
|
||||
|
||||
try
|
||||
{
|
||||
new SMIMEEnveloped(msg);
|
||||
}
|
||||
catch (CMSException e)
|
||||
{
|
||||
if (!e.getMessage().equals("Malformed content."))
|
||||
{
|
||||
fail("wrong exception on bogus envelope");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifySigners(Store certs, SignerInformationStore signers)
|
||||
throws Exception
|
||||
{
|
||||
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)));
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b)
|
||||
throws Exception
|
||||
{
|
||||
ByteArrayOutputStream bOut1 = new ByteArrayOutputStream();
|
||||
|
||||
a.writeTo(bOut1);
|
||||
bOut1.close();
|
||||
|
||||
ByteArrayOutputStream bOut2 = new ByteArrayOutputStream();
|
||||
|
||||
b.writeTo(bOut2);
|
||||
bOut2.close();
|
||||
|
||||
assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mime message representing the multipart. We need to do
|
||||
* this as otherwise no raw content stream for the message will exist.
|
||||
*/
|
||||
private MimeMessage createMimeMessage(File tmpFile, MimeMultipart smm)
|
||||
throws Exception
|
||||
{
|
||||
FileOutputStream fOut = new FileOutputStream(tmpFile);
|
||||
Properties props = System.getProperties();
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>");
|
||||
Address toUser = new InternetAddress("example@bouncycastle.org");
|
||||
|
||||
MimeMessage body = new MimeMessage(session);
|
||||
body.setFrom(fromUser);
|
||||
body.setRecipient(Message.RecipientType.TO, toUser);
|
||||
body.setSubject("example signed message");
|
||||
body.setContent(smm, smm.getContentType());
|
||||
body.saveChanges();
|
||||
|
||||
body.writeTo(fOut);
|
||||
|
||||
fOut.close();
|
||||
|
||||
return new MimeMessage(session, new FileInputStream(tmpFile));
|
||||
}
|
||||
|
||||
private ASN1EncodableVector generateSignedAttributes()
|
||||
{
|
||||
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));
|
||||
|
||||
return signedAttrs;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
// Copyright (c) 2005 The Legion Of The Bouncy Castle (http://www.bouncycastle.org)
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import junit.extensions.TestSetup;
|
||||
import junit.framework.Test;
|
||||
|
||||
import javax.activation.CommandMap;
|
||||
import javax.activation.MailcapCommandMap;
|
||||
import java.security.Security;
|
||||
|
||||
class SMIMETestSetup extends TestSetup
|
||||
{
|
||||
private CommandMap originalMap = null;
|
||||
|
||||
public SMIMETestSetup(Test test)
|
||||
{
|
||||
super(test);
|
||||
}
|
||||
|
||||
protected void setUp()
|
||||
{
|
||||
Security
|
||||
.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
|
||||
MailcapCommandMap _mailcap = (MailcapCommandMap)CommandMap
|
||||
.getDefaultCommandMap();
|
||||
|
||||
_mailcap
|
||||
.addMailcap("application/pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_signature");
|
||||
_mailcap
|
||||
.addMailcap("application/pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.pkcs7_mime");
|
||||
_mailcap
|
||||
.addMailcap("application/x-pkcs7-signature;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_signature");
|
||||
_mailcap
|
||||
.addMailcap("application/x-pkcs7-mime;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.x_pkcs7_mime");
|
||||
_mailcap
|
||||
.addMailcap("multipart/signed;; x-java-content-handler=org.bouncycastle.mail.smime.handlers.multipart_signed");
|
||||
|
||||
originalMap = CommandMap.getDefaultCommandMap();
|
||||
CommandMap.setDefaultCommandMap(_mailcap);
|
||||
}
|
||||
|
||||
protected void tearDown()
|
||||
{
|
||||
CommandMap.setDefaultCommandMap(originalMap);
|
||||
originalMap = null;
|
||||
Security.removeProvider("BC");
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
|
||||
import javax.mail.MessagingException;
|
||||
import javax.mail.internet.MimeBodyPart;
|
||||
import javax.mail.internet.MimeMultipart;
|
||||
import java.security.Security;
|
||||
|
||||
public class SMIMETestUtil
|
||||
{
|
||||
public static final boolean DEBUG = true;
|
||||
|
||||
static
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
}
|
||||
|
||||
/*
|
||||
*
|
||||
* MAIL
|
||||
*
|
||||
*/
|
||||
|
||||
public static MimeBodyPart makeMimeBodyPart(String msg)
|
||||
throws MessagingException
|
||||
{
|
||||
|
||||
MimeBodyPart _mbp = new MimeBodyPart();
|
||||
_mbp.setText(msg);
|
||||
return _mbp;
|
||||
}
|
||||
|
||||
public static MimeBodyPart makeMimeBodyPart(MimeMultipart mm)
|
||||
throws MessagingException
|
||||
{
|
||||
|
||||
MimeBodyPart _mbp = new MimeBodyPart();
|
||||
_mbp.setContent(mm, mm.getContentType());
|
||||
return _mbp;
|
||||
}
|
||||
|
||||
public static MimeMultipart makeMimeMultipart(String msg1, String msg2)
|
||||
throws MessagingException
|
||||
{
|
||||
|
||||
MimeMultipart _mm = new MimeMultipart();
|
||||
_mm.addBodyPart(makeMimeBodyPart(msg1));
|
||||
_mm.addBodyPart(makeMimeBodyPart(msg2));
|
||||
|
||||
return _mm;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,474 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
import java.security.cert.CertPath;
|
||||
import java.security.cert.CertStore;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.security.cert.CollectionCertStoreParameters;
|
||||
import java.security.cert.PKIXParameters;
|
||||
import java.security.cert.TrustAnchor;
|
||||
import java.security.cert.X509CRL;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Properties;
|
||||
import java.util.Set;
|
||||
import java.util.TimeZone;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
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.ASN1Encodable;
|
||||
import org.bouncycastle.asn1.ASN1Encoding;
|
||||
import org.bouncycastle.asn1.x509.X509Extension;
|
||||
import org.bouncycastle.cert.jcajce.JcaCertStore;
|
||||
import org.bouncycastle.cms.SignerInformation;
|
||||
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
|
||||
import org.bouncycastle.cms.test.CMSTestUtil;
|
||||
import org.bouncycastle.i18n.ErrorBundle;
|
||||
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
|
||||
import org.bouncycastle.mail.smime.validator.SignedMailValidator;
|
||||
import org.bouncycastle.util.Store;
|
||||
import org.bouncycastle.x509.PKIXCertPathReviewer;
|
||||
import org.bouncycastle.x509.extension.X509ExtensionUtil;
|
||||
|
||||
public class SignedMailValidatorTest extends TestCase
|
||||
{
|
||||
static String TEST_TRUST_ACHOR = "validator.root.crt";
|
||||
|
||||
public void testShortKey() throws Exception
|
||||
{
|
||||
String message = "validator.shortKey.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isValidSignature());
|
||||
assertContainsMessage(result.getNotifications(),
|
||||
"SignedMailValidator.shortSigningKey",
|
||||
"Warning: The signing key is only 512 bits long.");
|
||||
}
|
||||
|
||||
public void testKeyUsage() throws Exception
|
||||
{
|
||||
String message = "validator.keyUsage.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertTrue(result.getCertPathReview().isValidCertPath());
|
||||
assertFalse(result.isValidSignature());
|
||||
|
||||
assertContainsMessage(
|
||||
result.getErrors(),
|
||||
"SignedMailValidator.signingNotPermitted",
|
||||
"The key usage extension of signer certificate does not permit using the key for email signatures.");
|
||||
}
|
||||
|
||||
public void testExtKeyUsage() throws Exception
|
||||
{
|
||||
String message = "validator.extKeyUsage.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertTrue(result.getCertPathReview().isValidCertPath());
|
||||
assertFalse(result.isValidSignature());
|
||||
|
||||
assertContainsMessage(
|
||||
result.getErrors(),
|
||||
"SignedMailValidator.extKeyUsageNotPermitted",
|
||||
"The extended key usage extension of the signer certificate does not permit using the key for email signatures.");
|
||||
}
|
||||
|
||||
public void testNoEmail() throws Exception
|
||||
{
|
||||
String message = "validator.noEmail.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertTrue(result.getCertPathReview().isValidCertPath());
|
||||
assertFalse(result.isValidSignature());
|
||||
|
||||
assertContainsMessage(
|
||||
result.getErrors(),
|
||||
"SignedMailValidator.noEmailInCert",
|
||||
"The signer certificate is not usable for email signatures: it contains no email address.");
|
||||
}
|
||||
|
||||
public void testNotYetValid() throws Exception
|
||||
{
|
||||
String message = "validator.notYetValid.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertFalse(result.isValidSignature());
|
||||
assertContainsMessage(result.getErrors(),
|
||||
"SignedMailValidator.certNotYetValid",
|
||||
"The message was signed at Aug 28, 2006 3:04:01 PM GMT. But the certificate is not valid before Dec 28, 2006 2:19:31 PM GMT.");
|
||||
|
||||
PKIXCertPathReviewer review = result.getCertPathReview();
|
||||
assertFalse(review.isValidCertPath());
|
||||
assertContainsMessage(
|
||||
review.getErrors(0),
|
||||
"CertPathReviewer.certificateNotYetValid",
|
||||
"Could not validate the certificate. Certificate is not valid until Dec 28, 2006 2:19:31 PM GMT.");
|
||||
}
|
||||
|
||||
public void testExpired() throws Exception
|
||||
{
|
||||
String message = "validator.expired.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertFalse(result.isValidSignature());
|
||||
assertContainsMessage(result.getErrors(),
|
||||
"SignedMailValidator.certExpired",
|
||||
"The message was signed at Sep 1, 2006 9:08:35 AM GMT. But the certificate expired at Sep 1, 2006 8:39:20 AM GMT.");
|
||||
|
||||
PKIXCertPathReviewer review = result.getCertPathReview();
|
||||
assertFalse(review.isValidCertPath());
|
||||
assertContainsMessage(
|
||||
review.getErrors(0),
|
||||
"CertPathReviewer.certificateExpired",
|
||||
"Could not validate the certificate. Certificate expired on Sep 1, 2006 8:39:20 AM GMT.");
|
||||
}
|
||||
|
||||
public void testRevoked() throws Exception
|
||||
{
|
||||
String message = "validator.revoked.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
List crlList = new ArrayList();
|
||||
crlList.add(loadCRL("validator.revoked.crl"));
|
||||
CertStore crls = CertStore.getInstance("Collection",new CollectionCertStoreParameters(crlList));
|
||||
params.addCertStore(crls);
|
||||
params.setRevocationEnabled(true);
|
||||
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertFalse(result.isValidSignature());
|
||||
|
||||
PKIXCertPathReviewer review = result.getCertPathReview();
|
||||
assertFalse(review.isValidCertPath());
|
||||
assertContainsMessage(
|
||||
review.getErrors(0),
|
||||
"CertPathReviewer.certRevoked",
|
||||
"The certificate was revoked at Sep 1, 2006 9:30:00 AM GMT. Reason: Key Compromise.");
|
||||
}
|
||||
|
||||
public void testLongValidity() throws Exception
|
||||
{
|
||||
String message = "validator.longValidity.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertTrue(result.isValidSignature());
|
||||
|
||||
assertContainsMessage(result.getNotifications(),
|
||||
"SignedMailValidator.longValidity",
|
||||
"Warning: The signing certificate has a very long validity period: from Sep 1, 2006 11:00:00 AM GMT until Aug 8, 2106 11:00:00 AM GMT.");
|
||||
}
|
||||
|
||||
public void testSelfSignedCert()
|
||||
throws Exception
|
||||
{
|
||||
MimeBodyPart baseMsg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n");
|
||||
String signDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
|
||||
KeyPair signKP = CMSTestUtil.makeKeyPair();
|
||||
X509Certificate signCert = CMSTestUtil.makeV1Certificate(signKP, signDN, signKP, signDN);
|
||||
|
||||
// check basic path validation
|
||||
Set trustanchors = new HashSet();
|
||||
TrustAnchor ta = new TrustAnchor(signCert, null);
|
||||
trustanchors.add(ta);
|
||||
|
||||
X509Certificate rootCert = ta.getTrustedCert();
|
||||
|
||||
// init cert stores
|
||||
List certStores = new ArrayList();
|
||||
List certList = new ArrayList();
|
||||
certList.add(rootCert);
|
||||
CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList));
|
||||
certStores.add(store);
|
||||
|
||||
// first path
|
||||
CertPath path = SignedMailValidator.createCertPath(rootCert, trustanchors, certStores);
|
||||
|
||||
assertTrue("path size is not 1", path.getCertificates().size() == 1);
|
||||
|
||||
// check message validation
|
||||
certList = new ArrayList();
|
||||
|
||||
certList.add(signCert);
|
||||
|
||||
Store certs = new JcaCertStore(certList);
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider("BC").build("SHA1withRSA", signKP.getPrivate(), signCert));
|
||||
gen.addCertificates(certs);
|
||||
|
||||
MimeMultipart signedMsg = gen.generate(baseMsg);
|
||||
|
||||
Properties props = System.getProperties();
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
// read message
|
||||
MimeMessage msg = new MimeMessage(session);
|
||||
|
||||
Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>");
|
||||
Address toUser = new InternetAddress("example@bouncycastle.org");
|
||||
|
||||
msg.setFrom(fromUser);
|
||||
msg.setRecipient(Message.RecipientType.TO, toUser);
|
||||
msg.setContent(signedMsg, signedMsg.getContentType());
|
||||
|
||||
msg.saveChanges();
|
||||
|
||||
PKIXParameters params = new PKIXParameters(trustanchors);
|
||||
params.setRevocationEnabled(false);
|
||||
|
||||
SignedMailValidator validator = new SignedMailValidator(msg, params);
|
||||
SignerInformation signer = (SignerInformation) validator
|
||||
.getSignerInformationStore().getSigners().iterator().next();
|
||||
|
||||
SignedMailValidator.ValidationResult res = validator.getValidationResult(signer);
|
||||
|
||||
assertTrue(res.isVerifiedSignature());
|
||||
assertTrue(res.isValidSignature());
|
||||
}
|
||||
|
||||
// TODO: this test needs to be replaced, unfortunately it was working due to a bug in
|
||||
// trust anchor extension handling
|
||||
// public void testCorruptRootStore() throws Exception
|
||||
// {
|
||||
// String message = "validator.validMail.eml";
|
||||
// Set trustanchors = new HashSet();
|
||||
// trustanchors.add(getTrustAnchor(TEST_TRUST_ACHOR));
|
||||
// trustanchors.add(getTrustAnchor("validator.fakeRoot.crt"));
|
||||
// PKIXParameters params = new PKIXParameters(trustanchors);
|
||||
// params.setRevocationEnabled(false);
|
||||
//
|
||||
// SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
//
|
||||
// assertTrue(result.isVerifiedSignature());
|
||||
// assertFalse(result.isValidSignature());
|
||||
//
|
||||
// PKIXCertPathReviewer review = result.getCertPathReview();
|
||||
//
|
||||
// assertFalse(review.isValidCertPath());
|
||||
// assertContainsMessage(review.getErrors(-1),
|
||||
// "CertPathReviewer.conflictingTrustAnchors",
|
||||
// "Warning: corrupt trust root store: There are 2 trusted public keys for the CA \"CN=SignedMailValidatorTest Root, C=CH\" - please ensure with CA which is the correct key.");
|
||||
// }
|
||||
|
||||
public void testCircular() throws Exception
|
||||
{
|
||||
String message = "circular.eml";
|
||||
PKIXParameters params = createDefaultParams();
|
||||
SignedMailValidator.ValidationResult result = doTest(message, params);
|
||||
|
||||
assertTrue(result.isVerifiedSignature());
|
||||
assertFalse(result.isValidSignature());
|
||||
assertFalse(result.getCertPathReview().isValidCertPath());
|
||||
assertTrue("cert path size", result.getCertPathReview().getCertPathSize() > 2);
|
||||
}
|
||||
|
||||
public void testExtendedReviewer() throws Exception
|
||||
{
|
||||
try
|
||||
{
|
||||
// Get a Session object with the default properties.
|
||||
Properties props = System.getProperties();
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
// read message
|
||||
MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("validator.shortKey.eml"));
|
||||
|
||||
SignedMailValidator validator = new SignedMailValidator(msg, createDefaultParams(), String.class);
|
||||
fail();
|
||||
}
|
||||
catch (IllegalArgumentException e)
|
||||
{
|
||||
assertTrue(e.getMessage().startsWith("certPathReviewerClass is not a subclass of"));
|
||||
}
|
||||
|
||||
// Get a Session object with the default properties.
|
||||
Properties props = System.getProperties();
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
// read message
|
||||
MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("validator.shortKey.eml"));
|
||||
|
||||
SignedMailValidator validator = new SignedMailValidator(msg, createDefaultParams(), DummyCertPathReviewer.class);
|
||||
SignerInformation sInfo = (SignerInformation) validator.getSignerInformationStore().getSigners().iterator().next();
|
||||
SignedMailValidator.ValidationResult result = validator.getValidationResult(sInfo);
|
||||
|
||||
assertTrue(result.isValidSignature());
|
||||
assertContainsMessage(result.getNotifications(),
|
||||
"SignedMailValidator.shortSigningKey",
|
||||
"Warning: The signing key is only 512 bits long.");
|
||||
}
|
||||
|
||||
public void testCreateCertPath() throws Exception
|
||||
{
|
||||
// load trust anchor
|
||||
Set trustanchors = new HashSet();
|
||||
TrustAnchor ta = getTrustAnchor("certpath_root.crt");
|
||||
trustanchors.add(ta);
|
||||
|
||||
X509Certificate rootCert = ta.getTrustedCert();
|
||||
X509Certificate interCert1 = loadCert("certpath_inter1.crt");
|
||||
X509Certificate interCert2 = loadCert("certpath_inter2.crt");
|
||||
X509Certificate endCert1 = loadCert("certpath_end1.crt");
|
||||
X509Certificate endCert2 = loadCert("certpath_end2.crt");
|
||||
|
||||
// init cert stores
|
||||
List certStores = new ArrayList();
|
||||
List certList = new ArrayList();
|
||||
certList.add(interCert1);
|
||||
certList.add(interCert2);
|
||||
CertStore store = CertStore.getInstance("Collection", new CollectionCertStoreParameters(certList));
|
||||
certStores.add(store);
|
||||
|
||||
// first path
|
||||
CertPath path = SignedMailValidator.createCertPath(endCert1, trustanchors, certStores);
|
||||
assertTrue("path size is not 3", path.getCertificates().size() == 3);
|
||||
assertEquals("different end certificate", path.getCertificates().get(0), endCert1);
|
||||
assertEquals("different intermediate certificate", path.getCertificates().get(1), interCert1);
|
||||
assertEquals("different root certificate", path.getCertificates().get(2), rootCert);
|
||||
|
||||
// second path
|
||||
path = SignedMailValidator.createCertPath(endCert2, trustanchors, certStores);
|
||||
assertTrue("path size is not 3", path.getCertificates().size() == 3);
|
||||
assertEquals("different end certificate", path.getCertificates().get(0), endCert2);
|
||||
assertEquals("different intermediate certificate", path.getCertificates().get(1), interCert2);
|
||||
assertEquals("different root certificate", path.getCertificates().get(2), rootCert);
|
||||
}
|
||||
|
||||
private SignedMailValidator.ValidationResult doTest(String message,
|
||||
PKIXParameters params) throws Exception
|
||||
{
|
||||
// Get a Session object with the default properties.
|
||||
Properties props = System.getProperties();
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
// read message
|
||||
MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream(message));
|
||||
|
||||
SignedMailValidator validator = new SignedMailValidator(msg, params);
|
||||
SignerInformation signer = (SignerInformation) validator
|
||||
.getSignerInformationStore().getSigners().iterator().next();
|
||||
return validator.getValidationResult(signer);
|
||||
}
|
||||
|
||||
private void assertContainsMessage(List msgList, String messageId,
|
||||
String text) throws Exception
|
||||
{
|
||||
Iterator it = msgList.iterator();
|
||||
boolean found = false;
|
||||
while (it.hasNext())
|
||||
{
|
||||
ErrorBundle message = (ErrorBundle) it.next();
|
||||
if (message.getId().equals(messageId))
|
||||
{
|
||||
found = true;
|
||||
assertEquals(text, message.getText(Locale.ENGLISH, TimeZone
|
||||
.getTimeZone("GMT")));
|
||||
break;
|
||||
}
|
||||
}
|
||||
assertTrue("Expected message not found!", found);
|
||||
}
|
||||
|
||||
private PKIXParameters createDefaultParams() throws Exception
|
||||
{
|
||||
Set trustanchors = new HashSet();
|
||||
trustanchors.add(getTrustAnchor(TEST_TRUST_ACHOR));
|
||||
PKIXParameters defParams = new PKIXParameters(trustanchors);
|
||||
defParams.setRevocationEnabled(false);
|
||||
|
||||
return defParams;
|
||||
}
|
||||
|
||||
private TrustAnchor getTrustAnchor(String trustcert) throws Exception
|
||||
{
|
||||
X509Certificate cert = loadCert(trustcert);
|
||||
if (cert != null)
|
||||
{
|
||||
byte[] ncBytes = cert
|
||||
.getExtensionValue(X509Extension.nameConstraints.getId());
|
||||
|
||||
if (ncBytes != null)
|
||||
{
|
||||
ASN1Encodable extValue = X509ExtensionUtil
|
||||
.fromExtensionValue(ncBytes);
|
||||
return new TrustAnchor(cert, extValue.toASN1Primitive().getEncoded(ASN1Encoding.DER));
|
||||
}
|
||||
return new TrustAnchor(cert, null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private X509Certificate loadCert(String certfile) throws Exception
|
||||
{
|
||||
X509Certificate cert = null;
|
||||
InputStream in = getClass().getResourceAsStream(certfile);
|
||||
|
||||
CertificateFactory cf = CertificateFactory.getInstance("X.509", "BC");
|
||||
cert = (X509Certificate) cf.generateCertificate(in);
|
||||
return cert;
|
||||
}
|
||||
|
||||
private X509CRL loadCRL(String crlfile) throws Exception
|
||||
{
|
||||
X509CRL crl = null;
|
||||
InputStream in = this.getClass().getResourceAsStream(crlfile);
|
||||
|
||||
CertificateFactory cf = CertificateFactory.getInstance("x.509", "BC");
|
||||
crl = (X509CRL) cf.generateCRL(in);
|
||||
return crl;
|
||||
}
|
||||
|
||||
public void setUp()
|
||||
{
|
||||
if (Security.getProvider("BC") == null)
|
||||
{
|
||||
Security
|
||||
.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
|
||||
}
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception
|
||||
{
|
||||
junit.textui.TestRunner.run(suite());
|
||||
}
|
||||
|
||||
public static Test suite() throws Exception
|
||||
{
|
||||
TestSuite suite = new TestSuite("SignedMailValidator Tests");
|
||||
|
||||
suite.addTestSuite(SignedMailValidatorTest.class);
|
||||
|
||||
return suite;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,224 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.InputStream;
|
||||
import java.security.KeyPair;
|
||||
import org.bouncycastle.jce.cert.CertStore;
|
||||
import org.bouncycastle.jce.cert.CollectionCertStoreParameters;
|
||||
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.cms.SignerInformation;
|
||||
import org.bouncycastle.cms.SignerInformationStore;
|
||||
import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter;
|
||||
import org.bouncycastle.cms.test.CMSTestUtil;
|
||||
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;
|
||||
|
||||
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();
|
||||
|
||||
boolean DEBUG = true;
|
||||
|
||||
MimeBodyPart msg;
|
||||
|
||||
String signDN;
|
||||
KeyPair signKP;
|
||||
X509Certificate signCert;
|
||||
|
||||
String origDN;
|
||||
KeyPair origKP;
|
||||
X509Certificate origCert;
|
||||
|
||||
String reciDN;
|
||||
KeyPair reciKP;
|
||||
X509Certificate reciCert;
|
||||
|
||||
KeyPair dsaSignKP;
|
||||
X509Certificate dsaSignCert;
|
||||
|
||||
KeyPair dsaOrigKP;
|
||||
X509Certificate dsaOrigCert;
|
||||
|
||||
/*
|
||||
*
|
||||
* INFRASTRUCTURE
|
||||
*
|
||||
*/
|
||||
|
||||
public SMIMECompressedTest(
|
||||
String name)
|
||||
throws Exception
|
||||
{
|
||||
super(name);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
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, SMIMECompressedGenerator.ZLIB);
|
||||
|
||||
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, SMIMECompressedGenerator.ZLIB);
|
||||
|
||||
SMIMECompressed sc = new SMIMECompressed(cbp);
|
||||
|
||||
msg.writeTo(bOut);
|
||||
|
||||
assertTrue(Arrays.areEqual(bOut.toByteArray(), sc.getContent()));
|
||||
}
|
||||
|
||||
public void testParser()
|
||||
throws Exception
|
||||
{
|
||||
SMIMECompressedGenerator cgen = new SMIMECompressedGenerator();
|
||||
ByteArrayOutputStream bOut1 = new ByteArrayOutputStream();
|
||||
ByteArrayOutputStream bOut2 = new ByteArrayOutputStream();
|
||||
MimeBodyPart cbp = cgen.generate(msg, SMIMECompressedGenerator.ZLIB);
|
||||
SMIMECompressedParser sc = new SMIMECompressedParser(cbp);
|
||||
|
||||
msg.writeTo(bOut1);
|
||||
|
||||
InputStream in = sc.getContent().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);
|
||||
|
||||
CertStore certs = CertStore.getInstance("Collection",
|
||||
new CollectionCertStoreParameters(certList), "BC");
|
||||
|
||||
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.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA1, new AttributeTable(signedAttrs), null);
|
||||
|
||||
gen.addCertificatesAndCRLs(certs);
|
||||
|
||||
MimeMultipart smp = gen.generate(msg, "BC");
|
||||
|
||||
MimeMessage bp2 = new MimeMessage((Session)null);
|
||||
|
||||
bp2.setContent(smp);
|
||||
|
||||
bp2.saveChanges();
|
||||
|
||||
SMIMECompressedGenerator cgen = new SMIMECompressedGenerator();
|
||||
|
||||
MimeBodyPart cbp = cgen.generate(bp2, SMIMECompressedGenerator.ZLIB);
|
||||
|
||||
SMIMECompressed cm = new SMIMECompressed(cbp);
|
||||
|
||||
MimeMultipart mm = (MimeMultipart)SMIMEUtil.toMimeBodyPart(cm.getContent()).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.getCertificatesAndCRLs("Collection", "BC");
|
||||
|
||||
SignerInformationStore signers = s.getSignerInfos();
|
||||
Collection c = signers.getSigners();
|
||||
Iterator it = c.iterator();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
SignerInformation signer = (SignerInformation)it.next();
|
||||
Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID()));
|
||||
|
||||
Iterator certIt = certCollection.iterator();
|
||||
X509Certificate cert = (X509Certificate)certIt.next();
|
||||
|
||||
assertEquals(true, signer.verify(cert, "BC"));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,361 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.security.KeyPair;
|
||||
import java.security.Security;
|
||||
import org.bouncycastle.jce.cert.CertStore;
|
||||
import org.bouncycastle.jce.cert.CollectionCertStoreParameters;
|
||||
import java.security.cert.X509Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.mail.Address;
|
||||
import javax.mail.Message;
|
||||
import javax.mail.Session;
|
||||
import javax.mail.internet.InternetAddress;
|
||||
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.cms.CMSException;
|
||||
import org.bouncycastle.cms.RecipientInformation;
|
||||
import org.bouncycastle.cms.SignerInformation;
|
||||
import org.bouncycastle.cms.SignerInformationStore;
|
||||
import org.bouncycastle.cms.jcajce.JcaX509CertSelectorConverter;
|
||||
import org.bouncycastle.cms.test.CMSTestUtil;
|
||||
import org.bouncycastle.jce.provider.BouncyCastleProvider;
|
||||
import org.bouncycastle.mail.smime.SMIMECompressedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnveloped;
|
||||
import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMESigned;
|
||||
import org.bouncycastle.mail.smime.SMIMESignedGenerator;
|
||||
import org.bouncycastle.mail.smime.SMIMESignedParser;
|
||||
import org.bouncycastle.mail.smime.SMIMEUtil;
|
||||
import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart;
|
||||
|
||||
public class SMIMEMiscTest
|
||||
extends TestCase
|
||||
{
|
||||
static MimeBodyPart msg;
|
||||
|
||||
static String signDN;
|
||||
static KeyPair signKP;
|
||||
static X509Certificate signCert;
|
||||
|
||||
static String origDN;
|
||||
static KeyPair origKP;
|
||||
static X509Certificate origCert;
|
||||
|
||||
static String reciDN;
|
||||
static KeyPair reciKP;
|
||||
static X509Certificate reciCert;
|
||||
|
||||
private static final JcaX509CertSelectorConverter selectorConverter = new JcaX509CertSelectorConverter();
|
||||
|
||||
KeyPair dsaSignKP;
|
||||
X509Certificate dsaSignCert;
|
||||
|
||||
KeyPair dsaOrigKP;
|
||||
X509Certificate dsaOrigCert;
|
||||
|
||||
static
|
||||
{
|
||||
try
|
||||
{
|
||||
msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n");
|
||||
|
||||
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 SMIMEMiscTest(String name)
|
||||
{
|
||||
super(name);
|
||||
}
|
||||
|
||||
public static void main(String args[])
|
||||
{
|
||||
Security.addProvider(new BouncyCastleProvider());
|
||||
|
||||
junit.textui.TestRunner.run(SMIMEMiscTest.class);
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
{
|
||||
return new SMIMETestSetup(new TestSuite(SMIMEMiscTest.class));
|
||||
}
|
||||
|
||||
public void testSHA256WithRSAParserEncryptedWithAES()
|
||||
throws Exception
|
||||
{
|
||||
List certList = new ArrayList();
|
||||
|
||||
certList.add(origCert);
|
||||
certList.add(signCert);
|
||||
|
||||
CertStore certs = CertStore.getInstance("Collection",
|
||||
new CollectionCertStoreParameters(certList), "BC");
|
||||
|
||||
SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
encGen.addKeyTransRecipient(origCert);
|
||||
|
||||
MimeBodyPart mp = encGen.generate(msg, SMIMEEnvelopedGenerator.AES128_CBC, "BC");
|
||||
ASN1EncodableVector signedAttrs = generateSignedAttributes();
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null);
|
||||
gen.addCertificatesAndCRLs(certs);
|
||||
|
||||
MimeMultipart smm = gen.generate(mp, "BC");
|
||||
File tmpFile = File.createTempFile("bcTest", ".mime");
|
||||
|
||||
MimeMessage msg = createMimeMessage(tmpFile, smm);
|
||||
|
||||
SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)msg.getContent());
|
||||
|
||||
certs = s.getCertificatesAndCRLs("Collection", "BC");
|
||||
|
||||
verifyMessageBytes(mp, s.getContent());
|
||||
|
||||
verifySigners(certs, s.getSignerInfos());
|
||||
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
public void testSHA256WithRSACompressed()
|
||||
throws Exception
|
||||
{
|
||||
List certList = new ArrayList();
|
||||
|
||||
certList.add(origCert);
|
||||
certList.add(signCert);
|
||||
|
||||
CertStore certs = CertStore.getInstance("Collection",
|
||||
new CollectionCertStoreParameters(certList), "BC");
|
||||
|
||||
SMIMECompressedGenerator cGen = new SMIMECompressedGenerator();
|
||||
|
||||
MimeBodyPart mp = cGen.generate(msg, SMIMECompressedGenerator.ZLIB);
|
||||
|
||||
ASN1EncodableVector signedAttrs = generateSignedAttributes();
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null);
|
||||
gen.addCertificatesAndCRLs(certs);
|
||||
|
||||
MimeMultipart smm = gen.generate(mp, "BC");
|
||||
File tmpFile = File.createTempFile("bcTest", ".mime");
|
||||
|
||||
MimeMessage msg = createMimeMessage(tmpFile, smm);
|
||||
|
||||
SMIMESigned s = new SMIMESigned((MimeMultipart)msg.getContent());
|
||||
|
||||
certs = s.getCertificatesAndCRLs("Collection", "BC");
|
||||
|
||||
verifyMessageBytes(mp, s.getContent());
|
||||
|
||||
verifySigners(certs, s.getSignerInfos());
|
||||
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
public void testQuotePrintableSigPreservation()
|
||||
throws Exception
|
||||
{
|
||||
MimeMessage msg = new MimeMessage((Session)null, getClass().getResourceAsStream("qp-soft-break.eml"));
|
||||
|
||||
SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator();
|
||||
|
||||
encGen.addKeyTransRecipient(origCert);
|
||||
|
||||
MimeBodyPart mp = encGen.generate(msg, SMIMEEnvelopedGenerator.AES128_CBC, "BC");
|
||||
|
||||
SMIMEEnveloped env = new SMIMEEnveloped(mp);
|
||||
RecipientInformation ri = (RecipientInformation)env.getRecipientInfos().getRecipients().iterator().next();
|
||||
MimeBodyPart mm = SMIMEUtil.toMimeBodyPart(ri.getContentStream(origKP.getPrivate(), "BC"));
|
||||
SMIMESigned s = new SMIMESigned((MimeMultipart)mm.getContent());
|
||||
Collection c = s.getSignerInfos().getSigners();
|
||||
Iterator it = c.iterator();
|
||||
CertStore certs = s.getCertificatesAndCRLs("Collection", "BC");
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
SignerInformation signer = (SignerInformation)it.next();
|
||||
Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID()));
|
||||
|
||||
Iterator certIt = certCollection.iterator();
|
||||
X509Certificate cert = (X509Certificate)certIt.next();
|
||||
|
||||
assertEquals(true, signer.verify(cert, "BC"));
|
||||
}
|
||||
|
||||
((FileBackedMimeBodyPart)mm).dispose();
|
||||
}
|
||||
|
||||
public void testSHA256WithRSAParserCompressed()
|
||||
throws Exception
|
||||
{
|
||||
List certList = new ArrayList();
|
||||
|
||||
certList.add(origCert);
|
||||
certList.add(signCert);
|
||||
|
||||
CertStore certs = CertStore.getInstance("Collection",
|
||||
new CollectionCertStoreParameters(certList), "BC");
|
||||
|
||||
SMIMECompressedGenerator cGen = new SMIMECompressedGenerator();
|
||||
|
||||
MimeBodyPart mp = cGen.generate(msg, SMIMECompressedGenerator.ZLIB);
|
||||
|
||||
ASN1EncodableVector signedAttrs = generateSignedAttributes();
|
||||
|
||||
SMIMESignedGenerator gen = new SMIMESignedGenerator();
|
||||
|
||||
gen.addSigner(origKP.getPrivate(), origCert, SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(signedAttrs), null);
|
||||
gen.addCertificatesAndCRLs(certs);
|
||||
|
||||
MimeMultipart smm = gen.generate(mp, "BC");
|
||||
File tmpFile = File.createTempFile("bcTest", ".mime");
|
||||
|
||||
MimeMessage msg = createMimeMessage(tmpFile, smm);
|
||||
|
||||
SMIMESignedParser s = new SMIMESignedParser((MimeMultipart)msg.getContent());
|
||||
|
||||
certs = s.getCertificatesAndCRLs("Collection", "BC");
|
||||
|
||||
verifyMessageBytes(mp, s.getContent());
|
||||
|
||||
verifySigners(certs, s.getSignerInfos());
|
||||
|
||||
tmpFile.delete();
|
||||
}
|
||||
|
||||
public void testBrokenEnvelope()
|
||||
throws Exception
|
||||
{
|
||||
Session session = Session.getDefaultInstance(System.getProperties(), null);
|
||||
MimeMessage msg = new MimeMessage(session, getClass().getResourceAsStream("brokenEnv.message"));
|
||||
|
||||
try
|
||||
{
|
||||
new SMIMEEnveloped(msg);
|
||||
}
|
||||
catch (CMSException e)
|
||||
{
|
||||
if (!e.getMessage().equals("Malformed content."))
|
||||
{
|
||||
fail("wrong exception on bogus envelope");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void verifySigners(CertStore certs, SignerInformationStore signers)
|
||||
throws Exception
|
||||
{
|
||||
Collection c = signers.getSigners();
|
||||
Iterator it = c.iterator();
|
||||
|
||||
while (it.hasNext())
|
||||
{
|
||||
SignerInformation signer = (SignerInformation)it.next();
|
||||
Collection certCollection = certs.getCertificates(selectorConverter.getCertSelector(signer.getSID()));
|
||||
|
||||
Iterator certIt = certCollection.iterator();
|
||||
X509Certificate cert = (X509Certificate)certIt.next();
|
||||
|
||||
assertEquals(true, signer.verify(cert, "BC"));
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b)
|
||||
throws Exception
|
||||
{
|
||||
ByteArrayOutputStream bOut1 = new ByteArrayOutputStream();
|
||||
|
||||
a.writeTo(bOut1);
|
||||
bOut1.close();
|
||||
|
||||
ByteArrayOutputStream bOut2 = new ByteArrayOutputStream();
|
||||
|
||||
b.writeTo(bOut2);
|
||||
bOut2.close();
|
||||
|
||||
assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2.toByteArray()));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a mime message representing the multipart. We need to do
|
||||
* this as otherwise no raw content stream for the message will exist.
|
||||
*/
|
||||
private MimeMessage createMimeMessage(File tmpFile, MimeMultipart smm)
|
||||
throws Exception
|
||||
{
|
||||
FileOutputStream fOut = new FileOutputStream(tmpFile);
|
||||
Properties props = System.getProperties();
|
||||
Session session = Session.getDefaultInstance(props, null);
|
||||
|
||||
Address fromUser = new InternetAddress("\"Eric H. Echidna\"<eric@bouncycastle.org>");
|
||||
Address toUser = new InternetAddress("example@bouncycastle.org");
|
||||
|
||||
MimeMessage body = new MimeMessage(session);
|
||||
body.setFrom(fromUser);
|
||||
body.setRecipient(Message.RecipientType.TO, toUser);
|
||||
body.setSubject("example signed message");
|
||||
body.setContent(smm, smm.getContentType());
|
||||
body.saveChanges();
|
||||
|
||||
body.writeTo(fOut);
|
||||
|
||||
fOut.close();
|
||||
|
||||
return new MimeMessage(session, new FileInputStream(tmpFile));
|
||||
}
|
||||
|
||||
private ASN1EncodableVector generateSignedAttributes()
|
||||
{
|
||||
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));
|
||||
|
||||
return signedAttrs;
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,25 @@
|
||||
package org.bouncycastle.mail.smime.test;
|
||||
|
||||
import junit.framework.Test;
|
||||
import junit.framework.TestSuite;
|
||||
|
||||
public class AllTests
|
||||
{
|
||||
public static void main (String[] args)
|
||||
throws Exception
|
||||
{
|
||||
junit.textui.TestRunner.run (suite());
|
||||
}
|
||||
|
||||
public static Test suite()
|
||||
throws Exception
|
||||
{
|
||||
TestSuite suite= new TestSuite("SMIME tests");
|
||||
|
||||
suite.addTest(NewSMIMESignedTest.suite());
|
||||
suite.addTest(NewSMIMEEnvelopedTest.suite());
|
||||
suite.addTest(SMIMECompressedTest.suite());
|
||||
suite.addTest(SMIMEMiscTest.suite());
|
||||
return suite;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user