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/SMimeV4Demo.java 8 12.02.25 17:59 Dbratko $ 059 // $Revision: 8 $ 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.SMimeMultipart; 098 import iaik.smime.SMimeParameters; 099 import iaik.smime.SignedContent; 100 import iaik.x509.X509Certificate; 101 102 /** 103 * This class demonstrates the usage of the IAIK S/MIME implementation. It shows how to create 104 * signed and/or encrypted S/MIMEv4 messages and how to parse them and verify the signatures 105 * and decrypt the content, respectively. 106 * <p> 107 * To run this demo the following packages are required: 108 * <ul> 109 * <li> 110 * <code>iaik_cms.jar</code> (IAIK-CMS/SMIME) 111 * </li> 112 * <li> 113 * <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>). 114 * </li> 115 * <li> 116 * <code>mail.jar</code> (<a href="http://www.oracle.com/technetwork/java/javamail/index.html" target="_blank">JavaMail API</a>). 117 * </li> 118 * <li> 119 * <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). 120 * </li> 121 * </ul> 122 * You also will need the IAIK-JCE library, <code>iaik_jce(_full).jar</code>. 123 * <p> 124 * This demo uses RSA both for signing an encryption. Look at the demos in package <code>demo.smime.ecc</code> for 125 * examples based on elliptic curve cryptography. 126 * 127 */ 128 public class SMimeV4Demo { 129 130 // whether to print dump all generates test messages to System.out 131 final static boolean PRINT_MESSAGES = false; 132 133 134 String firstName_ = "John"; 135 String lastName_ = "SMime"; 136 String to_ = "smimetest@iaik.tugraz.at"; // email recipient 137 String from_ = "smimetest@iaik.tugraz.at"; // email sender 138 String host_ = "mailhost"; // name of the mailhost 139 140 X509Certificate[] signerCertificates_; // list of certificates to include in the S/MIME message 141 X509Certificate signerCertificate_; // certificate of the signer/sender 142 PrivateKey signerPrivateKey_; // private key of the signer/sender 143 144 X509Certificate senderCryptCertificate_; // the encryption certificate of the signer/sender 145 146 X509Certificate rsaRecipientCertificate_; // RSA encryption cert and key of a recipient 147 148 /** 149 * Default constructor. Reads certificates and keys from the demo keystore. 150 */ 151 public SMimeV4Demo() { 152 153 System.out.println(); 154 System.out.println("********************************************************************************************"); 155 System.out.println("* SMimeV4Demo demo *"); 156 System.out.println("* (shows how to create and parse (verify, decrypt) signed and encrypted S/MIMEv4 messages) *"); 157 System.out.println("********************************************************************************************"); 158 System.out.println(); 159 160 // get the certificates from the KeyStore 161 signerCertificates_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1); 162 signerPrivateKey_ = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1); 163 signerCertificate_ = signerCertificates_[0]; 164 senderCryptCertificate_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1)[0]; 165 166 rsaRecipientCertificate_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2)[0]; 167 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 // 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 // This is an explicitly signed message 213 msg = createSignedMessage(session, multipart, false, AlgorithmID.sha256, AlgorithmID.rsaEncryption); 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 // This is an implicitly signed message 229 msg = createSignedMessage(session, multipart, true, AlgorithmID.sha256, AlgorithmID.rsaEncryption); 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 // Now create encrypted messages with different content encryption algorithms 244 245 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CBC.clone(), 128); 246 System.out.println("creating encrypted message [AES/128]..."); 247 baos.reset(); 248 msg.saveChanges(); 249 msg.writeTo(baos); 250 bais = new ByteArrayInputStream(baos.toByteArray()); 251 msg = new MimeMessage(session, bais); 252 if (PRINT_MESSAGES) { 253 printMessage(msg); 254 } 255 DumpMessage.dumpEncryptedMessage(msg); 256 257 System.out.println("\n\n*****************************************\n\n"); 258 259 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CBC.clone(), 192); 260 System.out.println("creating encrypted message [AES/192]..."); 261 baos.reset(); 262 msg.saveChanges(); 263 msg.writeTo(baos); 264 bais = new ByteArrayInputStream(baos.toByteArray()); 265 msg = new MimeMessage(session, bais); 266 if (PRINT_MESSAGES) { 267 printMessage(msg); 268 } 269 DumpMessage.dumpEncryptedMessage(msg); 270 271 System.out.println("\n\n*****************************************\n\n"); 272 273 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256); 274 System.out.println("creating encrypted message [AES/256]..."); 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 implicitly signed and encrypted message with attachment 288 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CBC.clone(), 128, multipart, true, false); 289 System.out.println("creating implicitly signed and encrypted message [AES/128]..."); 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.aes192_CBC.clone(), 192, multipart, true, false); 304 System.out.println("creating implicitly signed and encrypted message [AES/192]..."); 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.aes192_CBC.clone(), 192, multipart, false, false);; 319 System.out.println("creating explicitly signed and encrypted message [AES/192]..."); 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 an implicitly signed and encrypted message with attachment 333 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256, multipart, true, false); 334 System.out.println("creating implicitly signed and encrypted message [AES/256]..."); 335 baos.reset(); 336 msg.saveChanges(); 337 msg.writeTo(baos); 338 bais = new ByteArrayInputStream(baos.toByteArray()); 339 msg = new MimeMessage(session, bais); 340 if (PRINT_MESSAGES) { 341 printMessage(msg); 342 } 343 DumpMessage.dumpEncryptedMessage(msg); 344 345 System.out.println("\n\n*****************************************\n\n"); 346 347 // Now create an explicitly signed and encrypted message with attachment 348 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256, multipart, false, false);; 349 System.out.println("creating explicitly signed and encrypted message [AES/256]..."); 350 baos.reset(); 351 msg.saveChanges(); 352 msg.writeTo(baos); 353 bais = new ByteArrayInputStream(baos.toByteArray()); 354 msg = new MimeMessage(session, bais); 355 if (PRINT_MESSAGES) { 356 printMessage(msg); 357 } 358 DumpMessage.dumpEncryptedMessage(msg); 359 360 System.out.println("\n\n*****************************************\n\n"); 361 362 // Now create authenticated encrypted messages with different content encryption algorithms 363 if (DemoUtil.getIaikProviderVersion() >= 5.62) { 364 365 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_GCM.clone(), 128); 366 System.out.println("creating authenticated encrypted message [AES-GCM/128]..."); 367 baos.reset(); 368 msg.saveChanges(); 369 msg.writeTo(baos); 370 bais = new ByteArrayInputStream(baos.toByteArray()); 371 msg = new MimeMessage(session, bais); 372 if (PRINT_MESSAGES) { 373 printMessage(msg); 374 } 375 DumpMessage.dumpEncryptedMessage(msg); 376 377 System.out.println("\n\n*****************************************\n\n"); 378 379 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_GCM.clone(), 192); 380 System.out.println("creating authenticated encrypted message [AES-GCM/192]..."); 381 baos.reset(); 382 msg.saveChanges(); 383 msg.writeTo(baos); 384 bais = new ByteArrayInputStream(baos.toByteArray()); 385 msg = new MimeMessage(session, bais); 386 if (PRINT_MESSAGES) { 387 printMessage(msg); 388 } 389 DumpMessage.dumpEncryptedMessage(msg); 390 391 System.out.println("\n\n*****************************************\n\n"); 392 393 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256); 394 System.out.println("creating authenticated encrypted message [AES-GCM/256]..."); 395 baos.reset(); 396 msg.saveChanges(); 397 msg.writeTo(baos); 398 bais = new ByteArrayInputStream(baos.toByteArray()); 399 msg = new MimeMessage(session, bais); 400 if (PRINT_MESSAGES) { 401 printMessage(msg); 402 } 403 DumpMessage.dumpEncryptedMessage(msg); 404 405 System.out.println("\n\n*****************************************\n\n"); 406 407 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CCM.clone(), 128); 408 System.out.println("creating authenticated encrypted message [AES-CCM/128]..."); 409 baos.reset(); 410 msg.saveChanges(); 411 msg.writeTo(baos); 412 bais = new ByteArrayInputStream(baos.toByteArray()); 413 msg = new MimeMessage(session, bais); 414 if (PRINT_MESSAGES) { 415 printMessage(msg); 416 } 417 DumpMessage.dumpEncryptedMessage(msg); 418 419 System.out.println("\n\n*****************************************\n\n"); 420 421 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CCM.clone(), 192); 422 System.out.println("creating authenticated encrypted message [AES-CCM/192]..."); 423 baos.reset(); 424 msg.saveChanges(); 425 msg.writeTo(baos); 426 bais = new ByteArrayInputStream(baos.toByteArray()); 427 msg = new MimeMessage(session, bais); 428 if (PRINT_MESSAGES) { 429 printMessage(msg); 430 } 431 DumpMessage.dumpEncryptedMessage(msg); 432 433 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CCM.clone(), 256); 434 System.out.println("creating authenticated encrypted message [AES-CCM/256]..."); 435 baos.reset(); 436 msg.saveChanges(); 437 msg.writeTo(baos); 438 bais = new ByteArrayInputStream(baos.toByteArray()); 439 msg = new MimeMessage(session, bais); 440 if (PRINT_MESSAGES) { 441 printMessage(msg); 442 } 443 DumpMessage.dumpEncryptedMessage(msg); 444 445 System.out.println("\n\n*****************************************\n\n"); 446 447 msg = createAuthEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256); 448 System.out.println("creating authenticated encrypted message [ChaChaPoly1305]..."); 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.aes128_GCM.clone(), 128, multipart, true, true); 463 System.out.println("creating implicitly signed and authenticated encrypted message [AES-GCM/128]..."); 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.aes128_GCM.clone(), 128, multipart, true, true); 478 System.out.println("creating explicitly signed and authenticated encrypted message [AES-GCM/128]..."); 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.aes192_GCM.clone(), 192, multipart, true, true); 493 System.out.println("creating implicitly signed and authenticated encrypted message [AES-GCM/192]..."); 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.aes192_GCM.clone(), 192, multipart, true, true); 508 System.out.println("creating explicitly signed and authenticated encrypted message [AES-GCM/192]..."); 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 // Create an implicitly signed and authenticated encrypted message with attachment 522 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256, multipart, true, true); 523 System.out.println("creating implicitly signed and authenticated encrypted message [AES-GCM/256]..."); 524 baos.reset(); 525 msg.saveChanges(); 526 msg.writeTo(baos); 527 bais = new ByteArrayInputStream(baos.toByteArray()); 528 msg = new MimeMessage(session, bais); 529 if (PRINT_MESSAGES) { 530 printMessage(msg); 531 } 532 DumpMessage.dumpEncryptedMessage(msg); 533 534 System.out.println("\n\n*****************************************\n\n"); 535 536 // Create an explicitly signed and authenticated encrypted message with attachment 537 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_GCM.clone(), 256, multipart, true, true); 538 System.out.println("creating explicitly signed and authenticated encrypted message [AES-GCM/256]..."); 539 baos.reset(); 540 msg.saveChanges(); 541 msg.writeTo(baos); 542 bais = new ByteArrayInputStream(baos.toByteArray()); 543 msg = new MimeMessage(session, bais); 544 if (PRINT_MESSAGES) { 545 printMessage(msg); 546 } 547 DumpMessage.dumpEncryptedMessage(msg); 548 549 System.out.println("\n\n*****************************************\n\n"); 550 551 552 // Create an implicitly signed and authenticated encrypted message with attachment 553 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CCM.clone(), 128, multipart, true, true); 554 System.out.println("creating implicitly signed and authenticated encrypted message [AES-CCM/128]..."); 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.aes128_CCM.clone(), 128, multipart, true, true); 569 System.out.println("creating explicitly signed and authenticated encrypted message [AES-CCM/128]..."); 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.aes192_CCM.clone(), 192, multipart, true, true); 584 System.out.println("creating implicitly signed and authenticated encrypted message [AES-CCM/192]..."); 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.aes192_CCM.clone(), 192, multipart, true, true); 599 System.out.println("creating explicitly signed and authenticated encrypted message [AES-CCM/192]..."); 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.aes256_CCM.clone(), 256, multipart, true, true); 614 System.out.println("creating implicitly signed and authenticated encrypted message [AES-CCM/256]..."); 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.aes256_CCM.clone(), 256, multipart, true, true); 629 System.out.println("creating explicitly signed and authenticated encrypted message [AES-CCM/256]..."); 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 // Create an implicitly signed and authenticated encrypted message with attachment 643 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256, multipart, true, true); 644 System.out.println("creating implicitly signed and authenticated encrypted message [ChaCha20Poly1305]..."); 645 baos.reset(); 646 msg.saveChanges(); 647 msg.writeTo(baos); 648 bais = new ByteArrayInputStream(baos.toByteArray()); 649 msg = new MimeMessage(session, bais); 650 if (PRINT_MESSAGES) { 651 printMessage(msg); 652 } 653 DumpMessage.dumpEncryptedMessage(msg); 654 655 System.out.println("\n\n*****************************************\n\n"); 656 657 // Create an explicitly signed and authenticated encrypted message with attachment 658 msg = createSignedAndEncryptedMessage(session, (AlgorithmID)AlgorithmID.chacha20Poly1305.clone(), 256, multipart, true, true); 659 System.out.println("creating explicitly signed and authenticated encrypted message [ChaCha20Poly1305]..."); 660 baos.reset(); 661 msg.saveChanges(); 662 msg.writeTo(baos); 663 bais = new ByteArrayInputStream(baos.toByteArray()); 664 msg = new MimeMessage(session, bais); 665 if (PRINT_MESSAGES) { 666 printMessage(msg); 667 } 668 DumpMessage.dumpEncryptedMessage(msg); 669 670 System.out.println("\n\n*****************************************\n\n"); 671 672 } 673 674 // certs only message 675 msg = createCertsOnlyMessage(session); 676 System.out.println("creating certs-only 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 // second certs only message 690 msg = createCertsOnlyMultiPartMessage(session); 691 System.out.println("creating message with certs-only 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 // application/pkcs10 cert request message 705 msg = createPKCS10Message(session); 706 System.out.println("creating application/pkcs10 message..."); 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 System.out.println("\n\n*****************************************\n\n"); 718 719 // sending application/pkcs10 message where the request is in the second part 720 msg = createPKCS10MultiPartMessage(session); 721 System.out.println("creating message with pkcs10 part..."); 722 baos.reset(); 723 msg.saveChanges(); 724 msg.writeTo(baos); 725 bais = new ByteArrayInputStream(baos.toByteArray()); 726 msg = new MimeMessage(session, bais); 727 if (PRINT_MESSAGES) { 728 printMessage(msg); 729 } 730 DumpMessage.dumpMsg(msg); 731 732 System.out.println("\n\n*****************************************\n\n"); 733 734 // compressed message 735 msg = createCompressedMessage(session, multipart, (AlgorithmID)CMSAlgorithmID.zlib_compress.clone()); 736 System.out.println("creating message with compressed data..."); 737 baos.reset(); 738 msg.saveChanges(); 739 msg.writeTo(baos); 740 bais = new ByteArrayInputStream(baos.toByteArray()); 741 msg = new MimeMessage(session, bais); 742 if (PRINT_MESSAGES) { 743 printMessage(msg); 744 } 745 DumpMessage.dumpMsg(msg); 746 747 } catch (Exception ex) { 748 ex.printStackTrace(); 749 throw new RuntimeException(ex.toString()); 750 } 751 } 752 753 /** 754 * Creates a MIME message container with the given subject for the given session. 755 * 756 * @param session the mail sesion 757 * @param subject the subject of the message 758 * 759 * @return the MIME message with FROM, TO, DATE and SUBJECT headers (without content) 760 * 761 * @throws MessagingException if the message cannot be created 762 */ 763 public Message createMessage(Session session, String subject) throws MessagingException { 764 MimeMessage msg = new MimeMessage(session); 765 msg.setFrom(new InternetAddress(from_)); 766 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to_, false)); 767 msg.setSentDate(new Date()); 768 msg.setSubject(subject); 769 return msg; 770 } 771 772 /** 773 * Creates a simple plain (neither signed nor encrypted) message. 774 * 775 * @param session the mail session 776 * @param dataHandler the content of the message 777 * 778 * @return the plain message 779 * 780 * @throws MessagingException if an error occurs when creating the message 781 */ 782 public Message createPlainMessage(Session session, DataHandler dataHandler) throws MessagingException { 783 784 Message msg = createMessage(session, "IAIK-S/MIME: Plain message"); 785 if (dataHandler != null) { 786 msg.setDataHandler(dataHandler); 787 } else { 788 msg.setText("This is a plain message!\nIt is wether signed nor encrypted!\n"); 789 } 790 return msg; 791 } 792 793 /** 794 * Creates a signed and encrypted message. 795 * 796 * @param session the mail session 797 * @param contentEA the content encryption algorithm to be used 798 * @param keyLength the length of the secret content encryption key to be created and used 799 * @param dataHandler the content of the message to be signed and encrypted 800 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 801 * (multipart/signed) signing 802 * @param authEncrypt whether to create an authenticated encrypted message 803 * 804 * @return the signed and encrypted message 805 * 806 * @throws MessagingException if an error occurs when creating the message 807 */ 808 public Message createSignedAndEncryptedMessage(Session session, 809 AlgorithmID contentEA, int keyLength, 810 DataHandler dataHandler, boolean implicit, boolean authEncrypt) 811 throws MessagingException { 812 813 String subject = null; 814 String text = null; 815 if (implicit) { 816 subject = "IAIK-S/MIME: Implicitly signed and " + (authEncrypt ? "authenticated " : "") + "encrypted"; 817 text = "This message is implicitly signed and " + (authEncrypt ? "authenticated " : "") + "encrypted!\n\n\n"; 818 } else { 819 subject = "IAIK-S/MIME: explicitly signed and " + (authEncrypt ? "authenticated " : "") + " encrypted"; 820 text = "This message is explicitly signed and " + (authEncrypt ? "authenticated " : "") + " encrypted!\n\n\n"; 821 } 822 Message msg = createMessage(session, subject); 823 824 SignedContent sc = new SignedContent(implicit); 825 if (dataHandler != null) { 826 sc.setDataHandler(dataHandler); 827 } else { 828 sc.setText(text); 829 } 830 sc.setCertificates(signerCertificates_); 831 try { 832 sc.addSigner(signerPrivateKey_, 833 signerCertificate_, 834 (AlgorithmID)AlgorithmID.sha256.clone(), 835 (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 836 } catch (NoSuchAlgorithmException ex) { 837 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 838 } 839 840 EncryptedContent ec = null; 841 if (authEncrypt) { 842 ec = new AuthEncryptedContent(sc); 843 } else { 844 ec = new EncryptedContent(sc); 845 } 846 847 848 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 849 850 // sender wants to be able to decrypt the message 851 ec.addRecipient(senderCryptCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 852 853 // add RSA recipient 854 ec.addRecipient(rsaRecipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 855 // set the encryption algorithm 856 try { 857 ec.setEncryptionAlgorithm(algorithm, keyLength); 858 } catch (NoSuchAlgorithmException ex) { 859 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 860 } 861 msg.setContent(ec, ec.getContentType()); 862 // let the EncryptedContent update some message headers 863 ec.setHeaders(msg); 864 865 return msg; 866 } 867 868 /** 869 * Creates a signed message. 870 * 871 * @param session the mail session 872 * @param dataHandler the content of the message to be signed 873 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 874 * (multipart/signed) signing 875 * @param digestAlgorithm the digest algorithm to be used 876 * @param signatureAlgorithm the signature algorithm to be used 877 * 878 * @return the signed message 879 * 880 * @throws MessagingException if an error occurs when creating the message 881 */ 882 public Message createSignedMessage(Session session, 883 DataHandler dataHandler, 884 boolean implicit, 885 AlgorithmID digestAlgorithm, 886 AlgorithmID signatureAlgorithm) 887 throws MessagingException { 888 889 String subject = null; 890 StringBuffer buf = new StringBuffer(); 891 892 if (implicit) { 893 subject = "IAIK-S/MIME: Implicitly Signed"; 894 buf.append("This message is implicitly signed!\n"); 895 buf.append("You need an S/MIME aware mail client to view this message.\n"); 896 buf.append("\n\n"); 897 } else { 898 subject = "IAIK-S/MIME: Explicitly Signed"; 899 buf.append("This message is explicitly signed!\n"); 900 buf.append("Every mail client can view this message.\n"); 901 buf.append("Non S/MIME mail clients will show the signature as attachment.\n"); 902 buf.append("\n\n"); 903 } 904 905 Message msg = createMessage(session, subject); 906 907 SignedContent sc = new SignedContent(implicit); 908 if (dataHandler != null) { 909 sc.setDataHandler(dataHandler); 910 } else { 911 sc.setText(buf.toString()); 912 } 913 sc.setCertificates(signerCertificates_); 914 915 try { 916 sc.addSigner(signerPrivateKey_, 917 signerCertificate_, 918 (AlgorithmID)digestAlgorithm.clone(), 919 (AlgorithmID)signatureAlgorithm.clone()); 920 } catch (NoSuchAlgorithmException ex) { 921 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 922 } 923 924 msg.setContent(sc, sc.getContentType()); 925 // let the SignedContent update some message headers 926 sc.setHeaders(msg); 927 return msg; 928 } 929 930 /** 931 * Creates an encrypted message. 932 * 933 * @param session the mail session 934 * @param contentEA the content encryption algorithm to be used 935 * @param keyLength the length of the secret content encryption key to be created and used 936 * 937 * @return the encrypted message 938 * 939 * @throws MessagingException if an error occurs when creating the message 940 */ 941 public Message createEncryptedMessage(Session session, AlgorithmID contentEA, int keyLength) 942 throws MessagingException { 943 944 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 945 946 StringBuffer subject = new StringBuffer(); 947 subject.append("IAIK-S/MIME: Encrypted ["+algorithm.getName()); 948 if (keyLength > 0) { 949 subject.append("/"+keyLength); 950 } 951 subject.append("]"); 952 Message msg = createMessage(session, subject.toString()); 953 954 EncryptedContent ec = new EncryptedContent(); 955 956 StringBuffer buf = new StringBuffer(); 957 buf.append("This is the encrypted content!\n"); 958 buf.append("Content encryption algorithm: "+algorithm.getName()); 959 buf.append("\n\n"); 960 961 ec.setText(buf.toString()); 962 963 // sender wants to be able to decrypt the message 964 ec.addRecipient(senderCryptCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 965 966 // add RSA recipient 967 ec.addRecipient(rsaRecipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 968 try { 969 ec.setEncryptionAlgorithm(algorithm, keyLength); 970 } catch (NoSuchAlgorithmException ex) { 971 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 972 } 973 974 msg.setContent(ec, ec.getContentType()); 975 // let the EncryptedContent update some message headers 976 ec.setHeaders(msg); 977 978 return msg; 979 } 980 981 /** 982 * Creates an authenticated encrypted message. 983 * 984 * @param session the mail session 985 * @param contentEA the content encryption algorithm to be used 986 * @param keyLength the length of the secret content encryption key to be created and used 987 * 988 * @return the encrypted message 989 * 990 * @throws MessagingException if an error occurs when creating the message 991 */ 992 public Message createAuthEncryptedMessage(Session session, AlgorithmID contentEA, int keyLength) 993 throws MessagingException { 994 995 AlgorithmID algorithm = (AlgorithmID)contentEA.clone(); 996 997 StringBuffer subject = new StringBuffer(); 998 subject.append("IAIK-S/MIME: Authenticated Encrypted ["+algorithm.getName()); 999 if (keyLength > 0) { 1000 subject.append("/"+keyLength); 1001 } 1002 subject.append("]"); 1003 Message msg = createMessage(session, subject.toString()); 1004 1005 AuthEncryptedContent ec = new AuthEncryptedContent(); 1006 1007 StringBuffer buf = new StringBuffer(); 1008 buf.append("This is the authenticated encrypted content!\n"); 1009 buf.append("Content encryption algorithm: "+algorithm.getName()); 1010 buf.append("\n\n"); 1011 1012 ec.setText(buf.toString()); 1013 1014 // sender wants to be able to decrypt the message 1015 ec.addRecipient(senderCryptCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 1016 1017 // add RSA recipient 1018 ec.addRecipient(rsaRecipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 1019 try { 1020 ec.setEncryptionAlgorithm(algorithm, keyLength); 1021 } catch (NoSuchAlgorithmException ex) { 1022 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 1023 } 1024 1025 msg.setContent(ec, ec.getContentType()); 1026 // let the EncryptedContent update some message headers 1027 ec.setHeaders(msg); 1028 1029 return msg; 1030 } 1031 1032 /** 1033 * Creates a certs-only message. 1034 * 1035 * @param session the mail session 1036 * 1037 * @return the certs-only message 1038 * 1039 * @throws MessagingException if an error occurs when creating the message 1040 */ 1041 public Message createCertsOnlyMessage(Session session) 1042 throws MessagingException { 1043 1044 Message msg = createMessage(session, "IAIK S/MIME: Certs-only message"); 1045 //use new content types 1046 SMimeParameters.useNewContentTypes(true); 1047 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 1048 sc.setCertificates(signerCertificates_); 1049 msg.setContent(sc, sc.getContentType()); 1050 //set filename and attachment parameters 1051 sc.setHeaders(msg); 1052 1053 return msg; 1054 } 1055 1056 1057 /** 1058 * Creates a certs-only message where the certificate list is transferred as attachment. 1059 * 1060 * @param session the mail session 1061 * 1062 * @return the certs-only message 1063 * 1064 * @throws MessagingException if an error occurs when creating the message 1065 */ 1066 public Message createCertsOnlyMultiPartMessage(Session session) throws MessagingException { 1067 1068 MimeBodyPart mbp1 = new MimeBodyPart(); 1069 mbp1.setText("This is a test where the certs-only message is included in the second part!\n\n"); 1070 1071 MimeBodyPart attachment = new MimeBodyPart(); 1072 //use new content types 1073 SMimeParameters.useNewContentTypes(true); 1074 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 1075 sc.setCertificates(signerCertificates_); 1076 attachment.setContent(sc, sc.getContentType()); 1077 // let the SignedContent update some headers 1078 sc.setHeaders(attachment); 1079 Multipart mp = new MimeMultipart(); 1080 mp.addBodyPart(mbp1); 1081 mp.addBodyPart(attachment); 1082 1083 Message msg = createMessage(session, "IAIK S/MIME: Certs-only multipart message"); 1084 msg.setContent(mp, mp.getContentType()); 1085 return msg; 1086 } 1087 1088 /** 1089 * Creates a compressed message. 1090 * 1091 * @param session the mail session 1092 * @param dataHandler the datahandler supplying the content to be compressed 1093 * @param algorithm the compression algorithm to be used 1094 * 1095 * @return the compressed message 1096 * 1097 * @throws MessagingException if an error occurs when creating the message 1098 */ 1099 public Message createCompressedMessage(Session session, DataHandler dataHandler, AlgorithmID algorithm) 1100 throws MessagingException { 1101 1102 String subject = "IAIK-S/MIME: Compressed ["+algorithm.getName()+"]"; 1103 Message msg = createMessage(session, subject.toString()); 1104 1105 CompressedContent compressedContent = new CompressedContent(); 1106 1107 if (dataHandler == null) { 1108 StringBuffer buf = new StringBuffer(); 1109 buf.append("This is the compressed content!\n"); 1110 buf.append("Compression algorithm: "+algorithm.getName()); 1111 buf.append("\n\n"); 1112 compressedContent.setText(buf.toString()); 1113 } else { 1114 compressedContent.setDataHandler(dataHandler); 1115 } 1116 1117 try { 1118 compressedContent.setCompressionAlgorithm(algorithm); 1119 } catch (NoSuchAlgorithmException ex) { 1120 throw new MessagingException("Compression algorithm not supported: " + ex.getMessage()); 1121 } 1122 1123 msg.setContent(compressedContent, compressedContent.getContentType()); 1124 // let the CompressedContent update some message headers 1125 compressedContent.setHeaders(msg); 1126 1127 return msg; 1128 } 1129 1130 /** 1131 * Creates a PKCS#10 certificate request message. 1132 * 1133 * @param session the mail session 1134 * 1135 * @return the PKCS#10 certificate request message 1136 * 1137 * @throws MessagingException if an error occurs when creating the message 1138 */ 1139 public Message createPKCS10Message(Session session) 1140 throws MessagingException { 1141 1142 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request"); 1143 1144 PKCS10Content pc = new PKCS10Content(); 1145 CertificateRequest request = null; 1146 try { 1147 request = createCertificateRequest(); 1148 } catch (PKCSException ex) { 1149 throw new MessagingException(ex.getMessage()); 1150 } 1151 pc.setCertRequest(request); 1152 msg.setContent(pc, pc.getContentType()); 1153 // let the PKCS10Content update some message headers 1154 pc.setHeaders(msg); 1155 1156 return msg; 1157 } 1158 1159 1160 private CertificateRequest createCertificateRequest() throws PKCSException { 1161 try { 1162 Name subject = new Name(); 1163 subject.addRDN(ObjectID.commonName, firstName_ + " " + lastName_); 1164 subject.addRDN(ObjectID.emailAddress, from_); 1165 CertificateRequest certRequest; 1166 certRequest = new CertificateRequest(signerCertificate_.getPublicKey(), subject); 1167 certRequest.sign((AlgorithmID)AlgorithmID.sha256WithRSAEncryption.clone(), signerPrivateKey_); 1168 certRequest.verify(); 1169 return certRequest; 1170 } catch (Exception ex) { 1171 throw new PKCSException("Cannot create cert request: " + ex.getMessage()); 1172 } 1173 1174 } 1175 1176 /** 1177 * Creates a PKCS#10 message where the certificate request is transferred as attachment. 1178 * 1179 * @param session the mail session 1180 * 1181 * @return the PKCS#10 certificate request message 1182 * 1183 * @throws MessagingException if an error occurs when creating the message 1184 */ 1185 public Message createPKCS10MultiPartMessage(Session session) throws MessagingException { 1186 1187 MimeBodyPart mbp1 = new MimeBodyPart(); 1188 mbp1.setText("This is a test where the request message is included in the second part!\n\n"); 1189 // try to test an attachment 1190 // this demo attaches our homepage 1191 MimeBodyPart attachment = new MimeBodyPart(); 1192 //use new content types 1193 SMimeParameters.useNewContentTypes(true); 1194 PKCS10Content pc = new PKCS10Content(); 1195 CertificateRequest request = null; 1196 try { 1197 request = createCertificateRequest(); 1198 } catch (PKCSException ex) { 1199 throw new MessagingException(ex.getMessage()); 1200 } 1201 pc.setCertRequest(request); 1202 DataHandler pkcs10Handler = new DataHandler(pc, pc.getContentType()); 1203 attachment.setDataHandler(pkcs10Handler); 1204 attachment.setDisposition("attachment"); 1205 attachment.setFileName("smime.p10"); 1206 Multipart mp = new MimeMultipart(); 1207 mp.addBodyPart(mbp1); 1208 mp.addBodyPart(attachment); 1209 1210 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request multipart message"); 1211 msg.setContent(mp, mp.getContentType()); 1212 return msg; 1213 } 1214 1215 /** 1216 * Prints a dump of the given message to System.out. 1217 * 1218 * @param msg the message to be dumped to System.out 1219 * 1220 * @throws IOException if an I/O error occurs 1221 */ 1222 static void printMessage(Message msg) throws IOException { 1223 System.out.println("------------------------------------------------------------------"); 1224 System.out.println("Message dump: \n"); 1225 try { 1226 msg.writeTo(System.out); 1227 } catch (MessagingException ex) { 1228 throw new IOException(ex.getMessage()); 1229 } 1230 System.out.println("\n------------------------------------------------------------------"); 1231 } 1232 1233 /** 1234 * The main method. 1235 */ 1236 public static void main(String[] argv) throws IOException { 1237 1238 DemoSMimeUtil.initDemos(); 1239 (new SMimeV4Demo()).start(); 1240 System.out.println("\nReady!"); 1241 DemoUtil.waitKey(); 1242 } 1243 }