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/keystore/CMSKeyStore.java 29 12.02.25 17:58 Dbratko $ 029// $Revision: 29 $ 030// 031 032package demo.keystore; 033 034import iaik.cms.CertificateIdentifier; 035import iaik.cms.KeyIdentifier; 036import iaik.cms.SecurityProvider; 037import iaik.smime.ess.utils.KeyStoreDatabase; 038import iaik.utils.Util; 039import iaik.x509.X509Certificate; 040 041import java.io.File; 042import java.io.FileInputStream; 043import java.security.KeyStore; 044import java.security.PrivateKey; 045 046/** 047 * KeyStore repository used providing keys and certificates 048 * for the several CMS and S/MIME demos. 049 * <p> 050 * Reads and loads keys and certificates from an IaikKeyStore 051 * files and provides methods to access the keys and certificates 052 * based on algorithm name and algorithm type. 053 */ 054public class CMSKeyStore implements CMSKeyStoreConstants { 055 056 /** 057 * Certificates. 058 */ 059 public static Object[][] certificates = new Object[5][12]; 060 /** 061 * Keys. 062 */ 063 public static PrivateKey[][] keys = new PrivateKey[5][12]; 064 /** 065 * Ca certificates. 066 */ 067 public static X509Certificate[] ca_certificates = new X509Certificate[3]; 068 /** 069 * Ca keys. 070 */ 071 public static PrivateKey[] ca_keys = new PrivateKey[3]; 072 073 /** 074 * Repository holding keys and certificates by their corresponding (certificate) ids. 075 * Used by class {@link demo.smime.DumpMessage DempMessgae} to search for recipient 076 * keys/certificates based on their recipient key (certificate) ids. 077 * For simplicity we use the {@link iaik.smime.ess.utils.KeyStoreDatabase KeyStoreDatabase} 078 * utility. 079 */ 080 private static KeyStoreDatabase recipientKeys_ = new KeyStoreDatabase(); 081 082 /** 083 * Adds a key and certificate by its key (certificate) ids to the given recipient keys/certs repositories. 084 * 085 * @param recipientKey the recipient key to be added 086 * @param recipientCertChain the recipient certificate chain 087 * 088 */ 089 public static void addRecipientKey(PrivateKey recipientKey, X509Certificate[] recipientCertChain) { 090 091 try { 092 recipientKeys_.addKey(recipientKey, recipientCertChain, null); 093 } catch (Exception e) { 094 System.err.println("Cannot add recipient key for " + recipientCertChain[0].getSubjectDN() + " " + e.toString()); 095 } 096 097 } 098 099 /** 100 * Gets a recipient key by the given key (certificate) id. 101 * 102 * @param keyId the key identifier 103 * 104 * @return the recipient key or <code>null</code> if no key for the given id can be found 105 * 106 */ 107 public static PrivateKey getRecipientKey(KeyIdentifier keyId) { 108 109 PrivateKey key = null; 110 try { 111 key = (PrivateKey)recipientKeys_.getKey(keyId); 112 } catch (Exception e) { 113 // ignore 114 } 115 return key; 116 117 } 118 119 /** 120 * Gets a recipient cert by the given certificate id from the given recipient certs repository. 121 * 122 * @param certId the certificate identifier 123 * 124 * @return the recipient cert or <code>null</code> if no cert for the given id can be found 125 * 126 */ 127 public static X509Certificate getRecipientCert(CertificateIdentifier certId) { 128 X509Certificate cert = null; 129 try { 130 cert = recipientKeys_.getCertificate(certId); 131 } catch (Exception e) { 132 // ignore 133 } 134 return cert; 135 } 136 137 /** 138 * Indices into the cert/key tables 139 */ 140 public final static int RSA = 0; 141 public final static int DSA = 1; 142 public final static int RSAPSS = 2; 143 public final static int ESDH = 3; 144 public final static int SSDH = 4; 145 146 147 public final static int SZ_1024_SIGN = 0; 148 public final static int SZ_2048_SIGN_1 = 1; 149 public final static int SZ_2048_SIGN_2 = 2; 150 public final static int SZ_2048_SIGN_3 = 3; 151 public final static int SZ_3072_SIGN = 4; 152 public final static int SZ_2048_CRYPT_1 = 5; 153 public final static int SZ_2048_CRYPT_2 = 6; 154 public final static int SZ_2048_CRYPT_3 = 7; 155 public final static int SZ_2048_SHA1_SIGN = 8; 156 public final static int SZ_2048_SHA256_SIGN = 9; 157 public final static int SZ_2048_SHA384_SIGN = 10; 158 public final static int SZ_2048_SHA512_SIGN = 11; 159 160 /** 161 * Certificate chain of demo time stamp server. 162 */ 163 static X509Certificate[] tsp_server_certs; 164 165 /** 166 * Key of demo time stamp server. 167 */ 168 static PrivateKey tsp_server_key; 169 170 /** 171 * Keystore. 172 */ 173 static KeyStore key_store; 174 175 /** 176 * The KeyStore file name. 177 */ 178 public static String ks_filename = KS_FILENAME; 179 180 181 182 /** 183 * Loads and inits keystore. 184 */ 185 static { 186 System.out.println("initializing KeyStore..."); 187 loadKeyStore(); 188 initKeyStore(); 189 System.out.println(); 190 } 191 192 /** 193 * Loads the keystore from the file ("cms.keystore"). 194 */ 195 private static void loadKeyStore() { 196 197 boolean createKeyStore = false; 198 // try to locate the KeyStore 199 // first check the current working directory 200 File ks = new File(KS_DIRECTORY, ks_filename); 201 if (!ks.exists()) { 202 createKeyStore = true; 203 // called from demo batch file (try parent directory) 204 File ksDir = new File(KS_DIRECTORY); 205 if (ksDir.exists()) { 206 String parentDir = ksDir.getParent(); 207 String pDir = parentDir.toLowerCase(); 208 if ((pDir.endsWith("cms")) || (pDir.endsWith("smime")) || 209 (pDir.endsWith("cmd")) || (pDir.endsWith("sh"))) { 210 File ksParent = new File(parentDir, ks_filename); 211 if (ksParent.exists()) { 212 ks = ksParent; 213 createKeyStore = false; 214 } 215 } 216 } 217 if (createKeyStore) { 218 // keystore does not exist ==> create new one 219 System.out.println(); 220 System.out.println(); 221 System.out.println("Can not find the KeyStore " + ks_filename + " in directory:"); 222 System.out.println(ks.getAbsolutePath()); 223 System.out.println("Generating key store!"); 224 try { 225 SetupCMSKeyStore.main(new String[] {}); 226 } catch (Exception ex) { 227 System.out.println("Unable to create KeyStore!"); 228 ex.printStackTrace(); 229 demo.DemoUtil.waitKey(); 230 System.exit(1); 231 } 232 } 233 } 234 235 FileInputStream fis = null; 236 // now try to create and load the KeyStore 237 try { 238 fis = new FileInputStream(ks); 239 key_store = SecurityProvider.getSecurityProvider().getKeyStore("IAIKKeyStore"); 240 key_store.load(fis, KS_PASSWORD); 241 fis.close(); 242 } catch (Exception ex) { 243 System.out.println("Unable to load KeyStore!"); 244 ex.printStackTrace(); 245 if (fis != null) { 246 try { 247 fis.close(); 248 } catch (Exception e) { 249 // ignore 250 } 251 } 252 demo.DemoUtil.waitKey(); 253 System.exit(1); 254 } 255 256 } 257 258 /** 259 * Initializes the keystore. 260 */ 261 public static void initKeyStore() { 262 263 try { 264 ca_certificates[RSA] = Util.convertCertificateChain(key_store.getCertificateChain(CA_RSA))[0]; 265 ca_keys[RSA] = (PrivateKey)key_store.getKey(CA_RSA, KS_PASSWORD); 266 ca_keys[RSAPSS] = (PrivateKey)key_store.getKey(CA_RSAPSS, KS_PASSWORD); 267 268 // RSA for signing 269 certificates[RSA][SZ_2048_SIGN_1] = Util.convertCertificateChain(key_store.getCertificateChain(RSA_2048_SIGN_1)); 270 keys[RSA][SZ_2048_SIGN_1] = (PrivateKey)key_store.getKey(RSA_2048_SIGN_1, KS_PASSWORD); 271 certificates[RSA][SZ_2048_SIGN_2] = Util.convertCertificateChain(key_store.getCertificateChain(RSA_2048_SIGN_2)); 272 keys[RSA][SZ_2048_SIGN_2] = (PrivateKey)key_store.getKey(RSA_2048_SIGN_2, KS_PASSWORD); 273 certificates[RSA][SZ_2048_SIGN_3] = Util.convertCertificateChain(key_store.getCertificateChain(RSA_2048_SIGN_3)); 274 keys[RSA][SZ_2048_SIGN_3] = (PrivateKey)key_store.getKey(RSA_2048_SIGN_3, KS_PASSWORD); 275 // RSA for encrypting 276 certificates[RSA][SZ_2048_CRYPT_1] = Util.convertCertificateChain(key_store.getCertificateChain(RSA_2048_CRYPT_1)); 277 keys[RSA][SZ_2048_CRYPT_1] = (PrivateKey)key_store.getKey(RSA_2048_CRYPT_1, KS_PASSWORD); 278 addRecipientKey(keys[RSA][SZ_2048_CRYPT_1], ((X509Certificate[])certificates[RSA][SZ_2048_CRYPT_1])); 279 certificates[RSA][SZ_2048_CRYPT_2] = Util.convertCertificateChain(key_store.getCertificateChain(RSA_2048_CRYPT_2)); 280 keys[RSA][SZ_2048_CRYPT_2] = (PrivateKey)key_store.getKey(RSA_2048_CRYPT_2, KS_PASSWORD); 281 addRecipientKey(keys[RSA][SZ_2048_CRYPT_2], ((X509Certificate[])certificates[RSA][SZ_2048_CRYPT_2])); 282 certificates[RSA][SZ_2048_CRYPT_3] = Util.convertCertificateChain(key_store.getCertificateChain(RSA_2048_CRYPT_3)); 283 keys[RSA][SZ_2048_CRYPT_3] = (PrivateKey)key_store.getKey(RSA_2048_CRYPT_3, KS_PASSWORD); 284 addRecipientKey(keys[RSA][SZ_2048_CRYPT_3], ((X509Certificate[])certificates[RSA][SZ_2048_CRYPT_3])); 285 } catch (Exception ex) { 286 System.out.println("RSA certificates not loaded: " + ex.getMessage()); 287 // ex.printStackTrace(); 288 } 289 290 try { 291 ca_certificates[DSA] = Util.convertCertificateChain(key_store.getCertificateChain(CA_DSA))[0]; 292 ca_keys[DSA] = (PrivateKey)key_store.getKey(CA_DSA, KS_PASSWORD); 293 certificates[DSA][SZ_1024_SIGN] = Util.convertCertificateChain(key_store.getCertificateChain(DSA_1024)); 294 keys[DSA][SZ_1024_SIGN] = (PrivateKey)key_store.getKey(DSA_1024, KS_PASSWORD); 295 } catch (Exception ex) { 296 System.out.println("DSA certificates not loaded: " + ex.getMessage()); 297 // ex.printStackTrace(); 298 } 299 300 try { 301 certificates[DSA][SZ_2048_SIGN_1] = Util.convertCertificateChain(key_store.getCertificateChain(DSA_2048)); 302 keys[DSA][SZ_2048_SIGN_1] = (PrivateKey)key_store.getKey(DSA_2048, KS_PASSWORD); 303 certificates[DSA][SZ_2048_SIGN_2] = Util.convertCertificateChain(key_store.getCertificateChain(DSA_2048)); 304 keys[DSA][SZ_2048_SIGN_2] = (PrivateKey)key_store.getKey(DSA_2048, KS_PASSWORD); 305 certificates[DSA][SZ_3072_SIGN] = Util.convertCertificateChain(key_store.getCertificateChain(DSA_3072)); 306 keys[DSA][SZ_3072_SIGN] = (PrivateKey)key_store.getKey(DSA_3072, KS_PASSWORD); 307 } catch (Exception ex) { 308 System.out.println("Unable to get DSA SHA-2 certificate from KeyStore: " + ex.getMessage()); 309 } 310 311 try { 312 certificates[ESDH][SZ_2048_CRYPT_1] = Util.convertCertificateChain(key_store.getCertificateChain(ESDH_2048_1)); 313 keys[ESDH][SZ_2048_CRYPT_1] = (PrivateKey)key_store.getKey(ESDH_2048_1, KS_PASSWORD); 314 addRecipientKey(keys[ESDH][SZ_2048_CRYPT_1], ((X509Certificate[])certificates[ESDH][SZ_2048_CRYPT_1])); 315 certificates[ESDH][SZ_2048_CRYPT_2] = Util.convertCertificateChain(key_store.getCertificateChain(ESDH_2048_2)); 316 keys[ESDH][SZ_2048_CRYPT_2] = (PrivateKey)key_store.getKey(ESDH_2048_2, KS_PASSWORD); 317 addRecipientKey(keys[ESDH][SZ_2048_CRYPT_2], ((X509Certificate[])certificates[ESDH][SZ_2048_CRYPT_2])); 318 certificates[SSDH][SZ_2048_CRYPT_1] = Util.convertCertificateChain(key_store.getCertificateChain(SSDH_2048_1)); 319 keys[SSDH][SZ_2048_CRYPT_1] = (PrivateKey)key_store.getKey(SSDH_2048_1, KS_PASSWORD); 320 addRecipientKey(keys[SSDH][SZ_2048_CRYPT_1], ((X509Certificate[])certificates[SSDH][SZ_2048_CRYPT_1])); 321 certificates[SSDH][SZ_2048_CRYPT_2] = Util.convertCertificateChain(key_store.getCertificateChain(SSDH_2048_2)); 322 keys[SSDH][SZ_2048_CRYPT_2] = (PrivateKey)key_store.getKey(SSDH_2048_2, KS_PASSWORD); 323 addRecipientKey(keys[SSDH][SZ_2048_CRYPT_2], ((X509Certificate[])certificates[SSDH][SZ_2048_CRYPT_2])); 324 } catch (Exception ex) { 325 System.out.println("Diffie-Hellman certificates not loaded: " + ex.getMessage()); 326 // ex.printStackTrace(); 327 } 328 329 // TSP server cert 330 try { 331 tsp_server_certs = Util.convertCertificateChain(key_store.getCertificateChain(TSP_SERVER)); 332 tsp_server_key = (PrivateKey)key_store.getKey(TSP_SERVER, KS_PASSWORD); 333 } catch (Exception ex) { 334 System.out.println("TSP server certificate not loaded: " + ex.getMessage()); 335 // ex.printStackTrace(); 336 } 337 338 // RSA-PSS 339 try { 340 341 ca_certificates[RSAPSS] = Util.convertCertificateChain(key_store.getCertificateChain(CA_RSAPSS))[0]; 342 ca_keys[RSAPSS] = (PrivateKey)key_store.getKey(CA_RSAPSS, KS_PASSWORD); 343 344 certificates[RSAPSS][SZ_2048_SHA1_SIGN] = Util.convertCertificateChain(key_store.getCertificateChain(RSAPSS_2048_SHA1_SIGN)); 345 keys[RSAPSS][SZ_2048_SHA1_SIGN] = (PrivateKey)key_store.getKey(RSAPSS_2048_SHA1_SIGN, KS_PASSWORD); 346 certificates[RSAPSS][SZ_2048_SHA256_SIGN] = Util.convertCertificateChain(key_store.getCertificateChain(RSAPSS_2048_SHA256_SIGN)); 347 keys[RSAPSS][SZ_2048_SHA256_SIGN] = (PrivateKey)key_store.getKey(RSAPSS_2048_SHA256_SIGN, KS_PASSWORD); 348 certificates[RSAPSS][SZ_2048_SHA384_SIGN] = Util.convertCertificateChain(key_store.getCertificateChain(RSAPSS_2048_SHA384_SIGN)); 349 keys[RSAPSS][SZ_2048_SHA384_SIGN] = (PrivateKey)key_store.getKey(RSAPSS_2048_SHA384_SIGN, KS_PASSWORD); 350 certificates[RSAPSS][SZ_2048_SHA512_SIGN] = Util.convertCertificateChain(key_store.getCertificateChain(RSAPSS_2048_SHA512_SIGN)); 351 keys[RSAPSS][SZ_2048_SHA512_SIGN] = (PrivateKey)key_store.getKey(RSAPSS_2048_SHA512_SIGN, KS_PASSWORD); 352 353 354 } catch (Exception ex) { 355 System.out.println("RSA-PSS certificates not loaded: " + ex.getMessage()); 356 // ex.printStackTrace(); 357 } 358 359 } 360 361 /** 362 * Returns the private key of a CA certificate. 363 * 364 * @param type {@link #RSA RSA} or {@link #DSA DSA} or {@link #ESDH ESDH} 365 * @param size the key size 366 * 367 * @return the key 368 */ 369 public static PrivateKey getPrivateKey(int type, int size) { 370 try { 371 return keys[type][size]; 372 } catch (ArrayIndexOutOfBoundsException ex) { 373 throw new RuntimeException("Wrong type or size!"); 374 } 375 } 376 377 /** 378 * Returns a demo user certificate. 379 * 380 * @param type {@link #RSA RSA} or {@link #DSA DSA} or {@link #ESDH ESDH} or {@link #SSDH SSDH} 381 * @param size the size of the corresponding key 382 * 383 * @return the certificate chain 384 */ 385 public static X509Certificate[] getCertificateChain(int type, int size) { 386 try { 387 return (X509Certificate[])certificates[type][size]; 388 } catch (ArrayIndexOutOfBoundsException ex) { 389 throw new RuntimeException("Wrong type or size!"); 390 } 391 } 392 393 /** 394 * Returns the private key of a CA certificate. 395 * 396 * @param type {@link #RSA RSA} or {@link #DSA DSA} 397 * 398 * @return the key 399 */ 400 public static PrivateKey getCaPrivateKey(int type) { 401 try { 402 return ca_keys[type]; 403 } catch (ArrayIndexOutOfBoundsException ex) { 404 throw new RuntimeException("Wrong type or size!"); 405 } 406 } 407 408 /** 409 * Returns a demo CA certificate. 410 * 411 * @param type {@link #RSA RSA} or {@link #DSA DSA} 412 * 413 * @return the ca certificate 414 */ 415 public static X509Certificate getCaCertificate(int type) { 416 try { 417 return ca_certificates[type]; 418 } catch (ArrayIndexOutOfBoundsException ex) { 419 throw new RuntimeException("Wrong type or size!"); 420 } 421 } 422 423 /** 424 * Returns the private key of the TSP demo server. 425 * 426 * @return the key 427 */ 428 public static PrivateKey getTspServerPrivateKey() { 429 return tsp_server_key; 430 } 431 432 /** 433 * Returns the certificate chain of the TSP demo server. 434 * 435 * @return the tsp server certificate 436 */ 437 public static X509Certificate[] getTspServerCertificate() { 438 return tsp_server_certs; 439 } 440 441 442}