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