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 }