Added CCM and CCM_8 cipher suites.
[BoarSSL] / SSLTLS / SSL.cs
1 /*
2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining
5 * a copy of this software and associated documentation files (the
6 * "Software"), to deal in the Software without restriction, including
7 * without limitation the rights to use, copy, modify, merge, publish,
8 * distribute, sublicense, and/or sell copies of the Software, and to
9 * permit persons to whom the Software is furnished to do so, subject to
10 * the following conditions:
11 *
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
19 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
20 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
21 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22 * SOFTWARE.
23 */
24
25 using System;
26 using System.Collections.Generic;
27 using System.Security.Cryptography.X509Certificates;
28 using System.Text;
29
30 using Asn1;
31 using Crypto;
32 using XKeys;
33
34 namespace SSLTLS {
35
36 /*
37 * A fake class that serves as container for various constants.
38 */
39
40 public sealed class SSL {
41
42 /*
43 * Protocol versions.
44 */
45 public const int SSL30 = 0x0300;
46 public const int TLS10 = 0x0301;
47 public const int TLS11 = 0x0302;
48 public const int TLS12 = 0x0303;
49
50 /*
51 * Record types.
52 */
53 public const int CHANGE_CIPHER_SPEC = 20;
54 public const int ALERT = 21;
55 public const int HANDSHAKE = 22;
56 public const int APPLICATION_DATA = 23;
57
58 /*
59 * Alert levels.
60 */
61 public const int WARNING = 1;
62 public const int FATAL = 2;
63
64 /*
65 * Alert messages.
66 */
67 public const int CLOSE_NOTIFY = 0;
68 public const int UNEXPECTED_MESSAGE = 10;
69 public const int BAD_RECORD_MAC = 20;
70 public const int DECRYPTION_FAILED = 21;
71 public const int RECORD_OVERFLOW = 22;
72 public const int DECOMPRESSION_FAILURE = 30;
73 public const int HANDSHAKE_FAILURE = 40;
74 public const int BAD_CERTIFICATE = 42;
75 public const int UNSUPPORTED_CERTIFICATE = 43;
76 public const int CERTIFICATE_REVOKED = 44;
77 public const int CERTIFICATE_EXPIRED = 45;
78 public const int CERTIFICATE_UNKNOWN = 46;
79 public const int ILLEGAL_PARAMETER = 47;
80 public const int UNKNOWN_CA = 48;
81 public const int ACCESS_DENIED = 49;
82 public const int DECODE_ERROR = 50;
83 public const int DECRYPT_ERROR = 51;
84 public const int EXPORT_RESTRICTION = 60;
85 public const int PROTOCOL_VERSION = 70;
86 public const int INSUFFICIENT_SECURITY = 71;
87 public const int INTERNAL_ERROR = 80;
88 public const int USER_CANCELED = 90;
89 public const int NO_RENEGOTIATION = 100;
90
91 /*
92 * Handshake message types.
93 */
94 public const int HELLO_REQUEST = 0;
95 public const int CLIENT_HELLO = 1;
96 public const int SERVER_HELLO = 2;
97 public const int CERTIFICATE = 11;
98 public const int SERVER_KEY_EXCHANGE = 12;
99 public const int CERTIFICATE_REQUEST = 13;
100 public const int SERVER_HELLO_DONE = 14;
101 public const int CERTIFICATE_VERIFY = 15;
102 public const int CLIENT_KEY_EXCHANGE = 16;
103 public const int FINISHED = 20;
104
105 /*
106 * Cipher suites.
107 */
108
109 /* From RFC 5246 */
110 public const int NULL_WITH_NULL_NULL = 0x0000;
111 public const int RSA_WITH_NULL_MD5 = 0x0001;
112 public const int RSA_WITH_NULL_SHA = 0x0002;
113 public const int RSA_WITH_NULL_SHA256 = 0x003B;
114 public const int RSA_WITH_RC4_128_MD5 = 0x0004;
115 public const int RSA_WITH_RC4_128_SHA = 0x0005;
116 public const int RSA_WITH_3DES_EDE_CBC_SHA = 0x000A;
117 public const int RSA_WITH_AES_128_CBC_SHA = 0x002F;
118 public const int RSA_WITH_AES_256_CBC_SHA = 0x0035;
119 public const int RSA_WITH_AES_128_CBC_SHA256 = 0x003C;
120 public const int RSA_WITH_AES_256_CBC_SHA256 = 0x003D;
121 public const int DH_DSS_WITH_3DES_EDE_CBC_SHA = 0x000D;
122 public const int DH_RSA_WITH_3DES_EDE_CBC_SHA = 0x0010;
123 public const int DHE_DSS_WITH_3DES_EDE_CBC_SHA = 0x0013;
124 public const int DHE_RSA_WITH_3DES_EDE_CBC_SHA = 0x0016;
125 public const int DH_DSS_WITH_AES_128_CBC_SHA = 0x0030;
126 public const int DH_RSA_WITH_AES_128_CBC_SHA = 0x0031;
127 public const int DHE_DSS_WITH_AES_128_CBC_SHA = 0x0032;
128 public const int DHE_RSA_WITH_AES_128_CBC_SHA = 0x0033;
129 public const int DH_DSS_WITH_AES_256_CBC_SHA = 0x0036;
130 public const int DH_RSA_WITH_AES_256_CBC_SHA = 0x0037;
131 public const int DHE_DSS_WITH_AES_256_CBC_SHA = 0x0038;
132 public const int DHE_RSA_WITH_AES_256_CBC_SHA = 0x0039;
133 public const int DH_DSS_WITH_AES_128_CBC_SHA256 = 0x003E;
134 public const int DH_RSA_WITH_AES_128_CBC_SHA256 = 0x003F;
135 public const int DHE_DSS_WITH_AES_128_CBC_SHA256 = 0x0040;
136 public const int DHE_RSA_WITH_AES_128_CBC_SHA256 = 0x0067;
137 public const int DH_DSS_WITH_AES_256_CBC_SHA256 = 0x0068;
138 public const int DH_RSA_WITH_AES_256_CBC_SHA256 = 0x0069;
139 public const int DHE_DSS_WITH_AES_256_CBC_SHA256 = 0x006A;
140 public const int DHE_RSA_WITH_AES_256_CBC_SHA256 = 0x006B;
141 public const int DH_anon_WITH_RC4_128_MD5 = 0x0018;
142 public const int DH_anon_WITH_3DES_EDE_CBC_SHA = 0x001B;
143 public const int DH_anon_WITH_AES_128_CBC_SHA = 0x0034;
144 public const int DH_anon_WITH_AES_256_CBC_SHA = 0x003A;
145 public const int DH_anon_WITH_AES_128_CBC_SHA256 = 0x006C;
146 public const int DH_anon_WITH_AES_256_CBC_SHA256 = 0x006D;
147
148 /* From RFC 4492 */
149 public const int ECDH_ECDSA_WITH_NULL_SHA = 0xC001;
150 public const int ECDH_ECDSA_WITH_RC4_128_SHA = 0xC002;
151 public const int ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC003;
152 public const int ECDH_ECDSA_WITH_AES_128_CBC_SHA = 0xC004;
153 public const int ECDH_ECDSA_WITH_AES_256_CBC_SHA = 0xC005;
154 public const int ECDHE_ECDSA_WITH_NULL_SHA = 0xC006;
155 public const int ECDHE_ECDSA_WITH_RC4_128_SHA = 0xC007;
156 public const int ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA = 0xC008;
157 public const int ECDHE_ECDSA_WITH_AES_128_CBC_SHA = 0xC009;
158 public const int ECDHE_ECDSA_WITH_AES_256_CBC_SHA = 0xC00A;
159 public const int ECDH_RSA_WITH_NULL_SHA = 0xC00B;
160 public const int ECDH_RSA_WITH_RC4_128_SHA = 0xC00C;
161 public const int ECDH_RSA_WITH_3DES_EDE_CBC_SHA = 0xC00D;
162 public const int ECDH_RSA_WITH_AES_128_CBC_SHA = 0xC00E;
163 public const int ECDH_RSA_WITH_AES_256_CBC_SHA = 0xC00F;
164 public const int ECDHE_RSA_WITH_NULL_SHA = 0xC010;
165 public const int ECDHE_RSA_WITH_RC4_128_SHA = 0xC011;
166 public const int ECDHE_RSA_WITH_3DES_EDE_CBC_SHA = 0xC012;
167 public const int ECDHE_RSA_WITH_AES_128_CBC_SHA = 0xC013;
168 public const int ECDHE_RSA_WITH_AES_256_CBC_SHA = 0xC014;
169 public const int ECDH_anon_WITH_NULL_SHA = 0xC015;
170 public const int ECDH_anon_WITH_RC4_128_SHA = 0xC016;
171 public const int ECDH_anon_WITH_3DES_EDE_CBC_SHA = 0xC017;
172 public const int ECDH_anon_WITH_AES_128_CBC_SHA = 0xC018;
173 public const int ECDH_anon_WITH_AES_256_CBC_SHA = 0xC019;
174
175 /* From RFC 5288 */
176 public const int RSA_WITH_AES_128_GCM_SHA256 = 0x009C;
177 public const int RSA_WITH_AES_256_GCM_SHA384 = 0x009D;
178 public const int DHE_RSA_WITH_AES_128_GCM_SHA256 = 0x009E;
179 public const int DHE_RSA_WITH_AES_256_GCM_SHA384 = 0x009F;
180 public const int DH_RSA_WITH_AES_128_GCM_SHA256 = 0x00A0;
181 public const int DH_RSA_WITH_AES_256_GCM_SHA384 = 0x00A1;
182 public const int DHE_DSS_WITH_AES_128_GCM_SHA256 = 0x00A2;
183 public const int DHE_DSS_WITH_AES_256_GCM_SHA384 = 0x00A3;
184 public const int DH_DSS_WITH_AES_128_GCM_SHA256 = 0x00A4;
185 public const int DH_DSS_WITH_AES_256_GCM_SHA384 = 0x00A5;
186 public const int DH_anon_WITH_AES_128_GCM_SHA256 = 0x00A6;
187 public const int DH_anon_WITH_AES_256_GCM_SHA384 = 0x00A7;
188
189 /* From RFC 5289 */
190 public const int ECDHE_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC023;
191 public const int ECDHE_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC024;
192 public const int ECDH_ECDSA_WITH_AES_128_CBC_SHA256 = 0xC025;
193 public const int ECDH_ECDSA_WITH_AES_256_CBC_SHA384 = 0xC026;
194 public const int ECDHE_RSA_WITH_AES_128_CBC_SHA256 = 0xC027;
195 public const int ECDHE_RSA_WITH_AES_256_CBC_SHA384 = 0xC028;
196 public const int ECDH_RSA_WITH_AES_128_CBC_SHA256 = 0xC029;
197 public const int ECDH_RSA_WITH_AES_256_CBC_SHA384 = 0xC02A;
198 public const int ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02B;
199 public const int ECDHE_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02C;
200 public const int ECDH_ECDSA_WITH_AES_128_GCM_SHA256 = 0xC02D;
201 public const int ECDH_ECDSA_WITH_AES_256_GCM_SHA384 = 0xC02E;
202 public const int ECDHE_RSA_WITH_AES_128_GCM_SHA256 = 0xC02F;
203 public const int ECDHE_RSA_WITH_AES_256_GCM_SHA384 = 0xC030;
204 public const int ECDH_RSA_WITH_AES_128_GCM_SHA256 = 0xC031;
205 public const int ECDH_RSA_WITH_AES_256_GCM_SHA384 = 0xC032;
206
207 /* From RFC 6655 and 7251 */
208 public const int RSA_WITH_AES_128_CCM = 0xC09C;
209 public const int RSA_WITH_AES_256_CCM = 0xC09D;
210 public const int RSA_WITH_AES_128_CCM_8 = 0xC0A0;
211 public const int RSA_WITH_AES_256_CCM_8 = 0xC0A1;
212 public const int ECDHE_ECDSA_WITH_AES_128_CCM = 0xC0AC;
213 public const int ECDHE_ECDSA_WITH_AES_256_CCM = 0xC0AD;
214 public const int ECDHE_ECDSA_WITH_AES_128_CCM_8 = 0xC0AE;
215 public const int ECDHE_ECDSA_WITH_AES_256_CCM_8 = 0xC0AF;
216
217 /* From RFC 7905 */
218 public const int ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8;
219 public const int ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9;
220 public const int DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA;
221 public const int PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB;
222 public const int ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC;
223 public const int DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD;
224 public const int RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE;
225
226 /* From RFC 7507 */
227 public const int FALLBACK_SCSV = 0x5600;
228
229 /* From RFC 5746 */
230 public const int EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF;
231
232 /*
233 * Client certificate types.
234 */
235 public const int RSA_SIGN = 1;
236 public const int DSS_SIGN = 2;
237 public const int RSA_FIXED_DH = 3;
238 public const int DSS_FIXED_DH = 4;
239
240 /*
241 * Hash algorithm identifiers. The special "MD5SHA1" is for use
242 * with RSA signatures in TLS 1.0 and 1.1 only.
243 */
244 public const int MD5SHA1 = 0;
245 public const int MD5 = 1;
246 public const int SHA1 = 2;
247 public const int SHA224 = 3;
248 public const int SHA256 = 4;
249 public const int SHA384 = 5;
250 public const int SHA512 = 6;
251
252 /*
253 * Signature algorithm identifiers.
254 */
255 public const int RSA = 1;
256 public const int DSA = 2;
257 public const int ECDSA = 3;
258
259 /*
260 * Combined hash-and-sign algorithms.
261 */
262 public const int RSA_MD5SHA1 = (MD5SHA1 << 8) + RSA;
263 public const int RSA_MD5 = (MD5 << 8) + RSA;
264 public const int RSA_SHA1 = (SHA1 << 8) + RSA;
265 public const int RSA_SHA224 = (SHA224 << 8) + RSA;
266 public const int RSA_SHA256 = (SHA256 << 8) + RSA;
267 public const int RSA_SHA384 = (SHA384 << 8) + RSA;
268 public const int RSA_SHA512 = (SHA512 << 8) + RSA;
269 public const int ECDSA_MD5 = (MD5 << 8) + ECDSA;
270 public const int ECDSA_SHA1 = (SHA1 << 8) + ECDSA;
271 public const int ECDSA_SHA224 = (SHA224 << 8) + ECDSA;
272 public const int ECDSA_SHA256 = (SHA256 << 8) + ECDSA;
273 public const int ECDSA_SHA384 = (SHA384 << 8) + ECDSA;
274 public const int ECDSA_SHA512 = (SHA512 << 8) + ECDSA;
275
276 /*
277 * Symbolic identifiers for named curves.
278 */
279 public const int NIST_P256 = 23;
280 public const int NIST_P384 = 24;
281 public const int NIST_P521 = 25;
282 public const int Curve25519 = 29;
283
284 /*
285 * Get a human-readable name for a version.
286 */
287 public static string VersionName(int version)
288 {
289 switch (version) {
290 case SSL30: return "SSL 3.0";
291 case TLS10: return "TLS 1.0";
292 case TLS11: return "TLS 1.1";
293 case TLS12: return "TLS 1.2";
294 }
295 if ((version >> 8) == 3) {
296 return String.Format("TLS 1.{0}", (version & 0xFF) - 1);
297 }
298 return String.Format("UNKNOWN:0x{0:X4}", version);
299 }
300
301 /*
302 * Parse a version name.
303 */
304 public static int GetVersionByName(string s)
305 {
306 string t = s.Trim().Replace(" ", "").Replace(".", "")
307 .Replace("-", "").ToUpperInvariant();
308 switch (t) {
309 case "SSL3":
310 case "SSLV3":
311 case "SSL30":
312 case "SSLV30":
313 return SSL30;
314 case "TLS1":
315 case "TLSV1":
316 case "TLS10":
317 case "TLSV10":
318 return TLS10;
319 case "TLS11":
320 case "TLSV11":
321 return TLS11;
322 case "TLS12":
323 case "TLSV12":
324 return TLS12;
325 default:
326 throw new Exception(string.Format(
327 "Unknown protocol version: '{0}'", s));
328 }
329 }
330
331 /*
332 * Get a human-readable name for a cipher suite.
333 */
334 public static string CipherSuiteName(int cipherSuite)
335 {
336 switch (cipherSuite) {
337 case NULL_WITH_NULL_NULL:
338 return "NULL_WITH_NULL_NULL";
339 case RSA_WITH_NULL_MD5:
340 return "RSA_WITH_NULL_MD5";
341 case RSA_WITH_NULL_SHA:
342 return "RSA_WITH_NULL_SHA";
343 case RSA_WITH_NULL_SHA256:
344 return "RSA_WITH_NULL_SHA256";
345 case RSA_WITH_RC4_128_MD5:
346 return "RSA_WITH_RC4_128_MD5";
347 case RSA_WITH_RC4_128_SHA:
348 return "RSA_WITH_RC4_128_SHA";
349 case RSA_WITH_3DES_EDE_CBC_SHA:
350 return "RSA_WITH_3DES_EDE_CBC_SHA";
351 case RSA_WITH_AES_128_CBC_SHA:
352 return "RSA_WITH_AES_128_CBC_SHA";
353 case RSA_WITH_AES_256_CBC_SHA:
354 return "RSA_WITH_AES_256_CBC_SHA";
355 case RSA_WITH_AES_128_CBC_SHA256:
356 return "RSA_WITH_AES_128_CBC_SHA256";
357 case RSA_WITH_AES_256_CBC_SHA256:
358 return "RSA_WITH_AES_256_CBC_SHA256";
359 case DH_DSS_WITH_3DES_EDE_CBC_SHA:
360 return "DH_DSS_WITH_3DES_EDE_CBC_SHA";
361 case DH_RSA_WITH_3DES_EDE_CBC_SHA:
362 return "DH_RSA_WITH_3DES_EDE_CBC_SHA";
363 case DHE_DSS_WITH_3DES_EDE_CBC_SHA:
364 return "DHE_DSS_WITH_3DES_EDE_CBC_SHA";
365 case DHE_RSA_WITH_3DES_EDE_CBC_SHA:
366 return "DHE_RSA_WITH_3DES_EDE_CBC_SHA";
367 case DH_DSS_WITH_AES_128_CBC_SHA:
368 return "DH_DSS_WITH_AES_128_CBC_SHA";
369 case DH_RSA_WITH_AES_128_CBC_SHA:
370 return "DH_RSA_WITH_AES_128_CBC_SHA";
371 case DHE_DSS_WITH_AES_128_CBC_SHA:
372 return "DHE_DSS_WITH_AES_128_CBC_SHA";
373 case DHE_RSA_WITH_AES_128_CBC_SHA:
374 return "DHE_RSA_WITH_AES_128_CBC_SHA";
375 case DH_DSS_WITH_AES_256_CBC_SHA:
376 return "DH_DSS_WITH_AES_256_CBC_SHA";
377 case DH_RSA_WITH_AES_256_CBC_SHA:
378 return "DH_RSA_WITH_AES_256_CBC_SHA";
379 case DHE_DSS_WITH_AES_256_CBC_SHA:
380 return "DHE_DSS_WITH_AES_256_CBC_SHA";
381 case DHE_RSA_WITH_AES_256_CBC_SHA:
382 return "DHE_RSA_WITH_AES_256_CBC_SHA";
383 case DH_DSS_WITH_AES_128_CBC_SHA256:
384 return "DH_DSS_WITH_AES_128_CBC_SHA256";
385 case DH_RSA_WITH_AES_128_CBC_SHA256:
386 return "DH_RSA_WITH_AES_128_CBC_SHA256";
387 case DHE_DSS_WITH_AES_128_CBC_SHA256:
388 return "DHE_DSS_WITH_AES_128_CBC_SHA256";
389 case DHE_RSA_WITH_AES_128_CBC_SHA256:
390 return "DHE_RSA_WITH_AES_128_CBC_SHA256";
391 case DH_DSS_WITH_AES_256_CBC_SHA256:
392 return "DH_DSS_WITH_AES_256_CBC_SHA256";
393 case DH_RSA_WITH_AES_256_CBC_SHA256:
394 return "DH_RSA_WITH_AES_256_CBC_SHA256";
395 case DHE_DSS_WITH_AES_256_CBC_SHA256:
396 return "DHE_DSS_WITH_AES_256_CBC_SHA256";
397 case DHE_RSA_WITH_AES_256_CBC_SHA256:
398 return "DHE_RSA_WITH_AES_256_CBC_SHA256";
399 case DH_anon_WITH_RC4_128_MD5:
400 return "DH_anon_WITH_RC4_128_MD5";
401 case DH_anon_WITH_3DES_EDE_CBC_SHA:
402 return "DH_anon_WITH_3DES_EDE_CBC_SHA";
403 case DH_anon_WITH_AES_128_CBC_SHA:
404 return "DH_anon_WITH_AES_128_CBC_SHA";
405 case DH_anon_WITH_AES_256_CBC_SHA:
406 return "DH_anon_WITH_AES_256_CBC_SHA";
407 case DH_anon_WITH_AES_128_CBC_SHA256:
408 return "DH_anon_WITH_AES_128_CBC_SHA256";
409 case DH_anon_WITH_AES_256_CBC_SHA256:
410 return "DH_anon_WITH_AES_256_CBC_SHA256";
411 case ECDH_ECDSA_WITH_NULL_SHA:
412 return "ECDH_ECDSA_WITH_NULL_SHA";
413 case ECDH_ECDSA_WITH_RC4_128_SHA:
414 return "ECDH_ECDSA_WITH_RC4_128_SHA";
415 case ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
416 return "ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
417 case ECDH_ECDSA_WITH_AES_128_CBC_SHA:
418 return "ECDH_ECDSA_WITH_AES_128_CBC_SHA";
419 case ECDH_ECDSA_WITH_AES_256_CBC_SHA:
420 return "ECDH_ECDSA_WITH_AES_256_CBC_SHA";
421 case ECDHE_ECDSA_WITH_NULL_SHA:
422 return "ECDHE_ECDSA_WITH_NULL_SHA";
423 case ECDHE_ECDSA_WITH_RC4_128_SHA:
424 return "ECDHE_ECDSA_WITH_RC4_128_SHA";
425 case ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
426 return "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
427 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
428 return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
429 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
430 return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
431 case ECDH_RSA_WITH_NULL_SHA:
432 return "ECDH_RSA_WITH_NULL_SHA";
433 case ECDH_RSA_WITH_RC4_128_SHA:
434 return "ECDH_RSA_WITH_RC4_128_SHA";
435 case ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
436 return "ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
437 case ECDH_RSA_WITH_AES_128_CBC_SHA:
438 return "ECDH_RSA_WITH_AES_128_CBC_SHA";
439 case ECDH_RSA_WITH_AES_256_CBC_SHA:
440 return "ECDH_RSA_WITH_AES_256_CBC_SHA";
441 case ECDHE_RSA_WITH_NULL_SHA:
442 return "ECDHE_RSA_WITH_NULL_SHA";
443 case ECDHE_RSA_WITH_RC4_128_SHA:
444 return "ECDHE_RSA_WITH_RC4_128_SHA";
445 case ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
446 return "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
447 case ECDHE_RSA_WITH_AES_128_CBC_SHA:
448 return "ECDHE_RSA_WITH_AES_128_CBC_SHA";
449 case ECDHE_RSA_WITH_AES_256_CBC_SHA:
450 return "ECDHE_RSA_WITH_AES_256_CBC_SHA";
451 case ECDH_anon_WITH_NULL_SHA:
452 return "ECDH_anon_WITH_NULL_SHA";
453 case ECDH_anon_WITH_RC4_128_SHA:
454 return "ECDH_anon_WITH_RC4_128_SHA";
455 case ECDH_anon_WITH_3DES_EDE_CBC_SHA:
456 return "ECDH_anon_WITH_3DES_EDE_CBC_SHA";
457 case ECDH_anon_WITH_AES_128_CBC_SHA:
458 return "ECDH_anon_WITH_AES_128_CBC_SHA";
459 case ECDH_anon_WITH_AES_256_CBC_SHA:
460 return "ECDH_anon_WITH_AES_256_CBC_SHA";
461 case RSA_WITH_AES_128_GCM_SHA256:
462 return "RSA_WITH_AES_128_GCM_SHA256";
463 case RSA_WITH_AES_256_GCM_SHA384:
464 return "RSA_WITH_AES_256_GCM_SHA384";
465 case DHE_RSA_WITH_AES_128_GCM_SHA256:
466 return "DHE_RSA_WITH_AES_128_GCM_SHA256";
467 case DHE_RSA_WITH_AES_256_GCM_SHA384:
468 return "DHE_RSA_WITH_AES_256_GCM_SHA384";
469 case DH_RSA_WITH_AES_128_GCM_SHA256:
470 return "DH_RSA_WITH_AES_128_GCM_SHA256";
471 case DH_RSA_WITH_AES_256_GCM_SHA384:
472 return "DH_RSA_WITH_AES_256_GCM_SHA384";
473 case DHE_DSS_WITH_AES_128_GCM_SHA256:
474 return "DHE_DSS_WITH_AES_128_GCM_SHA256";
475 case DHE_DSS_WITH_AES_256_GCM_SHA384:
476 return "DHE_DSS_WITH_AES_256_GCM_SHA384";
477 case DH_DSS_WITH_AES_128_GCM_SHA256:
478 return "DH_DSS_WITH_AES_128_GCM_SHA256";
479 case DH_DSS_WITH_AES_256_GCM_SHA384:
480 return "DH_DSS_WITH_AES_256_GCM_SHA384";
481 case DH_anon_WITH_AES_128_GCM_SHA256:
482 return "DH_anon_WITH_AES_128_GCM_SHA256";
483 case DH_anon_WITH_AES_256_GCM_SHA384:
484 return "DH_anon_WITH_AES_256_GCM_SHA384";
485 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
486 return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
487 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
488 return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
489 case ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
490 return "ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
491 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
492 return "ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
493 case ECDHE_RSA_WITH_AES_128_CBC_SHA256:
494 return "ECDHE_RSA_WITH_AES_128_CBC_SHA256";
495 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
496 return "ECDHE_RSA_WITH_AES_256_CBC_SHA384";
497 case ECDH_RSA_WITH_AES_128_CBC_SHA256:
498 return "ECDH_RSA_WITH_AES_128_CBC_SHA256";
499 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
500 return "ECDH_RSA_WITH_AES_256_CBC_SHA384";
501 case ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
502 return "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
503 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
504 return "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
505 case ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
506 return "ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
507 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
508 return "ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
509 case ECDHE_RSA_WITH_AES_128_GCM_SHA256:
510 return "ECDHE_RSA_WITH_AES_128_GCM_SHA256";
511 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
512 return "ECDHE_RSA_WITH_AES_256_GCM_SHA384";
513 case ECDH_RSA_WITH_AES_128_GCM_SHA256:
514 return "ECDH_RSA_WITH_AES_128_GCM_SHA256";
515 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
516 return "ECDH_RSA_WITH_AES_256_GCM_SHA384";
517 case RSA_WITH_AES_128_CCM:
518 return "RSA_WITH_AES_128_CCM";
519 case RSA_WITH_AES_256_CCM:
520 return "RSA_WITH_AES_256_CCM";
521 case RSA_WITH_AES_128_CCM_8:
522 return "RSA_WITH_AES_128_CCM_8";
523 case RSA_WITH_AES_256_CCM_8:
524 return "RSA_WITH_AES_256_CCM_8";
525 case ECDHE_ECDSA_WITH_AES_128_CCM:
526 return "ECDHE_ECDSA_WITH_AES_128_CCM";
527 case ECDHE_ECDSA_WITH_AES_256_CCM:
528 return "ECDHE_ECDSA_WITH_AES_256_CCM";
529 case ECDHE_ECDSA_WITH_AES_128_CCM_8:
530 return "ECDHE_ECDSA_WITH_AES_128_CCM_8";
531 case ECDHE_ECDSA_WITH_AES_256_CCM_8:
532 return "ECDHE_ECDSA_WITH_AES_256_CCM_8";
533 case ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
534 return "ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
535 case ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
536 return "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
537 case DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
538 return "DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
539 case PSK_WITH_CHACHA20_POLY1305_SHA256:
540 return "PSK_WITH_CHACHA20_POLY1305_SHA256";
541 case ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
542 return "ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
543 case DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
544 return "DHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
545 case RSA_PSK_WITH_CHACHA20_POLY1305_SHA256:
546 return "RSA_PSK_WITH_CHACHA20_POLY1305_SHA256";
547 case FALLBACK_SCSV:
548 return "FALLBACK_SCSV";
549 case EMPTY_RENEGOTIATION_INFO_SCSV:
550 return "EMPTY_RENEGOTIATION_INFO_SCSV";
551 default:
552 return String.Format("UNKNOWN:0x{0:X4}", cipherSuite);
553 }
554 }
555
556 /*
557 * Parse a cipher suite name.
558 */
559 public static int GetSuiteByName(string s)
560 {
561 string t = s.Trim().Replace("_", "").Replace("-", "")
562 .ToUpperInvariant();
563 if (t.StartsWith("TLS") || t.StartsWith("SSL")) {
564 t = t.Substring(3);
565 }
566 switch (t) {
567 case "NULLWITHNULLNULL":
568 return NULL_WITH_NULL_NULL;
569 case "RSAWITHNULLMD5":
570 return RSA_WITH_NULL_MD5;
571 case "RSAWITHNULLSHA":
572 return RSA_WITH_NULL_SHA;
573 case "RSAWITHNULLSHA256":
574 return RSA_WITH_NULL_SHA256;
575 case "RSAWITHRC4128MD5":
576 return RSA_WITH_RC4_128_MD5;
577 case "RSAWITHRC4128SHA":
578 return RSA_WITH_RC4_128_SHA;
579 case "RSAWITH3DESEDECBCSHA":
580 return RSA_WITH_3DES_EDE_CBC_SHA;
581 case "RSAWITHAES128CBCSHA":
582 return RSA_WITH_AES_128_CBC_SHA;
583 case "RSAWITHAES256CBCSHA":
584 return RSA_WITH_AES_256_CBC_SHA;
585 case "RSAWITHAES128CBCSHA256":
586 return RSA_WITH_AES_128_CBC_SHA256;
587 case "RSAWITHAES256CBCSHA256":
588 return RSA_WITH_AES_256_CBC_SHA256;
589 case "DHDSSWITH3DESEDECBCSHA":
590 return DH_DSS_WITH_3DES_EDE_CBC_SHA;
591 case "DHRSAWITH3DESEDECBCSHA":
592 return DH_RSA_WITH_3DES_EDE_CBC_SHA;
593 case "DHEDSSWITH3DESEDECBCSHA":
594 return DHE_DSS_WITH_3DES_EDE_CBC_SHA;
595 case "DHERSAWITH3DESEDECBCSHA":
596 return DHE_RSA_WITH_3DES_EDE_CBC_SHA;
597 case "DHDSSWITHAES128CBCSHA":
598 return DH_DSS_WITH_AES_128_CBC_SHA;
599 case "DHRSAWITHAES128CBCSHA":
600 return DH_RSA_WITH_AES_128_CBC_SHA;
601 case "DHEDSSWITHAES128CBCSHA":
602 return DHE_DSS_WITH_AES_128_CBC_SHA;
603 case "DHERSAWITHAES128CBCSHA":
604 return DHE_RSA_WITH_AES_128_CBC_SHA;
605 case "DHDSSWITHAES256CBCSHA":
606 return DH_DSS_WITH_AES_256_CBC_SHA;
607 case "DHRSAWITHAES256CBCSHA":
608 return DH_RSA_WITH_AES_256_CBC_SHA;
609 case "DHEDSSWITHAES256CBCSHA":
610 return DHE_DSS_WITH_AES_256_CBC_SHA;
611 case "DHERSAWITHAES256CBCSHA":
612 return DHE_RSA_WITH_AES_256_CBC_SHA;
613 case "DHDSSWITHAES128CBCSHA256":
614 return DH_DSS_WITH_AES_128_CBC_SHA256;
615 case "DHRSAWITHAES128CBCSHA256":
616 return DH_RSA_WITH_AES_128_CBC_SHA256;
617 case "DHEDSSWITHAES128CBCSHA256":
618 return DHE_DSS_WITH_AES_128_CBC_SHA256;
619 case "DHERSAWITHAES128CBCSHA256":
620 return DHE_RSA_WITH_AES_128_CBC_SHA256;
621 case "DHDSSWITHAES256CBCSHA256":
622 return DH_DSS_WITH_AES_256_CBC_SHA256;
623 case "DHRSAWITHAES256CBCSHA256":
624 return DH_RSA_WITH_AES_256_CBC_SHA256;
625 case "DHEDSSWITHAES256CBCSHA256":
626 return DHE_DSS_WITH_AES_256_CBC_SHA256;
627 case "DHERSAWITHAES256CBCSHA256":
628 return DHE_RSA_WITH_AES_256_CBC_SHA256;
629 case "DHANONWITHRC4128MD5":
630 return DH_anon_WITH_RC4_128_MD5;
631 case "DHANONWITH3DESEDECBCSHA":
632 return DH_anon_WITH_3DES_EDE_CBC_SHA;
633 case "DHANONWITHAES128CBCSHA":
634 return DH_anon_WITH_AES_128_CBC_SHA;
635 case "DHANONWITHAES256CBCSHA":
636 return DH_anon_WITH_AES_256_CBC_SHA;
637 case "DHANONWITHAES128CBCSHA256":
638 return DH_anon_WITH_AES_128_CBC_SHA256;
639 case "DHANONWITHAES256CBCSHA256":
640 return DH_anon_WITH_AES_256_CBC_SHA256;
641 case "ECDHECDSAWITHNULLSHA":
642 return ECDH_ECDSA_WITH_NULL_SHA;
643 case "ECDHECDSAWITHRC4128SHA":
644 return ECDH_ECDSA_WITH_RC4_128_SHA;
645 case "ECDHECDSAWITH3DESEDECBCSHA":
646 return ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA;
647 case "ECDHECDSAWITHAES128CBCSHA":
648 return ECDH_ECDSA_WITH_AES_128_CBC_SHA;
649 case "ECDHECDSAWITHAES256CBCSHA":
650 return ECDH_ECDSA_WITH_AES_256_CBC_SHA;
651 case "ECDHEECDSAWITHNULLSHA":
652 return ECDHE_ECDSA_WITH_NULL_SHA;
653 case "ECDHEECDSAWITHRC4128SHA":
654 return ECDHE_ECDSA_WITH_RC4_128_SHA;
655 case "ECDHEECDSAWITH3DESEDECBCSHA":
656 return ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA;
657 case "ECDHEECDSAWITHAES128CBCSHA":
658 return ECDHE_ECDSA_WITH_AES_128_CBC_SHA;
659 case "ECDHEECDSAWITHAES256CBCSHA":
660 return ECDHE_ECDSA_WITH_AES_256_CBC_SHA;
661 case "ECDHRSAWITHNULLSHA":
662 return ECDH_RSA_WITH_NULL_SHA;
663 case "ECDHRSAWITHRC4128SHA":
664 return ECDH_RSA_WITH_RC4_128_SHA;
665 case "ECDHRSAWITH3DESEDECBCSHA":
666 return ECDH_RSA_WITH_3DES_EDE_CBC_SHA;
667 case "ECDHRSAWITHAES128CBCSHA":
668 return ECDH_RSA_WITH_AES_128_CBC_SHA;
669 case "ECDHRSAWITHAES256CBCSHA":
670 return ECDH_RSA_WITH_AES_256_CBC_SHA;
671 case "ECDHERSAWITHNULLSHA":
672 return ECDHE_RSA_WITH_NULL_SHA;
673 case "ECDHERSAWITHRC4128SHA":
674 return ECDHE_RSA_WITH_RC4_128_SHA;
675 case "ECDHERSAWITH3DESEDECBCSHA":
676 return ECDHE_RSA_WITH_3DES_EDE_CBC_SHA;
677 case "ECDHERSAWITHAES128CBCSHA":
678 return ECDHE_RSA_WITH_AES_128_CBC_SHA;
679 case "ECDHERSAWITHAES256CBCSHA":
680 return ECDHE_RSA_WITH_AES_256_CBC_SHA;
681 case "ECDHANONWITHNULLSHA":
682 return ECDH_anon_WITH_NULL_SHA;
683 case "ECDHANONWITHRC4128SHA":
684 return ECDH_anon_WITH_RC4_128_SHA;
685 case "ECDHANONWITH3DESEDECBCSHA":
686 return ECDH_anon_WITH_3DES_EDE_CBC_SHA;
687 case "ECDHANONWITHAES128CBCSHA":
688 return ECDH_anon_WITH_AES_128_CBC_SHA;
689 case "ECDHANONWITHAES256CBCSHA":
690 return ECDH_anon_WITH_AES_256_CBC_SHA;
691 case "RSAWITHAES128GCMSHA256":
692 return RSA_WITH_AES_128_GCM_SHA256;
693 case "RSAWITHAES256GCMSHA384":
694 return RSA_WITH_AES_256_GCM_SHA384;
695 case "DHERSAWITHAES128GCMSHA256":
696 return DHE_RSA_WITH_AES_128_GCM_SHA256;
697 case "DHERSAWITHAES256GCMSHA384":
698 return DHE_RSA_WITH_AES_256_GCM_SHA384;
699 case "DHRSAWITHAES128GCMSHA256":
700 return DH_RSA_WITH_AES_128_GCM_SHA256;
701 case "DHRSAWITHAES256GCMSHA384":
702 return DH_RSA_WITH_AES_256_GCM_SHA384;
703 case "DHEDSSWITHAES128GCMSHA256":
704 return DHE_DSS_WITH_AES_128_GCM_SHA256;
705 case "DHEDSSWITHAES256GCMSHA384":
706 return DHE_DSS_WITH_AES_256_GCM_SHA384;
707 case "DHDSSWITHAES128GCMSHA256":
708 return DH_DSS_WITH_AES_128_GCM_SHA256;
709 case "DHDSSWITHAES256GCMSHA384":
710 return DH_DSS_WITH_AES_256_GCM_SHA384;
711 case "DHANONWITHAES128GCMSHA256":
712 return DH_anon_WITH_AES_128_GCM_SHA256;
713 case "DHANONWITHAES256GCMSHA384":
714 return DH_anon_WITH_AES_256_GCM_SHA384;
715 case "ECDHEECDSAWITHAES128CBCSHA256":
716 return ECDHE_ECDSA_WITH_AES_128_CBC_SHA256;
717 case "ECDHEECDSAWITHAES256CBCSHA384":
718 return ECDHE_ECDSA_WITH_AES_256_CBC_SHA384;
719 case "ECDHECDSAWITHAES128CBCSHA256":
720 return ECDH_ECDSA_WITH_AES_128_CBC_SHA256;
721 case "ECDHECDSAWITHAES256CBCSHA384":
722 return ECDH_ECDSA_WITH_AES_256_CBC_SHA384;
723 case "ECDHERSAWITHAES128CBCSHA256":
724 return ECDHE_RSA_WITH_AES_128_CBC_SHA256;
725 case "ECDHERSAWITHAES256CBCSHA384":
726 return ECDHE_RSA_WITH_AES_256_CBC_SHA384;
727 case "ECDHRSAWITHAES128CBCSHA256":
728 return ECDH_RSA_WITH_AES_128_CBC_SHA256;
729 case "ECDHRSAWITHAES256CBCSHA384":
730 return ECDH_RSA_WITH_AES_256_CBC_SHA384;
731 case "ECDHEECDSAWITHAES128GCMSHA256":
732 return ECDHE_ECDSA_WITH_AES_128_GCM_SHA256;
733 case "ECDHEECDSAWITHAES256GCMSHA384":
734 return ECDHE_ECDSA_WITH_AES_256_GCM_SHA384;
735 case "ECDHECDSAWITHAES128GCMSHA256":
736 return ECDH_ECDSA_WITH_AES_128_GCM_SHA256;
737 case "ECDHECDSAWITHAES256GCMSHA384":
738 return ECDH_ECDSA_WITH_AES_256_GCM_SHA384;
739 case "ECDHERSAWITHAES128GCMSHA256":
740 return ECDHE_RSA_WITH_AES_128_GCM_SHA256;
741 case "ECDHERSAWITHAES256GCMSHA384":
742 return ECDHE_RSA_WITH_AES_256_GCM_SHA384;
743 case "ECDHRSAWITHAES128GCMSHA256":
744 return ECDH_RSA_WITH_AES_128_GCM_SHA256;
745 case "ECDHRSAWITHAES256GCMSHA384":
746 return ECDH_RSA_WITH_AES_256_GCM_SHA384;
747 case "RSAWITHAES128CCM":
748 return RSA_WITH_AES_128_CCM;
749 case "RSAWITHAES256CCM":
750 return RSA_WITH_AES_256_CCM;
751 case "RSAWITHAES128CCM8":
752 return RSA_WITH_AES_128_CCM_8;
753 case "RSAWITHAES256CCM8":
754 return RSA_WITH_AES_256_CCM_8;
755 case "ECDHEECDSAWITHAES128CCM":
756 return ECDHE_ECDSA_WITH_AES_128_CCM;
757 case "ECDHEECDSAWITHAES256CCM":
758 return ECDHE_ECDSA_WITH_AES_256_CCM;
759 case "ECDHEECDSAWITHAES128CCM8":
760 return ECDHE_ECDSA_WITH_AES_128_CCM_8;
761 case "ECDHEECDSAWITHAES256CCM8":
762 return ECDHE_ECDSA_WITH_AES_256_CCM_8;
763 case "ECDHERSAWITHCHACHA20POLY1305SHA256":
764 return ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
765 case "ECDHEECDSAWITHCHACHA20POLY1305SHA256":
766 return ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256;
767 case "DHERSAWITHCHACHA20POLY1305SHA256":
768 return DHE_RSA_WITH_CHACHA20_POLY1305_SHA256;
769 case "PSKWITHCHACHA20POLY1305SHA256":
770 return PSK_WITH_CHACHA20_POLY1305_SHA256;
771 case "ECDHEPSKWITHCHACHA20POLY1305SHA256":
772 return ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
773 case "DHEPSKWITHCHACHA20POLY1305SHA256":
774 return DHE_PSK_WITH_CHACHA20_POLY1305_SHA256;
775 case "RSAPSKWITHCHACHA20POLY1305SHA256":
776 return RSA_PSK_WITH_CHACHA20_POLY1305_SHA256;
777
778 default:
779 throw new Exception(string.Format(
780 "Unknown cipher suite: '{0}'", s));
781 }
782 }
783
784 /*
785 * Get a human-readable name for a hash-and-sign algorithm.
786 */
787 public static string HashAndSignName(int hs)
788 {
789 switch (hs) {
790 case RSA_MD5: return "RSA_MD5";
791 case RSA_SHA1: return "RSA_SHA1";
792 case RSA_SHA224: return "RSA_SHA224";
793 case RSA_SHA256: return "RSA_SHA256";
794 case RSA_SHA384: return "RSA_SHA384";
795 case RSA_SHA512: return "RSA_SHA512";
796 case ECDSA_MD5: return "ECDSA_MD5";
797 case ECDSA_SHA1: return "ECDSA_SHA1";
798 case ECDSA_SHA224: return "ECDSA_SHA224";
799 case ECDSA_SHA256: return "ECDSA_SHA256";
800 case ECDSA_SHA384: return "ECDSA_SHA384";
801 case ECDSA_SHA512: return "ECDSA_SHA512";
802 default:
803 return String.Format("UNKNOWN:0x{0:X4}", hs);
804 }
805 }
806
807 /*
808 * Parse a hash-and-sign name.
809 */
810 public static int GetHashAndSignByName(string s)
811 {
812 string t = s.Trim().Replace(" ", "").Replace("_", "")
813 .Replace("-", "").Replace("/", "")
814 .ToUpperInvariant();
815 switch (t) {
816 case "RSAMD5": return RSA_MD5;
817 case "RSASHA1": return RSA_SHA1;
818 case "RSASHA224": return RSA_SHA224;
819 case "RSASHA256": return RSA_SHA256;
820 case "RSASHA384": return RSA_SHA384;
821 case "RSASHA512": return RSA_SHA512;
822 case "ECDSAMD5": return ECDSA_MD5;
823 case "ECDSASHA1": return ECDSA_SHA1;
824 case "ECDSASHA224": return ECDSA_SHA224;
825 case "ECDSASHA256": return ECDSA_SHA256;
826 case "ECDSASHA384": return ECDSA_SHA384;
827 case "ECDSASHA512": return ECDSA_SHA512;
828 default:
829 throw new Exception(string.Format(
830 "Unknown hash-and-sign: '{0}'", s));
831 }
832 }
833
834 /*
835 * Get a human-readable name for a curve.
836 */
837 public static string CurveName(int id)
838 {
839 switch (id) {
840 case Curve25519: return "Curve25519";
841 case NIST_P256: return "NIST_P256";
842 case NIST_P384: return "NIST_P384";
843 case NIST_P521: return "NIST_P521";
844 default:
845 return String.Format("UNKNOWN:0x{0:X4}", id);
846 }
847 }
848
849 /*
850 * Get a curve by name.
851 */
852 public static int GetCurveByName(string s)
853 {
854 string t = s.Trim().Replace(" ", "").Replace("_", "")
855 .Replace("-", "").ToLowerInvariant();
856 switch (t) {
857 case "c25519":
858 case "curve25519":
859 return Curve25519;
860 case "secp256r1":
861 case "p256":
862 case "nistp256":
863 case "prime256":
864 case "prime256v1":
865 return NIST_P256;
866 case "secp384r1":
867 case "p384":
868 case "nistp384":
869 return NIST_P384;
870 case "secp521r1":
871 case "p521":
872 case "nistp521":
873 return NIST_P521;
874 default:
875 throw new Exception(string.Format(
876 "Unknown curve: '{0}'", s));
877 }
878 }
879
880 /*
881 * Extract the public key from an encoded X.509 certificate.
882 * This does NOT make any attempt at validating the certificate.
883 */
884 internal static IPublicKey GetKeyFromCert(byte[] cert)
885 {
886 AsnElt ae = AsnElt.Decode(cert);
887 ae.CheckTag(AsnElt.SEQUENCE);
888 ae.CheckNumSub(3);
889 ae = ae.GetSub(0);
890 ae.CheckTag(AsnElt.SEQUENCE);
891 ae.CheckNumSubMin(6);
892 int off = 5;
893 if (ae.GetSub(0).TagValue != AsnElt.INTEGER) {
894 ae.CheckNumSubMin(7);
895 off ++;
896 }
897 return KF.DecodePublicKey(ae.GetSub(off));
898 }
899
900 internal static bool IsRSA(int cs)
901 {
902 switch (cs) {
903 case RSA_WITH_RC4_128_MD5:
904 case RSA_WITH_RC4_128_SHA:
905 case RSA_WITH_3DES_EDE_CBC_SHA:
906 case RSA_WITH_AES_128_CBC_SHA:
907 case RSA_WITH_AES_256_CBC_SHA:
908 case RSA_WITH_AES_128_CBC_SHA256:
909 case RSA_WITH_AES_256_CBC_SHA256:
910 case RSA_WITH_AES_128_GCM_SHA256:
911 case RSA_WITH_AES_256_GCM_SHA384:
912 case RSA_WITH_AES_128_CCM:
913 case RSA_WITH_AES_256_CCM:
914 case RSA_WITH_AES_128_CCM_8:
915 case RSA_WITH_AES_256_CCM_8:
916 return true;
917 default:
918 return false;
919 }
920 }
921
922 internal static bool IsDH_DSA(int cs)
923 {
924 switch (cs) {
925 case DH_DSS_WITH_3DES_EDE_CBC_SHA:
926 case DH_DSS_WITH_AES_128_CBC_SHA:
927 case DH_DSS_WITH_AES_256_CBC_SHA:
928 case DH_DSS_WITH_AES_128_CBC_SHA256:
929 case DH_DSS_WITH_AES_256_CBC_SHA256:
930 case DH_DSS_WITH_AES_128_GCM_SHA256:
931 case DH_DSS_WITH_AES_256_GCM_SHA384:
932 return true;
933 default:
934 return false;
935 }
936 }
937
938 internal static bool IsDH_RSA(int cs)
939 {
940 switch (cs) {
941 case DH_RSA_WITH_3DES_EDE_CBC_SHA:
942 case DH_RSA_WITH_AES_128_CBC_SHA:
943 case DH_RSA_WITH_AES_256_CBC_SHA:
944 case DH_RSA_WITH_AES_128_CBC_SHA256:
945 case DH_RSA_WITH_AES_256_CBC_SHA256:
946 case DH_RSA_WITH_AES_128_GCM_SHA256:
947 case DH_RSA_WITH_AES_256_GCM_SHA384:
948 return true;
949 default:
950 return false;
951 }
952 }
953
954 internal static bool IsDH(int cs)
955 {
956 return IsDH_DSA(cs) || IsDH_RSA(cs);
957 }
958
959 internal static bool IsDHE_DSS(int cs)
960 {
961 switch (cs) {
962 case DHE_DSS_WITH_3DES_EDE_CBC_SHA:
963 case DHE_DSS_WITH_AES_128_CBC_SHA:
964 case DHE_DSS_WITH_AES_256_CBC_SHA:
965 case DHE_DSS_WITH_AES_128_CBC_SHA256:
966 case DHE_DSS_WITH_AES_256_CBC_SHA256:
967 case DHE_DSS_WITH_AES_128_GCM_SHA256:
968 case DHE_DSS_WITH_AES_256_GCM_SHA384:
969 return true;
970 default:
971 return false;
972 }
973 }
974
975 internal static bool IsDHE_RSA(int cs)
976 {
977 switch (cs) {
978 case DHE_RSA_WITH_3DES_EDE_CBC_SHA:
979 case DHE_RSA_WITH_AES_128_CBC_SHA:
980 case DHE_RSA_WITH_AES_256_CBC_SHA:
981 case DHE_RSA_WITH_AES_128_CBC_SHA256:
982 case DHE_RSA_WITH_AES_256_CBC_SHA256:
983 case DHE_RSA_WITH_AES_128_GCM_SHA256:
984 case DHE_RSA_WITH_AES_256_GCM_SHA384:
985 case DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
986 return true;
987 default:
988 return false;
989 }
990 }
991
992 internal static bool IsECDH_ECDSA(int cs)
993 {
994 switch (cs) {
995 case ECDH_ECDSA_WITH_NULL_SHA:
996 case ECDH_ECDSA_WITH_RC4_128_SHA:
997 case ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
998 case ECDH_ECDSA_WITH_AES_128_CBC_SHA:
999 case ECDH_ECDSA_WITH_AES_256_CBC_SHA:
1000 case ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
1001 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
1002 case ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
1003 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
1004 return true;
1005 default:
1006 return false;
1007 }
1008 }
1009
1010 internal static bool IsECDH_RSA(int cs)
1011 {
1012 switch (cs) {
1013 case ECDH_RSA_WITH_NULL_SHA:
1014 case ECDH_RSA_WITH_RC4_128_SHA:
1015 case ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
1016 case ECDH_RSA_WITH_AES_128_CBC_SHA:
1017 case ECDH_RSA_WITH_AES_256_CBC_SHA:
1018 case ECDH_RSA_WITH_AES_128_CBC_SHA256:
1019 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
1020 case ECDH_RSA_WITH_AES_128_GCM_SHA256:
1021 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
1022 return true;
1023 default:
1024 return false;
1025 }
1026 }
1027
1028 internal static bool IsECDH(int cs)
1029 {
1030 return IsECDH_ECDSA(cs) || IsECDH_RSA(cs);
1031 }
1032
1033 internal static bool IsECDHE_ECDSA(int cs)
1034 {
1035 switch (cs) {
1036 case ECDHE_ECDSA_WITH_NULL_SHA:
1037 case ECDHE_ECDSA_WITH_RC4_128_SHA:
1038 case ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
1039 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
1040 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
1041 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
1042 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
1043 case ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
1044 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
1045 case ECDHE_ECDSA_WITH_AES_128_CCM:
1046 case ECDHE_ECDSA_WITH_AES_256_CCM:
1047 case ECDHE_ECDSA_WITH_AES_128_CCM_8:
1048 case ECDHE_ECDSA_WITH_AES_256_CCM_8:
1049 case ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
1050 return true;
1051 default:
1052 return false;
1053 }
1054 }
1055
1056 internal static bool IsECDHE_RSA(int cs)
1057 {
1058 switch (cs) {
1059 case ECDHE_RSA_WITH_NULL_SHA:
1060 case ECDHE_RSA_WITH_RC4_128_SHA:
1061 case ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
1062 case ECDHE_RSA_WITH_AES_128_CBC_SHA:
1063 case ECDHE_RSA_WITH_AES_256_CBC_SHA:
1064 case ECDHE_RSA_WITH_AES_128_CBC_SHA256:
1065 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
1066 case ECDHE_RSA_WITH_AES_128_GCM_SHA256:
1067 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
1068 case ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
1069 return true;
1070 default:
1071 return false;
1072 }
1073 }
1074
1075 internal static bool IsECDHE(int cs)
1076 {
1077 return IsECDHE_RSA(cs) || IsECDHE_ECDSA(cs);
1078 }
1079
1080 internal static bool IsSHA384(int cs)
1081 {
1082 switch (cs) {
1083 case RSA_WITH_AES_256_GCM_SHA384:
1084 case DH_DSS_WITH_AES_256_GCM_SHA384:
1085 case DH_RSA_WITH_AES_256_GCM_SHA384:
1086 case DHE_DSS_WITH_AES_256_GCM_SHA384:
1087 case DHE_RSA_WITH_AES_256_GCM_SHA384:
1088 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
1089 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
1090 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
1091 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
1092 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
1093 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
1094 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
1095 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
1096 return true;
1097 default:
1098 return false;
1099 }
1100 }
1101
1102 internal static bool IsTLS12(int cs)
1103 {
1104 switch (cs) {
1105 case RSA_WITH_NULL_SHA256:
1106 case RSA_WITH_AES_128_CBC_SHA256:
1107 case RSA_WITH_AES_256_CBC_SHA256:
1108 case DH_DSS_WITH_AES_128_CBC_SHA256:
1109 case DH_RSA_WITH_AES_128_CBC_SHA256:
1110 case DHE_DSS_WITH_AES_128_CBC_SHA256:
1111 case DHE_RSA_WITH_AES_128_CBC_SHA256:
1112 case DH_DSS_WITH_AES_256_CBC_SHA256:
1113 case DH_RSA_WITH_AES_256_CBC_SHA256:
1114 case DHE_DSS_WITH_AES_256_CBC_SHA256:
1115 case DHE_RSA_WITH_AES_256_CBC_SHA256:
1116 case DH_anon_WITH_AES_128_CBC_SHA256:
1117 case DH_anon_WITH_AES_256_CBC_SHA256:
1118 case RSA_WITH_AES_128_GCM_SHA256:
1119 case RSA_WITH_AES_256_GCM_SHA384:
1120 case DHE_RSA_WITH_AES_128_GCM_SHA256:
1121 case DHE_RSA_WITH_AES_256_GCM_SHA384:
1122 case DH_RSA_WITH_AES_128_GCM_SHA256:
1123 case DH_RSA_WITH_AES_256_GCM_SHA384:
1124 case DHE_DSS_WITH_AES_128_GCM_SHA256:
1125 case DHE_DSS_WITH_AES_256_GCM_SHA384:
1126 case DH_DSS_WITH_AES_128_GCM_SHA256:
1127 case DH_DSS_WITH_AES_256_GCM_SHA384:
1128 case DH_anon_WITH_AES_128_GCM_SHA256:
1129 case DH_anon_WITH_AES_256_GCM_SHA384:
1130 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
1131 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
1132 case ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
1133 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
1134 case ECDHE_RSA_WITH_AES_128_CBC_SHA256:
1135 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
1136 case ECDH_RSA_WITH_AES_128_CBC_SHA256:
1137 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
1138 case ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
1139 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
1140 case ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
1141 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
1142 case ECDHE_RSA_WITH_AES_128_GCM_SHA256:
1143 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
1144 case ECDH_RSA_WITH_AES_128_GCM_SHA256:
1145 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
1146 case RSA_WITH_AES_128_CCM:
1147 case RSA_WITH_AES_256_CCM:
1148 case RSA_WITH_AES_128_CCM_8:
1149 case RSA_WITH_AES_256_CCM_8:
1150 case ECDHE_ECDSA_WITH_AES_128_CCM:
1151 case ECDHE_ECDSA_WITH_AES_256_CCM:
1152 case ECDHE_ECDSA_WITH_AES_128_CCM_8:
1153 case ECDHE_ECDSA_WITH_AES_256_CCM_8:
1154 case ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
1155 case ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
1156 case DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
1157 case PSK_WITH_CHACHA20_POLY1305_SHA256:
1158 case ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
1159 case DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
1160 case RSA_PSK_WITH_CHACHA20_POLY1305_SHA256:
1161 return true;
1162 default:
1163 return false;
1164 }
1165 }
1166
1167 internal static PRF GetPRFForTLS12(int cs)
1168 {
1169 return new PRF(IsSHA384(cs)
1170 ? (IDigest)new SHA384()
1171 : (IDigest)new SHA256());
1172 }
1173
1174 internal static ECCurve GetCurveByID(int id)
1175 {
1176 switch (id) {
1177 case NIST_P256: return EC.P256;
1178 case NIST_P384: return EC.P384;
1179 case NIST_P521: return EC.P521;
1180 case Curve25519: return EC.Curve25519;
1181 default:
1182 throw new SSLException("Unknown curve: " + id);
1183 }
1184 }
1185
1186 /*
1187 * Get ID for a curve. This returns -1 if the curve is not
1188 * recognised.
1189 */
1190 internal static int CurveToID(ECCurve curve)
1191 {
1192 switch (curve.Name) {
1193 case "P-256": return SSL.NIST_P256;
1194 case "P-384": return SSL.NIST_P384;
1195 case "P-521": return SSL.NIST_P521;
1196 case "Curve25519": return SSL.Curve25519;
1197 default:
1198 return -1;
1199 }
1200 }
1201
1202 internal static IDigest GetHashByID(int id)
1203 {
1204 switch (id) {
1205 case 1: return new MD5();
1206 case 2: return new SHA1();
1207 case 3: return new SHA224();
1208 case 4: return new SHA256();
1209 case 5: return new SHA384();
1210 case 6: return new SHA512();
1211 default:
1212 throw new SSLException("Unknown hash: " + id);
1213 }
1214 }
1215 }
1216
1217 }