Skip to content

Instantly share code, notes, and snippets.

@swankjesse
Last active August 2, 2021 05:56
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save swankjesse/b4aac43f61ebfc1fcbaaf058e6c2d448 to your computer and use it in GitHub Desktop.
Save swankjesse/b4aac43f61ebfc1fcbaaf058e6c2d448 to your computer and use it in GitHub Desktop.
/*
* 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;
import java.io.IOException;
import java.security.Security;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import okio.ByteString;
import org.conscrypt.Conscrypt;
/**
* Organizes information on SSL cipher suite inclusion and precedence for this spreadsheet.
* https://docs.google.com/spreadsheets/d/1C3FdZSlCBq_-qrVwG1KDIzNIB3Hyg_rKAcgmSzOsHyQ/edit#gid=0
*/
public final class CipherSuiteSurvey {
/** Example: {@code 0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA Y [RFC4346]}. */
static final Pattern IANA_ROW_PATTERN = Pattern.compile("0x(\\w\\w),0x(\\w\\w)\\s+(\\w+).*");
/** Example: {@code 0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256}. */
static final Pattern SPREADSHEET_ROW_PATTERN = Pattern.compile("0x(\\w\\w\\w\\w)\\s+(\\w+)");
/** Example: {@code TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) 112}. */
static final Pattern SSL_LABS_ROW = Pattern.compile("(\\w+)\\s+\\(0x(\\w+)\\).*");
/** https://www.iana.org/assignments/tls-parameters/tls-parameters.xhtml */
static final List<SuiteId> IANA_SUITES = Arrays.asList(
parseIanaRow("0x00,0x00 TLS_NULL_WITH_NULL_NULL Y N [RFC5246]"),
parseIanaRow("0x00,0x01 TLS_RSA_WITH_NULL_MD5 Y N [RFC5246]"),
parseIanaRow("0x00,0x02 TLS_RSA_WITH_NULL_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x03 TLS_RSA_EXPORT_WITH_RC4_40_MD5 N N [RFC4346][RFC6347]"),
parseIanaRow("0x00,0x04 TLS_RSA_WITH_RC4_128_MD5 N N [RFC5246][RFC6347]"),
parseIanaRow("0x00,0x05 TLS_RSA_WITH_RC4_128_SHA N N [RFC5246][RFC6347]"),
parseIanaRow("0x00,0x06 TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5 Y N [RFC4346]"),
parseIanaRow("0x00,0x07 TLS_RSA_WITH_IDEA_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x08 TLS_RSA_EXPORT_WITH_DES40_CBC_SHA Y N [RFC4346]"),
parseIanaRow("0x00,0x09 TLS_RSA_WITH_DES_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x0A TLS_RSA_WITH_3DES_EDE_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x0B TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA Y N [RFC4346]"),
parseIanaRow("0x00,0x0C TLS_DH_DSS_WITH_DES_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x0D TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x0E TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA Y N [RFC4346]"),
parseIanaRow("0x00,0x0F TLS_DH_RSA_WITH_DES_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x10 TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x11 TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA Y N [RFC4346]"),
parseIanaRow("0x00,0x12 TLS_DHE_DSS_WITH_DES_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x13 TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x14 TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA Y N [RFC4346]"),
parseIanaRow("0x00,0x15 TLS_DHE_RSA_WITH_DES_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x16 TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x17 TLS_DH_anon_EXPORT_WITH_RC4_40_MD5 N N [RFC4346][RFC6347]"),
parseIanaRow("0x00,0x18 TLS_DH_anon_WITH_RC4_128_MD5 N N [RFC5246][RFC6347]"),
parseIanaRow("0x00,0x19 TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA Y N [RFC4346]"),
parseIanaRow("0x00,0x1A TLS_DH_anon_WITH_DES_CBC_SHA Y N [RFC5469]"),
parseIanaRow("0x00,0x1B TLS_DH_anon_WITH_3DES_EDE_CBC_SHA Y N [RFC5246]"),
//parseIanaRow("0x00,0x1C-1D Reserved to avoid conflicts with SSLv3 [RFC5246]"),
parseIanaRow("0x00,0x1E TLS_KRB5_WITH_DES_CBC_SHA Y N [RFC2712]"),
parseIanaRow("0x00,0x1F TLS_KRB5_WITH_3DES_EDE_CBC_SHA Y N [RFC2712]"),
parseIanaRow("0x00,0x20 TLS_KRB5_WITH_RC4_128_SHA N N [RFC2712][RFC6347]"),
parseIanaRow("0x00,0x21 TLS_KRB5_WITH_IDEA_CBC_SHA Y N [RFC2712]"),
parseIanaRow("0x00,0x22 TLS_KRB5_WITH_DES_CBC_MD5 Y N [RFC2712]"),
parseIanaRow("0x00,0x23 TLS_KRB5_WITH_3DES_EDE_CBC_MD5 Y N [RFC2712]"),
parseIanaRow("0x00,0x24 TLS_KRB5_WITH_RC4_128_MD5 N N [RFC2712][RFC6347]"),
parseIanaRow("0x00,0x25 TLS_KRB5_WITH_IDEA_CBC_MD5 Y N [RFC2712]"),
parseIanaRow("0x00,0x26 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA Y N [RFC2712]"),
parseIanaRow("0x00,0x27 TLS_KRB5_EXPORT_WITH_RC2_CBC_40_SHA Y N [RFC2712]"),
parseIanaRow("0x00,0x28 TLS_KRB5_EXPORT_WITH_RC4_40_SHA N N [RFC2712][RFC6347]"),
parseIanaRow("0x00,0x29 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5 Y N [RFC2712]"),
parseIanaRow("0x00,0x2A TLS_KRB5_EXPORT_WITH_RC2_CBC_40_MD5 Y N [RFC2712]"),
parseIanaRow("0x00,0x2B TLS_KRB5_EXPORT_WITH_RC4_40_MD5 N N [RFC2712][RFC6347]"),
parseIanaRow("0x00,0x2C TLS_PSK_WITH_NULL_SHA Y N [RFC4785]"),
parseIanaRow("0x00,0x2D TLS_DHE_PSK_WITH_NULL_SHA Y N [RFC4785]"),
parseIanaRow("0x00,0x2E TLS_RSA_PSK_WITH_NULL_SHA Y N [RFC4785]"),
parseIanaRow("0x00,0x2F TLS_RSA_WITH_AES_128_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x30 TLS_DH_DSS_WITH_AES_128_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x31 TLS_DH_RSA_WITH_AES_128_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x32 TLS_DHE_DSS_WITH_AES_128_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x33 TLS_DHE_RSA_WITH_AES_128_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x34 TLS_DH_anon_WITH_AES_128_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x35 TLS_RSA_WITH_AES_256_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x36 TLS_DH_DSS_WITH_AES_256_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x37 TLS_DH_RSA_WITH_AES_256_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x38 TLS_DHE_DSS_WITH_AES_256_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x39 TLS_DHE_RSA_WITH_AES_256_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x3A TLS_DH_anon_WITH_AES_256_CBC_SHA Y N [RFC5246]"),
parseIanaRow("0x00,0x3B TLS_RSA_WITH_NULL_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x3C TLS_RSA_WITH_AES_128_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x3D TLS_RSA_WITH_AES_256_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x3E TLS_DH_DSS_WITH_AES_128_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x3F TLS_DH_RSA_WITH_AES_128_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x40 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x41 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x42 TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x43 TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x44 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x45 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x46 TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA Y N [RFC5932]"),
//parseIanaRow("0x00,0x47-4F Reserved to avoid conflicts with deployed implementations [Pasi_Eronen]"),
//parseIanaRow("0x00,0x50-58 Reserved to avoid conflicts [Pasi Eronen, <pasi.eronen&nokia.com>, 2008-04-04. 2008-04-04]"),
//parseIanaRow("0x00,0x59-5C Reserved to avoid conflicts with deployed implementations [Pasi_Eronen]"),
//parseIanaRow("0x00,0x5D-5F Unassigned "),
//parseIanaRow("0x00,0x60-66 Reserved to avoid conflicts with widely deployed implementations [Pasi_Eronen]"),
parseIanaRow("0x00,0x67 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x68 TLS_DH_DSS_WITH_AES_256_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x69 TLS_DH_RSA_WITH_AES_256_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x6A TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x6B TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x6C TLS_DH_anon_WITH_AES_128_CBC_SHA256 Y N [RFC5246]"),
parseIanaRow("0x00,0x6D TLS_DH_anon_WITH_AES_256_CBC_SHA256 Y N [RFC5246]"),
//parseIanaRow("0x00,0x6E-83 Unassigned "),
parseIanaRow("0x00,0x84 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x85 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x86 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x87 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x88 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x89 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA Y N [RFC5932]"),
parseIanaRow("0x00,0x8A TLS_PSK_WITH_RC4_128_SHA N N [RFC4279][RFC6347]"),
parseIanaRow("0x00,0x8B TLS_PSK_WITH_3DES_EDE_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x8C TLS_PSK_WITH_AES_128_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x8D TLS_PSK_WITH_AES_256_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x8E TLS_DHE_PSK_WITH_RC4_128_SHA N N [RFC4279][RFC6347]"),
parseIanaRow("0x00,0x8F TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x90 TLS_DHE_PSK_WITH_AES_128_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x91 TLS_DHE_PSK_WITH_AES_256_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x92 TLS_RSA_PSK_WITH_RC4_128_SHA N N [RFC4279][RFC6347]"),
parseIanaRow("0x00,0x93 TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x94 TLS_RSA_PSK_WITH_AES_128_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x95 TLS_RSA_PSK_WITH_AES_256_CBC_SHA Y N [RFC4279]"),
parseIanaRow("0x00,0x96 TLS_RSA_WITH_SEED_CBC_SHA Y N [RFC4162]"),
parseIanaRow("0x00,0x97 TLS_DH_DSS_WITH_SEED_CBC_SHA Y N [RFC4162]"),
parseIanaRow("0x00,0x98 TLS_DH_RSA_WITH_SEED_CBC_SHA Y N [RFC4162]"),
parseIanaRow("0x00,0x99 TLS_DHE_DSS_WITH_SEED_CBC_SHA Y N [RFC4162]"),
parseIanaRow("0x00,0x9A TLS_DHE_RSA_WITH_SEED_CBC_SHA Y N [RFC4162]"),
parseIanaRow("0x00,0x9B TLS_DH_anon_WITH_SEED_CBC_SHA Y N [RFC4162]"),
parseIanaRow("0x00,0x9C TLS_RSA_WITH_AES_128_GCM_SHA256 Y N [RFC5288]"),
parseIanaRow("0x00,0x9D TLS_RSA_WITH_AES_256_GCM_SHA384 Y N [RFC5288]"),
parseIanaRow("0x00,0x9E TLS_DHE_RSA_WITH_AES_128_GCM_SHA256 Y Y [RFC5288]"),
parseIanaRow("0x00,0x9F TLS_DHE_RSA_WITH_AES_256_GCM_SHA384 Y Y [RFC5288]"),
parseIanaRow("0x00,0xA0 TLS_DH_RSA_WITH_AES_128_GCM_SHA256 Y N [RFC5288]"),
parseIanaRow("0x00,0xA1 TLS_DH_RSA_WITH_AES_256_GCM_SHA384 Y N [RFC5288]"),
parseIanaRow("0x00,0xA2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256 Y N [RFC5288]"),
parseIanaRow("0x00,0xA3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384 Y N [RFC5288]"),
parseIanaRow("0x00,0xA4 TLS_DH_DSS_WITH_AES_128_GCM_SHA256 Y N [RFC5288]"),
parseIanaRow("0x00,0xA5 TLS_DH_DSS_WITH_AES_256_GCM_SHA384 Y N [RFC5288]"),
parseIanaRow("0x00,0xA6 TLS_DH_anon_WITH_AES_128_GCM_SHA256 Y N [RFC5288]"),
parseIanaRow("0x00,0xA7 TLS_DH_anon_WITH_AES_256_GCM_SHA384 Y N [RFC5288]"),
parseIanaRow("0x00,0xA8 TLS_PSK_WITH_AES_128_GCM_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xA9 TLS_PSK_WITH_AES_256_GCM_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xAA TLS_DHE_PSK_WITH_AES_128_GCM_SHA256 Y Y [RFC5487]"),
parseIanaRow("0x00,0xAB TLS_DHE_PSK_WITH_AES_256_GCM_SHA384 Y Y [RFC5487]"),
parseIanaRow("0x00,0xAC TLS_RSA_PSK_WITH_AES_128_GCM_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xAD TLS_RSA_PSK_WITH_AES_256_GCM_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xAE TLS_PSK_WITH_AES_128_CBC_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xAF TLS_PSK_WITH_AES_256_CBC_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xB0 TLS_PSK_WITH_NULL_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xB1 TLS_PSK_WITH_NULL_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xB2 TLS_DHE_PSK_WITH_AES_128_CBC_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xB3 TLS_DHE_PSK_WITH_AES_256_CBC_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xB4 TLS_DHE_PSK_WITH_NULL_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xB5 TLS_DHE_PSK_WITH_NULL_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xB6 TLS_RSA_PSK_WITH_AES_128_CBC_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xB7 TLS_RSA_PSK_WITH_AES_256_CBC_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xB8 TLS_RSA_PSK_WITH_NULL_SHA256 Y N [RFC5487]"),
parseIanaRow("0x00,0xB9 TLS_RSA_PSK_WITH_NULL_SHA384 Y N [RFC5487]"),
parseIanaRow("0x00,0xBA TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xBB TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xBC TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xBD TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xBE TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xBF TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xC0 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xC1 TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xC2 TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xC3 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xC4 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 Y N [RFC5932]"),
parseIanaRow("0x00,0xC5 TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256 Y N [RFC5932]"),
//parseIanaRow("0x00,0xC6-FE Unassigned "),
parseIanaRow("0x00,0xFF TLS_EMPTY_RENEGOTIATION_INFO_SCSV Y N [RFC5746]"),
//parseIanaRow("0x01-12,* Unassigned "),
//parseIanaRow("0x13,0x00 Unassigned "),
parseIanaRow("0x13,0x01 TLS_AES_128_GCM_SHA256 Y Y [RFC8446]"),
parseIanaRow("0x13,0x02 TLS_AES_256_GCM_SHA384 Y Y [RFC8446]"),
parseIanaRow("0x13,0x03 TLS_CHACHA20_POLY1305_SHA256 Y Y [RFC8446]"),
parseIanaRow("0x13,0x04 TLS_AES_128_CCM_SHA256 Y Y [RFC8446]"),
parseIanaRow("0x13,0x05 TLS_AES_128_CCM_8_SHA256 Y N [RFC8446][IESG Action 2018-08-16]"),
//parseIanaRow("0x13,0x06-0xFF Unassigned "),
//parseIanaRow("0x14-55,* Unassigned "),
parseIanaRow("0x56,0x00 TLS_FALLBACK_SCSV Y N [RFC7507]"),
//parseIanaRow("0x56,0x01-0xC0,0x00 Unassigned "),
parseIanaRow("0xC0,0x01 TLS_ECDH_ECDSA_WITH_NULL_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x02 TLS_ECDH_ECDSA_WITH_RC4_128_SHA N N [RFC8422][RFC6347]"),
parseIanaRow("0xC0,0x03 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x04 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x05 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x06 TLS_ECDHE_ECDSA_WITH_NULL_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x07 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA N N [RFC8422][RFC6347]"),
parseIanaRow("0xC0,0x08 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x09 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x0A TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x0B TLS_ECDH_RSA_WITH_NULL_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x0C TLS_ECDH_RSA_WITH_RC4_128_SHA N N [RFC8422][RFC6347]"),
parseIanaRow("0xC0,0x0D TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x0E TLS_ECDH_RSA_WITH_AES_128_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x0F TLS_ECDH_RSA_WITH_AES_256_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x10 TLS_ECDHE_RSA_WITH_NULL_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x11 TLS_ECDHE_RSA_WITH_RC4_128_SHA N N [RFC8422][RFC6347]"),
parseIanaRow("0xC0,0x12 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x13 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x14 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x15 TLS_ECDH_anon_WITH_NULL_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x16 TLS_ECDH_anon_WITH_RC4_128_SHA N N [RFC8422][RFC6347]"),
parseIanaRow("0xC0,0x17 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x18 TLS_ECDH_anon_WITH_AES_128_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x19 TLS_ECDH_anon_WITH_AES_256_CBC_SHA Y N [RFC8422]"),
parseIanaRow("0xC0,0x1A TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x1B TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x1C TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x1D TLS_SRP_SHA_WITH_AES_128_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x1E TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x1F TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x20 TLS_SRP_SHA_WITH_AES_256_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x21 TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x22 TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA Y N [RFC5054]"),
parseIanaRow("0xC0,0x23 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 Y N [RFC5289]"),
parseIanaRow("0xC0,0x24 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 Y N [RFC5289]"),
parseIanaRow("0xC0,0x25 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256 Y N [RFC5289]"),
parseIanaRow("0xC0,0x26 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384 Y N [RFC5289]"),
parseIanaRow("0xC0,0x27 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256 Y N [RFC5289]"),
parseIanaRow("0xC0,0x28 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 Y N [RFC5289]"),
parseIanaRow("0xC0,0x29 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256 Y N [RFC5289]"),
parseIanaRow("0xC0,0x2A TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384 Y N [RFC5289]"),
parseIanaRow("0xC0,0x2B TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 Y Y [RFC5289]"),
parseIanaRow("0xC0,0x2C TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 Y Y [RFC5289]"),
parseIanaRow("0xC0,0x2D TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256 Y N [RFC5289]"),
parseIanaRow("0xC0,0x2E TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384 Y N [RFC5289]"),
parseIanaRow("0xC0,0x2F TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 Y Y [RFC5289]"),
parseIanaRow("0xC0,0x30 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 Y Y [RFC5289]"),
parseIanaRow("0xC0,0x31 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256 Y N [RFC5289]"),
parseIanaRow("0xC0,0x32 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384 Y N [RFC5289]"),
parseIanaRow("0xC0,0x33 TLS_ECDHE_PSK_WITH_RC4_128_SHA N N [RFC5489][RFC6347]"),
parseIanaRow("0xC0,0x34 TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA Y N [RFC5489]"),
parseIanaRow("0xC0,0x35 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA Y N [RFC5489]"),
parseIanaRow("0xC0,0x36 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA Y N [RFC5489]"),
parseIanaRow("0xC0,0x37 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256 Y N [RFC5489]"),
parseIanaRow("0xC0,0x38 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384 Y N [RFC5489]"),
parseIanaRow("0xC0,0x39 TLS_ECDHE_PSK_WITH_NULL_SHA Y N [RFC5489]"),
parseIanaRow("0xC0,0x3A TLS_ECDHE_PSK_WITH_NULL_SHA256 Y N [RFC5489]"),
parseIanaRow("0xC0,0x3B TLS_ECDHE_PSK_WITH_NULL_SHA384 Y N [RFC5489]"),
parseIanaRow("0xC0,0x3C TLS_RSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x3D TLS_RSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x3E TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x3F TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x40 TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x41 TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x42 TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x43 TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x44 TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x45 TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x46 TLS_DH_anon_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x47 TLS_DH_anon_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x48 TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x49 TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x4A TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x4B TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x4C TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x4D TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x4E TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x4F TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x50 TLS_RSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x51 TLS_RSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x52 TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x53 TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x54 TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x55 TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x56 TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x57 TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x58 TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x59 TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x5A TLS_DH_anon_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x5B TLS_DH_anon_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x5C TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x5D TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x5E TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x5F TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x60 TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x61 TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x62 TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x63 TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x64 TLS_PSK_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x65 TLS_PSK_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x66 TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x67 TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x68 TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x69 TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x6A TLS_PSK_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x6B TLS_PSK_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x6C TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x6D TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x6E TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x6F TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x70 TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256 Y N [RFC6209]"),
parseIanaRow("0xC0,0x71 TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384 Y N [RFC6209]"),
parseIanaRow("0xC0,0x72 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x73 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x74 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x75 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x76 TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x77 TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x78 TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x79 TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x7A TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x7B TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x7C TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x7D TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x7E TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x7F TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x80 TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x81 TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x82 TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x83 TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x84 TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x85 TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x86 TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x87 TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x88 TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x89 TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x8A TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x8B TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x8C TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x8D TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x8E TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x8F TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x90 TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x91 TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x92 TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x93 TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x94 TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x95 TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x96 TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x97 TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x98 TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x99 TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x9A TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 Y N [RFC6367]"),
parseIanaRow("0xC0,0x9B TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 Y N [RFC6367]"),
parseIanaRow("0xC0,0x9C TLS_RSA_WITH_AES_128_CCM Y N [RFC6655]"),
parseIanaRow("0xC0,0x9D TLS_RSA_WITH_AES_256_CCM Y N [RFC6655]"),
parseIanaRow("0xC0,0x9E TLS_DHE_RSA_WITH_AES_128_CCM Y Y [RFC6655]"),
parseIanaRow("0xC0,0x9F TLS_DHE_RSA_WITH_AES_256_CCM Y Y [RFC6655]"),
parseIanaRow("0xC0,0xA0 TLS_RSA_WITH_AES_128_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xA1 TLS_RSA_WITH_AES_256_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xA2 TLS_DHE_RSA_WITH_AES_128_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xA3 TLS_DHE_RSA_WITH_AES_256_CCM_8 N N [RFC6655]"),
parseIanaRow("0xC0,0xA4 TLS_PSK_WITH_AES_128_CCM Y N [RFC6655]"),
parseIanaRow("0xC0,0xA5 TLS_PSK_WITH_AES_256_CCM Y N [RFC6655]"),
parseIanaRow("0xC0,0xA6 TLS_DHE_PSK_WITH_AES_128_CCM Y Y [RFC6655]"),
parseIanaRow("0xC0,0xA7 TLS_DHE_PSK_WITH_AES_256_CCM Y Y [RFC6655]"),
parseIanaRow("0xC0,0xA8 TLS_PSK_WITH_AES_128_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xA9 TLS_PSK_WITH_AES_256_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xAA TLS_PSK_DHE_WITH_AES_128_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xAB TLS_PSK_DHE_WITH_AES_256_CCM_8 Y N [RFC6655]"),
parseIanaRow("0xC0,0xAC TLS_ECDHE_ECDSA_WITH_AES_128_CCM Y N [RFC7251]"),
parseIanaRow("0xC0,0xAD TLS_ECDHE_ECDSA_WITH_AES_256_CCM Y N [RFC7251]"),
parseIanaRow("0xC0,0xAE TLS_ECDHE_ECDSA_WITH_AES_128_CCM_8 Y N [RFC7251]"),
parseIanaRow("0xC0,0xAF TLS_ECDHE_ECDSA_WITH_AES_256_CCM_8 Y N [RFC7251]"),
parseIanaRow("0xC0,0xB0 TLS_ECCPWD_WITH_AES_128_GCM_SHA256 Y N [RFC-harkins-tls-dragonfly-03]"),
parseIanaRow("0xC0,0xB1 TLS_ECCPWD_WITH_AES_256_GCM_SHA384 Y N [RFC-harkins-tls-dragonfly-03]"),
parseIanaRow("0xC0,0xB2 TLS_ECCPWD_WITH_AES_128_CCM_SHA256 Y N [RFC-harkins-tls-dragonfly-03]"),
parseIanaRow("0xC0,0xB3 TLS_ECCPWD_WITH_AES_256_CCM_SHA384 Y N [RFC-harkins-tls-dragonfly-03]"),
parseIanaRow("0xC0,0xB4 TLS_SHA256_SHA256 Y N [draft-camwinget-tls-ts13-macciphersuites]"),
parseIanaRow("0xC0,0xB5 TLS_SHA384_SHA384 Y N [draft-camwinget-tls-ts13-macciphersuites]"),
//parseIanaRow("0xC0,0xB6-FF Unassigned "),
parseIanaRow("0xC1,0x00 TLS_GOSTR341112_256_WITH_KUZNYECHIK_CTR_OMAC N N [draft-smyshlyaev-tls12-gost-suites]"),
parseIanaRow("0xC1,0x01 TLS_GOSTR341112_256_WITH_MAGMA_CTR_OMAC N N [draft-smyshlyaev-tls12-gost-suites]"),
parseIanaRow("0xC1,0x02 TLS_GOSTR341112_256_WITH_28147_CNT_IMIT N N [draft-smyshlyaev-tls12-gost-suites]"),
//parseIanaRow("0xC1,0x03-FF Unassigned "),
//parseIanaRow("0xC2-CB,* Unassigned "),
//parseIanaRow("0xCC,0x00-A7 Unassigned "),
parseIanaRow("0xCC,0xA8 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 Y Y [RFC7905]"),
parseIanaRow("0xCC,0xA9 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 Y Y [RFC7905]"),
parseIanaRow("0xCC,0xAA TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 Y Y [RFC7905]"),
parseIanaRow("0xCC,0xAB TLS_PSK_WITH_CHACHA20_POLY1305_SHA256 Y N [RFC7905]"),
parseIanaRow("0xCC,0xAC TLS_ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 Y Y [RFC7905]"),
parseIanaRow("0xCC,0xAD TLS_DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 Y Y [RFC7905]"),
parseIanaRow("0xCC,0xAE TLS_RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 Y N [RFC7905]"),
//parseIanaRow("0xCC,0xAF-FF Unassigned "),
//parseIanaRow("0xCD-CF,* Unassigned "),
//parseIanaRow("0xD0,0x00 Unassigned "),
parseIanaRow("0xD0,0x01 TLS_ECDHE_PSK_WITH_AES_128_GCM_SHA256 Y Y [RFC8442]"),
parseIanaRow("0xD0,0x02 TLS_ECDHE_PSK_WITH_AES_256_GCM_SHA384 Y Y [RFC8442]"),
parseIanaRow("0xD0,0x03 TLS_ECDHE_PSK_WITH_AES_128_CCM_8_SHA256 Y N [RFC8442]"),
//parseIanaRow("0xD0,0x04 Unassigned "),
parseIanaRow("0xD0,0x05 TLS_ECDHE_PSK_WITH_AES_128_CCM_SHA256 Y Y [RFC8442]"),
//parseIanaRow("0xD0,0x06-FF Unassigned "),
//parseIanaRow("0xD1-FD,* Unassigned "),
//parseIanaRow("0xFE,0x00-FD Unassigned "),
//parseIanaRow("0xFE,0xFE-FF Reserved to avoid conflicts with widely deployed implementations [Pasi_Eronen]"),
//parseIanaRow("0xFF,0x00-FF Reserved for Private Use [RFC8446]")
// TLS 1.3 suites.
// https://tools.ietf.org/html/rfc8446#appendix-B.4
parseIanaRow("0x13,0x01 TLS_AES_128_GCM_SHA256"),
parseIanaRow("0x13,0x02 TLS_AES_256_GCM_SHA384"),
parseIanaRow("0x13,0x03 TLS_CHACHA20_POLY1305_SHA256"),
parseIanaRow("0x13,0x04 TLS_AES_128_CCM_SHA256"),
parseIanaRow("0x13,0x05 TLS_AES_128_CCM_8_SHA256")
);
static final Map<SuiteId, Record> RECORDS = new LinkedHashMap<>();
static {
addRecord(RECORDS, "0x1301 TLS_AES_128_GCM_SHA256", "", "");
addRecord(RECORDS, "0x1302 TLS_AES_256_GCM_SHA384", "", "");
addRecord(RECORDS, "0x1303 TLS_CHACHA20_POLY1305_SHA256", "", "");
addRecord(RECORDS, "0x1304 TLS_AES_128_CCM_SHA256", "", "");
addRecord(RECORDS, "0x1305 TLS_AES_128_CCM_8_SHA256", "", "");
addRecord(RECORDS, "0xc02b TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256", "1", "0");
addRecord(RECORDS, "0xc02f TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256", "8", "3");
addRecord(RECORDS, "0xc02c TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384", "0", "1");
addRecord(RECORDS, "0xc030 TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384", "2", "4");
addRecord(RECORDS, "0xcca9 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "", "2");
addRecord(RECORDS, "0xcca8 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "", "5");
addRecord(RECORDS, "0xcc14 TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256", "", "");
addRecord(RECORDS, "0xcc13 TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "", "");
addRecord(RECORDS, "0xc009 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA", "35", "6");
addRecord(RECORDS, "0xc013 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA", "36", "8");
addRecord(RECORDS, "0xc00a TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA", "21", "7");
addRecord(RECORDS, "0xc014 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA", "22", "9");
addRecord(RECORDS, "0x0033 TLS_DHE_RSA_WITH_AES_128_CBC_SHA", "40", "");
addRecord(RECORDS, "0x0039 TLS_DHE_RSA_WITH_AES_256_CBC_SHA", "26", "");
addRecord(RECORDS, "0x009c TLS_RSA_WITH_AES_128_GCM_SHA256", "9", "10");
addRecord(RECORDS, "0x009d TLS_RSA_WITH_AES_256_GCM_SHA384", "3", "11");
addRecord(RECORDS, "0x002f TLS_RSA_WITH_AES_128_CBC_SHA", "37", "12");
addRecord(RECORDS, "0x0035 TLS_RSA_WITH_AES_256_CBC_SHA", "23", "13");
addRecord(RECORDS, "0x000a SSL_RSA_WITH_3DES_EDE_CBC_SHA", "44", "□");
addRecord(RECORDS, "0x009e TLS_DHE_RSA_WITH_AES_128_GCM_SHA256", "12", "");
addRecord(RECORDS, "0xc007 TLS_ECDHE_ECDSA_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0xc011 TLS_ECDHE_RSA_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0x0032 TLS_DHE_DSS_WITH_AES_128_CBC_SHA", "41", "");
addRecord(RECORDS, "0x0005 SSL_RSA_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0x0004 SSL_RSA_WITH_RC4_128_MD5", "", "");
addRecord(RECORDS, "0x00ff TLS_EMPTY_RENEGOTIATION_INFO_SCSV", "49", "14");
addRecord(RECORDS, "0x0088 TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA", "", "");
addRecord(RECORDS, "0x0087 TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA", "", "");
addRecord(RECORDS, "0xcc15 TLS_DHE_RSA_WITH_CHACHA20_POLY1305_SHA256", "", "");
addRecord(RECORDS, "0x0038 TLS_DHE_DSS_WITH_AES_256_CBC_SHA", "27", "");
addRecord(RECORDS, "0xc00f TLS_ECDH_RSA_WITH_AES_256_CBC_SHA", "25", "");
addRecord(RECORDS, "0xc005 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA", "24", "");
addRecord(RECORDS, "0x0084 TLS_RSA_WITH_CAMELLIA_256_CBC_SHA", "", "");
addRecord(RECORDS, "0x0045 TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA", "", "");
addRecord(RECORDS, "0x0044 TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA", "", "");
addRecord(RECORDS, "0xc00c TLS_ECDH_RSA_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0xc00e TLS_ECDH_RSA_WITH_AES_128_CBC_SHA", "39", "");
addRecord(RECORDS, "0xc002 TLS_ECDH_ECDSA_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0xc004 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA", "38", "");
addRecord(RECORDS, "0x0096 TLS_RSA_WITH_SEED_CBC_SHA", "", "");
addRecord(RECORDS, "0x0041 TLS_RSA_WITH_CAMELLIA_128_CBC_SHA", "", "");
addRecord(RECORDS, "0xc008 TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA", "42", "");
addRecord(RECORDS, "0xc012 TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA", "43", "");
addRecord(RECORDS, "0x0016 SSL_DHE_RSA_WITH_3DES_EDE_CBC_SHA", "47", "");
addRecord(RECORDS, "0x0013 SSL_DHE_DSS_WITH_3DES_EDE_CBC_SHA", "48", "");
addRecord(RECORDS, "0xc00d TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA", "46", "");
addRecord(RECORDS, "0xc003 TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA", "45", "");
addRecord(RECORDS, "0xc024 TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384", "14", "□");
addRecord(RECORDS, "0xc028 TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384", "15", "□");
addRecord(RECORDS, "0x003d TLS_RSA_WITH_AES_256_CBC_SHA256", "16", "□");
addRecord(RECORDS, "0xc026 TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384", "17", "");
addRecord(RECORDS, "0xc02a TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384", "18", "");
addRecord(RECORDS, "0x006b TLS_DHE_RSA_WITH_AES_256_CBC_SHA256", "19", "");
addRecord(RECORDS, "0x006a TLS_DHE_DSS_WITH_AES_256_CBC_SHA256", "20", "");
addRecord(RECORDS, "0xc023 TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256", "28", "□");
addRecord(RECORDS, "0xc027 TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256", "29", "□");
addRecord(RECORDS, "0x009f TLS_DHE_RSA_WITH_AES_256_GCM_SHA384", "6", "");
addRecord(RECORDS, "0x003c TLS_RSA_WITH_AES_128_CBC_SHA256", "30", "□");
addRecord(RECORDS, "0xc025 TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256", "31", "");
addRecord(RECORDS, "0xc029 TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256", "32", "");
addRecord(RECORDS, "0x0067 TLS_DHE_RSA_WITH_AES_128_CBC_SHA256", "33", "");
addRecord(RECORDS, "0x0040 TLS_DHE_DSS_WITH_AES_128_CBC_SHA256", "34", "");
addRecord(RECORDS, "0xc02e TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384", "4", "");
addRecord(RECORDS, "0xc032 TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384", "5", "");
addRecord(RECORDS, "0x00a3 TLS_DHE_DSS_WITH_AES_256_GCM_SHA384", "7", "");
addRecord(RECORDS, "0xc02d TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256", "10", "");
addRecord(RECORDS, "0xc031 TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256", "11", "");
addRecord(RECORDS, "0x00a2 TLS_DHE_DSS_WITH_AES_128_GCM_SHA256", "13", "");
addRecord(RECORDS, "0x00a7 TLS_DH_anon_WITH_AES_256_GCM_SHA384", "□", "");
addRecord(RECORDS, "0x00a6 TLS_DH_anon_WITH_AES_128_GCM_SHA256", "□", "");
addRecord(RECORDS, "0x006d TLS_DH_anon_WITH_AES_256_CBC_SHA256", "□", "");
addRecord(RECORDS, "0xc019 TLS_ECDH_anon_WITH_AES_256_CBC_SHA", "□", "");
addRecord(RECORDS, "0x003a TLS_DH_anon_WITH_AES_256_CBC_SHA", "□", "");
addRecord(RECORDS, "0x006c TLS_DH_anon_WITH_AES_128_CBC_SHA256", "□", "");
addRecord(RECORDS, "0xc018 TLS_ECDH_anon_WITH_AES_128_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0034 TLS_DH_anon_WITH_AES_128_CBC_SHA", "□", "");
addRecord(RECORDS, "0xc016 TLS_ECDH_anon_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0x0018 SSL_DH_anon_WITH_RC4_128_MD5", "", "");
addRecord(RECORDS, "0xc017 TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA", "□", "");
addRecord(RECORDS, "0x001b SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", "□", "");
addRecord(RECORDS, "0x003b TLS_RSA_WITH_NULL_SHA256", "□", "");
addRecord(RECORDS, "0xc006 TLS_ECDHE_ECDSA_WITH_NULL_SHA", "□", "");
addRecord(RECORDS, "0xc010 TLS_ECDHE_RSA_WITH_NULL_SHA", "□", "");
addRecord(RECORDS, "0x0002 SSL_RSA_WITH_NULL_SHA", "□", "");
addRecord(RECORDS, "0xc001 TLS_ECDH_ECDSA_WITH_NULL_SHA", "□", "");
addRecord(RECORDS, "0xc00b TLS_ECDH_RSA_WITH_NULL_SHA", "□", "");
addRecord(RECORDS, "0xc015 TLS_ECDH_anon_WITH_NULL_SHA", "□", "");
addRecord(RECORDS, "0x0001 SSL_RSA_WITH_NULL_MD5", "□", "");
addRecord(RECORDS, "0x0009 SSL_RSA_WITH_DES_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0015 SSL_DHE_RSA_WITH_DES_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0012 SSL_DHE_DSS_WITH_DES_CBC_SHA", "□", "");
addRecord(RECORDS, "0x001a SSL_DH_anon_WITH_DES_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0003 SSL_RSA_EXPORT_WITH_RC4_40_MD5", "", "");
addRecord(RECORDS, "0x0017 SSL_DH_anon_EXPORT_WITH_RC4_40_MD5", "", "");
addRecord(RECORDS, "0x0008 SSL_RSA_EXPORT_WITH_DES40_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0014 SSL_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0011 SSL_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0019 SSL_DH_anon_EXPORT_WITH_DES40_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0020 TLS_KRB5_WITH_RC4_128_SHA", "", "");
addRecord(RECORDS, "0x0024 TLS_KRB5_WITH_RC4_128_MD5", "", "");
addRecord(RECORDS, "0x001f TLS_KRB5_WITH_3DES_EDE_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0023 TLS_KRB5_WITH_3DES_EDE_CBC_MD5", "□", "");
addRecord(RECORDS, "0x001e TLS_KRB5_WITH_DES_CBC_SHA", "□", "");
addRecord(RECORDS, "0x0022 TLS_KRB5_WITH_DES_CBC_MD5", "□", "");
addRecord(RECORDS, "0x0028 TLS_KRB5_EXPORT_WITH_RC4_40_SHA", "", "");
addRecord(RECORDS, "0x002b TLS_KRB5_EXPORT_WITH_RC4_40_MD5", "", "");
addRecord(RECORDS, "0x0026 TLS_KRB5_EXPORT_WITH_DES_CBC_40_SHA", "□", "");
addRecord(RECORDS, "0x0029 TLS_KRB5_EXPORT_WITH_DES_CBC_40_MD5", "□", "");
addRecord(RECORDS, "0xc035 TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA", "", "□");
addRecord(RECORDS, "0xc036 TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA", "", "□");
addRecord(RECORDS, "0x5600 TLS_FALLBACK_SCSV", "", "□");
addRecord(RECORDS, "0x008b TLS_PSK_WITH_3DES_EDE_CBC_SHA", "", "");
addRecord(RECORDS, "0x008c TLS_PSK_WITH_AES_128_CBC_SHA", "", "□");
addRecord(RECORDS, "0x008d TLS_PSK_WITH_AES_256_CBC_SHA", "", "□");
addRecord(RECORDS, "0x008a TLS_PSK_WITH_RC4_128_SHA", "", "");
}
static final List<Client> CLIENTS = Arrays.asList(
conscrypt()
//currentVm(),
//currentOkHttp(),
//new Client("SQ")
// .enabled(
// suiteId(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384),
// suiteId(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256),
// suiteId(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA),
// suiteId(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA),
// suiteId(CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256),
// suiteId(CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384),
// suiteId(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA256),
// suiteId(CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA256),
// suiteId(CipherSuite.TLS_RSA_WITH_AES_128_CBC_SHA),
// suiteId(CipherSuite.TLS_RSA_WITH_AES_256_CBC_SHA),
// suiteId(CipherSuite.TLS_RSA_WITH_AES_128_GCM_SHA256),
// suiteId(CipherSuite.TLS_RSA_WITH_AES_256_GCM_SHA384)),
//new Client("Firefox 65")
// .enabled(
// parseSslLabsRow("TLS_AES_128_GCM_SHA256 (0x1301) Forward Secrecy 128"),
// parseSslLabsRow("TLS_CHACHA20_POLY1305_SHA256 (0x1303) Forward Secrecy 256"),
// parseSslLabsRow("TLS_AES_256_GCM_SHA384 (0x1302) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA (0xc00a) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA (0xc009) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Forward Secrecy 256"),
// parseSslLabsRow("TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x33) Forward Secrecy 128"),
// parseSslLabsRow("TLS_DHE_RSA_WITH_AES_256_CBC_SHA (0x39) Forward Secrecy 256"),
// parseSslLabsRow("TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) WEAK 128"),
// parseSslLabsRow("TLS_RSA_WITH_AES_256_CBC_SHA (0x35) WEAK 256"),
// parseSslLabsRow("TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) WEAK 112")),
//new Client("Chrome 72")
// .enabled(
// //parseSslLabsRow("TLS_GREASE_2A (0x2a2a) -"),
// parseSslLabsRow("TLS_AES_128_GCM_SHA256 (0x1301) Forward Secrecy 128"),
// parseSslLabsRow("TLS_AES_256_GCM_SHA384 (0x1302) Forward Secrecy 256"),
// parseSslLabsRow("TLS_CHACHA20_POLY1305_SHA256 (0x1303) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Forward Secrecy 256"),
// parseSslLabsRow("TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) WEAK 128"),
// parseSslLabsRow("TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d) WEAK 256"),
// parseSslLabsRow("TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) WEAK 128"),
// parseSslLabsRow("TLS_RSA_WITH_AES_256_CBC_SHA (0x35) WEAK 256"),
// parseSslLabsRow("TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) WEAK 112")),
//new Client("Chrome 64")
// .enabled(
// //parseSslLabsRow("TLS_GREASE_1A (0x1a1a) -"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 (0xc02b) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256 (0xc02f) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 (0xc02c) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (0xc030) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca9) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 (0xcca8) Forward Secrecy 256"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA (0xc013) Forward Secrecy 128"),
// parseSslLabsRow("TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA (0xc014) Forward Secrecy 256"),
// parseSslLabsRow("TLS_RSA_WITH_AES_128_GCM_SHA256 (0x9c) WEAK 128"),
// parseSslLabsRow("TLS_RSA_WITH_AES_256_GCM_SHA384 (0x9d) WEAK 256"),
// parseSslLabsRow("TLS_RSA_WITH_AES_128_CBC_SHA (0x2f) WEAK 128"),
// parseSslLabsRow("TLS_RSA_WITH_AES_256_CBC_SHA (0x35) WEAK 256"),
// parseSslLabsRow("TLS_RSA_WITH_3DES_EDE_CBC_SHA (0xa) WEAK 112"))
);
public static void main(String[] args) {
for (Client client : CLIENTS) {
for (SuiteId suiteId : client.enabled) {
if (!RECORDS.containsKey(suiteId)) {
System.out.println("Unexpected suite " + suiteId + " in " + client.name);
}
}
for (SuiteId suiteId : client.disabled) {
if (!RECORDS.containsKey(suiteId)) {
System.out.println("Unexpected suite " + suiteId + " in " + client.name);
}
}
}
System.out.print("id");
System.out.print("\tname");
for (Client client : CLIENTS) {
System.out.print("\t");
System.out.print(client.name);
}
System.out.println();
for (SuiteId suiteId : RECORDS.keySet()) {
System.out.print("0x");
System.out.print(suiteId.id.hex());
System.out.print("\t");
System.out.print(suiteId.name);
for (Client client : CLIENTS) {
System.out.print("\t");
int index = client.enabled.indexOf(suiteId);
if (index != -1) {
System.out.print(index);
} else if (client.disabled.contains(suiteId)) {
System.out.print("□");
}
}
System.out.println();
}
System.out.println();
for (SuiteId suiteId : IANA_SUITES) {
Record record = RECORDS.get(suiteId);
StringBuilder declaration = new StringBuilder();
declaration.append(" ");
if (record == null || (record.java.trim().isEmpty() && record.android.trim().isEmpty())) {
declaration.append("// ");
}
declaration.append("public static final CipherSuite ");
declaration.append(suiteId.name);
declaration.append(" = of(\"");
declaration.append(suiteId.name);
declaration.append("\", ");
declaration.append("0x");
declaration.append(suiteId.id.hex());
declaration.append(");");
System.out.println(declaration.toString());
}
}
static SuiteId parseIanaRow(String s) {
Matcher matcher = IANA_ROW_PATTERN.matcher(s);
if (!matcher.matches()) throw new IllegalArgumentException(s);
ByteString id = ByteString.decodeHex(matcher.group(1) + matcher.group(2));
return new SuiteId(id, matcher.group(3));
}
static void addRecord(Map<SuiteId, Record> records, String s, String java, String android) {
Matcher matcher = SPREADSHEET_ROW_PATTERN.matcher(s);
if (!matcher.matches()) throw new IllegalArgumentException(s);
ByteString id = ByteString.decodeHex(matcher.group(1));
SuiteId suiteId = new SuiteId(id, matcher.group(2));
records.put(suiteId, new Record(java, android));
}
static SuiteId parseSslLabsRow(String s) {
Matcher matcher = SSL_LABS_ROW.matcher(s);
if (!matcher.matches()) throw new IllegalArgumentException(s);
String hexId = matcher.group(2);
while (hexId.length() < 4) {
hexId = "0" + hexId;
}
ByteString id = ByteString.decodeHex(hexId);
return new SuiteId(id, matcher.group(1));
}
private static Client currentOkHttp() {
List<SuiteId> supportedSuites = new ArrayList<>();
for (CipherSuite suite : ConnectionSpec.MODERN_TLS.cipherSuites()) {
supportedSuites.add(fromJavaName(suite.javaName()));
}
List<SuiteId> enabledSuites = new ArrayList<>();
for (CipherSuite suite : ConnectionSpec.COMPATIBLE_TLS.cipherSuites()) {
enabledSuites.add(fromJavaName(suite.javaName()));
}
return new Client("OkHttp", enabledSuites, supportedSuites);
}
private static Client currentVm() {
String name = System.getProperty("java.vm.name") + " " + System.getProperty("java.version");
return systemDefault(name);
}
private static Client conscrypt() {
Security.addProvider(Conscrypt.newProvider());
Conscrypt.Version version = Conscrypt.version();
return systemDefault("Conscrypt " + version.major() + "." + version.minor());
}
private static Client systemDefault(String name) {
try {
SSLSocketFactory socketFactory = (SSLSocketFactory) SSLSocketFactory.getDefault();
SSLSocket sslSocket = (SSLSocket) socketFactory.createSocket();
List<SuiteId> supportedSuites = new ArrayList<>();
for (String suite : sslSocket.getSupportedCipherSuites()) {
supportedSuites.add(fromJavaName(suite));
}
List<SuiteId> enabledSuites = new ArrayList<>();
for (String suite : sslSocket.getEnabledCipherSuites()) {
enabledSuites.add(fromJavaName(suite));
}
return new Client(name, enabledSuites, supportedSuites);
} catch (IOException e) {
throw new RuntimeException(e);
}
}
private static SuiteId suiteId(CipherSuite cipherSuite) {
for (SuiteId ianaSuite : IANA_SUITES) {
if (ianaSuite.name.equals(cipherSuite.javaName())) return ianaSuite;
}
throw new UnsupportedOperationException();
}
private static SuiteId fromJavaName(String javaName) {
for (SuiteId suiteId : IANA_SUITES) {
String alternateName = "TLS_" + javaName.substring(4);
if (suiteId.name.equals(javaName) || suiteId.name.equals(alternateName)) {
return suiteId;
}
}
throw new IllegalArgumentException("No such suite: " + javaName);
}
static class Client {
final String name;
final List<SuiteId> enabled;
final List<SuiteId> disabled;
public Client(String name) {
this(name, Collections.<SuiteId>emptyList(), Collections.<SuiteId>emptyList());
}
private Client(String name, List<SuiteId> enabled, List<SuiteId> disabled) {
this.name = name;
this.enabled = Collections.unmodifiableList(new ArrayList<>(enabled));
this.disabled = Collections.unmodifiableList(new ArrayList<>(disabled));
}
public Client enabled(SuiteId... suites) {
return new Client(name, Arrays.asList(suites), disabled);
}
public Client disabled(SuiteId... suites) {
return new Client(name, enabled, Arrays.asList(suites));
}
}
static class SuiteId {
final ByteString id;
final String name;
public SuiteId(ByteString id, String name) {
this.id = id;
this.name = name;
}
@Override public boolean equals(Object other) {
return other instanceof SuiteId
&& ((SuiteId) other).id.equals(id);
}
@Override public int hashCode() {
return id.hashCode();
}
@Override public String toString() {
return id.hex() + "/" + name;
}
}
static class Record {
final String java;
final String android;
public Record(String java, String android) {
this.java = java;
this.android = android;
}
}
}
@swankjesse
Copy link
Author

pbpaste | Rip.java '(.*\t.*)\t(.*)\t(.*)' '      addRecord(RECORDS, "%2$s", "%3$s", "%4$s");' | pbcopy

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment