-
-
Save arifNislam/3b3c6e8d2b3e5bee73ad53f267a78fdc to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Implementation of [SSLSocketFactory] that adds [TlsVersion.TLS_1_2] as an enabled protocol for every [SSLSocket] | |
* created by [delegate]. | |
* | |
* [See this discussion for more details.](https://github.com/square/okhttp/issues/2372#issuecomment-244807676) | |
* | |
* @see SSLSocket | |
* @see SSLSocketFactory | |
*/ | |
class Tls12SocketFactory(private val delegate: SSLSocketFactory) : SSLSocketFactory() { | |
companion object { | |
/** | |
* @return [X509TrustManager] from [TrustManagerFactory] | |
* | |
* @throws [NoSuchElementException] if not found. According to the Android docs for [TrustManagerFactory], this | |
* should never happen because PKIX is the only supported algorithm | |
*/ | |
private val trustManager by lazy { | |
val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) | |
trustManagerFactory.init(null as KeyStore?) | |
trustManagerFactory.trustManagers | |
.first { it is X509TrustManager } as X509TrustManager | |
} | |
/** | |
* If on [Build.VERSION_CODES.LOLLIPOP] or lower, sets [OkHttpClient.Builder.sslSocketFactory] to an instance of | |
* [Tls12SocketFactory] that wraps the default [SSLContext.getSocketFactory] for [TlsVersion.TLS_1_2]. | |
* | |
* Does nothing when called on [Build.VERSION_CODES.LOLLIPOP_MR1] or higher. | |
* | |
* For some reason, Android supports TLS v1.2 from [Build.VERSION_CODES.JELLY_BEAN], but the spec only has it | |
* enabled by default from API [Build.VERSION_CODES.KITKAT]. Furthermore, some devices on | |
* [Build.VERSION_CODES.LOLLIPOP] don't have it enabled, despite the spec saying they should. | |
* | |
* @return the (potentially modified) [OkHttpClient.Builder] | |
*/ | |
@JvmStatic | |
fun OkHttpClient.Builder.enableTls12() = apply { | |
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.LOLLIPOP_MR1) { | |
try { | |
val sslContext = SSLContext.getInstance(TlsVersion.TLS_1_2.javaName()) | |
sslContext.init(null, arrayOf(trustManager), null) | |
sslSocketFactory(Tls12SocketFactory(sslContext.socketFactory), trustManager) | |
} catch (e: Exception) { | |
Timber.e(e, "Error while setting TLS 1.2 compatibility") | |
} | |
} | |
} | |
} | |
/** | |
* Forcefully adds [TlsVersion.TLS_1_2] as an enabled protocol if called on an [SSLSocket] | |
* | |
* @return the (potentially modified) [Socket] | |
*/ | |
private fun Socket.patchForTls12(): Socket { | |
return (this as? SSLSocket)?.apply { | |
enabledProtocols += TlsVersion.TLS_1_2.javaName() | |
} ?: this | |
} | |
override fun getDefaultCipherSuites(): Array<String> { | |
return delegate.defaultCipherSuites | |
} | |
override fun getSupportedCipherSuites(): Array<String> { | |
return delegate.supportedCipherSuites | |
} | |
@Throws(IOException::class) | |
override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket? { | |
return delegate.createSocket(s, host, port, autoClose) | |
.patchForTls12() | |
} | |
@Throws(IOException::class, UnknownHostException::class) | |
override fun createSocket(host: String, port: Int): Socket? { | |
return delegate.createSocket(host, port) | |
.patchForTls12() | |
} | |
@Throws(IOException::class, UnknownHostException::class) | |
override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket? { | |
return delegate.createSocket(host, port, localHost, localPort) | |
.patchForTls12() | |
} | |
@Throws(IOException::class) | |
override fun createSocket(host: InetAddress, port: Int): Socket? { | |
return delegate.createSocket(host, port) | |
.patchForTls12() | |
} | |
@Throws(IOException::class) | |
override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket? { | |
return delegate.createSocket(address, port, localAddress, localPort) | |
.patchForTls12() | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment