You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@tomcat.apache.org by re...@apache.org on 2020/07/03 09:18:02 UTC

[tomcat] branch master updated (7763877 -> 091f11f)

This is an automated email from the ASF dual-hosted git repository.

remm pushed a change to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git.


    from 7763877  Direct use of the ALPN API
     new 35d8448  Revert "Direct use of the ALPN API"
     new 091f11f  Revert

The 2 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 java/org/apache/tomcat/util/compat/JreCompat.java  | 69 ++++++++++++++++++++++
 .../tomcat/util/compat/LocalStrings.properties     |  3 +
 .../tomcat/util/net/AbstractJsseEndpoint.java      | 20 ++++++-
 .../apache/tomcat/util/net/SSLImplementation.java  |  1 +
 java/org/apache/tomcat/util/net/SSLUtil.java       | 12 ++++
 .../apache/tomcat/util/net/SecureNio2Channel.java  |  9 ++-
 .../apache/tomcat/util/net/SecureNioChannel.java   |  9 ++-
 .../tomcat/util/net/jsse/JSSEImplementation.java   |  5 ++
 .../tomcat/util/net/openssl/OpenSSLEngine.java     |  5 +-
 .../util/net/openssl/OpenSSLImplementation.java    |  5 ++
 webapps/docs/changelog.xml                         |  8 ---
 11 files changed, 131 insertions(+), 15 deletions(-)


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


[tomcat] 01/02: Revert "Direct use of the ALPN API"

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 35d84487fd10bfd6f2a00494078a5e3eef1b1830
Author: remm <re...@apache.org>
AuthorDate: Fri Jul 3 11:16:24 2020 +0200

    Revert "Direct use of the ALPN API"
    
    This reverts commit 7763877a98e5c74bb579b64f31e938fea17290a5.
---
 java/org/apache/tomcat/util/compat/JreCompat.java  | 69 ++++++++++++++++++++++
 .../tomcat/util/compat/LocalStrings.properties     |  3 +
 .../tomcat/util/net/AbstractJsseEndpoint.java      | 20 ++++++-
 .../apache/tomcat/util/net/SSLImplementation.java  |  1 +
 java/org/apache/tomcat/util/net/SSLUtil.java       | 12 ++++
 .../apache/tomcat/util/net/SecureNio2Channel.java  |  9 ++-
 .../apache/tomcat/util/net/SecureNioChannel.java   |  9 ++-
 .../tomcat/util/net/jsse/JSSEImplementation.java   |  5 ++
 .../tomcat/util/net/openssl/OpenSSLEngine.java     |  5 +-
 .../util/net/openssl/OpenSSLImplementation.java    |  5 ++
 10 files changed, 131 insertions(+), 7 deletions(-)

diff --git a/java/org/apache/tomcat/util/compat/JreCompat.java b/java/org/apache/tomcat/util/compat/JreCompat.java
index 2f0268f..8275e60 100644
--- a/java/org/apache/tomcat/util/compat/JreCompat.java
+++ b/java/org/apache/tomcat/util/compat/JreCompat.java
@@ -19,11 +19,18 @@ package org.apache.tomcat.util.compat;
 import java.io.File;
 import java.io.IOException;
 import java.lang.reflect.AccessibleObject;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
 import java.net.URL;
 import java.net.URLConnection;
 import java.util.Deque;
 import java.util.jar.JarFile;
 
+import javax.net.ssl.SSLEngine;
+import javax.net.ssl.SSLParameters;
+
+import org.apache.tomcat.util.res.StringManager;
+
 /**
  * This is the base implementation class for JRE compatibility and provides an
  * implementation based on Java 8. Sub-classes may extend this class and provide
@@ -37,6 +44,10 @@ public class JreCompat {
     private static final boolean graalAvailable;
     private static final boolean jre11Available;
     private static final boolean jre9Available;
+    private static final StringManager sm = StringManager.getManager(JreCompat.class);
+
+    protected static final Method setApplicationProtocolsMethod;
+    protected static final Method getApplicationProtocolMethod;
 
     static {
         // This is Tomcat 9 with a minimum Java version of Java 8.
@@ -55,6 +66,17 @@ public class JreCompat {
             jre9Available = false;
         }
         jre11Available = instance.jarFileRuntimeMajorVersion() >= 11;
+
+        Method m1 = null;
+        Method m2 = null;
+        try {
+            m1 = SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
+            m2 = SSLEngine.class.getMethod("getApplicationProtocol");
+        } catch (ReflectiveOperationException | IllegalArgumentException e) {
+            // Only the newest Java 8 have the ALPN API, so ignore
+        }
+        setApplicationProtocolsMethod = m1;
+        getApplicationProtocolMethod = m2;
     }
 
 
@@ -68,6 +90,11 @@ public class JreCompat {
     }
 
 
+    public static boolean isAlpnSupported() {
+        return setApplicationProtocolsMethod != null && getApplicationProtocolMethod != null;
+    }
+
+
     public static boolean isJre9Available() {
         return jre9Available;
     }
@@ -96,6 +123,48 @@ public class JreCompat {
 
 
     /**
+     * Set the application protocols the server will accept for ALPN
+     *
+     * @param sslParameters The SSL parameters for a connection
+     * @param protocols     The application protocols to be allowed for that
+     *                      connection
+     */
+    public void setApplicationProtocols(SSLParameters sslParameters, String[] protocols) {
+        if (setApplicationProtocolsMethod != null) {
+            try {
+                setApplicationProtocolsMethod.invoke(sslParameters, (Object) protocols);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                throw new UnsupportedOperationException(e);
+            }
+        } else {
+            throw new UnsupportedOperationException(sm.getString("jreCompat.noApplicationProtocols"));
+        }
+    }
+
+
+    /**
+     * Get the application protocol that has been negotiated for connection
+     * associated with the given SSLEngine.
+     *
+     * @param sslEngine The SSLEngine for which to obtain the negotiated
+     *                  protocol
+     *
+     * @return The name of the negotiated protocol
+     */
+    public String getApplicationProtocol(SSLEngine sslEngine) {
+        if (getApplicationProtocolMethod != null) {
+            try {
+                return (String) getApplicationProtocolMethod.invoke(sslEngine);
+            } catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
+                throw new UnsupportedOperationException(e);
+            }
+        } else {
+            throw new UnsupportedOperationException(sm.getString("jreCompat.noApplicationProtocol"));
+        }
+    }
+
+
+    /**
      * Disables caching for JAR URL connections. For Java 8 and earlier, this also disables
      * caching for ALL URL connections.
      *
diff --git a/java/org/apache/tomcat/util/compat/LocalStrings.properties b/java/org/apache/tomcat/util/compat/LocalStrings.properties
index 34ffd70..891782c 100644
--- a/java/org/apache/tomcat/util/compat/LocalStrings.properties
+++ b/java/org/apache/tomcat/util/compat/LocalStrings.properties
@@ -16,3 +16,6 @@
 jre9Compat.invalidModuleUri=The module URI provided [{0}] could not be converted to a URL for the JarScanner to process
 jre9Compat.javaPre9=Class not found so assuming code is running on a pre-Java 9 JVM
 jre9Compat.unexpected=Failed to create references to Java 9 classes and methods
+
+jreCompat.noApplicationProtocol=Java Runtime does not support SSLEngine.getApplicationProtocol(). You must use Java 9 to use this feature.
+jreCompat.noApplicationProtocols=Java Runtime does not support SSLParameters.setApplicationProtocols(). You must use Java 9 to use this feature.
diff --git a/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java b/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
index 1488393..925e91d 100644
--- a/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
+++ b/java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java
@@ -28,6 +28,7 @@ import java.util.Set;
 import javax.net.ssl.SSLEngine;
 import javax.net.ssl.SSLParameters;
 
+import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
 
 public abstract class AbstractJsseEndpoint<S,U> extends AbstractEndpoint<S,U> {
@@ -122,7 +123,7 @@ public abstract class AbstractJsseEndpoint<S,U> extends AbstractEndpoint<S,U> {
 
         SSLParameters sslParameters = engine.getSSLParameters();
         sslParameters.setUseCipherSuitesOrder(sslHostConfig.getHonorCipherOrder());
-        if (clientRequestedApplicationProtocols != null
+        if (JreCompat.isAlpnSupported() && clientRequestedApplicationProtocols != null
                 && clientRequestedApplicationProtocols.size() > 0
                 && negotiableProtocols.size() > 0) {
             // Only try to negotiate if both client and server have at least
@@ -133,7 +134,7 @@ public abstract class AbstractJsseEndpoint<S,U> extends AbstractEndpoint<S,U> {
             commonProtocols.retainAll(clientRequestedApplicationProtocols);
             if (commonProtocols.size() > 0) {
                 String[] commonProtocolsArray = commonProtocols.toArray(new String[0]);
-                sslParameters.setApplicationProtocols(commonProtocolsArray);
+                JreCompat.getInstance().setApplicationProtocols(sslParameters, commonProtocolsArray);
             }
         }
         switch (sslHostConfig.getCertificateVerification()) {
@@ -192,7 +193,20 @@ public abstract class AbstractJsseEndpoint<S,U> extends AbstractEndpoint<S,U> {
     @Override
     public boolean isAlpnSupported() {
         // ALPN requires TLS so if TLS is not enabled, ALPN cannot be supported
-        return isSSLEnabled();
+        if (!isSSLEnabled()) {
+            return false;
+        }
+
+        // Depends on the SSLImplementation.
+        SSLImplementation sslImplementation;
+        try {
+            sslImplementation = SSLImplementation.getInstance(getSslImplementationName());
+        } catch (ClassNotFoundException e) {
+            // Ignore the exception. It will be logged when trying to start the
+            // end point.
+            return false;
+        }
+        return sslImplementation.isAlpnSupported();
     }
 
 
diff --git a/java/org/apache/tomcat/util/net/SSLImplementation.java b/java/org/apache/tomcat/util/net/SSLImplementation.java
index fb11b82..43ccbe5 100644
--- a/java/org/apache/tomcat/util/net/SSLImplementation.java
+++ b/java/org/apache/tomcat/util/net/SSLImplementation.java
@@ -68,4 +68,5 @@ public abstract class SSLImplementation {
 
     public abstract SSLUtil getSSLUtil(SSLHostConfigCertificate certificate);
 
+    public abstract boolean isAlpnSupported();
 }
diff --git a/java/org/apache/tomcat/util/net/SSLUtil.java b/java/org/apache/tomcat/util/net/SSLUtil.java
index 4ba3504..c65f7a2 100644
--- a/java/org/apache/tomcat/util/net/SSLUtil.java
+++ b/java/org/apache/tomcat/util/net/SSLUtil.java
@@ -67,4 +67,16 @@ public interface SSLUtil {
      */
     public String[] getEnabledCiphers() throws IllegalArgumentException;
 
+    /**
+     * Optional interface that can be implemented by
+     * {@link javax.net.ssl.SSLEngine}s to indicate that they support ALPN and
+     * can provided the protocol agreed with the client.
+     */
+    public interface ProtocolInfo {
+        /**
+         * ALPN information.
+         * @return the protocol selected using ALPN
+         */
+        public String getNegotiatedProtocol();
+    }
 }
diff --git a/java/org/apache/tomcat/util/net/SecureNio2Channel.java b/java/org/apache/tomcat/util/net/SecureNio2Channel.java
index 3db1038..394837c 100644
--- a/java/org/apache/tomcat/util/net/SecureNio2Channel.java
+++ b/java/org/apache/tomcat/util/net/SecureNio2Channel.java
@@ -38,6 +38,7 @@ import javax.net.ssl.SSLException;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.buf.ByteBufferUtils;
+import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.net.TLSClientHelloExtractor.ExtractorResult;
 import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
 import org.apache.tomcat.util.res.StringManager;
@@ -241,7 +242,13 @@ public class SecureNio2Channel extends Nio2Channel  {
                 }
                 case FINISHED: {
                     if (endpoint.hasNegotiableProtocols()) {
-                        socketWrapper.setNegotiatedProtocol(sslEngine.getApplicationProtocol());
+                        if (sslEngine instanceof SSLUtil.ProtocolInfo) {
+                            socketWrapper.setNegotiatedProtocol(
+                                    ((SSLUtil.ProtocolInfo) sslEngine).getNegotiatedProtocol());
+                        } else if (JreCompat.isAlpnSupported()) {
+                            socketWrapper.setNegotiatedProtocol(
+                                    JreCompat.getInstance().getApplicationProtocol(sslEngine));
+                        }
                     }
                     //we are complete if we have delivered the last package
                     handshakeComplete = !netOutBuffer.hasRemaining();
diff --git a/java/org/apache/tomcat/util/net/SecureNioChannel.java b/java/org/apache/tomcat/util/net/SecureNioChannel.java
index ef0a33e..a176675 100644
--- a/java/org/apache/tomcat/util/net/SecureNioChannel.java
+++ b/java/org/apache/tomcat/util/net/SecureNioChannel.java
@@ -35,6 +35,7 @@ import javax.net.ssl.SSLException;
 import org.apache.juli.logging.Log;
 import org.apache.juli.logging.LogFactory;
 import org.apache.tomcat.util.buf.ByteBufferUtils;
+import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper;
 import org.apache.tomcat.util.net.TLSClientHelloExtractor.ExtractorResult;
 import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
@@ -166,7 +167,13 @@ public class SecureNioChannel extends NioChannel {
                     throw new IOException(sm.getString("channel.nio.ssl.notHandshaking"));
                 case FINISHED:
                     if (endpoint.hasNegotiableProtocols()) {
-                        socketWrapper.setNegotiatedProtocol(sslEngine.getApplicationProtocol());
+                        if (sslEngine instanceof SSLUtil.ProtocolInfo) {
+                            socketWrapper.setNegotiatedProtocol(
+                                    ((SSLUtil.ProtocolInfo) sslEngine).getNegotiatedProtocol());
+                        } else if (JreCompat.isAlpnSupported()) {
+                            socketWrapper.setNegotiatedProtocol(
+                                    JreCompat.getInstance().getApplicationProtocol(sslEngine));
+                        }
                     }
                     //we are complete if we have delivered the last package
                     handshakeComplete = !netOutBuffer.hasRemaining();
diff --git a/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java b/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
index 4fa54be..1c1eae8 100644
--- a/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
+++ b/java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java
@@ -18,6 +18,7 @@ package org.apache.tomcat.util.net.jsse;
 
 import javax.net.ssl.SSLSession;
 
+import org.apache.tomcat.util.compat.JreCompat;
 import org.apache.tomcat.util.net.SSLHostConfigCertificate;
 import org.apache.tomcat.util.net.SSLImplementation;
 import org.apache.tomcat.util.net.SSLSupport;
@@ -49,4 +50,8 @@ public class JSSEImplementation extends SSLImplementation {
         return new JSSEUtil(certificate);
     }
 
+    @Override
+    public boolean isAlpnSupported() {
+        return JreCompat.isAlpnSupported();
+    }
 }
diff --git a/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java b/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java
index 16f1451..058ee71 100644
--- a/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java
+++ b/java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java
@@ -46,6 +46,7 @@ import org.apache.tomcat.jni.SSL;
 import org.apache.tomcat.jni.SSLContext;
 import org.apache.tomcat.util.buf.ByteBufferUtils;
 import org.apache.tomcat.util.net.Constants;
+import org.apache.tomcat.util.net.SSLUtil;
 import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser;
 import org.apache.tomcat.util.res.StringManager;
 
@@ -54,7 +55,7 @@ import org.apache.tomcat.util.res.StringManager;
  * <a href="https://www.openssl.org/docs/crypto/BIO_s_bio.html#EXAMPLE">OpenSSL
  * BIO abstractions</a>.
  */
-public final class OpenSSLEngine extends SSLEngine {
+public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolInfo {
 
     private static final Log logger = LogFactory.getLog(OpenSSLEngine.class);
     private static final StringManager sm = StringManager.getManager(OpenSSLEngine.class);
@@ -208,7 +209,7 @@ public final class OpenSSLEngine extends SSLEngine {
     }
 
     @Override
-    public String getApplicationProtocol() {
+    public String getNegotiatedProtocol() {
         return selectedProtocol;
     }
 
diff --git a/java/org/apache/tomcat/util/net/openssl/OpenSSLImplementation.java b/java/org/apache/tomcat/util/net/openssl/OpenSSLImplementation.java
index 6f2c3bf..94b4bf2 100644
--- a/java/org/apache/tomcat/util/net/openssl/OpenSSLImplementation.java
+++ b/java/org/apache/tomcat/util/net/openssl/OpenSSLImplementation.java
@@ -36,4 +36,9 @@ public class OpenSSLImplementation extends SSLImplementation {
         return new OpenSSLUtil(certificate);
     }
 
+    @Override
+    public boolean isAlpnSupported() {
+        // OpenSSL supported ALPN
+        return true;
+    }
 }


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


[tomcat] 02/02: Revert

Posted by re...@apache.org.
This is an automated email from the ASF dual-hosted git repository.

remm pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/tomcat.git

commit 091f11ff5c31e32b8615347ec88cd97dc858885a
Author: remm <re...@apache.org>
AuthorDate: Fri Jul 3 11:17:40 2020 +0200

    Revert
---
 webapps/docs/changelog.xml | 8 --------
 1 file changed, 8 deletions(-)

diff --git a/webapps/docs/changelog.xml b/webapps/docs/changelog.xml
index 16e4fb2..fcd4cc8 100644
--- a/webapps/docs/changelog.xml
+++ b/webapps/docs/changelog.xml
@@ -45,14 +45,6 @@
   issues do not "pop up" wrt. others).
 -->
 <section name="Tomcat 10.0.0-M8 (markt)" rtext="in development">
-  <subsection name="Coyote">
-    <changelog>
-      <fix>
-        Remove ALPN abstraction to simplify code. Tomcat now requires
-        Java 8 251 or 252 for TLS support. (remm)
-      </fix>
-    </changelog>
-  </subsection>
 </section>
 <section name="Tomcat 10.0.0-M7 (markt)" rtext="release in progress">
   <subsection name="Catalina">


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