Skip to content

Commit 7763877

Browse files
committed
Direct use of the ALPN API
Tomcat 10 will now require at least Java 8_251, which was released in April 2020, for TLS support. Any Java 9+ JVM will work too. This will not be backported to Tomcat 9.0 as it slightly changes the APIs, although the changes are trivial.
1 parent 7414188 commit 7763877

File tree

10 files changed

+7
-131
lines changed

10 files changed

+7
-131
lines changed

java/org/apache/tomcat/util/compat/JreCompat.java

Lines changed: 0 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -19,18 +19,11 @@
1919
import java.io.File;
2020
import java.io.IOException;
2121
import java.lang.reflect.AccessibleObject;
22-
import java.lang.reflect.InvocationTargetException;
23-
import java.lang.reflect.Method;
2422
import java.net.URL;
2523
import java.net.URLConnection;
2624
import java.util.Deque;
2725
import java.util.jar.JarFile;
2826

29-
import javax.net.ssl.SSLEngine;
30-
import javax.net.ssl.SSLParameters;
31-
32-
import org.apache.tomcat.util.res.StringManager;
33-
3427
/**
3528
* This is the base implementation class for JRE compatibility and provides an
3629
* implementation based on Java 8. Sub-classes may extend this class and provide
@@ -44,10 +37,6 @@ public class JreCompat {
4437
private static final boolean graalAvailable;
4538
private static final boolean jre11Available;
4639
private static final boolean jre9Available;
47-
private static final StringManager sm = StringManager.getManager(JreCompat.class);
48-
49-
protected static final Method setApplicationProtocolsMethod;
50-
protected static final Method getApplicationProtocolMethod;
5140

5241
static {
5342
// This is Tomcat 9 with a minimum Java version of Java 8.
@@ -66,17 +55,6 @@ public class JreCompat {
6655
jre9Available = false;
6756
}
6857
jre11Available = instance.jarFileRuntimeMajorVersion() >= 11;
69-
70-
Method m1 = null;
71-
Method m2 = null;
72-
try {
73-
m1 = SSLParameters.class.getMethod("setApplicationProtocols", String[].class);
74-
m2 = SSLEngine.class.getMethod("getApplicationProtocol");
75-
} catch (ReflectiveOperationException | IllegalArgumentException e) {
76-
// Only the newest Java 8 have the ALPN API, so ignore
77-
}
78-
setApplicationProtocolsMethod = m1;
79-
getApplicationProtocolMethod = m2;
8058
}
8159

8260

@@ -90,11 +68,6 @@ public static boolean isGraalAvailable() {
9068
}
9169

9270

93-
public static boolean isAlpnSupported() {
94-
return setApplicationProtocolsMethod != null && getApplicationProtocolMethod != null;
95-
}
96-
97-
9871
public static boolean isJre9Available() {
9972
return jre9Available;
10073
}
@@ -122,48 +95,6 @@ public boolean isInstanceOfInaccessibleObjectException(Throwable t) {
12295
}
12396

12497

125-
/**
126-
* Set the application protocols the server will accept for ALPN
127-
*
128-
* @param sslParameters The SSL parameters for a connection
129-
* @param protocols The application protocols to be allowed for that
130-
* connection
131-
*/
132-
public void setApplicationProtocols(SSLParameters sslParameters, String[] protocols) {
133-
if (setApplicationProtocolsMethod != null) {
134-
try {
135-
setApplicationProtocolsMethod.invoke(sslParameters, (Object) protocols);
136-
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
137-
throw new UnsupportedOperationException(e);
138-
}
139-
} else {
140-
throw new UnsupportedOperationException(sm.getString("jreCompat.noApplicationProtocols"));
141-
}
142-
}
143-
144-
145-
/**
146-
* Get the application protocol that has been negotiated for connection
147-
* associated with the given SSLEngine.
148-
*
149-
* @param sslEngine The SSLEngine for which to obtain the negotiated
150-
* protocol
151-
*
152-
* @return The name of the negotiated protocol
153-
*/
154-
public String getApplicationProtocol(SSLEngine sslEngine) {
155-
if (getApplicationProtocolMethod != null) {
156-
try {
157-
return (String) getApplicationProtocolMethod.invoke(sslEngine);
158-
} catch (IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
159-
throw new UnsupportedOperationException(e);
160-
}
161-
} else {
162-
throw new UnsupportedOperationException(sm.getString("jreCompat.noApplicationProtocol"));
163-
}
164-
}
165-
166-
16798
/**
16899
* Disables caching for JAR URL connections. For Java 8 and earlier, this also disables
169100
* caching for ALL URL connections.

java/org/apache/tomcat/util/compat/LocalStrings.properties

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,3 @@
1616
jre9Compat.invalidModuleUri=The module URI provided [{0}] could not be converted to a URL for the JarScanner to process
1717
jre9Compat.javaPre9=Class not found so assuming code is running on a pre-Java 9 JVM
1818
jre9Compat.unexpected=Failed to create references to Java 9 classes and methods
19-
20-
jreCompat.noApplicationProtocol=Java Runtime does not support SSLEngine.getApplicationProtocol(). You must use Java 9 to use this feature.
21-
jreCompat.noApplicationProtocols=Java Runtime does not support SSLParameters.setApplicationProtocols(). You must use Java 9 to use this feature.

java/org/apache/tomcat/util/net/AbstractJsseEndpoint.java

Lines changed: 3 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,6 @@
2828
import javax.net.ssl.SSLEngine;
2929
import javax.net.ssl.SSLParameters;
3030

31-
import org.apache.tomcat.util.compat.JreCompat;
3231
import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
3332

3433
public abstract class AbstractJsseEndpoint<S,U> extends AbstractEndpoint<S,U> {
@@ -123,7 +122,7 @@ protected SSLEngine createSSLEngine(String sniHostName, List<Cipher> clientReque
123122

124123
SSLParameters sslParameters = engine.getSSLParameters();
125124
sslParameters.setUseCipherSuitesOrder(sslHostConfig.getHonorCipherOrder());
126-
if (JreCompat.isAlpnSupported() && clientRequestedApplicationProtocols != null
125+
if (clientRequestedApplicationProtocols != null
127126
&& clientRequestedApplicationProtocols.size() > 0
128127
&& negotiableProtocols.size() > 0) {
129128
// Only try to negotiate if both client and server have at least
@@ -134,7 +133,7 @@ protected SSLEngine createSSLEngine(String sniHostName, List<Cipher> clientReque
134133
commonProtocols.retainAll(clientRequestedApplicationProtocols);
135134
if (commonProtocols.size() > 0) {
136135
String[] commonProtocolsArray = commonProtocols.toArray(new String[0]);
137-
JreCompat.getInstance().setApplicationProtocols(sslParameters, commonProtocolsArray);
136+
sslParameters.setApplicationProtocols(commonProtocolsArray);
138137
}
139138
}
140139
switch (sslHostConfig.getCertificateVerification()) {
@@ -193,20 +192,7 @@ private SSLHostConfigCertificate selectCertificate(
193192
@Override
194193
public boolean isAlpnSupported() {
195194
// ALPN requires TLS so if TLS is not enabled, ALPN cannot be supported
196-
if (!isSSLEnabled()) {
197-
return false;
198-
}
199-
200-
// Depends on the SSLImplementation.
201-
SSLImplementation sslImplementation;
202-
try {
203-
sslImplementation = SSLImplementation.getInstance(getSslImplementationName());
204-
} catch (ClassNotFoundException e) {
205-
// Ignore the exception. It will be logged when trying to start the
206-
// end point.
207-
return false;
208-
}
209-
return sslImplementation.isAlpnSupported();
195+
return isSSLEnabled();
210196
}
211197

212198

java/org/apache/tomcat/util/net/SSLImplementation.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,5 +68,4 @@ public static SSLImplementation getInstance(String className)
6868

6969
public abstract SSLUtil getSSLUtil(SSLHostConfigCertificate certificate);
7070

71-
public abstract boolean isAlpnSupported();
7271
}

java/org/apache/tomcat/util/net/SSLUtil.java

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,16 +67,4 @@ public interface SSLUtil {
6767
*/
6868
public String[] getEnabledCiphers() throws IllegalArgumentException;
6969

70-
/**
71-
* Optional interface that can be implemented by
72-
* {@link javax.net.ssl.SSLEngine}s to indicate that they support ALPN and
73-
* can provided the protocol agreed with the client.
74-
*/
75-
public interface ProtocolInfo {
76-
/**
77-
* ALPN information.
78-
* @return the protocol selected using ALPN
79-
*/
80-
public String getNegotiatedProtocol();
81-
}
8270
}

java/org/apache/tomcat/util/net/SecureNio2Channel.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,6 @@
3838
import org.apache.juli.logging.Log;
3939
import org.apache.juli.logging.LogFactory;
4040
import org.apache.tomcat.util.buf.ByteBufferUtils;
41-
import org.apache.tomcat.util.compat.JreCompat;
4241
import org.apache.tomcat.util.net.TLSClientHelloExtractor.ExtractorResult;
4342
import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
4443
import org.apache.tomcat.util.res.StringManager;
@@ -242,13 +241,7 @@ protected int handshakeInternal(boolean async) throws IOException {
242241
}
243242
case FINISHED: {
244243
if (endpoint.hasNegotiableProtocols()) {
245-
if (sslEngine instanceof SSLUtil.ProtocolInfo) {
246-
socketWrapper.setNegotiatedProtocol(
247-
((SSLUtil.ProtocolInfo) sslEngine).getNegotiatedProtocol());
248-
} else if (JreCompat.isAlpnSupported()) {
249-
socketWrapper.setNegotiatedProtocol(
250-
JreCompat.getInstance().getApplicationProtocol(sslEngine));
251-
}
244+
socketWrapper.setNegotiatedProtocol(sslEngine.getApplicationProtocol());
252245
}
253246
//we are complete if we have delivered the last package
254247
handshakeComplete = !netOutBuffer.hasRemaining();

java/org/apache/tomcat/util/net/SecureNioChannel.java

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@
3535
import org.apache.juli.logging.Log;
3636
import org.apache.juli.logging.LogFactory;
3737
import org.apache.tomcat.util.buf.ByteBufferUtils;
38-
import org.apache.tomcat.util.compat.JreCompat;
3938
import org.apache.tomcat.util.net.NioEndpoint.NioSocketWrapper;
4039
import org.apache.tomcat.util.net.TLSClientHelloExtractor.ExtractorResult;
4140
import org.apache.tomcat.util.net.openssl.ciphers.Cipher;
@@ -167,13 +166,7 @@ public int handshake(boolean read, boolean write) throws IOException {
167166
throw new IOException(sm.getString("channel.nio.ssl.notHandshaking"));
168167
case FINISHED:
169168
if (endpoint.hasNegotiableProtocols()) {
170-
if (sslEngine instanceof SSLUtil.ProtocolInfo) {
171-
socketWrapper.setNegotiatedProtocol(
172-
((SSLUtil.ProtocolInfo) sslEngine).getNegotiatedProtocol());
173-
} else if (JreCompat.isAlpnSupported()) {
174-
socketWrapper.setNegotiatedProtocol(
175-
JreCompat.getInstance().getApplicationProtocol(sslEngine));
176-
}
169+
socketWrapper.setNegotiatedProtocol(sslEngine.getApplicationProtocol());
177170
}
178171
//we are complete if we have delivered the last package
179172
handshakeComplete = !netOutBuffer.hasRemaining();

java/org/apache/tomcat/util/net/jsse/JSSEImplementation.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
import javax.net.ssl.SSLSession;
2020

21-
import org.apache.tomcat.util.compat.JreCompat;
2221
import org.apache.tomcat.util.net.SSLHostConfigCertificate;
2322
import org.apache.tomcat.util.net.SSLImplementation;
2423
import org.apache.tomcat.util.net.SSLSupport;
@@ -50,8 +49,4 @@ public SSLUtil getSSLUtil(SSLHostConfigCertificate certificate) {
5049
return new JSSEUtil(certificate);
5150
}
5251

53-
@Override
54-
public boolean isAlpnSupported() {
55-
return JreCompat.isAlpnSupported();
56-
}
5752
}

java/org/apache/tomcat/util/net/openssl/OpenSSLEngine.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@
4646
import org.apache.tomcat.jni.SSLContext;
4747
import org.apache.tomcat.util.buf.ByteBufferUtils;
4848
import org.apache.tomcat.util.net.Constants;
49-
import org.apache.tomcat.util.net.SSLUtil;
5049
import org.apache.tomcat.util.net.openssl.ciphers.OpenSSLCipherConfigurationParser;
5150
import org.apache.tomcat.util.res.StringManager;
5251

@@ -55,7 +54,7 @@
5554
* <a href="https://www.openssl.org/docs/crypto/BIO_s_bio.html#EXAMPLE">OpenSSL
5655
* BIO abstractions</a>.
5756
*/
58-
public final class OpenSSLEngine extends SSLEngine implements SSLUtil.ProtocolInfo {
57+
public final class OpenSSLEngine extends SSLEngine {
5958

6059
private static final Log logger = LogFactory.getLog(OpenSSLEngine.class);
6160
private static final StringManager sm = StringManager.getManager(OpenSSLEngine.class);
@@ -209,7 +208,7 @@ private enum Accepted { NOT, IMPLICIT, EXPLICIT }
209208
}
210209

211210
@Override
212-
public String getNegotiatedProtocol() {
211+
public String getApplicationProtocol() {
213212
return selectedProtocol;
214213
}
215214

java/org/apache/tomcat/util/net/openssl/OpenSSLImplementation.java

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,9 +36,4 @@ public SSLUtil getSSLUtil(SSLHostConfigCertificate certificate) {
3636
return new OpenSSLUtil(certificate);
3737
}
3838

39-
@Override
40-
public boolean isAlpnSupported() {
41-
// OpenSSL supported ALPN
42-
return true;
43-
}
4439
}

0 commit comments

Comments
 (0)