mirror of
https://github.com/square/okhttp.git
synced 2025-11-24 18:41:06 +03:00
Refresh the OkHttp cipher suite process (#7393)
This commit is contained in:
26
samples/tlssurvey/build.gradle.kts
Normal file
26
samples/tlssurvey/build.gradle.kts
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
plugins {
|
||||||
|
kotlin("jvm")
|
||||||
|
application
|
||||||
|
id("com.google.devtools.ksp").version("1.6.21-1.0.6")
|
||||||
|
}
|
||||||
|
|
||||||
|
application {
|
||||||
|
mainClass.set("okhttp3.survey.RunSurveyKt")
|
||||||
|
}
|
||||||
|
|
||||||
|
dependencies {
|
||||||
|
implementation("com.squareup.okhttp3:okhttp:5.0.0-alpha.10")
|
||||||
|
implementation("com.squareup.okhttp3:okhttp-coroutines:5.0.0-alpha.10")
|
||||||
|
implementation(libs.conscrypt.openjdk)
|
||||||
|
|
||||||
|
implementation("com.squareup.retrofit2:retrofit:2.9.0")
|
||||||
|
implementation("com.squareup.retrofit2:converter-moshi:2.9.0")
|
||||||
|
implementation(libs.squareup.moshi)
|
||||||
|
implementation(libs.squareup.moshi.kotlin)
|
||||||
|
|
||||||
|
ksp("com.squareup.moshi:moshi-kotlin-codegen:1.13.0")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.compileJava {
|
||||||
|
options.isWarnings = false
|
||||||
|
}
|
||||||
@@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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
|
||||||
|
|
||||||
|
import okhttp3.survey.types.Client
|
||||||
|
import okhttp3.survey.types.SuiteId
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Organizes information on SSL cipher suite inclusion and precedence for this spreadsheet.
|
||||||
|
* https://docs.google.com/spreadsheets/d/1C3FdZSlCBq_-qrVwG1KDIzNIB3Hyg_rKAcgmSzOsHyQ/edit#gid=0
|
||||||
|
*/
|
||||||
|
class CipherSuiteSurvey(
|
||||||
|
val clients: List<Client>,
|
||||||
|
val ianaSuites: IanaSuites,
|
||||||
|
val orderBy: List<SuiteId>
|
||||||
|
) {
|
||||||
|
|
||||||
|
fun printGoogleSheet() {
|
||||||
|
print("name")
|
||||||
|
for (client in clients) {
|
||||||
|
print("\t")
|
||||||
|
print(client.nameAndVersion)
|
||||||
|
}
|
||||||
|
println()
|
||||||
|
val sortedSuites = ianaSuites.suites.sortedBy { ianaSuite ->
|
||||||
|
val index = orderBy.indexOfFirst { it.matches(ianaSuite) }
|
||||||
|
if (index == -1) Integer.MAX_VALUE else index
|
||||||
|
}
|
||||||
|
for (suiteId in sortedSuites) {
|
||||||
|
print(suiteId.name)
|
||||||
|
for (client in clients) {
|
||||||
|
print("\t")
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
81
samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt
Normal file
81
samples/tlssurvey/src/main/kotlin/okhttp3/survey/Clients.kt
Normal file
@@ -0,0 +1,81 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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
|
||||||
|
|
||||||
|
import java.io.IOException
|
||||||
|
import javax.net.ssl.SSLSocket
|
||||||
|
import javax.net.ssl.SSLSocketFactory
|
||||||
|
import okhttp3.ConnectionSpec
|
||||||
|
import okhttp3.OkHttp
|
||||||
|
import okhttp3.survey.types.Client
|
||||||
|
import okhttp3.survey.types.SuiteId
|
||||||
|
import okio.FileSystem
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun historicOkHttp(version: String): Client {
|
||||||
|
val enabled = FileSystem.RESOURCES.read("okhttp_${version.replace(".", "_")}.txt".toPath()) {
|
||||||
|
this.readUtf8().lines().filter { it.isNotBlank() }.map {
|
||||||
|
SuiteId(null, it.trim())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return Client("OkHttp", version, null, enabled = enabled)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun currentVm(ianaSuites: IanaSuites): Client {
|
||||||
|
return systemDefault(System.getProperty("java.vm.name"), System.getProperty("java.version"), ianaSuites)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun conscrypt(ianaSuites: IanaSuites): Client {
|
||||||
|
val version = Conscrypt.version()
|
||||||
|
return systemDefault("Conscrypt", "" + version.major() + "." + version.minor(), ianaSuites)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun systemDefault(name: String, 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))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Client(name, version, null, enabledSuites, supportedSuites)
|
||||||
|
} catch (e: IOException) {
|
||||||
|
throw RuntimeException(e)
|
||||||
|
}
|
||||||
|
}
|
||||||
64
samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt
Normal file
64
samples/tlssurvey/src/main/kotlin/okhttp3/survey/Iana.kt
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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
|
||||||
|
|
||||||
|
import okhttp3.HttpUrl.Companion.toHttpUrl
|
||||||
|
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
|
||||||
|
|
||||||
|
/** Example: "0x00,0x08",TLS_RSA_EXPORT_WITH_DES40_CBC_SHA,Y,N,[RFC4346] */
|
||||||
|
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()
|
||||||
|
return SuiteId(id, matcher.groupValues[3])
|
||||||
|
}
|
||||||
|
|
||||||
|
class IanaSuites(
|
||||||
|
val name: String, 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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
suspend fun fetchIanaSuites(okHttpClient: OkHttpClient): IanaSuites {
|
||||||
|
val url = "https://www.iana.org/assignments/tls-parameters/tls-parameters-4.csv"
|
||||||
|
|
||||||
|
val call = okHttpClient.newCall(Request(url.toHttpUrl()))
|
||||||
|
|
||||||
|
val suites = call.executeAsync().use {
|
||||||
|
if (!it.isSuccessful) {
|
||||||
|
throw IOException("Failed ${it.code} ${it.message}")
|
||||||
|
}
|
||||||
|
it.body.string().lines()
|
||||||
|
}.mapNotNull { parseIanaCsvRow(it) }
|
||||||
|
|
||||||
|
return IanaSuites("current", suites)
|
||||||
|
}
|
||||||
108
samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt
Normal file
108
samples/tlssurvey/src/main/kotlin/okhttp3/survey/RunSurvey.kt
Normal file
@@ -0,0 +1,108 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2018 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
|
||||||
|
|
||||||
|
import java.security.Security
|
||||||
|
import okhttp3.Cache
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.survey.ssllabs.SslLabsScraper
|
||||||
|
import okhttp3.survey.types.Client
|
||||||
|
import okhttp3.survey.types.SuiteId
|
||||||
|
import okio.FileSystem
|
||||||
|
import okio.Path.Companion.toPath
|
||||||
|
import org.conscrypt.Conscrypt
|
||||||
|
|
||||||
|
suspend fun main() {
|
||||||
|
val includeConscrypt = false
|
||||||
|
|
||||||
|
val client = OkHttpClient.Builder()
|
||||||
|
.cache(Cache("build/okhttp_cache".toPath(), 100_000_000, FileSystem.SYSTEM))
|
||||||
|
.build()
|
||||||
|
|
||||||
|
val sslLabsScraper = SslLabsScraper(client)
|
||||||
|
|
||||||
|
try {
|
||||||
|
val ianaSuitesNew = fetchIanaSuites(client)
|
||||||
|
|
||||||
|
val sslLabsClients = sslLabsScraper.query()
|
||||||
|
|
||||||
|
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 = currentOkHttp(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 currentVm = currentVm(ianaSuitesNew)
|
||||||
|
|
||||||
|
val conscrypt = if (includeConscrypt) {
|
||||||
|
Security.addProvider(Conscrypt.newProvider())
|
||||||
|
conscrypt(ianaSuitesNew)
|
||||||
|
} else {
|
||||||
|
Client("Conscrypt", "Disabled", null, listOf())
|
||||||
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun rest(clients: List<Client>): List<SuiteId> {
|
||||||
|
// combine all ciphers to get these near the top
|
||||||
|
return clients.flatMap { it.enabled }
|
||||||
|
}
|
||||||
@@ -0,0 +1,58 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.Moshi
|
||||||
|
import okhttp3.Call
|
||||||
|
import okhttp3.OkHttpClient
|
||||||
|
import okhttp3.survey.ssllabs.SslLabsService
|
||||||
|
import okhttp3.survey.types.Client
|
||||||
|
import okhttp3.survey.types.SuiteId
|
||||||
|
import retrofit2.Retrofit
|
||||||
|
import retrofit2.converter.moshi.MoshiConverterFactory
|
||||||
|
|
||||||
|
class SslLabsScraper(
|
||||||
|
private val callFactory: Call.Factory,
|
||||||
|
) {
|
||||||
|
private val moshi = Moshi.Builder().build()
|
||||||
|
|
||||||
|
private val moshiConverterFactory = MoshiConverterFactory.create(moshi)
|
||||||
|
|
||||||
|
private val retrofit = Retrofit.Builder()
|
||||||
|
.baseUrl(SslLabsService.BASE_URL)
|
||||||
|
.addConverterFactory(moshiConverterFactory)
|
||||||
|
.callFactory(callFactory)
|
||||||
|
.build()
|
||||||
|
|
||||||
|
private val api = retrofit.create(SslLabsService::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 main() {
|
||||||
|
val client = OkHttpClient()
|
||||||
|
|
||||||
|
val scraper = SslLabsScraper(client)
|
||||||
|
|
||||||
|
println(scraper.query())
|
||||||
|
|
||||||
|
client.connectionPool.evictAll()
|
||||||
|
client.dispatcher.executorService.shutdown()
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
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/"
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
package okhttp3.survey.ssllabs
|
||||||
|
|
||||||
|
import com.squareup.moshi.JsonClass
|
||||||
|
|
||||||
|
|
||||||
|
@JsonClass(generateAdapter = true)
|
||||||
|
data class UserAgentCapabilities(
|
||||||
|
val abortsOnUnrecognizedName: Boolean,
|
||||||
|
val alpnProtocols: List<String>,
|
||||||
|
val ellipticCurves: List<Int>,
|
||||||
|
val handshakeFormat: String,
|
||||||
|
val hexHandshakeBytes: String,
|
||||||
|
val highestProtocol: Int,
|
||||||
|
val id: Int,
|
||||||
|
val isGrade0: Boolean,
|
||||||
|
val lowestProtocol: Int,
|
||||||
|
val maxDhBits: Int,
|
||||||
|
val maxRsaBits: Int,
|
||||||
|
val minDhBits: Int,
|
||||||
|
val minEcdsaBits: Int,
|
||||||
|
val minRsaBits: Int,
|
||||||
|
val name: String,
|
||||||
|
val npnProtocols: List<String>,
|
||||||
|
val platform: String?,
|
||||||
|
val requiresSha2: Boolean,
|
||||||
|
val signatureAlgorithms: List<Int>,
|
||||||
|
val suiteIds: List<Int>,
|
||||||
|
val suiteNames: List<String>,
|
||||||
|
val supportsCompression: Boolean,
|
||||||
|
val supportsNpn: Boolean,
|
||||||
|
val supportsRi: Boolean,
|
||||||
|
val supportsSni: Boolean,
|
||||||
|
val supportsStapling: Boolean,
|
||||||
|
val supportsTickets: Boolean,
|
||||||
|
val userAgent: String?,
|
||||||
|
val version: String
|
||||||
|
)
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.types
|
||||||
|
|
||||||
|
data class Client(
|
||||||
|
val userAgent: String,
|
||||||
|
val version: String,
|
||||||
|
val platform: String?,
|
||||||
|
val enabled: List<SuiteId> = listOf(),
|
||||||
|
val supported: List<SuiteId> = listOf()
|
||||||
|
) {
|
||||||
|
val nameAndVersion: String
|
||||||
|
get() = "$userAgent/$version"
|
||||||
|
}
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.types
|
||||||
|
|
||||||
|
|
||||||
|
data class Record(val java: String, val android: String)
|
||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (C) 2016 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.types
|
||||||
|
|
||||||
|
import okio.ByteString
|
||||||
|
|
||||||
|
data class SuiteId(val id: ByteString?, val name: String) {
|
||||||
|
fun matches(suiteId: SuiteId): Boolean {
|
||||||
|
return id == suiteId.id || name.substring(4) == suiteId.name.substring(4)
|
||||||
|
}
|
||||||
|
}
|
||||||
13
samples/tlssurvey/src/main/resources/okhttp_3_11.txt
Normal file
13
samples/tlssurvey/src/main/resources/okhttp_3_11.txt
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
18
samples/tlssurvey/src/main/resources/okhttp_3_13.txt
Normal file
18
samples/tlssurvey/src/main/resources/okhttp_3_13.txt
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
TLS_AES_128_GCM_SHA256
|
||||||
|
TLS_AES_256_GCM_SHA384
|
||||||
|
TLS_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_AES_128_CCM_SHA256
|
||||||
|
TLS_AES_256_CCM_8_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
16
samples/tlssurvey/src/main/resources/okhttp_3_14.txt
Normal file
16
samples/tlssurvey/src/main/resources/okhttp_3_14.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
TLS_AES_128_GCM_SHA256
|
||||||
|
TLS_AES_256_GCM_SHA384
|
||||||
|
TLS_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
15
samples/tlssurvey/src/main/resources/okhttp_3_9.txt
Normal file
15
samples/tlssurvey/src/main/resources/okhttp_3_9.txt
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
16
samples/tlssurvey/src/main/resources/okhttp_4_10.txt
Normal file
16
samples/tlssurvey/src/main/resources/okhttp_4_10.txt
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
TLS_AES_128_GCM_SHA256
|
||||||
|
TLS_AES_256_GCM_SHA384
|
||||||
|
TLS_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_128_GCM_SHA256
|
||||||
|
TLS_RSA_WITH_AES_256_GCM_SHA384
|
||||||
|
TLS_RSA_WITH_AES_128_CBC_SHA
|
||||||
|
TLS_RSA_WITH_AES_256_CBC_SHA
|
||||||
|
TLS_RSA_WITH_3DES_EDE_CBC_SHA
|
||||||
@@ -41,6 +41,7 @@ include(":samples:guide")
|
|||||||
include(":samples:simple-client")
|
include(":samples:simple-client")
|
||||||
include(":samples:slack")
|
include(":samples:slack")
|
||||||
include(":samples:static-server")
|
include(":samples:static-server")
|
||||||
|
include(":samples:tlssurvey")
|
||||||
include(":samples:unixdomainsockets")
|
include(":samples:unixdomainsockets")
|
||||||
|
|
||||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
|
|||||||
Reference in New Issue
Block a user