diff --git a/changelog.d/4192.misc b/changelog.d/4192.misc new file mode 100644 index 0000000000..3587e3cb7c --- /dev/null +++ b/changelog.d/4192.misc @@ -0,0 +1 @@ +Limit supported TLS versions and cipher suites \ No newline at end of file diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt index 3359e253f6..306ed45500 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/MatrixConfiguration.kt @@ -16,6 +16,7 @@ package org.matrix.android.sdk.api +import okhttp3.ConnectionSpec import org.matrix.android.sdk.api.crypto.MXCryptoConfig import java.net.Proxy @@ -44,6 +45,10 @@ data class MatrixConfiguration( * You can create one using for instance Proxy(proxyType, InetSocketAddress.createUnresolved(hostname, port). */ val proxy: Proxy? = null, + /** + * TLS versions and cipher suites limitation for unauthenticated requests + */ + val connectionSpec: ConnectionSpec = ConnectionSpec.RESTRICTED_TLS, /** * True to advertise support for call transfers to other parties on Matrix calls. */ diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt index 215f0a0351..e87824d6a5 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/HomeServerConnectionConfig.kt @@ -19,6 +19,7 @@ package org.matrix.android.sdk.api.auth.data import android.net.Uri import com.squareup.moshi.JsonClass import okhttp3.CipherSuite +import okhttp3.ConnectionSpec import okhttp3.TlsVersion import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig.Builder import org.matrix.android.sdk.internal.network.ssl.Fingerprint @@ -191,32 +192,25 @@ data class HomeServerConnectionConfig( /** * Convenient method to limit the TLS versions and cipher suites for this Builder * Ref: - * - https://www.ssi.gouv.fr/uploads/2017/02/security-recommendations-for-tls_v1.1.pdf + * - https://www.ssi.gouv.fr/uploads/2017/07/anssi-guide-recommandations_de_securite_relatives_a_tls-v1.2.pdf * - https://developer.android.com/reference/javax/net/ssl/SSLEngine * * @param tlsLimitations true to use Tls limitations * @param enableCompatibilityMode set to true for Android < 20 * @return this builder */ + @Deprecated("TLS versions and cipher suites are limited by default") fun withTlsLimitations(tlsLimitations: Boolean, enableCompatibilityMode: Boolean): Builder { if (tlsLimitations) { withShouldAcceptTlsExtensions(false) - // Tls versions - addAcceptedTlsVersion(TlsVersion.TLS_1_2) - addAcceptedTlsVersion(TlsVersion.TLS_1_3) + // TlS versions + ConnectionSpec.RESTRICTED_TLS.tlsVersions?.let { this.tlsVersions.addAll(it) } forceUsageOfTlsVersions(enableCompatibilityMode) // Cipher suites - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256) - addAcceptedTlsCipherSuite(CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256) + ConnectionSpec.RESTRICTED_TLS.cipherSuites?.let { this.tlsCipherSuites.addAll(it) } if (enableCompatibilityMode) { // Adopt some preceding cipher suites for Android < 20 to be able to negotiate diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt index fa59b94c17..ad34a4d8a6 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/di/NetworkModule.kt @@ -20,6 +20,7 @@ import com.facebook.stetho.okhttp3.StethoInterceptor import com.squareup.moshi.Moshi import dagger.Module import dagger.Provides +import okhttp3.ConnectionSpec import okhttp3.OkHttpClient import okhttp3.logging.HttpLoggingInterceptor import org.matrix.android.sdk.BuildConfig @@ -29,6 +30,7 @@ import org.matrix.android.sdk.internal.network.TimeOutInterceptor import org.matrix.android.sdk.internal.network.UserAgentInterceptor import org.matrix.android.sdk.internal.network.interceptors.CurlLoggingInterceptor import org.matrix.android.sdk.internal.network.interceptors.FormattedJsonHttpLogger +import java.util.Collections import java.util.concurrent.TimeUnit @Module @@ -66,6 +68,8 @@ internal object NetworkModule { httpLoggingInterceptor: HttpLoggingInterceptor, curlLoggingInterceptor: CurlLoggingInterceptor, apiInterceptor: ApiInterceptor): OkHttpClient { + val spec = ConnectionSpec.Builder(matrixConfiguration.connectionSpec).build() + return OkHttpClient.Builder() .connectTimeout(30, TimeUnit.SECONDS) .readTimeout(60, TimeUnit.SECONDS) @@ -87,6 +91,7 @@ internal object NetworkModule { proxy(it) } } + .connectionSpecs(Collections.singletonList(spec)) .build() } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt index 92c7f3f236..d8bdc5fc2b 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/network/ssl/CertUtil.kt @@ -177,15 +177,13 @@ internal object CertUtil { val trustPinned = arrayOf(PinnedTrustManagerProvider.provide(hsConfig.allowedFingerprints, defaultTrustManager)) - val sslSocketFactory: SSLSocketFactory - - if (hsConfig.forceUsageTlsVersions && hsConfig.tlsVersions != null) { + val sslSocketFactory = if (hsConfig.forceUsageTlsVersions && !hsConfig.tlsVersions.isNullOrEmpty()) { // Force usage of accepted Tls Versions for Android < 20 - sslSocketFactory = TLSSocketFactory(trustPinned, hsConfig.tlsVersions) + TLSSocketFactory(trustPinned, hsConfig.tlsVersions) } else { val sslContext = SSLContext.getInstance("TLS") sslContext.init(null, trustPinned, java.security.SecureRandom()) - sslSocketFactory = sslContext.socketFactory + sslContext.socketFactory } return PinnedSSLSocketFactory(sslSocketFactory, defaultTrustManager!!) @@ -237,14 +235,14 @@ internal object CertUtil { * @return a list of accepted TLS specifications. */ fun newConnectionSpecs(hsConfig: HomeServerConnectionConfig): List { - val builder = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) + val builder = ConnectionSpec.Builder(ConnectionSpec.RESTRICTED_TLS) val tlsVersions = hsConfig.tlsVersions - if (null != tlsVersions && tlsVersions.isNotEmpty()) { + if (!tlsVersions.isNullOrEmpty()) { builder.tlsVersions(*tlsVersions.toTypedArray()) } val tlsCipherSuites = hsConfig.tlsCipherSuites - if (null != tlsCipherSuites && tlsCipherSuites.isNotEmpty()) { + if (!tlsCipherSuites.isNullOrEmpty()) { builder.cipherSuites(*tlsCipherSuites.toTypedArray()) }