Skip to content

Commit 4c62401

Browse files
authored
Tidy the tls survey code (#8324)
* Tidy the tls survey code * Spotless
1 parent 3cde79c commit 4c62401

15 files changed

+153
-156
lines changed

samples/tlssurvey/src/main/kotlin/okhttp3/survey/CipherSuiteSurvey.kt

+1-8
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016 Square, Inc.
2+
* Copyright (C) 2022 Square, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -46,13 +46,6 @@ class CipherSuiteSurvey(
4646
val index = client.enabled.indexOfFirst { it.matches(suiteId) }
4747
if (index != -1) {
4848
print(index + 1)
49-
} else if (client.supported.find { it.matches(suiteId) } != null) {
50-
// Not currently supported, as since 3.9.x we filter to a list
51-
// that is a subset of the platforms.
52-
// The correct answer for developers who override ConnectionSpec,
53-
// it would be the platform defaults, so look at Java and Android
54-
// for the answers.
55-
print("")
5649
}
5750
}
5851
println()
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016 Square, Inc.
2+
* Copyright (C) 2022 Square, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -15,7 +15,6 @@
1515
*/
1616
package okhttp3.survey
1717

18-
import java.io.IOException
1918
import javax.net.ssl.SSLSocket
2019
import javax.net.ssl.SSLSocketFactory
2120
import okhttp3.ConnectionSpec
@@ -27,64 +26,63 @@ import okio.Path.Companion.toPath
2726
import org.conscrypt.Conscrypt
2827

2928
fun currentOkHttp(ianaSuites: IanaSuites): Client {
30-
val supportedSuites =
31-
buildList {
32-
for (suite in ConnectionSpec.COMPATIBLE_TLS.cipherSuites!!) {
33-
add(ianaSuites.fromJavaName(suite.javaName))
34-
}
35-
}
36-
val enabledSuites =
37-
buildList {
38-
for (suite in ConnectionSpec.MODERN_TLS.cipherSuites!!) {
39-
add(ianaSuites.fromJavaName(suite.javaName))
40-
}
41-
}
42-
43-
return Client("OkHttp", OkHttp.VERSION, null, enabledSuites, supportedSuites)
29+
return Client(
30+
userAgent = "OkHttp",
31+
version = OkHttp.VERSION,
32+
enabled =
33+
ConnectionSpec.MODERN_TLS.cipherSuites!!.map {
34+
ianaSuites.fromJavaName(it.javaName)
35+
},
36+
supported =
37+
ConnectionSpec.COMPATIBLE_TLS.cipherSuites!!.map {
38+
ianaSuites.fromJavaName(it.javaName)
39+
},
40+
)
4441
}
4542

4643
fun historicOkHttp(version: String): Client {
4744
val enabled =
48-
FileSystem.RESOURCES.read("okhttp_${version.replace(".", "_")}.txt".toPath()) {
45+
FileSystem.RESOURCES.read("okhttp_$version.txt".toPath()) {
4946
this.readUtf8().lines().filter { it.isNotBlank() }.map {
50-
SuiteId(null, it.trim())
47+
SuiteId(id = null, name = it.trim())
5148
}
5249
}
53-
return Client("OkHttp", version, null, enabled = enabled)
50+
return Client(
51+
userAgent = "OkHttp",
52+
version = version,
53+
enabled = enabled,
54+
)
5455
}
5556

5657
fun currentVm(ianaSuites: IanaSuites): Client {
57-
return systemDefault(System.getProperty("java.vm.name"), System.getProperty("java.version"), ianaSuites)
58+
return systemDefault(
59+
name = System.getProperty("java.vm.name"),
60+
version = System.getProperty("java.version"),
61+
ianaSuites = ianaSuites,
62+
)
5863
}
5964

6065
fun conscrypt(ianaSuites: IanaSuites): Client {
6166
val version = Conscrypt.version()
62-
return systemDefault("Conscrypt", "" + version.major() + "." + version.minor(), ianaSuites)
67+
return systemDefault(
68+
name = "Conscrypt",
69+
version = "${version.major()}.${version.minor()}",
70+
ianaSuites = ianaSuites,
71+
)
6372
}
6473

6574
fun systemDefault(
6675
name: String,
6776
version: String,
6877
ianaSuites: IanaSuites,
6978
): Client {
70-
return try {
71-
val socketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory
72-
val sslSocket = socketFactory.createSocket() as SSLSocket
73-
val supportedSuites =
74-
buildList {
75-
for (suite in sslSocket.supportedCipherSuites) {
76-
add(ianaSuites.fromJavaName(suite))
77-
}
78-
}
79-
val enabledSuites =
80-
buildList {
81-
for (suite in sslSocket.enabledCipherSuites) {
82-
add(ianaSuites.fromJavaName(suite))
83-
}
84-
}
79+
val socketFactory = SSLSocketFactory.getDefault() as SSLSocketFactory
80+
val sslSocket = socketFactory.createSocket() as SSLSocket
8581

86-
Client(name, version, null, enabledSuites, supportedSuites)
87-
} catch (e: IOException) {
88-
throw RuntimeException(e)
89-
}
82+
return Client(
83+
userAgent = name,
84+
version = version,
85+
enabled = sslSocket.enabledCipherSuites.map { ianaSuites.fromJavaName(it) },
86+
supported = sslSocket.supportedCipherSuites.map { ianaSuites.fromJavaName(it) },
87+
)
9088
}

samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt

+7-11
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016 Square, Inc.
2+
* Copyright (C) 2022 Square, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -20,7 +20,6 @@ import okhttp3.OkHttpClient
2020
import okhttp3.Request
2121
import okhttp3.executeAsync
2222
import okhttp3.survey.types.SuiteId
23-
import okio.ByteString
2423
import okio.ByteString.Companion.decodeHex
2524
import okio.IOException
2625

@@ -30,7 +29,7 @@ val IANA_CSV_PATTERN = "\"0x(\\w\\w),0x(\\w\\w)\",(\\w+).*".toRegex()
3029
fun parseIanaCsvRow(s: String): SuiteId? {
3130
if (s.contains("Reserved") || s.contains("Unassigned")) return null
3231
val matcher = IANA_CSV_PATTERN.matchEntire(s) ?: return null
33-
val id: ByteString = (matcher.groupValues[1] + matcher.groupValues[2]).decodeHex()
32+
val id = (matcher.groupValues[1] + matcher.groupValues[2]).decodeHex()
3433
return SuiteId(id, matcher.groupValues[3])
3534
}
3635

@@ -39,13 +38,9 @@ class IanaSuites(
3938
val suites: List<SuiteId>,
4039
) {
4140
fun fromJavaName(javaName: String): SuiteId {
42-
for (suiteId in suites) {
43-
val alternateName = "TLS_" + javaName.substring(4)
44-
if (suiteId.name == javaName || suiteId.name == alternateName) {
45-
return suiteId
46-
}
47-
}
48-
throw IllegalArgumentException("No such suite: $javaName")
41+
return suites.firstOrNull {
42+
it.name == javaName || it.name == "TLS_${javaName.drop(4)}"
43+
} ?: throw IllegalArgumentException("No such suite: $javaName")
4944
}
5045
}
5146

@@ -60,7 +55,8 @@ suspend fun fetchIanaSuites(okHttpClient: OkHttpClient): IanaSuites {
6055
throw IOException("Failed ${it.code} ${it.message}")
6156
}
6257
it.body.string().lines()
63-
}.mapNotNull { parseIanaCsvRow(it) }
58+
.mapNotNull { parseIanaCsvRow(it) }
59+
}
6460

6561
return IanaSuites("current", suites)
6662
}

samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt

+57-64
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2018 Square, Inc.
2+
* Copyright (C) 2022 Square, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -18,7 +18,7 @@ package okhttp3.survey
1818
import java.security.Security
1919
import okhttp3.Cache
2020
import okhttp3.OkHttpClient
21-
import okhttp3.survey.ssllabs.SslLabsScraper
21+
import okhttp3.survey.ssllabs.SslLabsClient
2222
import okhttp3.survey.types.Client
2323
import okhttp3.survey.types.SuiteId
2424
import okio.FileSystem
@@ -34,76 +34,69 @@ suspend fun main() {
3434
.cache(Cache("build/okhttp_cache".toPath(), 100_000_000, FileSystem.SYSTEM))
3535
.build()
3636

37-
val sslLabsScraper = SslLabsScraper(client)
37+
val sslLabsClients = SslLabsClient(client).clients()
38+
val ianaSuitesNew = fetchIanaSuites(client)
3839

39-
try {
40-
val ianaSuitesNew = fetchIanaSuites(client)
40+
val android5 = sslLabsClients.first { it.userAgent == "Android" && it.version == "5.0.0" }
41+
val android9 = sslLabsClients.first { it.userAgent == "Android" && it.version == "9.0" }
42+
val chrome33 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "33" }
43+
val chrome57 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "57" }
44+
val chrome80 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "80" }
45+
val firefox34 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "34" }
46+
val firefox53 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "53" }
47+
val firefox73 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "73" }
48+
val java7 = sslLabsClients.first { it.userAgent == "Java" && it.version == "7u25" }
49+
val java12 = sslLabsClients.first { it.userAgent == "Java" && it.version == "12.0.1" }
50+
val safari12iOS = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "iOS 12.3.1" }
51+
val safari12Osx =
52+
sslLabsClients.first { it.userAgent == "Safari" && it.platform == "MacOS 10.14.6 Beta" }
4153

42-
val sslLabsClients = sslLabsScraper.query()
54+
val okhttp = currentOkHttp(ianaSuitesNew)
4355

44-
val android5 = sslLabsClients.first { it.userAgent == "Android" && it.version == "5.0.0" }
45-
val android9 = sslLabsClients.first { it.userAgent == "Android" && it.version == "9.0" }
46-
val chrome33 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "33" }
47-
val chrome57 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "57" }
48-
val chrome80 = sslLabsClients.first { it.userAgent == "Chrome" && it.version == "80" }
49-
val firefox34 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "34" }
50-
val firefox53 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "53" }
51-
val firefox73 = sslLabsClients.first { it.userAgent == "Firefox" && it.version == "73" }
52-
val java7 = sslLabsClients.first { it.userAgent == "Java" && it.version == "7u25" }
53-
val java12 = sslLabsClients.first { it.userAgent == "Java" && it.version == "12.0.1" }
54-
val safari12iOS = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "iOS 12.3.1" }
55-
val safari12Osx = sslLabsClients.first { it.userAgent == "Safari" && it.platform == "MacOS 10.14.6 Beta" }
56+
val okHttp_4_10 = historicOkHttp("4.10")
57+
val okHttp_3_14 = historicOkHttp("3.14")
58+
val okHttp_3_13 = historicOkHttp("3.13")
59+
val okHttp_3_11 = historicOkHttp("3.11")
60+
val okHttp_3_9 = historicOkHttp("3.9")
5661

57-
val okhttp = currentOkHttp(ianaSuitesNew)
62+
val currentVm = currentVm(ianaSuitesNew)
5863

59-
val okHttp_4_10 = historicOkHttp("4.10")
60-
val okHttp_3_14 = historicOkHttp("3.14")
61-
val okHttp_3_13 = historicOkHttp("3.13")
62-
val okHttp_3_11 = historicOkHttp("3.11")
63-
val okHttp_3_9 = historicOkHttp("3.9")
64+
val conscrypt =
65+
if (includeConscrypt) {
66+
Security.addProvider(Conscrypt.newProvider())
67+
conscrypt(ianaSuitesNew)
68+
} else {
69+
Client("Conscrypt", "Disabled", null, listOf())
70+
}
6471

65-
val currentVm = currentVm(ianaSuitesNew)
72+
val clients =
73+
listOf(
74+
okhttp,
75+
chrome80,
76+
firefox73,
77+
android9,
78+
safari12iOS,
79+
conscrypt,
80+
currentVm,
81+
okHttp_3_9,
82+
okHttp_3_11,
83+
okHttp_3_13,
84+
okHttp_3_14,
85+
okHttp_4_10,
86+
android5,
87+
java7,
88+
java12,
89+
firefox34,
90+
firefox53,
91+
chrome33,
92+
chrome57,
93+
safari12Osx,
94+
)
6695

67-
val conscrypt =
68-
if (includeConscrypt) {
69-
Security.addProvider(Conscrypt.newProvider())
70-
conscrypt(ianaSuitesNew)
71-
} else {
72-
Client("Conscrypt", "Disabled", null, listOf())
73-
}
96+
val orderBy = okhttp.enabled + chrome80.enabled + safari12Osx.enabled + rest(clients)
97+
val survey = CipherSuiteSurvey(clients = clients, ianaSuites = ianaSuitesNew, orderBy = orderBy)
7498

75-
val clients =
76-
listOf(
77-
okhttp,
78-
chrome80,
79-
firefox73,
80-
android9,
81-
safari12iOS,
82-
conscrypt,
83-
currentVm,
84-
okHttp_3_9,
85-
okHttp_3_11,
86-
okHttp_3_13,
87-
okHttp_3_14,
88-
okHttp_4_10,
89-
android5,
90-
java7,
91-
java12,
92-
firefox34,
93-
firefox53,
94-
chrome33,
95-
chrome57,
96-
safari12Osx,
97-
)
98-
99-
val orderBy = okhttp.enabled + chrome80.enabled + safari12Osx.enabled + rest(clients)
100-
val survey = CipherSuiteSurvey(clients = clients, ianaSuites = ianaSuitesNew, orderBy = orderBy)
101-
102-
survey.printGoogleSheet()
103-
} finally {
104-
client.dispatcher.executorService.shutdown()
105-
client.connectionPool.evictAll()
106-
}
99+
survey.printGoogleSheet()
107100
}
108101

109102
fun rest(clients: List<Client>): List<SuiteId> {

samples/tlssurvey/src/main/kotlin/okhttp3/survey/types/Record.kt samples/tlssurvey/src/main/kotlin/okhttp3/survey/ssllabs/SslLabsApi.kt

+12-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
/*
2-
* Copyright (C) 2016 Square, Inc.
2+
* Copyright (C) 2022 Square, Inc.
33
*
44
* Licensed under the Apache License, Version 2.0 (the "License");
55
* you may not use this file except in compliance with the License.
@@ -13,6 +13,15 @@
1313
* See the License for the specific language governing permissions and
1414
* limitations under the License.
1515
*/
16-
package okhttp3.survey.types
16+
package okhttp3.survey.ssllabs
1717

18-
data class Record(val java: String, val android: String)
18+
import retrofit2.http.GET
19+
20+
interface SslLabsApi {
21+
@GET("getClients")
22+
suspend fun clients(): List<UserAgentCapabilities>
23+
24+
companion object {
25+
const val BASE_URL = "https://api.ssllabs.com/api/v3/"
26+
}
27+
}

0 commit comments

Comments
 (0)