diff --git a/src/main/java/eu/siacs/conversations/AppSettings.java b/src/main/java/eu/siacs/conversations/AppSettings.java index e6221e238..bbb4e49b6 100644 --- a/src/main/java/eu/siacs/conversations/AppSettings.java +++ b/src/main/java/eu/siacs/conversations/AppSettings.java @@ -49,9 +49,9 @@ public class AppSettings { public static final String SHOW_LINK_PREVIEWS = "show_link_previews"; public static final String SHOW_AVATARS = "show_avatars"; public static final String CALL_INTEGRATION = "call_integration"; - private static final String ACCEPT_INVITES_FROM_STRANGERS = "accept_invites_from_strangers"; private static final String INSTALLATION_ID = "im.conversations.android.install_id"; + public static final String SECURE_TLS = "secure_tls"; private final Context context; @@ -124,6 +124,10 @@ public class AppSettings { return getBooleanPreference(SHOW_AVATARS, R.bool.show_avatars); } + public boolean isSecureTLS() { + return getBooleanPreference(SECURE_TLS, R.bool.secure_tls); + } + public boolean isCallIntegration() { return getBooleanPreference(CALL_INTEGRATION, R.bool.call_integration); } diff --git a/src/main/java/eu/siacs/conversations/Config.java b/src/main/java/eu/siacs/conversations/Config.java index 1fca62354..ba848af36 100644 --- a/src/main/java/eu/siacs/conversations/Config.java +++ b/src/main/java/eu/siacs/conversations/Config.java @@ -163,15 +163,15 @@ public final class Config { //only allow secure tls chipers now public static final String[] ENABLED_CIPHERS = { + //post quantum key agreement with traditional encryption + "TLS_ECDHE_KYBER_WITH_CHACHA20_POLY1305_SHA256", + //pre shared key for resource constrained devices (e.g. Alexa, IoT) + // with post quantum encryption + "TLS_PSK_WITH_AES_128_GCM_SHA256", //TLS 1.3 "TLS_AES_256_GCM_SHA384", "TLS_CHACHA20_POLY1305_SHA256", "TLS_AES_128_GCM_SHA256", - //post quantum key agreement with traditional encryption - "TLS_ECDHE_KYBER_WITH_CHACHA20_POLY1305_SHA256", - //pre shared key for resource constrained devices (e.g. Alexa, IoT) - // with post quantum encryption - "TLS_PSK_WITH_AES_128_GCM_SHA256", //TLS 1.2 with traditional key agreement and encryption "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", @@ -181,6 +181,20 @@ public final class Config { "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", }; + public static final String[] SECURE_CIPHERS = { + //post quantum key agreement with traditional encryption + "TLS_ECDHE_KYBER_WITH_CHACHA20_POLY1305_SHA256", + //pre shared key for resource constrained devices (e.g. Alexa, IoT) + // with post quantum encryption + "TLS_PSK_WITH_AES_128_GCM_SHA256", + //TLS 1.3 + "TLS_AES_256_GCM_SHA384", + "TLS_CHACHA20_POLY1305_SHA256", + "TLS_AES_128_GCM_SHA256", + }; + + + public static final String[] WEAK_CIPHER_PATTERNS = { "_NULL_", "_EXPORT_", diff --git a/src/main/java/eu/siacs/conversations/ui/fragment/settings/SecuritySettingsFragment.java b/src/main/java/eu/siacs/conversations/ui/fragment/settings/SecuritySettingsFragment.java index 3a79e4419..8b504fac3 100644 --- a/src/main/java/eu/siacs/conversations/ui/fragment/settings/SecuritySettingsFragment.java +++ b/src/main/java/eu/siacs/conversations/ui/fragment/settings/SecuritySettingsFragment.java @@ -73,7 +73,7 @@ public class SecuritySettingsFragment extends XmppPreferenceFragment { requireService().updateMemorizingTrustManager(); reconnectAccounts(); } - case AppSettings.DANE_ENFORCED, AppSettings.REQUIRE_CHANNEL_BINDING -> { + case AppSettings.DANE_ENFORCED, AppSettings.REQUIRE_CHANNEL_BINDING, AppSettings.SECURE_TLS -> { reconnectAccounts(); } case AppSettings.AUTOMATIC_MESSAGE_DELETION -> { diff --git a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java index c2ea88f9d..73397e4ab 100644 --- a/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java +++ b/src/main/java/eu/siacs/conversations/utils/CryptoHelper.java @@ -31,12 +31,15 @@ import java.util.LinkedHashSet; import java.util.List; import java.util.regex.Pattern; +import eu.siacs.conversations.AppSettings; +import eu.siacs.conversations.Conversations; import io.ipfs.cid.Cid; import io.ipfs.multihash.Multihash; import eu.siacs.conversations.Config; import eu.siacs.conversations.R; import eu.siacs.conversations.entities.Account; +import eu.siacs.conversations.entities.Conversation; import eu.siacs.conversations.entities.Message; import eu.siacs.conversations.xmpp.Jid; @@ -51,6 +54,7 @@ public final class CryptoHelper { public static final String FILETRANSFER = "?FILETRANSFERv1:"; private final static char[] hexArray = "0123456789abcdef".toCharArray(); + public static String bytesToHex(byte[] bytes) { char[] hexChars = new char[bytes.length * 2]; for (int j = 0; j < bytes.length; j++) { @@ -155,13 +159,24 @@ public final class CryptoHelper { } public static String[] getOrderedCipherSuites(final String[] platformSupportedCipherSuites) { - final Collection cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS)); - final List platformCiphers = Arrays.asList(platformSupportedCipherSuites); - cipherSuites.retainAll(platformCiphers); - cipherSuites.addAll(platformCiphers); - filterWeakCipherSuites(cipherSuites); - cipherSuites.remove("TLS_FALLBACK_SCSV"); - return cipherSuites.toArray(new String[cipherSuites.size()]); + final var appSettings = new AppSettings(Conversations.getContext()); + if (appSettings.isSecureTLS()) { + final Collection secureCipherSuites = new LinkedHashSet<>(Arrays.asList(Config.SECURE_CIPHERS)); + final List platformCiphers = Arrays.asList(platformSupportedCipherSuites); + secureCipherSuites.retainAll(platformCiphers); + secureCipherSuites.addAll(platformCiphers); + filterWeakCipherSuites(secureCipherSuites); + secureCipherSuites.remove("TLS_FALLBACK_SCSV"); + return secureCipherSuites.toArray(new String[secureCipherSuites.size()]); + } else { + final Collection cipherSuites = new LinkedHashSet<>(Arrays.asList(Config.ENABLED_CIPHERS)); + final List platformCiphers = Arrays.asList(platformSupportedCipherSuites); + cipherSuites.retainAll(platformCiphers); + cipherSuites.addAll(platformCiphers); + filterWeakCipherSuites(cipherSuites); + cipherSuites.remove("TLS_FALLBACK_SCSV"); + return cipherSuites.toArray(new String[cipherSuites.size()]); + } } private static void filterWeakCipherSuites(final Collection cipherSuites) { diff --git a/src/main/res/values/bools.xml b/src/main/res/values/bools.xml index 81270f69b..9c4a6e7eb 100644 --- a/src/main/res/values/bools.xml +++ b/src/main/res/values/bools.xml @@ -11,4 +11,5 @@ false false false + false diff --git a/src/main/res/values/strings.xml b/src/main/res/values/strings.xml index 28f611404..23cc77113 100644 --- a/src/main/res/values/strings.xml +++ b/src/main/res/values/strings.xml @@ -1402,4 +1402,6 @@ to Hide media in gallery Hide received and sent media from system gallery views + Use only securest TLS ciphers including post quantum key agreement if available on server + Use secure TLS Ciphers only \ No newline at end of file diff --git a/src/main/res/xml/preferences_security.xml b/src/main/res/xml/preferences_security.xml index 38cda08b4..fe71ed63f 100644 --- a/src/main/res/xml/preferences_security.xml +++ b/src/main/res/xml/preferences_security.xml @@ -31,6 +31,12 @@ android:key="enforce_dane" android:summary="@string/pref_enforce_dane_summary" android:title="@string/pref_enforce_dane" /> +