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/DemoUtil.java 29 12.02.25 17:58 Dbratko $ 059 // $Revision: 29 $ 060 // 061 062 package demo; 063 064 import java.io.IOException; 065 import java.security.AlgorithmParameters; 066 import java.security.InvalidAlgorithmParameterException; 067 import java.security.MessageDigest; 068 import java.security.NoSuchAlgorithmException; 069 import java.security.Provider; 070 import java.security.Security; 071 import java.security.spec.InvalidParameterSpecException; 072 import java.util.Random; 073 074 import iaik.asn1.ObjectID; 075 import iaik.asn1.structures.AlgorithmID; 076 import iaik.cms.SecurityProvider; 077 import iaik.pkcs.pkcs1.MGF1ParameterSpec; 078 import iaik.pkcs.pkcs1.MaskGenerationAlgorithm; 079 import iaik.pkcs.pkcs1.RSAPssParameterSpec; 080 import iaik.security.provider.IAIK; 081 import iaik.security.random.MetaSeedGenerator; 082 import iaik.security.random.SecRandom; 083 import iaik.security.random.SeedGenerator; 084 085 /** 086 * Some basic utility methods used by the demos. 087 */ 088 public class DemoUtil { 089 090 /** Debug flag for all demos */ 091 public final static boolean DEMO_DEBUG = true; 092 093 /** 094 * Base OID for IAIK-CMS demos. 095 */ 096 public final static ObjectID IAIK_JAVA_SECURITY_DEMO_CMS_OID = new ObjectID("1.3.6.1.4.1.2706.2.2.4", "IAIK JavaSecurity CMS Demo"); 097 098 /** 099 * Greeting message. 100 */ 101 final static String[] GREETING = { 102 "* *", 103 "* Welcome to the IAIK-CMS/SMIMEv4 Demo Programs *", 104 "* *", 105 "* These simple programs show how to use the IAIK-CMS library. Please *", 106 "* see the documentation and the source code for more information. *", 107 "* *", 108 "* *", 109 "* NOTE that most of the demos require certificates to work, they are *", 110 "* taken from a keystore file (cms.keystore) located in your current *", 111 "* working directory. If yet not exist, the keystore can be generated *", 112 "* by calling demo.keystore.SetupCMSKeyStore. *", 113 "* *", 114 "", 115 }; 116 117 118 /** 119 * Whether to {@link demo.keystore.SetupCMSKeyStore create} a new demo keystore automatically 120 * if it is not present or to explicitly ask if to create it. 121 */ 122 public static boolean CREATE_DEMO_KEYSTORE_AUTOMATICAllY = false; 123 /** 124 * Initialization done? 125 */ 126 static boolean initialized_ = false; 127 128 /** 129 * Version number of the IAIK-JCE crypto provider. 130 */ 131 static double iaikProviderVersion_ = -1; 132 133 /** 134 * Empty constructor. 135 */ 136 DemoUtil() { 137 // empty 138 } 139 140 /** Perform a some initial setup to allow the demos to work */ 141 public synchronized static void initDemos() { 142 initDemos(true); 143 } 144 145 /** 146 * Perform a some initial setup to allow the demos to work 147 * 148 * @param quickStart whether to init the random generator with a 149 * (not strong) seed for quick start (ONLY FOR 150 * DEMO PURPOSES; NOT FOR PRODUCTION ENVIRONMENT!) 151 */ 152 public synchronized static void initDemos(boolean quickStart) { 153 154 if( initialized_ ) { 155 return; 156 } 157 initialized_ = true; 158 for( int i=0; i<GREETING.length; i++ ) { 159 System.out.println(GREETING[i]); 160 } 161 initRandom(quickStart); 162 addIaikProvider(); 163 } 164 165 166 /** 167 * Adds the IAIK JCE as a first security provider. 168 */ 169 public static void addIaikProvider() { 170 IAIK.addAsProvider(); 171 Provider iaikProv = Security.getProvider("IAIK"); 172 iaikProviderVersion_ = iaikProv.getVersion(); 173 } 174 175 /** 176 * Gets the version number of the IAIK-JCE provider used for this demos. 177 * 178 * @return the version number of the IAIK JCA/JCE provider 179 */ 180 public static double getIaikProviderVersion() { 181 if (iaikProviderVersion_ == -1) { 182 addIaikProvider(); 183 } 184 return iaikProviderVersion_; 185 } 186 187 /** 188 * Adds the cryptography provider with the given name. 189 * 190 * Note that it may <em>not</em> be enough to just add it as a provider; 191 * see the {@link iaik.cms.SecurityProvider SecurityProvider} class for more information. 192 * 193 * @param name the name of the provider to be added 194 */ 195 public static void addProvider(String name) { 196 try { 197 Class clazz = Class.forName(name); 198 Provider provider = (Provider)clazz.newInstance(); 199 Security.addProvider(provider); 200 } catch (ClassNotFoundException ex) { 201 System.out.println("Provider IAIK not found. Add iaik_jce.jar or iaik_jce_full.jar to your classpath."); 202 System.out.println("If you are going to use a different provider please take a look at Readme.html!"); 203 System.exit(0); 204 } catch (Exception ex) { 205 System.out.println("Error adding provider:"); 206 ex.printStackTrace(System.err); 207 System.exit(0); 208 } 209 } 210 211 /** 212 * Setup the random number generator for a quick start. 213 * THIS IS NOT SECURE AND SHOULD BE USED FOR DEMO PURPOSES ONLY. 214 * ANY CRYPTOGRAPHIC KEY DERIVED IN THIS WAY IS WEAK AND NO STRONGER THAN 20 BIT!!! 215 */ 216 public static void initRandom() { 217 System.out.println("Quick-starting random number generator (not for use in production systems!)..."); 218 Random random = new Random(); 219 byte[] seed = new byte[20]; 220 random.nextBytes(seed); 221 MetaSeedGenerator.setSeed(seed); 222 SeedGenerator.setDefault(MetaSeedGenerator.class); 223 } 224 225 /** 226 * Setup the random number generator for a quick start. 227 * THIS IS NOT SECURE AND SHOULD BE USED FOR DEMO PURPOSES ONLY. 228 * ANY CRYPTOGRAPHIC KEY DERIVED IN THIS WAY IS WEAK AND NO STRONGER THAN 20 BIT!!! 229 * 230 * @param quick whether to init the random generator with a (not strong) seed 231 * for quick start (only for demonstration purposes) 232 */ 233 public static void initRandom(boolean quick) { 234 if (quick) { 235 System.out.println("Quick-starting random number generator (not for use in production systems!)..."); 236 Random random = new Random(); 237 byte[] seed = new byte[20]; 238 random.nextBytes(seed); 239 MetaSeedGenerator.setSeed(seed); 240 SeedGenerator.setDefault(MetaSeedGenerator.class); 241 } else { 242 // create a new Thread which initializes the Secure Random Number generator 243 (new Thread() { 244 public void run() { 245 setPriority(Thread.MIN_PRIORITY); 246 SecRandom.getDefault().nextInt(); 247 } 248 }).start(); 249 } 250 } 251 252 /** 253 * Creates a RSA-PSS AlgorithmID with the supplied parameters (hash algorithm id, 254 * mask generation function, salt length). 255 * 256 * @param hashID the hash algorithm to be used 257 * @param mgfID the mask generation function to be used 258 * @param saltLength the salt length to be used 259 * 260 * @return the RSA-PSS algorithm id with the given parameters 261 * 262 * @throws InvalidAlgorithmParameterException if the parameters cannot be created/set 263 * @throws NoSuchAlgorithmException if there is no AlgorithmParameters implementation 264 * for RSA-PSS 265 */ 266 public static AlgorithmID createPssAlgorithmID(AlgorithmID hashID, AlgorithmID mgfID, int saltLength) 267 throws InvalidAlgorithmParameterException, NoSuchAlgorithmException { 268 269 SecurityProvider provider = SecurityProvider.getSecurityProvider(); 270 AlgorithmID rsaPssID = (AlgorithmID)AlgorithmID.rsassaPss.clone(); 271 mgfID.setParameter(hashID.toASN1Object()); 272 // create a RSAPssParameterSpec 273 RSAPssParameterSpec pssParamSpec = new RSAPssParameterSpec(hashID, mgfID, saltLength); 274 // optionally set hash and mgf engines 275 MessageDigest hashEngine = provider.getMessageDigest(hashID); 276 pssParamSpec.setHashEngine(hashEngine); 277 MaskGenerationAlgorithm mgfEngine = provider.getMaskGenerationAlgorithm(mgfID); 278 MGF1ParameterSpec mgf1Spec = new MGF1ParameterSpec(hashID); 279 mgf1Spec.setHashEngine(hashEngine); 280 mgfEngine.setParameters(mgf1Spec); 281 pssParamSpec.setMGFEngine(mgfEngine); 282 283 AlgorithmParameters pssParams = null; 284 try { 285 pssParams = provider.getAlgorithmParameters(SecurityProvider.IMPLEMENTATION_NAME_RSA_PSS); 286 pssParams.init(pssParamSpec); 287 288 289 } catch (InvalidParameterSpecException ex) { 290 throw new InvalidAlgorithmParameterException("Cannot init PSS params: " + ex.getMessage()); 291 } 292 293 rsaPssID.setAlgorithmParameters(pssParams); 294 return rsaPssID; 295 } 296 297 298 /** 299 * Wait for the user to press the return key on System.in. 300 */ 301 public static void waitKey() { 302 try { 303 System.out.println("Hit the <RETURN> key."); 304 do { 305 System.in.read(); 306 } while( System.in.available() > 0 ); 307 } catch( IOException e ) { 308 // ignore 309 } 310 } 311 312 }