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 }