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/SMimeV3Demo.java 49 12.02.25 17:58 Dbratko $ 059 // $Revision: 49 $ 060 // 061 062 package demo.smime.basic; 063 064 import java.io.ByteArrayInputStream; 065 import java.io.ByteArrayOutputStream; 066 import java.io.IOException; 067 import java.security.NoSuchAlgorithmException; 068 import java.security.PrivateKey; 069 import java.util.Date; 070 071 import javax.activation.DataHandler; 072 import javax.activation.FileDataSource; 073 import javax.mail.Message; 074 import javax.mail.MessagingException; 075 import javax.mail.Multipart; 076 import javax.mail.Session; 077 import javax.mail.internet.InternetAddress; 078 import javax.mail.internet.MimeBodyPart; 079 import javax.mail.internet.MimeMessage; 080 import javax.mail.internet.MimeMultipart; 081 082 import demo.DemoSMimeUtil; 083 import demo.DemoUtil; 084 import demo.keystore.CMSKeyStore; 085 import demo.smime.DumpMessage; 086 import iaik.asn1.ObjectID; 087 import iaik.asn1.structures.AlgorithmID; 088 import iaik.asn1.structures.Name; 089 import iaik.cms.CMSAlgorithmID; 090 import iaik.pkcs.PKCSException; 091 import iaik.pkcs.pkcs10.CertificateRequest; 092 import iaik.smime.AuthEncryptedContent; 093 import iaik.smime.CompressedContent; 094 import iaik.smime.EncryptedContent; 095 import iaik.smime.PKCS10Content; 096 import iaik.smime.SMimeBodyPart; 097 import iaik.smime.SMimeException; 098 import iaik.smime.SMimeMultipart; 099 import iaik.smime.SMimeParameters; 100 import iaik.smime.SignedContent; 101 import iaik.x509.X509Certificate; 102 103 /** 104 * This class demonstrates the usage of the IAIK S/MIME implementation. It shows how to create 105 * signed and/or encrypted S/MIMEv3 messages and how to parse them and verify the signatures 106 * and decrypt the content, respectively. 107 * <p> 108 * To run this demo the following packages are required: 109 * <ul> 110 * <li> 111 * <code>iaik_cms.jar</code> (IAIK-CMS/SMIME) 112 * </li> 113 * <li> 114 * <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>). 115 * </li> 116 * <li> 117 * <code>mail.jar</code> (<a href="http://www.oracle.com/technetwork/java/javamail/index.html" target="_blank">JavaMail API</a>). 118 * </li> 119 * <li> 120 * <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). 121 * </li> 122 * </ul> 123 * You also will need the ESDH implementation of IAIK-JCE contained in <code>iaik_esdh.jar</code> or 124 * <code>iaik_jce_full.jar</code>; the first may be used in addition to <code>iaik_jce.jar</code>, 125 * the second instead of <code>iaik_jce.jar</code>. 126 */ 127 public class SMimeV3Demo { 128 129 // whether to print dump all generates test messages to System.out 130 final static boolean PRINT_MESSAGES = false; 131 132 133 String firstName = "John"; 134 String lastName = "SMime"; 135 String to = "smimetest@iaik.tugraz.at"; // email recipient 136 String from = "smimetest@iaik.tugraz.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 SMimeV3Demo() { 149 150 System.out.println(); 151 System.out.println("********************************************************************************************"); 152 System.out.println("* SMimeV3Demo demo *"); 153 System.out.println("* (shows how to create and parse (verify, decrypt) signed and encrypted S/MIMEv3 messages) *"); 154 System.out.println("********************************************************************************************"); 155 System.out.println(); 156 157 // get the certificates from the KeyStore 158 signerCertificates = CMSKeyStore.getCertificateChain(CMSKeyStore.DSA, CMSKeyStore.SZ_2048_SIGN_1); 159 signerPrivateKey = CMSKeyStore.getPrivateKey(CMSKeyStore.DSA, CMSKeyStore.SZ_2048_SIGN_1); 160 signerCertificate = signerCertificates[0]; 161 162 // recipient = signer for this test 163 recipientCertificate = CMSKeyStore.getCertificateChain(CMSKeyStore.ESDH, CMSKeyStore.SZ_2048_CRYPT_1)[0]; 164 if (recipientCertificate == null) { 165 throw new NullPointerException("ESDH certificate not available! Add iaik_esdh.jar to your classpath!"); 166 } 167 encryptionCertOfSigner = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1)[0]; 168 } 169 170 /** 171 * Starts the demo. 172 * 173 * @throws IOException if an I/O related error occurs 174 */ 175 public void start() throws IOException { 176 177 // get the default Session 178 Session session = DemoSMimeUtil.getSession(); 179 180 try { 181 // Create a demo Multipart 182 MimeBodyPart mbp1 = new SMimeBodyPart(); 183 mbp1.setText("This is a Test of the IAIK S/MIME implementation!\n\n"); 184 // attachment 185 MimeBodyPart attachment = new SMimeBodyPart(); 186 attachment.setDataHandler(new DataHandler(new FileDataSource("test.html"))); 187 attachment.setFileName("test.html"); 188 189 Multipart mp = new SMimeMultipart(); 190 mp.addBodyPart(mbp1); 191 mp.addBodyPart(attachment); 192 DataHandler multipart = new DataHandler(mp, mp.getContentType()); 193 194 Message msg; // the message to send 195 ByteArrayOutputStream baos = new ByteArrayOutputStream(); // we write to a stream 196 ByteArrayInputStream bais; // we read from a stream 197 198 // 1. This is a plain message 199 msg = createPlainMessage(session, multipart); 200 System.out.println("creating plain message..."); 201 msg.saveChanges(); 202 msg.writeTo(baos); 203 bais = new ByteArrayInputStream(baos.toByteArray()); 204 msg = new MimeMessage(session, bais); 205 if (PRINT_MESSAGES) { 206 printMessage(msg); 207 } 208 DumpMessage.dumpMsg(msg); 209 210 System.out.println("\n\n*****************************************\n\n"); 211 212 // 2. This is an explicitly signed message 213 msg = createSignedMessage(session, multipart, false, AlgorithmID.sha256, AlgorithmID.dsaWithSHA256); 214 System.out.println("creating explicitly signed message..."); 215 baos.reset(); 216 msg.saveChanges(); 217 msg.writeTo(baos); 218 bais = new ByteArrayInputStream(baos.toByteArray()); 219 msg = new MimeMessage(session, bais); 220 if (PRINT_MESSAGES) { 221 printMessage(msg); 222 } 223 DumpMessage.dumpMsg(msg); 224 225 System.out.println("\n\n*****************************************\n\n"); 226 227 228 // 3. This is an implicitly signed message 229 msg = createSignedMessage(session, multipart, true, AlgorithmID.sha256, AlgorithmID.dsaWithSHA256); 230 System.out.println("creating implicitly signed message..."); 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.dumpMsg(msg); 240 241 System.out.println("\n\n*****************************************\n\n"); 242 243 // 4. Now create encrypted messages with different content encryption algorithms 244 245 // RC2 is deprecated; only demonstrated here 246 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 40, 247 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)AlgorithmID.cms_rc2_wrap.clone(), 128); 248 System.out.println("creating encrypted message [RC2/40]..."); 249 baos.reset(); 250 msg.saveChanges(); 251 msg.writeTo(baos); 252 bais = new ByteArrayInputStream(baos.toByteArray()); 253 msg = new MimeMessage(session, bais); 254 if (PRINT_MESSAGES) { 255 printMessage(msg); 256 } 257 DumpMessage.dumpMsg(msg); 258 259 System.out.println("\n\n*****************************************\n\n"); 260 261 // RC2 is deprecated; only demonstrated here 262 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 64, 263 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)AlgorithmID.cms_rc2_wrap.clone(), 128); 264 System.out.println("creating encrypted message [RC2/64]..."); 265 baos.reset(); 266 msg.saveChanges(); 267 msg.writeTo(baos); 268 bais = new ByteArrayInputStream(baos.toByteArray()); 269 msg = new MimeMessage(session, bais); 270 if (PRINT_MESSAGES) { 271 printMessage(msg); 272 } 273 DumpMessage.dumpMsg(msg); 274 275 System.out.println("\n\n*****************************************\n\n"); 276 277 // RC2 is deprecated; only demonstrated here 278 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 128, 279 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)AlgorithmID.cms_rc2_wrap.clone(), 128); 280 System.out.println("creating encrypted message [RC2/128]..."); 281 baos.reset(); 282 msg.saveChanges(); 283 msg.writeTo(baos); 284 bais = new ByteArrayInputStream(baos.toByteArray()); 285 msg = new MimeMessage(session, bais); 286 if (PRINT_MESSAGES) { 287 printMessage(msg); 288 } 289 DumpMessage.dumpMsg(msg); 290 291 292 System.out.println("\n\n*****************************************\n\n"); 293 294 // DES EDE is deprecated; only demonstrated here 295 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.des_EDE3_CBC.clone(), 192, 296 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)AlgorithmID.cms_3DES_wrap.clone(), 192); 297 System.out.println("creating encrypted message [TripleDES]..."); 298 baos.reset(); 299 msg.saveChanges(); 300 msg.writeTo(baos); 301 bais = new ByteArrayInputStream(baos.toByteArray()); 302 msg = new MimeMessage(session, bais); 303 if (PRINT_MESSAGES) { 304 printMessage(msg); 305 } 306 DumpMessage.dumpMsg(msg); 307 308 System.out.println("\n\n*****************************************\n\n"); 309 310 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CBC.clone(), 128, 311 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes128_wrap.clone(), 128); 312 System.out.println("creating encrypted message [AES/128]..."); 313 baos.reset(); 314 msg.saveChanges(); 315 msg.writeTo(baos); 316 bais = new ByteArrayInputStream(baos.toByteArray()); 317 msg = new MimeMessage(session, bais); 318 if (PRINT_MESSAGES) { 319 printMessage(msg); 320 } 321 DumpMessage.dumpMsg(msg); 322 323 System.out.println("\n\n*****************************************\n\n"); 324 325 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CBC.clone(), 192, 326 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes192_wrap.clone(), 192); 327 System.out.println("creating encrypted message [AES/192]..."); 328 baos.reset(); 329 msg.saveChanges(); 330 msg.writeTo(baos); 331 bais = new ByteArrayInputStream(baos.toByteArray()); 332 msg = new MimeMessage(session, bais); 333 if (PRINT_MESSAGES) { 334 printMessage(msg); 335 } 336 DumpMessage.dumpMsg(msg); 337 338 System.out.println("\n\n*****************************************\n\n"); 339 340 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256, 341 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes256_wrap.clone(), 256); 342 System.out.println("creating encrypted message [AES/256]..."); 343 baos.reset(); 344 msg.saveChanges(); 345 msg.writeTo(baos); 346 bais = new ByteArrayInputStream(baos.toByteArray()); 347 msg = new MimeMessage(session, bais); 348 if (PRINT_MESSAGES) { 349 printMessage(msg); 350 } 351 DumpMessage.dumpMsg(msg); 352 353 354 System.out.println("\n\n*****************************************\n\n"); 355 356 // 5. Now create an implicitly signed and encrypted message with attachment 357 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), multipart, true); 358 System.out.println("creating implicitly signed and encrypted message [AES/256]..."); 359 baos.reset(); 360 msg.saveChanges(); 361 msg.writeTo(baos); 362 bais = new ByteArrayInputStream(baos.toByteArray()); 363 msg = new MimeMessage(session, bais); 364 if (PRINT_MESSAGES) { 365 printMessage(msg); 366 } 367 DumpMessage.dumpMsg(msg); 368 369 System.out.println("\n\n*****************************************\n\n"); 370 371 // 6. Now create an explicitly signed and encrypted message with attachment 372 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), multipart, false); 373 System.out.println("creating explicitly signed and encrypted message [AES/256]..."); 374 baos.reset(); 375 msg.saveChanges(); 376 msg.writeTo(baos); 377 bais = new ByteArrayInputStream(baos.toByteArray()); 378 msg = new MimeMessage(session, bais); 379 if (PRINT_MESSAGES) { 380 printMessage(msg); 381 } 382 DumpMessage.dumpMsg(msg); 383 384 System.out.println("\n\n*****************************************\n\n"); 385 386 // 7. Now create authenticated encrypted messages with different content encryption algorithms 387 if (DemoUtil.getIaikProviderVersion() >= 5.62) { 388 389 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_GCM.clone(), 128, 390 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes128_wrap.clone(), 128); 391 System.out.println("creating authenticated encrypted message [AES-GCM/128]..."); 392 baos.reset(); 393 msg.saveChanges(); 394 msg.writeTo(baos); 395 bais = new ByteArrayInputStream(baos.toByteArray()); 396 msg = new MimeMessage(session, bais); 397 if (PRINT_MESSAGES) { 398 printMessage(msg); 399 } 400 DumpMessage.dumpMsg(msg); 401 402 System.out.println("\n\n*****************************************\n\n"); 403 404 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_GCM.clone(), 192, 405 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes192_wrap.clone(), 192); 406 System.out.println("creating authenticated encrypted message [AES-GCM/192]..."); 407 baos.reset(); 408 msg.saveChanges(); 409 msg.writeTo(baos); 410 bais = new ByteArrayInputStream(baos.toByteArray()); 411 msg = new MimeMessage(session, bais); 412 if (PRINT_MESSAGES) { 413 printMessage(msg); 414 } 415 DumpMessage.dumpMsg(msg); 416 417 System.out.println("\n\n*****************************************\n\n"); 418 419 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256, 420 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes256_wrap.clone(), 256); 421 System.out.println("creating authenticated encrypted message [AES-GCM/256]..."); 422 baos.reset(); 423 msg.saveChanges(); 424 msg.writeTo(baos); 425 bais = new ByteArrayInputStream(baos.toByteArray()); 426 msg = new MimeMessage(session, bais); 427 if (PRINT_MESSAGES) { 428 printMessage(msg); 429 } 430 DumpMessage.dumpMsg(msg); 431 432 System.out.println("\n\n*****************************************\n\n"); 433 434 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CCM.clone(), 128, 435 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes128_wrap.clone(), 128); 436 System.out.println("creating authenticated encrypted message [AES-CCM/128]..."); 437 baos.reset(); 438 msg.saveChanges(); 439 msg.writeTo(baos); 440 bais = new ByteArrayInputStream(baos.toByteArray()); 441 msg = new MimeMessage(session, bais); 442 if (PRINT_MESSAGES) { 443 printMessage(msg); 444 } 445 DumpMessage.dumpMsg(msg); 446 447 System.out.println("\n\n*****************************************\n\n"); 448 449 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CCM.clone(), 192, 450 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes192_wrap.clone(), 192); 451 System.out.println("creating authenticated encrypted message [AES-CCM/192]..."); 452 baos.reset(); 453 msg.saveChanges(); 454 msg.writeTo(baos); 455 bais = new ByteArrayInputStream(baos.toByteArray()); 456 msg = new MimeMessage(session, bais); 457 if (PRINT_MESSAGES) { 458 printMessage(msg); 459 } 460 DumpMessage.dumpMsg(msg); 461 462 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), 256, 463 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes256_wrap.clone(), 256); 464 System.out.println("creating authenticated encrypted message [AES-CCM/256]..."); 465 baos.reset(); 466 msg.saveChanges(); 467 msg.writeTo(baos); 468 bais = new ByteArrayInputStream(baos.toByteArray()); 469 msg = new MimeMessage(session, bais); 470 if (PRINT_MESSAGES) { 471 printMessage(msg); 472 } 473 DumpMessage.dumpMsg(msg); 474 475 System.out.println("\n\n*****************************************\n\n"); 476 477 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256, 478 (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(), (AlgorithmID)CMSAlgorithmID.cms_aes256_wrap.clone(), 256); 479 System.out.println("creating authenticated encrypted message [ChaChaPoly1305]..."); 480 baos.reset(); 481 msg.saveChanges(); 482 msg.writeTo(baos); 483 bais = new ByteArrayInputStream(baos.toByteArray()); 484 msg = new MimeMessage(session, bais); 485 if (PRINT_MESSAGES) { 486 printMessage(msg); 487 } 488 DumpMessage.dumpMsg(msg); 489 490 System.out.println("\n\n*****************************************\n\n"); 491 492 // Create an implicitly signed and authenticated encrypted message with attachment 493 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), multipart, true); 494 System.out.println("creating implicitly signed and encrypted message [AES-GCM/256]..."); 495 baos.reset(); 496 msg.saveChanges(); 497 msg.writeTo(baos); 498 bais = new ByteArrayInputStream(baos.toByteArray()); 499 msg = new MimeMessage(session, bais); 500 if (PRINT_MESSAGES) { 501 printMessage(msg); 502 } 503 DumpMessage.dumpMsg(msg); 504 505 System.out.println("\n\n*****************************************\n\n"); 506 507 // Create an explicitly signed and encrypted message with attachment 508 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), multipart, false); 509 System.out.println("creating explicitly signed and encrypted message [AES-GCM/256]..."); 510 baos.reset(); 511 msg.saveChanges(); 512 msg.writeTo(baos); 513 bais = new ByteArrayInputStream(baos.toByteArray()); 514 msg = new MimeMessage(session, bais); 515 if (PRINT_MESSAGES) { 516 printMessage(msg); 517 } 518 DumpMessage.dumpMsg(msg); 519 520 System.out.println("\n\n*****************************************\n\n"); 521 522 // Create an implicitly signed and authenticated encrypted message with attachment 523 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), multipart, true); 524 System.out.println("creating implicitly signed and encrypted message [AES-CCM/256]..."); 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.dumpMsg(msg); 534 535 System.out.println("\n\n*****************************************\n\n"); 536 537 // Create an explicitly signed and encrypted message with attachment 538 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), multipart, false); 539 System.out.println("creating explicitly signed and encrypted message [AES-CCM/256]..."); 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.dumpMsg(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.chacha20Poly1305.clone(), multipart, true); 554 System.out.println("creating implicitly signed and encrypted message [ChaCha20Poly1305]..."); 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.dumpMsg(msg); 564 565 System.out.println("\n\n*****************************************\n\n"); 566 567 // Create an explicitly signed and encrypted message with attachment 568 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), multipart, false); 569 System.out.println("creating explicitly signed and encrypted message [ChaCha20Poly1305]..."); 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.dumpMsg(msg); 579 580 System.out.println("\n\n*****************************************\n\n"); 581 582 } 583 584 // 8. certs only message 585 msg = createCertsOnlyMessage(session); 586 System.out.println("creating certs-only message"); 587 baos.reset(); 588 msg.saveChanges(); 589 msg.writeTo(baos); 590 bais = new ByteArrayInputStream(baos.toByteArray()); 591 msg = new MimeMessage(session, bais); 592 if (PRINT_MESSAGES) { 593 printMessage(msg); 594 } 595 DumpMessage.dumpMsg(msg); 596 597 System.out.println("\n\n*****************************************\n\n"); 598 599 // 9. second certs only message 600 msg = createCertsOnlyMultiPartMessage(session); 601 System.out.println("creating message with certs-only part"); 602 baos.reset(); 603 msg.saveChanges(); 604 msg.writeTo(baos); 605 bais = new ByteArrayInputStream(baos.toByteArray()); 606 msg = new MimeMessage(session, bais); 607 if (PRINT_MESSAGES) { 608 printMessage(msg); 609 } 610 DumpMessage.dumpMsg(msg); 611 612 System.out.println("\n\n*****************************************\n\n"); 613 614 // 10. application/pkcs10 cert request message 615 msg = createPKCS10Message(session); 616 System.out.println("creating application/pkcs10 message..."); 617 baos.reset(); 618 msg.saveChanges(); 619 msg.writeTo(baos); 620 bais = new ByteArrayInputStream(baos.toByteArray()); 621 msg = new MimeMessage(session, bais); 622 if (PRINT_MESSAGES) { 623 printMessage(msg); 624 } 625 DumpMessage.dumpMsg(msg); 626 627 System.out.println("\n\n*****************************************\n\n"); 628 629 // 11. ending application/pkcs10 message where the request is in the second part 630 msg = createPKCS10MultiPartMessage(session); 631 System.out.println("creating message with pkcs10 part..."); 632 baos.reset(); 633 msg.saveChanges(); 634 msg.writeTo(baos); 635 bais = new ByteArrayInputStream(baos.toByteArray()); 636 msg = new MimeMessage(session, bais); 637 if (PRINT_MESSAGES) { 638 printMessage(msg); 639 } 640 DumpMessage.dumpMsg(msg); 641 642 System.out.println("\n\n*****************************************\n\n"); 643 644 // 12. compressed message 645 msg = createCompressedMessage(session, multipart, (AlgorithmID)CMSAlgorithmID.zlib_compress.clone()); 646 System.out.println("creating message with compressed data..."); 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 } catch (Exception ex) { 658 ex.printStackTrace(); 659 throw new RuntimeException(ex.toString()); 660 } 661 } 662 663 /** 664 * Creates a MIME message container with the given subject for the given session. 665 * 666 * @param session the mail sesion 667 * @param subject the subject of the message 668 * 669 * @return the MIME message with FROM, TO, DATE and SUBJECT headers (without content) 670 * 671 * @throws MessagingException if the message cannot be created 672 */ 673 public Message createMessage(Session session, String subject) throws MessagingException { 674 MimeMessage msg = new MimeMessage(session); 675 msg.setFrom(new InternetAddress(from)); 676 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to, false)); 677 msg.setSentDate(new Date()); 678 msg.setSubject(subject); 679 return msg; 680 } 681 682 /** 683 * Creates a simple plain (neither signed nor encrypted) message. 684 * 685 * @param session the mail session 686 * @param dataHandler the content of the message 687 * 688 * @return the plain message 689 * 690 * @throws MessagingException if an error occurs when creating the message 691 */ 692 public Message createPlainMessage(Session session, DataHandler dataHandler) throws MessagingException { 693 694 Message msg = createMessage(session, "IAIK-S/MIME: Plain message"); 695 if (dataHandler != null) { 696 msg.setDataHandler(dataHandler); 697 } else { 698 msg.setText("This is a plain message!\nIt is wether signed nor encrypted!\n"); 699 } 700 return msg; 701 } 702 703 /** 704 * Creates a signed and encrypted message. 705 * 706 * @param session the mail session 707 * @param algorithm the content encryption algorithm to be used 708 * @param dataHandler the content of the message to be signed and encrypted 709 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 710 * (multipart/signed) signing 711 * 712 * @return the signed and encrypted message 713 * 714 * @throws MessagingException if an error occurs when creating the message 715 */ 716 public Message createSignedAndEncryptedMessage(Session session, AlgorithmID algorithm, DataHandler dataHandler, boolean implicit) 717 throws MessagingException { 718 719 String subject = null; 720 String text = null; 721 if (implicit) { 722 subject = "IAIK-S/MIME: Implicitly Signed and Encrypted"; 723 text = "This message is implicitly signed and encrypted!\n\n\n"; 724 } else { 725 subject = "IAIK-S/MIME: Explicitly Signed and Encrypted"; 726 text = "This message is explicitly signed and encrypted!\n\n\n"; 727 } 728 Message msg = createMessage(session, subject); 729 730 SignedContent sc = new SignedContent(implicit); 731 if (dataHandler != null) { 732 sc.setDataHandler(dataHandler); 733 } else { 734 sc.setText(text); 735 } 736 sc.setCertificates(signerCertificates); 737 try { 738 sc.addSigner(signerPrivateKey, 739 signerCertificate, 740 (AlgorithmID)AlgorithmID.sha256.clone(), 741 (AlgorithmID)AlgorithmID.dsaWithSHA256.clone()); 742 } catch (NoSuchAlgorithmException ex) { 743 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 744 } 745 746 EncryptedContent ec = null; 747 if (algorithm.equals(AlgorithmID.aes256_CBC)) { 748 ec = new EncryptedContent(sc); 749 } else { 750 ec = new AuthEncryptedContent(sc); 751 } 752 // encrypt for the recipient 753 AlgorithmID keyEA = (AlgorithmID)AlgorithmID.esdhKeyAgreement.clone(); 754 // the key wrap algorithm to use: 755 AlgorithmID keyWrapAlg = (AlgorithmID)AlgorithmID.cms_aes256_wrap.clone(); 756 // the length of the key encryption key to be generated: 757 int kekLength = 256; 758 try { 759 ec.addRecipient(recipientCertificate, keyEA, keyWrapAlg, kekLength); 760 } catch (SMimeException ex) { 761 throw new MessagingException("Error adding ESDH recipient: " + ex.getMessage()); 762 } 763 // I want to be able to decrypt the message, too 764 ec.addRecipient(encryptionCertOfSigner, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 765 // set the encryption algorithm 766 try { 767 ec.setEncryptionAlgorithm(algorithm, -1); 768 } catch (NoSuchAlgorithmException ex) { 769 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 770 } 771 msg.setContent(ec, ec.getContentType()); 772 // let the EncryptedContent update some message headers 773 ec.setHeaders(msg); 774 775 return msg; 776 } 777 778 /** 779 * Creates a signed message. 780 * 781 * @param session the mail session 782 * @param dataHandler the content of the message to be signed 783 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 784 * (multipart/signed) signing 785 * @param digestAlgorithm the digest algorithm to be used 786 * @param signatureAlgorithm the signature algorithm to be used 787 * 788 * @return the signed message 789 * 790 * @throws MessagingException if an error occurs when creating the message 791 */ 792 public Message createSignedMessage(Session session, 793 DataHandler dataHandler, 794 boolean implicit, 795 AlgorithmID digestAlgorithm, 796 AlgorithmID signatureAlgorithm) 797 throws MessagingException { 798 799 String subject = null; 800 StringBuffer buf = new StringBuffer(); 801 802 if (implicit) { 803 subject = "IAIK-S/MIME: Implicitly Signed"; 804 buf.append("This message is implicitly signed!\n"); 805 buf.append("You need an S/MIME aware mail client to view this message.\n"); 806 buf.append("\n\n"); 807 } else { 808 subject = "IAIK-S/MIME: Explicitly Signed"; 809 buf.append("This message is explicitly signed!\n"); 810 buf.append("Every mail client can view this message.\n"); 811 buf.append("Non S/MIME mail clients will show the signature as attachment.\n"); 812 buf.append("\n\n"); 813 } 814 815 Message msg = createMessage(session, subject); 816 817 SignedContent sc = new SignedContent(implicit); 818 if (dataHandler != null) { 819 sc.setDataHandler(dataHandler); 820 } else { 821 sc.setText(buf.toString()); 822 } 823 sc.setCertificates(signerCertificates); 824 825 try { 826 sc.addSigner(signerPrivateKey, 827 signerCertificate, 828 (AlgorithmID)digestAlgorithm.clone(), 829 (AlgorithmID)signatureAlgorithm.clone()); 830 } catch (NoSuchAlgorithmException ex) { 831 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 832 } 833 834 msg.setContent(sc, sc.getContentType()); 835 // let the SignedContent update some message headers 836 sc.setHeaders(msg); 837 return msg; 838 } 839 840 /** 841 * Creates an encrypted message. 842 * 843 * @param session the mail session 844 * @param contentEA the content encryption algorithm to be used 845 * @param keyLength the length of the secret content encryption key to be created and used 846 * @param keyEA the key encryption algorithm to be used 847 * @param keyWrapAlgorithm the key wrap algorithm to be used 848 * @param kekLength the length of the key encryption algorithm 849 * 850 * @return the encrypted message 851 * 852 * @throws MessagingException if an error occurs when creating the message 853 */ 854 public Message createEncryptedMessage(Session session, AlgorithmID contentEA, int keyLength, 855 AlgorithmID keyEA, AlgorithmID keyWrapAlgorithm, int kekLength) 856 throws MessagingException { 857 858 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 859 AlgorithmID keyAgreeAlg = (AlgorithmID)keyEA.clone(); 860 AlgorithmID keyWrapAlg = (AlgorithmID)keyWrapAlgorithm.clone(); 861 862 StringBuffer subject = new StringBuffer(); 863 subject.append("IAIK-S/MIME: Encrypted ["+algorithm.getName()); 864 if (keyLength > 0) { 865 subject.append("/"+keyLength); 866 } 867 subject.append("]"); 868 Message msg = createMessage(session, subject.toString()); 869 870 EncryptedContent ec = new EncryptedContent(); 871 872 StringBuffer buf = new StringBuffer(); 873 buf.append("This is the encrypted content!\n"); 874 buf.append("Content encryption algorithm: "+algorithm.getName()); 875 buf.append("\n\n"); 876 877 ec.setText(buf.toString()); 878 879 try { 880 ec.addRecipient(recipientCertificate, keyAgreeAlg, keyWrapAlg, kekLength); 881 } catch (SMimeException ex) { 882 throw new MessagingException("Error adding ESDH recipient: " + ex.getMessage()); 883 } 884 // I want to be able to decrypt the message, too 885 ec.addRecipient(encryptionCertOfSigner, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 886 try { 887 ec.setEncryptionAlgorithm(algorithm, keyLength); 888 } catch (NoSuchAlgorithmException ex) { 889 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 890 } 891 892 msg.setContent(ec, ec.getContentType()); 893 // let the EncryptedContent update some message headers 894 ec.setHeaders(msg); 895 896 return msg; 897 } 898 899 /** 900 * Creates an authenticated encrypted message. 901 * 902 * @param session the mail session 903 * @param contentEA the content encryption algorithm to be used 904 * @param keyLength the length of the secret content encryption key to be created and used 905 * @param keyEA the key encryption algorithm to be used 906 * @param keyWrapAlgorithm the key wrap algorithm to be used 907 * @param kekLength the length of the key encryption algorithm 908 * @return the encrypted message 909 * 910 * @throws MessagingException if an error occurs when creating the message 911 */ 912 public Message createAuthEncryptedMessage(Session session, AlgorithmID contentEA, int keyLength, 913 AlgorithmID keyEA, AlgorithmID keyWrapAlgorithm, int kekLength) 914 throws MessagingException { 915 916 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 917 AlgorithmID keyAgreeAlg = (AlgorithmID)keyEA.clone(); 918 AlgorithmID keyWrapAlg = (AlgorithmID)keyWrapAlgorithm.clone(); 919 920 StringBuffer subject = new StringBuffer(); 921 subject.append("IAIK-S/MIME: Authenticated Encrypted ["+algorithm.getName()); 922 if (keyLength > 0) { 923 subject.append("/"+keyLength); 924 } 925 subject.append("]"); 926 Message msg = createMessage(session, subject.toString()); 927 928 AuthEncryptedContent ec = new AuthEncryptedContent(); 929 930 StringBuffer buf = new StringBuffer(); 931 buf.append("This is the authenticated encrypted content!\n"); 932 buf.append("Content encryption algorithm: "+algorithm.getName()); 933 buf.append("\n\n"); 934 935 ec.setText(buf.toString()); 936 937 try { 938 ec.addRecipient(recipientCertificate, keyAgreeAlg, keyWrapAlg, kekLength); 939 } catch (SMimeException ex) { 940 throw new MessagingException("Error adding ESDH recipient: " + ex.getMessage()); 941 } 942 // I want to be able to decrypt the message, too 943 ec.addRecipient(encryptionCertOfSigner, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 944 try { 945 ec.setEncryptionAlgorithm(algorithm, keyLength); 946 } catch (NoSuchAlgorithmException ex) { 947 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 948 } 949 950 msg.setContent(ec, ec.getContentType()); 951 // let the EncryptedContent update some message headers 952 ec.setHeaders(msg); 953 954 return msg; 955 } 956 957 /** 958 * Creates a certs-only message. 959 * 960 * @param session the mail session 961 * 962 * @return the certs-only message 963 * 964 * @throws MessagingException if an error occurs when creating the message 965 */ 966 public Message createCertsOnlyMessage(Session session) 967 throws MessagingException { 968 969 Message msg = createMessage(session, "IAIK S/MIME: Certs-only message"); 970 //use new content types 971 SMimeParameters.useNewContentTypes(true); 972 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 973 sc.setCertificates(signerCertificates); 974 msg.setContent(sc, sc.getContentType()); 975 //set filename and attachment parameters 976 sc.setHeaders(msg); 977 978 return msg; 979 } 980 981 982 /** 983 * Creates a certs-only message where the certificate list is transferred as attachment. 984 * 985 * @param session the mail session 986 * 987 * @return the certs-only message 988 * 989 * @throws MessagingException if an error occurs when creating the message 990 */ 991 public Message createCertsOnlyMultiPartMessage(Session session) throws MessagingException { 992 993 MimeBodyPart mbp1 = new MimeBodyPart(); 994 mbp1.setText("This is a test where the certs-only message is included in the second part!\n\n"); 995 996 MimeBodyPart attachment = new MimeBodyPart(); 997 //use new content types 998 SMimeParameters.useNewContentTypes(true); 999 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 1000 sc.setCertificates(signerCertificates); 1001 attachment.setContent(sc, sc.getContentType()); 1002 // let the SignedContent update some headers 1003 sc.setHeaders(attachment); 1004 Multipart mp = new MimeMultipart(); 1005 mp.addBodyPart(mbp1); 1006 mp.addBodyPart(attachment); 1007 1008 Message msg = createMessage(session, "IAIK S/MIME: Certs-only multipart message"); 1009 msg.setContent(mp, mp.getContentType()); 1010 return msg; 1011 } 1012 1013 /** 1014 * Creates a compressed message. 1015 * 1016 * @param session the mail session 1017 * @param dataHandler the datahandler supplying the content to be compressed 1018 * @param algorithm the compression algorithm to be used 1019 * 1020 * @return the compressed message 1021 * 1022 * @throws MessagingException if an error occurs when creating the message 1023 */ 1024 public Message createCompressedMessage(Session session, DataHandler dataHandler, AlgorithmID algorithm) 1025 throws MessagingException { 1026 1027 String subject = "IAIK-S/MIME: Compressed ["+algorithm.getName()+"]"; 1028 Message msg = createMessage(session, subject.toString()); 1029 1030 CompressedContent compressedContent = new CompressedContent(); 1031 1032 if (dataHandler == null) { 1033 StringBuffer buf = new StringBuffer(); 1034 buf.append("This is the compressed content!\n"); 1035 buf.append("Compression algorithm: "+algorithm.getName()); 1036 buf.append("\n\n"); 1037 compressedContent.setText(buf.toString()); 1038 } else { 1039 compressedContent.setDataHandler(dataHandler); 1040 } 1041 1042 try { 1043 compressedContent.setCompressionAlgorithm(algorithm); 1044 } catch (NoSuchAlgorithmException ex) { 1045 throw new MessagingException("Compression algorithm not supported: " + ex.getMessage()); 1046 } 1047 1048 msg.setContent(compressedContent, compressedContent.getContentType()); 1049 // let the CompressedContent update some message headers 1050 compressedContent.setHeaders(msg); 1051 1052 return msg; 1053 } 1054 1055 /** 1056 * Creates a PKCS#10 certificate request message. 1057 * 1058 * @param session the mail session 1059 * 1060 * @return the PKCS#10 certificate request message 1061 * 1062 * @throws MessagingException if an error occurs when creating the message 1063 */ 1064 public Message createPKCS10Message(Session session) 1065 throws MessagingException { 1066 1067 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request"); 1068 1069 PKCS10Content pc = new PKCS10Content(); 1070 CertificateRequest request = null; 1071 try { 1072 request = createCertificateRequest(); 1073 } catch (PKCSException ex) { 1074 throw new MessagingException(ex.getMessage()); 1075 } 1076 pc.setCertRequest(request); 1077 msg.setContent(pc, pc.getContentType()); 1078 // let the PKCS10Content update some message headers 1079 pc.setHeaders(msg); 1080 1081 return msg; 1082 } 1083 1084 1085 private CertificateRequest createCertificateRequest() throws PKCSException { 1086 try { 1087 Name subject = new Name(); 1088 subject.addRDN(ObjectID.commonName, firstName + " " + lastName); 1089 subject.addRDN(ObjectID.emailAddress, from); 1090 CertificateRequest certRequest; 1091 certRequest = new CertificateRequest(signerCertificate.getPublicKey(), subject); 1092 certRequest.sign((AlgorithmID)AlgorithmID.dsaWithSHA256.clone(), signerPrivateKey); 1093 certRequest.verify(); 1094 return certRequest; 1095 } catch (Exception ex) { 1096 throw new PKCSException("Cannot create cert request: " + ex.getMessage()); 1097 } 1098 1099 } 1100 1101 /** 1102 * Creates a PKCS#10 message where the certificate request is transferred as attachment. 1103 * 1104 * @param session the mail session 1105 * 1106 * @return the PKCS#10 certificate request message 1107 * 1108 * @throws MessagingException if an error occurs when creating the message 1109 */ 1110 public Message createPKCS10MultiPartMessage(Session session) throws MessagingException { 1111 1112 MimeBodyPart mbp1 = new MimeBodyPart(); 1113 mbp1.setText("This is a test where the request message is included in the second part!\n\n"); 1114 // try to test an attachment 1115 // this demo attaches our homepage 1116 MimeBodyPart attachment = new MimeBodyPart(); 1117 //use new content types 1118 SMimeParameters.useNewContentTypes(true); 1119 PKCS10Content pc = new PKCS10Content(); 1120 CertificateRequest request = null; 1121 try { 1122 request = createCertificateRequest(); 1123 } catch (PKCSException ex) { 1124 throw new MessagingException(ex.getMessage()); 1125 } 1126 pc.setCertRequest(request); 1127 DataHandler pkcs10Handler = new DataHandler(pc, pc.getContentType()); 1128 attachment.setDataHandler(pkcs10Handler); 1129 attachment.setDisposition("attachment"); 1130 attachment.setFileName("smime.p10"); 1131 Multipart mp = new MimeMultipart(); 1132 mp.addBodyPart(mbp1); 1133 mp.addBodyPart(attachment); 1134 1135 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request multipart message"); 1136 msg.setContent(mp, mp.getContentType()); 1137 return msg; 1138 } 1139 1140 /** 1141 * Prints a dump of the given message to System.out. 1142 * 1143 * @param msg the message to be dumped to System.out 1144 * 1145 * @throws IOException if an I/O error occurs 1146 */ 1147 static void printMessage(Message msg) throws IOException { 1148 System.out.println("------------------------------------------------------------------"); 1149 System.out.println("Message dump: \n"); 1150 try { 1151 msg.writeTo(System.out); 1152 } catch (MessagingException ex) { 1153 throw new IOException(ex.getMessage()); 1154 } 1155 System.out.println("\n------------------------------------------------------------------"); 1156 } 1157 1158 1159 /** 1160 * The main method. 1161 */ 1162 public static void main(String[] argv) throws IOException { 1163 1164 DemoSMimeUtil.initDemos(); 1165 (new SMimeV3Demo()).start(); 1166 System.out.println("\nReady!"); 1167 DemoUtil.waitKey(); 1168 } 1169 }