disable all really weak cipher suites

Boris Wachtmeister created

With #959 all ciphers of the platform were enabled, but this also
includes several suites that are considered as very weak, even down to
NULL- and anon-ciphers which disable completely disable encryption
and/or authentication. Especially the anon-ciphers could be easily used
for a mitm-attack.

To remove all weak ciphers a blacklist with patterns of cipher-names was
added to Config.java. The blacklist is based on the "mandatory discards"
that Mozilla suggests to not use for TLS-servers because they are weak
or known to be broken.
https://wiki.mozilla.org/Security/Server_Side_TLS#Mandatory_discards

Change summary

src/main/java/eu/siacs/conversations/Config.java             |  9 +++
src/main/java/eu/siacs/conversations/utils/CryptoHelper.java | 16 ++++++
2 files changed, 25 insertions(+)

Detailed changes

src/main/java/eu/siacs/conversations/Config.java 🔗

@@ -64,6 +64,15 @@ public final class Config {
 		"TLS_RSA_WITH_AES_256_CBC_SHA",
 	};
 
+	public static final String WEAK_CIPHER_PATTERNS[] = {
+		"_NULL_",
+		"_EXPORT_",
+		"_anon_",
+		"_RC4_",
+		"_DES_",
+		"_MD5",
+	};
+
 	private Config() {
 
 	}

src/main/java/eu/siacs/conversations/utils/CryptoHelper.java 🔗

@@ -4,6 +4,7 @@ import java.security.SecureRandom;
 import java.text.Normalizer;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.List;
 
@@ -103,6 +104,21 @@ public final class CryptoHelper {
 		final List<String> platformCiphers = Arrays.asList(platformSupportedCipherSuites);
 		cipherSuites.retainAll(platformCiphers);
 		cipherSuites.addAll(platformCiphers);
+		filterWeakCipherSuites(cipherSuites);
 		return cipherSuites.toArray(new String[cipherSuites.size()]);
 	}
+
+	private static void filterWeakCipherSuites(final Collection<String> cipherSuites) {
+		final Iterator<String> it = cipherSuites.iterator();
+		while (it.hasNext()) {
+			String cipherName = it.next();
+			// remove all ciphers with no or very weak encryption or no authentication
+			for (String weakCipherPattern : Config.WEAK_CIPHER_PATTERNS) {
+				if (cipherName.contains(weakCipherPattern)) {
+					it.remove();
+					break;
+				}
+			}
+		}
+	}
 }