Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ELY-2026] Use reflection to pass through the new methods if they are now available on the SSLEngine, SSLParameters, and SSLSocket APIs. #1448

Merged
merged 2 commits into from
Oct 7, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
124 changes: 124 additions & 0 deletions ssl/src/main/java/org/wildfly/security/ssl/JDKSpecific.java
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@

package org.wildfly.security.ssl;

import static org.wildfly.security.ssl.ElytronMessages.tls;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.List;
import java.util.function.BiFunction;

Expand All @@ -27,23 +31,88 @@

final class JDKSpecific {

// SSLEngine Methods

private static final Method SSLENGINE_GET_APPLICATION_PROTOCOL = getMethodOrNull(SSLEngine.class, "getApplicationProtocol");
private static final Method SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL = getMethodOrNull(SSLEngine.class, "getHandshakeApplicationProtocol");
private static final Method SSLENGINE_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLEngine.class, "setHandshakeApplicationProtocolSelector", BiFunction.class);
private static final Method SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLEngine.class, "getHandshakeApplicationProtocolSelector");

// SSLParameters Methods

private static final Method SSLPARAMETERS_GET_APPLICATION_PROTOCOLS = getMethodOrNull(SSLParameters.class, "getApplicationProtocols");
private static final Method SSLPARAMETERS_SET_APPLICATION_PROTOCOLS = getMethodOrNull(SSLParameters.class, "setApplicationProtocols", String[].class);

// SSLSocket Methods

private static final Method SSLSOCKET_GET_APPLICATION_PROTOCOL = getMethodOrNull(SSLSocket.class, "getApplicationProtocol");
private static final Method SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL = getMethodOrNull(SSLSocket.class, "getHandshakeApplicationProtocol");
private static final Method SSLSOCKET_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLSocket.class, "setHandshakeApplicationProtocolSelector", BiFunction.class);
private static final Method SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR = getMethodOrNull(SSLSocket.class, "getHandshakeApplicationProtocolSelector");

private static Method getMethodOrNull(Class clazz, String methodName, Class... parameterTypes) {
try {
return clazz.getMethod(methodName, parameterTypes);
} catch (Exception e) {
if (tls.isTraceEnabled()) {
tls.tracef(e, "Unable to getMethod %s on class %s", methodName, clazz.getName());
} else if (tls.isDebugEnabled()) {
tls.debugf("Unable to getMethod %s on class %s", methodName, clazz.getName());
}

return null;
}
}

/*
* SSLEngine
*/

static String getApplicationProtocol(SSLEngine sslEngine) {
if (SSLENGINE_GET_APPLICATION_PROTOCOL != null) {
try {
return (String) SSLENGINE_GET_APPLICATION_PROTOCOL.invoke(sslEngine);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static String getHandshakeApplicationProtocol(SSLEngine sslEngine) {
if (SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL != null) {
try {
return (String) SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL.invoke(sslEngine);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static void setHandshakeApplicationProtocolSelector(SSLEngine sslEngine, BiFunction<SSLEngine, List<String>, String> selector) {
if (SSLENGINE_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) {
try {
SSLENGINE_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(sslEngine, selector);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtocolSelector(SSLEngine sslEngine) {
if (SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) {
try {
return (BiFunction<SSLEngine, List<String>, String>) SSLENGINE_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(sslEngine);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

Expand All @@ -52,10 +121,26 @@ static BiFunction<SSLEngine, List<String>, String> getHandshakeApplicationProtoc
*/

static String[] getApplicationProtocols(SSLParameters parameters) {
if (SSLPARAMETERS_GET_APPLICATION_PROTOCOLS != null) {
try {
return (String[]) SSLPARAMETERS_GET_APPLICATION_PROTOCOLS.invoke(parameters);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static void setApplicationProtocols(SSLParameters parameters, String[] protocols) {
if (SSLPARAMETERS_SET_APPLICATION_PROTOCOLS != null) {
try {
SSLPARAMETERS_SET_APPLICATION_PROTOCOLS.invoke(parameters, (Object) protocols);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this work or should it be new Object[] {protocols}?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah this works, I found the same in the Undertow code as well. The main point was to stop the protocols array itself being seen as an array of arguments - when I test this Undertow is setting an array of three Strings.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Right yeah. It seemed like it may work, I've just never tried it this way is all :)

} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

Expand All @@ -79,6 +164,13 @@ static SSLParameters setSSLParameters(SSLParameters original) {
} else if (original.getNeedClientAuth()) {
params.setNeedClientAuth(original.getNeedClientAuth());
}

try {
if (SSLPARAMETERS_GET_APPLICATION_PROTOCOLS != null && SSLPARAMETERS_SET_APPLICATION_PROTOCOLS != null) {
setApplicationProtocols(params, getApplicationProtocols(original));
}
} catch (Exception ignored) {}

return params;
}

Expand All @@ -87,18 +179,50 @@ static SSLParameters setSSLParameters(SSLParameters original) {
*/

static String getApplicationProtocol(SSLSocket socket) {
if (SSLSOCKET_GET_APPLICATION_PROTOCOL != null) {
try {
return (String) SSLSOCKET_GET_APPLICATION_PROTOCOL.invoke(socket);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static String getHandshakeApplicationProtocol(SSLSocket socket) {
if (SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL != null) {
try {
return (String) SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL.invoke(socket);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static void setHandshakeApplicationProtocolSelector(SSLSocket socket, BiFunction<SSLSocket, List<String>, String> selector) {
if (SSLSOCKET_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) {
try {
SSLSOCKET_SET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(socket, selector);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

static BiFunction<SSLSocket, List<String>, String> getHandshakeApplicationProtocolSelector(SSLSocket socket) {
if (SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR != null) {
try {
return (BiFunction<SSLSocket, List<String>, String>) SSLSOCKET_GET_HANDSHAKE_APPLICATION_PROTOCOL_SELECTOR.invoke(socket);
} catch (IllegalAccessException | InvocationTargetException e) {
throw new UnsupportedOperationException(e);
}
}

throw new UnsupportedOperationException();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,27 +133,27 @@ public void setNeedClientAuth(final SSLContext sslContext, final SSLServerSocket
}

public void setEnabledCipherSuites(final SSLContext sslContext, final SSLSocket sslSocket, final String[] cipherSuites) {
// ignored
sslSocket.setEnabledCipherSuites(cipherSuiteSelector.evaluate(cipherSuites));
}

public void setEnabledCipherSuites(final SSLContext sslContext, final SSLEngine sslEngine, final String[] cipherSuites) {
// ignored
sslEngine.setEnabledCipherSuites(cipherSuiteSelector.evaluate(cipherSuites));
}

public void setEnabledCipherSuites(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final String[] suites) {
// ignored
public void setEnabledCipherSuites(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final String[] cipherSuites) {
sslServerSocket.setEnabledCipherSuites(cipherSuiteSelector.evaluate(cipherSuites));
}

public void setEnabledProtocols(final SSLContext sslContext, final SSLSocket sslSocket, final String[] protocols) {
// ignored
sslSocket.setEnabledProtocols(protocolSelector.evaluate(protocols));
}

public void setEnabledProtocols(final SSLContext sslContext, final SSLEngine sslEngine, final String[] protocols) {
// ignored
sslEngine.setEnabledProtocols(protocolSelector.evaluate(protocols));
}

public void setEnabledProtocols(final SSLContext sslContext, final SSLServerSocket sslServerSocket, final String[] protocols) {
// ignored
sslServerSocket.setEnabledProtocols(protocolSelector.evaluate(protocols));
}

private SSLParameters redefine(SSLParameters original) {
Expand Down