OpenSslEngine.getSupportedCipherSuites() must return java names as well.
Motivation: At the moment OpenSslEngine.getSupportedCipherSuites() only return the original openssl cipher names and not the java names. We need also include the java names. Modifications: Correctly return the java names as well. Result: Correct implementation of OpenSslEngine.getSupportedCipherSuites()
This commit is contained in:
parent
278c36af0c
commit
7c1374dd54
@ -27,7 +27,9 @@ import org.apache.tomcat.jni.Pool;
|
||||
import org.apache.tomcat.jni.SSL;
|
||||
import org.apache.tomcat.jni.SSLContext;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.Locale;
|
||||
import java.util.Set;
|
||||
@ -43,7 +45,28 @@ public final class OpenSsl {
|
||||
private static final String UNKNOWN = "unknown";
|
||||
private static final Throwable UNAVAILABILITY_CAUSE;
|
||||
|
||||
private static final Set<String> AVAILABLE_CIPHER_SUITES;
|
||||
static final Set<String> AVAILABLE_CIPHER_SUITES;
|
||||
private static final Set<String> AVAILABLE_OPENSSL_CIPHER_SUITES;
|
||||
private static final Set<String> AVAILABLE_JAVA_CIPHER_SUITES;
|
||||
|
||||
// Protocols
|
||||
static final String PROTOCOL_SSL_V2_HELLO = "SSLv2Hello";
|
||||
static final String PROTOCOL_SSL_V2 = "SSLv2";
|
||||
static final String PROTOCOL_SSL_V3 = "SSLv3";
|
||||
static final String PROTOCOL_TLS_V1 = "TLSv1";
|
||||
static final String PROTOCOL_TLS_V1_1 = "TLSv1.1";
|
||||
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
|
||||
};
|
||||
static final Set<String> SUPPORTED_PROTOCOLS_SET = Collections.unmodifiableSet(
|
||||
new HashSet<String>(Arrays.asList(SUPPORTED_PROTOCOLS)));
|
||||
|
||||
static {
|
||||
Throwable cause = null;
|
||||
@ -93,7 +116,7 @@ public final class OpenSsl {
|
||||
UNAVAILABILITY_CAUSE = cause;
|
||||
|
||||
if (cause == null) {
|
||||
final Set<String> availableCipherSuites = new LinkedHashSet<String>(128);
|
||||
final Set<String> availableOpenSslCipherSuites = new LinkedHashSet<String>(128);
|
||||
final long aprPool = Pool.create(0);
|
||||
try {
|
||||
final long sslCtx = SSLContext.make(aprPool, SSL.SSL_PROTOCOL_ALL, SSL.SSL_MODE_SERVER);
|
||||
@ -104,10 +127,10 @@ public final class OpenSsl {
|
||||
try {
|
||||
for (String c: SSL.getCiphers(ssl)) {
|
||||
// Filter out bad input.
|
||||
if (c == null || c.length() == 0 || availableCipherSuites.contains(c)) {
|
||||
if (c == null || c.length() == 0 || availableOpenSslCipherSuites.contains(c)) {
|
||||
continue;
|
||||
}
|
||||
availableCipherSuites.add(c);
|
||||
availableOpenSslCipherSuites.add(c);
|
||||
}
|
||||
} finally {
|
||||
SSL.freeSSL(ssl);
|
||||
@ -120,9 +143,29 @@ public final class OpenSsl {
|
||||
} finally {
|
||||
Pool.destroy(aprPool);
|
||||
}
|
||||
AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.unmodifiableSet(availableOpenSslCipherSuites);
|
||||
|
||||
AVAILABLE_CIPHER_SUITES = Collections.unmodifiableSet(availableCipherSuites);
|
||||
final Set<String> availableJavaCipherSuites = new LinkedHashSet<String>(
|
||||
AVAILABLE_OPENSSL_CIPHER_SUITES.size() * 2);
|
||||
for (String cipher: AVAILABLE_OPENSSL_CIPHER_SUITES) {
|
||||
// Included converted but also openssl cipher name
|
||||
availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "TLS"));
|
||||
availableJavaCipherSuites.add(CipherSuiteConverter.toJava(cipher, "SSL"));
|
||||
}
|
||||
AVAILABLE_JAVA_CIPHER_SUITES = Collections.unmodifiableSet(availableJavaCipherSuites);
|
||||
|
||||
final Set<String> availableCipherSuites = new LinkedHashSet<String>(
|
||||
AVAILABLE_OPENSSL_CIPHER_SUITES.size() + AVAILABLE_JAVA_CIPHER_SUITES.size());
|
||||
for (String cipher: AVAILABLE_OPENSSL_CIPHER_SUITES) {
|
||||
availableCipherSuites.add(cipher);
|
||||
}
|
||||
for (String cipher: AVAILABLE_JAVA_CIPHER_SUITES) {
|
||||
availableCipherSuites.add(cipher);
|
||||
}
|
||||
AVAILABLE_CIPHER_SUITES = availableCipherSuites;
|
||||
} else {
|
||||
AVAILABLE_OPENSSL_CIPHER_SUITES = Collections.emptySet();
|
||||
AVAILABLE_JAVA_CIPHER_SUITES = Collections.emptySet();
|
||||
AVAILABLE_CIPHER_SUITES = Collections.emptySet();
|
||||
}
|
||||
}
|
||||
@ -189,12 +232,28 @@ public final class OpenSsl {
|
||||
return UNAVAILABILITY_CAUSE;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated use {@link #availableOpenSslCipherSuites()}
|
||||
*/
|
||||
@Deprecated
|
||||
public static Set<String> availableCipherSuites() {
|
||||
return availableOpenSslCipherSuites();
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the available OpenSSL cipher suites.
|
||||
* Please note that the returned array may include the cipher suites that are insecure or non-functional.
|
||||
*/
|
||||
public static Set<String> availableCipherSuites() {
|
||||
return AVAILABLE_CIPHER_SUITES;
|
||||
public static Set<String> availableOpenSslCipherSuites() {
|
||||
return AVAILABLE_OPENSSL_CIPHER_SUITES;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns all the available cipher suites (Java-style).
|
||||
* Please note that the returned array may include the cipher suites that are insecure or non-functional.
|
||||
*/
|
||||
public static Set<String> availableJavaCipherSuites() {
|
||||
return AVAILABLE_JAVA_CIPHER_SUITES;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -206,7 +265,7 @@ public final class OpenSsl {
|
||||
if (converted != null) {
|
||||
cipherSuite = converted;
|
||||
}
|
||||
return AVAILABLE_CIPHER_SUITES.contains(cipherSuite);
|
||||
return AVAILABLE_OPENSSL_CIPHER_SUITES.contains(cipherSuite);
|
||||
}
|
||||
|
||||
static boolean isError(long errorCode) {
|
||||
|
@ -37,10 +37,8 @@ import java.security.cert.Certificate;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
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 javax.net.ssl.SSLEngine;
|
||||
@ -154,24 +152,6 @@ 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;
|
||||
|
||||
@ -1038,8 +1018,7 @@ public final class OpenSslEngine extends SSLEngine {
|
||||
|
||||
@Override
|
||||
public String[] getSupportedCipherSuites() {
|
||||
Set<String> availableCipherSuites = OpenSsl.availableCipherSuites();
|
||||
return availableCipherSuites.toArray(new String[availableCipherSuites.size()]);
|
||||
return OpenSsl.AVAILABLE_CIPHER_SUITES.toArray(new String[OpenSsl.AVAILABLE_CIPHER_SUITES.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -1110,14 +1089,14 @@ public final class OpenSslEngine extends SSLEngine {
|
||||
|
||||
@Override
|
||||
public String[] getSupportedProtocols() {
|
||||
return SUPPORTED_PROTOCOLS.clone();
|
||||
return OpenSsl.SUPPORTED_PROTOCOLS_SET.toArray(new String[OpenSsl.SUPPORTED_PROTOCOLS_SET.size()]);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String[] getEnabledProtocols() {
|
||||
List<String> enabled = InternalThreadLocalMap.get().arrayList();
|
||||
// Seems like there is no way to explict disable SSLv2Hello in openssl so it is always enabled
|
||||
enabled.add(PROTOCOL_SSL_V2_HELLO);
|
||||
enabled.add(OpenSsl.PROTOCOL_SSL_V2_HELLO);
|
||||
|
||||
int opts;
|
||||
synchronized (this) {
|
||||
@ -1128,19 +1107,19 @@ public final class OpenSslEngine extends SSLEngine {
|
||||
}
|
||||
}
|
||||
if ((opts & SSL.SSL_OP_NO_TLSv1) == 0) {
|
||||
enabled.add(PROTOCOL_TLS_V1);
|
||||
enabled.add(OpenSsl.PROTOCOL_TLS_V1);
|
||||
}
|
||||
if ((opts & SSL.SSL_OP_NO_TLSv1_1) == 0) {
|
||||
enabled.add(PROTOCOL_TLS_V1_1);
|
||||
enabled.add(OpenSsl.PROTOCOL_TLS_V1_1);
|
||||
}
|
||||
if ((opts & SSL.SSL_OP_NO_TLSv1_2) == 0) {
|
||||
enabled.add(PROTOCOL_TLS_V1_2);
|
||||
enabled.add(OpenSsl.PROTOCOL_TLS_V1_2);
|
||||
}
|
||||
if ((opts & SSL.SSL_OP_NO_SSLv2) == 0) {
|
||||
enabled.add(PROTOCOL_SSL_V2);
|
||||
enabled.add(OpenSsl.PROTOCOL_SSL_V2);
|
||||
}
|
||||
if ((opts & SSL.SSL_OP_NO_SSLv3) == 0) {
|
||||
enabled.add(PROTOCOL_SSL_V3);
|
||||
enabled.add(OpenSsl.PROTOCOL_SSL_V3);
|
||||
}
|
||||
return enabled.toArray(new String[enabled.size()]);
|
||||
}
|
||||
@ -1157,18 +1136,18 @@ public final class OpenSslEngine extends SSLEngine {
|
||||
boolean tlsv1_1 = false;
|
||||
boolean tlsv1_2 = false;
|
||||
for (String p: protocols) {
|
||||
if (!SUPPORTED_PROTOCOLS_SET.contains(p)) {
|
||||
if (!OpenSsl.SUPPORTED_PROTOCOLS_SET.contains(p)) {
|
||||
throw new IllegalArgumentException("Protocol " + p + " is not supported.");
|
||||
}
|
||||
if (p.equals(PROTOCOL_SSL_V2)) {
|
||||
if (p.equals(OpenSsl.PROTOCOL_SSL_V2)) {
|
||||
sslv2 = true;
|
||||
} else if (p.equals(PROTOCOL_SSL_V3)) {
|
||||
} else if (p.equals(OpenSsl.PROTOCOL_SSL_V3)) {
|
||||
sslv3 = true;
|
||||
} else if (p.equals(PROTOCOL_TLS_V1)) {
|
||||
} else if (p.equals(OpenSsl.PROTOCOL_TLS_V1)) {
|
||||
tlsv1 = true;
|
||||
} else if (p.equals(PROTOCOL_TLS_V1_1)) {
|
||||
} else if (p.equals(OpenSsl.PROTOCOL_TLS_V1_1)) {
|
||||
tlsv1_1 = true;
|
||||
} else if (p.equals(PROTOCOL_TLS_V1_2)) {
|
||||
} else if (p.equals(OpenSsl.PROTOCOL_TLS_V1_2)) {
|
||||
tlsv1_2 = true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user