package org.springframework.data.rest.shell.commands; import java.io.File; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import org.springframework.shell.core.CommandMarker; import org.springframework.shell.core.annotation.CliCommand; import org.springframework.shell.core.annotation.CliOption; import org.springframework.stereotype.Component; /** * Commands for managing SSL configuration. * * @author Jon Brisbin */ @Component public class SslCommands implements CommandMarker { private final SSLContext defaultContext; private SSLContext customContext; private boolean validate = true; private KeyManager[] keyManagers; private TrustManager[] trustManagers; private File truststore; private String truststorePassword; private File keystore; private String keystorePassword; { try { defaultContext = SSLContext.getDefault(); } catch(NoSuchAlgorithmException e) { throw new IllegalStateException(e.getMessage(), e); } } public SSLContext getCustomContext() { return (null == customContext ? defaultContext : customContext); } public KeyManager[] getKeyManagers() throws IOException, KeyStoreException, NoSuchAlgorithmException, CertificateException { if(null != keystore) { KeyStore keyks = KeyStore.getInstance("JKS"); keyks.load(new FileInputStream(keystore), keystorePassword.toCharArray()); KeyManagerFactory keyfac = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); keyManagers = keyfac.getKeyManagers(); } return keyManagers; } public TrustManager[] getTrustManagers() throws KeyStoreException, IOException, NoSuchAlgorithmException, CertificateException { if(!validate) { return new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public void checkServerTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException { } @Override public X509Certificate[] getAcceptedIssuers() { return null; } } }; } else if(null != truststore) { KeyStore trustks = KeyStore.getInstance("JKS"); trustks.load(new FileInputStream(truststore), truststorePassword.toCharArray()); TrustManagerFactory trustfac = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); trustManagers = trustfac.getTrustManagers(); } return trustManagers; } public boolean getValidate() { return validate; } @CliCommand(value = "ssl reset", help = "Reset the SSL configuration back to the system default") public void reset() { SSLContext.setDefault(defaultContext); } @CliCommand(value = "ssl truststore", help = "Manage the truststore TrustManagers") public void truststore( @CliOption( key = "file", mandatory = true, help = "Set the truststore file to use for SSL") File truststore, @CliOption( key = "password", mandatory = false, help = "Set the truststore password to use for SSL") String password) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException { this.truststore = truststore; this.truststorePassword = (null == password ? "" : password); setCustomContext(); } @CliCommand(value = "ssl keystore", help = "Manage the keystore KeyManagers") public void keystore( @CliOption( key = "file", mandatory = true, help = "Set the keystore file to use for SSL") File keystore, @CliOption( key = "password", mandatory = false, help = "Set the keystore password to use for SSL") String password) throws IOException, NoSuchAlgorithmException, KeyManagementException, KeyStoreException, CertificateException { this.keystore = keystore; this.keystorePassword = (null == password ? "" : password); setCustomContext(); } @CliCommand(value = "ssl validate", help = "Manage settings for validation of SSL certificates") public void validate( @CliOption( key = "enabled", mandatory = false, unspecifiedDefaultValue = "true", help = "Turns certificate checking on or off") boolean enabled) throws NoSuchAlgorithmException, KeyManagementException, IOException, KeyStoreException, CertificateException { this.validate = enabled; setCustomContext(); } private void setCustomContext() throws NoSuchAlgorithmException, IOException, KeyStoreException, CertificateException, KeyManagementException { customContext = SSLContext.getInstance("TLS"); customContext.init(getKeyManagers(), getTrustManagers(), null); } }