001// Copyright (C) 2002 IAIK 002// https://sic.tech/ 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// This source is provided for inspection purposes and recompilation only, 011// unless specified differently in a contract with IAIK. This source has to 012// be kept in strict confidence and must not be disclosed to any third party 013// under any circumstances. Redistribution in source and binary forms, with 014// or without modification, are <not> permitted in any case! 015// 016// THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 017// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 018// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 019// ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 020// FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 021// DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 022// OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 023// HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 024// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 025// OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 026// SUCH DAMAGE. 027// 028// $Header: /IAIK-CMS/current/src/demo/smime/basic/SMimeV4Demo.java 8 12.02.25 17:59 Dbratko $ 029// $Revision: 8 $ 030// 031 032package demo.smime.basic; 033 034import java.io.ByteArrayInputStream; 035import java.io.ByteArrayOutputStream; 036import java.io.IOException; 037import java.security.NoSuchAlgorithmException; 038import java.security.PrivateKey; 039import java.util.Date; 040 041import jakarta.activation.DataHandler; 042import jakarta.activation.FileDataSource; 043import jakarta.mail.Message; 044import jakarta.mail.MessagingException; 045import jakarta.mail.Multipart; 046import jakarta.mail.Session; 047import jakarta.mail.internet.InternetAddress; 048import jakarta.mail.internet.MimeBodyPart; 049import jakarta.mail.internet.MimeMessage; 050import jakarta.mail.internet.MimeMultipart; 051 052import demo.DemoSMimeUtil; 053import demo.DemoUtil; 054import demo.keystore.CMSKeyStore; 055import demo.smime.DumpMessage; 056import iaik.asn1.ObjectID; 057import iaik.asn1.structures.AlgorithmID; 058import iaik.asn1.structures.Name; 059import iaik.cms.CMSAlgorithmID; 060import iaik.pkcs.PKCSException; 061import iaik.pkcs.pkcs10.CertificateRequest; 062import iaik.smime.AuthEncryptedContent; 063import iaik.smime.CompressedContent; 064import iaik.smime.EncryptedContent; 065import iaik.smime.PKCS10Content; 066import iaik.smime.SMimeBodyPart; 067import iaik.smime.SMimeMultipart; 068import iaik.smime.SMimeParameters; 069import iaik.smime.SignedContent; 070import iaik.x509.X509Certificate; 071 072/** 073 * This class demonstrates the usage of the IAIK S/MIME implementation. It shows how to create 074 * signed and/or encrypted S/MIMEv4 messages and how to parse them and verify the signatures 075 * and decrypt the content, respectively. 076 * <p> 077 * To run this demo the following packages are required: 078 * <ul> 079 * <li> 080 * <code>iaik_cms.jar</code> (IAIK-CMS/SMIME) 081 * </li> 082 * <li> 083 * <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>). 084 * </li> 085 * <li> 086 * <a href="https://jakarta.ee/specifications/mail/" target="_blank">Jakarta</a>/<a href="https://eclipse-ee4j.github.io/angus-mail/" target="_blank">Angus</a> Mail 087 * </li> 088 * <li> 089 * <a href="https://jakarta.ee/specifications/activation/" target="_blank">Jakarta Activation Framework</a> 090 * </li> 091 * </ul> 092 * You also will need the IAIK-JCE library, <code>iaik_jce(_full).jar</code>. 093 * <p> 094 * This demo uses RSA both for signing an encryption. Look at the demos in package <code>demo.smime.ecc</code> for 095 * examples based on elliptic curve cryptography. 096 * 097 */ 098public class SMimeV4Demo { 099 100 // whether to print dump all generates test messages to System.out 101 final static boolean PRINT_MESSAGES = false; 102 103 104 String firstName_ = "John"; 105 String lastName_ = "SMime"; 106 String to_ = "smimetest@iaik.tugraz.at"; // email recipient 107 String from_ = "smimetest@iaik.tugraz.at"; // email sender 108 String host_ = "mailhost"; // name of the mailhost 109 110 X509Certificate[] signerCertificates_; // list of certificates to include in the S/MIME message 111 X509Certificate signerCertificate_; // certificate of the signer/sender 112 PrivateKey signerPrivateKey_; // private key of the signer/sender 113 114 X509Certificate senderCryptCertificate_; // the encryption certificate of the signer/sender 115 116 X509Certificate rsaRecipientCertificate_; // RSA encryption cert and key of a recipient 117 118 /** 119 * Default constructor. Reads certificates and keys from the demo keystore. 120 */ 121 public SMimeV4Demo() { 122 123 System.out.println(); 124 System.out.println("********************************************************************************************"); 125 System.out.println("* SMimeV4Demo demo *"); 126 System.out.println("* (shows how to create and parse (verify, decrypt) signed and encrypted S/MIMEv4 messages) *"); 127 System.out.println("********************************************************************************************"); 128 System.out.println(); 129 130 // get the certificates from the KeyStore 131 signerCertificates_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1); 132 signerPrivateKey_ = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1); 133 signerCertificate_ = signerCertificates_[0]; 134 senderCryptCertificate_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1)[0]; 135 136 rsaRecipientCertificate_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2)[0]; 137 138 } 139 140 /** 141 * Starts the demo. 142 * 143 * @throws IOException if an I/O related error occurs 144 */ 145 public void start() throws IOException { 146 147 // get the default Session 148 Session session = DemoSMimeUtil.getSession(); 149 150 try { 151 // Create a demo Multipart 152 MimeBodyPart mbp1 = new SMimeBodyPart(); 153 mbp1.setText("This is a Test of the IAIK S/MIME implementation!\n\n"); 154 // attachment 155 MimeBodyPart attachment = new SMimeBodyPart(); 156 attachment.setDataHandler(new DataHandler(new FileDataSource("test.html"))); 157 attachment.setFileName("test.html"); 158 159 Multipart mp = new SMimeMultipart(); 160 mp.addBodyPart(mbp1); 161 mp.addBodyPart(attachment); 162 DataHandler multipart = new DataHandler(mp, mp.getContentType()); 163 164 Message msg; // the message to send 165 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // we write to a stream 166 ByteArrayInputStream bais; // we read from a stream 167 168 // This is a plain message 169 msg = createPlainMessage(session, multipart); 170 System.out.println("creating plain message..."); 171 msg.saveChanges(); 172 msg.writeTo(baos); 173 bais = new ByteArrayInputStream(baos.toByteArray()); 174 msg = new MimeMessage(session, bais); 175 if (PRINT_MESSAGES) { 176 printMessage(msg); 177 } 178 DumpMessage.dumpMsg(msg); 179 180 System.out.println("\n\n*****************************************\n\n"); 181 182 // This is an explicitly signed message 183 msg = createSignedMessage(session, multipart, false, AlgorithmID.sha256, AlgorithmID.rsaEncryption); 184 System.out.println("creating explicitly signed message..."); 185 baos.reset(); 186 msg.saveChanges(); 187 msg.writeTo(baos); 188 bais = new ByteArrayInputStream(baos.toByteArray()); 189 msg = new MimeMessage(session, bais); 190 if (PRINT_MESSAGES) { 191 printMessage(msg); 192 } 193 DumpMessage.dumpMsg(msg); 194 195 System.out.println("\n\n*****************************************\n\n"); 196 197 198 // This is an implicitly signed message 199 msg = createSignedMessage(session, multipart, true, AlgorithmID.sha256, AlgorithmID.rsaEncryption); 200 System.out.println("creating implicitly signed message..."); 201 baos.reset(); 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 211 System.out.println("\n\n*****************************************\n\n"); 212 213 // Now create encrypted messages with different content encryption algorithms 214 215 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CBC.clone(), 128); 216 System.out.println("creating encrypted message [AES/128]..."); 217 baos.reset(); 218 msg.saveChanges(); 219 msg.writeTo(baos); 220 bais = new ByteArrayInputStream(baos.toByteArray()); 221 msg = new MimeMessage(session, bais); 222 if (PRINT_MESSAGES) { 223 printMessage(msg); 224 } 225 DumpMessage.dumpEncryptedMessage(msg); 226 227 System.out.println("\n\n*****************************************\n\n"); 228 229 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CBC.clone(), 192); 230 System.out.println("creating encrypted message [AES/192]..."); 231 baos.reset(); 232 msg.saveChanges(); 233 msg.writeTo(baos); 234 bais = new ByteArrayInputStream(baos.toByteArray()); 235 msg = new MimeMessage(session, bais); 236 if (PRINT_MESSAGES) { 237 printMessage(msg); 238 } 239 DumpMessage.dumpEncryptedMessage(msg); 240 241 System.out.println("\n\n*****************************************\n\n"); 242 243 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256); 244 System.out.println("creating encrypted message [AES/256]..."); 245 baos.reset(); 246 msg.saveChanges(); 247 msg.writeTo(baos); 248 bais = new ByteArrayInputStream(baos.toByteArray()); 249 msg = new MimeMessage(session, bais); 250 if (PRINT_MESSAGES) { 251 printMessage(msg); 252 } 253 DumpMessage.dumpEncryptedMessage(msg); 254 255 System.out.println("\n\n*****************************************\n\n"); 256 257 // Now create an implicitly signed and encrypted message with attachment 258 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CBC.clone(), 128, multipart, true, false); 259 System.out.println("creating implicitly signed and encrypted message [AES/128]..."); 260 baos.reset(); 261 msg.saveChanges(); 262 msg.writeTo(baos); 263 bais = new ByteArrayInputStream(baos.toByteArray()); 264 msg = new MimeMessage(session, bais); 265 if (PRINT_MESSAGES) { 266 printMessage(msg); 267 } 268 DumpMessage.dumpEncryptedMessage(msg); 269 270 System.out.println("\n\n*****************************************\n\n"); 271 272 // Now create an implicitly signed and encrypted message with attachment 273 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CBC.clone(), 192, multipart, true, false); 274 System.out.println("creating implicitly signed and encrypted message [AES/192]..."); 275 baos.reset(); 276 msg.saveChanges(); 277 msg.writeTo(baos); 278 bais = new ByteArrayInputStream(baos.toByteArray()); 279 msg = new MimeMessage(session, bais); 280 if (PRINT_MESSAGES) { 281 printMessage(msg); 282 } 283 DumpMessage.dumpEncryptedMessage(msg); 284 285 System.out.println("\n\n*****************************************\n\n"); 286 287 // Now create an explicitly signed and encrypted message with attachment 288 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CBC.clone(), 192, multipart, false, false);; 289 System.out.println("creating explicitly signed and encrypted message [AES/192]..."); 290 baos.reset(); 291 msg.saveChanges(); 292 msg.writeTo(baos); 293 bais = new ByteArrayInputStream(baos.toByteArray()); 294 msg = new MimeMessage(session, bais); 295 if (PRINT_MESSAGES) { 296 printMessage(msg); 297 } 298 DumpMessage.dumpEncryptedMessage(msg); 299 300 System.out.println("\n\n*****************************************\n\n"); 301 302 // Now create an implicitly signed and encrypted message with attachment 303 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256, multipart, true, false); 304 System.out.println("creating implicitly signed and encrypted message [AES/256]..."); 305 baos.reset(); 306 msg.saveChanges(); 307 msg.writeTo(baos); 308 bais = new ByteArrayInputStream(baos.toByteArray()); 309 msg = new MimeMessage(session, bais); 310 if (PRINT_MESSAGES) { 311 printMessage(msg); 312 } 313 DumpMessage.dumpEncryptedMessage(msg); 314 315 System.out.println("\n\n*****************************************\n\n"); 316 317 // Now create an explicitly signed and encrypted message with attachment 318 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256, multipart, false, false);; 319 System.out.println("creating explicitly signed and encrypted message [AES/256]..."); 320 baos.reset(); 321 msg.saveChanges(); 322 msg.writeTo(baos); 323 bais = new ByteArrayInputStream(baos.toByteArray()); 324 msg = new MimeMessage(session, bais); 325 if (PRINT_MESSAGES) { 326 printMessage(msg); 327 } 328 DumpMessage.dumpEncryptedMessage(msg); 329 330 System.out.println("\n\n*****************************************\n\n"); 331 332 // Now create authenticated encrypted messages with different content encryption algorithms 333 if (DemoUtil.getIaikProviderVersion() >= 5.62) { 334 335 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_GCM.clone(), 128); 336 System.out.println("creating authenticated encrypted message [AES-GCM/128]..."); 337 baos.reset(); 338 msg.saveChanges(); 339 msg.writeTo(baos); 340 bais = new ByteArrayInputStream(baos.toByteArray()); 341 msg = new MimeMessage(session, bais); 342 if (PRINT_MESSAGES) { 343 printMessage(msg); 344 } 345 DumpMessage.dumpEncryptedMessage(msg); 346 347 System.out.println("\n\n*****************************************\n\n"); 348 349 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_GCM.clone(), 192); 350 System.out.println("creating authenticated encrypted message [AES-GCM/192]..."); 351 baos.reset(); 352 msg.saveChanges(); 353 msg.writeTo(baos); 354 bais = new ByteArrayInputStream(baos.toByteArray()); 355 msg = new MimeMessage(session, bais); 356 if (PRINT_MESSAGES) { 357 printMessage(msg); 358 } 359 DumpMessage.dumpEncryptedMessage(msg); 360 361 System.out.println("\n\n*****************************************\n\n"); 362 363 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256); 364 System.out.println("creating authenticated encrypted message [AES-GCM/256]..."); 365 baos.reset(); 366 msg.saveChanges(); 367 msg.writeTo(baos); 368 bais = new ByteArrayInputStream(baos.toByteArray()); 369 msg = new MimeMessage(session, bais); 370 if (PRINT_MESSAGES) { 371 printMessage(msg); 372 } 373 DumpMessage.dumpEncryptedMessage(msg); 374 375 System.out.println("\n\n*****************************************\n\n"); 376 377 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CCM.clone(), 128); 378 System.out.println("creating authenticated encrypted message [AES-CCM/128]..."); 379 baos.reset(); 380 msg.saveChanges(); 381 msg.writeTo(baos); 382 bais = new ByteArrayInputStream(baos.toByteArray()); 383 msg = new MimeMessage(session, bais); 384 if (PRINT_MESSAGES) { 385 printMessage(msg); 386 } 387 DumpMessage.dumpEncryptedMessage(msg); 388 389 System.out.println("\n\n*****************************************\n\n"); 390 391 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CCM.clone(), 192); 392 System.out.println("creating authenticated encrypted message [AES-CCM/192]..."); 393 baos.reset(); 394 msg.saveChanges(); 395 msg.writeTo(baos); 396 bais = new ByteArrayInputStream(baos.toByteArray()); 397 msg = new MimeMessage(session, bais); 398 if (PRINT_MESSAGES) { 399 printMessage(msg); 400 } 401 DumpMessage.dumpEncryptedMessage(msg); 402 403 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), 256); 404 System.out.println("creating authenticated encrypted message [AES-CCM/256]..."); 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.dumpEncryptedMessage(msg); 414 415 System.out.println("\n\n*****************************************\n\n"); 416 417 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256); 418 System.out.println("creating authenticated encrypted message [ChaChaPoly1305]..."); 419 baos.reset(); 420 msg.saveChanges(); 421 msg.writeTo(baos); 422 bais = new ByteArrayInputStream(baos.toByteArray()); 423 msg = new MimeMessage(session, bais); 424 if (PRINT_MESSAGES) { 425 printMessage(msg); 426 } 427 DumpMessage.dumpEncryptedMessage(msg); 428 429 System.out.println("\n\n*****************************************\n\n"); 430 431 // Create an implicitly signed and authenticated encrypted message with attachment 432 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_GCM.clone(), 128, multipart, true, true); 433 System.out.println("creating implicitly signed and authenticated encrypted message [AES-GCM/128]..."); 434 baos.reset(); 435 msg.saveChanges(); 436 msg.writeTo(baos); 437 bais = new ByteArrayInputStream(baos.toByteArray()); 438 msg = new MimeMessage(session, bais); 439 if (PRINT_MESSAGES) { 440 printMessage(msg); 441 } 442 DumpMessage.dumpEncryptedMessage(msg); 443 444 System.out.println("\n\n*****************************************\n\n"); 445 446 // Create an explicitly signed and authenticated encrypted message with attachment 447 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_GCM.clone(), 128, multipart, true, true); 448 System.out.println("creating explicitly signed and authenticated encrypted message [AES-GCM/128]..."); 449 baos.reset(); 450 msg.saveChanges(); 451 msg.writeTo(baos); 452 bais = new ByteArrayInputStream(baos.toByteArray()); 453 msg = new MimeMessage(session, bais); 454 if (PRINT_MESSAGES) { 455 printMessage(msg); 456 } 457 DumpMessage.dumpEncryptedMessage(msg); 458 459 System.out.println("\n\n*****************************************\n\n"); 460 461 // Create an implicitly signed and authenticated encrypted message with attachment 462 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_GCM.clone(), 192, multipart, true, true); 463 System.out.println("creating implicitly signed and authenticated encrypted message [AES-GCM/192]..."); 464 baos.reset(); 465 msg.saveChanges(); 466 msg.writeTo(baos); 467 bais = new ByteArrayInputStream(baos.toByteArray()); 468 msg = new MimeMessage(session, bais); 469 if (PRINT_MESSAGES) { 470 printMessage(msg); 471 } 472 DumpMessage.dumpEncryptedMessage(msg); 473 474 System.out.println("\n\n*****************************************\n\n"); 475 476 // Create an explicitly signed and authenticated encrypted message with attachment 477 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_GCM.clone(), 192, multipart, true, true); 478 System.out.println("creating explicitly signed and authenticated encrypted message [AES-GCM/192]..."); 479 baos.reset(); 480 msg.saveChanges(); 481 msg.writeTo(baos); 482 bais = new ByteArrayInputStream(baos.toByteArray()); 483 msg = new MimeMessage(session, bais); 484 if (PRINT_MESSAGES) { 485 printMessage(msg); 486 } 487 DumpMessage.dumpEncryptedMessage(msg); 488 489 System.out.println("\n\n*****************************************\n\n"); 490 491 // Create an implicitly signed and authenticated encrypted message with attachment 492 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256, multipart, true, true); 493 System.out.println("creating implicitly signed and authenticated encrypted message [AES-GCM/256]..."); 494 baos.reset(); 495 msg.saveChanges(); 496 msg.writeTo(baos); 497 bais = new ByteArrayInputStream(baos.toByteArray()); 498 msg = new MimeMessage(session, bais); 499 if (PRINT_MESSAGES) { 500 printMessage(msg); 501 } 502 DumpMessage.dumpEncryptedMessage(msg); 503 504 System.out.println("\n\n*****************************************\n\n"); 505 506 // Create an explicitly signed and authenticated encrypted message with attachment 507 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256, multipart, true, true); 508 System.out.println("creating explicitly signed and authenticated encrypted message [AES-GCM/256]..."); 509 baos.reset(); 510 msg.saveChanges(); 511 msg.writeTo(baos); 512 bais = new ByteArrayInputStream(baos.toByteArray()); 513 msg = new MimeMessage(session, bais); 514 if (PRINT_MESSAGES) { 515 printMessage(msg); 516 } 517 DumpMessage.dumpEncryptedMessage(msg); 518 519 System.out.println("\n\n*****************************************\n\n"); 520 521 522 // Create an implicitly signed and authenticated encrypted message with attachment 523 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CCM.clone(), 128, multipart, true, true); 524 System.out.println("creating implicitly signed and authenticated encrypted message [AES-CCM/128]..."); 525 baos.reset(); 526 msg.saveChanges(); 527 msg.writeTo(baos); 528 bais = new ByteArrayInputStream(baos.toByteArray()); 529 msg = new MimeMessage(session, bais); 530 if (PRINT_MESSAGES) { 531 printMessage(msg); 532 } 533 DumpMessage.dumpEncryptedMessage(msg); 534 535 System.out.println("\n\n*****************************************\n\n"); 536 537 // Create an explicitly signed and authenticated encrypted message with attachment 538 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CCM.clone(), 128, multipart, true, true); 539 System.out.println("creating explicitly signed and authenticated encrypted message [AES-CCM/128]..."); 540 baos.reset(); 541 msg.saveChanges(); 542 msg.writeTo(baos); 543 bais = new ByteArrayInputStream(baos.toByteArray()); 544 msg = new MimeMessage(session, bais); 545 if (PRINT_MESSAGES) { 546 printMessage(msg); 547 } 548 DumpMessage.dumpEncryptedMessage(msg); 549 550 System.out.println("\n\n*****************************************\n\n"); 551 552 // Create an implicitly signed and authenticated encrypted message with attachment 553 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CCM.clone(), 192, multipart, true, true); 554 System.out.println("creating implicitly signed and authenticated encrypted message [AES-CCM/192]..."); 555 baos.reset(); 556 msg.saveChanges(); 557 msg.writeTo(baos); 558 bais = new ByteArrayInputStream(baos.toByteArray()); 559 msg = new MimeMessage(session, bais); 560 if (PRINT_MESSAGES) { 561 printMessage(msg); 562 } 563 DumpMessage.dumpEncryptedMessage(msg); 564 565 System.out.println("\n\n*****************************************\n\n"); 566 567 // Create an explicitly signed and authenticated encrypted message with attachment 568 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CCM.clone(), 192, multipart, true, true); 569 System.out.println("creating explicitly signed and authenticated encrypted message [AES-CCM/192]..."); 570 baos.reset(); 571 msg.saveChanges(); 572 msg.writeTo(baos); 573 bais = new ByteArrayInputStream(baos.toByteArray()); 574 msg = new MimeMessage(session, bais); 575 if (PRINT_MESSAGES) { 576 printMessage(msg); 577 } 578 DumpMessage.dumpEncryptedMessage(msg); 579 580 System.out.println("\n\n*****************************************\n\n"); 581 582 // Create an implicitly signed and authenticated encrypted message with attachment 583 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), 256, multipart, true, true); 584 System.out.println("creating implicitly signed and authenticated encrypted message [AES-CCM/256]..."); 585 baos.reset(); 586 msg.saveChanges(); 587 msg.writeTo(baos); 588 bais = new ByteArrayInputStream(baos.toByteArray()); 589 msg = new MimeMessage(session, bais); 590 if (PRINT_MESSAGES) { 591 printMessage(msg); 592 } 593 DumpMessage.dumpEncryptedMessage(msg); 594 595 System.out.println("\n\n*****************************************\n\n"); 596 597 // Create an explicitly signed and authenticated encrypted message with attachment 598 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), 256, multipart, true, true); 599 System.out.println("creating explicitly signed and authenticated encrypted message [AES-CCM/256]..."); 600 baos.reset(); 601 msg.saveChanges(); 602 msg.writeTo(baos); 603 bais = new ByteArrayInputStream(baos.toByteArray()); 604 msg = new MimeMessage(session, bais); 605 if (PRINT_MESSAGES) { 606 printMessage(msg); 607 } 608 DumpMessage.dumpEncryptedMessage(msg); 609 610 System.out.println("\n\n*****************************************\n\n"); 611 612 // Create an implicitly signed and authenticated encrypted message with attachment 613 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256, multipart, true, true); 614 System.out.println("creating implicitly signed and authenticated encrypted message [ChaCha20Poly1305]..."); 615 baos.reset(); 616 msg.saveChanges(); 617 msg.writeTo(baos); 618 bais = new ByteArrayInputStream(baos.toByteArray()); 619 msg = new MimeMessage(session, bais); 620 if (PRINT_MESSAGES) { 621 printMessage(msg); 622 } 623 DumpMessage.dumpEncryptedMessage(msg); 624 625 System.out.println("\n\n*****************************************\n\n"); 626 627 // Create an explicitly signed and authenticated encrypted message with attachment 628 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256, multipart, true, true); 629 System.out.println("creating explicitly signed and authenticated encrypted message [ChaCha20Poly1305]..."); 630 baos.reset(); 631 msg.saveChanges(); 632 msg.writeTo(baos); 633 bais = new ByteArrayInputStream(baos.toByteArray()); 634 msg = new MimeMessage(session, bais); 635 if (PRINT_MESSAGES) { 636 printMessage(msg); 637 } 638 DumpMessage.dumpEncryptedMessage(msg); 639 640 System.out.println("\n\n*****************************************\n\n"); 641 642 } 643 644 // certs only message 645 msg = createCertsOnlyMessage(session); 646 System.out.println("creating certs-only message"); 647 baos.reset(); 648 msg.saveChanges(); 649 msg.writeTo(baos); 650 bais = new ByteArrayInputStream(baos.toByteArray()); 651 msg = new MimeMessage(session, bais); 652 if (PRINT_MESSAGES) { 653 printMessage(msg); 654 } 655 DumpMessage.dumpMsg(msg); 656 657 System.out.println("\n\n*****************************************\n\n"); 658 659 // second certs only message 660 msg = createCertsOnlyMultiPartMessage(session); 661 System.out.println("creating message with certs-only part"); 662 baos.reset(); 663 msg.saveChanges(); 664 msg.writeTo(baos); 665 bais = new ByteArrayInputStream(baos.toByteArray()); 666 msg = new MimeMessage(session, bais); 667 if (PRINT_MESSAGES) { 668 printMessage(msg); 669 } 670 DumpMessage.dumpMsg(msg); 671 672 System.out.println("\n\n*****************************************\n\n"); 673 674 // application/pkcs10 cert request message 675 msg = createPKCS10Message(session); 676 System.out.println("creating application/pkcs10 message..."); 677 baos.reset(); 678 msg.saveChanges(); 679 msg.writeTo(baos); 680 bais = new ByteArrayInputStream(baos.toByteArray()); 681 msg = new MimeMessage(session, bais); 682 if (PRINT_MESSAGES) { 683 printMessage(msg); 684 } 685 DumpMessage.dumpMsg(msg); 686 687 System.out.println("\n\n*****************************************\n\n"); 688 689 // sending application/pkcs10 message where the request is in the second part 690 msg = createPKCS10MultiPartMessage(session); 691 System.out.println("creating message with pkcs10 part..."); 692 baos.reset(); 693 msg.saveChanges(); 694 msg.writeTo(baos); 695 bais = new ByteArrayInputStream(baos.toByteArray()); 696 msg = new MimeMessage(session, bais); 697 if (PRINT_MESSAGES) { 698 printMessage(msg); 699 } 700 DumpMessage.dumpMsg(msg); 701 702 System.out.println("\n\n*****************************************\n\n"); 703 704 // compressed message 705 msg = createCompressedMessage(session, multipart, (AlgorithmID)CMSAlgorithmID.zlib_compress.clone()); 706 System.out.println("creating message with compressed data..."); 707 baos.reset(); 708 msg.saveChanges(); 709 msg.writeTo(baos); 710 bais = new ByteArrayInputStream(baos.toByteArray()); 711 msg = new MimeMessage(session, bais); 712 if (PRINT_MESSAGES) { 713 printMessage(msg); 714 } 715 DumpMessage.dumpMsg(msg); 716 717 } catch (Exception ex) { 718 ex.printStackTrace(); 719 throw new RuntimeException(ex.toString()); 720 } 721 } 722 723 /** 724 * Creates a MIME message container with the given subject for the given session. 725 * 726 * @param session the mail sesion 727 * @param subject the subject of the message 728 * 729 * @return the MIME message with FROM, TO, DATE and SUBJECT headers (without content) 730 * 731 * @throws MessagingException if the message cannot be created 732 */ 733 public Message createMessage(Session session, String subject) throws MessagingException { 734 MimeMessage msg = new MimeMessage(session); 735 msg.setFrom(new InternetAddress(from_)); 736 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to_, false)); 737 msg.setSentDate(new Date()); 738 msg.setSubject(subject); 739 return msg; 740 } 741 742 /** 743 * Creates a simple plain (neither signed nor encrypted) message. 744 * 745 * @param session the mail session 746 * @param dataHandler the content of the message 747 * 748 * @return the plain message 749 * 750 * @throws MessagingException if an error occurs when creating the message 751 */ 752 public Message createPlainMessage(Session session, DataHandler dataHandler) throws MessagingException { 753 754 Message msg = createMessage(session, "IAIK-S/MIME: Plain message"); 755 if (dataHandler != null) { 756 msg.setDataHandler(dataHandler); 757 } else { 758 msg.setText("This is a plain message!\nIt is wether signed nor encrypted!\n"); 759 } 760 return msg; 761 } 762 763 /** 764 * Creates a signed and encrypted message. 765 * 766 * @param session the mail session 767 * @param contentEA the content encryption algorithm to be used 768 * @param keyLength the length of the secret content encryption key to be created and used 769 * @param dataHandler the content of the message to be signed and encrypted 770 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 771 * (multipart/signed) signing 772 * @param authEncrypt whether to create an authenticated encrypted message 773 * 774 * @return the signed and encrypted message 775 * 776 * @throws MessagingException if an error occurs when creating the message 777 */ 778 public Message createSignedAndEncryptedMessage(Session session, 779 AlgorithmID contentEA, int keyLength, 780 DataHandler dataHandler, boolean implicit, boolean authEncrypt) 781 throws MessagingException { 782 783 String subject = null; 784 String text = null; 785 if (implicit) { 786 subject = "IAIK-S/MIME: Implicitly signed and " + (authEncrypt ? "authenticated " : "") + "encrypted"; 787 text = "This message is implicitly signed and " + (authEncrypt ? "authenticated " : "") + "encrypted!\n\n\n"; 788 } else { 789 subject = "IAIK-S/MIME: explicitly signed and " + (authEncrypt ? "authenticated " : "") + " encrypted"; 790 text = "This message is explicitly signed and " + (authEncrypt ? "authenticated " : "") + " encrypted!\n\n\n"; 791 } 792 Message msg = createMessage(session, subject); 793 794 SignedContent sc = new SignedContent(implicit); 795 if (dataHandler != null) { 796 sc.setDataHandler(dataHandler); 797 } else { 798 sc.setText(text); 799 } 800 sc.setCertificates(signerCertificates_); 801 try { 802 sc.addSigner(signerPrivateKey_, 803 signerCertificate_, 804 (AlgorithmID)AlgorithmID.sha256.clone(), 805 (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 806 } catch (NoSuchAlgorithmException ex) { 807 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 808 } 809 810 EncryptedContent ec = null; 811 if (authEncrypt) { 812 ec = new AuthEncryptedContent(sc); 813 } else { 814 ec = new EncryptedContent(sc); 815 } 816 817 818 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 819 820 // sender wants to be able to decrypt the message 821 ec.addRecipient(senderCryptCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 822 823 // add RSA recipient 824 ec.addRecipient(rsaRecipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 825 // set the encryption algorithm 826 try { 827 ec.setEncryptionAlgorithm(algorithm, keyLength); 828 } catch (NoSuchAlgorithmException ex) { 829 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 830 } 831 msg.setContent(ec, ec.getContentType()); 832 // let the EncryptedContent update some message headers 833 ec.setHeaders(msg); 834 835 return msg; 836 } 837 838 /** 839 * Creates a signed message. 840 * 841 * @param session the mail session 842 * @param dataHandler the content of the message to be signed 843 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 844 * (multipart/signed) signing 845 * @param digestAlgorithm the digest algorithm to be used 846 * @param signatureAlgorithm the signature algorithm to be used 847 * 848 * @return the signed message 849 * 850 * @throws MessagingException if an error occurs when creating the message 851 */ 852 public Message createSignedMessage(Session session, 853 DataHandler dataHandler, 854 boolean implicit, 855 AlgorithmID digestAlgorithm, 856 AlgorithmID signatureAlgorithm) 857 throws MessagingException { 858 859 String subject = null; 860 StringBuffer buf = new StringBuffer(); 861 862 if (implicit) { 863 subject = "IAIK-S/MIME: Implicitly Signed"; 864 buf.append("This message is implicitly signed!\n"); 865 buf.append("You need an S/MIME aware mail client to view this message.\n"); 866 buf.append("\n\n"); 867 } else { 868 subject = "IAIK-S/MIME: Explicitly Signed"; 869 buf.append("This message is explicitly signed!\n"); 870 buf.append("Every mail client can view this message.\n"); 871 buf.append("Non S/MIME mail clients will show the signature as attachment.\n"); 872 buf.append("\n\n"); 873 } 874 875 Message msg = createMessage(session, subject); 876 877 SignedContent sc = new SignedContent(implicit); 878 if (dataHandler != null) { 879 sc.setDataHandler(dataHandler); 880 } else { 881 sc.setText(buf.toString()); 882 } 883 sc.setCertificates(signerCertificates_); 884 885 try { 886 sc.addSigner(signerPrivateKey_, 887 signerCertificate_, 888 (AlgorithmID)digestAlgorithm.clone(), 889 (AlgorithmID)signatureAlgorithm.clone()); 890 } catch (NoSuchAlgorithmException ex) { 891 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 892 } 893 894 msg.setContent(sc, sc.getContentType()); 895 // let the SignedContent update some message headers 896 sc.setHeaders(msg); 897 return msg; 898 } 899 900 /** 901 * Creates an encrypted message. 902 * 903 * @param session the mail session 904 * @param contentEA the content encryption algorithm to be used 905 * @param keyLength the length of the secret content encryption key to be created and used 906 * 907 * @return the encrypted message 908 * 909 * @throws MessagingException if an error occurs when creating the message 910 */ 911 public Message createEncryptedMessage(Session session, AlgorithmID contentEA, int keyLength) 912 throws MessagingException { 913 914 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 915 916 StringBuffer subject = new StringBuffer(); 917 subject.append("IAIK-S/MIME: Encrypted ["+algorithm.getName()); 918 if (keyLength > 0) { 919 subject.append("/"+keyLength); 920 } 921 subject.append("]"); 922 Message msg = createMessage(session, subject.toString()); 923 924 EncryptedContent ec = new EncryptedContent(); 925 926 StringBuffer buf = new StringBuffer(); 927 buf.append("This is the encrypted content!\n"); 928 buf.append("Content encryption algorithm: "+algorithm.getName()); 929 buf.append("\n\n"); 930 931 ec.setText(buf.toString()); 932 933 // sender wants to be able to decrypt the message 934 ec.addRecipient(senderCryptCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 935 936 // add RSA recipient 937 ec.addRecipient(rsaRecipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 938 try { 939 ec.setEncryptionAlgorithm(algorithm, keyLength); 940 } catch (NoSuchAlgorithmException ex) { 941 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 942 } 943 944 msg.setContent(ec, ec.getContentType()); 945 // let the EncryptedContent update some message headers 946 ec.setHeaders(msg); 947 948 return msg; 949 } 950 951 /** 952 * Creates an authenticated encrypted message. 953 * 954 * @param session the mail session 955 * @param contentEA the content encryption algorithm to be used 956 * @param keyLength the length of the secret content encryption key to be created and used 957 * 958 * @return the encrypted message 959 * 960 * @throws MessagingException if an error occurs when creating the message 961 */ 962 public Message createAuthEncryptedMessage(Session session, AlgorithmID contentEA, int keyLength) 963 throws MessagingException { 964 965 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 966 967 StringBuffer subject = new StringBuffer(); 968 subject.append("IAIK-S/MIME: Authenticated Encrypted ["+algorithm.getName()); 969 if (keyLength > 0) { 970 subject.append("/"+keyLength); 971 } 972 subject.append("]"); 973 Message msg = createMessage(session, subject.toString()); 974 975 AuthEncryptedContent ec = new AuthEncryptedContent(); 976 977 StringBuffer buf = new StringBuffer(); 978 buf.append("This is the authenticated encrypted content!\n"); 979 buf.append("Content encryption algorithm: "+algorithm.getName()); 980 buf.append("\n\n"); 981 982 ec.setText(buf.toString()); 983 984 // sender wants to be able to decrypt the message 985 ec.addRecipient(senderCryptCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 986 987 // add RSA recipient 988 ec.addRecipient(rsaRecipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 989 try { 990 ec.setEncryptionAlgorithm(algorithm, keyLength); 991 } catch (NoSuchAlgorithmException ex) { 992 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 993 } 994 995 msg.setContent(ec, ec.getContentType()); 996 // let the EncryptedContent update some message headers 997 ec.setHeaders(msg); 998 999 return msg; 1000 } 1001 1002 /** 1003 * Creates a certs-only message. 1004 * 1005 * @param session the mail session 1006 * 1007 * @return the certs-only message 1008 * 1009 * @throws MessagingException if an error occurs when creating the message 1010 */ 1011 public Message createCertsOnlyMessage(Session session) 1012 throws MessagingException { 1013 1014 Message msg = createMessage(session, "IAIK S/MIME: Certs-only message"); 1015 //use new content types 1016 SMimeParameters.useNewContentTypes(true); 1017 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 1018 sc.setCertificates(signerCertificates_); 1019 msg.setContent(sc, sc.getContentType()); 1020 //set filename and attachment parameters 1021 sc.setHeaders(msg); 1022 1023 return msg; 1024 } 1025 1026 1027 /** 1028 * Creates a certs-only message where the certificate list is transferred as attachment. 1029 * 1030 * @param session the mail session 1031 * 1032 * @return the certs-only message 1033 * 1034 * @throws MessagingException if an error occurs when creating the message 1035 */ 1036 public Message createCertsOnlyMultiPartMessage(Session session) throws MessagingException { 1037 1038 MimeBodyPart mbp1 = new MimeBodyPart(); 1039 mbp1.setText("This is a test where the certs-only message is included in the second part!\n\n"); 1040 1041 MimeBodyPart attachment = new MimeBodyPart(); 1042 //use new content types 1043 SMimeParameters.useNewContentTypes(true); 1044 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 1045 sc.setCertificates(signerCertificates_); 1046 attachment.setContent(sc, sc.getContentType()); 1047 // let the SignedContent update some headers 1048 sc.setHeaders(attachment); 1049 Multipart mp = new MimeMultipart(); 1050 mp.addBodyPart(mbp1); 1051 mp.addBodyPart(attachment); 1052 1053 Message msg = createMessage(session, "IAIK S/MIME: Certs-only multipart message"); 1054 msg.setContent(mp, mp.getContentType()); 1055 return msg; 1056 } 1057 1058 /** 1059 * Creates a compressed message. 1060 * 1061 * @param session the mail session 1062 * @param dataHandler the datahandler supplying the content to be compressed 1063 * @param algorithm the compression algorithm to be used 1064 * 1065 * @return the compressed message 1066 * 1067 * @throws MessagingException if an error occurs when creating the message 1068 */ 1069 public Message createCompressedMessage(Session session, DataHandler dataHandler, AlgorithmID algorithm) 1070 throws MessagingException { 1071 1072 String subject = "IAIK-S/MIME: Compressed ["+algorithm.getName()+"]"; 1073 Message msg = createMessage(session, subject.toString()); 1074 1075 CompressedContent compressedContent = new CompressedContent(); 1076 1077 if (dataHandler == null) { 1078 StringBuffer buf = new StringBuffer(); 1079 buf.append("This is the compressed content!\n"); 1080 buf.append("Compression algorithm: "+algorithm.getName()); 1081 buf.append("\n\n"); 1082 compressedContent.setText(buf.toString()); 1083 } else { 1084 compressedContent.setDataHandler(dataHandler); 1085 } 1086 1087 try { 1088 compressedContent.setCompressionAlgorithm(algorithm); 1089 } catch (NoSuchAlgorithmException ex) { 1090 throw new MessagingException("Compression algorithm not supported: " + ex.getMessage()); 1091 } 1092 1093 msg.setContent(compressedContent, compressedContent.getContentType()); 1094 // let the CompressedContent update some message headers 1095 compressedContent.setHeaders(msg); 1096 1097 return msg; 1098 } 1099 1100 /** 1101 * Creates a PKCS#10 certificate request message. 1102 * 1103 * @param session the mail session 1104 * 1105 * @return the PKCS#10 certificate request message 1106 * 1107 * @throws MessagingException if an error occurs when creating the message 1108 */ 1109 public Message createPKCS10Message(Session session) 1110 throws MessagingException { 1111 1112 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request"); 1113 1114 PKCS10Content pc = new PKCS10Content(); 1115 CertificateRequest request = null; 1116 try { 1117 request = createCertificateRequest(); 1118 } catch (PKCSException ex) { 1119 throw new MessagingException(ex.getMessage()); 1120 } 1121 pc.setCertRequest(request); 1122 msg.setContent(pc, pc.getContentType()); 1123 // let the PKCS10Content update some message headers 1124 pc.setHeaders(msg); 1125 1126 return msg; 1127 } 1128 1129 1130 private CertificateRequest createCertificateRequest() throws PKCSException { 1131 try { 1132 Name subject = new Name(); 1133 subject.addRDN(ObjectID.commonName, firstName_ + " " + lastName_); 1134 subject.addRDN(ObjectID.emailAddress, from_); 1135 CertificateRequest certRequest; 1136 certRequest = new CertificateRequest(signerCertificate_.getPublicKey(), subject); 1137 certRequest.sign((AlgorithmID)AlgorithmID.sha256WithRSAEncryption.clone(), signerPrivateKey_); 1138 certRequest.verify(); 1139 return certRequest; 1140 } catch (Exception ex) { 1141 throw new PKCSException("Cannot create cert request: " + ex.getMessage()); 1142 } 1143 1144 } 1145 1146 /** 1147 * Creates a PKCS#10 message where the certificate request is transferred as attachment. 1148 * 1149 * @param session the mail session 1150 * 1151 * @return the PKCS#10 certificate request message 1152 * 1153 * @throws MessagingException if an error occurs when creating the message 1154 */ 1155 public Message createPKCS10MultiPartMessage(Session session) throws MessagingException { 1156 1157 MimeBodyPart mbp1 = new MimeBodyPart(); 1158 mbp1.setText("This is a test where the request message is included in the second part!\n\n"); 1159 // try to test an attachment 1160 // this demo attaches our homepage 1161 MimeBodyPart attachment = new MimeBodyPart(); 1162 //use new content types 1163 SMimeParameters.useNewContentTypes(true); 1164 PKCS10Content pc = new PKCS10Content(); 1165 CertificateRequest request = null; 1166 try { 1167 request = createCertificateRequest(); 1168 } catch (PKCSException ex) { 1169 throw new MessagingException(ex.getMessage()); 1170 } 1171 pc.setCertRequest(request); 1172 DataHandler pkcs10Handler = new DataHandler(pc, pc.getContentType()); 1173 attachment.setDataHandler(pkcs10Handler); 1174 attachment.setDisposition("attachment"); 1175 attachment.setFileName("smime.p10"); 1176 Multipart mp = new MimeMultipart(); 1177 mp.addBodyPart(mbp1); 1178 mp.addBodyPart(attachment); 1179 1180 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request multipart message"); 1181 msg.setContent(mp, mp.getContentType()); 1182 return msg; 1183 } 1184 1185 /** 1186 * Prints a dump of the given message to System.out. 1187 * 1188 * @param msg the message to be dumped to System.out 1189 * 1190 * @throws IOException if an I/O error occurs 1191 */ 1192 static void printMessage(Message msg) throws IOException { 1193 System.out.println("------------------------------------------------------------------"); 1194 System.out.println("Message dump: \n"); 1195 try { 1196 msg.writeTo(System.out); 1197 } catch (MessagingException ex) { 1198 throw new IOException(ex.getMessage()); 1199 } 1200 System.out.println("\n------------------------------------------------------------------"); 1201 } 1202 1203 /** 1204 * The main method. 1205 */ 1206 public static void main(String[] argv) throws IOException { 1207 1208 DemoSMimeUtil.initDemos(); 1209 (new SMimeV4Demo()).start(); 1210 System.out.println("\nReady!"); 1211 DemoUtil.waitKey(); 1212 } 1213}