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/SMimeV4BrainpoolDemo.java 3 12.02.25 17:59 Dbratko $ 059 // $Revision: 3 $ 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 ECC keys with Berainpool curves 081 * and how to parse them and verify the signatures and decrypt the content, respectively. 082 * <p> 083 * Although Brainpool curves may not be widely used with S/MIME applications they are, e.g., recommended 084 * by the German Federal Office for Information Security (BSI) for their Technical Guideline BSI TR-03116 085 * defining cryptographic requirements for projects of the Federal Government. 086 * Note that whereas S/MIME in general uses AEAD cipher modes like GCM with the <code>AuthEnvelopedData</code> 087 * content type, BSI TR-03116 specifies GCM for use with the <code>EnvelopedData</code> type. For that 088 * reason GCM is used with <code>EnvelopedData</code> in this demo (in difference to the parent 089 * {@link SMimeV4EccDemo SMimeV4EccDemo} which uses GCM with the <code>AuthEnvelopedData</code> type. 090 * 091 * <p> 092 * Additionally to <code>iaik_cms.jar</code> you also must have 093 * <code>iaik_jce_(full).jar</code> (IAIK-JCE, <a href = 094 * "https://sic.tech/products/core-crypto-toolkits/jca-jce/" target="_blank"> 095 * https://sic.tech/products/core-crypto-toolkits/jca-jce/</a>), 096 * and <code>iaik_eccelarate.jar</code> (IAIK-ECCelerate<sup><small>TM</small></sup>, <a href = 097 * "https://sic.tech/products/core-crypto-toolkits/eccelerate/" target="_blank"> 098 * https://sic.tech/products/core-crypto-toolkits/eccelerate/</a>) 099 * in your classpath. 100 * <p> 101 * To run this demo the following packages are required: 102 * <ul> 103 * <li> 104 * <code>iaik_cms.jar</code> 105 * </li> 106 * <li> 107 * <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>). 108 * </li> 109 * <li> 110 * <code>iaik_eccelerate.jar</code> (<a href="https://sic.tech/products/core-crypto-toolkits/eccelerate/" target="_blank">IAIK ECC Library</a>). 111 * </li> 112 * <li> 113 * <code>mail.jar</code> (<a href="http://www.oracle.com/technetwork/java/javamail/index.html" target="_blank">JavaMail API</a>). 114 * </li> 115 * <li> 116 * <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 < 1.6). 117 * </li> 118 * </ul> 119 * 120 * This demo requires Java 7 or later. 121 */ 122 public class SMimeV4BrainpoolDemo extends SMimeV4EccDemo { 123 124 125 /** 126 * Default constructor. 127 */ 128 public SMimeV4BrainpoolDemo() { 129 130 System.out.println(); 131 System.out.println("********************************************************************************************"); 132 System.out.println("* SMimeV4EccDemo demo *"); 133 System.out.println("* (shows how to create and parse (verify, decrypt) signed and encrypted S/MIMEv4 messages) *"); 134 System.out.println("********************************************************************************************"); 135 System.out.println(); 136 137 } 138 139 140 /** 141 * Starts the demo. 142 * 143 * @throws Exception if an error occurs 144 */ 145 public void start() throws Exception { 146 147 // get the default Session 148 Session session = DemoSMimeUtil.getSession(); 149 150 // Create a demo Multipart 151 DataHandler multipart = createMultipart(); 152 153 // get signer key and certs 154 KeyAndCertificate[] signerKeyAndCerts = { 155 // Brainpool P-224 156 new KeyAndCertificate( 157 CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, 158 CMSEccKeyStore.SZ_224_BRAINPOOL_SIGN), 159 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, 160 CMSEccKeyStore.SZ_224_BRAINPOOL_SIGN)), 161 162 // Brainpool P-256 163 new KeyAndCertificate( 164 CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, 165 CMSEccKeyStore.SZ_256_BRAINPOOL_SIGN), 166 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, 167 CMSEccKeyStore.SZ_256_BRAINPOOL_SIGN)), 168 // Brainpool P-384 169 new KeyAndCertificate( 170 CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, 171 CMSEccKeyStore.SZ_384_BRAINPOOL_SIGN), 172 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, 173 CMSEccKeyStore.SZ_384_BRAINPOOL_SIGN)), 174 // Brainpool P-512 175 new KeyAndCertificate( 176 CMSEccKeyStore.getPrivateKey(CMSEccKeyStore.ECDSA, 177 CMSEccKeyStore.SZ_512_BRAINPOOL_SIGN), 178 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDSA, 179 CMSEccKeyStore.SZ_512_BRAINPOOL_SIGN)), 180 181 }; 182 183 // the digest and signature algorithms to be used 184 AlgorithmID[][] digestAndSignatureAlgorithms = new AlgorithmID[][] { 185 { CMSAlgorithmID.sha224, CMSAlgorithmID.ecdsa_With_SHA224 }, 186 { CMSAlgorithmID.sha256, CMSAlgorithmID.ecdsa_With_SHA256 }, 187 { CMSAlgorithmID.sha384, CMSAlgorithmID.ecdsa_With_SHA384 }, 188 { CMSAlgorithmID.sha512, CMSAlgorithmID.ecdsa_With_SHA512 }, 189 }; 190 191 192 /**************************************************************************/ 193 /* */ 194 /* Signing Demo */ 195 /* */ 196 /**************************************************************************/ 197 198 final int DIGEST_ALG = 0; 199 final int SIGNATURE_ALG = 1; 200 for (int i = 0; i < digestAndSignatureAlgorithms.length; i++) { 201 AlgorithmID digestAlg = digestAndSignatureAlgorithms[i][DIGEST_ALG]; 202 AlgorithmID signatureAlg = digestAndSignatureAlgorithms[i][SIGNATURE_ALG]; 203 PrivateKey signerKey = signerKeyAndCerts[i].getPrivateKey(); 204 X509Certificate[] signerCerts = signerKeyAndCerts[i].getCertificateChain(); 205 System.out.println("Running signing demo for " + signatureAlg.getName()); 206 startSigningDemo(session, 207 multipart, 208 digestAlg, 209 signatureAlg, 210 signerKey, 211 signerCerts); 212 } 213 214 // (authenticated) encryption demos 215 216 // get recipient certs 217 X509Certificate[] recipientCerts = { 218 // Brainpool P-224 219 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 220 CMSEccKeyStore.SZ_224_BRAINPOOL_CRYPT_1)[0], 221 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 222 CMSEccKeyStore.SZ_224_BRAINPOOL_CRYPT_2)[0], 223 // Brainpool P-256 224 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 225 CMSEccKeyStore.SZ_256_BRAINPOOL_CRYPT_1)[0], 226 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 227 CMSEccKeyStore.SZ_256_BRAINPOOL_CRYPT_2)[0], 228 // Brainpool P-384 229 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 230 CMSEccKeyStore.SZ_384_BRAINPOOL_CRYPT_1)[0], 231 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 232 CMSEccKeyStore.SZ_384_BRAINPOOL_CRYPT_2)[0], 233 //Brainpool P-512 234 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 235 CMSEccKeyStore.SZ_512_BRAINPOOL_CRYPT_1)[0], 236 CMSEccKeyStore.getCertificateChain(CMSEccKeyStore.ECDH, 237 CMSEccKeyStore.SZ_512_BRAINPOOL_CRYPT_2)[0], 238 239 }; 240 241 // the key encryption algorithms to be used 242 AlgorithmID[] keyEAs = { 243 AlgorithmID.dhSinglePass_stdDH_sha224kdf_scheme, 244 AlgorithmID.dhSinglePass_stdDH_sha256kdf_scheme, 245 AlgorithmID.dhSinglePass_stdDH_sha384kdf_scheme, 246 AlgorithmID.dhSinglePass_stdDH_hkdf_sha256_scheme, 247 AlgorithmID.dhSinglePass_stdDH_hkdf_sha384_scheme, 248 AlgorithmID.dhSinglePass_stdDH_hkdf_sha512_scheme, 249 }; 250 // key wrap algorithms 251 AlgorithmID[] keyWrapAlgs = { 252 CMSAlgorithmID.cms_aes128_wrap, 253 CMSAlgorithmID.cms_aes192_wrap, 254 CMSAlgorithmID.cms_aes256_wrap, 255 }; 256 // whether to encrypt or authenticated encrypt 257 boolean[] doAuthEncrypt = { false, true }; 258 for (int i = 0; i < keyEAs.length; i++) { 259 AlgorithmID[] contentEAs; 260 AlgorithmID keyEA = keyEAs[i]; 261 for (int j = 0; j < keyWrapAlgs.length; j++) { 262 AlgorithmID keyWrapAlg = keyWrapAlgs[j]; 263 int kekLength; 264 int keyLength; 265 if (keyWrapAlg.equals(CMSAlgorithmID.cms_aes192_wrap)) { 266 kekLength = 192; 267 keyLength = 192; 268 contentEAs = new AlgorithmID[] { AlgorithmID.aes192_GCM, AlgorithmID.aes192_CCM }; 269 } else if (keyWrapAlg.equals(CMSAlgorithmID.cms_aes128_wrap)) { 270 kekLength = 128; 271 keyLength = 128; 272 contentEAs = new AlgorithmID[] { AlgorithmID.aes128_GCM, AlgorithmID.aes128_CCM }; 273 } else { 274 kekLength = 256; 275 keyLength = 256; 276 contentEAs = new AlgorithmID[] { AlgorithmID.aes256_GCM, AlgorithmID.aes256_CCM, AlgorithmID.chacha20Poly1305 }; 277 } 278 279 for (int k = 0; k < contentEAs.length; k++) { 280 281 /**************************************************************************/ 282 /* */ 283 /* (Authenticated) Encryption Demo */ 284 /* */ 285 /**************************************************************************/ 286 287 AlgorithmID contentEA = contentEAs[k]; 288 // in practice we may not create one message for recipients with different strength; 289 // however, for simplicity we use all recipients here 290 System.out.println("Running encryption demo for " + 291 keyEA.getName() + " with " + keyWrapAlg.getName() +" and " + contentEA.getName()); 292 startEncryptionDemo(session, 293 contentEA, 294 keyLength, 295 keyEA, 296 keyWrapAlg, 297 kekLength, 298 false, 299 recipientCerts); 300 301 302 /**************************************************************************/ 303 /* */ 304 /* Signing and (Authenticated) Encryption Demo */ 305 /* */ 306 /**************************************************************************/ 307 308 for (int l = 0; l < digestAndSignatureAlgorithms.length; l++) { 309 AlgorithmID digestAlg = digestAndSignatureAlgorithms[l][DIGEST_ALG]; 310 AlgorithmID signatureAlg = digestAndSignatureAlgorithms[l][SIGNATURE_ALG]; 311 PrivateKey signerKey = signerKeyAndCerts[l].getPrivateKey(); 312 X509Certificate[] signerCerts = signerKeyAndCerts[l].getCertificateChain(); 313 System.out.println("Running signing and encryption and demo for " + signatureAlg.getName()); 314 startSigningAndEncryptionDemo(session, 315 multipart, 316 digestAlg, 317 signatureAlg, 318 contentEA, 319 keyLength, 320 keyEA, 321 keyWrapAlg, 322 kekLength, 323 false, 324 signerKey, 325 signerCerts, 326 recipientCerts); 327 } 328 } 329 } 330 } 331 332 } 333 334 /** 335 * The main method. 336 */ 337 public static void main(String[] argv) throws Exception { 338 339 String jdkVersion = (String) System.getProperty("java.version"); 340 if (jdkVersion.compareTo("1.7") >= 0) { 341 DemoSMimeUtil.initDemos(); 342 // add ECC provider 343 ECCDemoUtil.installIaikEccProvider(); 344 345 (new SMimeV4BrainpoolDemo()).start(); 346 System.out.println("\nReady!"); 347 } else { 348 System.err.println("This demo requires Java 7 or later!"); 349 } 350 DemoUtil.waitKey(); 351 } 352 }