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