001: package org.bouncycastle.mail.smime.test;
002:
003: import junit.framework.Test;
004: import junit.framework.TestCase;
005: import junit.framework.TestSuite;
006: import org.bouncycastle.asn1.ASN1EncodableVector;
007: import org.bouncycastle.asn1.cms.AttributeTable;
008: import org.bouncycastle.asn1.smime.SMIMECapabilitiesAttribute;
009: import org.bouncycastle.asn1.smime.SMIMECapability;
010: import org.bouncycastle.asn1.smime.SMIMECapabilityVector;
011: import org.bouncycastle.cms.SignerInformation;
012: import org.bouncycastle.cms.SignerInformationStore;
013: import org.bouncycastle.cms.test.CMSTestUtil;
014: import org.bouncycastle.jce.provider.BouncyCastleProvider;
015: import org.bouncycastle.mail.smime.SMIMECompressedGenerator;
016: import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
017: import org.bouncycastle.mail.smime.SMIMESigned;
018: import org.bouncycastle.mail.smime.SMIMESignedGenerator;
019: import org.bouncycastle.mail.smime.SMIMESignedParser;
020:
021: import javax.mail.Address;
022: import javax.mail.Message;
023: import javax.mail.Session;
024: import javax.mail.internet.InternetAddress;
025: import javax.mail.internet.MimeBodyPart;
026: import javax.mail.internet.MimeMessage;
027: import javax.mail.internet.MimeMultipart;
028: import java.io.ByteArrayOutputStream;
029: import java.io.File;
030: import java.io.FileInputStream;
031: import java.io.FileOutputStream;
032: import java.security.KeyPair;
033: import java.security.Security;
034: import java.security.cert.CertStore;
035: import java.security.cert.CollectionCertStoreParameters;
036: import java.security.cert.X509Certificate;
037: import java.util.ArrayList;
038: import java.util.Arrays;
039: import java.util.Collection;
040: import java.util.Iterator;
041: import java.util.List;
042: import java.util.Properties;
043:
044: public class SMIMEMiscTest extends TestCase {
045: static MimeBodyPart msg;
046:
047: static String signDN;
048: static KeyPair signKP;
049: static X509Certificate signCert;
050:
051: static String origDN;
052: static KeyPair origKP;
053: static X509Certificate origCert;
054:
055: static String reciDN;
056: static KeyPair reciKP;
057: static X509Certificate reciCert;
058:
059: KeyPair dsaSignKP;
060: X509Certificate dsaSignCert;
061:
062: KeyPair dsaOrigKP;
063: X509Certificate dsaOrigCert;
064:
065: static {
066: try {
067: msg = SMIMETestUtil.makeMimeBodyPart("Hello world!\n");
068:
069: signDN = "O=Bouncy Castle, C=AU";
070: signKP = CMSTestUtil.makeKeyPair();
071: signCert = CMSTestUtil.makeCertificate(signKP, signDN,
072: signKP, signDN);
073:
074: origDN = "CN=Eric H. Echidna, E=eric@bouncycastle.org, O=Bouncy Castle, C=AU";
075: origKP = CMSTestUtil.makeKeyPair();
076: origCert = CMSTestUtil.makeCertificate(origKP, origDN,
077: signKP, signDN);
078: } catch (Exception e) {
079: throw new RuntimeException(
080: "problem setting up signed test class: " + e);
081: }
082: }
083:
084: /*
085: *
086: * INFRASTRUCTURE
087: *
088: */
089:
090: public SMIMEMiscTest(String name) {
091: super (name);
092: }
093:
094: public static void main(String args[]) {
095: Security.addProvider(new BouncyCastleProvider());
096:
097: junit.textui.TestRunner.run(SMIMEMiscTest.class);
098: }
099:
100: public static Test suite() {
101: return new SMIMETestSetup(new TestSuite(SMIMEMiscTest.class));
102: }
103:
104: public void testSHA256WithRSAParserEncryptedWithAES()
105: throws Exception {
106: List certList = new ArrayList();
107:
108: certList.add(origCert);
109: certList.add(signCert);
110:
111: CertStore certs = CertStore.getInstance("Collection",
112: new CollectionCertStoreParameters(certList), "BC");
113:
114: SMIMEEnvelopedGenerator encGen = new SMIMEEnvelopedGenerator();
115:
116: encGen.addKeyTransRecipient(origCert);
117:
118: MimeBodyPart mp = encGen.generate(msg,
119: SMIMEEnvelopedGenerator.AES128_CBC, "BC");
120: ASN1EncodableVector signedAttrs = generateSignedAttributes();
121:
122: SMIMESignedGenerator gen = new SMIMESignedGenerator();
123:
124: gen.addSigner(origKP.getPrivate(), origCert,
125: SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(
126: signedAttrs), null);
127: gen.addCertificatesAndCRLs(certs);
128:
129: MimeMultipart smm = gen.generate(mp, "BC");
130: File tmpFile = File.createTempFile("bcTest", ".mime");
131:
132: MimeMessage msg = createMimeMessage(tmpFile, smm);
133:
134: SMIMESignedParser s = new SMIMESignedParser((MimeMultipart) msg
135: .getContent());
136:
137: certs = s.getCertificatesAndCRLs("Collection", "BC");
138:
139: verifyMessageBytes(mp, s.getContent());
140:
141: verifySigners(certs, s.getSignerInfos());
142:
143: tmpFile.delete();
144: }
145:
146: public void testSHA256WithRSACompressed() throws Exception {
147: List certList = new ArrayList();
148:
149: certList.add(origCert);
150: certList.add(signCert);
151:
152: CertStore certs = CertStore.getInstance("Collection",
153: new CollectionCertStoreParameters(certList), "BC");
154:
155: SMIMECompressedGenerator cGen = new SMIMECompressedGenerator();
156:
157: MimeBodyPart mp = cGen.generate(msg,
158: SMIMECompressedGenerator.ZLIB);
159:
160: ASN1EncodableVector signedAttrs = generateSignedAttributes();
161:
162: SMIMESignedGenerator gen = new SMIMESignedGenerator();
163:
164: gen.addSigner(origKP.getPrivate(), origCert,
165: SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(
166: signedAttrs), null);
167: gen.addCertificatesAndCRLs(certs);
168:
169: MimeMultipart smm = gen.generate(mp, "BC");
170: File tmpFile = File.createTempFile("bcTest", ".mime");
171:
172: MimeMessage msg = createMimeMessage(tmpFile, smm);
173:
174: SMIMESigned s = new SMIMESigned((MimeMultipart) msg
175: .getContent());
176:
177: certs = s.getCertificatesAndCRLs("Collection", "BC");
178:
179: verifyMessageBytes(mp, s.getContent());
180:
181: verifySigners(certs, s.getSignerInfos());
182: }
183:
184: public void testSHA256WithRSAParserCompressed() throws Exception {
185: List certList = new ArrayList();
186:
187: certList.add(origCert);
188: certList.add(signCert);
189:
190: CertStore certs = CertStore.getInstance("Collection",
191: new CollectionCertStoreParameters(certList), "BC");
192:
193: SMIMECompressedGenerator cGen = new SMIMECompressedGenerator();
194:
195: MimeBodyPart mp = cGen.generate(msg,
196: SMIMECompressedGenerator.ZLIB);
197:
198: ASN1EncodableVector signedAttrs = generateSignedAttributes();
199:
200: SMIMESignedGenerator gen = new SMIMESignedGenerator();
201:
202: gen.addSigner(origKP.getPrivate(), origCert,
203: SMIMESignedGenerator.DIGEST_SHA256, new AttributeTable(
204: signedAttrs), null);
205: gen.addCertificatesAndCRLs(certs);
206:
207: MimeMultipart smm = gen.generate(mp, "BC");
208: File tmpFile = File.createTempFile("bcTest", ".mime");
209:
210: MimeMessage msg = createMimeMessage(tmpFile, smm);
211:
212: SMIMESignedParser s = new SMIMESignedParser((MimeMultipart) msg
213: .getContent());
214:
215: certs = s.getCertificatesAndCRLs("Collection", "BC");
216:
217: verifyMessageBytes(mp, s.getContent());
218:
219: verifySigners(certs, s.getSignerInfos());
220: }
221:
222: private void verifySigners(CertStore certs,
223: SignerInformationStore signers) throws Exception {
224: Collection c = signers.getSigners();
225: Iterator it = c.iterator();
226:
227: while (it.hasNext()) {
228: SignerInformation signer = (SignerInformation) it.next();
229: Collection certCollection = certs.getCertificates(signer
230: .getSID());
231:
232: Iterator certIt = certCollection.iterator();
233: X509Certificate cert = (X509Certificate) certIt.next();
234:
235: assertEquals(true, signer.verify(cert, "BC"));
236: }
237: }
238:
239: private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b)
240: throws Exception {
241: ByteArrayOutputStream bOut1 = new ByteArrayOutputStream();
242:
243: a.writeTo(bOut1);
244: bOut1.close();
245:
246: ByteArrayOutputStream bOut2 = new ByteArrayOutputStream();
247:
248: b.writeTo(bOut2);
249: bOut2.close();
250:
251: assertEquals(true, Arrays.equals(bOut1.toByteArray(), bOut2
252: .toByteArray()));
253: }
254:
255: /**
256: * Create a mime message representing the multipart. We need to do
257: * this as otherwise no raw content stream for the message will exist.
258: */
259: private MimeMessage createMimeMessage(File tmpFile,
260: MimeMultipart smm) throws Exception {
261: FileOutputStream fOut = new FileOutputStream(tmpFile);
262: Properties props = System.getProperties();
263: Session session = Session.getDefaultInstance(props, null);
264:
265: Address fromUser = new InternetAddress(
266: "\"Eric H. Echidna\"<eric@bouncycastle.org>");
267: Address toUser = new InternetAddress("example@bouncycastle.org");
268:
269: MimeMessage body = new MimeMessage(session);
270: body.setFrom(fromUser);
271: body.setRecipient(Message.RecipientType.TO, toUser);
272: body.setSubject("example signed message");
273: body.setContent(smm, smm.getContentType());
274: body.saveChanges();
275:
276: body.writeTo(fOut);
277:
278: fOut.close();
279:
280: return new MimeMessage(session, new FileInputStream(tmpFile));
281: }
282:
283: private ASN1EncodableVector generateSignedAttributes() {
284: ASN1EncodableVector signedAttrs = new ASN1EncodableVector();
285: SMIMECapabilityVector caps = new SMIMECapabilityVector();
286:
287: caps.addCapability(SMIMECapability.dES_EDE3_CBC);
288: caps.addCapability(SMIMECapability.rC2_CBC, 128);
289: caps.addCapability(SMIMECapability.dES_CBC);
290:
291: signedAttrs.add(new SMIMECapabilitiesAttribute(caps));
292:
293: return signedAttrs;
294: }
295: }
|