diff --git a/AndroidManifest.xml b/AndroidManifest.xml index 29bc0fbc4..ec106a1b4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,8 +1,8 @@ + android:versionCode="43" + android:versionName="0.6.5" android:installLocation="internalOnly"> = Build.VERSION_CODES.JELLY_BEAN_MR1) { Log.d(TAG, "Using documented SNI with host name " + host); @@ -120,4 +124,57 @@ public class TlsSniSocketFactory implements LayeredConnectionSocketFactory { " using " + session.getCipherSuite()); } + + @SuppressLint("DefaultLocale") + private void setReasonableEncryption(SSLSocket ssl) { + // set reasonable SSL/TLS settings before the handshake: + + // - enable all supported protocols (enables TLSv1.1 and TLSv1.2 on Android <4.4.3, if available) + // - remove all SSL versions (especially SSLv3) because they're insecure now + List protocols = new LinkedList(); + for (String protocol : ssl.getSupportedProtocols()) + if (!protocol.toUpperCase().contains("SSL")) + protocols.add(protocol); + Log.d(TAG, "Setting allowed TLS protocols: " + StringUtils.join(protocols, ", ")); + ssl.setEnabledProtocols(protocols.toArray(new String[0])); + + // choose secure cipher suites + List allowedCiphers = Arrays.asList(new String[] { + // allowed secure ciphers according to NIST.SP.800-52r1.pdf Section 3.3.1 (see docs directory) + // TLS 1.2 + "TLS_RSA_WITH_AES_256_GCM_SHA384", + "TLS_RSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", + "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", + "TLS_ECHDE_RSA_WITH_AES_128_GCM_SHA256", + // maximum interoperability + "TLS_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_RSA_WITH_AES_128_CBC_SHA", + // additionally + "TLS_RSA_WITH_AES_256_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", + "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", + "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", + }); + + List availableCiphers = Arrays.asList(ssl.getSupportedCipherSuites()); + + // preferred ciphers = allowed Ciphers \ availableCiphers + HashSet preferredCiphers = new HashSet(allowedCiphers); + preferredCiphers.retainAll(availableCiphers); + + // add preferred ciphers to enabled ciphers + // for maximum security, preferred ciphers should *replace* enabled ciphers, + // but I guess for the security level of DAVdroid, disabling of insecure + // ciphers should be a server-side task + HashSet enabledCiphers = new HashSet(Arrays.asList(ssl.getEnabledCipherSuites())); + enabledCiphers.addAll(preferredCiphers); + + Log.d(TAG, "Setting allowed TLS ciphers: " + StringUtils.join(enabledCiphers, ", ")); + ssl.setEnabledCipherSuites(enabledCiphers.toArray(new String[0])); + } + }