Allow to enable/disable protocols on the OpenSslEngine
Motivation: To be compatible with SSLEngine we need to support enable / disable procols on the OpenSslEngine Modifications: Implement OpenSslEngine.getSupportedProtocols() , getEnabledProtocols() and setEnabledProtocols(...) Result: Better compability with SSLEngine
This commit is contained in:
parent
6bfc68c785
commit
eabfb91686
@ -313,12 +313,12 @@ public abstract class OpenSslContext extends SslContext {
|
|||||||
return OpenSslDefaultApplicationProtocolNegotiator.INSTANCE;
|
return OpenSslDefaultApplicationProtocolNegotiator.INSTANCE;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(config.protocol()) {
|
switch (config.protocol()) {
|
||||||
case NONE:
|
case NONE:
|
||||||
return OpenSslDefaultApplicationProtocolNegotiator.INSTANCE;
|
return OpenSslDefaultApplicationProtocolNegotiator.INSTANCE;
|
||||||
case NPN:
|
case NPN:
|
||||||
if (isServer) {
|
if (isServer) {
|
||||||
switch(config.selectedListenerFailureBehavior()) {
|
switch (config.selectedListenerFailureBehavior()) {
|
||||||
case CHOOSE_MY_LAST_PROTOCOL:
|
case CHOOSE_MY_LAST_PROTOCOL:
|
||||||
return new OpenSslNpnApplicationProtocolNegotiator(config.supportedProtocols());
|
return new OpenSslNpnApplicationProtocolNegotiator(config.supportedProtocols());
|
||||||
default:
|
default:
|
||||||
|
@ -38,8 +38,13 @@ import java.nio.ByteBuffer;
|
|||||||
import java.nio.ReadOnlyBufferException;
|
import java.nio.ReadOnlyBufferException;
|
||||||
import java.security.Principal;
|
import java.security.Principal;
|
||||||
import java.security.cert.Certificate;
|
import java.security.cert.Certificate;
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||||
import java.util.regex.Pattern;
|
import java.util.regex.Pattern;
|
||||||
@ -82,6 +87,24 @@ public final class OpenSslEngine extends SSLEngine {
|
|||||||
private static final int MAX_COMPRESSED_LENGTH = MAX_PLAINTEXT_LENGTH + 1024;
|
private static final int MAX_COMPRESSED_LENGTH = MAX_PLAINTEXT_LENGTH + 1024;
|
||||||
private static final int MAX_CIPHERTEXT_LENGTH = MAX_COMPRESSED_LENGTH + 1024;
|
private static final int MAX_CIPHERTEXT_LENGTH = MAX_COMPRESSED_LENGTH + 1024;
|
||||||
|
|
||||||
|
// Protocols
|
||||||
|
private static final String PROTOCOL_SSL_V2_HELLO = "SSLv2Hello";
|
||||||
|
private static final String PROTOCOL_SSL_V2 = "SSLv2";
|
||||||
|
private static final String PROTOCOL_SSL_V3 = "SSLv3";
|
||||||
|
private static final String PROTOCOL_TLS_V1 = "TLSv1";
|
||||||
|
private static final String PROTOCOL_TLS_V1_1 = "TLSv1.1";
|
||||||
|
private static final String PROTOCOL_TLS_V1_2 = "TLSv1.2";
|
||||||
|
|
||||||
|
private static final String[] SUPPORTED_PROTOCOLS = {
|
||||||
|
PROTOCOL_SSL_V2_HELLO,
|
||||||
|
PROTOCOL_SSL_V2,
|
||||||
|
PROTOCOL_SSL_V3,
|
||||||
|
PROTOCOL_TLS_V1,
|
||||||
|
PROTOCOL_TLS_V1_1,
|
||||||
|
PROTOCOL_TLS_V1_2
|
||||||
|
};
|
||||||
|
private static final Set<String> SUPPORTED_PROTOCOLS_SET = new HashSet<String>(Arrays.asList(SUPPORTED_PROTOCOLS));
|
||||||
|
|
||||||
// Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256)
|
// Header (5) + Data (2^14) + Compression (1024) + Encryption (1024) + MAC (20) + Padding (256)
|
||||||
static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256;
|
static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256;
|
||||||
|
|
||||||
@ -644,17 +667,83 @@ public final class OpenSslEngine extends SSLEngine {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getSupportedProtocols() {
|
public String[] getSupportedProtocols() {
|
||||||
return EmptyArrays.EMPTY_STRINGS;
|
return SUPPORTED_PROTOCOLS.clone();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] getEnabledProtocols() {
|
public String[] getEnabledProtocols() {
|
||||||
return EmptyArrays.EMPTY_STRINGS;
|
List<String> enabled = new ArrayList<String>();
|
||||||
|
// Seems like there is no way to explict disable SSLv2Hello in openssl so it is always enabled
|
||||||
|
enabled.add(PROTOCOL_SSL_V2_HELLO);
|
||||||
|
int opts = SSL.getOptions(ssl);
|
||||||
|
if ((opts & SSL.SSL_OP_NO_TLSv1) == 0) {
|
||||||
|
enabled.add(PROTOCOL_TLS_V1);
|
||||||
|
}
|
||||||
|
if ((opts & SSL.SSL_OP_NO_TLSv1_1) == 0) {
|
||||||
|
enabled.add(PROTOCOL_TLS_V1_1);
|
||||||
|
}
|
||||||
|
if ((opts & SSL.SSL_OP_NO_TLSv1_2) == 0) {
|
||||||
|
enabled.add(PROTOCOL_TLS_V1_2);
|
||||||
|
}
|
||||||
|
if ((opts & SSL.SSL_OP_NO_SSLv2) == 0) {
|
||||||
|
enabled.add(PROTOCOL_SSL_V2);
|
||||||
|
}
|
||||||
|
if ((opts & SSL.SSL_OP_NO_SSLv3) == 0) {
|
||||||
|
enabled.add(PROTOCOL_SSL_V3);
|
||||||
|
}
|
||||||
|
int size = enabled.size();
|
||||||
|
if (size == 0) {
|
||||||
|
return EmptyArrays.EMPTY_STRINGS;
|
||||||
|
} else {
|
||||||
|
return enabled.toArray(new String[size]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void setEnabledProtocols(String[] strings) {
|
public void setEnabledProtocols(String[] protocols) {
|
||||||
throw new UnsupportedOperationException();
|
if (protocols == null) {
|
||||||
|
// This is correct from the API docs
|
||||||
|
throw new IllegalArgumentException();
|
||||||
|
}
|
||||||
|
boolean sslv2 = false;
|
||||||
|
boolean sslv3 = false;
|
||||||
|
boolean tlsv1 = false;
|
||||||
|
boolean tlsv1_1 = false;
|
||||||
|
boolean tlsv1_2 = false;
|
||||||
|
for (String p: protocols) {
|
||||||
|
if (!SUPPORTED_PROTOCOLS_SET.contains(p)) {
|
||||||
|
throw new IllegalArgumentException("Protocol " + p + " is not supported.");
|
||||||
|
}
|
||||||
|
if (p.equals(PROTOCOL_SSL_V2)) {
|
||||||
|
sslv2 = true;
|
||||||
|
} else if (p.equals(PROTOCOL_SSL_V3)) {
|
||||||
|
sslv3 = true;
|
||||||
|
} else if (p.equals(PROTOCOL_TLS_V1)) {
|
||||||
|
tlsv1 = true;
|
||||||
|
} else if (p.equals(PROTOCOL_TLS_V1_1)) {
|
||||||
|
tlsv1_1 = true;
|
||||||
|
} else if (p.equals(PROTOCOL_TLS_V1_2)) {
|
||||||
|
tlsv1_2 = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Enable all and then disable what we not want
|
||||||
|
SSL.setOptions(ssl, SSL.SSL_OP_ALL);
|
||||||
|
|
||||||
|
if (!sslv2) {
|
||||||
|
SSL.setOptions(ssl, SSL.SSL_OP_NO_SSLv2);
|
||||||
|
}
|
||||||
|
if (!sslv3) {
|
||||||
|
SSL.setOptions(ssl, SSL.SSL_OP_NO_SSLv3);
|
||||||
|
}
|
||||||
|
if (!tlsv1) {
|
||||||
|
SSL.setOptions(ssl, SSL.SSL_OP_NO_TLSv1);
|
||||||
|
}
|
||||||
|
if (!tlsv1_1) {
|
||||||
|
SSL.setOptions(ssl, SSL.SSL_OP_NO_TLSv1_1);
|
||||||
|
}
|
||||||
|
if (!tlsv1_2) {
|
||||||
|
SSL.setOptions(ssl, SSL.SSL_OP_NO_TLSv1_2);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private Certificate[] initPeerCertChain() throws SSLPeerUnverifiedException {
|
private Certificate[] initPeerCertChain() throws SSLPeerUnverifiedException {
|
||||||
|
Loading…
Reference in New Issue
Block a user