001 // Copyright (C) 2002 IAIK
002 // https://jce.iaik.tugraz.at
003 //
004 // Copyright (C) 2003 - 2025 Stiftung Secure Information and
005 // Communication Technologies SIC
006 // https://sic.tech
007 //
008 // All rights reserved.
009 //
010 // Redistribution and use in source and binary forms, with or without
011 // modification, are permitted provided that the following conditions
012 // are met:
013 // 1. Redistributions of source code must retain the above copyright
014 // notice, this list of conditions and the following disclaimer.
015 // 2. Redistributions in binary form must reproduce the above copyright
016 // notice, this list of conditions and the following disclaimer in the
017 // documentation and/or other materials provided with the distribution.
018 //
019 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
020 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
021 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
022 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
023 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
024 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
025 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
026 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
027 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
028 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
029 // SUCH DAMAGE.
030
031 // Copyright (C) 2002 IAIK
032 // https://sic.tech/
033 //
034 // Copyright (C) 2003 - 2025 Stiftung Secure Information and
035 // Communication Technologies SIC
036 // https://sic.tech/
037 //
038 // All rights reserved.
039 //
040 // This source is provided for inspection purposes and recompilation only,
041 // unless specified differently in a contract with IAIK. This source has to
042 // be kept in strict confidence and must not be disclosed to any third party
043 // under any circumstances. Redistribution in source and binary forms, with
044 // or without modification, are <not> permitted in any case!
045 //
046 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
047 // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
048 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
049 // ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
050 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
051 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
052 // OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
053 // HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
054 // LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
055 // OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
056 // SUCH DAMAGE.
057 //
058 // $Header: /IAIK-CMS/current/src/demo/smime/basic/ProcessMessageDemo.java 20 12.02.25 17:58 Dbratko $
059 // $Revision: 20 $
060 //
061
062 package demo.smime.basic;
063
064 import iaik.asn1.structures.AlgorithmID;
065 import iaik.cms.CMSAlgorithmID;
066 import iaik.smime.CompressedContent;
067 import iaik.smime.EncryptedContent;
068 import iaik.smime.SMimeBodyPart;
069 import iaik.smime.SMimeMultipart;
070 import iaik.smime.SMimeParameters;
071 import iaik.smime.SignedContent;
072 import iaik.x509.X509Certificate;
073
074 import java.io.ByteArrayInputStream;
075 import java.io.ByteArrayOutputStream;
076 import java.io.IOException;
077 import java.security.NoSuchAlgorithmException;
078 import java.security.PrivateKey;
079 import java.security.interfaces.RSAPrivateKey;
080 import java.util.Date;
081
082 import javax.activation.DataHandler;
083 import javax.activation.FileDataSource;
084 import javax.mail.Message;
085 import javax.mail.MessagingException;
086 import javax.mail.Multipart;
087 import javax.mail.Session;
088 import javax.mail.internet.InternetAddress;
089 import javax.mail.internet.MimeBodyPart;
090 import javax.mail.internet.MimeMessage;
091
092 import demo.DemoSMimeUtil;
093 import demo.DemoUtil;
094 import demo.keystore.CMSKeyStore;
095 import demo.smime.DumpMessage;
096
097 /**
098 * This class demonstrates the usage of the IAIK S/MIME implementation for
099 * cryptographically processing (e.g. signing or encrypting) a received
100 * message. Since the message to be processed has a -- already canonicalized --
101 * multipart content, the SMimeMultipart/SMimeBodyPart control can be disabled
102 * either globally for the whole application:
103 * <pre>
104 * SMimeParameters.setCheckForSMimeParts(false);
105 * </pre>
106 * or only for the specific SignedContent object(s) in use:
107 * <pre>
108 * SignedContent sc = ...;
109 * sc.checkForSMimeParts(false);
110 * ...
111 * </pre>
112 * To run this demo the following packages are required:
113 * <ul>
114 * <li>
115 * <code>iaik_cms.jar</code> (IAIK-CMS/SMIME)
116 * </li>
117 * <li>
118 * <code>iaik_jce(_full).jar</code> (<a href="https://sic.tech/products/core-crypto-toolkits/jca-jce/" target="_blank">IAIK-JCE Core Crypto Library</a>).
119 * </li>
120 * <li>
121 * <code>mail.jar</code> (<a href="http://www.oracle.com/technetwork/java/javamail/index.html" target="_blank">JavaMail API</a>).
122 * </li>
123 * <li>
124 * <code>activation.jar</code> (<a href="http://www.oracle.com/technetwork/java/javase/downloads/index-135046.html" target="_blank">Java Activation Framework</a>; required for JDK versions < 1.6).
125 * </li>
126 * </ul>
127 */
128 public class ProcessMessageDemo {
129
130 // whether to print all generates test messages to System.out
131 final static boolean PRINT_MESSAGES = true;
132
133 String firstName = "John";
134 String lastName = "SMime";
135 String to = "smimetest@iaik.at"; // email recipient
136 String from = "smimetest@iaik.at"; // email sender
137 String host = "mailhost"; // name of the mailhost
138
139 X509Certificate[] signerCertificates; // list of certificates to include in the S/MIME message
140 X509Certificate recipientCertificate; // certificate of the recipient
141 X509Certificate signerCertificate; // certificate of the signer/sender
142 X509Certificate encryptionCertOfSigner; // signer uses different certificate for encryption
143 PrivateKey signerPrivateKey; // private key of the signer/sender
144
145 /**
146 * Default constructor. Reads certificates and keys from the demo keystore.
147 */
148 public ProcessMessageDemo() {
149
150 System.out.println();
151 System.out.println("******************************************************************************************");
152 System.out.println("* ProcessMessageDemo *");
153 System.out.println("* (shows how to cryptographically process (sign, verify) an existing message) *");
154 System.out.println("******************************************************************************************");
155 System.out.println();
156
157 // get the certificates from the KeyStore
158 signerCertificates = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1);
159 signerPrivateKey = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1);
160 signerCertificate = signerCertificates[0];
161
162 // recipient = signer for this test
163 recipientCertificate = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2)[0];
164 encryptionCertOfSigner = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1)[0];
165
166 // we will cryptographically process an already existing (canonicalized)
167 // message and therefore can disable SMimeMultipart/SMimeBodyPart control
168 SMimeParameters.setCheckForSMimeParts(false);
169 }
170
171 /**
172 * Starts the demo.
173 *
174 * @throws IOException if an I/O related error occurs
175 */
176 public void start() throws IOException {
177
178 // get the default Session
179 Session session = DemoSMimeUtil.getSession();
180
181 try {
182 // Create a demo Multipart
183 MimeBodyPart mbp1 = new SMimeBodyPart();
184 mbp1.setText("This is a Test of the IAIK S/MIME implementation!\n\n");
185 // attachment
186 MimeBodyPart attachment = new SMimeBodyPart();
187 attachment.setDataHandler(new DataHandler(new FileDataSource("test.html")));
188 attachment.setFileName("test.html");
189
190 Multipart mp = new SMimeMultipart();
191 mp.addBodyPart(mbp1);
192 mp.addBodyPart(attachment);
193 DataHandler multipart = new DataHandler(mp, mp.getContentType());
194
195 Message msg; // the message to send
196 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // we write to a stream
197 ByteArrayInputStream bais; // we read from a stream
198
199 // Create the plain test message
200 msg = createPlainMessage(session, multipart);
201 System.out.println("creating plain message...");
202 msg.saveChanges();
203 msg.writeTo(baos);
204 bais = new ByteArrayInputStream(baos.toByteArray());
205 msg = new MimeMessage(session, bais);
206 if (PRINT_MESSAGES) {
207 printMessage(msg);
208 }
209 DumpMessage.dumpMsg(msg);
210 // the plain message to be crytographically processed
211 MimeMessage plainMessage = (MimeMessage)msg;
212
213 System.out.println("\n\n*****************************************\n\n");
214
215 // include RFC822 headers of original message
216 boolean includeHeaders = true;
217 // This is an explicitly signed message
218 msg = createSignedMessage(session, plainMessage, false, includeHeaders);
219 System.out.println("creating explicitly signed message...");
220 baos.reset();
221 msg.saveChanges();
222 msg.writeTo(baos);
223 bais = new ByteArrayInputStream(baos.toByteArray());
224 msg = new MimeMessage(session, bais);
225 if (PRINT_MESSAGES) {
226 printMessage(msg);
227 }
228 DumpMessage.dumpMsg(msg);
229
230 System.out.println("\n\n*****************************************\n\n");
231
232 // This is an implicitly signed message
233 msg = createSignedMessage(session, plainMessage, true, includeHeaders);
234 System.out.println("creating implicitly signed message...");
235 baos.reset();
236 msg.saveChanges();
237 msg.writeTo(baos);
238 bais = new ByteArrayInputStream(baos.toByteArray());
239 msg = new MimeMessage(session, bais);
240 if (PRINT_MESSAGES) {
241 printMessage(msg);
242 }
243 DumpMessage.dumpMsg(msg);
244
245 System.out.println("\n\n*****************************************\n\n");
246
247 // Now create an encrypted message
248 msg = createEncryptedMessage(session,
249 plainMessage,
250 (AlgorithmID)AlgorithmID.aes256_CBC.clone(),
251 256,
252 includeHeaders);
253 System.out.println("creating encrypted message [AES]...");
254 baos.reset();
255 msg.saveChanges();
256 msg.writeTo(baos);
257 bais = new ByteArrayInputStream(baos.toByteArray());
258 msg = new MimeMessage(session, bais);
259 if (PRINT_MESSAGES) {
260 printMessage(msg);
261 }
262 DumpMessage.dumpMsg(msg);
263
264 System.out.println("\n\n*****************************************\n\n");
265
266 // Now create a implicitly signed and encrypted message with attachment
267 System.out.println("creating implicitly signed and encrypted message...");
268 msg = createSignedAndEncryptedMessage(session,
269 plainMessage,
270 true,
271 includeHeaders);
272
273 baos.reset();
274 msg.saveChanges();
275 msg.writeTo(baos);
276 bais = new ByteArrayInputStream(baos.toByteArray());
277 msg = new MimeMessage(session, bais);
278 if (PRINT_MESSAGES) {
279 printMessage(msg);
280 }
281 DumpMessage.dumpMsg(msg);
282
283 System.out.println("\n\n*****************************************\n\n");
284
285 // Now create a explicitly signed and encrypted message with attachment
286 System.out.println("creating explicitly signed and encrypted message ...");
287 msg = createSignedAndEncryptedMessage(session, plainMessage, false, includeHeaders);
288 baos.reset();
289 msg.saveChanges();
290 msg.writeTo(baos);
291 bais = new ByteArrayInputStream(baos.toByteArray());
292 msg = new MimeMessage(session, bais);
293 if (PRINT_MESSAGES) {
294 printMessage(msg);
295 }
296 DumpMessage.dumpMsg(msg);
297
298 System.out.println("\n\n*****************************************\n\n");
299
300 // compressed message
301 msg = createCompressedMessage(session,
302 plainMessage,
303 (AlgorithmID)CMSAlgorithmID.zlib_compress.clone(),
304 includeHeaders);
305 System.out.println("creating message with compressed data...");
306 baos.reset();
307 msg.saveChanges();
308 msg.writeTo(baos);
309 bais = new ByteArrayInputStream(baos.toByteArray());
310 msg = new MimeMessage(session, bais);
311 if (PRINT_MESSAGES) {
312 printMessage(msg);
313 }
314 DumpMessage.dumpMsg(msg);
315
316
317 // now the same again but do not include RFC822 headers of original message
318 includeHeaders = false;
319 // This is an explicitly signed message
320 msg = createSignedMessage(session, plainMessage, false, includeHeaders);
321 System.out.println("creating explicitly signed message...");
322 baos.reset();
323 msg.saveChanges();
324 msg.writeTo(baos);
325 bais = new ByteArrayInputStream(baos.toByteArray());
326 msg = new MimeMessage(session, bais);
327 if (PRINT_MESSAGES) {
328 printMessage(msg);
329 }
330 DumpMessage.dumpMsg(msg);
331
332 System.out.println("\n\n*****************************************\n\n");
333
334
335 // This is an implicitly signed message
336 msg = createSignedMessage(session, plainMessage, true, includeHeaders);
337 System.out.println("creating implicitly signed message...");
338 baos.reset();
339 msg.saveChanges();
340 msg.writeTo(baos);
341 bais = new ByteArrayInputStream(baos.toByteArray());
342 msg = new MimeMessage(session, bais);
343 if (PRINT_MESSAGES) {
344 printMessage(msg);
345 }
346 DumpMessage.dumpMsg(msg);
347
348 System.out.println("\n\n*****************************************\n\n");
349
350 // Now create an encrypted message
351 msg = createEncryptedMessage(session,
352 plainMessage,
353 (AlgorithmID)AlgorithmID.aes256_CBC.clone(),
354 256,
355 includeHeaders);
356 System.out.println("creating encrypted message [AES]...");
357 baos.reset();
358 msg.saveChanges();
359 msg.writeTo(baos);
360 bais = new ByteArrayInputStream(baos.toByteArray());
361 msg = new MimeMessage(session, bais);
362 if (PRINT_MESSAGES) {
363 printMessage(msg);
364 }
365 DumpMessage.dumpMsg(msg);
366
367 System.out.println("\n\n*****************************************\n\n");
368
369 // Now create a implicitly signed and encrypted message with attachment
370 System.out.println("creating implicitly signed and encrypted message ...");
371 msg = createSignedAndEncryptedMessage(session, plainMessage, true, includeHeaders);
372 baos.reset();
373 msg.saveChanges();
374 msg.writeTo(baos);
375 bais = new ByteArrayInputStream(baos.toByteArray());
376 msg = new MimeMessage(session, bais);
377 if (PRINT_MESSAGES) {
378 printMessage(msg);
379 }
380 DumpMessage.dumpMsg(msg);
381
382 System.out.println("\n\n*****************************************\n\n");
383
384 // Now create a explicitly signed and encrypted message with attachment
385 System.out.println("creating explicitly signed and encrypted message...");
386 msg = createSignedAndEncryptedMessage(session, plainMessage, false, includeHeaders);
387 baos.reset();
388 msg.saveChanges();
389 msg.writeTo(baos);
390 bais = new ByteArrayInputStream(baos.toByteArray());
391 msg = new MimeMessage(session, bais);
392 if (PRINT_MESSAGES) {
393 printMessage(msg);
394 }
395 DumpMessage.dumpMsg(msg);
396
397 System.out.println("\n\n*****************************************\n\n");
398
399 // compressed message
400 msg = createCompressedMessage(session,
401 plainMessage,
402 (AlgorithmID)CMSAlgorithmID.zlib_compress.clone(),
403 includeHeaders);
404 System.out.println("creating message with compressed data...");
405 baos.reset();
406 msg.saveChanges();
407 msg.writeTo(baos);
408 bais = new ByteArrayInputStream(baos.toByteArray());
409 msg = new MimeMessage(session, bais);
410 if (PRINT_MESSAGES) {
411 printMessage(msg);
412 }
413 DumpMessage.dumpMsg(msg);
414
415 } catch (Exception ex) {
416 ex.printStackTrace();
417 throw new RuntimeException(ex.toString());
418 }
419 }
420
421 /**
422 * Creates a MIME message container with the given subject for the given session.
423 *
424 * @param session the mail sesion
425 * @param subject the subject of the message
426 *
427 * @return the MIME message with FROM, TO, DATE and SUBJECT headers (without content)
428 *
429 * @throws MessagingException if the message cannot be created
430 */
431 public Message createMessage(Session session, String subject) throws MessagingException {
432 MimeMessage msg = new MimeMessage(session);
433 msg.setFrom(new InternetAddress(from));
434 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false));
435 msg.setSentDate(new Date());
436 msg.setSubject(subject);
437 return msg;
438 }
439
440 /**
441 * Creates a simple plain (neither signed nor encrypted) message.
442 *
443 * @param session the mail session
444 * @param dataHandler the content of the message
445 *
446 * @return the plain message
447 *
448 * @throws MessagingException if an error occurs when creating the message
449 */
450 public Message createPlainMessage(Session session, DataHandler dataHandler) throws MessagingException {
451
452 Message msg = createMessage(session, "IAIK-S/MIME: Plain message");
453 if (dataHandler != null) {
454 msg.setDataHandler(dataHandler);
455 } else {
456 msg.setText("This is a plain message!\nIt is wether signed nor encrypted!\n");
457 }
458 return msg;
459 }
460
461 /**
462 * Creates a signed and encrypted message.
463 *
464 * @param session the mail session
465 * @param message the message to be signed and encrypted
466 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit
467 * (multipart/signed) signing
468 * @param includeHeaders whether to inlcude the RFC822 headers of the original
469 * message
470 *
471 * @return the signed and encrypted message
472 *
473 * @throws MessagingException if an error occurs when creating the message
474 */
475 public Message createSignedAndEncryptedMessage(Session session,
476 MimeMessage message,
477 boolean implicit,
478 boolean includeHeaders)
479 throws MessagingException {
480
481 String subject = null;
482 String text = null;
483 if (implicit) {
484 subject = "IAIK-S/MIME: Implicitly Signed and Encrypted";
485 text = "This message is implicitly signed and encrypted!\n\n\n";
486 } else {
487 subject = "IAIK-S/MIME: Explicitly Signed and Encrypted";
488 text = "This message is explicitly signed and encrypted!\n\n\n";
489 }
490 Message msg = createMessage(session, subject);
491
492 SignedContent sc = new SignedContent(implicit);
493 // set the message content
494 if (includeHeaders) {
495 sc.setContent(message, message.getContentType());
496 } else {
497 sc.setDataHandler(message.getDataHandler());
498 }
499 sc.setCertificates(signerCertificates);
500 try {
501 sc.addSigner((RSAPrivateKey)signerPrivateKey, signerCertificate);
502 } catch (NoSuchAlgorithmException ex) {
503 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex);
504 }
505
506 EncryptedContent ec = new EncryptedContent(sc);
507 // encrypt for the recipient
508 ec.addRecipient(recipientCertificate, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
509 // I want to be able to decrypt the message, too
510 ec.addRecipient(encryptionCertOfSigner, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
511 // set the encryption algorithm
512 try {
513 ec.setEncryptionAlgorithm((AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256);
514 } catch (NoSuchAlgorithmException ex) {
515 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage());
516 }
517 msg.setContent(ec, ec.getContentType());
518 // let the EncryptedContent update some message headers
519 ec.setHeaders(msg);
520
521 return msg;
522 }
523
524 /**
525 * Creates a signed message.
526 *
527 * @param session the mail session
528 * @param message the message to be signed
529 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit
530 * (multipart/signed) signing
531 * @param includeHeaders whether to inlcude the RFC822 headers of the original
532 * message
533 *
534 * @return the signed message
535 *
536 * @throws MessagingException if an error occurs when creating the message
537 */
538 public Message createSignedMessage(Session session,
539 MimeMessage message,
540 boolean implicit,
541 boolean includeHeaders)
542 throws Exception {
543
544 String subject = null;
545
546 if (implicit) {
547 subject = "IAIK-S/MIME: Implicitly Signed";
548 } else {
549 subject = "IAIK-S/MIME: Explicitly Signed";
550 }
551
552 Message msg = createMessage(session, subject);
553
554 SignedContent sc = new SignedContent(implicit);
555 // set message content
556 if (includeHeaders) {
557 sc.setContent(message, message.getContentType());
558 } else {
559 sc.setDataHandler(message.getDataHandler());
560 }
561 sc.setCertificates(signerCertificates);
562
563 try {
564 sc.addSigner((RSAPrivateKey)signerPrivateKey, signerCertificate);
565 } catch (NoSuchAlgorithmException ex) {
566 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex);
567 }
568
569 msg.setContent(sc, sc.getContentType());
570 // let the SignedContent update some message headers
571 sc.setHeaders(msg);
572 return msg;
573 }
574
575 /**
576 * Creates an encrypted message.
577 *
578 * @param session the mail session
579 * @param message the message to be encrypted
580 * @param algorithm the content encryption algorithm to be used
581 * @param keyLength the length of the secret content encryption key to be created and used
582 * @param includeHeaders whether to inlcude the RFC822 headers of the original
583 * message
584 *
585 * @return the encrypted message
586 *
587 * @throws MessagingException if an error occurs when creating the message
588 */
589 public Message createEncryptedMessage(Session session,
590 MimeMessage message,
591 AlgorithmID algorithm,
592 int keyLength,
593 boolean includeHeaders)
594 throws MessagingException {
595
596 StringBuffer subject = new StringBuffer();
597 subject.append("IAIK-S/MIME: Encrypted ["+algorithm.getName());
598 if (keyLength > 0) {
599 subject.append("/"+keyLength);
600 }
601 subject.append("]");
602 Message msg = createMessage(session, subject.toString());
603
604 EncryptedContent ec = new EncryptedContent();
605 // set message content
606 if (includeHeaders) {
607 ec.setContent(message, message.getContentType());
608 } else {
609 ec.setDataHandler(message.getDataHandler());
610 }
611
612 // encrypt for the recipient
613 ec.addRecipient(recipientCertificate, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
614 // I want to be able to decrypt the message, too
615 ec.addRecipient(encryptionCertOfSigner, (AlgorithmID)AlgorithmID.rsaEncryption.clone());
616 try {
617 ec.setEncryptionAlgorithm(algorithm, keyLength);
618 } catch (NoSuchAlgorithmException ex) {
619 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage());
620 }
621
622 msg.setContent(ec, ec.getContentType());
623 // let the EncryptedContent update some message headers
624 ec.setHeaders(msg);
625
626 return msg;
627 }
628
629
630 /**
631 * Creates a compressed message.
632 *
633 * @param session the mail session
634 * @param message the message to be compressed
635 * @param algorithm the compression algorithm to be used
636 * @param includeHeaders whether to inlcude the RFC822 headers of the original
637 * message
638 *
639 * @return the compressed message
640 *
641 * @throws MessagingException if an error occurs when creating the message
642 */
643 public Message createCompressedMessage(Session session,
644 MimeMessage message,
645 AlgorithmID algorithm,
646 boolean includeHeaders)
647 throws MessagingException {
648
649 String subject = "IAIK-S/MIME: Compressed ["+algorithm.getName()+"]";
650 Message msg = createMessage(session, subject.toString());
651
652 CompressedContent compressedContent = new CompressedContent();
653 // set message content
654 if (includeHeaders) {
655 compressedContent.setContent(message, message.getContentType());
656 } else {
657 compressedContent.setDataHandler(message.getDataHandler());
658 }
659
660 try {
661 compressedContent.setCompressionAlgorithm(algorithm);
662 } catch (NoSuchAlgorithmException ex) {
663 throw new MessagingException("Compression algorithm not supported: " + ex.getMessage());
664 }
665
666 msg.setContent(compressedContent, compressedContent.getContentType());
667 // let the CompressedContent update some message headers
668 compressedContent.setHeaders(msg);
669
670 return msg;
671 }
672
673
674
675 /**
676 * Prints a dump of the given message to System.out.
677 *
678 * @param msg the message to be dumped to System.out
679 */
680 private static void printMessage(Message msg) throws IOException {
681 System.out.println("------------------------------------------------------------------");
682 System.out.println("Message dump: \n");
683 try {
684 msg.writeTo(System.out);
685 } catch (MessagingException ex) {
686 throw new IOException(ex.getMessage());
687 }
688 System.out.println("\n------------------------------------------------------------------");
689 }
690
691
692 /**
693 * The main method.
694 */
695 public static void main(String[] argv) throws IOException {
696
697 DemoSMimeUtil.initDemos();
698 (new ProcessMessageDemo()).start();
699 System.out.println("\nReady!");
700 DemoUtil.waitKey();
701 }
702 }