Created
August 3, 2018 19:19
-
-
Save ankushg/8c0c3144318b1c17abb228d6211ba996 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() | |
} | |
} |
to add it to your chain you need something like OkHttpClient httpClient = enableTls12(new OkHttpClient.Builder()) .addInterceptor(new SignatureInterceptor()) .connectionSpecs(Arrays.asList(requireTls12)) .build();
handy code from OP but i don't know why he didn't tell us that line! it wasn't obvious to me
@georgiecasey, thanks! It looks like
val okHttpClient = OkHttpClient().newBuilder()
.enableTls12()
...
.build()
Where did you get SignatureInterceptor
? Also requireTls12
is unresolved. As I understood, those classed in Glide
and OkHttp
are deprecated.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Unable to add it to my okhttp chain. Just ain't recognizing this method.