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