Author: markt Date: Thu Aug 31 21:49:19 2017 New Revision: 1806873 URL: http://svn.apache.org/viewvc?rev=1806873&view=rev Log: Fix https://bz.apache.org/bugzilla/show_bug.cgi?id=61451 Correct a regression in the fix to enable the use of Java key stores that contained multiple keys that did not all have the same password. The regression broke support for any key store that did not store keys in PKCS #8 format such as hardware key stores and Windows key stores.
Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java tomcat/trunk/webapps/docs/changelog.xml Modified: tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java?rev=1806873&r1=1806872&r2=1806873&view=diff ============================================================================== --- tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java (original) +++ tomcat/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java Thu Aug 31 21:49:19 2017 @@ -18,6 +18,7 @@ package org.apache.tomcat.util.net.jsse; import java.io.IOException; import java.io.InputStream; +import java.security.Key; import java.security.KeyManagementException; import java.security.KeyStore; import java.security.NoSuchAlgorithmException; @@ -180,18 +181,19 @@ public class JSSEUtil extends SSLUtilBas } KeyStore ks = certificate.getCertificateKeystore(); + KeyStore ksUsed = ks; /* - * Always use an in memory key store. + * Use an in memory key store where possible. * For PEM format keys and certificates, it allows them to be imported * into the expected format. - * For Java key stores, it enables Tomcat to handle the case where - * multiple keys exist in the key store, each with a different password. - * The KeyManagerFactory can't handle that so using an in memory key - * store with just the required key works around that. + * For Java key stores with PKCS8 encoded keys (e.g. JKS files), it + * enables Tomcat to handle the case where multiple keys exist in the + * key store, each with a different password. The KeyManagerFactory + * can't handle that so using an in memory key store with just the + * required key works around that. + * Other keys stores (hardware, MS, etc.) will be used as is. */ - KeyStore inMemoryKeyStore = KeyStore.getInstance("JKS"); - inMemoryKeyStore.load(null, null); char[] keyPassArray = keyPass.toCharArray(); @@ -211,7 +213,12 @@ public class JSSEUtil extends SSLUtilBas if (keyAlias == null) { keyAlias = "tomcat"; } - inMemoryKeyStore.setKeyEntry(keyAlias, privateKeyFile.getPrivateKey(), keyPass.toCharArray(), chain.toArray(new Certificate[chain.size()])); + + // Switch to in-memory key store + ksUsed = KeyStore.getInstance("JKS"); + ksUsed.load(null, null); + ksUsed.setKeyEntry(keyAlias, privateKeyFile.getPrivateKey(), keyPass.toCharArray(), + chain.toArray(new Certificate[chain.size()])); } else { if (keyAlias != null && !ks.isKeyEntry(keyAlias)) { throw new IOException(sm.getString("jsse.alias_no_key_entry", keyAlias)); @@ -231,13 +238,19 @@ public class JSSEUtil extends SSLUtilBas } } - inMemoryKeyStore.setKeyEntry(keyAlias, ks.getKey(keyAlias, keyPassArray), keyPassArray, - ks.getCertificateChain(keyAlias)); + Key k = ks.getKey(keyAlias, keyPassArray); + if (k != null && "PKCS#8".equalsIgnoreCase(k.getFormat())) { + // Switch to in-memory key store + ksUsed = KeyStore.getInstance("JKS"); + ksUsed.load(null, null); + ksUsed.setKeyEntry(keyAlias, k, keyPassArray, ks.getCertificateChain(keyAlias)); + } + // Non-PKCS#8 key stores will use the original key store } KeyManagerFactory kmf = KeyManagerFactory.getInstance(algorithm); - kmf.init(inMemoryKeyStore, keyPassArray); + kmf.init(ksUsed, keyPassArray); return kmf.getKeyManagers(); } Modified: tomcat/trunk/webapps/docs/changelog.xml URL: http://svn.apache.org/viewvc/tomcat/trunk/webapps/docs/changelog.xml?rev=1806873&r1=1806872&r2=1806873&view=diff ============================================================================== --- tomcat/trunk/webapps/docs/changelog.xml (original) +++ tomcat/trunk/webapps/docs/changelog.xml Thu Aug 31 21:49:19 2017 @@ -142,6 +142,13 @@ <fix> <bug>61450</bug>: Fix default key alias algorithm. (remm) </fix> + <fix> + <bug>61451</bug>: Correct a regression in the fix to enable the use of + Java key stores that contained multiple keys that did not all have the + same password. The regression broke support for any key store that did + not store keys in PKCS #8 format such as hardware key stores and Windows + key stores. (markt) + </fix> </changelog> </subsection> <subsection name="Web applications"> --------------------------------------------------------------------- To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org For additional commands, e-mail: dev-h...@tomcat.apache.org