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/SMimeSendDemo.java 38 12.02.25 17:58 Dbratko $ 059 // $Revision: 38 $ 060 // 061 062 package demo.smime.basic; 063 064 import iaik.asn1.ObjectID; 065 import iaik.asn1.structures.AlgorithmID; 066 import iaik.asn1.structures.Name; 067 import iaik.pkcs.PKCSException; 068 import iaik.pkcs.pkcs10.CertificateRequest; 069 import iaik.smime.EncryptedContent; 070 import iaik.smime.PKCS10Content; 071 import iaik.smime.SMimeBodyPart; 072 import iaik.smime.SMimeMultipart; 073 import iaik.smime.SMimeParameters; 074 import iaik.smime.SignedContent; 075 import iaik.x509.X509Certificate; 076 077 import java.io.IOException; 078 import java.security.NoSuchAlgorithmException; 079 import java.security.PrivateKey; 080 import java.security.interfaces.RSAPrivateKey; 081 import java.util.Date; 082 083 import javax.activation.DataHandler; 084 import javax.activation.FileDataSource; 085 import javax.mail.Message; 086 import javax.mail.MessagingException; 087 import javax.mail.Multipart; 088 import javax.mail.Session; 089 import javax.mail.Transport; 090 import javax.mail.internet.InternetAddress; 091 import javax.mail.internet.MimeBodyPart; 092 import javax.mail.internet.MimeMessage; 093 import javax.mail.internet.MimeMultipart; 094 095 import demo.DemoSMimeUtil; 096 import demo.DemoUtil; 097 import demo.keystore.CMSKeyStore; 098 099 /** 100 * This class demonstrates the usage of the IAIK S/MIME implementation for sending 101 * signed and/or encryped emails based on the JavaMail API. 102 * <p> 103 * To run this demo the following packages are required: 104 * <ul> 105 * <li> 106 * <code>iaik_cms.jar</code> (IAIK-CMS/SMIME) 107 * </li> 108 * <li> 109 * <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>). 110 * </li> 111 * <li> 112 * <code>mail.jar</code> (<a href="http://www.oracle.com/technetwork/java/javamail/index.html" target="_blank">JavaMail API</a>). 113 * </li> 114 * <li> 115 * <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). 116 * </li> 117 * </ul> 118 * 119 * <b>Usage:</b> 120 * <pre> 121 * SMimeSend [-H host] [-S sender name] [-F (From) sender address] [-T (To) recipient address] 122 * </pre> 123 * <b>Example</b>: 124 * <pre> 125 * SMimeSend -H mailhost -S \"John SMime\" -F smimetest@iaik.tugraz.at -T smimetest@iaik.tugraz.at 126 * </pre> 127 * By default this demo used "mailhost" as host, "John SMime" as sender name, and "smimetest@iaik.tugraz.at" 128 * as sender and also as recipient mail address. "smimetest@iaik.tugraz.at" is also the email address 129 * contained in the demo certificates. Although you should specify other email addresses to send 130 * the test messages to yourself, be aware that the certificate email check may fail on the 131 * receiving side ({@link SMimeShowDemo SMimeShowDemo}). 132 * 133 * @see iaik.smime.EncryptedContent 134 * @see iaik.smime.SignedContent 135 */ 136 public class SMimeSendDemo { 137 138 String senderName_ = "John SMime"; 139 String to_ = "smimetest@iaik.tugraz.at"; // email recipient 140 String from_ = "smimetest@iaik.tugraz.at"; // email sender 141 String host_ = "mailhost"; // name of the mailhost 142 143 X509Certificate[] signerCertificates_; // list of certificates to include in the S/MIME message 144 X509Certificate recipientCertificate_; // certificate of the recipient 145 X509Certificate signerCertificate_; // certificate of the signer/sender 146 X509Certificate encryptionCertOfSigner_; // signer uses different certificate for encryption 147 PrivateKey signerPrivateKey_; // private key of the signer/sender 148 149 /** 150 * Default constructor. Reads certificates and keys from the demo keystore. 151 */ 152 public SMimeSendDemo() { 153 154 System.out.println(); 155 System.out.println("******************************************************************************************"); 156 System.out.println("* SMimeSend demo *"); 157 System.out.println("* (shows how to create and send signed and encrypted S/MIME messages) *"); 158 System.out.println("******************************************************************************************"); 159 System.out.println(); 160 161 // get the certificates from the KeyStore 162 signerCertificates_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1); 163 signerPrivateKey_ = CMSKeyStore.getPrivateKey(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_SIGN_1); 164 signerCertificate_ = signerCertificates_[0]; 165 166 // recipient = signer for this test 167 recipientCertificate_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_2)[0]; 168 encryptionCertOfSigner_ = CMSKeyStore.getCertificateChain(CMSKeyStore.RSA, CMSKeyStore.SZ_2048_CRYPT_1)[0]; 169 170 // send the encryption cert of the signer along with the signer certificates 171 X509Certificate[] tmpCerts = new X509Certificate[signerCertificates_.length + 1]; 172 System.arraycopy(signerCertificates_, 0, tmpCerts, 0, signerCertificates_.length); 173 tmpCerts[signerCertificates_.length] = encryptionCertOfSigner_; 174 signerCertificates_ = tmpCerts; 175 } 176 177 /** 178 * Starts the demo. 179 * 180 * 181 * @param argv optional parameters like mailhost, sender name,... 182 * 183 * @throws IOException if an I/O related error occurs 184 */ 185 public void start(String[] argv) throws IOException { 186 187 int optind = 0; 188 if (argv.length > 0) { 189 for (optind = 0; optind < argv.length; optind++) { 190 if (argv[optind].equals("-H")) { 191 host_ = argv[++optind]; 192 } else if (argv[optind].equals("-S")) { 193 senderName_ = argv[++optind]; 194 } else if (argv[optind].equals("-F")) { 195 from_ = argv[++optind]; 196 } else if (argv[optind].equals("-T")) { 197 to_ = argv[++optind]; 198 } else { 199 System.out.println("Usage: SMimeSend [-H host] [-S sender name] [-F (From) sender address] [-T (To) recipient address]"); 200 System.out.println("e.g.:"); 201 System.out.println("Usage: SMimeSend -H mailhost -S \"John SMime\" -F smimetest@iaik.tugraz.at -T smimetest@iaik.tugraz.at"); 202 System.exit(1); 203 } 204 } 205 } 206 207 208 // get the default Session 209 Session session = DemoSMimeUtil.getSession(host_); 210 211 try { 212 // Create a demo Multipart 213 MimeBodyPart mbp1 = new SMimeBodyPart(); 214 mbp1.setText("This is a Test of the IAIK S/MIME implementation!\n\n"); 215 // try to test an attachment 216 MimeBodyPart attachment = new SMimeBodyPart(); 217 attachment.setDataHandler(new DataHandler(new FileDataSource("test.html"))); 218 attachment.setFileName("test.html"); 219 Multipart mp = new SMimeMultipart(); 220 mp.addBodyPart(mbp1); 221 mp.addBodyPart(attachment); 222 DataHandler multipart = new DataHandler(mp, mp.getContentType()); 223 224 Message msg; // the message to send 225 226 // 1. This is a plain message 227 msg = createPlainMessage(session, multipart); 228 System.out.println("sending plain message..."); 229 Transport.send(msg); 230 231 // 2. This is an explicitly signed message 232 msg = createSignedMessage(session, multipart, false); 233 System.out.println("sending explicitly signed message..."); 234 Transport.send(msg); 235 236 // 3. This is an implicitly signed message 237 msg = createSignedMessage(session, multipart, true); 238 System.out.println("sending implicitly signed message..."); 239 Transport.send(msg); 240 241 // 4. Now create encrypted messages with different content encryption algorithms 242 // RC2 is deprecated; only demonstrated here 243 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 40); 244 System.out.println("sending encrypted message [RC2/40]..."); 245 Transport.send(msg); 246 247 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 64); 248 System.out.println("sending encrypted message [RC2/64]..."); 249 Transport.send(msg); 250 251 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.rc2_CBC.clone(), 128); 252 System.out.println("sending encrypted message [RC2/128]..."); 253 Transport.send(msg); 254 255 // TripleDES is deprecated; only demonstrated here 256 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.des_EDE3_CBC.clone(), 192); 257 System.out.println("sending encrypted message [TripleDES]..."); 258 Transport.send(msg); 259 260 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes128_CBC.clone(), 128); 261 System.out.println("sending encrypted message [AES-128]..."); 262 Transport.send(msg); 263 264 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes192_CBC.clone(), 192); 265 System.out.println("sending encrypted message [AES-192]..."); 266 Transport.send(msg); 267 268 msg = createEncryptedMessage(session, (AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256); 269 System.out.println("sending encrypted message [AES-256]..."); 270 Transport.send(msg); 271 272 // 5. Now create a implicitly signed and encrypted message with attachment 273 msg = createSignedAndEncryptedMessage(session, multipart, true); 274 System.out.println("sending implicitly signed and encrypted message [AES-256]..."); 275 Transport.send(msg); 276 277 // 6. Now create a explicitly signed and encrypted message with attachment 278 msg = createSignedAndEncryptedMessage(session, multipart, false); 279 System.out.println("sending explicitly signed and encrypted message [AES-256]..."); 280 Transport.send(msg); 281 282 // 7. certs only message 283 msg = createCertsOnlyMessage(session); 284 System.out.println("sending certs-only message"); 285 Transport.send(msg); 286 287 // 8. second certs only message 288 msg = createCertsOnlyMultiPartMessage(session); 289 System.out.println("sending message with certs-only part"); 290 Transport.send(msg); 291 292 //sending cert request 293 msg = createPKCS10Message(session); 294 System.out.println("sending application/pkcs10 message..."); 295 Transport.send(msg); 296 297 // ending application/pkcs10 message where the request is in the second part 298 msg = createPKCS10MultiPartMessage(session); 299 System.out.println("sending message with pkcs10 part..."); 300 Transport.send(msg); 301 302 } catch (MessagingException mex) { 303 mex.printStackTrace(); 304 Exception ex = null; 305 if ((ex = mex.getNextException()) != null) { 306 ex.printStackTrace(); 307 } 308 throw new RuntimeException(mex.toString()); 309 } 310 311 } 312 313 /** 314 * Creates a MIME message container with the given subject for the given session. 315 * 316 * @param session the mail sesion 317 * @param subject the subject of the message 318 * 319 * @return the MIME message with FROM, TO, DATE and SUBJECT headers (without content) 320 * 321 * @throws MessagingException if the message cannot be created 322 */ 323 public Message createMessage(Session session, String subject) throws MessagingException { 324 MimeMessage msg = new MimeMessage(session); 325 msg.setFrom(new InternetAddress(from_)); 326 msg.setRecipients(Message.RecipientType.TO, InternetAddress.parse(to_, false)); 327 msg.setSentDate(new Date()); 328 msg.setSubject(subject); 329 return msg; 330 } 331 332 /** 333 * Creates a simple plain (neither signed nor encrypted) message. 334 * 335 * @param session the mail session 336 * @param dataHandler the content of the message 337 * 338 * @return the plain message 339 * 340 * @throws MessagingException if an error occurs when creating the message 341 */ 342 public Message createPlainMessage(Session session, DataHandler dataHandler) throws MessagingException { 343 344 Message msg = createMessage(session, "IAIK-S/MIME: Plain message"); 345 if (dataHandler != null) { 346 msg.setDataHandler(dataHandler); 347 } else { 348 msg.setText("This is a plain message!\nIt is wether signed nor encrypted!\n"); 349 } 350 return msg; 351 } 352 353 /** 354 * Creates a signed and encrypted message. 355 * 356 * @param session the mail session 357 * @param dataHandler the content of the message to be signed and encrypted 358 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 359 * (multipart/signed) signing 360 * 361 * @return the signed and encrypted message 362 * 363 * @throws MessagingException if an error occurs when creating the message 364 */ 365 public Message createSignedAndEncryptedMessage(Session session, DataHandler dataHandler, boolean implicit) 366 throws MessagingException { 367 368 String subject = null; 369 String text = null; 370 if (implicit) { 371 subject = "IAIK-S/MIME: Implicitly Signed and Encrypted"; 372 text = "This message is implicitly signed and encrypted!\n\n\n"; 373 } else { 374 subject = "IAIK-S/MIME: Explicitly Signed and Encrypted"; 375 text = "This message is explicitly signed and encrypted!\n\n\n"; 376 } 377 Message msg = createMessage(session, subject); 378 379 SignedContent sc = new SignedContent(implicit); 380 if (dataHandler != null) { 381 sc.setDataHandler(dataHandler); 382 } else { 383 sc.setText(text); 384 } 385 sc.setCertificates(signerCertificates_); 386 try { 387 sc.addSigner((RSAPrivateKey)signerPrivateKey_, signerCertificate_, encryptionCertOfSigner_, true); 388 } catch (NoSuchAlgorithmException ex) { 389 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 390 } 391 392 EncryptedContent ec = new EncryptedContent(sc); 393 // encrypt for the recipient 394 ec.addRecipient(recipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 395 // I want to be able to decrypt the message, too 396 ec.addRecipient(encryptionCertOfSigner_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 397 // set the encryption algorithm 398 try { 399 ec.setEncryptionAlgorithm((AlgorithmID)AlgorithmID.aes256_CBC.clone(), 256); 400 } catch (NoSuchAlgorithmException ex) { 401 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 402 } 403 msg.setContent(ec, ec.getContentType()); 404 // let the EncryptedContent update some message headers 405 ec.setHeaders(msg); 406 407 return msg; 408 } 409 410 /** 411 * Creates a signed message. 412 * 413 * @param session the mail session 414 * @param dataHandler the content of the message to be signed 415 * @param implicit whether to use implicit (application/pkcs7-mime) or explicit 416 * (multipart/signed) signing 417 * 418 * @return the signed message 419 * 420 * @throws MessagingException if an error occurs when creating the message 421 */ 422 public Message createSignedMessage(Session session, DataHandler dataHandler, boolean implicit) 423 throws MessagingException { 424 425 String subject = null; 426 StringBuffer buf = new StringBuffer(); 427 428 if (implicit) { 429 subject = "IAIK-S/MIME: Implicitly Signed"; 430 buf.append("This message is implicitly signed!\n"); 431 buf.append("You need an S/MIME aware mail client to view this message.\n"); 432 buf.append("\n\n"); 433 } else { 434 subject = "IAIK-S/MIME: Explicitly Signed"; 435 buf.append("This message is explicitly signed!\n"); 436 buf.append("Every mail client can view this message.\n"); 437 buf.append("Non S/MIME mail clients will show the signature as attachment.\n"); 438 buf.append("\n\n"); 439 } 440 441 Message msg = createMessage(session, subject); 442 443 SignedContent sc = new SignedContent(implicit); 444 if (dataHandler != null) { 445 sc.setDataHandler(dataHandler); 446 } else { 447 sc.setText(buf.toString()); 448 } 449 sc.setCertificates(signerCertificates_); 450 451 try { 452 sc.addSigner((RSAPrivateKey)signerPrivateKey_, signerCertificate_, encryptionCertOfSigner_, true); 453 } catch (NoSuchAlgorithmException ex) { 454 throw new MessagingException("Algorithm not supported: " + ex.getMessage(), ex); 455 } 456 457 msg.setContent(sc, sc.getContentType()); 458 // let the SignedContent update some message headers 459 sc.setHeaders(msg); 460 return msg; 461 } 462 463 /** 464 * Creates an encrypted message. 465 * 466 * @param session the mail session 467 * @param algorithm the content encryption algorithm to be used 468 * @param keyLength the length of the secret content encryption key to be created and used 469 * 470 * @return the encrypted message 471 * 472 * @throws MessagingException if an error occurs when creating the message 473 */ 474 public Message createEncryptedMessage(Session session, AlgorithmID algorithm, int keyLength) 475 throws MessagingException { 476 477 StringBuffer subject = new StringBuffer(); 478 subject.append("IAIK-S/MIME: Encrypted ["+algorithm.getName()); 479 if (keyLength > 0) { 480 subject.append("/"+keyLength); 481 } 482 subject.append("]"); 483 Message msg = createMessage(session, subject.toString()); 484 485 EncryptedContent ec = new EncryptedContent(); 486 487 StringBuffer buf = new StringBuffer(); 488 buf.append("This is the encrypted content!\n"); 489 buf.append("Content encryption algorithm: "+algorithm.getName()); 490 buf.append("\n\n"); 491 492 ec.setText(buf.toString()); 493 // encrypt for the recipient 494 ec.addRecipient(recipientCertificate_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 495 // I want to be able to decrypt the message, too 496 ec.addRecipient(encryptionCertOfSigner_, (AlgorithmID)AlgorithmID.rsaEncryption.clone()); 497 try { 498 ec.setEncryptionAlgorithm(algorithm, keyLength); 499 } catch (NoSuchAlgorithmException ex) { 500 throw new MessagingException("Content encryption algorithm not supported: " + ex.getMessage()); 501 } 502 503 msg.setContent(ec, ec.getContentType()); 504 // let the EncryptedContent update some message headers 505 ec.setHeaders(msg); 506 507 return msg; 508 } 509 510 /** 511 * Creates a certs-only message. 512 * 513 * @param session the mail session 514 * 515 * @return the certs-only message 516 * 517 * @throws MessagingException if an error occurs when creating the message 518 */ 519 public Message createCertsOnlyMessage(Session session) 520 throws MessagingException { 521 522 Message msg = createMessage(session, "IAIK S/MIME: Certs-only message"); 523 //use new content types 524 SMimeParameters.useNewContentTypes(true); 525 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 526 sc.setCertificates(signerCertificates_); 527 msg.setContent(sc, sc.getContentType()); 528 //set filename and attachment parameters 529 sc.setHeaders(msg); 530 531 532 return msg; 533 } 534 535 536 /** 537 * Creates a certs-only message where the certificate list is transferred as attachment. 538 * 539 * @param session the mail session 540 * 541 * @return the certs-only message 542 * 543 * @throws MessagingException if an error occurs when creating the message 544 */ 545 public Message createCertsOnlyMultiPartMessage(Session session) throws MessagingException { 546 547 MimeBodyPart mbp1 = new MimeBodyPart(); 548 mbp1.setText("This is a test where the certs-only message is included in the second part!\n\n"); 549 550 MimeBodyPart attachment = new MimeBodyPart(); 551 //use new content types 552 SMimeParameters.useNewContentTypes(true); 553 SignedContent sc = new SignedContent(true, SignedContent.CERTS_ONLY); 554 sc.setCertificates(signerCertificates_); 555 attachment.setContent(sc, sc.getContentType()); 556 // let the SignedContent update some message headers 557 sc.setHeaders(attachment); 558 Multipart mp = new MimeMultipart(); 559 mp.addBodyPart(mbp1); 560 mp.addBodyPart(attachment); 561 562 Message msg = createMessage(session, "IAIK S/MIME: Certs-only multipart message"); 563 msg.setContent(mp, mp.getContentType()); 564 return msg; 565 } 566 567 568 /** 569 * Creates a PKCS#10 certificate request message. 570 * 571 * @param session the mail session 572 * 573 * @return the PKCS#10 certificate request message 574 * 575 * @throws MessagingException if an error occurs when creating the message 576 */ 577 public Message createPKCS10Message(Session session) 578 throws MessagingException { 579 580 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request"); 581 582 PKCS10Content pc = new PKCS10Content(); 583 CertificateRequest request = null; 584 try { 585 request = createCertificateRequest(); 586 } catch (PKCSException ex) { 587 throw new MessagingException(ex.getMessage()); 588 } 589 pc.setCertRequest(request); 590 msg.setContent(pc, pc.getContentType()); 591 // let the PKCS10Content update some message headers 592 pc.setHeaders(msg); 593 594 return msg; 595 } 596 597 /** 598 * Creates a PKCS#10 certificate request. 599 * 600 * @return the certificate request 601 * 602 * @throws PKCSException if the request cannot be created 603 */ 604 private CertificateRequest createCertificateRequest() throws PKCSException { 605 try { 606 Name subject = new Name(); 607 subject.addRDN(ObjectID.commonName, senderName_); 608 subject.addRDN(ObjectID.emailAddress, from_); 609 CertificateRequest certRequest; 610 611 certRequest = new CertificateRequest(signerCertificate_.getPublicKey(), subject); 612 certRequest.sign((AlgorithmID)AlgorithmID.sha256WithRSAEncryption.clone(), signerPrivateKey_); 613 certRequest.verify(); 614 return certRequest; 615 } catch (Exception ex) { 616 throw new PKCSException("Cannot create cert request: " + ex.getMessage()); 617 } 618 619 } 620 621 /** 622 * Creates a PKCS#10 message where the certificate request is transferred as attachment. 623 * 624 * @param session the mail session 625 * 626 * @return the PKCS#10 certificate request message 627 * 628 * @throws MessagingException if an error occurs when creating the message 629 */ 630 public Message createPKCS10MultiPartMessage(Session session) throws MessagingException { 631 632 MimeBodyPart mbp1 = new MimeBodyPart(); 633 mbp1.setText("This is a test where the request message is included in the second part!\n\n"); 634 // try to test an attachment 635 // this demo attaches our homepage 636 MimeBodyPart attachment = new MimeBodyPart(); 637 //use new content types 638 SMimeParameters.useNewContentTypes(true); 639 PKCS10Content pc = new PKCS10Content(); 640 CertificateRequest request = null; 641 try { 642 request = createCertificateRequest(); 643 } catch (PKCSException ex) { 644 throw new MessagingException(ex.getMessage()); 645 } 646 pc.setCertRequest(request); 647 DataHandler pkcs10Handler = new DataHandler(pc, pc.getContentType()); 648 attachment.setDataHandler(pkcs10Handler); 649 attachment.setDisposition("attachment"); 650 attachment.setFileName("smime.p10"); 651 Multipart mp = new MimeMultipart(); 652 mp.addBodyPart(mbp1); 653 mp.addBodyPart(attachment); 654 655 Message msg = createMessage(session, "IAIK-S/MIME: Certificate Request multipart message"); 656 msg.setContent(mp, mp.getContentType()); 657 return msg; 658 } 659 660 661 /** 662 * Main method. 663 */ 664 public static void main(String[] argv) throws IOException { 665 666 DemoSMimeUtil.initDemos(); 667 (new SMimeSendDemo()).start(argv); 668 System.out.println("\nReady!"); 669 DemoUtil.waitKey(); 670 } 671 }