1 /** 2 * TLS Cipher Suites 3 * 4 * Copyright: 5 * (C) 2004-2011,2012 Jack Lloyd 6 * (C) 2014-2015 Etienne Cimon 7 * 8 * License: 9 * Botan is released under the Simplified BSD License (see LICENSE.md) 10 */ 11 12 module botan.tls.ciphersuite; 13 14 import botan.constants; 15 static if (BOTAN_HAS_TLS): 16 17 import botan.utils.types; 18 import botan.libstate.libstate; 19 import botan.utils.parsing; 20 import std.array : Appender; 21 import std.exception; 22 23 /** 24 * TLSCiphersuite Information 25 */ 26 struct TLSCiphersuite 27 { 28 public: 29 /** 30 * Convert an SSL/TLS ciphersuite to algorithm fields 31 * Params: 32 * suite = the ciphersuite code number 33 * Returns: ciphersuite object 34 */ 35 static TLSCiphersuite byId(ushort suite) 36 { 37 switch(suite) 38 { 39 case 0x0013: // DHE_DSS_WITH_3DES_EDE_CBC_SHA 40 return TLSCiphersuite(0x0013, "DSA", "DH", "3DES", 24, 8, 0, "SHA-1", 20); 41 case 0x0032: // DHE_DSS_WITH_AES_128_CBC_SHA 42 return TLSCiphersuite(0x0032, "DSA", "DH", "AES-128", 16, 16, 0, "SHA-1", 20); 43 case 0x0040: // DHE_DSS_WITH_AES_128_CBC_SHA256 44 return TLSCiphersuite(0x0040, "DSA", "DH", "AES-128", 16, 16, 0, "SHA-256", 32); 45 case 0x00A2: // DHE_DSS_WITH_AES_128_GCM_SHA256 46 return TLSCiphersuite(0x00A2, "DSA", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 47 case 0x0038: // DHE_DSS_WITH_AES_256_CBC_SHA 48 return TLSCiphersuite(0x0038, "DSA", "DH", "AES-256", 32, 16, 0, "SHA-1", 20); 49 case 0x006A: // DHE_DSS_WITH_AES_256_CBC_SHA256 50 return TLSCiphersuite(0x006A, "DSA", "DH", "AES-256", 32, 16, 0, "SHA-256", 32); 51 case 0x00A3: // DHE_DSS_WITH_AES_256_GCM_SHA384 52 return TLSCiphersuite(0x00A3, "DSA", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 53 case 0x0044: // DHE_DSS_WITH_CAMELLIA_128_CBC_SHA 54 return TLSCiphersuite(0x0044, "DSA", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20); 55 case 0x00BD: // DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256 56 return TLSCiphersuite(0x00BD, "DSA", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 57 case 0xC080: // DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256 58 return TLSCiphersuite(0xC080, "DSA", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 59 case 0x0087: // DHE_DSS_WITH_CAMELLIA_256_CBC_SHA 60 return TLSCiphersuite(0x0087, "DSA", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20); 61 case 0x00C3: // DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256 62 return TLSCiphersuite(0x00C3, "DSA", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32); 63 case 0xC081: // DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384 64 return TLSCiphersuite(0xC081, "DSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 65 case 0x0066: // DHE_DSS_WITH_RC4_128_SHA 66 return TLSCiphersuite(0x0066, "DSA", "DH", "RC4", 16, 0, 0, "SHA-1", 20); 67 case 0x0099: // DHE_DSS_WITH_SEED_CBC_SHA 68 return TLSCiphersuite(0x0099, "DSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20); 69 case 0x008F: // DHE_PSK_WITH_3DES_EDE_CBC_SHA 70 return TLSCiphersuite(0x008F, "", "DHE_PSK", "3DES", 24, 8, 0, "SHA-1", 20); 71 case 0x0090: // DHE_PSK_WITH_AES_128_CBC_SHA 72 return TLSCiphersuite(0x0090, "", "DHE_PSK", "AES-128", 16, 16, 0, "SHA-1", 20); 73 case 0x00B2: // DHE_PSK_WITH_AES_128_CBC_SHA256 74 return TLSCiphersuite(0x00B2, "", "DHE_PSK", "AES-128", 16, 16, 0, "SHA-256", 32); 75 case 0xC0A6: // DHE_PSK_WITH_AES_128_CCM 76 return TLSCiphersuite(0xC0A6, "", "DHE_PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 77 case 0x00AA: // DHE_PSK_WITH_AES_128_GCM_SHA256 78 return TLSCiphersuite(0x00AA, "", "DHE_PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 79 case 0x0091: // DHE_PSK_WITH_AES_256_CBC_SHA 80 return TLSCiphersuite(0x0091, "", "DHE_PSK", "AES-256", 32, 16, 0, "SHA-1", 20); 81 case 0x00B3: // DHE_PSK_WITH_AES_256_CBC_SHA384 82 return TLSCiphersuite(0x00B3, "", "DHE_PSK", "AES-256", 32, 16, 0, "SHA-384", 48); 83 case 0xC0A7: // DHE_PSK_WITH_AES_256_CCM 84 return TLSCiphersuite(0xC0A7, "", "DHE_PSK", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 85 case 0x00AB: // DHE_PSK_WITH_AES_256_GCM_SHA384 86 return TLSCiphersuite(0x00AB, "", "DHE_PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 87 case 0xC096: // DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 88 return TLSCiphersuite(0xC096, "", "DHE_PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32); 89 case 0xC090: // DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256 90 return TLSCiphersuite(0xC090, "", "DHE_PSK", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 91 case 0xC097: // DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 92 return TLSCiphersuite(0xC097, "", "DHE_PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48); 93 case 0xC091: // DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384 94 return TLSCiphersuite(0xC091, "", "DHE_PSK", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 95 case 0x008E: // DHE_PSK_WITH_RC4_128_SHA 96 return TLSCiphersuite(0x008E, "", "DHE_PSK", "RC4", 16, 0, 0, "SHA-1", 20); 97 case 0x0016: // DHE_RSA_WITH_3DES_EDE_CBC_SHA 98 return TLSCiphersuite(0x0016, "RSA", "DH", "3DES", 24, 8, 0, "SHA-1", 20); 99 case 0x0033: // DHE_RSA_WITH_AES_128_CBC_SHA 100 return TLSCiphersuite(0x0033, "RSA", "DH", "AES-128", 16, 16, 0, "SHA-1", 20); 101 case 0x0067: // DHE_RSA_WITH_AES_128_CBC_SHA256 102 return TLSCiphersuite(0x0067, "RSA", "DH", "AES-128", 16, 16, 0, "SHA-256", 32); 103 case 0xC09E: // DHE_RSA_WITH_AES_128_CCM 104 return TLSCiphersuite(0xC09E, "RSA", "DH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 105 case 0xC0A2: // DHE_RSA_WITH_AES_128_CCM_8 106 return TLSCiphersuite(0xC0A2, "RSA", "DH", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 107 case 0x009E: // DHE_RSA_WITH_AES_128_GCM_SHA256 108 return TLSCiphersuite(0x009E, "RSA", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 109 case 0x0039: // DHE_RSA_WITH_AES_256_CBC_SHA 110 return TLSCiphersuite(0x0039, "RSA", "DH", "AES-256", 32, 16, 0, "SHA-1", 20); 111 case 0x006B: // DHE_RSA_WITH_AES_256_CBC_SHA256 112 return TLSCiphersuite(0x006B, "RSA", "DH", "AES-256", 32, 16, 0, "SHA-256", 32); 113 case 0xC09F: // DHE_RSA_WITH_AES_256_CCM 114 return TLSCiphersuite(0xC09F, "RSA", "DH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 115 case 0xC0A3: // DHE_RSA_WITH_AES_256_CCM_8 116 return TLSCiphersuite(0xC0A3, "RSA", "DH", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 117 case 0x009F: // DHE_RSA_WITH_AES_256_GCM_SHA384 118 return TLSCiphersuite(0x009F, "RSA", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 119 case 0x0045: // DHE_RSA_WITH_CAMELLIA_128_CBC_SHA 120 return TLSCiphersuite(0x0045, "RSA", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20); 121 case 0x00BE: // DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 122 return TLSCiphersuite(0x00BE, "RSA", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 123 case 0xC07C: // DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 124 return TLSCiphersuite(0xC07C, "RSA", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 125 case 0x0088: // DHE_RSA_WITH_CAMELLIA_256_CBC_SHA 126 return TLSCiphersuite(0x0088, "RSA", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20); 127 case 0x00C4: // DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256 128 return TLSCiphersuite(0x00C4, "RSA", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32); 129 case 0xC07D: // DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 130 return TLSCiphersuite(0xC07D, "RSA", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 131 case 0xCC15: // DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 132 return TLSCiphersuite(0xCC15, "RSA", "DH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); 133 case 0x009A: // DHE_RSA_WITH_SEED_CBC_SHA 134 return TLSCiphersuite(0x009A, "RSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20); 135 case 0x001B: // DH_anon_WITH_3DES_EDE_CBC_SHA 136 return TLSCiphersuite(0x001B, "", "DH", "3DES", 24, 8, 0, "SHA-1", 20); 137 case 0x0034: // DH_anon_WITH_AES_128_CBC_SHA 138 return TLSCiphersuite(0x0034, "", "DH", "AES-128", 16, 16, 0, "SHA-1", 20); 139 case 0x006C: // DH_anon_WITH_AES_128_CBC_SHA256 140 return TLSCiphersuite(0x006C, "", "DH", "AES-128", 16, 16, 0, "SHA-256", 32); 141 case 0x00A6: // DH_anon_WITH_AES_128_GCM_SHA256 142 return TLSCiphersuite(0x00A6, "", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 143 case 0x003A: // DH_anon_WITH_AES_256_CBC_SHA 144 return TLSCiphersuite(0x003A, "", "DH", "AES-256", 32, 16, 0, "SHA-1", 20); 145 case 0x006D: // DH_anon_WITH_AES_256_CBC_SHA256 146 return TLSCiphersuite(0x006D, "", "DH", "AES-256", 32, 16, 0, "SHA-256", 32); 147 case 0x00A7: // DH_anon_WITH_AES_256_GCM_SHA384 148 return TLSCiphersuite(0x00A7, "", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 149 case 0x0046: // DH_anon_WITH_CAMELLIA_128_CBC_SHA 150 return TLSCiphersuite(0x0046, "", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20); 151 case 0x00BF: // DH_anon_WITH_CAMELLIA_128_CBC_SHA256 152 return TLSCiphersuite(0x00BF, "", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 153 case 0xC084: // DH_anon_WITH_CAMELLIA_128_GCM_SHA256 154 return TLSCiphersuite(0xC084, "", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 155 case 0x0089: // DH_anon_WITH_CAMELLIA_256_CBC_SHA 156 return TLSCiphersuite(0x0089, "", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20); 157 case 0x00C5: // DH_anon_WITH_CAMELLIA_256_CBC_SHA256 158 return TLSCiphersuite(0x00C5, "", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32); 159 case 0xC085: // DH_anon_WITH_CAMELLIA_256_GCM_SHA384 160 return TLSCiphersuite(0xC085, "", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 161 case 0x0018: // DH_anon_WITH_RC4_128_MD5 162 return TLSCiphersuite(0x0018, "", "DH", "RC4", 16, 0, 0, "MD5", 16); 163 case 0x009B: // DH_anon_WITH_SEED_CBC_SHA 164 return TLSCiphersuite(0x009B, "", "DH", "SEED", 16, 16, 0, "SHA-1", 20); 165 case 0xC008: // ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 166 return TLSCiphersuite(0xC008, "ECDSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20); 167 case 0xC009: // ECDHE_ECDSA_WITH_AES_128_CBC_SHA 168 return TLSCiphersuite(0xC009, "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20); 169 case 0xC023: // ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 170 return TLSCiphersuite(0xC023, "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-256", 32); 171 case 0xC0AC: // ECDHE_ECDSA_WITH_AES_128_CCM 172 return TLSCiphersuite(0xC0AC, "ECDSA", "ECDH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 173 case 0xC0AE: // ECDHE_ECDSA_WITH_AES_128_CCM_8 174 return TLSCiphersuite(0xC0AE, "ECDSA", "ECDH", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 175 case 0xC02B: // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 176 return TLSCiphersuite(0xC02B, "ECDSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 177 case 0xC00A: // ECDHE_ECDSA_WITH_AES_256_CBC_SHA 178 return TLSCiphersuite(0xC00A, "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20); 179 case 0xC024: // ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 180 return TLSCiphersuite(0xC024, "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-384", 48); 181 case 0xC0AD: // ECDHE_ECDSA_WITH_AES_256_CCM 182 return TLSCiphersuite(0xC0AD, "ECDSA", "ECDH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 183 case 0xC0AF: // ECDHE_ECDSA_WITH_AES_256_CCM_8 184 return TLSCiphersuite(0xC0AF, "ECDSA", "ECDH", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 185 case 0xC02C: // ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 186 return TLSCiphersuite(0xC02C, "ECDSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 187 case 0xC072: // ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 188 return TLSCiphersuite(0xC072, "ECDSA", "ECDH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 189 case 0xC086: // ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 190 return TLSCiphersuite(0xC086, "ECDSA", "ECDH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 191 case 0xC073: // ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 192 return TLSCiphersuite(0xC073, "ECDSA", "ECDH", "Camellia-256", 32, 16, 0, "SHA-384", 48); 193 case 0xC087: // ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 194 return TLSCiphersuite(0xC087, "ECDSA", "ECDH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 195 case 0xCC14: // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 196 return TLSCiphersuite(0xCC14, "ECDSA", "ECDH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); 197 case 0xC007: // ECDHE_ECDSA_WITH_RC4_128_SHA 198 return TLSCiphersuite(0xC007, "ECDSA", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20); 199 case 0xC034: // ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 200 return TLSCiphersuite(0xC034, "", "ECDHE_PSK", "3DES", 24, 8, 0, "SHA-1", 20); 201 case 0xC035: // ECDHE_PSK_WITH_AES_128_CBC_SHA 202 return TLSCiphersuite(0xC035, "", "ECDHE_PSK", "AES-128", 16, 16, 0, "SHA-1", 20); 203 case 0xC037: // ECDHE_PSK_WITH_AES_128_CBC_SHA256 204 return TLSCiphersuite(0xC037, "", "ECDHE_PSK", "AES-128", 16, 16, 0, "SHA-256", 32); 205 case 0xC036: // ECDHE_PSK_WITH_AES_256_CBC_SHA 206 return TLSCiphersuite(0xC036, "", "ECDHE_PSK", "AES-256", 32, 16, 0, "SHA-1", 20); 207 case 0xC038: // ECDHE_PSK_WITH_AES_256_CBC_SHA384 208 return TLSCiphersuite(0xC038, "", "ECDHE_PSK", "AES-256", 32, 16, 0, "SHA-384", 48); 209 case 0xC09A: // ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 210 return TLSCiphersuite(0xC09A, "", "ECDHE_PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32); 211 case 0xC09B: // ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 212 return TLSCiphersuite(0xC09B, "", "ECDHE_PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48); 213 case 0xC033: // ECDHE_PSK_WITH_RC4_128_SHA 214 return TLSCiphersuite(0xC033, "", "ECDHE_PSK", "RC4", 16, 0, 0, "SHA-1", 20); 215 case 0xC012: // ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 216 return TLSCiphersuite(0xC012, "RSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20); 217 case 0xC013: // ECDHE_RSA_WITH_AES_128_CBC_SHA 218 return TLSCiphersuite(0xC013, "RSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20); 219 case 0xC027: // ECDHE_RSA_WITH_AES_128_CBC_SHA256 220 return TLSCiphersuite(0xC027, "RSA", "ECDH", "AES-128", 16, 16, 0, "SHA-256", 32); 221 case 0xC02F: // ECDHE_RSA_WITH_AES_128_GCM_SHA256 222 return TLSCiphersuite(0xC02F, "RSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 223 case 0xC014: // ECDHE_RSA_WITH_AES_256_CBC_SHA 224 return TLSCiphersuite(0xC014, "RSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20); 225 case 0xC028: // ECDHE_RSA_WITH_AES_256_CBC_SHA384 226 return TLSCiphersuite(0xC028, "RSA", "ECDH", "AES-256", 32, 16, 0, "SHA-384", 48); 227 case 0xC030: // ECDHE_RSA_WITH_AES_256_GCM_SHA384 228 return TLSCiphersuite(0xC030, "RSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 229 case 0xC076: // ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 230 return TLSCiphersuite(0xC076, "RSA", "ECDH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 231 case 0xC08A: // ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 232 return TLSCiphersuite(0xC08A, "RSA", "ECDH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 233 case 0xC077: // ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 234 return TLSCiphersuite(0xC077, "RSA", "ECDH", "Camellia-256", 32, 16, 0, "SHA-384", 48); 235 case 0xC08B: // ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 236 return TLSCiphersuite(0xC08B, "RSA", "ECDH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 237 case 0xCC13: // ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 238 return TLSCiphersuite(0xCC13, "RSA", "ECDH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); 239 case 0xC011: // ECDHE_RSA_WITH_RC4_128_SHA 240 return TLSCiphersuite(0xC011, "RSA", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20); 241 case 0xC017: // ECDH_anon_WITH_3DES_EDE_CBC_SHA 242 return TLSCiphersuite(0xC017, "", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20); 243 case 0xC018: // ECDH_anon_WITH_AES_128_CBC_SHA 244 return TLSCiphersuite(0xC018, "", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20); 245 case 0xC019: // ECDH_anon_WITH_AES_256_CBC_SHA 246 return TLSCiphersuite(0xC019, "", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20); 247 case 0xC016: // ECDH_anon_WITH_RC4_128_SHA 248 return TLSCiphersuite(0xC016, "", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20); 249 case 0xC0AA: // PSK_DHE_WITH_AES_128_CCM_8 250 return TLSCiphersuite(0xC0AA, "", "DHE_PSK", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 251 case 0xC0AB: // PSK_DHE_WITH_AES_256_CCM_8 252 return TLSCiphersuite(0xC0AB, "", "DHE_PSK", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 253 case 0x008B: // PSK_WITH_3DES_EDE_CBC_SHA 254 return TLSCiphersuite(0x008B, "", "PSK", "3DES", 24, 8, 0, "SHA-1", 20); 255 case 0x008C: // PSK_WITH_AES_128_CBC_SHA 256 return TLSCiphersuite(0x008C, "", "PSK", "AES-128", 16, 16, 0, "SHA-1", 20); 257 case 0x00AE: // PSK_WITH_AES_128_CBC_SHA256 258 return TLSCiphersuite(0x00AE, "", "PSK", "AES-128", 16, 16, 0, "SHA-256", 32); 259 case 0xC0A4: // PSK_WITH_AES_128_CCM 260 return TLSCiphersuite(0xC0A4, "", "PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 261 case 0xC0A8: // PSK_WITH_AES_128_CCM_8 262 return TLSCiphersuite(0xC0A8, "", "PSK", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 263 case 0x00A8: // PSK_WITH_AES_128_GCM_SHA256 264 return TLSCiphersuite(0x00A8, "", "PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 265 case 0x008D: // PSK_WITH_AES_256_CBC_SHA 266 return TLSCiphersuite(0x008D, "", "PSK", "AES-256", 32, 16, 0, "SHA-1", 20); 267 case 0x00AF: // PSK_WITH_AES_256_CBC_SHA384 268 return TLSCiphersuite(0x00AF, "", "PSK", "AES-256", 32, 16, 0, "SHA-384", 48); 269 case 0xC0A5: // PSK_WITH_AES_256_CCM 270 return TLSCiphersuite(0xC0A5, "", "PSK", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 271 case 0xC0A9: // PSK_WITH_AES_256_CCM_8 272 return TLSCiphersuite(0xC0A9, "", "PSK", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 273 case 0x00A9: // PSK_WITH_AES_256_GCM_SHA384 274 return TLSCiphersuite(0x00A9, "", "PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 275 case 0xC094: // PSK_WITH_CAMELLIA_128_CBC_SHA256 276 return TLSCiphersuite(0xC094, "", "PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32); 277 case 0xC08E: // PSK_WITH_CAMELLIA_128_GCM_SHA256 278 return TLSCiphersuite(0xC08E, "", "PSK", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 279 case 0xC095: // PSK_WITH_CAMELLIA_256_CBC_SHA384 280 return TLSCiphersuite(0xC095, "", "PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48); 281 case 0xC08F: // PSK_WITH_CAMELLIA_256_GCM_SHA384 282 return TLSCiphersuite(0xC08F, "", "PSK", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 283 case 0x008A: // PSK_WITH_RC4_128_SHA 284 return TLSCiphersuite(0x008A, "", "PSK", "RC4", 16, 0, 0, "SHA-1", 20); 285 case 0x000A: // RSA_WITH_3DES_EDE_CBC_SHA 286 return TLSCiphersuite(0x000A, "RSA", "RSA", "3DES", 24, 8, 0, "SHA-1", 20); 287 case 0x002F: // RSA_WITH_AES_128_CBC_SHA 288 return TLSCiphersuite(0x002F, "RSA", "RSA", "AES-128", 16, 16, 0, "SHA-1", 20); 289 case 0x003C: // RSA_WITH_AES_128_CBC_SHA256 290 return TLSCiphersuite(0x003C, "RSA", "RSA", "AES-128", 16, 16, 0, "SHA-256", 32); 291 case 0xC09C: // RSA_WITH_AES_128_CCM 292 return TLSCiphersuite(0xC09C, "RSA", "RSA", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 293 case 0xC0A0: // RSA_WITH_AES_128_CCM_8 294 return TLSCiphersuite(0xC0A0, "RSA", "RSA", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 295 case 0x009C: // RSA_WITH_AES_128_GCM_SHA256 296 return TLSCiphersuite(0x009C, "RSA", "RSA", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 297 case 0x0035: // RSA_WITH_AES_256_CBC_SHA 298 return TLSCiphersuite(0x0035, "RSA", "RSA", "AES-256", 32, 16, 0, "SHA-1", 20); 299 case 0x003D: // RSA_WITH_AES_256_CBC_SHA256 300 return TLSCiphersuite(0x003D, "RSA", "RSA", "AES-256", 32, 16, 0, "SHA-256", 32); 301 case 0xC09D: // RSA_WITH_AES_256_CCM 302 return TLSCiphersuite(0xC09D, "RSA", "RSA", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 303 case 0xC0A1: // RSA_WITH_AES_256_CCM_8 304 return TLSCiphersuite(0xC0A1, "RSA", "RSA", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 305 case 0x009D: // RSA_WITH_AES_256_GCM_SHA384 306 return TLSCiphersuite(0x009D, "RSA", "RSA", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 307 case 0x0041: // RSA_WITH_CAMELLIA_128_CBC_SHA 308 return TLSCiphersuite(0x0041, "RSA", "RSA", "Camellia-128", 16, 16, 0, "SHA-1", 20); 309 case 0x00BA: // RSA_WITH_CAMELLIA_128_CBC_SHA256 310 return TLSCiphersuite(0x00BA, "RSA", "RSA", "Camellia-128", 16, 16, 0, "SHA-256", 32); 311 case 0xC07A: // RSA_WITH_CAMELLIA_128_GCM_SHA256 312 return TLSCiphersuite(0xC07A, "RSA", "RSA", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 313 case 0x0084: // RSA_WITH_CAMELLIA_256_CBC_SHA 314 return TLSCiphersuite(0x0084, "RSA", "RSA", "Camellia-256", 32, 16, 0, "SHA-1", 20); 315 case 0x00C0: // RSA_WITH_CAMELLIA_256_CBC_SHA256 316 return TLSCiphersuite(0x00C0, "RSA", "RSA", "Camellia-256", 32, 16, 0, "SHA-256", 32); 317 case 0xC07B: // RSA_WITH_CAMELLIA_256_GCM_SHA384 318 return TLSCiphersuite(0xC07B, "RSA", "RSA", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 319 case 0x0004: // RSA_WITH_RC4_128_MD5 320 return TLSCiphersuite(0x0004, "RSA", "RSA", "RC4", 16, 0, 0, "MD5", 16); 321 case 0x0005: // RSA_WITH_RC4_128_SHA 322 return TLSCiphersuite(0x0005, "RSA", "RSA", "RC4", 16, 0, 0, "SHA-1", 20); 323 case 0x0096: // RSA_WITH_SEED_CBC_SHA 324 return TLSCiphersuite(0x0096, "RSA", "RSA", "SEED", 16, 16, 0, "SHA-1", 20); 325 case 0xC01C: // SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 326 return TLSCiphersuite(0xC01C, "DSA", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20); 327 case 0xC01F: // SRP_SHA_DSS_WITH_AES_128_CBC_SHA 328 return TLSCiphersuite(0xC01F, "DSA", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20); 329 case 0xC022: // SRP_SHA_DSS_WITH_AES_256_CBC_SHA 330 return TLSCiphersuite(0xC022, "DSA", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20); 331 case 0xC01B: // SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 332 return TLSCiphersuite(0xC01B, "RSA", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20); 333 case 0xC01E: // SRP_SHA_RSA_WITH_AES_128_CBC_SHA 334 return TLSCiphersuite(0xC01E, "RSA", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20); 335 case 0xC021: // SRP_SHA_RSA_WITH_AES_256_CBC_SHA 336 return TLSCiphersuite(0xC021, "RSA", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20); 337 case 0xC01A: // SRP_SHA_WITH_3DES_EDE_CBC_SHA 338 return TLSCiphersuite(0xC01A, "", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20); 339 case 0xC01D: // SRP_SHA_WITH_AES_128_CBC_SHA 340 return TLSCiphersuite(0xC01D, "", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20); 341 case 0xC020: // SRP_SHA_WITH_AES_256_CBC_SHA 342 return TLSCiphersuite(0xC020, "", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20); 343 344 default: 345 return TLSCiphersuite.init; // some unknown ciphersuite 346 } 347 } 348 349 /** 350 * Lookup a ciphersuite by name 351 * Params: 352 * name = the name (eg TLS_RSA_WITH_RC4_128_SHA) 353 * Returns: ciphersuite object 354 */ 355 static TLSCiphersuite byName(in string name) 356 { 357 auto all_ciphersuites = allKnownCiphersuites(); 358 foreach (const ref TLSCiphersuite suite; all_ciphersuites) 359 { 360 if (suite.toString() == name) 361 return suite; 362 } 363 364 return TLSCiphersuite.init; // some unknown ciphersuite 365 } 366 367 /** 368 * Generate a static list of all known ciphersuites and return it. 369 * 370 * Returns: list of all known ciphersuites 371 */ 372 static const(TLSCiphersuite[]) allKnownCiphersuites() 373 { 374 static Vector!TLSCiphersuite all_ciphersuites; 375 static bool initialized; 376 if (!initialized) { 377 initialized = true; 378 all_ciphersuites = gatherKnownCiphersuites(); 379 } 380 return cast(const)all_ciphersuites[]; 381 } 382 383 /** 384 * Formats the ciphersuite back to an RFC-style ciphersuite string 385 * Returns: RFC ciphersuite string identifier 386 */ 387 string toString() const 388 { 389 if (m_cipher_keylen == 0) 390 throw new Exception("toString - no value set"); 391 Appender!string output; 392 393 output ~= "TLS_"; 394 395 if (kexAlgo() != "RSA") 396 { 397 if (kexAlgo() == "DH") 398 output ~= "DHE"; 399 else if (kexAlgo() == "ECDH") 400 output ~= "ECDHE"; 401 else 402 output ~= kexAlgo(); 403 404 output ~= '_'; 405 } 406 407 if (sigAlgo() == "DSA") 408 output ~= "DSS_"; 409 else if (sigAlgo() != "") 410 output ~= sigAlgo() ~ '_'; 411 412 output ~= "WITH_"; 413 414 if (cipherAlgo() == "RC4") 415 { 416 output ~= "RC4_128_"; 417 } 418 else if(cipherAlgo() == "ChaCha20Poly1305") 419 { 420 output ~= "CHACHA20_POLY1305_"; 421 } 422 else 423 { 424 if (cipherAlgo() == "3DES") 425 output ~= "3DES_EDE"; 426 else if (cipherAlgo().find("Camellia") == -1) 427 output ~= "CAMELLIA_" ~ to!string(8*cipherKeylen()); 428 else 429 output ~= replaceChars(cipherAlgo(), ['-', '/'], '_'); 430 431 if (cipherAlgo().find("/") != -1) 432 output ~= "_"; // some explicit mode already included 433 else 434 output ~= "_CBC_"; 435 } 436 437 if (macAlgo() == "SHA-1") 438 output ~= "SHA"; 439 else if (macAlgo() == "AEAD") 440 output ~= eraseChars(prfAlgo(), ['-']); 441 else 442 output ~= eraseChars(macAlgo(), ['-']); 443 444 return output.data; 445 } 446 447 /** 448 * Returns: ciphersuite number 449 */ 450 ushort ciphersuiteCode() const { return m_ciphersuite_code; } 451 452 /** 453 * Returns: true if this is a PSK ciphersuite 454 */ 455 bool pskCiphersuite() const 456 { 457 return (kexAlgo() == "PSK" || 458 kexAlgo() == "DHE_PSK" || 459 kexAlgo() == "ECDHE_PSK"); 460 } 461 462 /** 463 * Returns: true if this is an ECC ciphersuite 464 */ 465 bool eccCiphersuite() const 466 { 467 return (sigAlgo() == "ECDSA" || kexAlgo() == "ECDH" || kexAlgo() == "ECDHE_PSK"); 468 } 469 470 /** 471 * Returns: key exchange algorithm used by this ciphersuite 472 */ 473 ref const(string) kexAlgo() const { return m_kex_algo; } 474 475 /** 476 * Returns: signature algorithm used by this ciphersuite 477 */ 478 ref const(string) sigAlgo() const { return m_sig_algo; } 479 480 /** 481 * Returns: symmetric cipher algorithm used by this ciphersuite 482 */ 483 ref const(string) cipherAlgo() const { return m_cipher_algo; } 484 485 /** 486 * Returns: message authentication algorithm used by this ciphersuite 487 */ 488 ref const(string) macAlgo() const { return m_mac_algo; } 489 490 ref const(string) prfAlgo() const 491 { 492 return (m_prf_algo != "") ? m_prf_algo : m_mac_algo; 493 } 494 495 /** 496 * Returns: cipher key length used by this ciphersuite 497 */ 498 size_t cipherKeylen() const { return m_cipher_keylen; } 499 500 size_t nonceBytesFromHandshake() const { return m_nonce_bytes_from_handshake; } 501 502 size_t nonceBytesFromRecord() const { return m_nonce_bytes_from_record; } 503 504 size_t macKeylen() const { return m_mac_keylen; } 505 506 /** 507 * Returns: true if this is a valid/known ciphersuite 508 */ 509 bool valid() const 510 { 511 if (!m_cipher_keylen) // uninitialized object 512 return false; 513 514 AlgorithmFactory af = globalState().algorithmFactory(); 515 516 if (!af.prototypeHashFunction(prfAlgo())) 517 return false; 518 519 if (macAlgo() == "AEAD") 520 { 521 if (cipherAlgo() == "ChaCha20Poly1305") 522 { 523 static if (!BOTAN_HAS_AEAD_CHACHA20_POLY1305) { 524 return false; 525 } 526 } 527 else { 528 auto cipher_and_mode = splitter(cipherAlgo(), '/'); 529 assert(cipher_and_mode.length == 2, "Expected format for AEAD algo"); 530 if (!af.prototypeBlockCipher(cipher_and_mode[0])) 531 return false; 532 533 const auto mode = cipher_and_mode[1]; 534 535 static if (!BOTAN_HAS_AEAD_CCM) { 536 if (mode == "CCM" || mode == "CCM-8") 537 return false; 538 } 539 540 static if (!BOTAN_HAS_AEAD_GCM) { 541 if (mode == "GCM") 542 return false; 543 } 544 545 static if (!BOTAN_HAS_AEAD_OCB) { 546 if (mode == "OCB") 547 return false; 548 } 549 } 550 } 551 else 552 { 553 if (!af.prototypeBlockCipher(cipherAlgo()) && 554 !af.prototypeStreamCipher(cipherAlgo())) 555 return false; 556 557 if (!af.prototypeHashFunction(macAlgo())) 558 return false; 559 } 560 561 if (kexAlgo() == "SRP_SHA") 562 { 563 static if (!BOTAN_HAS_SRP6) { 564 return false; 565 } 566 } 567 else if (kexAlgo() == "ECDH" || kexAlgo() == "ECDHE_PSK") 568 { 569 static if (!BOTAN_HAS_ECDH) { 570 return false; 571 } 572 } 573 else if (kexAlgo() == "DH" || kexAlgo() == "DHE_PSK") 574 { 575 static if (!BOTAN_HAS_DIFFIE_HELLMAN) { 576 return false; 577 } 578 } 579 580 if (sigAlgo() == "DSA") 581 { 582 static if (!BOTAN_HAS_DSA) { 583 return false; 584 } 585 } 586 else if (sigAlgo() == "ECDSA") 587 { 588 static if (!BOTAN_HAS_ECDSA) { 589 return false; 590 } 591 } 592 else if (sigAlgo() == "RSA") 593 { 594 static if (!BOTAN_HAS_RSA) { 595 return false; 596 } 597 } 598 599 return true; 600 } 601 private: 602 this(ushort ciphersuite_code, 603 string sig_algo, 604 string kex_algo, 605 string cipher_algo, 606 size_t cipher_keylen, 607 size_t nonce_bytes_from_handshake, 608 size_t nonce_bytes_from_record, 609 string mac_algo, 610 size_t mac_keylen, 611 string prf_algo = "") 612 { 613 m_ciphersuite_code = ciphersuite_code; 614 m_sig_algo = sig_algo; 615 m_kex_algo = kex_algo; 616 m_prf_algo = prf_algo; 617 m_cipher_algo = cipher_algo; 618 m_cipher_keylen = cipher_keylen; 619 m_nonce_bytes_from_handshake = nonce_bytes_from_handshake; 620 m_nonce_bytes_from_record = nonce_bytes_from_record; 621 m_mac_algo = mac_algo; 622 m_mac_keylen = mac_keylen; 623 } 624 625 /* 626 * This way all work happens at the constuctor call, and we can 627 * rely on that happening only once in D 628 */ 629 static Vector!TLSCiphersuite gatherKnownCiphersuites() 630 { 631 Vector!TLSCiphersuite ciphersuites; 632 633 for (size_t i = 0; i <= 0xFFFF; ++i) 634 { 635 TLSCiphersuite suite = byId(cast(ushort)i); 636 637 if (suite.valid()) 638 ciphersuites.pushBack(suite); 639 } 640 641 return ciphersuites; 642 } 643 644 ushort m_ciphersuite_code; 645 646 string m_sig_algo; 647 string m_kex_algo; 648 string m_prf_algo; 649 string m_cipher_algo; 650 651 size_t m_cipher_keylen; 652 size_t m_cipher_ivlen; 653 size_t m_nonce_bytes_from_handshake; 654 size_t m_nonce_bytes_from_record; 655 string m_mac_algo; 656 size_t m_mac_keylen; 657 } 658 659 ptrdiff_t find(string str, string str2) { 660 import std.algorithm : countUntil; 661 return str.countUntil(str2); 662 }