/* * KeyStoreTestUtils.java * * Created on Feb 5, 2010, 2:17:42 PM * * Description: Provides keystores and passwords for testing. * * Copyright (C) Feb 5, 2010 reed. * * This program is free software; you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Foundation; either * version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with this program; * if not, write to the Free Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ package org.texai.x509; import java.io.File; import java.io.FileOutputStream; import java.io.IOException; import java.security.InvalidAlgorithmParameterException; import java.security.InvalidKeyException; import java.security.KeyPair; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.NoSuchProviderException; import java.security.SignatureException; import java.security.cert.Certificate; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import net.jcip.annotations.NotThreadSafe; import org.apache.log4j.Logger; import org.texai.util.TexaiException; import static org.texai.x509.X509Utils.isTrustedDevelopmentSystem; /** Provides keystores and passwords for testing. * * @author reed */ @NotThreadSafe public final class KeyStoreTestUtils { /** the logger */ private static final Logger LOGGER = Logger.getLogger(KeyStoreTestUtils.class); /** the server keystore password */ private static final char[] SERVER_KEYSTORE_PASSWORD = "server-keystore-password".toCharArray(); /** the client keystore password */ private static final char[] CLIENT_KEYSTORE_PASSWORD = "client-keystore-password".toCharArray(); /** Prevents the instantiation of this utility class. */ private KeyStoreTestUtils() { } /** Initializes the test server keystore on the trusted development system, from where it is copied into the distributed code. */ public static synchronized void initializeServerKeyStore() { if (!X509Utils.isTrustedDevelopmentSystem()) { return; } try { // the test server keystore consists of the single test server X.509 certificate, which is generated and signed by // the Texai root certificate on the developement system that has the root private key. final KeyPair serverKeyPair = X509Utils.generateRSAKeyPair2048(); final X509Certificate serverX509Certificate = X509Utils.generateX509Certificate( serverKeyPair.getPublic(), X509Utils.getRootPrivateKey(), X509Utils.getRootX509Certificate(), null); // proceed as though the JCE unlimited strength jurisdiction policy files are installed, which they will be on the // trusted development system. String filePath = "data/test-server-keystore.uber"; File file = new File(filePath); if (file.exists()) { // do not overwrite it //Postconditions assert !isTrustedDevelopmentSystem() || X509Utils.isJCEUnlimitedStrengthPolicy() : "JCE unlimited strength policy must be in effect"; return; } LOGGER.info("creating test-server-keystore.uber"); assert X509Utils.isJCEUnlimitedStrengthPolicy(); KeyStore serverKeyStore = X509Utils.findOrCreateKeyStore(filePath, SERVER_KEYSTORE_PASSWORD); serverKeyStore.setKeyEntry( X509Utils.ENTRY_ALIAS, serverKeyPair.getPrivate(), SERVER_KEYSTORE_PASSWORD, new Certificate[]{serverX509Certificate, X509Utils.getRootX509Certificate()}); serverKeyStore.store(new FileOutputStream(filePath), SERVER_KEYSTORE_PASSWORD); // then proceed after disabling the JCE unlimited strength jurisdiction policy files indicator X509Utils.setIsJCEUnlimitedStrengthPolicy(false); filePath = "data/test-server-keystore.jceks"; LOGGER.info("creating test-server-keystore.jceks"); serverKeyStore = X509Utils.findOrCreateKeyStore(filePath, SERVER_KEYSTORE_PASSWORD); serverKeyStore.setKeyEntry( X509Utils.ENTRY_ALIAS, serverKeyPair.getPrivate(), SERVER_KEYSTORE_PASSWORD, new Certificate[]{serverX509Certificate, X509Utils.getRootX509Certificate()}); serverKeyStore.store(new FileOutputStream(filePath), SERVER_KEYSTORE_PASSWORD); // restore the JCE unlimited strength jurisdiction policy files indicator X509Utils.setIsJCEUnlimitedStrengthPolicy(true); } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException | IOException | KeyStoreException | CertificateException ex) { throw new TexaiException(ex); } //Postconditions assert !isTrustedDevelopmentSystem() || X509Utils.isJCEUnlimitedStrengthPolicy() : "JCE unlimited strength policy must be in effect"; } /** Initializes the test client keystore on the trusted development system, from where it is copied into the distributed code. */ public static synchronized void initializeClientKeyStore() { if (!X509Utils.isTrustedDevelopmentSystem()) { return; } try { // the test client keystore consists of the single test client X.509 certificate, which is generated and signed by // the Texai root certificate on the developement system that has the root private key. final KeyPair clientKeyPair = X509Utils.generateRSAKeyPair2048(); final X509Certificate clientX509Certificate = X509Utils.generateX509Certificate( clientKeyPair.getPublic(), X509Utils.getRootPrivateKey(), X509Utils.getRootX509Certificate(), null); // proceed as though the JCE unlimited strength jurisdiction policy files are installed, which they will be on the // trusted development system. String filePath = "data/test-client-keystore.uber"; File file = new File(filePath); if (file.exists()) { file.delete(); } LOGGER.info("creating test-client-keystore.uber"); assert X509Utils.isJCEUnlimitedStrengthPolicy(); KeyStore clientKeyStore = X509Utils.findOrCreateKeyStore(filePath, CLIENT_KEYSTORE_PASSWORD); clientKeyStore.setKeyEntry( X509Utils.ENTRY_ALIAS, clientKeyPair.getPrivate(), CLIENT_KEYSTORE_PASSWORD, new Certificate[]{clientX509Certificate, X509Utils.getRootX509Certificate()}); clientKeyStore.store(new FileOutputStream(filePath), CLIENT_KEYSTORE_PASSWORD); assert "UBER".equals(clientKeyStore.getType()); // then proceed after disabling the JCE unlimited strength jurisdiction policy files indicator X509Utils.setIsJCEUnlimitedStrengthPolicy(false); filePath = "data/test-client-keystore.jceks"; LOGGER.info("creating test-client-keystore.jceks"); clientKeyStore = X509Utils.findOrCreateKeyStore(filePath, CLIENT_KEYSTORE_PASSWORD); clientKeyStore.setKeyEntry( X509Utils.ENTRY_ALIAS, clientKeyPair.getPrivate(), CLIENT_KEYSTORE_PASSWORD, new Certificate[]{clientX509Certificate, X509Utils.getRootX509Certificate()}); clientKeyStore.store(new FileOutputStream(filePath), CLIENT_KEYSTORE_PASSWORD); assert "JCEKS".equals(clientKeyStore.getType()); // restore the JCE unlimited strength jurisdiction policy files indicator X509Utils.setIsJCEUnlimitedStrengthPolicy(true); } catch (NoSuchAlgorithmException | NoSuchProviderException | InvalidAlgorithmParameterException | SignatureException | InvalidKeyException | IOException | KeyStoreException | CertificateException ex) { throw new TexaiException(ex); } //Postconditions assert !isTrustedDevelopmentSystem() || X509Utils.isJCEUnlimitedStrengthPolicy() : "JCE unlimited strength policy must be in effect"; } /** Gets the test server keystore. * * @return the test server keystore */ public static KeyStore getServerKeyStore() { // create server keystore String filePath; if (X509Utils.isJCEUnlimitedStrengthPolicy()) { filePath = "../X509Security/data/test-server-keystore.uber"; File file = new File(filePath); if (!file.exists()) { filePath = "../Texai/X509Security/data/test-server-keystore.uber"; } file = new File(filePath); if (!file.exists()) { // for MessageRouter filePath = "data/test-server-keystore.uber"; } } else { filePath = "../X509Security/data/test-server-keystore.jceks"; File file = new File(filePath); if (!file.exists()) { filePath = "../Texai/X509Security/data/test-server-keystore.jceks"; } file = new File(filePath); if (!file.exists()) { // for MessageRouter filePath = "data/test-server-keystore.jceks"; } } try { return X509Utils.findOrCreateKeyStore(filePath, SERVER_KEYSTORE_PASSWORD); } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException ex) { throw new TexaiException(ex); } } /** Gets the test client keystore. * * @return the test client keystore */ public static KeyStore getClientKeyStore() { String filePath; if (X509Utils.isJCEUnlimitedStrengthPolicy()) { filePath = "data/test-client-keystore.uber"; } else { filePath = "data/test-client-keystore.jceks"; } LOGGER.debug("test-client-keystore path: " + filePath); try { final KeyStore clientKeyStore = X509Utils.findOrCreateKeyStore(filePath, CLIENT_KEYSTORE_PASSWORD); if (LOGGER.isDebugEnabled()) { X509Utils.logAliases(clientKeyStore); } //Postconditions assert !filePath.endsWith("uber") || clientKeyStore.getType().equals("UBER") : "keystore type is " + clientKeyStore.getType() + ", must be UBER"; return clientKeyStore; } catch (KeyStoreException | IOException | NoSuchAlgorithmException | CertificateException | NoSuchProviderException ex) { throw new TexaiException(ex); } } /** Gets the X509 security information for a test client. * * @return the X509 security information for a test client */ public static X509SecurityInfo getClientX509SecurityInfo() { return new X509SecurityInfo( X509Utils.getTruststore(), getClientKeyStore(), CLIENT_KEYSTORE_PASSWORD, null); } /** Gets the X509 security information for a test server. * * @return the X509 security information for a test server */ public static X509SecurityInfo getServerX509SecurityInfo() { return new X509SecurityInfo( X509Utils.getTruststore(), getServerKeyStore(), SERVER_KEYSTORE_PASSWORD, null); } /** Gets the test server keystore password. * * @return the test server keystore password */ public static char[] getServerKeyStorePassword() { return SERVER_KEYSTORE_PASSWORD; } /** Gets the test client keystore password. * * @return the test client keystore password */ public static char[] getClientKeyStorePassword() { return CLIENT_KEYSTORE_PASSWORD; } }