001: package org.bouncycastle.mail.smime.test;
002:
003: import java.io.ByteArrayOutputStream;
004: import java.io.IOException;
005: import java.security.KeyPair;
006: import java.security.MessageDigest;
007: import java.security.cert.CertificateEncodingException;
008: import java.security.cert.X509Certificate;
009: import java.util.Arrays;
010:
011: import javax.mail.MessagingException;
012: import javax.mail.internet.MimeBodyPart;
013:
014: import junit.framework.Test;
015: import junit.framework.TestCase;
016: import junit.framework.TestSuite;
017:
018: import org.bouncycastle.cms.RecipientId;
019: import org.bouncycastle.cms.RecipientInformation;
020: import org.bouncycastle.cms.RecipientInformationStore;
021: import org.bouncycastle.cms.test.CMSTestUtil;
022: import org.bouncycastle.jce.PrincipalUtil;
023: import org.bouncycastle.mail.smime.SMIMEEnveloped;
024: import org.bouncycastle.mail.smime.SMIMEEnvelopedGenerator;
025: import org.bouncycastle.mail.smime.SMIMEEnvelopedParser;
026: import org.bouncycastle.mail.smime.SMIMEUtil;
027: import org.bouncycastle.mail.smime.util.FileBackedMimeBodyPart;
028:
029: public class SMIMEEnvelopedTest extends TestCase {
030: private static String _signDN;
031: private static KeyPair _signKP;
032:
033: private static String _reciDN;
034: private static KeyPair _reciKP;
035: private static X509Certificate _reciCert;
036:
037: private static String _reciDN2;
038: private static KeyPair _reciKP2;
039: private static X509Certificate _reciCert2;
040:
041: private static boolean _initialised = false;
042:
043: private static void init() throws Exception {
044: if (!_initialised) {
045: _initialised = true;
046:
047: _signDN = "O=Bouncy Castle, C=AU";
048: _signKP = CMSTestUtil.makeKeyPair();
049:
050: _reciDN = "CN=Doug, OU=Sales, O=Bouncy Castle, C=AU";
051: _reciKP = CMSTestUtil.makeKeyPair();
052: _reciCert = CMSTestUtil.makeCertificate(_reciKP, _reciDN,
053: _signKP, _signDN);
054:
055: _reciDN2 = "CN=Fred, OU=Sales, O=Bouncy Castle, C=AU";
056: _reciKP2 = CMSTestUtil.makeKeyPair();
057: _reciCert2 = CMSTestUtil.makeCertificate(_reciKP2,
058: _reciDN2, _signKP, _signDN);
059: }
060: }
061:
062: public SMIMEEnvelopedTest(String name) {
063: super (name);
064: }
065:
066: public static void main(String args[]) {
067: junit.textui.TestRunner.run(SMIMEEnvelopedTest.class);
068: }
069:
070: public static Test suite() throws Exception {
071: return new SMIMETestSetup(new TestSuite(
072: SMIMEEnvelopedTest.class));
073: }
074:
075: public void setUp() throws Exception {
076: init();
077: }
078:
079: public void testHeaders() throws Exception {
080: MimeBodyPart _msg = SMIMETestUtil
081: .makeMimeBodyPart("WallaWallaWashington");
082:
083: SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
084:
085: gen.addKeyTransRecipient(_reciCert);
086:
087: //
088: // generate a MimeBodyPart object which encapsulates the content
089: // we want encrypted.
090: //
091:
092: MimeBodyPart mp = gen.generate(_msg,
093: SMIMEEnvelopedGenerator.DES_EDE3_CBC, "BC");
094:
095: assertEquals(
096: "application/pkcs7-mime; name=\"smime.p7m\"; smime-type=enveloped-data",
097: mp.getHeader("Content-Type")[0]);
098: assertEquals("attachment; filename=\"smime.p7m\"", mp
099: .getHeader("Content-Disposition")[0]);
100: assertEquals("S/MIME Encrypted Message", mp
101: .getHeader("Content-Description")[0]);
102: }
103:
104: public void testDESEDE3Encrypted() throws Exception {
105: MimeBodyPart msg = SMIMETestUtil
106: .makeMimeBodyPart("WallaWallaWashington");
107: String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC;
108:
109: verifyAlgorithm(algorithm, msg);
110: }
111:
112: public void testParserDESEDE3Encrypted() throws Exception {
113: MimeBodyPart msg = SMIMETestUtil
114: .makeMimeBodyPart("WallaWallaWashington");
115: String algorithm = SMIMEEnvelopedGenerator.DES_EDE3_CBC;
116:
117: verifyParserAlgorithm(algorithm, msg);
118: }
119:
120: public void testIDEAEncrypted() throws Exception {
121: MimeBodyPart msg = SMIMETestUtil
122: .makeMimeBodyPart("WallaWallaWashington");
123: String algorithm = SMIMEEnvelopedGenerator.IDEA_CBC;
124:
125: verifyAlgorithm(algorithm, msg);
126: }
127:
128: public void testRC2Encrypted() throws Exception {
129: MimeBodyPart msg = SMIMETestUtil
130: .makeMimeBodyPart("WallaWallaWashington");
131: String algorithm = SMIMEEnvelopedGenerator.RC2_CBC;
132:
133: verifyAlgorithm(algorithm, msg);
134: }
135:
136: public void testCASTEncrypted() throws Exception {
137: MimeBodyPart msg = SMIMETestUtil
138: .makeMimeBodyPart("WallaWallaWashington");
139: String algorithm = SMIMEEnvelopedGenerator.CAST5_CBC;
140:
141: verifyAlgorithm(algorithm, msg);
142: }
143:
144: public void testAES128Encrypted() throws Exception {
145: MimeBodyPart msg = SMIMETestUtil
146: .makeMimeBodyPart("WallaWallaWashington");
147: String algorithm = SMIMEEnvelopedGenerator.AES128_CBC;
148:
149: verifyAlgorithm(algorithm, msg);
150: }
151:
152: public void testAES192Encrypted() throws Exception {
153: MimeBodyPart msg = SMIMETestUtil
154: .makeMimeBodyPart("WallaWallaWashington");
155: String algorithm = SMIMEEnvelopedGenerator.AES192_CBC;
156:
157: verifyAlgorithm(algorithm, msg);
158: }
159:
160: public void testAES256Encrypted() throws Exception {
161: MimeBodyPart msg = SMIMETestUtil
162: .makeMimeBodyPart("WallaWallaWashington");
163: String algorithm = SMIMEEnvelopedGenerator.AES256_CBC;
164:
165: verifyAlgorithm(algorithm, msg);
166: }
167:
168: public void testSubKeyId() throws Exception {
169: MimeBodyPart _msg = SMIMETestUtil
170: .makeMimeBodyPart("WallaWallaWashington");
171:
172: SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
173:
174: //
175: // create a subject key id - this has to be done the same way as
176: // it is done in the certificate associated with the private key
177: //
178: MessageDigest dig = MessageDigest.getInstance("SHA1", "BC");
179: dig.update(_reciCert.getPublicKey().getEncoded());
180:
181: gen
182: .addKeyTransRecipient(_reciCert.getPublicKey(), dig
183: .digest());
184:
185: //
186: // generate a MimeBodyPart object which encapsulates the content
187: // we want encrypted.
188: //
189:
190: MimeBodyPart mp = gen.generate(_msg,
191: SMIMEEnvelopedGenerator.DES_EDE3_CBC, "BC");
192:
193: SMIMEEnveloped m = new SMIMEEnveloped(mp);
194:
195: RecipientId recId = new RecipientId();
196:
197: dig.update(_reciCert.getPublicKey().getEncoded());
198:
199: recId.setSubjectKeyIdentifier(dig.digest());
200:
201: RecipientInformationStore recipients = m.getRecipientInfos();
202: RecipientInformation recipient = recipients.get(recId);
203:
204: MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient
205: .getContent(_reciKP.getPrivate(), "BC"));
206:
207: verifyMessageBytes(_msg, res);
208: }
209:
210: public void testCapEncrypt() throws Exception {
211: MimeBodyPart _msg = SMIMETestUtil
212: .makeMimeBodyPart("WallaWallaWashington");
213:
214: SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
215:
216: //
217: // create a subject key id - this has to be done the same way as
218: // it is done in the certificate associated with the private key
219: //
220: MessageDigest dig = MessageDigest.getInstance("SHA1", "BC");
221: dig.update(_reciCert.getPublicKey().getEncoded());
222:
223: gen
224: .addKeyTransRecipient(_reciCert.getPublicKey(), dig
225: .digest());
226:
227: //
228: // generate a MimeBodyPart object which encapsulates the content
229: // we want encrypted.
230: //
231: MimeBodyPart mp = gen.generate(_msg,
232: SMIMEEnvelopedGenerator.RC2_CBC, 40, "BC");
233:
234: SMIMEEnveloped m = new SMIMEEnveloped(mp);
235:
236: RecipientId recId = new RecipientId();
237:
238: dig.update(_reciCert.getPublicKey().getEncoded());
239:
240: recId.setSubjectKeyIdentifier(dig.digest());
241:
242: RecipientInformationStore recipients = m.getRecipientInfos();
243: RecipientInformation recipient = recipients.get(recId);
244:
245: MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient
246: .getContent(_reciKP.getPrivate(), "BC"));
247:
248: verifyMessageBytes(_msg, res);
249: }
250:
251: public void testTwoRecipients() throws Exception {
252: MimeBodyPart _msg = SMIMETestUtil
253: .makeMimeBodyPart("WallaWallaWashington");
254:
255: SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
256:
257: gen.addKeyTransRecipient(_reciCert);
258: gen.addKeyTransRecipient(_reciCert2);
259:
260: //
261: // generate a MimeBodyPart object which encapsulates the content
262: // we want encrypted.
263: //
264: MimeBodyPart mp = gen.generate(_msg,
265: SMIMEEnvelopedGenerator.RC2_CBC, 40, "BC");
266:
267: SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp);
268:
269: RecipientId recId = getRecipientId(_reciCert2);
270:
271: RecipientInformationStore recipients = m.getRecipientInfos();
272: RecipientInformation recipient = recipients.get(recId);
273:
274: FileBackedMimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient
275: .getContentStream(_reciKP2.getPrivate(), "BC"));
276:
277: verifyMessageBytes(_msg, res);
278:
279: m = new SMIMEEnvelopedParser(mp);
280:
281: res.dispose();
282:
283: recId = getRecipientId(_reciCert);
284:
285: recipients = m.getRecipientInfos();
286: recipient = recipients.get(recId);
287:
288: res = SMIMEUtil.toMimeBodyPart(recipient.getContentStream(
289: _reciKP.getPrivate(), "BC"));
290:
291: verifyMessageBytes(_msg, res);
292:
293: res.dispose();
294: }
295:
296: private void verifyAlgorithm(String algorithmOid, MimeBodyPart msg)
297: throws Exception {
298: SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
299:
300: gen.addKeyTransRecipient(_reciCert);
301:
302: //
303: // generate a MimeBodyPart object which encapsulates the content
304: // we want encrypted.
305: //
306:
307: MimeBodyPart mp = gen.generate(msg, algorithmOid, "BC");
308: SMIMEEnveloped m = new SMIMEEnveloped(mp);
309: RecipientId recId = getRecipientId(_reciCert);
310:
311: RecipientInformationStore recipients = m.getRecipientInfos();
312: RecipientInformation recipient = recipients.get(recId);
313:
314: MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient
315: .getContent(_reciKP.getPrivate(), "BC"));
316:
317: verifyMessageBytes(msg, res);
318: }
319:
320: private void verifyParserAlgorithm(String algorithmOid,
321: MimeBodyPart msg) throws Exception {
322: SMIMEEnvelopedGenerator gen = new SMIMEEnvelopedGenerator();
323:
324: gen.addKeyTransRecipient(_reciCert);
325:
326: //
327: // generate a MimeBodyPart object which encapsulates the content
328: // we want encrypted.
329: //
330:
331: MimeBodyPart mp = gen.generate(msg, algorithmOid, "BC");
332: SMIMEEnvelopedParser m = new SMIMEEnvelopedParser(mp);
333: RecipientId recId = getRecipientId(_reciCert);
334:
335: RecipientInformationStore recipients = m.getRecipientInfos();
336: RecipientInformation recipient = recipients.get(recId);
337:
338: MimeBodyPart res = SMIMEUtil.toMimeBodyPart(recipient
339: .getContent(_reciKP.getPrivate(), "BC"));
340:
341: verifyMessageBytes(msg, res);
342: }
343:
344: private RecipientId getRecipientId(X509Certificate cert)
345: throws IOException, CertificateEncodingException {
346: RecipientId recId = new RecipientId();
347:
348: recId.setSerialNumber(cert.getSerialNumber());
349: recId.setIssuer(PrincipalUtil.getIssuerX509Principal(cert)
350: .getEncoded());
351: return recId;
352: }
353:
354: private void verifyMessageBytes(MimeBodyPart a, MimeBodyPart b)
355: throws IOException, MessagingException {
356: ByteArrayOutputStream _baos = new ByteArrayOutputStream();
357: a.writeTo(_baos);
358: _baos.close();
359: byte[] _msgBytes = _baos.toByteArray();
360: _baos = new ByteArrayOutputStream();
361: b.writeTo(_baos);
362: _baos.close();
363: byte[] _resBytes = _baos.toByteArray();
364:
365: assertEquals(true, Arrays.equals(_msgBytes, _resBytes));
366: }
367: }
|