Home | History | Annotate | Download | only in ssl
      1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style license that can be
      3 // found in the LICENSE file.
      4 
      5 #include "net/ssl/ssl_cipher_suite_names.h"
      6 
      7 #include <stdlib.h>
      8 
      9 #include "base/logging.h"
     10 #include "base/strings/string_number_conversions.h"
     11 #include "base/strings/string_util.h"
     12 #include "net/ssl/ssl_connection_status_flags.h"
     13 
     14 // Rather than storing the names of all the ciphersuites we eliminate the
     15 // redundancy and break each cipher suite into a key exchange method, cipher
     16 // and mac. For all the ciphersuites in the IANA registry, we extract each of
     17 // those components from the name, number them and pack the result into a
     18 // 16-bit number thus:
     19 //   (MSB to LSB)
     20 //   <3 bits> unused
     21 //   <5 bits> key exchange
     22 //   <5 bits> cipher
     23 //   <3 bits> mac
     24 
     25 // The following tables were generated by ssl_cipher_suite_names_generate.go,
     26 // found in the same directory as this file.
     27 
     28 struct CipherSuite {
     29   uint16 cipher_suite, encoded;
     30 };
     31 
     32 static const struct CipherSuite kCipherSuites[] = {
     33   {0x0, 0x0},  // TLS_NULL_WITH_NULL_NULL
     34   {0x1, 0x101},  // TLS_RSA_WITH_NULL_MD5
     35   {0x2, 0x102},  // TLS_RSA_WITH_NULL_SHA
     36   {0x3, 0x209},  // TLS_RSA_EXPORT_WITH_RC4_40_MD5
     37   {0x4, 0x111},  // TLS_RSA_WITH_RC4_128_MD5
     38   {0x5, 0x112},  // TLS_RSA_WITH_RC4_128_SHA
     39   {0x6, 0x219},  // TLS_RSA_EXPORT_WITH_RC2_CBC_40_MD5
     40   {0x7, 0x122},  // TLS_RSA_WITH_IDEA_CBC_SHA
     41   {0x8, 0x22a},  // TLS_RSA_EXPORT_WITH_DES40_CBC_SHA
     42   {0x9, 0x132},  // TLS_RSA_WITH_DES_CBC_SHA
     43   {0xa, 0x13a},  // TLS_RSA_WITH_3DES_EDE_CBC_SHA
     44   {0xb, 0x32a},  // TLS_DH_DSS_EXPORT_WITH_DES40_CBC_SHA
     45   {0xc, 0x432},  // TLS_DH_DSS_WITH_DES_CBC_SHA
     46   {0xd, 0x43a},  // TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA
     47   {0xe, 0x52a},  // TLS_DH_RSA_EXPORT_WITH_DES40_CBC_SHA
     48   {0xf, 0x632},  // TLS_DH_RSA_WITH_DES_CBC_SHA
     49   {0x10, 0x63a},  // TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA
     50   {0x11, 0x72a},  // TLS_DHE_DSS_EXPORT_WITH_DES40_CBC_SHA
     51   {0x12, 0x832},  // TLS_DHE_DSS_WITH_DES_CBC_SHA
     52   {0x13, 0x83a},  // TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA
     53   {0x14, 0x92a},  // TLS_DHE_RSA_EXPORT_WITH_DES40_CBC_SHA
     54   {0x15, 0xa32},  // TLS_DHE_RSA_WITH_DES_CBC_SHA
     55   {0x16, 0xa3a},  // TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA
     56   {0x17, 0xb09},  // TLS_DH_anon_EXPORT_WITH_RC4_40_MD5
     57   {0x18, 0xc11},  // TLS_DH_anon_WITH_RC4_128_MD5
     58   {0x19, 0xb2a},  // TLS_DH_anon_EXPORT_WITH_DES40_CBC_SHA
     59   {0x1a, 0xc32},  // TLS_DH_anon_WITH_DES_CBC_SHA
     60   {0x1b, 0xc3a},  // TLS_DH_anon_WITH_3DES_EDE_CBC_SHA
     61   {0x2f, 0x142},  // TLS_RSA_WITH_AES_128_CBC_SHA
     62   {0x30, 0x442},  // TLS_DH_DSS_WITH_AES_128_CBC_SHA
     63   {0x31, 0x642},  // TLS_DH_RSA_WITH_AES_128_CBC_SHA
     64   {0x32, 0x842},  // TLS_DHE_DSS_WITH_AES_128_CBC_SHA
     65   {0x33, 0xa42},  // TLS_DHE_RSA_WITH_AES_128_CBC_SHA
     66   {0x34, 0xc42},  // TLS_DH_anon_WITH_AES_128_CBC_SHA
     67   {0x35, 0x14a},  // TLS_RSA_WITH_AES_256_CBC_SHA
     68   {0x36, 0x44a},  // TLS_DH_DSS_WITH_AES_256_CBC_SHA
     69   {0x37, 0x64a},  // TLS_DH_RSA_WITH_AES_256_CBC_SHA
     70   {0x38, 0x84a},  // TLS_DHE_DSS_WITH_AES_256_CBC_SHA
     71   {0x39, 0xa4a},  // TLS_DHE_RSA_WITH_AES_256_CBC_SHA
     72   {0x3a, 0xc4a},  // TLS_DH_anon_WITH_AES_256_CBC_SHA
     73   {0x3b, 0x103},  // TLS_RSA_WITH_NULL_SHA256
     74   {0x3c, 0x143},  // TLS_RSA_WITH_AES_128_CBC_SHA256
     75   {0x3d, 0x14b},  // TLS_RSA_WITH_AES_256_CBC_SHA256
     76   {0x3e, 0x443},  // TLS_DH_DSS_WITH_AES_128_CBC_SHA256
     77   {0x3f, 0x643},  // TLS_DH_RSA_WITH_AES_128_CBC_SHA256
     78   {0x40, 0x843},  // TLS_DHE_DSS_WITH_AES_128_CBC_SHA256
     79   {0x41, 0x152},  // TLS_RSA_WITH_CAMELLIA_128_CBC_SHA
     80   {0x42, 0x452},  // TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA
     81   {0x43, 0x652},  // TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA
     82   {0x44, 0x852},  // TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA
     83   {0x45, 0xa52},  // TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA
     84   {0x46, 0xc52},  // TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA
     85   {0x67, 0xa43},  // TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
     86   {0x68, 0x44b},  // TLS_DH_DSS_WITH_AES_256_CBC_SHA256
     87   {0x69, 0x64b},  // TLS_DH_RSA_WITH_AES_256_CBC_SHA256
     88   {0x6a, 0x84b},  // TLS_DHE_DSS_WITH_AES_256_CBC_SHA256
     89   {0x6b, 0xa4b},  // TLS_DHE_RSA_WITH_AES_256_CBC_SHA256
     90   {0x6c, 0xc43},  // TLS_DH_anon_WITH_AES_128_CBC_SHA256
     91   {0x6d, 0xc4b},  // TLS_DH_anon_WITH_AES_256_CBC_SHA256
     92   {0x84, 0x15a},  // TLS_RSA_WITH_CAMELLIA_256_CBC_SHA
     93   {0x85, 0x45a},  // TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA
     94   {0x86, 0x65a},  // TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA
     95   {0x87, 0x85a},  // TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA
     96   {0x88, 0xa5a},  // TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA
     97   {0x89, 0xc5a},  // TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA
     98   {0x96, 0x162},  // TLS_RSA_WITH_SEED_CBC_SHA
     99   {0x97, 0x462},  // TLS_DH_DSS_WITH_SEED_CBC_SHA
    100   {0x98, 0x662},  // TLS_DH_RSA_WITH_SEED_CBC_SHA
    101   {0x99, 0x862},  // TLS_DHE_DSS_WITH_SEED_CBC_SHA
    102   {0x9a, 0xa62},  // TLS_DHE_RSA_WITH_SEED_CBC_SHA
    103   {0x9b, 0xc62},  // TLS_DH_anon_WITH_SEED_CBC_SHA
    104   {0x9c, 0x16f},  // TLS_RSA_WITH_AES_128_GCM_SHA256
    105   {0x9d, 0x177},  // TLS_RSA_WITH_AES_256_GCM_SHA384
    106   {0x9e, 0xa6f},  // TLS_DHE_RSA_WITH_AES_128_GCM_SHA256
    107   {0x9f, 0xa77},  // TLS_DHE_RSA_WITH_AES_256_GCM_SHA384
    108   {0xa0, 0x66f},  // TLS_DH_RSA_WITH_AES_128_GCM_SHA256
    109   {0xa1, 0x677},  // TLS_DH_RSA_WITH_AES_256_GCM_SHA384
    110   {0xa2, 0x86f},  // TLS_DHE_DSS_WITH_AES_128_GCM_SHA256
    111   {0xa3, 0x877},  // TLS_DHE_DSS_WITH_AES_256_GCM_SHA384
    112   {0xa4, 0x46f},  // TLS_DH_DSS_WITH_AES_128_GCM_SHA256
    113   {0xa5, 0x477},  // TLS_DH_DSS_WITH_AES_256_GCM_SHA384
    114   {0xa6, 0xc6f},  // TLS_DH_anon_WITH_AES_128_GCM_SHA256
    115   {0xa7, 0xc77},  // TLS_DH_anon_WITH_AES_256_GCM_SHA384
    116   {0xba, 0x153},  // TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256
    117   {0xbb, 0x453},  // TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256
    118   {0xbc, 0x653},  // TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256
    119   {0xbd, 0x853},  // TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256
    120   {0xbe, 0xa53},  // TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
    121   {0xbf, 0xc53},  // TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256
    122   {0xc0, 0x15b},  // TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256
    123   {0xc1, 0x45b},  // TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256
    124   {0xc2, 0x65b},  // TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256
    125   {0xc3, 0x85b},  // TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256
    126   {0xc4, 0xa5b},  // TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256
    127   {0xc5, 0xc5b},  // TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256
    128   {0xc001, 0xd02},  // TLS_ECDH_ECDSA_WITH_NULL_SHA
    129   {0xc002, 0xd12},  // TLS_ECDH_ECDSA_WITH_RC4_128_SHA
    130   {0xc003, 0xd3a},  // TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA
    131   {0xc004, 0xd42},  // TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA
    132   {0xc005, 0xd4a},  // TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA
    133   {0xc006, 0xe02},  // TLS_ECDHE_ECDSA_WITH_NULL_SHA
    134   {0xc007, 0xe12},  // TLS_ECDHE_ECDSA_WITH_RC4_128_SHA
    135   {0xc008, 0xe3a},  // TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA
    136   {0xc009, 0xe42},  // TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA
    137   {0xc00a, 0xe4a},  // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA
    138   {0xc00b, 0xf02},  // TLS_ECDH_RSA_WITH_NULL_SHA
    139   {0xc00c, 0xf12},  // TLS_ECDH_RSA_WITH_RC4_128_SHA
    140   {0xc00d, 0xf3a},  // TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA
    141   {0xc00e, 0xf42},  // TLS_ECDH_RSA_WITH_AES_128_CBC_SHA
    142   {0xc00f, 0xf4a},  // TLS_ECDH_RSA_WITH_AES_256_CBC_SHA
    143   {0xc010, 0x1002},  // TLS_ECDHE_RSA_WITH_NULL_SHA
    144   {0xc011, 0x1012},  // TLS_ECDHE_RSA_WITH_RC4_128_SHA
    145   {0xc012, 0x103a},  // TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA
    146   {0xc013, 0x1042},  // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA
    147   {0xc014, 0x104a},  // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA
    148   {0xc015, 0x1102},  // TLS_ECDH_anon_WITH_NULL_SHA
    149   {0xc016, 0x1112},  // TLS_ECDH_anon_WITH_RC4_128_SHA
    150   {0xc017, 0x113a},  // TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA
    151   {0xc018, 0x1142},  // TLS_ECDH_anon_WITH_AES_128_CBC_SHA
    152   {0xc019, 0x114a},  // TLS_ECDH_anon_WITH_AES_256_CBC_SHA
    153   {0xc023, 0xe43},  // TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256
    154   {0xc024, 0xe4c},  // TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384
    155   {0xc025, 0xd43},  // TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256
    156   {0xc026, 0xd4c},  // TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384
    157   {0xc027, 0x1043},  // TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256
    158   {0xc028, 0x104c},  // TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384
    159   {0xc029, 0xf43},  // TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256
    160   {0xc02a, 0xf4c},  // TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384
    161   {0xc02b, 0xe6f},  // TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256
    162   {0xc02c, 0xe77},  // TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384
    163   {0xc02d, 0xd6f},  // TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256
    164   {0xc02e, 0xd77},  // TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384
    165   {0xc02f, 0x106f},  // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    166   {0xc030, 0x1077},  // TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
    167   {0xc031, 0xf6f},  // TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256
    168   {0xc032, 0xf77},  // TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384
    169   {0xc072, 0xe53},  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
    170   {0xc073, 0xe5c},  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
    171   {0xc074, 0xd53},  // TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256
    172   {0xc075, 0xd5c},  // TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384
    173   {0xc076, 0x1053},  // TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256
    174   {0xc077, 0x105c},  // TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384
    175   {0xc078, 0xf53},  // TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256
    176   {0xc079, 0xf5c},  // TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384
    177   {0xc07a, 0x17f},  // TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256
    178   {0xc07b, 0x187},  // TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384
    179   {0xc07c, 0xa7f},  // TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
    180   {0xc07d, 0xa87},  // TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
    181   {0xc07e, 0x67f},  // TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256
    182   {0xc07f, 0x687},  // TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384
    183   {0xc080, 0x87f},  // TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256
    184   {0xc081, 0x887},  // TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384
    185   {0xc082, 0x47f},  // TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256
    186   {0xc083, 0x487},  // TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384
    187   {0xc084, 0xc7f},  // TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256
    188   {0xc085, 0xc87},  // TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384
    189   {0xc086, 0xe7f},  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
    190   {0xc087, 0xe87},  // TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
    191   {0xc088, 0xd7f},  // TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256
    192   {0xc089, 0xd87},  // TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384
    193   {0xc08a, 0x107f},  // TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256
    194   {0xc08b, 0x1087},  // TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384
    195   {0xc08c, 0xf7f},  // TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256
    196   {0xc08d, 0xf87},  // TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384
    197   {0xcc13, 0x108f},  // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305
    198   {0xcc14, 0x0e8f},  // TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305
    199 };
    200 
    201 static const struct {
    202   char name[15];
    203 } kKeyExchangeNames[18] = {
    204   {"NULL"},  // 0
    205   {"RSA"},  // 1
    206   {"RSA_EXPORT"},  // 2
    207   {"DH_DSS_EXPORT"},  // 3
    208   {"DH_DSS"},  // 4
    209   {"DH_RSA_EXPORT"},  // 5
    210   {"DH_RSA"},  // 6
    211   {"DHE_DSS_EXPORT"},  // 7
    212   {"DHE_DSS"},  // 8
    213   {"DHE_RSA_EXPORT"},  // 9
    214   {"DHE_RSA"},  // 10
    215   {"DH_anon_EXPORT"},  // 11
    216   {"DH_anon"},  // 12
    217   {"ECDH_ECDSA"},  // 13
    218   {"ECDHE_ECDSA"},  // 14
    219   {"ECDH_RSA"},  // 15
    220   {"ECDHE_RSA"},  // 16
    221   {"ECDH_anon"},  // 17
    222 };
    223 
    224 static const struct {
    225   char name[18];
    226 } kCipherNames[18] = {
    227   {"NULL"},  // 0
    228   {"RC4_40"},  // 1
    229   {"RC4_128"},  // 2
    230   {"RC2_CBC_40"},  // 3
    231   {"IDEA_CBC"},  // 4
    232   {"DES40_CBC"},  // 5
    233   {"DES_CBC"},  // 6
    234   {"3DES_EDE_CBC"},  // 7
    235   {"AES_128_CBC"},  // 8
    236   {"AES_256_CBC"},  // 9
    237   {"CAMELLIA_128_CBC"},  // 10
    238   {"CAMELLIA_256_CBC"},  // 11
    239   {"SEED_CBC"},  // 12
    240   {"AES_128_GCM"},  // 13
    241   {"AES_256_GCM"},  // 14
    242   {"CAMELLIA_128_GCM"},  // 15
    243   {"CAMELLIA_256_GCM"},  // 16
    244   {"CHACHA20_POLY1305"},  // 17
    245 };
    246 
    247 static const struct {
    248   char name[7];
    249 } kMacNames[5] = {
    250   {"NULL"},  // 0
    251   {"MD5"},  // 1
    252   {"SHA1"},  // 2
    253   {"SHA256"},  // 3
    254   {"SHA384"},  // 4
    255   // 7 is reserved to indicate an AEAD cipher suite.
    256 };
    257 
    258 static const int kAEADMACValue = 7;
    259 
    260 namespace net {
    261 
    262 static int CipherSuiteCmp(const void* ia, const void* ib) {
    263   const CipherSuite* a = static_cast<const CipherSuite*>(ia);
    264   const CipherSuite* b = static_cast<const CipherSuite*>(ib);
    265 
    266   if (a->cipher_suite < b->cipher_suite) {
    267     return -1;
    268   } else if (a->cipher_suite == b->cipher_suite) {
    269     return 0;
    270   } else {
    271     return 1;
    272   }
    273 }
    274 
    275 void SSLCipherSuiteToStrings(const char** key_exchange_str,
    276                              const char** cipher_str,
    277                              const char** mac_str,
    278                              bool *is_aead,
    279                              uint16 cipher_suite) {
    280   *key_exchange_str = *cipher_str = *mac_str = "???";
    281   *is_aead = false;
    282 
    283   struct CipherSuite desired = {0};
    284   desired.cipher_suite = cipher_suite;
    285 
    286   void* r = bsearch(&desired, kCipherSuites,
    287                     arraysize(kCipherSuites), sizeof(kCipherSuites[0]),
    288                     CipherSuiteCmp);
    289 
    290   if (!r)
    291     return;
    292 
    293   const CipherSuite* cs = static_cast<CipherSuite*>(r);
    294 
    295   const int key_exchange = cs->encoded >> 8;
    296   const int cipher = (cs->encoded >> 3) & 0x1f;
    297   const int mac = cs->encoded & 0x7;
    298 
    299   *key_exchange_str = kKeyExchangeNames[key_exchange].name;
    300   *cipher_str = kCipherNames[cipher].name;
    301   if (mac == kAEADMACValue) {
    302     *is_aead = true;
    303     *mac_str = NULL;
    304   } else {
    305     *mac_str = kMacNames[mac].name;
    306   }
    307 }
    308 
    309 void SSLVersionToString(const char** name, int ssl_version) {
    310   switch (ssl_version) {
    311     case SSL_CONNECTION_VERSION_SSL2:
    312       *name = "SSL 2.0";
    313       break;
    314     case SSL_CONNECTION_VERSION_SSL3:
    315       *name = "SSL 3.0";
    316       break;
    317     case SSL_CONNECTION_VERSION_TLS1:
    318       *name = "TLS 1.0";
    319       break;
    320     case SSL_CONNECTION_VERSION_TLS1_1:
    321       *name = "TLS 1.1";
    322       break;
    323     case SSL_CONNECTION_VERSION_TLS1_2:
    324       *name = "TLS 1.2";
    325       break;
    326     case SSL_CONNECTION_VERSION_QUIC:
    327       *name = "QUIC";
    328       break;
    329     default:
    330       NOTREACHED() << ssl_version;
    331       *name = "???";
    332       break;
    333   }
    334 }
    335 
    336 bool ParseSSLCipherString(const std::string& cipher_string,
    337                           uint16* cipher_suite) {
    338   int value = 0;
    339   if (cipher_string.size() == 6 &&
    340       StartsWithASCII(cipher_string, "0x", false /* case insensitive */) &&
    341       base::HexStringToInt(cipher_string, &value)) {
    342     *cipher_suite = static_cast<uint16>(value);
    343     return true;
    344   }
    345   return false;
    346 }
    347 
    348 bool IsSecureTLSCipherSuite(uint16 cipher_suite) {
    349   CipherSuite desired = {0};
    350   desired.cipher_suite = cipher_suite;
    351 
    352   void* r = bsearch(&desired,
    353                     kCipherSuites,
    354                     arraysize(kCipherSuites),
    355                     sizeof(kCipherSuites[0]),
    356                     CipherSuiteCmp);
    357 
    358   if (!r)
    359     return false;
    360 
    361   const CipherSuite* cs = static_cast<const CipherSuite*>(r);
    362 
    363   const int key_exchange = cs->encoded >> 8;
    364   const int cipher = (cs->encoded >> 3) & 0x1f;
    365   const int mac = cs->encoded & 0x7;
    366 
    367   // Only allow forward secure key exchanges.
    368   switch (key_exchange) {
    369     case 10:  // DHE_RSA
    370     case 14:  // ECDHE_ECDSA
    371     case 16:  // ECDHE_RSA
    372       break;
    373     default:
    374       return false;
    375   }
    376 
    377   switch (cipher) {
    378     case 13:  // AES_128_GCM
    379     case 14:  // AES_256_GCM
    380     case 17:  // CHACHA20_POLY1305
    381       break;
    382     default:
    383       return false;
    384   }
    385 
    386   // Only AEADs allowed.
    387   if (mac != kAEADMACValue)
    388     return false;
    389 
    390   return true;
    391 }
    392 
    393 }  // namespace net
    394