2 * Copyright (c) 2017 Thomas Pornin <pornin@bolet.org>
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:
12 * The above copyright notice and this permission notice shall be
13 * included in all copies or substantial portions of the Software.
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
26 using System.Collections.Generic;
27 using System.Security.Cryptography.X509Certificates;
37 * A fake class that serves as container for various constants.
40 public sealed class SSL {
45 public const int SSL30 = 0x0300;
46 public const int TLS10 = 0x0301;
47 public const int TLS11 = 0x0302;
48 public const int TLS12 = 0x0303;
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;
61 public const int WARNING = 1;
62 public const int FATAL = 2;
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;
92 * Handshake message types.
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;
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;
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;
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;
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;
208 public const int ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA8;
209 public const int ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCA9;
210 public const int DHE_RSA_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAA;
211 public const int PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAB;
212 public const int ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAC;
213 public const int DHE_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAD;
214 public const int RSA_PSK_WITH_CHACHA20_POLY1305_SHA256 = 0xCCAE;
217 public const int FALLBACK_SCSV = 0x5600;
220 public const int EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF;
223 * Client certificate types.
225 public const int RSA_SIGN = 1;
226 public const int DSS_SIGN = 2;
227 public const int RSA_FIXED_DH = 3;
228 public const int DSS_FIXED_DH = 4;
231 * Hash algorithm identifiers. The special "MD5SHA1" is for use
232 * with RSA signatures in TLS 1.0 and 1.1 only.
234 public const int MD5SHA1 = 0;
235 public const int MD5 = 1;
236 public const int SHA1 = 2;
237 public const int SHA224 = 3;
238 public const int SHA256 = 4;
239 public const int SHA384 = 5;
240 public const int SHA512 = 6;
243 * Signature algorithm identifiers.
245 public const int RSA = 1;
246 public const int DSA = 2;
247 public const int ECDSA = 3;
250 * Combined hash-and-sign algorithms.
252 public const int RSA_MD5SHA1 = (MD5SHA1 << 8) + RSA;
253 public const int RSA_MD5 = (MD5 << 8) + RSA;
254 public const int RSA_SHA1 = (SHA1 << 8) + RSA;
255 public const int RSA_SHA224 = (SHA224 << 8) + RSA;
256 public const int RSA_SHA256 = (SHA256 << 8) + RSA;
257 public const int RSA_SHA384 = (SHA384 << 8) + RSA;
258 public const int RSA_SHA512 = (SHA512 << 8) + RSA;
259 public const int ECDSA_MD5 = (MD5 << 8) + ECDSA;
260 public const int ECDSA_SHA1 = (SHA1 << 8) + ECDSA;
261 public const int ECDSA_SHA224 = (SHA224 << 8) + ECDSA;
262 public const int ECDSA_SHA256 = (SHA256 << 8) + ECDSA;
263 public const int ECDSA_SHA384 = (SHA384 << 8) + ECDSA;
264 public const int ECDSA_SHA512 = (SHA512 << 8) + ECDSA;
267 * Symbolic identifiers for named curves.
269 public const int NIST_P256 = 23;
270 public const int NIST_P384 = 24;
271 public const int NIST_P521 = 25;
272 public const int Curve25519 = 29;
275 * Get a human-readable name for a version.
277 public static string VersionName(int version)
280 case SSL30: return "SSL 3.0";
281 case TLS10: return "TLS 1.0";
282 case TLS11: return "TLS 1.1";
283 case TLS12: return "TLS 1.2";
285 if ((version >> 8) == 3) {
286 return String.Format("TLS 1.{0}", (version & 0xFF) - 1);
288 return String.Format("UNKNOWN:0x{0:X4}", version);
292 * Get a human-readable name for a cipher suite.
294 public static string CipherSuiteName(int cipherSuite)
296 switch (cipherSuite) {
297 case NULL_WITH_NULL_NULL:
298 return "NULL_WITH_NULL_NULL";
299 case RSA_WITH_NULL_MD5:
300 return "RSA_WITH_NULL_MD5";
301 case RSA_WITH_NULL_SHA:
302 return "RSA_WITH_NULL_SHA";
303 case RSA_WITH_NULL_SHA256:
304 return "RSA_WITH_NULL_SHA256";
305 case RSA_WITH_RC4_128_MD5:
306 return "RSA_WITH_RC4_128_MD5";
307 case RSA_WITH_RC4_128_SHA:
308 return "RSA_WITH_RC4_128_SHA";
309 case RSA_WITH_3DES_EDE_CBC_SHA:
310 return "RSA_WITH_3DES_EDE_CBC_SHA";
311 case RSA_WITH_AES_128_CBC_SHA:
312 return "RSA_WITH_AES_128_CBC_SHA";
313 case RSA_WITH_AES_256_CBC_SHA:
314 return "RSA_WITH_AES_256_CBC_SHA";
315 case RSA_WITH_AES_128_CBC_SHA256:
316 return "RSA_WITH_AES_128_CBC_SHA256";
317 case RSA_WITH_AES_256_CBC_SHA256:
318 return "RSA_WITH_AES_256_CBC_SHA256";
319 case DH_DSS_WITH_3DES_EDE_CBC_SHA:
320 return "DH_DSS_WITH_3DES_EDE_CBC_SHA";
321 case DH_RSA_WITH_3DES_EDE_CBC_SHA:
322 return "DH_RSA_WITH_3DES_EDE_CBC_SHA";
323 case DHE_DSS_WITH_3DES_EDE_CBC_SHA:
324 return "DHE_DSS_WITH_3DES_EDE_CBC_SHA";
325 case DHE_RSA_WITH_3DES_EDE_CBC_SHA:
326 return "DHE_RSA_WITH_3DES_EDE_CBC_SHA";
327 case DH_DSS_WITH_AES_128_CBC_SHA:
328 return "DH_DSS_WITH_AES_128_CBC_SHA";
329 case DH_RSA_WITH_AES_128_CBC_SHA:
330 return "DH_RSA_WITH_AES_128_CBC_SHA";
331 case DHE_DSS_WITH_AES_128_CBC_SHA:
332 return "DHE_DSS_WITH_AES_128_CBC_SHA";
333 case DHE_RSA_WITH_AES_128_CBC_SHA:
334 return "DHE_RSA_WITH_AES_128_CBC_SHA";
335 case DH_DSS_WITH_AES_256_CBC_SHA:
336 return "DH_DSS_WITH_AES_256_CBC_SHA";
337 case DH_RSA_WITH_AES_256_CBC_SHA:
338 return "DH_RSA_WITH_AES_256_CBC_SHA";
339 case DHE_DSS_WITH_AES_256_CBC_SHA:
340 return "DHE_DSS_WITH_AES_256_CBC_SHA";
341 case DHE_RSA_WITH_AES_256_CBC_SHA:
342 return "DHE_RSA_WITH_AES_256_CBC_SHA";
343 case DH_DSS_WITH_AES_128_CBC_SHA256:
344 return "DH_DSS_WITH_AES_128_CBC_SHA256";
345 case DH_RSA_WITH_AES_128_CBC_SHA256:
346 return "DH_RSA_WITH_AES_128_CBC_SHA256";
347 case DHE_DSS_WITH_AES_128_CBC_SHA256:
348 return "DHE_DSS_WITH_AES_128_CBC_SHA256";
349 case DHE_RSA_WITH_AES_128_CBC_SHA256:
350 return "DHE_RSA_WITH_AES_128_CBC_SHA256";
351 case DH_DSS_WITH_AES_256_CBC_SHA256:
352 return "DH_DSS_WITH_AES_256_CBC_SHA256";
353 case DH_RSA_WITH_AES_256_CBC_SHA256:
354 return "DH_RSA_WITH_AES_256_CBC_SHA256";
355 case DHE_DSS_WITH_AES_256_CBC_SHA256:
356 return "DHE_DSS_WITH_AES_256_CBC_SHA256";
357 case DHE_RSA_WITH_AES_256_CBC_SHA256:
358 return "DHE_RSA_WITH_AES_256_CBC_SHA256";
359 case DH_anon_WITH_RC4_128_MD5:
360 return "DH_anon_WITH_RC4_128_MD5";
361 case DH_anon_WITH_3DES_EDE_CBC_SHA:
362 return "DH_anon_WITH_3DES_EDE_CBC_SHA";
363 case DH_anon_WITH_AES_128_CBC_SHA:
364 return "DH_anon_WITH_AES_128_CBC_SHA";
365 case DH_anon_WITH_AES_256_CBC_SHA:
366 return "DH_anon_WITH_AES_256_CBC_SHA";
367 case DH_anon_WITH_AES_128_CBC_SHA256:
368 return "DH_anon_WITH_AES_128_CBC_SHA256";
369 case DH_anon_WITH_AES_256_CBC_SHA256:
370 return "DH_anon_WITH_AES_256_CBC_SHA256";
371 case ECDH_ECDSA_WITH_NULL_SHA:
372 return "ECDH_ECDSA_WITH_NULL_SHA";
373 case ECDH_ECDSA_WITH_RC4_128_SHA:
374 return "ECDH_ECDSA_WITH_RC4_128_SHA";
375 case ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
376 return "ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA";
377 case ECDH_ECDSA_WITH_AES_128_CBC_SHA:
378 return "ECDH_ECDSA_WITH_AES_128_CBC_SHA";
379 case ECDH_ECDSA_WITH_AES_256_CBC_SHA:
380 return "ECDH_ECDSA_WITH_AES_256_CBC_SHA";
381 case ECDHE_ECDSA_WITH_NULL_SHA:
382 return "ECDHE_ECDSA_WITH_NULL_SHA";
383 case ECDHE_ECDSA_WITH_RC4_128_SHA:
384 return "ECDHE_ECDSA_WITH_RC4_128_SHA";
385 case ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
386 return "ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA";
387 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
388 return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA";
389 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
390 return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
391 case ECDH_RSA_WITH_NULL_SHA:
392 return "ECDH_RSA_WITH_NULL_SHA";
393 case ECDH_RSA_WITH_RC4_128_SHA:
394 return "ECDH_RSA_WITH_RC4_128_SHA";
395 case ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
396 return "ECDH_RSA_WITH_3DES_EDE_CBC_SHA";
397 case ECDH_RSA_WITH_AES_128_CBC_SHA:
398 return "ECDH_RSA_WITH_AES_128_CBC_SHA";
399 case ECDH_RSA_WITH_AES_256_CBC_SHA:
400 return "ECDH_RSA_WITH_AES_256_CBC_SHA";
401 case ECDHE_RSA_WITH_NULL_SHA:
402 return "ECDHE_RSA_WITH_NULL_SHA";
403 case ECDHE_RSA_WITH_RC4_128_SHA:
404 return "ECDHE_RSA_WITH_RC4_128_SHA";
405 case ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
406 return "ECDHE_RSA_WITH_3DES_EDE_CBC_SHA";
407 case ECDHE_RSA_WITH_AES_128_CBC_SHA:
408 return "ECDHE_RSA_WITH_AES_128_CBC_SHA";
409 case ECDHE_RSA_WITH_AES_256_CBC_SHA:
410 return "ECDHE_RSA_WITH_AES_256_CBC_SHA";
411 case ECDH_anon_WITH_NULL_SHA:
412 return "ECDH_anon_WITH_NULL_SHA";
413 case ECDH_anon_WITH_RC4_128_SHA:
414 return "ECDH_anon_WITH_RC4_128_SHA";
415 case ECDH_anon_WITH_3DES_EDE_CBC_SHA:
416 return "ECDH_anon_WITH_3DES_EDE_CBC_SHA";
417 case ECDH_anon_WITH_AES_128_CBC_SHA:
418 return "ECDH_anon_WITH_AES_128_CBC_SHA";
419 case ECDH_anon_WITH_AES_256_CBC_SHA:
420 return "ECDH_anon_WITH_AES_256_CBC_SHA";
421 case RSA_WITH_AES_128_GCM_SHA256:
422 return "RSA_WITH_AES_128_GCM_SHA256";
423 case RSA_WITH_AES_256_GCM_SHA384:
424 return "RSA_WITH_AES_256_GCM_SHA384";
425 case DHE_RSA_WITH_AES_128_GCM_SHA256:
426 return "DHE_RSA_WITH_AES_128_GCM_SHA256";
427 case DHE_RSA_WITH_AES_256_GCM_SHA384:
428 return "DHE_RSA_WITH_AES_256_GCM_SHA384";
429 case DH_RSA_WITH_AES_128_GCM_SHA256:
430 return "DH_RSA_WITH_AES_128_GCM_SHA256";
431 case DH_RSA_WITH_AES_256_GCM_SHA384:
432 return "DH_RSA_WITH_AES_256_GCM_SHA384";
433 case DHE_DSS_WITH_AES_128_GCM_SHA256:
434 return "DHE_DSS_WITH_AES_128_GCM_SHA256";
435 case DHE_DSS_WITH_AES_256_GCM_SHA384:
436 return "DHE_DSS_WITH_AES_256_GCM_SHA384";
437 case DH_DSS_WITH_AES_128_GCM_SHA256:
438 return "DH_DSS_WITH_AES_128_GCM_SHA256";
439 case DH_DSS_WITH_AES_256_GCM_SHA384:
440 return "DH_DSS_WITH_AES_256_GCM_SHA384";
441 case DH_anon_WITH_AES_128_GCM_SHA256:
442 return "DH_anon_WITH_AES_128_GCM_SHA256";
443 case DH_anon_WITH_AES_256_GCM_SHA384:
444 return "DH_anon_WITH_AES_256_GCM_SHA384";
445 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
446 return "ECDHE_ECDSA_WITH_AES_128_CBC_SHA256";
447 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
448 return "ECDHE_ECDSA_WITH_AES_256_CBC_SHA384";
449 case ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
450 return "ECDH_ECDSA_WITH_AES_128_CBC_SHA256";
451 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
452 return "ECDH_ECDSA_WITH_AES_256_CBC_SHA384";
453 case ECDHE_RSA_WITH_AES_128_CBC_SHA256:
454 return "ECDHE_RSA_WITH_AES_128_CBC_SHA256";
455 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
456 return "ECDHE_RSA_WITH_AES_256_CBC_SHA384";
457 case ECDH_RSA_WITH_AES_128_CBC_SHA256:
458 return "ECDH_RSA_WITH_AES_128_CBC_SHA256";
459 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
460 return "ECDH_RSA_WITH_AES_256_CBC_SHA384";
461 case ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
462 return "ECDHE_ECDSA_WITH_AES_128_GCM_SHA256";
463 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
464 return "ECDHE_ECDSA_WITH_AES_256_GCM_SHA384";
465 case ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
466 return "ECDH_ECDSA_WITH_AES_128_GCM_SHA256";
467 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
468 return "ECDH_ECDSA_WITH_AES_256_GCM_SHA384";
469 case ECDHE_RSA_WITH_AES_128_GCM_SHA256:
470 return "ECDHE_RSA_WITH_AES_128_GCM_SHA256";
471 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
472 return "ECDHE_RSA_WITH_AES_256_GCM_SHA384";
473 case ECDH_RSA_WITH_AES_128_GCM_SHA256:
474 return "ECDH_RSA_WITH_AES_128_GCM_SHA256";
475 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
476 return "ECDH_RSA_WITH_AES_256_GCM_SHA384";
477 case ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
478 return "ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
479 case ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
480 return "ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256";
481 case DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
482 return "DHE_RSA_WITH_CHACHA20_POLY1305_SHA256";
483 case PSK_WITH_CHACHA20_POLY1305_SHA256:
484 return "PSK_WITH_CHACHA20_POLY1305_SHA256";
485 case ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
486 return "ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
487 case DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
488 return "DHE_PSK_WITH_CHACHA20_POLY1305_SHA256";
489 case RSA_PSK_WITH_CHACHA20_POLY1305_SHA256:
490 return "RSA_PSK_WITH_CHACHA20_POLY1305_SHA256";
492 return "FALLBACK_SCSV";
493 case EMPTY_RENEGOTIATION_INFO_SCSV:
494 return "EMPTY_RENEGOTIATION_INFO_SCSV";
496 return String.Format("UNKNOWN:0x{0:X4}", cipherSuite);
501 * Get a human-readable name for a hash-and-sign algorithm.
503 public static string HashAndSignName(int hs)
506 case RSA_MD5: return "RSA_MD5";
507 case RSA_SHA1: return "RSA_SHA1";
508 case RSA_SHA224: return "RSA_SHA224";
509 case RSA_SHA256: return "RSA_SHA256";
510 case RSA_SHA384: return "RSA_SHA384";
511 case RSA_SHA512: return "RSA_SHA512";
512 case ECDSA_MD5: return "ECDSA_MD5";
513 case ECDSA_SHA1: return "ECDSA_SHA1";
514 case ECDSA_SHA224: return "ECDSA_SHA224";
515 case ECDSA_SHA256: return "ECDSA_SHA256";
516 case ECDSA_SHA384: return "ECDSA_SHA384";
517 case ECDSA_SHA512: return "ECDSA_SHA512";
519 return String.Format("UNKNOWN:0x{0:X4}", hs);
524 * Get a human-readable name for a curve.
526 public static string CurveName(int id)
529 case Curve25519: return "Curve25519";
530 case NIST_P256: return "NIST_P256";
531 case NIST_P384: return "NIST_P384";
532 case NIST_P521: return "NIST_P521";
534 return String.Format("UNKNOWN:0x{0:X4}", id);
539 * Extract the public key from an encoded X.509 certificate.
540 * This does NOT make any attempt at validating the certificate.
542 internal static IPublicKey GetKeyFromCert(byte[] cert)
544 AsnElt ae = AsnElt.Decode(cert);
545 ae.CheckTag(AsnElt.SEQUENCE);
548 ae.CheckTag(AsnElt.SEQUENCE);
549 ae.CheckNumSubMin(6);
551 if (ae.GetSub(0).TagValue != AsnElt.INTEGER) {
552 ae.CheckNumSubMin(7);
555 return KF.DecodePublicKey(ae.GetSub(off));
558 internal static bool IsRSA(int cs)
561 case RSA_WITH_RC4_128_MD5:
562 case RSA_WITH_RC4_128_SHA:
563 case RSA_WITH_3DES_EDE_CBC_SHA:
564 case RSA_WITH_AES_128_CBC_SHA:
565 case RSA_WITH_AES_256_CBC_SHA:
566 case RSA_WITH_AES_128_CBC_SHA256:
567 case RSA_WITH_AES_256_CBC_SHA256:
568 case RSA_WITH_AES_128_GCM_SHA256:
569 case RSA_WITH_AES_256_GCM_SHA384:
576 internal static bool IsDH_DSA(int cs)
579 case DH_DSS_WITH_3DES_EDE_CBC_SHA:
580 case DH_DSS_WITH_AES_128_CBC_SHA:
581 case DH_DSS_WITH_AES_256_CBC_SHA:
582 case DH_DSS_WITH_AES_128_CBC_SHA256:
583 case DH_DSS_WITH_AES_256_CBC_SHA256:
584 case DH_DSS_WITH_AES_128_GCM_SHA256:
585 case DH_DSS_WITH_AES_256_GCM_SHA384:
592 internal static bool IsDH_RSA(int cs)
595 case DH_RSA_WITH_3DES_EDE_CBC_SHA:
596 case DH_RSA_WITH_AES_128_CBC_SHA:
597 case DH_RSA_WITH_AES_256_CBC_SHA:
598 case DH_RSA_WITH_AES_128_CBC_SHA256:
599 case DH_RSA_WITH_AES_256_CBC_SHA256:
600 case DH_RSA_WITH_AES_128_GCM_SHA256:
601 case DH_RSA_WITH_AES_256_GCM_SHA384:
608 internal static bool IsDH(int cs)
610 return IsDH_DSA(cs) || IsDH_RSA(cs);
613 internal static bool IsDHE_DSS(int cs)
616 case DHE_DSS_WITH_3DES_EDE_CBC_SHA:
617 case DHE_DSS_WITH_AES_128_CBC_SHA:
618 case DHE_DSS_WITH_AES_256_CBC_SHA:
619 case DHE_DSS_WITH_AES_128_CBC_SHA256:
620 case DHE_DSS_WITH_AES_256_CBC_SHA256:
621 case DHE_DSS_WITH_AES_128_GCM_SHA256:
622 case DHE_DSS_WITH_AES_256_GCM_SHA384:
629 internal static bool IsDHE_RSA(int cs)
632 case DHE_RSA_WITH_3DES_EDE_CBC_SHA:
633 case DHE_RSA_WITH_AES_128_CBC_SHA:
634 case DHE_RSA_WITH_AES_256_CBC_SHA:
635 case DHE_RSA_WITH_AES_128_CBC_SHA256:
636 case DHE_RSA_WITH_AES_256_CBC_SHA256:
637 case DHE_RSA_WITH_AES_128_GCM_SHA256:
638 case DHE_RSA_WITH_AES_256_GCM_SHA384:
639 case DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
646 internal static bool IsECDH_ECDSA(int cs)
649 case ECDH_ECDSA_WITH_NULL_SHA:
650 case ECDH_ECDSA_WITH_RC4_128_SHA:
651 case ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA:
652 case ECDH_ECDSA_WITH_AES_128_CBC_SHA:
653 case ECDH_ECDSA_WITH_AES_256_CBC_SHA:
654 case ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
655 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
656 case ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
657 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
664 internal static bool IsECDH_RSA(int cs)
667 case ECDH_RSA_WITH_NULL_SHA:
668 case ECDH_RSA_WITH_RC4_128_SHA:
669 case ECDH_RSA_WITH_3DES_EDE_CBC_SHA:
670 case ECDH_RSA_WITH_AES_128_CBC_SHA:
671 case ECDH_RSA_WITH_AES_256_CBC_SHA:
672 case ECDH_RSA_WITH_AES_128_CBC_SHA256:
673 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
674 case ECDH_RSA_WITH_AES_128_GCM_SHA256:
675 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
682 internal static bool IsECDH(int cs)
684 return IsECDH_ECDSA(cs) || IsECDH_RSA(cs);
687 internal static bool IsECDHE_ECDSA(int cs)
690 case ECDHE_ECDSA_WITH_NULL_SHA:
691 case ECDHE_ECDSA_WITH_RC4_128_SHA:
692 case ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA:
693 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA:
694 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA:
695 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
696 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
697 case ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
698 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
699 case ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
706 internal static bool IsECDHE_RSA(int cs)
709 case ECDHE_RSA_WITH_NULL_SHA:
710 case ECDHE_RSA_WITH_RC4_128_SHA:
711 case ECDHE_RSA_WITH_3DES_EDE_CBC_SHA:
712 case ECDHE_RSA_WITH_AES_128_CBC_SHA:
713 case ECDHE_RSA_WITH_AES_256_CBC_SHA:
714 case ECDHE_RSA_WITH_AES_128_CBC_SHA256:
715 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
716 case ECDHE_RSA_WITH_AES_128_GCM_SHA256:
717 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
718 case ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
725 internal static bool IsECDHE(int cs)
727 return IsECDHE_RSA(cs) || IsECDHE_ECDSA(cs);
730 internal static bool IsSHA384(int cs)
733 case RSA_WITH_AES_256_GCM_SHA384:
734 case DH_DSS_WITH_AES_256_GCM_SHA384:
735 case DH_RSA_WITH_AES_256_GCM_SHA384:
736 case DHE_DSS_WITH_AES_256_GCM_SHA384:
737 case DHE_RSA_WITH_AES_256_GCM_SHA384:
738 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
739 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
740 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
741 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
742 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
743 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
744 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
745 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
752 internal static bool IsTLS12(int cs)
755 case RSA_WITH_NULL_SHA256:
756 case RSA_WITH_AES_128_CBC_SHA256:
757 case RSA_WITH_AES_256_CBC_SHA256:
758 case DH_DSS_WITH_AES_128_CBC_SHA256:
759 case DH_RSA_WITH_AES_128_CBC_SHA256:
760 case DHE_DSS_WITH_AES_128_CBC_SHA256:
761 case DHE_RSA_WITH_AES_128_CBC_SHA256:
762 case DH_DSS_WITH_AES_256_CBC_SHA256:
763 case DH_RSA_WITH_AES_256_CBC_SHA256:
764 case DHE_DSS_WITH_AES_256_CBC_SHA256:
765 case DHE_RSA_WITH_AES_256_CBC_SHA256:
766 case DH_anon_WITH_AES_128_CBC_SHA256:
767 case DH_anon_WITH_AES_256_CBC_SHA256:
768 case RSA_WITH_AES_128_GCM_SHA256:
769 case RSA_WITH_AES_256_GCM_SHA384:
770 case DHE_RSA_WITH_AES_128_GCM_SHA256:
771 case DHE_RSA_WITH_AES_256_GCM_SHA384:
772 case DH_RSA_WITH_AES_128_GCM_SHA256:
773 case DH_RSA_WITH_AES_256_GCM_SHA384:
774 case DHE_DSS_WITH_AES_128_GCM_SHA256:
775 case DHE_DSS_WITH_AES_256_GCM_SHA384:
776 case DH_DSS_WITH_AES_128_GCM_SHA256:
777 case DH_DSS_WITH_AES_256_GCM_SHA384:
778 case DH_anon_WITH_AES_128_GCM_SHA256:
779 case DH_anon_WITH_AES_256_GCM_SHA384:
780 case ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
781 case ECDHE_ECDSA_WITH_AES_256_CBC_SHA384:
782 case ECDH_ECDSA_WITH_AES_128_CBC_SHA256:
783 case ECDH_ECDSA_WITH_AES_256_CBC_SHA384:
784 case ECDHE_RSA_WITH_AES_128_CBC_SHA256:
785 case ECDHE_RSA_WITH_AES_256_CBC_SHA384:
786 case ECDH_RSA_WITH_AES_128_CBC_SHA256:
787 case ECDH_RSA_WITH_AES_256_CBC_SHA384:
788 case ECDHE_ECDSA_WITH_AES_128_GCM_SHA256:
789 case ECDHE_ECDSA_WITH_AES_256_GCM_SHA384:
790 case ECDH_ECDSA_WITH_AES_128_GCM_SHA256:
791 case ECDH_ECDSA_WITH_AES_256_GCM_SHA384:
792 case ECDHE_RSA_WITH_AES_128_GCM_SHA256:
793 case ECDHE_RSA_WITH_AES_256_GCM_SHA384:
794 case ECDH_RSA_WITH_AES_128_GCM_SHA256:
795 case ECDH_RSA_WITH_AES_256_GCM_SHA384:
796 case ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
797 case ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256:
798 case DHE_RSA_WITH_CHACHA20_POLY1305_SHA256:
799 case PSK_WITH_CHACHA20_POLY1305_SHA256:
800 case ECDHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
801 case DHE_PSK_WITH_CHACHA20_POLY1305_SHA256:
802 case RSA_PSK_WITH_CHACHA20_POLY1305_SHA256:
809 internal static PRF GetPRFForTLS12(int cs)
811 return new PRF(IsSHA384(cs)
812 ? (IDigest)new SHA384()
813 : (IDigest)new SHA256());
816 internal static ECCurve GetCurveByID(int id)
819 case NIST_P256: return EC.P256;
820 case NIST_P384: return EC.P384;
821 case NIST_P521: return EC.P521;
822 case Curve25519: return EC.Curve25519;
824 throw new SSLException("Unknown curve: " + id);
829 * Get ID for a curve. This returns -1 if the curve is not
832 internal static int CurveToID(ECCurve curve)
834 switch (curve.Name) {
835 case "P-256": return SSL.NIST_P256;
836 case "P-384": return SSL.NIST_P384;
837 case "P-521": return SSL.NIST_P521;
838 case "Curve25519": return SSL.Curve25519;
844 internal static IDigest GetHashByID(int id)
847 case 1: return new MD5();
848 case 2: return new SHA1();
849 case 3: return new SHA224();
850 case 4: return new SHA256();
851 case 5: return new SHA384();
852 case 6: return new SHA512();
854 throw new SSLException("Unknown hash: " + id);