Author: remm
Date: Tue Apr 26 17:09:16 2016
New Revision: 1741061

URL: http://svn.apache.org/viewvc?rev=1741061&view=rev
Log:
59295: Add support for using pem encoded certificates with JSSE SSL. Submitted 
by Emmanuel Bourg with additional tweaks.

Added:
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/PEMFile.java
      - copied unchanged from r1740969, 
tomcat/trunk/java/org/apache/tomcat/util/net/jsse/PEMFile.java
Modified:
    tomcat/tc8.5.x/trunk/   (props changed)
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
    
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
    tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java
    
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties
    tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml
    tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml

Propchange: tomcat/tc8.5.x/trunk/
------------------------------------------------------------------------------
--- svn:mergeinfo (original)
+++ svn:mergeinfo Tue Apr 26 17:09:16 2016
@@ -1 +1 @@
-/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740980,1740991,1741015
+/tomcat/trunk:1734785,1734799,1734845,1734928,1735041,1735044,1735480,1735577,1735597,1735599-1735600,1735615,1736145,1736162,1736209,1736280,1736297,1736299,1736489,1736646,1736703,1736836,1736849,1737104-1737105,1737112,1737117,1737119-1737120,1737155,1737157,1737192,1737280,1737339,1737632,1737664,1737715,1737748,1737785,1737834,1737860,1737959,1738005,1738007,1738014-1738015,1738018,1738022,1738039,1738043,1738059-1738060,1738147,1738149,1738174-1738175,1738261,1738589,1738623-1738625,1738643,1738816,1738850,1738855,1738946-1738948,1738953-1738954,1738979,1738982,1739079-1739081,1739087,1739113,1739153,1739172,1739176,1739191,1739474,1739726,1739762,1739775,1739814,1739817-1739818,1739975,1740131,1740324,1740465,1740495,1740508-1740509,1740520,1740535,1740707,1740803,1740810,1740969,1740980,1740991,1740997,1741015,1741058,1741060

Modified: 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties?rev=1741061&r1=1741060&r2=1741061&view=diff
==============================================================================
--- 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties 
(original)
+++ 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/LocalStrings.properties 
Tue Apr 26 17:09:16 2016
@@ -122,6 +122,7 @@ sslHostConfig.certificateVerificationInv
 sslHostConfig.certificate.notype=Multiple certificates were specified and at 
least one is missing the required attribute type
 sslHostConfig.mismatch=The property [{0}] was set on the SSLHostConfig named 
[{1}] and is for connectors of type [{2}] but the SSLHostConfig is being used 
with a connector of type [{3}]
 sslHostConfig.prefix_missing=The protocol [{0}] was added to the list of 
protocols on the SSLHostConfig named [{1}]. Check if a +/- prefix is missing.
+sslHostConfigCertificate.mismatch=The property [{0}] was set on the 
SSLHostConfigCertificate named [{1}] and is for certificate storage type [{2}] 
but the certificate is being used with a storage of type [{3}]
 
 sslImplementation.cnfe= Unable to create SSLImplementation for class [{0}]
 

Modified: 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java?rev=1741061&r1=1741060&r2=1741061&view=diff
==============================================================================
--- 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
 (original)
+++ 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
 Tue Apr 26 17:09:16 2016
@@ -19,11 +19,17 @@ package org.apache.tomcat.util.net;
 import java.util.HashSet;
 import java.util.Set;
 
+import org.apache.juli.logging.Log;
+import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.net.openssl.ciphers.Authentication;
+import org.apache.tomcat.util.res.StringManager;
 
 
 public class SSLHostConfigCertificate {
 
+    private static final Log log = 
LogFactory.getLog(SSLHostConfigCertificate.class);
+    private static final StringManager sm = 
StringManager.getManager(SSLHostConfigCertificate.class);
+
     public static final Type DEFAULT_TYPE = Type.UNDEFINED;
 
     static final String DEFAULT_KEYSTORE_PROVIDER =
@@ -53,6 +59,8 @@ public class SSLHostConfigCertificate {
     private String certificateFile;
     private String certificateKeyFile;
 
+    // Certificate store type
+    private StoreType storeType = null;
 
     public SSLHostConfigCertificate() {
         this(null, Type.UNDEFINED);
@@ -113,6 +121,7 @@ public class SSLHostConfigCertificate {
     public void setCertificateKeystoreFile(String certificateKeystoreFile) {
         sslHostConfig.setProperty(
                 "Certificate.certificateKeystoreFile", 
SSLHostConfig.Type.JSSE);
+        setStoreType("Certificate.certificateKeystoreFile", 
StoreType.KEYSTORE);
         this.certificateKeystoreFile = certificateKeystoreFile;
     }
 
@@ -125,6 +134,7 @@ public class SSLHostConfigCertificate {
     public void setCertificateKeystorePassword(String 
certificateKeystorePassword) {
         sslHostConfig.setProperty(
                 "Certificate.certificateKeystorePassword", 
SSLHostConfig.Type.JSSE);
+        setStoreType("Certificate.certificateKeystorePassword", 
StoreType.KEYSTORE);
         this.certificateKeystorePassword = certificateKeystorePassword;
     }
 
@@ -137,6 +147,7 @@ public class SSLHostConfigCertificate {
     public void setCertificateKeystoreProvider(String 
certificateKeystoreProvider) {
         sslHostConfig.setProperty(
                 "Certificate.certificateKeystoreProvider", 
SSLHostConfig.Type.JSSE);
+        setStoreType("Certificate.certificateKeystoreProvider", 
StoreType.KEYSTORE);
         this.certificateKeystoreProvider = certificateKeystoreProvider;
     }
 
@@ -149,6 +160,7 @@ public class SSLHostConfigCertificate {
     public void setCertificateKeystoreType(String certificateKeystoreType) {
         sslHostConfig.setProperty(
                 "Certificate.certificateKeystoreType", 
SSLHostConfig.Type.JSSE);
+        setStoreType("Certificate.certificateKeystoreType", 
StoreType.KEYSTORE);
         this.certificateKeystoreType = certificateKeystoreType;
     }
 
@@ -161,8 +173,7 @@ public class SSLHostConfigCertificate {
     // OpenSSL
 
     public void setCertificateChainFile(String certificateChainFile) {
-        sslHostConfig.setProperty(
-                "Certificate.certificateChainFile", 
SSLHostConfig.Type.OPENSSL);
+        setStoreType("Certificate.certificateChainFile", StoreType.PEM);
         this.certificateChainFile = certificateChainFile;
     }
 
@@ -173,8 +184,7 @@ public class SSLHostConfigCertificate {
 
 
     public void setCertificateFile(String certificateFile) {
-        sslHostConfig.setProperty(
-                "Certificate.certificateFile", SSLHostConfig.Type.OPENSSL);
+        setStoreType("Certificate.certificateFile", StoreType.PEM);
         this.certificateFile = certificateFile;
     }
 
@@ -185,8 +195,7 @@ public class SSLHostConfigCertificate {
 
 
     public void setCertificateKeyFile(String certificateKeyFile) {
-        sslHostConfig.setProperty(
-                "Certificate.certificateKeyFile", SSLHostConfig.Type.OPENSSL);
+        setStoreType("Certificate.certificateKeyFile", StoreType.PEM);
         this.certificateKeyFile = certificateKeyFile;
     }
 
@@ -196,6 +205,15 @@ public class SSLHostConfigCertificate {
     }
 
 
+    private void setStoreType(String name, StoreType type) {
+        if (storeType == null) {
+            storeType = type;
+        } else if (storeType != type) {
+            log.warn(sm.getString("sslHostConfigCertificate.mismatch",
+                    name, sslHostConfig.getHostName(), type, this.storeType));
+        }
+    }
+
     // Nested types
 
     public static enum Type {
@@ -220,4 +238,9 @@ public class SSLHostConfigCertificate {
             return compatibleAuthentications.contains(au);
         }
     }
+
+    private enum StoreType {
+        KEYSTORE,
+        PEM
+    }
 }

Modified: 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java?rev=1741061&r1=1741060&r2=1741061&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java 
(original)
+++ tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/JSSEUtil.java Tue 
Apr 26 17:09:16 2016
@@ -28,11 +28,13 @@ import java.security.cert.CRLException;
 import java.security.cert.CertPathParameters;
 import java.security.cert.CertStore;
 import java.security.cert.CertStoreParameters;
+import java.security.cert.Certificate;
 import java.security.cert.CertificateException;
 import java.security.cert.CertificateFactory;
 import java.security.cert.CollectionCertStoreParameters;
 import java.security.cert.PKIXBuilderParameters;
 import java.security.cert.X509CertSelector;
+import java.util.ArrayList;
 import java.util.Arrays;
 import java.util.Collection;
 import java.util.HashSet;
@@ -275,7 +277,31 @@ public class JSSEUtil extends SSLUtilBas
 
         KeyManager[] kms = null;
 
-        KeyStore ks = getStore(keystoreType, keystoreProvider, keystoreFile, 
keystorePass);
+        KeyStore ks;
+
+        if (certificate.getCertificateFile() == null) {
+            ks = getStore(keystoreType, keystoreProvider, keystoreFile, 
keystorePass);
+        } else {
+            // create an in-memory keystore and import the private key
+            // and the certificate chain from the PEM files
+            ks = KeyStore.getInstance("JKS");
+            ks.load(null, null);
+
+            PEMFile privateKeyFile = new 
PEMFile(SSLHostConfig.adjustRelativePath
+                    (certificate.getCertificateKeyFile() != null ? 
certificate.getCertificateKeyFile() : certificate.getCertificateFile()),
+                    keyPass);
+            PEMFile certificateFile = new 
PEMFile(SSLHostConfig.adjustRelativePath(certificate.getCertificateFile()));
+
+            Collection<Certificate> chain = new ArrayList<>();
+            chain.addAll(certificateFile.getCertificates());
+            if (certificate.getCertificateChainFile() != null) {
+                PEMFile certificateChainFile = new 
PEMFile(SSLHostConfig.adjustRelativePath(certificate.getCertificateChainFile()));
+                chain.addAll(certificateChainFile.getCertificates());
+            }
+
+            ks.setKeyEntry(keyAlias, privateKeyFile.getPrivateKey(), 
keyPass.toCharArray(), chain.toArray(new Certificate[chain.size()]));
+        }
+
         if (keyAlias != null && !ks.isKeyEntry(keyAlias)) {
             throw new IOException(sm.getString("jsse.alias_no_key_entry", 
keyAlias));
         }

Modified: 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties?rev=1741061&r1=1741060&r2=1741061&view=diff
==============================================================================
--- 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties
 (original)
+++ 
tomcat/tc8.5.x/trunk/java/org/apache/tomcat/util/net/jsse/LocalStrings.properties
 Tue Apr 26 17:09:16 2016
@@ -25,6 +25,8 @@ jsse.excludeDefaultProtocol=The SSL prot
 jsse.noDefaultCiphers=Unable to determine a default for ciphers for [{0}]. Set 
an explicit value to ensure the connector can start.
 jsse.noDefaultProtocols=Unable to determine a default for sslEnabledProtocols. 
Set an explicit value to ensure the connector can start.
 jsse.exceptionOnClose=Failure to close socket.
+jsse.pemParseError=Unable to parse the key from [{0}]
+
 jsseSupport.clientCertError=Error trying to obtain a certificate from the 
client
 jseeSupport.certTranslationError=Error translating certificate [{0}]
 jsseSupport.noCertWant=No client certificate sent for want

Modified: tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml?rev=1741061&r1=1741060&r2=1741061&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/changelog.xml Tue Apr 26 17:09:16 2016
@@ -198,6 +198,10 @@
         the <code>Content-Langauge</code> HTTP header to ensure the locale is
         correctly represented. Patch provided by zikfat. (markt)
       </fix>
+      <update>
+        <bug>59295</bug>: Add support for using pem encoded certificates with
+        JSSE SSL. Submitted by Emmanuel Bourg with additional tweaks. (remm)
+      </update>
     </changelog>
   </subsection>
   <subsection name="WebSocket">

Modified: tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml
URL: 
http://svn.apache.org/viewvc/tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml?rev=1741061&r1=1741060&r2=1741061&view=diff
==============================================================================
--- tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml (original)
+++ tomcat/tc8.5.x/trunk/webapps/docs/config/http.xml Tue Apr 26 17:09:16 2016
@@ -1256,7 +1256,6 @@
   <attributes>
 
     <attribute name="certificateFile" required="true">
-      <p>OpenSSL only.</p>
       <p>Name of the file that contains the server certificate. The format is
       PEM-encoded. Relative paths will be resolved against
       <code>$CATALINA_BASE</code>.</p>
@@ -1268,7 +1267,6 @@
     </attribute>
 
     <attribute name="certificateChainFile" required="false">
-      <p>OpenSSL only.</p>
       <p>Name of the file that contains the certificate chain associated with
       the server certificate used. The format is
       PEM-encoded. Relative paths will be resolved against
@@ -1291,7 +1289,6 @@
     </attribute>
 
     <attribute name="certificateKeyFile" required="false">
-      <p>OpenSSL only.</p>
       <p>Name of the file that contains the server private key. The format is
       PEM-encoded. The default value is the value of
       <strong>certificateFile</strong> and in this case both certificate and



---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to