Conscryptの導入。TLS1.3対応。APKファイルが大きくなる
This commit is contained in:
parent
816e7bbec6
commit
3007f5b02b
|
@ -32,6 +32,7 @@
|
||||||
<w>foregrounder</w>
|
<w>foregrounder</w>
|
||||||
<w>gifv</w>
|
<w>gifv</w>
|
||||||
<w>github</w>
|
<w>github</w>
|
||||||
|
<w>hansshake</w>
|
||||||
<w>hashtag</w>
|
<w>hashtag</w>
|
||||||
<w>hashtags</w>
|
<w>hashtags</w>
|
||||||
<w>hhmm</w>
|
<w>hhmm</w>
|
||||||
|
|
|
@ -116,6 +116,7 @@ dependencies {
|
||||||
kapt 'com.github.bumptech.glide:compiler:4.7.1'
|
kapt 'com.github.bumptech.glide:compiler:4.7.1'
|
||||||
// kotlin では annotationProcessor の代わりに kapt を使う
|
// kotlin では annotationProcessor の代わりに kapt を使う
|
||||||
|
|
||||||
|
implementation "org.conscrypt:conscrypt-android:1.3.0"
|
||||||
|
|
||||||
implementation 'uk.co.chrisjenx:calligraphy:2.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.ByteArrayInputStream
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
import javax.net.ssl.HttpsURLConnection
|
||||||
|
|
||||||
class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
||||||
|
|
||||||
|
@ -330,6 +331,9 @@ class ActMediaViewer : AppCompatActivity(), View.OnClickListener {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// https://github.com/google/ExoPlayer/issues/1819
|
||||||
|
HttpsURLConnection.setDefaultSSLSocketFactory(MySslSocketFactory)
|
||||||
|
|
||||||
exoView.visibility = View.VISIBLE
|
exoView.visibility = View.VISIBLE
|
||||||
|
|
||||||
val defaultBandwidthMeter = DefaultBandwidthMeter()
|
val defaultBandwidthMeter = DefaultBandwidthMeter()
|
||||||
|
|
|
@ -29,8 +29,10 @@ import jp.juggler.subwaytooter.util.CustomEmojiLister
|
||||||
import jp.juggler.subwaytooter.util.ProgressResponseBody
|
import jp.juggler.subwaytooter.util.ProgressResponseBody
|
||||||
import jp.juggler.util.*
|
import jp.juggler.util.*
|
||||||
import okhttp3.*
|
import okhttp3.*
|
||||||
|
import org.conscrypt.Conscrypt
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.InputStream
|
import java.io.InputStream
|
||||||
|
import java.security.Security
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import java.util.concurrent.LinkedBlockingQueue
|
import java.util.concurrent.LinkedBlockingQueue
|
||||||
import java.util.concurrent.ThreadFactory
|
import java.util.concurrent.ThreadFactory
|
||||||
|
@ -219,20 +221,20 @@ class App1 : Application() {
|
||||||
timeoutSecondsConnect : Int,
|
timeoutSecondsConnect : Int,
|
||||||
timeoutSecondsRead : Int
|
timeoutSecondsRead : Int
|
||||||
) : OkHttpClient.Builder {
|
) : OkHttpClient.Builder {
|
||||||
|
|
||||||
val spec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
val spec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS)
|
||||||
.cipherSuites(*APPROVED_CIPHER_SUITES)
|
.allEnabledCipherSuites()
|
||||||
|
.allEnabledTlsVersions()
|
||||||
|
.supportsTlsExtensions(true)
|
||||||
.build()
|
.build()
|
||||||
|
|
||||||
val spec_list = ArrayList<ConnectionSpec>()
|
|
||||||
spec_list.add(spec)
|
|
||||||
spec_list.add(ConnectionSpec.CLEARTEXT)
|
|
||||||
|
|
||||||
return OkHttpClient.Builder()
|
return OkHttpClient.Builder()
|
||||||
.connectTimeout(timeoutSecondsConnect.toLong(), TimeUnit.SECONDS)
|
.connectTimeout(timeoutSecondsConnect.toLong(), TimeUnit.SECONDS)
|
||||||
.readTimeout(timeoutSecondsRead.toLong(), TimeUnit.SECONDS)
|
.readTimeout(timeoutSecondsRead.toLong(), TimeUnit.SECONDS)
|
||||||
.writeTimeout(timeoutSecondsRead.toLong(), TimeUnit.SECONDS)
|
.writeTimeout(timeoutSecondsRead.toLong(), TimeUnit.SECONDS)
|
||||||
.pingInterval(10, TimeUnit.SECONDS)
|
.pingInterval(10, TimeUnit.SECONDS)
|
||||||
.connectionSpecs(spec_list)
|
.connectionSpecs(Collections.singletonList(spec))
|
||||||
|
.sslSocketFactory(MySslSocketFactory,MySslSocketFactory.trustManager)
|
||||||
.addInterceptor(ProgressResponseBody.makeInterceptor())
|
.addInterceptor(ProgressResponseBody.makeInterceptor())
|
||||||
.addInterceptor(user_agent_interceptor)
|
.addInterceptor(user_agent_interceptor)
|
||||||
}
|
}
|
||||||
|
@ -257,6 +259,12 @@ class App1 : Application() {
|
||||||
var state = appStateX
|
var state = appStateX
|
||||||
if(state != null) return state
|
if(state != null) return state
|
||||||
|
|
||||||
|
// initialize Conscrypt
|
||||||
|
Security.insertProviderAt(
|
||||||
|
Conscrypt.newProvider(),
|
||||||
|
1 /* 1 means first position */
|
||||||
|
)
|
||||||
|
|
||||||
initializeFont()
|
initializeFont()
|
||||||
|
|
||||||
pref = Pref.pref(app_context)
|
pref = Pref.pref(app_context)
|
||||||
|
|
|
@ -50,6 +50,7 @@ class TootApiClient(
|
||||||
companion object {
|
companion object {
|
||||||
private val log = LogCategory("TootApiClient")
|
private val log = LogCategory("TootApiClient")
|
||||||
|
|
||||||
|
val debugHandshake = true
|
||||||
|
|
||||||
private const val DEFAULT_CLIENT_NAME = "SubwayTooter"
|
private const val DEFAULT_CLIENT_NAME = "SubwayTooter"
|
||||||
internal const val KEY_CLIENT_CREDENTIAL = "SubwayTooterClientCredential"
|
internal const val KEY_CLIENT_CREDENTIAL = "SubwayTooterClientCredential"
|
||||||
|
@ -266,6 +267,8 @@ class TootApiClient(
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
// ユーティリティ
|
// ユーティリティ
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// リクエストをokHttpに渡してレスポンスを取得する
|
// リクエストをokHttpに渡してレスポンスを取得する
|
||||||
internal inline fun sendRequest(
|
internal inline fun sendRequest(
|
||||||
result : TootApiResult,
|
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
|
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