Author: remm Date: Thu Nov 26 14:33:44 2015 New Revision: 1716691 URL: http://svn.apache.org/viewvc?rev=1716691&view=rev Log: - Since it should be the same thing, use the JSSE code to load the keystore and truststore, if using the JSSE style configuration. Then proceed to get the certificate and use setCertificateRaw as before. - If I missed something, let me know.
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java?rev=1716691&r1=1716690&r2=1716691&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLContext.java Thu Nov 26 14:33:44 2015 @@ -16,36 +16,19 @@ */ package org.apache.tomcat.util.net.openssl; -import java.io.IOException; -import java.io.InputStream; import java.nio.charset.StandardCharsets; -import java.security.InvalidAlgorithmParameterException; -import java.security.InvalidKeyException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; import java.security.PrivateKey; import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; import java.security.cert.CertificateException; import java.security.cert.CertificateFactory; import java.security.cert.X509Certificate; -import java.security.spec.InvalidKeySpecException; -import java.security.spec.PKCS8EncodedKeySpec; import java.util.ArrayList; import java.util.Base64; import java.util.List; import java.util.StringTokenizer; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; -import javax.crypto.Cipher; -import javax.crypto.EncryptedPrivateKeyInfo; -import javax.crypto.NoSuchPaddingException; -import javax.crypto.SecretKey; -import javax.crypto.SecretKeyFactory; -import javax.crypto.spec.PBEKeySpec; import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLEngine; import javax.net.ssl.SSLException; import javax.net.ssl.SSLParameters; @@ -61,11 +44,11 @@ import org.apache.tomcat.jni.Certificate import org.apache.tomcat.jni.Pool; import org.apache.tomcat.jni.SSL; import org.apache.tomcat.jni.SSLContext; -import org.apache.tomcat.util.file.ConfigFileLoader; import org.apache.tomcat.util.net.AbstractEndpoint; import org.apache.tomcat.util.net.Constants; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; +import org.apache.tomcat.util.net.jsse.JSSEKeyManager; import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser; import org.apache.tomcat.util.res.StringManager; @@ -326,16 +309,14 @@ public class OpenSSLContext implements o SSLContext.setCipherSuite(ctx, ciphers); // Load Server key and certificate if (certificate.getCertificateFile() != null) { - + // Set certificate SSLContext.setCertificate(ctx, SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile()), certificate.getCertificateKeyPassword(), SSL.SSL_AIDX_RSA); - // Set certificate chain file SSLContext.setCertificateChainFile(ctx, SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()), false); - // Support Client Certificates SSLContext.setCACertificate(ctx, SSLHostConfig.adjustRelativePath(sslHostConfig.getCaCertificateFile()), @@ -347,16 +328,14 @@ public class OpenSSLContext implements o SSLHostConfig.adjustRelativePath( sslHostConfig.getCertificateRevocationListPath())); } else { - /* Try use keystore */ - X509KeyManager keyManager = getJSSEKeyManager(sslHostConfig); - String alias = getJSSEAlias(sslHostConfig, keyManager); + X509KeyManager keyManager = chooseKeyManager(kms); + String alias = certificate.getCertificateKeyAlias(); X509Certificate certificate = keyManager.getCertificateChain(alias)[0]; PrivateKey key = keyManager.getPrivateKey(alias); StringBuilder sb = new StringBuilder(BEGIN_KEY); sb.append(Base64.getMimeEncoder(64, new byte[] {'\n'}).encodeToString(key.getEncoded())); sb.append(END_KEY); SSLContext.setCertificateRaw(ctx, certificate.getEncoded(), sb.toString().getBytes(StandardCharsets.US_ASCII), SSL.SSL_AIDX_RSA); - } // Client certificate verification int value = 0; @@ -411,64 +390,16 @@ public class OpenSSLContext implements o } } - String getJSSEAlias(SSLHostConfig sslHostConfig, X509KeyManager keyManager) { - String alias = null; - // TODO make sure we get the right one... - if (certificate.getCertificateKeyAlias() != null) - alias = certificate.getCertificateKeyAlias(); - return alias; - } - /** - * get the JSSE key manager for the keystore - * @throws KeyStoreException - * @throws NoSuchAlgorithmException - * @throws UnrecoverableKeyException - * @throws IOException - * @throws CertificateException - * - */ - static X509KeyManager getJSSEKeyManager(SSLHostConfig sslHostConfig) throws KeyStoreException, UnrecoverableKeyException, NoSuchAlgorithmException, CertificateException, IOException { - String keystoretype = null; - String keystoreprovider = null; - String keystorefile = null; - String password = null; - // TODO make sure we get the right one... - for (SSLHostConfigCertificate certificate : sslHostConfig.getCertificates(true)) { - if (certificate.getCertificateKeystoreFile() != null) - keystorefile = certificate.getCertificateKeystoreFile(); - if (certificate.getCertificateKeystorePassword() != null) - password = certificate.getCertificateKeystorePassword(); - if (certificate.getCertificateKeystoreType() != null) - keystoretype = certificate.getCertificateKeystoreType(); - if (certificate.getCertificateKeystoreProvider() != null) - keystoreprovider = certificate.getCertificateKeystoreProvider(); - } - KeyStore ks = KeyStore.getInstance(keystoretype); - InputStream stream = ConfigFileLoader.getInputStream(keystorefile); - ks.load(stream, password.toCharArray()); - KeyManagerFactory kmf; - if (keystoreprovider != null) - kmf = KeyManagerFactory.getInstance(keystoreprovider); - else - kmf = KeyManagerFactory.getInstance(KeyManagerFactory.getDefaultAlgorithm()); - kmf.init(ks, password.toCharArray()); - KeyManager[] kms = kmf.getKeyManagers(); - if (kms == null) { - return null; - } - return (X509KeyManager) kms[0]; - } - - static OpenSSLKeyManager chooseKeyManager(KeyManager[] managers) throws Exception { + private static JSSEKeyManager chooseKeyManager(KeyManager[] managers) throws Exception { for (KeyManager manager : managers) { - if (manager instanceof OpenSSLKeyManager) { - return (OpenSSLKeyManager) manager; + if (manager instanceof JSSEKeyManager) { + return (JSSEKeyManager) manager; } } throw new IllegalStateException(sm.getString("openssl.keyManagerMissing")); } - static X509TrustManager chooseTrustManager(TrustManager[] managers) { + private static X509TrustManager chooseTrustManager(TrustManager[] managers) { for (TrustManager m : managers) { if (m instanceof X509TrustManager) { return (X509TrustManager) m; @@ -506,46 +437,6 @@ public class OpenSSLContext implements o throw new UnsupportedOperationException(); } - /** - * Generates a key specification for an (encrypted) private key. - * - * @param password characters, if {@code null} or empty an unencrypted key - * is assumed - * @param key bytes of the DER encoded private key - * - * @return a key specification - * - * @throws IOException if parsing {@code key} fails - * @throws NoSuchAlgorithmException if the algorithm used to encrypt - * {@code key} is unknown - * @throws NoSuchPaddingException if the padding scheme specified in the - * decryption algorithm is unknown - * @throws InvalidKeySpecException if the decryption key based on - * {@code password} cannot be generated - * @throws InvalidKeyException if the decryption key based on - * {@code password} cannot be used to decrypt {@code key} - * @throws InvalidAlgorithmParameterException if decryption algorithm - * parameters are somehow faulty - */ - protected static PKCS8EncodedKeySpec generateKeySpec(char[] password, byte[] key) - throws IOException, NoSuchAlgorithmException, NoSuchPaddingException, InvalidKeySpecException, - InvalidKeyException, InvalidAlgorithmParameterException { - - if (password == null || password.length == 0) { - return new PKCS8EncodedKeySpec(key); - } - - EncryptedPrivateKeyInfo encryptedPrivateKeyInfo = new EncryptedPrivateKeyInfo(key); - SecretKeyFactory keyFactory = SecretKeyFactory.getInstance(encryptedPrivateKeyInfo.getAlgName()); - PBEKeySpec pbeKeySpec = new PBEKeySpec(password); - SecretKey pbeKey = keyFactory.generateSecret(pbeKeySpec); - - Cipher cipher = Cipher.getInstance(encryptedPrivateKeyInfo.getAlgName()); - cipher.init(Cipher.DECRYPT_MODE, pbeKey, encryptedPrivateKeyInfo.getAlgParameters()); - - return encryptedPrivateKeyInfo.getKeySpec(cipher); - } - @Override protected final void finalize() throws Throwable { super.finalize(); Modified: tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java?rev=1716691&r1=1716690&r2=1716691&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/openssl/OpenSSLUtil.java Thu Nov 26 14:33:44 2015 @@ -16,25 +16,23 @@ */ package org.apache.tomcat.util.net.openssl; -import java.io.InputStream; -import java.security.KeyStore; import java.util.List; import javax.net.ssl.KeyManager; import javax.net.ssl.SSLSessionContext; import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; -import org.apache.tomcat.util.file.ConfigFileLoader; import org.apache.tomcat.util.net.SSLContext; import org.apache.tomcat.util.net.SSLHostConfig; import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.apache.tomcat.util.net.SSLUtil; +import org.apache.tomcat.util.net.jsse.JSSESocketFactory; public class OpenSSLUtil implements SSLUtil { private final SSLHostConfig sslHostConfig; private final SSLHostConfigCertificate certificate; + private final JSSESocketFactory jsseUtil; private String[] enabledProtocols = null; private String[] enabledCiphers = null; @@ -42,6 +40,13 @@ public class OpenSSLUtil implements SSLU public OpenSSLUtil(SSLHostConfig sslHostConfig, SSLHostConfigCertificate certificate) { this.sslHostConfig = sslHostConfig; this.certificate = certificate; + if (certificate.getCertificateFile() == null) { + // Using JSSE configuration for keystore and truststore + jsseUtil = new JSSESocketFactory(sslHostConfig, certificate); + } else { + // Use OpenSSL configuration for certificates + jsseUtil = null; + } } @Override @@ -51,50 +56,27 @@ public class OpenSSLUtil implements SSLU @Override public KeyManager[] getKeyManagers() throws Exception { - KeyManager[] managers = { - new OpenSSLKeyManager(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), - SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile())) - }; - return managers; + if (jsseUtil != null) { + return jsseUtil.getKeyManagers(); + } else { + // Return something although it is not actually used + KeyManager[] managers = { + new OpenSSLKeyManager(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()), + SSLHostConfig.adjustRelativePath(certificate.getCertificateKeyFile())) + }; + return managers; + } } - /* In fact we can use the JSSE one for the moment */ @Override public TrustManager[] getTrustManagers() throws Exception { - String storefile = System.getProperty("java.home") + "/lib/security/cacerts"; - String password = "changeit"; - String type = "jks"; - String algorithm = null; - if (sslHostConfig.getTruststoreFile() != null) { - storefile = sslHostConfig.getTruststoreFile(); - } - if (sslHostConfig.getTruststorePassword() != null) { - password = sslHostConfig.getTruststorePassword(); - } - if (sslHostConfig.getTruststoreType() != null) { - type = sslHostConfig.getTruststoreType(); - } - if (sslHostConfig.getTruststoreAlgorithm() != null) { - algorithm = sslHostConfig.getTruststoreAlgorithm(); + if (jsseUtil != null) { + return jsseUtil.getTrustManagers(); + } else { + return null; } - - TrustManagerFactory factory; - if (algorithm == null) - factory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - else - factory = TrustManagerFactory.getInstance(algorithm); - - KeyStore keystore = KeyStore.getInstance(type); - try (InputStream stream = ConfigFileLoader.getInputStream(storefile)) { - keystore.load(stream, password.toCharArray()); - } - - factory.init(keystore); - TrustManager[] managers = factory.getTrustManagers(); - return managers; } - @Override public void configureSessionContext(SSLSessionContext sslSessionContext) { // do nothing. configuration is done in the init phase --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org