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/04/29 18:59:09 UTC

svn commit: r1676791 - in /tomcat/trunk/java/org/apache/tomcat: jni/SSLContext.java util/net/AprEndpoint.java

Author: markt
Date: Wed Apr 29 16:59:08 2015
New Revision: 1676791

URL: http://svn.apache.org/r1676791
Log:
Add the first pass at the Java side plumbing for SNI support with APR/native.

Modified:
    tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java
    tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java

Modified: tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java
URL: http://svn.apache.org/viewvc/tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java?rev=1676791&r1=1676790&r2=1676791&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/jni/SSLContext.java Wed Apr 29 16:59:08 2015
@@ -17,6 +17,9 @@
 
 package org.apache.tomcat.jni;
 
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
 /** SSL Context
  *
  * @author Mladen Turk
@@ -289,4 +292,25 @@ public final class SSLContext {
     public static native void setVerify(long ctx, int level, int depth);
 
     public static native int setALPN(long ctx, byte[] proto, int len);
+
+    public static long sniCallback(long defaultCtx, String sniHostName) {
+        SNICallBack sniCallBack = sniCallBacks.get(Long.valueOf(defaultCtx));
+        if (sniCallBack == null) {
+            return 0;
+        }
+        return sniCallBack.getSslContext(sniHostName);
+    }
+
+    private static Map<Long,SNICallBack> sniCallBacks = new ConcurrentHashMap<>();
+    public static void registerDefault(Long defaultSSLContext,
+            SNICallBack sniCallBack) {
+        sniCallBacks.put(defaultSSLContext, sniCallBack);
+    }
+    public static void unregisterDefault(Long ctx) {
+        sniCallBacks.remove(ctx);
+    }
+
+    public static interface SNICallBack {
+        public long getSslContext(String sniHostName);
+    }
 }

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=1676791&r1=1676790&r2=1676791&view=diff
==============================================================================
--- tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java (original)
+++ tomcat/trunk/java/org/apache/tomcat/util/net/AprEndpoint.java Wed Apr 29 16:59:08 2015
@@ -45,6 +45,7 @@ import org.apache.tomcat.jni.Poll;
 import org.apache.tomcat.jni.Pool;
 import org.apache.tomcat.jni.SSL;
 import org.apache.tomcat.jni.SSLContext;
+import org.apache.tomcat.jni.SSLContext.SNICallBack;
 import org.apache.tomcat.jni.SSLSocket;
 import org.apache.tomcat.jni.Sockaddr;
 import org.apache.tomcat.jni.Socket;
@@ -70,7 +71,7 @@ import org.apache.tomcat.util.net.SSLHos
  * @author Mladen Turk
  * @author Remy Maucherat
  */
-public class AprEndpoint extends AbstractEndpoint<Long> {
+public class AprEndpoint extends AbstractEndpoint<Long> implements SNICallBack {
 
     // -------------------------------------------------------------- Constants
 
@@ -472,12 +473,6 @@ public class AprEndpoint extends Abstrac
         if (isSSLEnabled()) {
             for (SSLHostConfig sslHostConfig : sslHostConfigs.values()) {
 
-                // TODO: No SNI support in APR/native so only process the
-                //       default host.
-                if (!SSLHostConfig.DEFAULT_SSL_HOST_NAME.equals(sslHostConfig.getHostName())) {
-                    continue;
-                }
-
                 if (sslHostConfig.getCertificateFile() == null) {
                     // This is required
                     throw new Exception(sm.getString("endpoint.apr.noSslCertFile"));
@@ -514,8 +509,9 @@ public class AprEndpoint extends Abstrac
                 }
 
                 // Create SSL Context
+                long ctx = 0;
                 try {
-                    sslContext = SSLContext.make(rootPool, value, SSL.SSL_MODE_SERVER);
+                    ctx = SSLContext.make(rootPool, value, SSL.SSL_MODE_SERVER);
                 } catch (Exception e) {
                     // If the sslEngine is disabled on the AprLifecycleListener
                     // there will be an Exception here but there is no way to check
@@ -529,7 +525,7 @@ public class AprEndpoint extends Abstrac
                     try {
                         legacyRenegSupported = SSL.hasOp(SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
                         if (legacyRenegSupported)
-                            SSLContext.setOptions(sslContext, SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
+                            SSLContext.setOptions(ctx, SSL.SSL_OP_ALLOW_UNSAFE_LEGACY_RENEGOTIATION);
                     } catch (UnsatisfiedLinkError e) {
                         // Ignore
                     }
@@ -546,7 +542,7 @@ public class AprEndpoint extends Abstrac
                     try {
                         orderCiphersSupported = SSL.hasOp(SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
                         if (orderCiphersSupported)
-                            SSLContext.setOptions(sslContext, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
+                            SSLContext.setOptions(ctx, SSL.SSL_OP_CIPHER_SERVER_PREFERENCE);
                     } catch (UnsatisfiedLinkError e) {
                         // Ignore
                     }
@@ -563,7 +559,7 @@ public class AprEndpoint extends Abstrac
                     try {
                         disableCompressionSupported = SSL.hasOp(SSL.SSL_OP_NO_COMPRESSION);
                         if (disableCompressionSupported)
-                            SSLContext.setOptions(sslContext, SSL.SSL_OP_NO_COMPRESSION);
+                            SSLContext.setOptions(ctx, SSL.SSL_OP_NO_COMPRESSION);
                     } catch (UnsatisfiedLinkError e) {
                         // Ignore
                     }
@@ -580,7 +576,7 @@ public class AprEndpoint extends Abstrac
                     try {
                         disableSessionTicketsSupported = SSL.hasOp(SSL.SSL_OP_NO_TICKET);
                         if (disableSessionTicketsSupported)
-                            SSLContext.setOptions(sslContext, SSL.SSL_OP_NO_TICKET);
+                            SSLContext.setOptions(ctx, SSL.SSL_OP_NO_TICKET);
                     } catch (UnsatisfiedLinkError e) {
                         // Ignore
                     }
@@ -593,16 +589,16 @@ public class AprEndpoint extends Abstrac
                 }
 
                 // List the ciphers that the client is permitted to negotiate
-                SSLContext.setCipherSuite(sslContext, SSLCipherSuite);
+                SSLContext.setCipherSuite(ctx, SSLCipherSuite);
                 // Load Server key and certificate
-                SSLContext.setCertificate(sslContext, sslHostConfig.getCertificateFile(),
+                SSLContext.setCertificate(ctx, sslHostConfig.getCertificateFile(),
                         sslHostConfig.getCertificateKeyFile(), SSLPassword, SSL.SSL_AIDX_RSA);
                 // Set certificate chain file
-                SSLContext.setCertificateChainFile(sslContext, SSLCertificateChainFile, false);
+                SSLContext.setCertificateChainFile(ctx, SSLCertificateChainFile, false);
                 // Support Client Certificates
-                SSLContext.setCACertificate(sslContext, SSLCACertificateFile, SSLCACertificatePath);
+                SSLContext.setCACertificate(ctx, SSLCACertificateFile, SSLCACertificatePath);
                 // Set revocation
-                SSLContext.setCARevocation(sslContext, SSLCARevocationFile, SSLCARevocationPath);
+                SSLContext.setCARevocation(ctx, SSLCARevocationFile, SSLCARevocationPath);
                 // Client certificate verification
                 value = SSL.SSL_CVERIFY_NONE;
                 if ("optional".equalsIgnoreCase(SSLVerifyClient)) {
@@ -612,7 +608,7 @@ public class AprEndpoint extends Abstrac
                 } else if ("optionalNoCA".equalsIgnoreCase(SSLVerifyClient)) {
                     value = SSL.SSL_CVERIFY_OPTIONAL_NO_CA;
                 }
-                SSLContext.setVerify(sslContext, value, SSLVerifyDepth);
+                SSLContext.setVerify(ctx, value, SSLVerifyDepth);
                 // For now, sendfile is not supported with SSL
                 if (getUseSendfile()) {
                     setUseSendfileInternal(false);
@@ -623,17 +619,35 @@ public class AprEndpoint extends Abstrac
 
                 if (negotiableProtocols.size() > 0) {
                     byte[] protocols = buildAlpnConfig(negotiableProtocols);
-                    if (SSLContext.setALPN(sslContext, protocols, protocols.length) != 0) {
+                    if (SSLContext.setALPN(ctx, protocols, protocols.length) != 0) {
                         log.warn(sm.getString("endpoint.alpn.fail", negotiableProtocols));
                     }
                 }
+                sslHostConfig.setSslContext(Long.valueOf(ctx));
             }
+            SSLHostConfig defaultSSLHostConfig = sslHostConfigs.get(SSLHostConfig.DEFAULT_SSL_HOST_NAME);
+            Long defaultSSLContext = (Long) defaultSSLHostConfig.getSslContext();
+            sslContext = defaultSSLContext.longValue();
+            SSLContext.registerDefault(defaultSSLContext, this);
+
         } else if (negotiableProtocols.size() > 0) {
             log.info(sm.getString("endpoint.noNegotiation", getName(), negotiableProtocols.toString()));
         }
     }
 
 
+    @Override
+    public long getSslContext(String sniHostName) {
+        SSLHostConfig sslHostConfig = getSSLHostConfig(sniHostName);
+        Long ctx = (Long) sslHostConfig.getSslContext();
+        if (ctx != null) {
+            return ctx.longValue();
+        }
+        // Default
+        return 0;
+    }
+
+
     private byte[] buildAlpnConfig(List<String> protocols) {
         /*
          * The expected format is zero or more of the following:
@@ -792,7 +806,14 @@ public class AprEndpoint extends Abstrac
             serverSock = 0;
         }
 
-        sslContext = 0;
+        if (sslContext != 0) {
+            Long ctx = Long.valueOf(sslContext);
+            SSLContext.unregisterDefault(ctx);
+            for (SSLHostConfig sslHostConfig : sslHostConfigs.values()) {
+                sslHostConfig.setSslContext(null);
+            }
+            sslContext = 0;
+        }
 
         // Close all APR memory pools and resources if initialised
         if (rootPool != 0) {



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