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;
|
||||
}
|
||||
|
||||
switch(config.protocol()) {
|
||||
switch (config.protocol()) {
|
||||
case NONE:
|
||||
return OpenSslDefaultApplicationProtocolNegotiator.INSTANCE;
|
||||
case NPN:
|
||||
if (isServer) {
|
||||
switch(config.selectedListenerFailureBehavior()) {
|
||||
switch (config.selectedListenerFailureBehavior()) {
|
||||
case CHOOSE_MY_LAST_PROTOCOL:
|
||||
return new OpenSslNpnApplicationProtocolNegotiator(config.supportedProtocols());
|
||||
default:
|
||||
|
@ -38,8 +38,13 @@ import java.nio.ByteBuffer;
|
||||
import java.nio.ReadOnlyBufferException;
|
||||
import java.security.Principal;
|
||||
import java.security.cert.Certificate;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicIntegerFieldUpdater;
|
||||
import java.util.concurrent.atomic.AtomicReferenceFieldUpdater;
|
||||
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_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)
|
||||
static final int MAX_ENCRYPTED_PACKET_LENGTH = MAX_CIPHERTEXT_LENGTH + 5 + 20 + 256;
|
||||
|
||||
@ -644,17 +667,83 @@ public final class OpenSslEngine extends SSLEngine {
|
||||
|
||||
@Override
|
||||
public String[] getSupportedProtocols() {
|
||||
return EmptyArrays.EMPTY_STRINGS;
|
||||
return SUPPORTED_PROTOCOLS.clone();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnabledProtocols() {
|
||||
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
|
||||
public void setEnabledProtocols(String[] strings) {
|
||||
throw new UnsupportedOperationException();
|
||||
public void setEnabledProtocols(String[] protocols) {
|
||||
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 {
|
||||
|
Loading…
Reference in New Issue
Block a user