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/ecc/SimpleSMimeV4EcDemo.java 5     12.02.25 17:59 Dbratko $
029// $Revision: 5 $
030//
031
032package demo.smime.ecc;
033
034import java.security.PrivateKey;
035
036import jakarta.activation.DataHandler;
037import jakarta.mail.Session;
038
039import demo.DemoSMimeUtil;
040import demo.DemoUtil;
041import demo.cms.ecc.ECCDemoUtil;
042import demo.cms.ecc.keystore.CMSEccKeyStore;
043import iaik.asn1.structures.AlgorithmID;
044import iaik.cms.CMSAlgorithmID;
045import iaik.utils.KeyAndCertificate;
046import iaik.x509.X509Certificate;
047
048/**
049 * This class demonstrates the usage of the IAIK S/MIME implementation. It shows how to create
050 * signed and/or (authenticated) encrypted S/MIMEv4 messages using EC keys and how to parse them
051 * and verify the signatures and decrypt the content, respectively.
052 * <p>
053 * This demo uses one set of cryptographic algorithms. A demo that uses several combinations of algorithms
054 * is shown in {@link SMimeV4EccDemo SMimeV4EccDemo}.
055 * <p>
056 * Additionally to <code>iaik_cms.jar</code> you also must have 
057 * <code>iaik_jce_(full).jar</code> (IAIK-JCE, <a href =
058 * "https://sic.tech/products/core-crypto-toolkits/jca-jce/" target="_blank">
059 * https://sic.tech/products/core-crypto-toolkits/jca-jce/</a>),
060 * and <code>iaik_eccelarate.jar</code> (IAIK-ECCelerate<sup><small>TM</small></sup>, <a href =
061 * "https://sic.tech/products/core-crypto-toolkits/eccelerate/" target="_blank">
062 * https://sic.tech/products/core-crypto-toolkits/eccelerate/</a>)
063 * in your classpath.
064 * <p>
065 * To run this demo the following packages are required:
066 * <ul>
067 *    <li>
068 *       <code>iaik_cms.jar</code> (IAIK-CMS/SMIME)
069 *    </li>
070 *    <li>
071 *       <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>).
072 *    </li>
073 *    <li>
074 *       <code>iaik_eccelerate.jar</code> (<a href="https://sic.tech/products/core-crypto-toolkits/eccelerate/" target="_blank">IAIK ECC Library</a>).
075 *    </li>
076 *    <li>
077 *       <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
078 *    </li>   
079 *    <li>
080 *       <a href="https://jakarta.ee/specifications/activation/" target="_blank">Jakarta Activation Framework</a>
081 *    </li> 
082 * </ul>
083 */
084public class SimpleSMimeV4EcDemo extends SMimeV4EccDemo {
085 
086  /**
087   * Default constructor. 
088   */
089  public SimpleSMimeV4EcDemo() {
090    
091    System.out.println();
092    System.out.println("********************************************************************************************");
093    System.out.println("*                                SimpleSMimeV4EcDemo demo                                  *");
094    System.out.println("* (shows how to create and parse (verify, decrypt) signed and encrypted S/MIMEv4 messages) *");
095    System.out.println("********************************************************************************************");
096    System.out.println();
097
098  }
099  
100   
101  /**
102   * Starts the demo.
103   *
104   * @throws Exception if an error occurs
105   */
106  public void start() throws Exception {
107    
108    // get the default Session
109    Session session = DemoSMimeUtil.getSession();
110
111    // Create a demo Multipart
112    DataHandler multipart = createMultipart();
113    
114    // get signer key and certs
115    KeyAndCertificate signerKeyAndCert = getSignerKeyAndCert();
116    PrivateKey signerKey = signerKeyAndCert.getPrivateKey();
117    X509Certificate[] signerCerts = signerKeyAndCert.getCertificateChain();
118     
119    // the digest and signature algorithms to be used
120    AlgorithmID digestAlg = getDigestAlgorithm();
121    AlgorithmID signatureAlg = getSignatureAlgorithm();
122   
123    /**************************************************************************/
124    /*                                                                        */
125    /*                               Signing Demo                             */
126    /*                                                                        */
127    /**************************************************************************/
128    
129    System.out.println("Running signing demo for " + signatureAlg.getName());
130    startSigningDemo(session, 
131                     multipart, 
132                     digestAlg, 
133                     signatureAlg, 
134                     signerKey,
135                     signerCerts);
136     
137    // (authenticated) encryption demos
138    
139    // get recipient certs
140    X509Certificate[] recipientCerts = getRecipientCerts();
141     
142    //  the key encryption algorithms to be used
143    AlgorithmID keyEA = AlgorithmID.dhSinglePass_stdDH_sha256kdf_scheme;
144    // key wrap algorithms
145    AlgorithmID keyWrapAlg = CMSAlgorithmID.cms_aes256_wrap;
146    int kekLength = 256;
147    int keyLength = 256;
148    
149    // whether to encrypt or authenticated encrypt
150    boolean[] doAuthEncrypt = { false, true };
151    for (int h = 0; h < doAuthEncrypt.length; h++) {
152      boolean authEncrypt = doAuthEncrypt[h]; 
153      AlgorithmID contentEA = authEncrypt ? AlgorithmID.aes256_GCM : AlgorithmID.aes256_CBC;
154      
155      /**************************************************************************/
156      /*                                                                        */
157      /*                  (Authenticated) Encryption Demo                       */
158      /*                                                                        */
159      /**************************************************************************/
160      
161      System.out.println("Running " + (authEncrypt ? "authenticated" : "") + "encryption demo for " + 
162                        keyEA.getName() + " with " + keyWrapAlg.getName() +" and " + contentEA.getName());
163      startEncryptionDemo(session,
164                          contentEA, 
165                          keyLength, 
166                          keyEA,
167                          keyWrapAlg,
168                          kekLength,
169                          authEncrypt, 
170                          recipientCerts);
171      
172      /**************************************************************************/
173      /*                                                                        */
174      /*             Signing and (Authenticated) Encryption Demo                */
175      /*                                                                        */
176      /**************************************************************************/
177            
178      startSigningAndEncryptionDemo(session,
179                                    multipart,
180                                    digestAlg,
181                                    signatureAlg,
182                                    contentEA, 
183                                    keyLength, 
184                                    keyEA,
185                                    keyWrapAlg,
186                                    kekLength,
187                                    authEncrypt,  
188                                    signerKey, 
189                                    signerCerts,
190                                    recipientCerts);
191    }
192    
193  } 
194  
195  /**
196   * Gets signing key and certificate.
197   * 
198   * @return signing key and certificate
199   */
200  protected KeyAndCertificate getSignerKeyAndCert() {
201    return new KeyAndCertificate(
202        CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA,
203            CMSEccKeyStore.SZ_256_SIGN),
204        CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA,
205            CMSEccKeyStore.SZ_256_SIGN));
206  }
207  
208  /**
209   * Gets the digest algorithm used for signing.
210   * 
211   * @return the digest algorithm
212   */
213  protected AlgorithmID getDigestAlgorithm() {
214    return AlgorithmID.sha256;
215  }
216  
217  /**
218   * Gets the signature algorithm.
219   * 
220   * @return the signature algorithm
221   */
222  protected AlgorithmID getSignatureAlgorithm() {
223    return AlgorithmID.ecdsa_With_SHA256;
224  }
225  
226  /**
227   * Gets the recipient certificates.
228   * 
229   * @return the certificates of the recipients
230   */
231  protected X509Certificate[] getRecipientCerts() {
232    X509Certificate[] recipientCerts = {
233        CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH,
234                CMSEccKeyStore.SZ_256_CRYPT_1)[0],
235        CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH,
236                CMSEccKeyStore.SZ_256_CRYPT_2)[0],
237    };
238    return recipientCerts;
239  }
240  
241 
242  /**
243   * The main method.
244   */
245  public static void main(String[] argv) throws Exception {
246     
247    DemoSMimeUtil.initDemos();
248    //  add ECC provider    
249    ECCDemoUtil.installIaikEccProvider();
250    
251        (new SimpleSMimeV4EcDemo()).start();
252    System.out.println("\nReady!");
253    DemoUtil.waitKey();
254  }
255}