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

Reply via email to