diff options
author | Jesse Wilson <jwilson@squareup.com> | 2024-04-01 21:44:15 -0400 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-04-01 21:44:15 -0400 |
commit | 4c6240137351cf2a4c65c74c9e83cb04fcd81d70 (patch) | |
tree | c68fa66bf78b947fcdb9a6ba4e0f06a997c64735 | |
parent | 3cde79c505c0c936d1d4365b79073600682d1d0d (diff) | |
download | okhttp4-4c6240137351cf2a4c65c74c9e83cb04fcd81d70.tar.gz |
Tidy the tls survey code (#8324)
* Tidy the tls survey code
* Spotless
15 files changed, 153 insertions, 156 deletions
diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt index 51d619958..f6036b614 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -46,13 +46,6 @@ class CipherSuiteSurvey( val index = client.enabled.indexOfFirst { it.matches(suiteId) } if (index != -1) { print(index + 1) - } else if (client.supported.find { it.matches(suiteId) } != null) { - // Not currently supported, as since 3.9.x we filter to a list - // that is a subset of the platforms. - // The correct answer for developers who override ConnectionSpec, - // it would be the platform defaults, so look at Java and Android - // for the answers. - print("□") } } println() diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt index ea3140619..3c8ba19ae 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -15,7 +15,6 @@ */ package okhttp3.survey -import java.io.IOException import javax.net.ssl.SSLSocket import javax.net.ssl.SSLSocketFactory import okhttp3.ConnectionSpec @@ -27,39 +26,49 @@ import okio.Path.Companion.toPath import org.conscrypt.Conscrypt fun currentOkHttp(ianaSuites: IanaSuites): Client { - val supportedSuites = - buildList { - for (suite in ConnectionSpec.COMPATIBLE_TLS.cipherSuites!!) { - add(ianaSuites.fromJavaName(suite.javaName)) - } - } - val enabledSuites = - buildList { - for (suite in ConnectionSpec.MODERN_TLS.cipherSuites!!) { - add(ianaSuites.fromJavaName(suite.javaName)) - } - } - - return Client("OkHttp", OkHttp.VERSION, null, enabledSuites, supportedSuites) + return Client( + userAgent = "OkHttp", + version = OkHttp.VERSION, + enabled = + ConnectionSpec.MODERN_TLS.cipherSuites!!.map { + ianaSuites.fromJavaName(it.javaName) + }, + supported = + ConnectionSpec.COMPATIBLE_TLS.cipherSuites!!.map { + ianaSuites.fromJavaName(it.javaName) + }, + ) } fun historicOkHttp(version: String): Client { val enabled = - FileSystem.RESOURCES.read("okhttp_${version.replace(".", "_")}.txt".toPath()) { + FileSystem.RESOURCES.read("okhttp_$version.txt".toPath()) { this.readUtf8().lines().filter { it.isNotBlank() }.map { - SuiteId(null, it.trim()) + SuiteId(id = null, name = it.trim()) } } - return Client("OkHttp", version, null, enabled = enabled) + return Client( + userAgent = "OkHttp", + version = version, + enabled = enabled, + ) } fun currentVm(ianaSuites: IanaSuites): Client { - return systemDefault(System.getProperty("java.vm.name"), System.getProperty("java.version"), ianaSuites) + return systemDefault( + name = System.getProperty("java.vm.name"), + version = System.getProperty("java.version"), + ianaSuites = ianaSuites, + ) } fun conscrypt(ianaSuites: IanaSuites): Client { val version = Conscrypt.version() - return systemDefault("Conscrypt", "" + version.major() + "." + version.minor(), ianaSuites) + return systemDefault( + name = "Conscrypt", + version = "${version.major()}.${version.minor()}", + ianaSuites = ianaSuites, + ) } fun systemDefault( @@ -67,24 +76,13 @@ fun systemDefault( version: String, ianaSuites: IanaSuites, ): Client { - return try { - val socketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory - val sslSocket = socketFactory.createSocket() as SSLSocket - val supportedSuites = - buildList { - for (suite in sslSocket.supportedCipherSuites) { - add(ianaSuites.fromJavaName(suite)) - } - } - val enabledSuites = - buildList { - for (suite in sslSocket.enabledCipherSuites) { - add(ianaSuites.fromJavaName(suite)) - } - } + val socketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory + val sslSocket = socketFactory.createSocket() as SSLSocket - Client(name, version, null, enabledSuites, supportedSuites) - } catch (e: IOException) { - throw RuntimeException(e) - } + return Client( + userAgent = name, + version = version, + enabled = sslSocket.enabledCipherSuites.map { ianaSuites.fromJavaName(it) }, + supported = sslSocket.supportedCipherSuites.map { ianaSuites.fromJavaName(it) }, + ) } diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt index 2b774f5ee..5427864e7 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -20,7 +20,6 @@ import okhttp3.OkHttpClient import okhttp3.Request import okhttp3.executeAsync import okhttp3.survey.types.SuiteId -import okio.ByteString import okio.ByteString.Companion.decodeHex import okio.IOException @@ -30,7 +29,7 @@ val IANA_CSV_PATTERN = "\"0x(\\w\\w),0x(\\w\\w)\",(\\w+).*".toRegex() fun parseIanaCsvRow(s: String): SuiteId? { if (s.contains("Reserved") || s.contains("Unassigned")) return null val matcher = IANA_CSV_PATTERN.matchEntire(s) ?: return null - val id: ByteString = (matcher.groupValues[1] + matcher.groupValues[2]).decodeHex() + val id = (matcher.groupValues[1] + matcher.groupValues[2]).decodeHex() return SuiteId(id, matcher.groupValues[3]) } @@ -39,13 +38,9 @@ class IanaSuites( val suites: List<SuiteId>, ) { fun fromJavaName(javaName: String): SuiteId { - for (suiteId in suites) { - val alternateName = "TLS_" + javaName.substring(4) - if (suiteId.name == javaName || suiteId.name == alternateName) { - return suiteId - } - } - throw IllegalArgumentException("No such suite: $javaName") + return suites.firstOrNull { + it.name == javaName || it.name == "TLS_${javaName.drop(4)}" + } ?: throw IllegalArgumentException("No such suite: $javaName") } } @@ -60,7 +55,8 @@ suspend fun fetchIanaSuites(okHttpClient: OkHttpClient): IanaSuites { throw IOException("Failed ${it.code} ${it.message}") } it.body.string().lines() - }.mapNotNull { parseIanaCsvRow(it) } + .mapNotNull { parseIanaCsvRow(it) } + } return IanaSuites("current", suites) } diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt index ced4cf205..dfb272b72 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2018 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package okhttp3.survey import java.security.Security import okhttp3.Cache import okhttp3.OkHttpClient -import okhttp3.survey.ssllabs.SslLabsScraper +import okhttp3.survey.ssllabs.SslLabsClient import okhttp3.survey.types.Client import okhttp3.survey.types.SuiteId import okio.FileSystem @@ -34,76 +34,69 @@ suspend fun main() { .cache(Cache("build/okhttp_cache".toPath(), 100_000_000, FileSystem.SYSTEM)) .build() - val sslLabsScraper = SslLabsScraper(client) + val sslLabsClients = SslLabsClient(client).clients() + val ianaSuitesNew = fetchIanaSuites(client) - try { - val ianaSuitesNew = fetchIanaSuites(client) + val android5 = sslLabsClients.first { it.userAgent == "Android" && it.version == "5.0.0" } + val android9 = sslLabsClients.first { it.userAgent == "Android" && it.version == "9.0" } + val chrome33 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "33" } + val chrome57 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "57" } + val chrome80 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "80" } + val firefox34 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "34" } + val firefox53 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "53" } + val firefox73 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "73" } + val java7 = sslLabsClients.first { it.userAgent == "Java" && it.version == "7u25" } + val java12 = sslLabsClients.first { it.userAgent == "Java" && it.version == "12.0.1" } + val safari12iOS = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "iOS 12.3.1" } + val safari12Osx = + sslLabsClients.first { it.userAgent == "Safari" && it.platform == "MacOS 10.14.6 Beta" } - val sslLabsClients = sslLabsScraper.query() + val okhttp = currentOkHttp(ianaSuitesNew) - val android5 = sslLabsClients.first { it.userAgent == "Android" && it.version == "5.0.0" } - val android9 = sslLabsClients.first { it.userAgent == "Android" && it.version == "9.0" } - val chrome33 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "33" } - val chrome57 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "57" } - val chrome80 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "80" } - val firefox34 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "34" } - val firefox53 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "53" } - val firefox73 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "73" } - val java7 = sslLabsClients.first { it.userAgent == "Java" && it.version == "7u25" } - val java12 = sslLabsClients.first { it.userAgent == "Java" && it.version == "12.0.1" } - val safari12iOS = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "iOS 12.3.1" } - val safari12Osx = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "MacOS 10.14.6 Beta" } + val okHttp_4_10 = historicOkHttp("4.10") + val okHttp_3_14 = historicOkHttp("3.14") + val okHttp_3_13 = historicOkHttp("3.13") + val okHttp_3_11 = historicOkHttp("3.11") + val okHttp_3_9 = historicOkHttp("3.9") - val okhttp = currentOkHttp(ianaSuitesNew) + val currentVm = currentVm(ianaSuitesNew) - val okHttp_4_10 = historicOkHttp("4.10") - val okHttp_3_14 = historicOkHttp("3.14") - val okHttp_3_13 = historicOkHttp("3.13") - val okHttp_3_11 = historicOkHttp("3.11") - val okHttp_3_9 = historicOkHttp("3.9") + val conscrypt = + if (includeConscrypt) { + Security.addProvider(Conscrypt.newProvider()) + conscrypt(ianaSuitesNew) + } else { + Client("Conscrypt", "Disabled", null, listOf()) + } - val currentVm = currentVm(ianaSuitesNew) + val clients = + listOf( + okhttp, + chrome80, + firefox73, + android9, + safari12iOS, + conscrypt, + currentVm, + okHttp_3_9, + okHttp_3_11, + okHttp_3_13, + okHttp_3_14, + okHttp_4_10, + android5, + java7, + java12, + firefox34, + firefox53, + chrome33, + chrome57, + safari12Osx, + ) - val conscrypt = - if (includeConscrypt) { - Security.addProvider(Conscrypt.newProvider()) - conscrypt(ianaSuitesNew) - } else { - Client("Conscrypt", "Disabled", null, listOf()) - } + val orderBy = okhttp.enabled + chrome80.enabled + safari12Osx.enabled + rest(clients) + val survey = CipherSuiteSurvey(clients = clients, ianaSuites = ianaSuitesNew, orderBy = orderBy) - val clients = - listOf( - okhttp, - chrome80, - firefox73, - android9, - safari12iOS, - conscrypt, - currentVm, - okHttp_3_9, - okHttp_3_11, - okHttp_3_13, - okHttp_3_14, - okHttp_4_10, - android5, - java7, - java12, - firefox34, - firefox53, - chrome33, - chrome57, - safari12Osx, - ) - - val orderBy = okhttp.enabled + chrome80.enabled + safari12Osx.enabled + rest(clients) - val survey = CipherSuiteSurvey(clients = clients, ianaSuites = ianaSuitesNew, orderBy = orderBy) - - survey.printGoogleSheet() - } finally { - client.dispatcher.executorService.shutdown() - client.connectionPool.evictAll() - } + survey.printGoogleSheet() } fun rest(clients: List<Client>): List<SuiteId> { diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Record.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsApi.kt index af4f05f4d..ea3909e11 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Record.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsApi.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -13,6 +13,15 @@ * See the License for the specific language governing permissions and * limitations under the License. */ -package okhttp3.survey.types +package okhttp3.survey.ssllabs -data class Record(val java: String, val android: String) +import retrofit2.http.GET + +interface SslLabsApi { + @GET("getClients") + suspend fun clients(): List<UserAgentCapabilities> + + companion object { + const val BASE_URL = "https://api.ssllabs.com/api/v3/" + } +} diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsScrape.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsClient.kt index 7b7c0168c..68808d169 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsScrape.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsClient.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -23,8 +23,8 @@ import okhttp3.survey.types.SuiteId import retrofit2.Retrofit import retrofit2.converter.moshi.MoshiConverterFactory -class SslLabsScraper( - private val callFactory: Call.Factory, +class SslLabsClient( + callFactory: Call.Factory, ) { private val moshi = Moshi.Builder().build() @@ -32,27 +32,32 @@ class SslLabsScraper( private val retrofit = Retrofit.Builder() - .baseUrl(SslLabsService.BASE_URL) + .baseUrl(SslLabsApi.BASE_URL) .addConverterFactory(moshiConverterFactory) .callFactory(callFactory) .build() - private val api = retrofit.create(SslLabsService::class.java) + private val sslLabsApi = retrofit.create(SslLabsApi::class.java) - suspend fun query(): List<Client> { - return api.clients().map { userAgent -> - Client(userAgent.name, userAgent.version, userAgent.platform, enabled = userAgent.suiteNames.map { SuiteId(null, it) }) + suspend fun clients(): List<Client> { + return sslLabsApi.clients().map { userAgent -> + Client( + userAgent = userAgent.name, + version = userAgent.version, + platform = userAgent.platform, + enabled = userAgent.suiteNames.map { SuiteId(null, it) }, + ) } } } suspend fun main() { - val client = OkHttpClient() + val sslLabsClient = + SslLabsClient( + callFactory = OkHttpClient(), + ) - val scraper = SslLabsScraper(client) - - println(scraper.query()) - - client.connectionPool.evictAll() - client.dispatcher.executorService.shutdown() + for (client in sslLabsClient.clients()) { + println(client) + } } diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt deleted file mode 100644 index 4715de7e7..000000000 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsService.kt +++ /dev/null @@ -1,12 +0,0 @@ -package okhttp3.survey.ssllabs - -import retrofit2.http.GET - -interface SslLabsService { - @GET("getClients") - suspend fun clients(): List<UserAgentCapabilities> - - companion object { - const val BASE_URL = "https://api.ssllabs.com/api/v3/" - } -} diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt index 26f61e4a9..b68b6ae74 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/UserAgentCapabilities.kt @@ -1,3 +1,18 @@ +/* + * Copyright (C) 2022 Square, Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ package okhttp3.survey.ssllabs import com.squareup.moshi.JsonClass diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt index 2e592b77d..9e5223276 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Client.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. @@ -18,7 +18,7 @@ package okhttp3.survey.types data class Client( val userAgent: String, val version: String, - val platform: String?, + val platform: String? = null, val enabled: List<SuiteId> = listOf(), val supported: List<SuiteId> = listOf(), ) { diff --git a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt index 13d566b56..a4dee2fd6 100644 --- a/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt +++ b/samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/SuiteId.kt @@ -1,5 +1,5 @@ /* - * Copyright (C) 2016 Square, Inc. + * Copyright (C) 2022 Square, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_11.txt b/samples/tlssurvey/src/main/resources/okhttp_3.11.txt index 618db5fed..618db5fed 100644 --- a/samples/tlssurvey/src/main/resources/okhttp_3_11.txt +++ b/samples/tlssurvey/src/main/resources/okhttp_3.11.txt diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_13.txt b/samples/tlssurvey/src/main/resources/okhttp_3.13.txt index 0d8acaf93..0d8acaf93 100644 --- a/samples/tlssurvey/src/main/resources/okhttp_3_13.txt +++ b/samples/tlssurvey/src/main/resources/okhttp_3.13.txt diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_14.txt b/samples/tlssurvey/src/main/resources/okhttp_3.14.txt index 056852f1a..056852f1a 100644 --- a/samples/tlssurvey/src/main/resources/okhttp_3_14.txt +++ b/samples/tlssurvey/src/main/resources/okhttp_3.14.txt diff --git a/samples/tlssurvey/src/main/resources/okhttp_3_9.txt b/samples/tlssurvey/src/main/resources/okhttp_3.9.txt index 41ed6ceae..41ed6ceae 100644 --- a/samples/tlssurvey/src/main/resources/okhttp_3_9.txt +++ b/samples/tlssurvey/src/main/resources/okhttp_3.9.txt diff --git a/samples/tlssurvey/src/main/resources/okhttp_4_10.txt b/samples/tlssurvey/src/main/resources/okhttp_4.10.txt index 056852f1a..056852f1a 100644 --- a/samples/tlssurvey/src/main/resources/okhttp_4_10.txt +++ b/samples/tlssurvey/src/main/resources/okhttp_4.10.txt |