blob: 48519450513b953fafe3258b79bc8ef51fd08698 [file] [log] [blame]
package org.bouncycastle.mime.test;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.security.KeyPair;
import java.security.Security;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import java.util.Collection;
import java.util.Iterator;
import junit.framework.TestCase;
import org.bouncycastle.cert.X509CertificateHolder;
import org.bouncycastle.cert.jcajce.JcaX509CertificateHolder;
import org.bouncycastle.cms.CMSException;
import org.bouncycastle.cms.SignerInformation;
import org.bouncycastle.cms.SignerInformationStore;
import org.bouncycastle.cms.jcajce.JcaSignerId;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoGeneratorBuilder;
import org.bouncycastle.cms.jcajce.JcaSimpleSignerInfoVerifierBuilder;
import org.bouncycastle.cms.test.CMSTestUtil;
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.bouncycastle.mime.Headers;
import org.bouncycastle.mime.MimeParser;
import org.bouncycastle.mime.MimeParserContext;
import org.bouncycastle.mime.MimeParserProvider;
import org.bouncycastle.mime.smime.SMIMESignedWriter;
import org.bouncycastle.mime.smime.SMimeParserListener;
import org.bouncycastle.mime.smime.SMimeParserProvider;
import org.bouncycastle.operator.OperatorCreationException;
import org.bouncycastle.operator.bc.BcDigestCalculatorProvider;
import org.bouncycastle.util.Store;
import org.bouncycastle.util.Strings;
import org.bouncycastle.util.encoders.Base64;
import org.bouncycastle.util.io.Streams;
public class TestSMIMESigned
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 _signCert;
private static X509Certificate _reciCert;
private static boolean _initialised = false;
private static final byte[] simpleMessage = Strings.toByteArray(
"Content-Type: text/plain; name=null; charset=us-ascii\r\n" +
"Content-Transfer-Encoding: 7bit\r\n" +
"Content-Disposition: inline; filename=null\r\n" +
"\r\n" +
"Hello, world!\r\n");
private static final byte[] simpleMessageContent = Strings.toByteArray(
"Hello, world!\r\n");
private static final byte[] testMultipartMessage = Base64.decode(
"TUlNRS1WZXJzaW9uOiAxLjANCkNvbnRlbnQtVHlwZTogbXVsdGlwYXJ0L21peGVkOyANCglib3VuZGFye" +
"T0iLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyIg0KQ29udGVudC1MYW5ndWFnZTogZW" +
"4NCkNvbnRlbnQtRGVzY3JpcHRpb246IEEgbWFpbCBmb2xsb3dpbmcgdGhlIERJUkVDVCBwcm9qZWN0IHN" +
"wZWNpZmljYXRpb25zDQoNCi0tLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzUwMTMyDQpDb250" +
"ZW50LVR5cGU6IHRleHQvcGxhaW47IG5hbWU9bnVsbDsgY2hhcnNldD11cy1hc2NpaQ0KQ29udGVudC1Uc" +
"mFuc2Zlci1FbmNvZGluZzogN2JpdA0KQ29udGVudC1EaXNwb3NpdGlvbjogaW5saW5lOyBmaWxlbmFtZT" +
"1udWxsDQoNCkNpYW8gZnJvbSB2aWVubmENCi0tLS0tLT1fUGFydF8wXzI2MDM5NjM4Ni4xMzUyOTA0NzU" +
"wMTMyLS0NCg==");
private static final byte[] testMultipartMessageContent = Base64.decode(
"LS0tLS0tPV9QYXJ0XzBfMjYwMzk2Mzg2LjEzNTI5MDQ3NTAxMzINCkNvbnRlbnQtVHlwZTogdGV4dC9w" +
"bGFpbjsgbmFtZT1udWxsOyBjaGFyc2V0PXVzLWFzY2lpDQpDb250ZW50LVRyYW5zZmVyLUVuY29kaW5n" +
"OiA3Yml0DQpDb250ZW50LURpc3Bvc2l0aW9uOiBpbmxpbmU7IGZpbGVuYW1lPW51bGwNCg0KQ2lhbyBm" +
"cm9tIHZpZW5uYQ0KLS0tLS0tPV9QYXJ0XzBfMjYwMzk2Mzg2LjEzNTI5MDQ3NTAxMzItLQ0K");
private static void init()
throws Exception
{
if (!_initialised)
{
if (Security.getProvider("BC") == null)
{
Security.addProvider(new BouncyCastleProvider());
}
_initialised = true;
_signDN = "O=Bouncy Castle, C=AU";
_signKP = CMSTestUtil.makeKeyPair();
_signCert = CMSTestUtil.makeCertificate(_signKP, _signDN, _signKP, _signDN);
_reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
_reciKP = CMSTestUtil.makeKeyPair();
_reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN, _signKP, _signDN);
}
}
public void setUp()
throws Exception
{
init();
}
public void testSimpleGeneration()
throws Exception
{
generationTest(simpleMessage, simpleMessageContent);
}
public void testEmbeddedMultipartGeneration()
throws Exception
{
generationTest(testMultipartMessage, testMultipartMessageContent);
}
private void generationTest(byte[] message, final byte[] messageContent)
throws Exception
{
//
// output
//
ByteArrayOutputStream bOut = new ByteArrayOutputStream();
SMIMESignedWriter.Builder sigBldr = new SMIMESignedWriter.Builder();
sigBldr.addCertificate(new JcaX509CertificateHolder(_signCert));
sigBldr.addSignerInfoGenerator(new JcaSimpleSignerInfoGeneratorBuilder().setProvider(BC).build("SHA256withRSA", _signKP.getPrivate(), _signCert));
SMIMESignedWriter sigWrt = sigBldr.build(bOut);
OutputStream out = sigWrt.getContentStream();
out.write(message);
out.close();
//
// parse
//
final TestDoneFlag dataParsed = new TestDoneFlag();
MimeParserProvider provider = new SMimeParserProvider("7bit", new BcDigestCalculatorProvider());
MimeParser p = provider.createParser(new ReadOnceInputStream(bOut.toByteArray()));
p.parse(new SMimeParserListener()
{
public void content(MimeParserContext parserContext, Headers headers, InputStream inputStream)
throws IOException
{
byte[] content = Streams.readAll(inputStream);
assertTrue(org.bouncycastle.util.Arrays.areEqual(messageContent, content));
}
public void signedData(MimeParserContext parserContext, Headers headers, Store certificates, Store CRLs, Store attributeCertificates, SignerInformationStore signers)
throws IOException, CMSException
{
SignerInformation signerInfo = signers.get(new JcaSignerId(_signCert));
assertNotNull(signerInfo);
Collection certCollection = certificates.getMatches(signerInfo.getSID());
Iterator certIt = certCollection.iterator();
X509CertificateHolder certHolder = (X509CertificateHolder)certIt.next();
try
{
assertEquals(true, signerInfo.verify(new JcaSimpleSignerInfoVerifierBuilder().setProvider("BC").build(certHolder)));
}
catch (OperatorCreationException e)
{
throw new CMSException(e.getMessage(), e);
}
catch (CertificateException e)
{
throw new CMSException(e.getMessage(), e);
}
dataParsed.markDone();
}
});
assertTrue(dataParsed.isDone());
}
}