Skip to content

Commit

Permalink
OpenSSL cipher mapping in trunk now works (i.e. tests pass) with 1.0.2.
Browse files Browse the repository at this point in the history
Need to test with 1.1.0 - I suspect some 'tweaks' will be required.

git-svn-id: https://svn.apache.org/repos/asf/tomcat/trunk@1695159 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
markt-asf committed Aug 10, 2015
1 parent 07aeed4 commit 8774e9a
Show file tree
Hide file tree
Showing 5 changed files with 186 additions and 81 deletions.
2 changes: 1 addition & 1 deletion java/org/apache/tomcat/util/net/jsse/openssl/Cipher.java
Expand Up @@ -4021,7 +4021,7 @@ public enum Cipher {
// RC2_128_CBC_WITH_MD5
SSL_CK_RC2_128_CBC_WITH_MD5(
-1,
"RC2-MD5",
"RC2-CBC-MD5",
KeyExchange.RSA,
Authentication.RSA,
Encryption.RC2,
Expand Down
Expand Up @@ -485,12 +485,13 @@ private static final void init() {
addListAlias(SRP, filterByKeyExchange(allCiphers, Collections.singleton(KeyExchange.SRP)));
initialized = true;
// Despite what the OpenSSL docs say, DEFAULT also excludes SSLv2
addListAlias(DEFAULT, parse("ALL:!eNULL:!aNULL:!SSLv2"));
addListAlias(DEFAULT, parse("ALL:!EXPORT:!eNULL:!aNULL:!SSLv2"));
// COMPLEMENTOFDEFAULT is also not exactly as defined by the docs
Set<Cipher> complementOfDefault = filterByKeyExchange(all, new HashSet<>(Arrays.asList(KeyExchange.EDH,KeyExchange.EECDH)));
complementOfDefault = filterByAuthentication(complementOfDefault, Collections.singleton(Authentication.aNULL));
complementOfDefault.removeAll(aliases.get(eNULL));
complementOfDefault.addAll(aliases.get(Constants.SSL_PROTO_SSLv2));
complementOfDefault.addAll(aliases.get(EXPORT));
addListAlias(COMPLEMENTOFDEFAULT, complementOfDefault);
}

Expand Down
44 changes: 2 additions & 42 deletions test/org/apache/tomcat/util/net/jsse/openssl/TestCipher.java
Expand Up @@ -23,17 +23,10 @@
import java.util.Set;

import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Test;

public class TestCipher {

@Before
public void checkVersion() {
Assume.assumeTrue(TesterOpenSSL.IS_EXPECTED_VERSION);
}

/*
* Checks that every cipher suite returned by OpenSSL is mapped to at least
* one cipher suite that is recognised by JSSE or is a cipher suite known
Expand Down Expand Up @@ -83,43 +76,10 @@ public void testOpenSSLCipherAvailability() throws Exception {
Set<String> availableCipherSuites = TesterOpenSSL.getOpenSSLCiphersAsSet("ALL:eNULL");
Set<String> expectedCipherSuites = new HashSet<>();
for (Cipher cipher : Cipher.values()) {
String openSSLAlias = cipher.getOpenSSLAlias();
// OpenSSL does not implement any FORTEZZA algorithms so exclude
// them from the expected list
if (openSSLAlias.contains("FZA")) {
continue;
}
// GOST algorithms are not enabled by default and no JSSE
// implementation supports them so exclude them from the expected
// list
if (openSSLAlias.contains("GOST")) {
continue;
}
// OpenSSL does not enable the experimental EXP1024 and
// DHE-DSS-RC4-SHA cipher suites unless the source is explicitly
// patched so exclude them from the expected list
if (openSSLAlias.contains("EXP1024")) {
continue;
}
if (openSSLAlias.contains("DHE-DSS-RC4-SHA")) {
continue;
}
// OpenSSL removed (broken) support for EXP-DH-RSA-DES-CBC-SHA
// and EXP-DH-DSS-DES-CBC-SHA on 2015-05-23.
if (openSSLAlias.contains("EXP-DH-")) {
continue;
}
// RC2-MD5 is not referenced in the OpenSSL source so exclude it
// from the expected list
if (openSSLAlias.contains("RC2-MD5")) {
continue;
}
// As of OpenSSL 1.1.0, SSLv2 ciphers are not supported so exclude
// them from the expected list
if (cipher.getProtocol().equals(Protocol.SSLv2)) {
if (TesterOpenSSL.OPENSSL_UNIMPLEMENTED_CIPHERS.contains(cipher)) {
continue;
}
expectedCipherSuites.add(openSSLAlias + "+" +
expectedCipherSuites.add(cipher.getOpenSSLAlias() + "+" +
cipher.getProtocol().getOpenSSLName());
}

Expand Down
Expand Up @@ -19,19 +19,11 @@
import java.util.List;

import org.junit.Assert;
import org.junit.Assume;
import org.junit.Before;
import org.junit.Ignore;
import org.junit.Test;

public class TestOpenSSLCipherConfigurationParser {

@Before
public void checkVersion() {
Assume.assumeTrue(TesterOpenSSL.IS_EXPECTED_VERSION);
}


@Test
public void testDEFAULT() throws Exception {
testSpecification("DEFAULT");
Expand Down
210 changes: 181 additions & 29 deletions test/org/apache/tomcat/util/net/jsse/openssl/TesterOpenSSL.java
Expand Up @@ -19,7 +19,6 @@
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
import java.util.List;
Expand All @@ -30,45 +29,196 @@

public class TesterOpenSSL {

public static final boolean IS_EXPECTED_VERSION;

public static final Set<Cipher> OPENSSL_UNIMPLEMENTED_CIPHERS =
Collections.unmodifiableSet(new HashSet<>(Arrays.asList(
// The following ciphers are not implemented in an OpenSSL
// version
Cipher.SSL2_DES_64_CBC_WITH_MD5,
Cipher.SSL_CK_RC2_128_CBC_WITH_MD5,
// The following are not implemented in 1.1.x onwards. They
// are implemented in 1.0.x and earlier
Cipher.SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5,
Cipher.SSL_CK_RC4_128_WITH_MD5,
Cipher.SSL2_DES_64_CBC_WITH_MD5,
Cipher.SSL2_DES_192_EDE3_CBC_WITH_MD5,
Cipher.SSL2_IDEA_128_CBC_WITH_MD5,
Cipher.SSL2_RC4_128_EXPORT40_WITH_MD5,
Cipher.TLS_RSA_EXPORT1024_WITH_RC4_56_MD5,
Cipher.TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5,
Cipher.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA,
Cipher.TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA,
Cipher.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,
Cipher.TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA,
Cipher.TLS_DHE_DSS_WITH_RC4_128_SHA,
// The following have been removed from OpenSSL on 2015-05-23
Cipher.TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA,
Cipher.TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA)));
public static final int VERSION;

public static final Set<Cipher> OPENSSL_UNIMPLEMENTED_CIPHERS;

static {
// Note: The tests are configured for the OpenSSL 1.1.0 development
// branch. Running with a different version is likely to trigger
// failures.
String expected_version = System.getProperty("tomcat.test.openssl.version", "");
String versionString = null;
try {
versionString = executeOpenSSLCommand("version");
} catch (IOException e) {
versionString = "";
}
IS_EXPECTED_VERSION = versionString.startsWith("OpenSSL " + expected_version);
if (versionString.startsWith("OpenSSL 1.1.0")) {
VERSION = 10100;
} else if (versionString.startsWith("OpenSSL 1.0.2")) {
VERSION = 10002;
} else if (versionString.startsWith("OpenSSL 1.0.1")) {
VERSION = 10001;
} else if (versionString.startsWith("OpenSSL 1.0.0")) {
VERSION = 10000;
} else if (versionString.startsWith("OpenSSL 0.9.8")) {
VERSION = 908;
} else {
// Unknown OpenSSL version
throw new IllegalStateException("Unknown OpenSSL version " + versionString);
}

HashSet<Cipher> unimplemented = new HashSet<>();

// Note: The following lists are intended to be aligned with the most
// recent release of each OpenSSL release branch

// TODO Validate this for all OpenSSL versions
// 0.9.8 - TODO
// 1.0.0 - TODO
// 1.0.1 - TODO
// 1.0.2 - Done
// 1.1.0 - TODO

// These were removed in 0.9.8 (or earlier) so won't be available in any
// supported version.
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_RC4_128_SHA);
unimplemented.add(Cipher.TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5);
unimplemented.add(Cipher.TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_RC4_56_MD5);

if (VERSION < 10000) {
// These were implemented in 1.0.0 so won't be available in any
// earlier version
} else {
// These were removed in 1.0.0 so won't be available from that
// version onwards.
}


if (VERSION < 10001) {
// These were added in 1.0.1 so won't be available in any earlier
// version
unimplemented.add(Cipher.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_PSK_WITH_AES_128_GCM_SHA256);
unimplemented.add(Cipher.TLS_PSK_WITH_AES_256_GCM_SHA384);
} else {
// These were removed in 1.0.1 so won't be available from that
// version onwards.
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_RC4_56_MD5);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_RC2_CBC_56_MD5);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_DES_CBC_SHA);
unimplemented.add(Cipher.TLS_DHE_DSS_EXPORT1024_WITH_DES_CBC_SHA);
unimplemented.add(Cipher.TLS_RSA_EXPORT1024_WITH_RC4_56_SHA);
unimplemented.add(Cipher.TLS_DHE_DSS_EXPORT1024_WITH_RC4_56_SHA);
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_RC4_128_SHA);
}

if (VERSION < 10002) {
// These were implemented in 1.0.2 so won't be available in any
// earlier version
} else {
// These were removed in 1.0.2 so won't be available from that
// version onwards.
unimplemented.add(Cipher.TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA);
unimplemented.add(Cipher.TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA);
}

if (VERSION < 10100) {
// These were implemented in 1.1.0 so won't be available in any
// earlier version
unimplemented.add(Cipher.TLS_PSK_WITH_NULL_SHA);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_NULL_SHA);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_NULL_SHA);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_AES_128_GCM_SHA256);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_AES_256_GCM_SHA384);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_AES_128_GCM_SHA256);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_AES_256_GCM_SHA384);
unimplemented.add(Cipher.TLS_PSK_WITH_AES_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_PSK_WITH_AES_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_PSK_WITH_NULL_SHA256);
unimplemented.add(Cipher.TLS_PSK_WITH_NULL_SHA384);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_AES_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_AES_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_NULL_SHA256);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_NULL_SHA384);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_AES_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_AES_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_NULL_SHA256);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_NULL_SHA384);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_RC4_128_SHA);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_AES_128_CBC_SHA);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_AES_256_CBC_SHA);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_RC4_128_SHA);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_AES_128_CBC_SHA);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_AES_256_CBC_SHA);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_RC4_128_SHA);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_NULL_SHA);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_NULL_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_NULL_SHA384);
unimplemented.add(Cipher.TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384);
unimplemented.add(Cipher.TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256);
unimplemented.add(Cipher.TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256);
unimplemented.add(Cipher.TLS_PSK_WITH_AES_128_GCM_SHA256);
unimplemented.add(Cipher.TLS_PSK_WITH_AES_256_GCM_SHA384);
unimplemented.add(Cipher.TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256);
} else {
// These were removed in 1.1.0 so won't be available from that
// version onwards.
unimplemented.add(Cipher.SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5);
unimplemented.add(Cipher.SSL_CK_RC4_128_WITH_MD5);
unimplemented.add(Cipher.SSL2_DES_192_EDE3_CBC_WITH_MD5);
unimplemented.add(Cipher.SSL2_DES_64_CBC_WITH_MD5);
unimplemented.add(Cipher.SSL2_IDEA_128_CBC_WITH_MD5);
unimplemented.add(Cipher.SSL2_RC4_128_EXPORT40_WITH_MD5);
unimplemented.add(Cipher.SSL_CK_RC2_128_CBC_WITH_MD5);
}
OPENSSL_UNIMPLEMENTED_CIPHERS = Collections.unmodifiableSet(unimplemented);
}


Expand Down Expand Up @@ -106,6 +256,8 @@ public static String getOpenSSLCiphersAsExpression(String specification) throws
// OpenSSL should have returned one cipher per line
String ciphers[] = stdout.split("\n");
for (String cipher : ciphers) {
// Handle rename for 1.1.0 onwards
cipher = cipher.replaceAll("EDH", "DHE");
if (first) {
first = false;
} else {
Expand Down

0 comments on commit 8774e9a

Please sign in to comment.