You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by ma...@apache.org on 2015/06/19 22:33:16 UTC

svn commit: r1686499 - in /tomcat/trunk/java/org/apache/tomcat/util/net: AbstractJsseEndpoint.java AprEndpoint.java SSLHostConfig.java SSLHostConfigCertificate.java

Author: markt
Date: Fri Jun 19 20:33:16 2015
New Revision: 1686499

URL: http://svn.apache.org/r1686499
Log:
Correct multiple certificate configuration plumbing.
APR/native can handle multiple certificates in a single 'SSLContext'
JSSE needs one 'SSLContext' per certificate

Get key/certificate selection completed to the point where a dummy implementation in a single method needs to be replaced with the real implementation.

Modified:
    tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java
    tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java?rev=1686499&r1=1686498&r2=1686499&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java Fri Jun 19 20:33:16 2015
@@ -17,6 +17,7 @@
 package org.apache.tomcat.util.net;
 
 import java.util.List;
+import java.util.Set;
 
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
@@ -85,7 +86,7 @@ public abstract class AbstractJsseEndpoi
                         sslUtil.configureSessionContext(sessionContext);
                     }
                     SSLContextWrapper sslContextWrapper = new SSLContextWrapper(sslContext, sslUtil);
-                    sslHostConfig.setSslContext(sslContextWrapper);
+                    certificate.setSslContextWrapper(sslContextWrapper);
                 }
             }
         }
@@ -94,7 +95,10 @@ public abstract class AbstractJsseEndpoi
 
     protected SSLEngine createSSLEngine(String sniHostName, List<Cipher> clientRequestedCiphers) {
         SSLHostConfig sslHostConfig = getSSLHostConfig(sniHostName);
-        SSLContextWrapper sslContextWrapper = (SSLContextWrapper) sslHostConfig.getSslContext();
+
+        SSLHostConfigCertificate certificate = selectCertificate(sslHostConfig, clientRequestedCiphers);
+
+        SSLContextWrapper sslContextWrapper = certificate.getSslContextWrapper();
         if (sslContextWrapper == null) {
             throw new IllegalStateException(
                     sm.getString("endpoint.jsse.noSslContext", sniHostName));
@@ -127,15 +131,35 @@ public abstract class AbstractJsseEndpoi
     }
 
 
+    private SSLHostConfigCertificate selectCertificate(
+            SSLHostConfig sslHostConfig, List<Cipher> clientRequestedCiphers) {
+
+        Set<SSLHostConfigCertificate> certificates = sslHostConfig.getCertificates(true);
+        if (certificates.size() == 1) {
+            return certificates.iterator().next();
+        }
+
+        // TODO:
+        // Need to select correct certificate based on the ciphers requested by
+        // the client, the ciphers configured for the server and which is
+        // configured to define the preference order
+
+        // For now, just return the first certificate
+        return certificates.iterator().next();
+    }
+
+
     @Override
     public void unbind() throws Exception {
         for (SSLHostConfig sslHostConfig : sslHostConfigs.values()) {
-            sslHostConfig.setSslContext(null);
+            for (SSLHostConfigCertificate certificate : sslHostConfig.getCertificates(true)) {
+                certificate.setSslContextWrapper(null);
+            }
         }
     }
 
 
-    private static class SSLContextWrapper {
+    static class SSLContextWrapper {
 
         private final SSLContext sslContext;
         private final String[] enabledCiphers;

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java?rev=1686499&r1=1686498&r2=1686499&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Fri Jun 19 20:33:16 2015
@@ -551,10 +551,10 @@ public class AprEndpoint extends Abstrac
                         log.warn(sm.getString("endpoint.alpn.fail", negotiableProtocols));
                     }
                 }
-                sslHostConfig.setSslContext(Long.valueOf(ctx));
+                sslHostConfig.setOpenSslContext(Long.valueOf(ctx));
             }
             SSLHostConfig defaultSSLHostConfig = sslHostConfigs.get(getDefaultSSLHostConfigName());
-            Long defaultSSLContext = (Long) defaultSSLHostConfig.getSslContext();
+            Long defaultSSLContext = (Long) defaultSSLHostConfig.getOpenSslContext();
             sslContext = defaultSSLContext.longValue();
             SSLContext.registerDefault(defaultSSLContext, this);
         }
@@ -564,7 +564,7 @@ public class AprEndpoint extends Abstrac
     @Override
     public long getSslContext(String sniHostName) {
         SSLHostConfig sslHostConfig = getSSLHostConfig(sniHostName);
-        Long ctx = (Long) sslHostConfig.getSslContext();
+        Long ctx = (Long) sslHostConfig.getOpenSslContext();
         if (ctx != null) {
             return ctx.longValue();
         }
@@ -743,7 +743,7 @@ public class AprEndpoint extends Abstrac
             Long ctx = Long.valueOf(sslContext);
             SSLContext.unregisterDefault(ctx);
             for (SSLHostConfig sslHostConfig : sslHostConfigs.values()) {
-                sslHostConfig.setSslContext(null);
+                sslHostConfig.setOpenSslContext(null);
             }
             sslContext = 0;
         }

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java?rev=1686499&r1=1686498&r2=1686499&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfig.java Fri Jun 19 20:33:16 2015
@@ -59,7 +59,10 @@ public class SSLHostConfig {
 
     private String hostName = DEFAULT_SSL_HOST_NAME;
 
-    private Object sslContext;
+    // OpenSSL can handle multiple certs in a single config so the reference to
+    // the context is here at the virtual host level. JSSE can't so the
+    // reference is held on the certificate.
+    private Long openSslContext;
 
     // Configuration properties
 
@@ -99,13 +102,13 @@ public class SSLHostConfig {
     }
 
 
-    public Object getSslContext() {
-        return sslContext;
+    public Object getOpenSslContext() {
+        return openSslContext;
     }
 
 
-    public void setSslContext(Object sslContext) {
-        this.sslContext = sslContext;
+    public void setOpenSslContext(Long openSslContext) {
+        this.openSslContext = openSslContext;
     }
 
 

Modified: tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java?rev=1686499&r1=1686498&r2=1686499&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/SSLHostConfigCertificate.java Fri Jun 19 20:33:16 2015
@@ -16,6 +16,8 @@
  */
 package org.apache.tomcat.util.net;
 
+import org.apache.tomcat.util.net.AbstractJsseEndpoint.SSLContextWrapper;
+
 
 public class SSLHostConfigCertificate {
 
@@ -26,6 +28,11 @@ public class SSLHostConfigCertificate {
     static final String DEFAULT_KEYSTORE_TYPE =
             System.getProperty("javax.net.ssl.keyStoreType", "JKS");
 
+    // OpenSSL can handle multiple certs in a single config so the reference to
+    // the context is at the virtual host level. JSSE can't so the reference is
+    // held here on the certificate.
+    private SSLContextWrapper sslContextWrapper;
+
     // Common
     private final SSLHostConfig sslHostConfig;
     private final Type type;
@@ -49,9 +56,19 @@ public class SSLHostConfigCertificate {
     }
 
 
+    public SSLContextWrapper getSslContextWrapper() {
+        return sslContextWrapper;
+    }
+
+
+    public void setSslContextWrapper(SSLContextWrapper sslContextWrapper) {
+        this.sslContextWrapper = sslContextWrapper;
+    }
+
+
     // Common
 
-    public Type getType() {
+        public Type getType() {
         return type;
     }
 



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