Java tutorial
/************************************************************************* * * * SignServer: The OpenSource Automated Signing Server * * * * This software is free software; you can redistribute it and/or * * modify it under the terms of the GNU Lesser General Public * * License as published by the Free Software Foundation; either * * version 2.1 of the License, or any later version. * * * * See terms of license at gnu.org. * * * *************************************************************************/ package org.signserver.client.cli.defaultimpl; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.io.PrintStream; import java.security.*; import java.security.cert.CertificateException; import java.util.Arrays; import java.util.List; import java.util.ResourceBundle; import javax.net.ssl.*; import org.apache.commons.cli.CommandLine; import org.apache.commons.cli.Option; import org.ejbca.ui.cli.util.ConsolePasswordReader; /** * Handles keystore and truststore options from the command line as well * as setting them up for use with SSL. * * @author Markus Kils * @version $Id: KeyStoreOptions.java 6019 2015-05-11 08:31:54Z netmackan $ */ public class KeyStoreOptions { /** ResourceBundle with internationalized StringS. */ private static final ResourceBundle TEXTS = ResourceBundle .getBundle("org/signserver/client/cli/defaultimpl/ResourceBundle"); /** Default host */ public static final String DEFAULT_HOST = "localhost"; /** Default HTTP port. */ public static final int DEFAULT_HTTP_PORT = 8080; /** Default public HTTPS port. */ public static final int DEFAULT_PUBLIC_HTTPS_PORT = 8442; /** Default private HTTPS port. */ public static final int DEFAULT_PRIVATE_HTTPS_PORT = 8443; /** Option TRUSTSTORE. */ public static final String TRUSTSTORE = "truststore"; /** Option TRUSTSTOREPWD. */ public static final String TRUSTSTOREPWD = "truststorepwd"; /** Option KEYSTORE. */ public static final String KEYSTORE = "keystore"; /** Option KEYSTOREPWD. */ public static final String KEYSTOREPWD = "keystorepwd"; /** Option KEYALIAS. */ public static final String KEYALIAS = "keyalias"; public static List<Option> getKeyStoreOptions() { return Arrays.asList( new Option(KeyStoreOptions.TRUSTSTORE, true, TEXTS.getString("TRUSTSTORE_DESCRIPTION")), new Option(KeyStoreOptions.TRUSTSTOREPWD, true, TEXTS.getString("TRUSTSTOREPWD_DESCRIPTION")), new Option(KeyStoreOptions.KEYSTORE, true, TEXTS.getString("KEYSTORE_DESCRIPTION")), new Option(KeyStoreOptions.KEYSTOREPWD, true, TEXTS.getString("KEYSTOREPWD_DESCRIPTION")), new Option(KeyStoreOptions.KEYALIAS, true, TEXTS.getString("KEYALIAS_DESCRIPTION"))); } private File truststoreFile; private String truststorePassword; private File keystoreFile; private String keystorePassword; private String keyAlias; private KeyStore truststore; private KeyStore keystore; private boolean useHTTPS; private boolean usePrivateHTTPS; public void parseCommandLine(CommandLine line, ConsolePasswordReader passwordReader, PrintStream out) throws IOException, NoSuchAlgorithmException, CertificateException, KeyStoreException { if (line.hasOption(KeyStoreOptions.TRUSTSTORE)) { truststoreFile = new File(line.getOptionValue(KeyStoreOptions.TRUSTSTORE, null)); } if (line.hasOption(KeyStoreOptions.TRUSTSTOREPWD)) { truststorePassword = line.getOptionValue(KeyStoreOptions.TRUSTSTOREPWD, null); } if (line.hasOption(KeyStoreOptions.KEYSTORE)) { keystoreFile = new File(line.getOptionValue(KeyStoreOptions.KEYSTORE, null)); } if (line.hasOption(KeyStoreOptions.KEYSTOREPWD)) { keystorePassword = line.getOptionValue(KeyStoreOptions.KEYSTOREPWD, null); } if (line.hasOption(KeyStoreOptions.KEYALIAS)) { keyAlias = line.getOptionValue(KeyStoreOptions.KEYALIAS, null); } if (passwordReader != null) { // Prompt for truststore password if not given if (truststoreFile != null && truststorePassword == null) { for (int i = 0; i < 3; i++) { out.print("Password for truststore: "); out.flush(); truststorePassword = new String(passwordReader.readPassword()); try { KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream(truststoreFile), truststorePassword.toCharArray()); break; } catch (IOException ex) { if (ex.getCause() instanceof UnrecoverableKeyException) { if (i >= 2) { throw ex; } continue; } else { throw ex; } } } } // Prompt for keystore password if not given if (keystoreFile != null && keystorePassword == null) { for (int i = 0; i < 3; i++) { out.print("Password for keystore: "); out.flush(); keystorePassword = new String(passwordReader.readPassword()); try { KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream(keystoreFile), keystorePassword.toCharArray()); break; } catch (IOException ex) { if (ex.getCause() instanceof UnrecoverableKeyException) { if (i >= 2) { throw ex; } continue; } else { throw ex; } } } } } } public void validateOptions() throws IllegalArgumentException { if (truststoreFile != null && truststorePassword == null) { throw new IllegalArgumentException("Missing -truststorepwd"); } else if (keystoreFile != null && keystorePassword == null) { throw new IllegalArgumentException("Missing -keystorepwd"); } } public String getKeyAlias() { return keyAlias; } public File getKeystoreFile() { return keystoreFile; } public String getKeystorePassword() { return keystorePassword; } public File getTruststoreFile() { return truststoreFile; } public String getTruststorePassword() { return truststorePassword; } public void setupHTTPS() { // If we should use HTTPS if (truststoreFile != null) { try { truststore = loadKeyStore(truststoreFile, truststorePassword); } catch (KeyStoreException ex) { throw new RuntimeException("Could not load truststore", ex); } catch (FileNotFoundException ex) { throw new RuntimeException("Could not load truststore", ex); } catch (IOException ex) { throw new RuntimeException("Could not load truststore", ex); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Could not load truststore", ex); } catch (CertificateException ex) { throw new RuntimeException("Could not load truststore", ex); } } // If we should use client authenticated HTTPS if (keystoreFile != null) { try { keystore = loadKeyStore(keystoreFile, keystorePassword); } catch (KeyStoreException ex) { throw new RuntimeException("Could not load keystore", ex); } catch (FileNotFoundException ex) { throw new RuntimeException("Could not load keystore", ex); } catch (IOException ex) { throw new RuntimeException("Could not load keystore", ex); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Could not load keystore", ex); } catch (CertificateException ex) { throw new RuntimeException("Could not load keystore", ex); } } if (truststore == null && keystore == null) { useHTTPS = false; } else if (keystore == null) { useHTTPS = true; } else { if (truststore == null) { truststore = keystore; } useHTTPS = true; usePrivateHTTPS = true; } if (useHTTPS) { try { setDefaultSocketFactory(truststore, keystore, keyAlias, keystorePassword == null ? null : keystorePassword.toCharArray()); } catch (NoSuchAlgorithmException ex) { throw new RuntimeException("Could not setup HTTPS", ex); } catch (KeyStoreException ex) { throw new RuntimeException("Could not setup HTTPS", ex); } catch (KeyManagementException ex) { throw new RuntimeException("Could not setup HTTPS", ex); } catch (UnrecoverableKeyException ex) { throw new RuntimeException("Could not setup HTTPS", ex); } } } private static KeyStore loadKeyStore(final File truststoreFile, final String truststorePassword) throws KeyStoreException, FileNotFoundException, IOException, NoSuchAlgorithmException, CertificateException { KeyStore keystore = KeyStore.getInstance("JKS"); keystore.load(new FileInputStream(truststoreFile), truststorePassword.toCharArray()); return keystore; } private static void setDefaultSocketFactory(final KeyStore truststore, final KeyStore keystore, String keyAlias, char[] keystorePassword) throws NoSuchAlgorithmException, KeyStoreException, KeyManagementException, UnrecoverableKeyException { final TrustManagerFactory tmf = TrustManagerFactory.getInstance("SunX509"); tmf.init(truststore); final KeyManager[] keyManagers; if (keystore == null) { keyManagers = null; } else { if (keyAlias == null) { keyAlias = keystore.aliases().nextElement(); } final KeyManagerFactory kKeyManagerFactory = KeyManagerFactory.getInstance("SunX509"); kKeyManagerFactory.init(keystore, keystorePassword); keyManagers = kKeyManagerFactory.getKeyManagers(); for (int i = 0; i < keyManagers.length; i++) { if (keyManagers[i] instanceof X509KeyManager) { keyManagers[i] = new AliasKeyManager((X509KeyManager) keyManagers[i], keyAlias); } } } final SSLContext context = SSLContext.getInstance("TLS"); context.init(keyManagers, tmf.getTrustManagers(), new SecureRandom()); SSLSocketFactory factory = context.getSocketFactory(); HttpsURLConnection.setDefaultSSLSocketFactory(factory); } public boolean isUseHTTPS() { return useHTTPS; } public boolean isUsePrivateHTTPS() { return usePrivateHTTPS; } public void setUsePrivateHTTPS(boolean usePrivateHTTPS) { this.usePrivateHTTPS = usePrivateHTTPS; } }