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/cms/ecc/StaticStaticECDHDemo.java 4     12.02.25 17:58 Dbratko $
059    // $Revision: 4 $
060    //
061    
062    
063    package demo.cms.ecc;
064    
065    import iaik.asn1.structures.AlgorithmID;
066    import iaik.cms.CMSAlgorithmID;
067    import iaik.cms.CMSException;
068    import iaik.cms.CertificateIdentifier;
069    import iaik.cms.KeyAgreeRecipientInfo;
070    import iaik.cms.KeyIdentifier;
071    import iaik.cms.RecipientInfo;
072    import iaik.security.random.SecRandom;
073    import iaik.x509.X509Certificate;
074    
075    import java.io.IOException;
076    import java.security.PrivateKey;
077    import java.security.SecureRandom;
078    
079    import demo.cms.ecc.keystore.CMSEccKeyStore;
080    
081    /**
082     * Base class for {@link ECDHAuthEnvelopedDataDemo ECDHAuthEnvelopedDataDemo} and
083     * {@link ECDHAuthenticatedDataDemo ECDHAuthenticatedDataDemo} demonstrating the
084     * usage of the CMS AuthEnvelopedData and AuthenticatedData content types
085     * by using Static-Static ECDH according to <a href = 
086     * "http://www.ietf.org/rfc/rfc6278.txt" target="_blank">6278</a> as 
087     * key agreement method.
088     * <p>
089     * Reads keys/certificates required for this demo from a keystore
090     * file "cmsecc.keystore" located in your current working directory. If
091     * the keystore file does not exist you can create it by running the
092     * {@link demo.cms.ecc.keystore.SetupCMSEccKeyStore SetupCMSEccKeyStore}
093     * program. 
094     * <p>
095     * Additionally to <code>iaik_cms.jar</code> you also must have 
096     * <code>iaik_jce_(full).jar</code> (IAIK-JCE, <a href =
097     * "https://sic.tech/products/core-crypto-toolkits/jca-jce/" target="_blank">
098     * https://sic.tech/products/core-crypto-toolkits/jca-jce/</a>),
099     * and <code>iaik_eccelarate.jar</code> (IAIK-ECCelerate<sup><small>TM</small></sup>, <a href =
100     * "https://sic.tech/products/core-crypto-toolkits/eccelerate/" target="_blank">
101     * https://sic.tech/products/core-crypto-toolkits/eccelerate/</a>)
102     * in your classpath.
103     *
104     * @see ECDHAuthEnvelopedDataDemo
105     * @see ECDHAuthenticatedDataDemo
106     * @see iaik.cms.AuthEnvelopedDataStream
107     * @see iaik.cms.AuthEnvelopedData
108     * @see iaik.cms.AuthEnvelopedDataOutputStream
109     * @see iaik.cms.RecipientInfo
110     * @see iaik.cms.KeyAgreeRecipientInfo
111     * @see demo.cms.ecc.keystore.SetupCMSEccKeyStore
112     */
113    public abstract class StaticStaticECDHDemo {
114    
115      // certificate of ecdhUser 1
116      X509Certificate ecdhUser1_;
117      // private key of ecdhUser 1
118      PrivateKey ecdhUser1Pk_;
119      // certificate of ecdhUser 2
120      X509Certificate ecdhUser2_;
121      // private key of ecdhUser 2
122      PrivateKey ecdhUser2Pk_;
123      
124      //SSDH
125      X509Certificate[] ecdhOriginatorCerts_;
126      //certificate of SSDH originator
127      X509Certificate ecdhOriginator_;
128      //private key of SSDH originator 
129      PrivateKey ecdhOriginatorPk_;
130      
131      // secure random number generator
132      SecureRandom random_;
133    
134      /**
135       * Setup the demo certificate chains.
136       *
137       * Keys and certificates are retrieved from the demo keyStore file
138       * "cmsecc.keystore" located in your current working directory. If
139       * the keystore file does not exist you can create it by running the
140       * {@link demo.cms.ecc.keystore.SetupCMSEccKeyStore SetupCMSEccKeyStore}
141       * program. 
142       *
143       * @throws IOException if keys/certificates cannot be read from the keystore
144       */
145      public StaticStaticECDHDemo() throws IOException {
146        
147        // add all certificates to the list
148        X509Certificate[] ecdhUser1Certs = CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, CMSEccKeyStore.SZ_256_CRYPT_1);
149        ecdhUser1_ = CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, CMSEccKeyStore.SZ_256_CRYPT_1)[0];
150        ecdhUser1Pk_ = CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDH, CMSEccKeyStore.SZ_256_CRYPT_1);
151        ecdhUser2_ = CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, CMSEccKeyStore.SZ_256_CRYPT_2)[0];
152        ecdhUser2Pk_ = CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDH, CMSEccKeyStore.SZ_256_CRYPT_2);
153        
154        // originator is ECDH user 1
155        ecdhOriginatorCerts_ = ecdhUser1Certs;
156        ecdhOriginator_ = ecdhOriginatorCerts_[0];
157        ecdhOriginatorPk_ = ecdhUser1Pk_;
158        
159        random_ = SecRandom.getDefault();
160        
161      }
162    
163     
164      /**
165       * Creates the RecipientInfos.
166       *
167       * @return the RecipientInfos created, two KeyAgreeRecipientInfos
168       *
169       * @throws CMSException if an error occurs when creating the recipient infos
170       */
171      public RecipientInfo[] createRecipients() throws CMSException {
172        
173        RecipientInfo[] recipients = new RecipientInfo[1];
174        try {
175          // recipients use key agreement
176          // the key encryption (key agreement) algorithm to use:
177          AlgorithmID keyEA = (AlgorithmID)CMSAlgorithmID.dhSinglePass_stdDH_sha256kdf_scheme.clone();
178          // the key wrap algorithm to use:
179          AlgorithmID keyWrapAlg = (AlgorithmID)AlgorithmID.cms_aes256_wrap.clone();
180          // the length of the key encryption key to be generated:
181          int kekLength = 256;
182          // in static-static mode we may supply user keying material
183          byte[] ukm = new byte[64];
184          random_.nextBytes(ukm);
185          // ssdhUser1 is originator
186          recipients[0] = new KeyAgreeRecipientInfo(ecdhOriginator_, 
187                                                    ecdhOriginatorPk_,
188                                                    KeyIdentifier.ISSUER_AND_SERIALNUMBER,
189                                                    keyEA, 
190                                                    keyWrapAlg, 
191                                                    kekLength, 
192                                                    ukm);
193          // add ssdhUser1 (originator) as recipient, too
194          ((KeyAgreeRecipientInfo)recipients[0]).addRecipient(ecdhUser1_, CertificateIdentifier.ISSUER_AND_SERIALNUMBER);
195          // ssdhUser2 is the recipient (cert identified by RecipientKeyIdentifier)
196          ((KeyAgreeRecipientInfo)recipients[0]).addRecipient(ecdhUser2_, CertificateIdentifier.RECIPIENT_KEY_IDENTIFIER);
197    
198          
199        } catch (Exception ex) {
200          throw new CMSException("Error adding recipients: " + ex.toString()); 
201        }    
202        return recipients;
203      }  
204      
205     
206    }