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 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 0xCC13: // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_OLD 132 return TLSCiphersuite(0xCC13, "RSA", "ECDH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); 133 case 0xCCA8: // TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 134 return TLSCiphersuite(0xCCA8, "RSA", "ECDH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); 135 case 0xCC14: // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_OLD 136 return TLSCiphersuite(0xCC14, "ECDSA", "ECDH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); 137 case 0xCCA9: // ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 138 return TLSCiphersuite(0xCCA9, "ECDSA", "ECDH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); 139 case 0xCC15: // DHE_RSA_WITH_CHACHA20_POLY1305_OLD 140 return TLSCiphersuite(0xCC15, "RSA", "DH", "ChaCha20Poly1305", 32, 0, 0, "AEAD", 0, "SHA-256"); 141 case 0xCCAA: // DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 142 return TLSCiphersuite(0xCCAA, "RSA", "DH", "ChaCha20Poly1305", 32, 12, 0, "AEAD", 0, "SHA-256"); 143 case 0x009A: // DHE_RSA_WITH_SEED_CBC_SHA 144 return TLSCiphersuite(0x009A, "RSA", "DH", "SEED", 16, 16, 0, "SHA-1", 20); 145 case 0x001B: // DH_anon_WITH_3DES_EDE_CBC_SHA 146 return TLSCiphersuite(0x001B, "", "DH", "3DES", 24, 8, 0, "SHA-1", 20); 147 case 0x0034: // DH_anon_WITH_AES_128_CBC_SHA 148 return TLSCiphersuite(0x0034, "", "DH", "AES-128", 16, 16, 0, "SHA-1", 20); 149 case 0x006C: // DH_anon_WITH_AES_128_CBC_SHA256 150 return TLSCiphersuite(0x006C, "", "DH", "AES-128", 16, 16, 0, "SHA-256", 32); 151 case 0x00A6: // DH_anon_WITH_AES_128_GCM_SHA256 152 return TLSCiphersuite(0x00A6, "", "DH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 153 case 0x003A: // DH_anon_WITH_AES_256_CBC_SHA 154 return TLSCiphersuite(0x003A, "", "DH", "AES-256", 32, 16, 0, "SHA-1", 20); 155 case 0x006D: // DH_anon_WITH_AES_256_CBC_SHA256 156 return TLSCiphersuite(0x006D, "", "DH", "AES-256", 32, 16, 0, "SHA-256", 32); 157 case 0x00A7: // DH_anon_WITH_AES_256_GCM_SHA384 158 return TLSCiphersuite(0x00A7, "", "DH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 159 case 0x0046: // DH_anon_WITH_CAMELLIA_128_CBC_SHA 160 return TLSCiphersuite(0x0046, "", "DH", "Camellia-128", 16, 16, 0, "SHA-1", 20); 161 case 0x00BF: // DH_anon_WITH_CAMELLIA_128_CBC_SHA256 162 return TLSCiphersuite(0x00BF, "", "DH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 163 case 0xC084: // DH_anon_WITH_CAMELLIA_128_GCM_SHA256 164 return TLSCiphersuite(0xC084, "", "DH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 165 case 0x0089: // DH_anon_WITH_CAMELLIA_256_CBC_SHA 166 return TLSCiphersuite(0x0089, "", "DH", "Camellia-256", 32, 16, 0, "SHA-1", 20); 167 case 0x00C5: // DH_anon_WITH_CAMELLIA_256_CBC_SHA256 168 return TLSCiphersuite(0x00C5, "", "DH", "Camellia-256", 32, 16, 0, "SHA-256", 32); 169 case 0xC085: // DH_anon_WITH_CAMELLIA_256_GCM_SHA384 170 return TLSCiphersuite(0xC085, "", "DH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 171 case 0x0018: // DH_anon_WITH_RC4_128_MD5 172 return TLSCiphersuite(0x0018, "", "DH", "RC4", 16, 0, 0, "MD5", 16); 173 case 0x009B: // DH_anon_WITH_SEED_CBC_SHA 174 return TLSCiphersuite(0x009B, "", "DH", "SEED", 16, 16, 0, "SHA-1", 20); 175 case 0xC008: // ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA 176 return TLSCiphersuite(0xC008, "ECDSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20); 177 case 0xC009: // ECDHE_ECDSA_WITH_AES_128_CBC_SHA 178 return TLSCiphersuite(0xC009, "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20); 179 case 0xC023: // ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 180 return TLSCiphersuite(0xC023, "ECDSA", "ECDH", "AES-128", 16, 16, 0, "SHA-256", 32); 181 case 0xC0AC: // ECDHE_ECDSA_WITH_AES_128_CCM 182 return TLSCiphersuite(0xC0AC, "ECDSA", "ECDH", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 183 case 0xC0AE: // ECDHE_ECDSA_WITH_AES_128_CCM_8 184 return TLSCiphersuite(0xC0AE, "ECDSA", "ECDH", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 185 case 0xC02B: // ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 186 return TLSCiphersuite(0xC02B, "ECDSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 187 case 0xC00A: // ECDHE_ECDSA_WITH_AES_256_CBC_SHA 188 return TLSCiphersuite(0xC00A, "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20); 189 case 0xC024: // ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 190 return TLSCiphersuite(0xC024, "ECDSA", "ECDH", "AES-256", 32, 16, 0, "SHA-384", 48); 191 case 0xC0AD: // ECDHE_ECDSA_WITH_AES_256_CCM 192 return TLSCiphersuite(0xC0AD, "ECDSA", "ECDH", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 193 case 0xC0AF: // ECDHE_ECDSA_WITH_AES_256_CCM_8 194 return TLSCiphersuite(0xC0AF, "ECDSA", "ECDH", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 195 case 0xC02C: // ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 196 return TLSCiphersuite(0xC02C, "ECDSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 197 case 0xC072: // ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256 198 return TLSCiphersuite(0xC072, "ECDSA", "ECDH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 199 case 0xC086: // ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256 200 return TLSCiphersuite(0xC086, "ECDSA", "ECDH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 201 case 0xC073: // ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384 202 return TLSCiphersuite(0xC073, "ECDSA", "ECDH", "Camellia-256", 32, 16, 0, "SHA-384", 48); 203 case 0xC087: // ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384 204 return TLSCiphersuite(0xC087, "ECDSA", "ECDH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 205 case 0xC007: // ECDHE_ECDSA_WITH_RC4_128_SHA 206 return TLSCiphersuite(0xC007, "ECDSA", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20); 207 case 0xC034: // ECDHE_PSK_WITH_3DES_EDE_CBC_SHA 208 return TLSCiphersuite(0xC034, "", "ECDHE_PSK", "3DES", 24, 8, 0, "SHA-1", 20); 209 case 0xC035: // ECDHE_PSK_WITH_AES_128_CBC_SHA 210 return TLSCiphersuite(0xC035, "", "ECDHE_PSK", "AES-128", 16, 16, 0, "SHA-1", 20); 211 case 0xC037: // ECDHE_PSK_WITH_AES_128_CBC_SHA256 212 return TLSCiphersuite(0xC037, "", "ECDHE_PSK", "AES-128", 16, 16, 0, "SHA-256", 32); 213 case 0xC036: // ECDHE_PSK_WITH_AES_256_CBC_SHA 214 return TLSCiphersuite(0xC036, "", "ECDHE_PSK", "AES-256", 32, 16, 0, "SHA-1", 20); 215 case 0xC038: // ECDHE_PSK_WITH_AES_256_CBC_SHA384 216 return TLSCiphersuite(0xC038, "", "ECDHE_PSK", "AES-256", 32, 16, 0, "SHA-384", 48); 217 case 0xC09A: // ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256 218 return TLSCiphersuite(0xC09A, "", "ECDHE_PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32); 219 case 0xC09B: // ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384 220 return TLSCiphersuite(0xC09B, "", "ECDHE_PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48); 221 case 0xC033: // ECDHE_PSK_WITH_RC4_128_SHA 222 return TLSCiphersuite(0xC033, "", "ECDHE_PSK", "RC4", 16, 0, 0, "SHA-1", 20); 223 case 0xC012: // ECDHE_RSA_WITH_3DES_EDE_CBC_SHA 224 return TLSCiphersuite(0xC012, "RSA", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20); 225 case 0xC013: // ECDHE_RSA_WITH_AES_128_CBC_SHA 226 return TLSCiphersuite(0xC013, "RSA", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20); 227 case 0xC027: // ECDHE_RSA_WITH_AES_128_CBC_SHA256 228 return TLSCiphersuite(0xC027, "RSA", "ECDH", "AES-128", 16, 16, 0, "SHA-256", 32); 229 case 0xC02F: // ECDHE_RSA_WITH_AES_128_GCM_SHA256 230 return TLSCiphersuite(0xC02F, "RSA", "ECDH", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 231 case 0xC014: // ECDHE_RSA_WITH_AES_256_CBC_SHA 232 return TLSCiphersuite(0xC014, "RSA", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20); 233 case 0xC028: // ECDHE_RSA_WITH_AES_256_CBC_SHA384 234 return TLSCiphersuite(0xC028, "RSA", "ECDH", "AES-256", 32, 16, 0, "SHA-384", 48); 235 case 0xC030: // ECDHE_RSA_WITH_AES_256_GCM_SHA384 236 return TLSCiphersuite(0xC030, "RSA", "ECDH", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 237 case 0xC076: // ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256 238 return TLSCiphersuite(0xC076, "RSA", "ECDH", "Camellia-128", 16, 16, 0, "SHA-256", 32); 239 case 0xC08A: // ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256 240 return TLSCiphersuite(0xC08A, "RSA", "ECDH", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 241 case 0xC077: // ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384 242 return TLSCiphersuite(0xC077, "RSA", "ECDH", "Camellia-256", 32, 16, 0, "SHA-384", 48); 243 case 0xC08B: // ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384 244 return TLSCiphersuite(0xC08B, "RSA", "ECDH", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 245 case 0xC011: // ECDHE_RSA_WITH_RC4_128_SHA 246 return TLSCiphersuite(0xC011, "RSA", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20); 247 case 0xC017: // ECDH_anon_WITH_3DES_EDE_CBC_SHA 248 return TLSCiphersuite(0xC017, "", "ECDH", "3DES", 24, 8, 0, "SHA-1", 20); 249 case 0xC018: // ECDH_anon_WITH_AES_128_CBC_SHA 250 return TLSCiphersuite(0xC018, "", "ECDH", "AES-128", 16, 16, 0, "SHA-1", 20); 251 case 0xC019: // ECDH_anon_WITH_AES_256_CBC_SHA 252 return TLSCiphersuite(0xC019, "", "ECDH", "AES-256", 32, 16, 0, "SHA-1", 20); 253 case 0xC016: // ECDH_anon_WITH_RC4_128_SHA 254 return TLSCiphersuite(0xC016, "", "ECDH", "RC4", 16, 0, 0, "SHA-1", 20); 255 case 0xC0AA: // PSK_DHE_WITH_AES_128_CCM_8 256 return TLSCiphersuite(0xC0AA, "", "DHE_PSK", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 257 case 0xC0AB: // PSK_DHE_WITH_AES_256_CCM_8 258 return TLSCiphersuite(0xC0AB, "", "DHE_PSK", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 259 case 0x008B: // PSK_WITH_3DES_EDE_CBC_SHA 260 return TLSCiphersuite(0x008B, "", "PSK", "3DES", 24, 8, 0, "SHA-1", 20); 261 case 0x008C: // PSK_WITH_AES_128_CBC_SHA 262 return TLSCiphersuite(0x008C, "", "PSK", "AES-128", 16, 16, 0, "SHA-1", 20); 263 case 0x00AE: // PSK_WITH_AES_128_CBC_SHA256 264 return TLSCiphersuite(0x00AE, "", "PSK", "AES-128", 16, 16, 0, "SHA-256", 32); 265 case 0xC0A4: // PSK_WITH_AES_128_CCM 266 return TLSCiphersuite(0xC0A4, "", "PSK", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 267 case 0xC0A8: // PSK_WITH_AES_128_CCM_8 268 return TLSCiphersuite(0xC0A8, "", "PSK", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 269 case 0x00A8: // PSK_WITH_AES_128_GCM_SHA256 270 return TLSCiphersuite(0x00A8, "", "PSK", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 271 case 0x008D: // PSK_WITH_AES_256_CBC_SHA 272 return TLSCiphersuite(0x008D, "", "PSK", "AES-256", 32, 16, 0, "SHA-1", 20); 273 case 0x00AF: // PSK_WITH_AES_256_CBC_SHA384 274 return TLSCiphersuite(0x00AF, "", "PSK", "AES-256", 32, 16, 0, "SHA-384", 48); 275 case 0xC0A5: // PSK_WITH_AES_256_CCM 276 return TLSCiphersuite(0xC0A5, "", "PSK", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 277 case 0xC0A9: // PSK_WITH_AES_256_CCM_8 278 return TLSCiphersuite(0xC0A9, "", "PSK", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 279 case 0x00A9: // PSK_WITH_AES_256_GCM_SHA384 280 return TLSCiphersuite(0x00A9, "", "PSK", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 281 case 0xC094: // PSK_WITH_CAMELLIA_128_CBC_SHA256 282 return TLSCiphersuite(0xC094, "", "PSK", "Camellia-128", 16, 16, 0, "SHA-256", 32); 283 case 0xC08E: // PSK_WITH_CAMELLIA_128_GCM_SHA256 284 return TLSCiphersuite(0xC08E, "", "PSK", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 285 case 0xC095: // PSK_WITH_CAMELLIA_256_CBC_SHA384 286 return TLSCiphersuite(0xC095, "", "PSK", "Camellia-256", 32, 16, 0, "SHA-384", 48); 287 case 0xC08F: // PSK_WITH_CAMELLIA_256_GCM_SHA384 288 return TLSCiphersuite(0xC08F, "", "PSK", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 289 case 0x008A: // PSK_WITH_RC4_128_SHA 290 return TLSCiphersuite(0x008A, "", "PSK", "RC4", 16, 0, 0, "SHA-1", 20); 291 case 0x000A: // RSA_WITH_3DES_EDE_CBC_SHA 292 return TLSCiphersuite(0x000A, "RSA", "RSA", "3DES", 24, 8, 0, "SHA-1", 20); 293 case 0x002F: // RSA_WITH_AES_128_CBC_SHA 294 return TLSCiphersuite(0x002F, "RSA", "RSA", "AES-128", 16, 16, 0, "SHA-1", 20); 295 case 0x003C: // RSA_WITH_AES_128_CBC_SHA256 296 return TLSCiphersuite(0x003C, "RSA", "RSA", "AES-128", 16, 16, 0, "SHA-256", 32); 297 case 0xC09C: // RSA_WITH_AES_128_CCM 298 return TLSCiphersuite(0xC09C, "RSA", "RSA", "AES-128/CCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 299 case 0xC0A0: // RSA_WITH_AES_128_CCM_8 300 return TLSCiphersuite(0xC0A0, "RSA", "RSA", "AES-128/CCM-8", 16, 4, 8, "AEAD", 0, "SHA-256"); 301 case 0x009C: // RSA_WITH_AES_128_GCM_SHA256 302 return TLSCiphersuite(0x009C, "RSA", "RSA", "AES-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 303 case 0x0035: // RSA_WITH_AES_256_CBC_SHA 304 return TLSCiphersuite(0x0035, "RSA", "RSA", "AES-256", 32, 16, 0, "SHA-1", 20); 305 case 0x003D: // RSA_WITH_AES_256_CBC_SHA256 306 return TLSCiphersuite(0x003D, "RSA", "RSA", "AES-256", 32, 16, 0, "SHA-256", 32); 307 case 0xC09D: // RSA_WITH_AES_256_CCM 308 return TLSCiphersuite(0xC09D, "RSA", "RSA", "AES-256/CCM", 32, 4, 8, "AEAD", 0, "SHA-256"); 309 case 0xC0A1: // RSA_WITH_AES_256_CCM_8 310 return TLSCiphersuite(0xC0A1, "RSA", "RSA", "AES-256/CCM-8", 32, 4, 8, "AEAD", 0, "SHA-256"); 311 case 0x009D: // RSA_WITH_AES_256_GCM_SHA384 312 return TLSCiphersuite(0x009D, "RSA", "RSA", "AES-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 313 case 0x0041: // RSA_WITH_CAMELLIA_128_CBC_SHA 314 return TLSCiphersuite(0x0041, "RSA", "RSA", "Camellia-128", 16, 16, 0, "SHA-1", 20); 315 case 0x00BA: // RSA_WITH_CAMELLIA_128_CBC_SHA256 316 return TLSCiphersuite(0x00BA, "RSA", "RSA", "Camellia-128", 16, 16, 0, "SHA-256", 32); 317 case 0xC07A: // RSA_WITH_CAMELLIA_128_GCM_SHA256 318 return TLSCiphersuite(0xC07A, "RSA", "RSA", "Camellia-128/GCM", 16, 4, 8, "AEAD", 0, "SHA-256"); 319 case 0x0084: // RSA_WITH_CAMELLIA_256_CBC_SHA 320 return TLSCiphersuite(0x0084, "RSA", "RSA", "Camellia-256", 32, 16, 0, "SHA-1", 20); 321 case 0x00C0: // RSA_WITH_CAMELLIA_256_CBC_SHA256 322 return TLSCiphersuite(0x00C0, "RSA", "RSA", "Camellia-256", 32, 16, 0, "SHA-256", 32); 323 case 0xC07B: // RSA_WITH_CAMELLIA_256_GCM_SHA384 324 return TLSCiphersuite(0xC07B, "RSA", "RSA", "Camellia-256/GCM", 32, 4, 8, "AEAD", 0, "SHA-384"); 325 case 0x0004: // RSA_WITH_RC4_128_MD5 326 return TLSCiphersuite(0x0004, "RSA", "RSA", "RC4", 16, 0, 0, "MD5", 16); 327 case 0x0005: // RSA_WITH_RC4_128_SHA 328 return TLSCiphersuite(0x0005, "RSA", "RSA", "RC4", 16, 0, 0, "SHA-1", 20); 329 case 0x0096: // RSA_WITH_SEED_CBC_SHA 330 return TLSCiphersuite(0x0096, "RSA", "RSA", "SEED", 16, 16, 0, "SHA-1", 20); 331 case 0xC01C: // SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA 332 return TLSCiphersuite(0xC01C, "DSA", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20); 333 case 0xC01F: // SRP_SHA_DSS_WITH_AES_128_CBC_SHA 334 return TLSCiphersuite(0xC01F, "DSA", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20); 335 case 0xC022: // SRP_SHA_DSS_WITH_AES_256_CBC_SHA 336 return TLSCiphersuite(0xC022, "DSA", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20); 337 case 0xC01B: // SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA 338 return TLSCiphersuite(0xC01B, "RSA", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20); 339 case 0xC01E: // SRP_SHA_RSA_WITH_AES_128_CBC_SHA 340 return TLSCiphersuite(0xC01E, "RSA", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20); 341 case 0xC021: // SRP_SHA_RSA_WITH_AES_256_CBC_SHA 342 return TLSCiphersuite(0xC021, "RSA", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20); 343 case 0xC01A: // SRP_SHA_WITH_3DES_EDE_CBC_SHA 344 return TLSCiphersuite(0xC01A, "", "SRP_SHA", "3DES", 24, 8, 0, "SHA-1", 20); 345 case 0xC01D: // SRP_SHA_WITH_AES_128_CBC_SHA 346 return TLSCiphersuite(0xC01D, "", "SRP_SHA", "AES-128", 16, 16, 0, "SHA-1", 20); 347 case 0xC020: // SRP_SHA_WITH_AES_256_CBC_SHA 348 return TLSCiphersuite(0xC020, "", "SRP_SHA", "AES-256", 32, 16, 0, "SHA-1", 20); 349 350 default: 351 return TLSCiphersuite.init; // some unknown ciphersuite 352 } 353 } 354 355 /** 356 * Lookup a ciphersuite by name 357 * Params: 358 * name = the name (eg TLS_RSA_WITH_RC4_128_SHA) 359 * Returns: ciphersuite object 360 */ 361 static TLSCiphersuite byName(in string name) 362 { 363 auto all_ciphersuites = allKnownCiphersuites(); 364 foreach (const ref TLSCiphersuite suite; all_ciphersuites) 365 { 366 if (suite.toString() == name) 367 return suite; 368 } 369 370 return TLSCiphersuite.init; // some unknown ciphersuite 371 } 372 373 /** 374 * Generate a static list of all known ciphersuites and return it. 375 * 376 * Returns: list of all known ciphersuites 377 */ 378 static const(TLSCiphersuite[]) allKnownCiphersuites() 379 { 380 static Vector!TLSCiphersuite all_ciphersuites; 381 static bool initialized; 382 if (!initialized) { 383 initialized = true; 384 all_ciphersuites = gatherKnownCiphersuites(); 385 } 386 return cast(const)all_ciphersuites[]; 387 } 388 389 /** 390 * Formats the ciphersuite back to an RFC-style ciphersuite string 391 * Returns: RFC ciphersuite string identifier 392 */ 393 string toString() const 394 { 395 if (m_cipher_keylen == 0) 396 throw new Exception("toString - no value set"); 397 Appender!string output; 398 399 output ~= "TLS_"; 400 401 if (kexAlgo() != "RSA") 402 { 403 if (kexAlgo() == "DH") 404 output ~= "DHE"; 405 else if (kexAlgo() == "ECDH") 406 output ~= "ECDHE"; 407 else 408 output ~= kexAlgo(); 409 410 output ~= '_'; 411 } 412 413 if (sigAlgo() == "DSA") 414 output ~= "DSS_"; 415 else if (sigAlgo() != "") 416 output ~= sigAlgo() ~ '_'; 417 418 output ~= "WITH_"; 419 420 if (cipherAlgo() == "RC4") 421 { 422 output ~= "RC4_128_"; 423 } 424 else if(cipherAlgo() == "ChaCha20Poly1305") 425 { 426 output ~= "CHACHA20_POLY1305_"; 427 } 428 else 429 { 430 if (cipherAlgo() == "3DES") 431 output ~= "3DES_EDE"; 432 else if (cipherAlgo().find("Camellia") == -1) 433 output ~= "CAMELLIA_" ~ to!string(8*cipherKeylen()); 434 else 435 output ~= replaceChars(cipherAlgo(), ['-', '/'], '_'); 436 437 if (cipherAlgo().find("/") != -1) 438 output ~= "_"; // some explicit mode already included 439 else 440 output ~= "_CBC_"; 441 } 442 443 if (macAlgo() == "SHA-1") 444 output ~= "SHA"; 445 else if (macAlgo() == "AEAD") 446 output ~= eraseChars(prfAlgo(), ['-']); 447 else 448 output ~= eraseChars(macAlgo(), ['-']); 449 450 return output.data; 451 } 452 453 /** 454 * Returns: ciphersuite number 455 */ 456 ushort ciphersuiteCode() const { return m_ciphersuite_code; } 457 458 /** 459 * Returns: true if this is a PSK ciphersuite 460 */ 461 bool pskCiphersuite() const 462 { 463 return (kexAlgo() == "PSK" || 464 kexAlgo() == "DHE_PSK" || 465 kexAlgo() == "ECDHE_PSK"); 466 } 467 468 /** 469 * Returns: true if this is an ECC ciphersuite 470 */ 471 bool eccCiphersuite() const 472 { 473 return (sigAlgo() == "ECDSA" || kexAlgo() == "ECDH" || kexAlgo() == "ECDHE_PSK"); 474 } 475 476 /** 477 * Returns: key exchange algorithm used by this ciphersuite 478 */ 479 ref const(string) kexAlgo() const { return m_kex_algo; } 480 481 /** 482 * Returns: signature algorithm used by this ciphersuite 483 */ 484 ref const(string) sigAlgo() const { return m_sig_algo; } 485 486 /** 487 * Returns: symmetric cipher algorithm used by this ciphersuite 488 */ 489 ref const(string) cipherAlgo() const { return m_cipher_algo; } 490 491 /** 492 * Returns: message authentication algorithm used by this ciphersuite 493 */ 494 ref const(string) macAlgo() const { return m_mac_algo; } 495 496 ref const(string) prfAlgo() const 497 { 498 return (m_prf_algo != "") ? m_prf_algo : m_mac_algo; 499 } 500 501 /** 502 * Returns: cipher key length used by this ciphersuite 503 */ 504 size_t cipherKeylen() const { return m_cipher_keylen; } 505 506 size_t nonceBytesFromHandshake() const { return m_nonce_bytes_from_handshake; } 507 508 size_t nonceBytesFromRecord() const { return m_nonce_bytes_from_record; } 509 510 size_t macKeylen() const { return m_mac_keylen; } 511 512 /** 513 * Returns: true if this is a valid/known ciphersuite 514 */ 515 bool valid() const 516 { 517 if (!m_cipher_keylen) // uninitialized object 518 return false; 519 520 AlgorithmFactory af = globalState().algorithmFactory(); 521 522 if (!af.prototypeHashFunction(prfAlgo())) 523 return false; 524 525 if (macAlgo() == "AEAD") 526 { 527 if (cipherAlgo() == "ChaCha20Poly1305") 528 { 529 static if (!BOTAN_HAS_AEAD_CHACHA20_POLY1305) { 530 return false; 531 } 532 } 533 else { 534 static string last_cipher_algo; 535 static Vector!string last_cipher_and_mode; 536 Vector!string cipher_and_mode; 537 if (last_cipher_algo == cipherAlgo()) 538 cipher_and_mode = last_cipher_and_mode.dup; 539 else { 540 cipher_and_mode = splitter(cipherAlgo(), '/'); 541 last_cipher_and_mode = cipher_and_mode.dup; 542 last_cipher_algo = cipherAlgo(); 543 } 544 assert(cipher_and_mode.length == 2, "Expected format for AEAD algo"); 545 if (!af.prototypeBlockCipher(cipher_and_mode[0])) 546 return false; 547 548 const auto mode = cipher_and_mode[1]; 549 550 static if (!BOTAN_HAS_AEAD_CCM) { 551 if (mode == "CCM" || mode == "CCM-8") 552 return false; 553 } 554 555 static if (!BOTAN_HAS_AEAD_GCM) { 556 if (mode == "GCM") 557 return false; 558 } 559 560 static if (!BOTAN_HAS_AEAD_OCB) { 561 if (mode == "OCB") 562 return false; 563 } 564 } 565 } 566 else 567 { 568 if (!af.prototypeBlockCipher(cipherAlgo()) && 569 !af.prototypeStreamCipher(cipherAlgo())) 570 return false; 571 572 if (!af.prototypeHashFunction(macAlgo())) 573 return false; 574 } 575 576 if (kexAlgo() == "SRP_SHA") 577 { 578 static if (!BOTAN_HAS_SRP6) { 579 return false; 580 } 581 } 582 else if (kexAlgo() == "ECDH" || kexAlgo() == "ECDHE_PSK") 583 { 584 static if (!BOTAN_HAS_ECDH) { 585 return false; 586 } 587 } 588 else if (kexAlgo() == "DH" || kexAlgo() == "DHE_PSK") 589 { 590 static if (!BOTAN_HAS_DIFFIE_HELLMAN) { 591 return false; 592 } 593 } 594 595 if (sigAlgo() == "DSA") 596 { 597 static if (!BOTAN_HAS_DSA) { 598 return false; 599 } 600 } 601 else if (sigAlgo() == "ECDSA") 602 { 603 static if (!BOTAN_HAS_ECDSA) { 604 return false; 605 } 606 } 607 else if (sigAlgo() == "RSA") 608 { 609 static if (!BOTAN_HAS_RSA) { 610 return false; 611 } 612 } 613 614 return true; 615 } 616 private: 617 this(ushort ciphersuite_code, 618 string sig_algo, 619 string kex_algo, 620 string cipher_algo, 621 size_t cipher_keylen, 622 size_t nonce_bytes_from_handshake, 623 size_t nonce_bytes_from_record, 624 string mac_algo, 625 size_t mac_keylen, 626 string prf_algo = "") 627 { 628 m_ciphersuite_code = ciphersuite_code; 629 m_sig_algo = sig_algo; 630 m_kex_algo = kex_algo; 631 m_prf_algo = prf_algo; 632 m_cipher_algo = cipher_algo; 633 m_cipher_keylen = cipher_keylen; 634 m_nonce_bytes_from_handshake = nonce_bytes_from_handshake; 635 m_nonce_bytes_from_record = nonce_bytes_from_record; 636 m_mac_algo = mac_algo; 637 m_mac_keylen = mac_keylen; 638 } 639 640 /* 641 * This way all work happens at the constuctor call, and we can 642 * rely on that happening only once in D 643 */ 644 static Vector!TLSCiphersuite gatherKnownCiphersuites() 645 { 646 Vector!TLSCiphersuite ciphersuites; 647 648 for (size_t i = 0; i <= 0xFFFF; ++i) 649 { 650 TLSCiphersuite suite = byId(cast(ushort)i); 651 652 if (suite.valid()) 653 ciphersuites.pushBack(suite); 654 } 655 656 return ciphersuites; 657 } 658 659 ushort m_ciphersuite_code; 660 661 string m_sig_algo; 662 string m_kex_algo; 663 string m_prf_algo; 664 string m_cipher_algo; 665 666 size_t m_cipher_keylen; 667 size_t m_cipher_ivlen; 668 size_t m_nonce_bytes_from_handshake; 669 size_t m_nonce_bytes_from_record; 670 string m_mac_algo; 671 size_t m_mac_keylen; 672 } 673 674 ptrdiff_t find(string str, string str2) { 675 import std.algorithm : countUntil; 676 return str.countUntil(str2); 677 }