Conscryptの導入。TLS1.3対応。APKファイルが大きくなる
This commit is contained in:
parent
816e7bbec6
commit
3007f5b02b
|
@ -32,6 +32,7 @@
|
|||
<w>foregrounder</w>
|
||||
<w>gifv</w>
|
||||
<w>github</w>
|
||||
<w>hansshake</w>
|
||||
<w>hashtag</w>
|
||||
<w>hashtags</w>
|
||||
<w>hhmm</w>
|
||||
|
|
|
@ -116,6 +116,7 @@ dependencies {
|
|||
kapt 'com.github.bumptech.glide:compiler:4.7.1'
|
||||
// kotlin では annotationProcessor の代わりに kapt を使う
|
||||
|
||||
implementation "org.conscrypt:conscrypt-android:1.3.0"
|
||||
|
||||
implementation 'uk.co.chrisjenx:calligraphy:2.3.0'
|
||||
|
||||
|
|
|
@ -46,6 +46,7 @@ import org.json.JSONObject
|
|||
import java.io.ByteArrayInputStream
|
||||
import java.io.IOException
|
||||
import java.util.*
|
||||
import javax.net.ssl.HttpsURLConnection
|
||||
|
||||
class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
||||
|
||||
|
@ -330,6 +331,9 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
|||
return
|
||||
}
|
||||
|
||||
// https://github.com/google/ExoPlayer/issues/1819
|
||||
HttpsURLConnection.setDefaultSSLSocketFactory(MySslSocketFactory)
|
||||
|
||||
exoView.visibility = View.VISIBLE
|
||||
|
||||
val defaultBandwidthMeter = DefaultBandwidthMeter()
|
||||
|
|
|
@ -29,8 +29,10 @@ import jp.juggler.subwaytooter.util.CustomEmojiLister
|
|||
import jp.juggler.subwaytooter.util.ProgressResponseBody
|
||||
import jp.juggler.util.*
|
||||
import okhttp3.*
|
||||
import org.conscrypt.Conscrypt
|
||||
import java.io.File
|
||||
import java.io.InputStream
|
||||
import java.security.Security
|
||||
import java.util.*
|
||||
import java.util.concurrent.LinkedBlockingQueue
|
||||
import java.util.concurrent.ThreadFactory
|
||||
|
@ -219,20 +221,20 @@ class App1 : Application() {
|
|||
timeoutSecondsConnect : Int,
|
||||
timeoutSecondsRead : Int
|
||||
) : OkHttpClient.Builder {
|
||||
|
||||
val spec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||
.cipherSuites(*APPROVED_CIPHER_SUITES)
|
||||
.allEnabledCipherSuites()
|
||||
.allEnabledTlsVersions()
|
||||
.supportsTlsExtensions(true)
|
||||
.build()
|
||||
|
||||
val spec_list = ArrayList<ConnectionSpec>()
|
||||
spec_list.add(spec)
|
||||
spec_list.add(ConnectionSpec.CLEARTEXT)
|
||||
|
||||
return OkHttpClient.Builder()
|
||||
.connectTimeout(timeoutSecondsConnect.toLong(), TimeUnit.SECONDS)
|
||||
.readTimeout(timeoutSecondsRead.toLong(), TimeUnit.SECONDS)
|
||||
.writeTimeout(timeoutSecondsRead.toLong(), TimeUnit.SECONDS)
|
||||
.pingInterval(10, TimeUnit.SECONDS)
|
||||
.connectionSpecs(spec_list)
|
||||
.connectionSpecs(Collections.singletonList(spec))
|
||||
.sslSocketFactory(MySslSocketFactory,MySslSocketFactory.trustManager)
|
||||
.addInterceptor(ProgressResponseBody.makeInterceptor())
|
||||
.addInterceptor(user_agent_interceptor)
|
||||
}
|
||||
|
@ -257,6 +259,12 @@ class App1 : Application() {
|
|||
var state = appStateX
|
||||
if(state != null) return state
|
||||
|
||||
// initialize Conscrypt
|
||||
Security.insertProviderAt(
|
||||
Conscrypt.newProvider(),
|
||||
1 /* 1 means first position */
|
||||
)
|
||||
|
||||
initializeFont()
|
||||
|
||||
pref = Pref.pref(app_context)
|
||||
|
|
|
@ -50,6 +50,7 @@ class TootApiClient(
|
|||
companion object {
|
||||
private val log = LogCategory("TootApiClient")
|
||||
|
||||
val debugHandshake = true
|
||||
|
||||
private const val DEFAULT_CLIENT_NAME = "SubwayTooter"
|
||||
internal const val KEY_CLIENT_CREDENTIAL = "SubwayTooterClientCredential"
|
||||
|
@ -266,6 +267,8 @@ class TootApiClient(
|
|||
//////////////////////////////////////////////////////////////////////
|
||||
// ユーティリティ
|
||||
|
||||
|
||||
|
||||
// リクエストをokHttpに渡してレスポンスを取得する
|
||||
internal inline fun sendRequest(
|
||||
result : TootApiResult,
|
||||
|
@ -288,7 +291,15 @@ class TootApiClient(
|
|||
)
|
||||
)
|
||||
|
||||
result.response = httpClient.getResponse(request, tmpOkhttpClient = tmpOkhttpClient)
|
||||
val response = httpClient.getResponse(request, tmpOkhttpClient = tmpOkhttpClient)
|
||||
result.response = response
|
||||
|
||||
if(debugHandshake) {
|
||||
val handshake = response.handshake()
|
||||
if(handshake != null) {
|
||||
log.d("handshake ${handshake.tlsVersion()},${handshake.cipherSuite()} ${request.url()}")
|
||||
}
|
||||
}
|
||||
|
||||
null == result.error
|
||||
|
||||
|
|
|
@ -0,0 +1,119 @@
|
|||
package jp.juggler.util
|
||||
|
||||
import java.io.IOException
|
||||
import java.net.InetAddress
|
||||
import java.net.Socket
|
||||
import java.net.UnknownHostException
|
||||
import java.security.KeyStore
|
||||
import javax.net.ssl.*
|
||||
|
||||
object MySslSocketFactory : SSLSocketFactory() {
|
||||
|
||||
var debugCipherSuites = false
|
||||
|
||||
private val log = LogCategory("MySslSocketFactory")
|
||||
|
||||
private val originalFactory: SSLSocketFactory =
|
||||
SSLContext.getInstance("TLS").apply {
|
||||
init(null, null, null)
|
||||
}.socketFactory
|
||||
|
||||
private fun check(socket: Socket?): Socket? {
|
||||
|
||||
// 端末のデフォルトでは1.3が含まれないので追加する
|
||||
(socket as? SSLSocket)?.enabledProtocols = arrayOf("TLSv1.1", "TLSv1.2", "TLSv1.3")
|
||||
|
||||
// デバッグフラグが変更された後に1回だけ、ソケットの暗号化スイートを列挙する
|
||||
if (debugCipherSuites) {
|
||||
debugCipherSuites = false
|
||||
(socket as? SSLSocket)?.enabledCipherSuites?.forEach { cs ->
|
||||
log.d("getEnabledCipherSuites : $cs")
|
||||
}
|
||||
}
|
||||
|
||||
return socket
|
||||
}
|
||||
|
||||
override fun getDefaultCipherSuites(): Array<String> {
|
||||
return originalFactory.defaultCipherSuites
|
||||
}
|
||||
|
||||
override fun getSupportedCipherSuites(): Array<String> {
|
||||
return originalFactory.supportedCipherSuites
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(): Socket? {
|
||||
return check(originalFactory.createSocket())
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(s: Socket, host: String, port: Int, autoClose: Boolean): Socket? {
|
||||
return check(
|
||||
originalFactory.createSocket(
|
||||
s,
|
||||
host,
|
||||
port,
|
||||
autoClose
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Throws(IOException::class, UnknownHostException::class)
|
||||
override fun createSocket(host: String, port: Int): Socket? {
|
||||
return check(
|
||||
originalFactory.createSocket(
|
||||
host,
|
||||
port
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Throws(IOException::class, UnknownHostException::class)
|
||||
override fun createSocket(host: String, port: Int, localHost: InetAddress, localPort: Int): Socket? {
|
||||
return check(
|
||||
originalFactory.createSocket(
|
||||
host,
|
||||
port,
|
||||
localHost,
|
||||
localPort
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(host: InetAddress, port: Int): Socket? {
|
||||
return check(
|
||||
originalFactory.createSocket(
|
||||
host,
|
||||
port
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
@Throws(IOException::class)
|
||||
override fun createSocket(address: InetAddress, port: Int, localAddress: InetAddress, localPort: Int): Socket? {
|
||||
return check(
|
||||
originalFactory.createSocket(
|
||||
address,
|
||||
port,
|
||||
localAddress,
|
||||
localPort
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
//
|
||||
val trustManager: X509TrustManager by lazy {
|
||||
val trustManagers = TrustManagerFactory
|
||||
.getInstance(TrustManagerFactory.getDefaultAlgorithm())
|
||||
.apply { init(null as KeyStore?) }
|
||||
.trustManagers
|
||||
|
||||
trustManagers
|
||||
.find { it is X509TrustManager }
|
||||
as? X509TrustManager
|
||||
?: error("missing X509TrustManager in $trustManagers")
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue