Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*
- * Command-line tool to test a SSL/TLS server for some vulnerabilities.
- * =====================================================================
- *
- * This application connects to the provided SSL/TLS server (by name and
- * port) and extracts the following information:
- * - supported versions (SSL 2.0, SSL 3.0, TLS 1.0 to 1.2)
- * - support of Deflate compression
- * - list of supported cipher suites (for each protocol version)
- * - BEAST/CRIME vulnerabilities.
- *
- * BEAST and CRIME are client-side attack, but the server can protect the
- * client by refusing to use the feature combinations which can be
- * attacked. For CRIME, the weakness is Deflate compression. For BEAST,
- * the attack conditions are more complex: it works with CBC ciphers with
- * SSL 3.0 and TLS 1.0. Hence, a server fails to protect the client against
- * BEAST if it does not enforce usage of RC4 over CBC ciphers under these
- * protocol versions, if given the choice.
- *
- * (The BEAST test considers only the cipher suites with strong
- * encryption; if the server supports none, then there are bigger
- * problems. We also assume that all clients support RC4-128; thus, the
- * server protects the client if it selects RC4-128 even if some strong
- * CBC-based ciphers are announced as supported by the client with a
- * higher preference level.)
- *
- * ----------------------------------------------------------------------
- * Copyright (c) 2012 Thomas Pornin <pornin@bolet.org>
- *
- * Permission is hereby granted, free of charge, to any person obtaining
- * a copy of this software and associated documentation files (the
- * "Software"), to deal in the Software without restriction, including
- * without limitation the rights to use, copy, modify, merge, publish,
- * distribute, sublicense, and/or sell copies of the Software, and to
- * permit persons to whom the Software is furnished to do so, subject to
- * the following conditions:
- *
- * The above copyright notice and this permission notice shall be
- * included in all copies or substantial portions of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
- * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
- * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
- * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
- * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
- * SOFTWARE.
- * ----------------------------------------------------------------------
- */
- using System;
- using System.Collections.Generic;
- using System.IO;
- using System.Net.Sockets;
- using System.Security.Cryptography;
- using System.Security.Cryptography.X509Certificates;
- using System.Text;
- namespace TestSSLServer {
- class TestSSLServer {
- static void Usage()
- {
- Console.WriteLine("usage: TestSSLServer servername [ port ]");
- Environment.Exit(1);
- }
- static void Main(string[] args)
- {
- try {
- Main0(args);
- } catch (Exception e) {
- Console.WriteLine(e.ToString());
- Environment.Exit(1);
- }
- }
- static void Main0(string[] args)
- {
- InitCipherSuites();
- if (args.Length == 0 || args.Length > 2) {
- Usage();
- }
- string name = args[0];
- int port = 443;
- if (args.Length == 2) {
- try {
- port = Int32.Parse(args[1]);
- } catch (Exception) {
- Usage();
- }
- if (port <= 0 || port > 65535) {
- Usage();
- }
- }
- IDictionary<int, int> sv = new SortedDictionary<int, int>();
- bool compress = false;
- for (int v = 0x0300; v <= 0x0303; v ++) {
- ServerHello sh = Connect(name, port,
- v, CIPHER_SUITES.Keys);
- if (sh == null) {
- continue;
- }
- AddToSet(sv, sh.protoVersion);
- if (sh.compression == 1) {
- compress = true;
- }
- }
- ServerHelloSSLv2 sh2 = ConnectV2(name, port);
- if (sh2 != null) {
- AddToSet(sv, 0x0200);
- }
- if (sv.Count == 0) {
- Console.WriteLine("No SSL/TLS server at " + name
- + ":" + port);
- Environment.Exit(1);
- }
- Console.WriteLine("Supported versions:");
- foreach (int v in sv.Keys) {
- Console.Write(" ");
- Console.Write(VersionString(v));
- }
- Console.WriteLine();
- Console.WriteLine("Deflate compression: "
- + (compress ? "YES" : "no"));
- Console.WriteLine("Supported cipher suites"
- + " (ORDER IS NOT SIGNIFICANT):");
- IDictionary<int, int> lastSuppCS = null;
- IDictionary<int, IDictionary<int, int>> suppCS =
- new SortedDictionary<int, IDictionary<int, int>>();
- IDictionary<string, int> certID =
- new SortedDictionary<string, int>();
- if (sh2 != null) {
- Console.WriteLine(" " + VersionString(0x0200));
- IDictionary<int, int> vc2 =
- new SortedDictionary<int, int>();
- foreach (int c in sh2.cipherSuites) {
- AddToSet(vc2, c);
- }
- foreach (int c in vc2.Keys) {
- Console.WriteLine(" "
- + CipherSuiteString(c));
- }
- suppCS.Add(0x0200, vc2);
- if (sh2.serverCertName != null) {
- AddToSet(certID, sh2.serverCertHash
- + ": " + sh2.serverCertName);
- }
- }
- foreach (int v in sv.Keys) {
- if (v == 0x0200) {
- continue;
- }
- IDictionary<int, int> vsc =
- SupportedSuites(name, port, v, certID);
- suppCS.Add(v, vsc);
- if (!SameSetInt(lastSuppCS, vsc)) {
- Console.WriteLine(" " + VersionString(v));
- foreach (int c in vsc.Keys) {
- Console.WriteLine(" "
- + CipherSuiteString(c));
- }
- lastSuppCS = vsc;
- } else {
- Console.WriteLine(" (" + VersionString(v)
- + ": idem)");
- }
- }
- Console.WriteLine("----------------------");
- if (certID.Count == 0) {
- Console.WriteLine("No server certificate !");
- } else {
- Console.WriteLine("Server certificate(s):");
- foreach (string cc in certID.Keys) {
- Console.WriteLine(" " + cc);
- }
- }
- Console.WriteLine("----------------------");
- int agMaxStrength = STRONG;
- int agMinStrength = STRONG;
- bool vulnBEAST = false;
- foreach (int v in sv.Keys) {
- IDictionary<int, int> vsc = suppCS[v];
- agMaxStrength = Math.Min(
- MaxStrength(vsc), agMaxStrength);
- agMinStrength = Math.Min(
- MinStrength(vsc), agMinStrength);
- if (!vulnBEAST) {
- vulnBEAST = TestBEAST(name, port, v, vsc);
- }
- }
- Console.WriteLine("Minimal encryption strength: "
- + StrengthString(agMinStrength));
- Console.WriteLine("Achievable encryption strength: "
- + StrengthString(agMaxStrength));
- Console.WriteLine("BEAST status: "
- + (vulnBEAST ? "vulnerable" : "protected"));
- Console.WriteLine("CRIME status: "
- + (compress ? "vulnerable" : "protected"));
- }
- static void AddToSet<T>(IDictionary<T, int> s, T val)
- {
- if (!s.ContainsKey(val)) {
- s.Add(val, 0);
- }
- }
- static bool IsInSet<T>(IDictionary<T, int> s, T val)
- {
- return s.ContainsKey(val);
- }
- static bool SameSetInt(
- IDictionary<int, int> s1, IDictionary<int, int> s2)
- {
- if (s1 == s2) {
- return true;
- }
- if (s1 == null || s2 == null) {
- return false;
- }
- if (s1.Count != s2.Count) {
- return false;
- }
- foreach (int k in s1.Keys) {
- if (!s2.ContainsKey(k)) {
- return false;
- }
- }
- return true;
- }
- /*
- * Get cipher suites supported by the server. This is done by
- * repeatedly contacting the server, each time removing from our
- * list of supported suites the suite which the server just
- * selected. We keep on until the server can no longer respond
- * to us with a ServerHello.
- */
- static IDictionary<int, int> SupportedSuites(
- string name, int port, int version,
- IDictionary<string, int> serverCertID)
- {
- IDictionary<int, int> cs = new SortedDictionary<int, int>();
- foreach (int k in CIPHER_SUITES.Keys) {
- AddToSet(cs, k);
- }
- IDictionary<int, int> rs = new SortedDictionary<int, int>();
- for (;;) {
- ServerHello sh = Connect(name, port, version, cs.Keys);
- if (sh == null) {
- break;
- }
- if (!IsInSet(cs, sh.cipherSuite)) {
- Console.WriteLine("[ERR: server wants to use"
- + " cipher suite 0x{0:X4} which client"
- + " did not announce]", sh.cipherSuite);
- break;
- }
- cs.Remove(sh.cipherSuite);
- AddToSet(rs, sh.cipherSuite);
- if (sh.serverCertName != null) {
- AddToSet(serverCertID, sh.serverCertHash
- + ": " + sh.serverCertName);
- }
- }
- return rs;
- }
- static int MinStrength(IDictionary<int, int> supp)
- {
- int m = STRONG;
- foreach (int suite in supp.Keys) {
- CipherSuite cs = CIPHER_SUITES[suite];
- if (cs == null) {
- continue;
- }
- if (cs.strength < m) {
- m = cs.strength;
- }
- }
- return m;
- }
- static int MaxStrength(IDictionary<int, int> supp)
- {
- int m = CLEAR;
- foreach (int suite in supp.Keys) {
- CipherSuite cs = CIPHER_SUITES[suite];
- if (cs == null) {
- continue;
- }
- if (cs.strength > m) {
- m = cs.strength;
- }
- }
- return m;
- }
- static bool TestBEAST(string name, int port,
- int version, IDictionary<int, int> supp)
- {
- /*
- * TLS 1.1+ is not vulnerable to BEAST.
- * We do not test SSLv2 either.
- */
- if (version < 0x0300 || version > 0x0301) {
- return false;
- }
- /*
- * BEAST attack works if the server allows the client to
- * use a CBC cipher. Existing clients also supports RC4,
- * so we consider that a server protects the clients if
- * it chooses RC4 over CBC streams when given the choice.
- * We only consider strong cipher suites here.
- */
- IList<int> strongCBC = new List<int>();
- IList<int> strongStream = new List<int>();
- foreach (int suite in supp.Keys) {
- CipherSuite cs = CIPHER_SUITES[suite];
- if (cs == null) {
- continue;
- }
- if (cs.strength < STRONG) {
- continue;
- }
- if (cs.isCBC) {
- strongCBC.Add(suite);
- } else {
- strongStream.Add(suite);
- }
- }
- if (strongCBC.Count == 0) {
- return false;
- }
- if (strongStream.Count == 0) {
- return true;
- }
- IList<int> ns = new List<int>();
- foreach (int suite in strongCBC) {
- ns.Add(suite);
- }
- foreach (int suite in strongStream) {
- ns.Add(suite);
- }
- ServerHello sh = Connect(name, port, version, ns);
- return CIPHER_SUITES[sh.cipherSuite].isCBC;
- }
- static string VersionString(int version)
- {
- if (version == 0x0200) {
- return "SSLv2";
- } else if (version == 0x0300) {
- return "SSLv3";
- } else if (((uint)version >> 8) == 0x03) {
- return "TLSv1." + ((version & 0xFF) - 1);
- } else {
- return String.Format(
- "UNKNOWN_VERSION:0x{0:X4}", version);
- }
- }
- /*
- * Connect to the server, send a ClientHello, and decode the
- * response (ServerHello). On error, null is returned.
- */
- static ServerHello Connect(string name, int port,
- int version, ICollection<int> cipherSuites)
- {
- NetworkStream ns = null;
- try {
- try {
- TcpClient tc = new TcpClient(name, port);
- ns = tc.GetStream();
- } catch (Exception e) {
- Console.WriteLine("could not connect to "
- + name + ":" + port);
- Console.WriteLine(e.ToString());
- return null;
- }
- byte[] ch = MakeClientHello(version, cipherSuites);
- SSLRecord rec = new SSLRecord(ns);
- rec.SetOutType(M.HANDSHAKE);
- rec.SetOutVersion(version);
- rec.Write(ch);
- rec.Flush();
- return new ServerHello(rec);
- } catch (Exception) {
- // ignored
- } finally {
- try {
- if (ns != null) {
- ns.Close();
- }
- } catch (Exception) {
- // ignored
- }
- }
- return null;
- }
- /*
- * Connect to the server, send a SSLv2 CLIENT-HELLO, and decode
- * the response (SERVER-HELLO). On error, null is returned.
- */
- static ServerHelloSSLv2 ConnectV2(string name, int port)
- {
- NetworkStream ns = null;
- try {
- try {
- TcpClient tc = new TcpClient(name, port);
- ns = tc.GetStream();
- } catch (Exception e) {
- Console.WriteLine("could not connect to "
- + name + ":" + port);
- Console.WriteLine(e.ToString());
- return null;
- }
- ns.Write(M.SSL2_CLIENT_HELLO,
- 0, M.SSL2_CLIENT_HELLO.Length);
- return new ServerHelloSSLv2(ns);
- } catch (Exception) {
- // ignored
- } finally {
- try {
- if (ns != null) {
- ns.Close();
- }
- } catch (Exception) {
- // ignored
- }
- }
- return null;
- }
- static readonly RandomNumberGenerator RNG =
- new RNGCryptoServiceProvider();
- /*
- * Build a ClientHello message, with the specified maximum
- * supported version, and list of cipher suites.
- */
- static byte[] MakeClientHello(int version,
- ICollection<int> cipherSuites)
- {
- MemoryStream b = new MemoryStream();
- /*
- * Message header:
- * message type: one byte (1 = "ClientHello")
- * message length: three bytes (this will be adjusted
- * at the end of this method).
- */
- b.WriteByte(1);
- b.WriteByte(0);
- b.WriteByte(0);
- b.WriteByte(0);
- /*
- * The maximum version that we intend to support.
- */
- b.WriteByte((byte)(version >> 8));
- b.WriteByte((byte)version);
- /*
- * The client random has length 32 bytes, but begins with
- * the client's notion of the current time, over 32 bits
- * (seconds since 1970/01/01 00:00:00 UTC, not counting
- * leap seconds).
- */
- byte[] rand = new byte[32];
- RNG.GetBytes(rand);
- M.Enc32be((int)(M.CurrentTimeMillis() / 1000), rand, 0);
- b.Write(rand, 0, rand.Length);
- /*
- * We send an empty session ID.
- */
- b.WriteByte(0);
- /*
- * The list of cipher suites (list of 16-bit values; the
- * list length in bytes is written first).
- */
- int num = cipherSuites.Count;
- byte[] cs = new byte[2 + num * 2];
- M.Enc16be(num * 2, cs, 0);
- int j = 2;
- foreach (int s in cipherSuites) {
- M.Enc16be(s, cs, j);
- j += 2;
- }
- b.Write(cs, 0, cs.Length);
- /*
- * Compression methods: we claim to support Deflate (1)
- * and the standard no-compression (0), with Deflate
- * being preferred.
- */
- b.WriteByte(2);
- b.WriteByte(1);
- b.WriteByte(0);
- /*
- * If we had extensions to add, they would go here.
- */
- /*
- * We now get the message as a blob. The message length
- * must be adjusted in the header.
- */
- byte[] msg = b.ToArray();
- M.Enc24be(msg.Length - 4, msg, 1);
- return msg;
- }
- static readonly IDictionary<int, CipherSuite> CIPHER_SUITES =
- new SortedDictionary<int, CipherSuite>();
- const int CLEAR = 0; // no encryption
- const int WEAK = 1; // weak encryption: 40-bit key
- const int MEDIUM = 2; // medium encryption: 56-bit key
- const int STRONG = 3; // strong encryption
- static string StrengthString(int strength)
- {
- switch (strength) {
- case CLEAR: return "no encryption";
- case WEAK: return "weak encryption (40-bit)";
- case MEDIUM: return "medium encryption (56-bit)";
- case STRONG: return "strong encryption (96-bit or more)";
- default:
- throw new Exception("strange strength: " + strength);
- }
- }
- static string CipherSuiteString(int suite)
- {
- CipherSuite cs = CIPHER_SUITES[suite];
- if (cs == null) {
- return String.Format("UNKNOWN_SUITE:0x{0:X4}", suite);
- } else {
- return cs.name;
- }
- }
- static string CipherSuiteStringV2(int suite)
- {
- CipherSuite cs = CIPHER_SUITES[suite];
- if (cs == null) {
- return String.Format(
- "UNKNOWN_SUITE:{0:X2},{0:X2},{0:X2}",
- suite >> 16, (suite >> 8) & 0xFF, suite & 0xFF);
- } else {
- return cs.name;
- }
- }
- static void MakeCS(int suite, String name,
- bool isCBC, int strength)
- {
- CipherSuite cs = new CipherSuite();
- cs.suite = suite;
- cs.name = name;
- cs.isCBC = isCBC;
- cs.strength = strength;
- CIPHER_SUITES.Add(suite, cs);
- /*
- * Consistency test: the strength and CBC status can normally
- * be inferred from the name itself.
- */
- bool inferredCBC = name.Contains("_CBC_");
- int inferredStrength;
- if (name.Contains("_NULL_")) {
- inferredStrength = CLEAR;
- } else if (name.Contains("DES40") || name.Contains("_40_")
- || name.Contains("EXPORT40"))
- {
- inferredStrength = WEAK;
- } else if ((name.Contains("_DES_") || name.Contains("DES_64"))
- && !name.Contains("DES_192"))
- {
- inferredStrength = MEDIUM;
- } else {
- inferredStrength = STRONG;
- }
- if (inferredStrength != strength || inferredCBC != isCBC) {
- throw new Exception("wrong classification: " + name);
- }
- }
- static void N(int suite, string name)
- {
- MakeCS(suite, name, false, CLEAR);
- }
- static void S4(int suite, string name)
- {
- MakeCS(suite, name, false, WEAK);
- }
- static void S8(int suite, string name)
- {
- MakeCS(suite, name, false, STRONG);
- }
- static void B4(int suite, string name)
- {
- MakeCS(suite, name, true, WEAK);
- }
- static void B5(int suite, string name)
- {
- MakeCS(suite, name, true, MEDIUM);
- }
- static void B8(int suite, string name)
- {
- MakeCS(suite, name, true, STRONG);
- }
- static void InitCipherSuites()
- {
- /*
- * SSLv2 cipher suites.
- */
- S8(0x010080, "RC4_128_WITH_MD5" );
- S4(0x020080, "RC4_128_EXPORT40_WITH_MD5" );
- B8(0x030080, "RC2_128_CBC_WITH_MD5" );
- B4(0x040080, "RC2_128_CBC_EXPORT40_WITH_MD5" );
- B8(0x050080, "IDEA_128_CBC_WITH_MD5" );
- B5(0x060040, "DES_64_CBC_WITH_MD5" );
- B8(0x0700C0, "DES_192_EDE3_CBC_WITH_MD5" );
- /*
- * Original suites (SSLv3, TLS 1.0).
- */
- N(0x0000, "NULL_WITH_NULL_NULL" );
- N(0x0001, "RSA_WITH_NULL_MD5" );
- N(0x0002, "RSA_WITH_NULL_SHA" );
- S4(0x0003, "RSA_EXPORT_WITH_RC4_40_MD5" );
- S8(0x0004, "RSA_WITH_RC4_128_MD5" );
- S8(0x0005, "RSA_WITH_RC4_128_SHA" );
- B4(0x0006, "RSA_EXPORT_WITH_RC2_CBC_40_MD5" );
- B8(0x0007, "RSA_WITH_IDEA_CBC_SHA" );
- B4(0x0008, "RSA_EXPORT_WITH_DES40_CBC_SHA" );
- B5(0x0009, "RSA_WITH_DES_CBC_SHA" );
- B8(0x000A, "RSA_WITH_3DES_EDE_CBC_SHA" );
- B4(0x000B, "DH_DSS_EXPORT_WITH_DES40_CBC_SHA" );
- B5(0x000C, "DH_DSS_WITH_DES_CBC_SHA" );
- B8(0x000D, "DH_DSS_WITH_3DES_EDE_CBC_SHA" );
- B4(0x000E, "DH_RSA_EXPORT_WITH_DES40_CBC_SHA" );
- B5(0x000F, "DH_RSA_WITH_DES_CBC_SHA" );
- B8(0x0010, "DH_RSA_WITH_3DES_EDE_CBC_SHA" );
- B4(0x0011, "DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" );
- B5(0x0012, "DHE_DSS_WITH_DES_CBC_SHA" );
- B8(0x0013, "DHE_DSS_WITH_3DES_EDE_CBC_SHA" );
- B4(0x0014, "DHE_RSA_EXPORT_WITH_DES40_CBC_SHA" );
- B5(0x0015, "DHE_RSA_WITH_DES_CBC_SHA" );
- B8(0x0016, "DHE_RSA_WITH_3DES_EDE_CBC_SHA" );
- S4(0x0017, "DH_anon_EXPORT_WITH_RC4_40_MD5" );
- S8(0x0018, "DH_anon_WITH_RC4_128_MD5" );
- B4(0x0019, "DH_anon_EXPORT_WITH_DES40_CBC_SHA" );
- B5(0x001A, "DH_anon_WITH_DES_CBC_SHA" );
- B8(0x001B, "DH_anon_WITH_3DES_EDE_CBC_SHA" );
- /*
- * FORTEZZA suites (SSLv3 only; see RFC 6101).
- */
- N(0x001C, "FORTEZZA_KEA_WITH_NULL_SHA" );
- B8(0x001D, "FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA" );
- /* This one is deactivated since it conflicts with
- one of the Kerberos cipher suites.
- S8(0x001E, "FORTEZZA_KEA_WITH_RC4_128_SHA" );
- */
- /*
- * Kerberos cipher suites (RFC 2712).
- */
- B5(0x001E, "KRB5_WITH_DES_CBC_SHA" );
- B8(0x001F, "KRB5_WITH_3DES_EDE_CBC_SHA" );
- S8(0x0020, "KRB5_WITH_RC4_128_SHA" );
- B8(0x0021, "KRB5_WITH_IDEA_CBC_SHA" );
- B5(0x0022, "KRB5_WITH_DES_CBC_MD5" );
- B8(0x0023, "KRB5_WITH_3DES_EDE_CBC_MD5" );
- S8(0x0024, "KRB5_WITH_RC4_128_MD5" );
- B8(0x0025, "KRB5_WITH_IDEA_CBC_MD5" );
- B4(0x0026, "KRB5_EXPORT_WITH_DES_CBC_40_SHA" );
- B4(0x0027, "KRB5_EXPORT_WITH_RC2_CBC_40_SHA" );
- S4(0x0028, "KRB5_EXPORT_WITH_RC4_40_SHA" );
- B4(0x0029, "KRB5_EXPORT_WITH_DES_CBC_40_MD5" );
- B4(0x002A, "KRB5_EXPORT_WITH_RC2_CBC_40_MD5" );
- S4(0x002B, "KRB5_EXPORT_WITH_RC4_40_MD5" );
- /*
- * Pre-shared key, no encryption cipher suites (RFC 4785).
- */
- N(0x002C, "PSK_WITH_NULL_SHA" );
- N(0x002D, "DHE_PSK_WITH_NULL_SHA" );
- N(0x002E, "RSA_PSK_WITH_NULL_SHA" );
- /*
- * AES-based suites (TLS 1.1).
- */
- B8(0x002F, "RSA_WITH_AES_128_CBC_SHA" );
- B8(0x0030, "DH_DSS_WITH_AES_128_CBC_SHA" );
- B8(0x0031, "DH_RSA_WITH_AES_128_CBC_SHA" );
- B8(0x0032, "DHE_DSS_WITH_AES_128_CBC_SHA" );
- B8(0x0033, "DHE_RSA_WITH_AES_128_CBC_SHA" );
- B8(0x0034, "DH_anon_WITH_AES_128_CBC_SHA" );
- B8(0x0035, "RSA_WITH_AES_256_CBC_SHA" );
- B8(0x0036, "DH_DSS_WITH_AES_256_CBC_SHA" );
- B8(0x0037, "DH_RSA_WITH_AES_256_CBC_SHA" );
- B8(0x0038, "DHE_DSS_WITH_AES_256_CBC_SHA" );
- B8(0x0039, "DHE_RSA_WITH_AES_256_CBC_SHA" );
- B8(0x003A, "DH_anon_WITH_AES_256_CBC_SHA" );
- /*
- * Suites with SHA-256 (TLS 1.2).
- */
- N(0x003B, "RSA_WITH_NULL_SHA256" );
- B8(0x003C, "RSA_WITH_AES_128_CBC_SHA256" );
- B8(0x003D, "RSA_WITH_AES_256_CBC_SHA256" );
- B8(0x003E, "DH_DSS_WITH_AES_128_CBC_SHA256" );
- B8(0x003F, "DH_RSA_WITH_AES_128_CBC_SHA256" );
- B8(0x0040, "DHE_DSS_WITH_AES_128_CBC_SHA256" );
- B8(0x0067, "DHE_RSA_WITH_AES_128_CBC_SHA256" );
- B8(0x0068, "DH_DSS_WITH_AES_256_CBC_SHA256" );
- B8(0x0069, "DH_RSA_WITH_AES_256_CBC_SHA256" );
- B8(0x006A, "DHE_DSS_WITH_AES_256_CBC_SHA256" );
- B8(0x006B, "DHE_RSA_WITH_AES_256_CBC_SHA256" );
- B8(0x006C, "DH_anon_WITH_AES_128_CBC_SHA256" );
- B8(0x006D, "DH_anon_WITH_AES_256_CBC_SHA256" );
- /*
- * Camellia cipher suites (RFC 5932).
- */
- B8(0x0041, "RSA_WITH_CAMELLIA_128_CBC_SHA" );
- B8(0x0042, "DH_DSS_WITH_CAMELLIA_128_CBC_SHA" );
- B8(0x0043, "DH_RSA_WITH_CAMELLIA_128_CBC_SHA" );
- B8(0x0044, "DHE_DSS_WITH_CAMELLIA_128_CBC_SHA" );
- B8(0x0045, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA" );
- B8(0x0046, "DH_anon_WITH_CAMELLIA_128_CBC_SHA" );
- B8(0x0084, "RSA_WITH_CAMELLIA_256_CBC_SHA" );
- B8(0x0085, "DH_DSS_WITH_CAMELLIA_256_CBC_SHA" );
- B8(0x0086, "DH_RSA_WITH_CAMELLIA_256_CBC_SHA" );
- B8(0x0087, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA" );
- B8(0x0088, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA" );
- B8(0x0089, "DH_anon_WITH_CAMELLIA_256_CBC_SHA" );
- /*
- * Unsorted (yet), from the IANA TLS registry:
- * http://www.iana.org/assignments/tls-parameters/
- */
- S8(0x008A, "TLS_PSK_WITH_RC4_128_SHA" );
- B8(0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA" );
- B8(0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA" );
- B8(0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA" );
- S8(0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA" );
- B8(0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA" );
- B8(0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA" );
- B8(0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA" );
- S8(0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA" );
- B8(0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA" );
- B8(0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA" );
- B8(0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA" );
- B8(0x0096, "TLS_RSA_WITH_SEED_CBC_SHA" );
- B8(0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA" );
- B8(0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA" );
- B8(0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA" );
- B8(0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA" );
- B8(0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA" );
- S8(0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256" );
- S8(0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384" );
- S8(0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256" );
- S8(0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384" );
- S8(0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256" );
- S8(0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384" );
- S8(0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256" );
- S8(0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384" );
- S8(0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256" );
- S8(0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384" );
- S8(0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256" );
- S8(0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384" );
- S8(0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256" );
- S8(0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384" );
- S8(0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256" );
- S8(0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384" );
- S8(0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256" );
- S8(0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384" );
- B8(0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256" );
- B8(0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384" );
- N(0x00B0, "TLS_PSK_WITH_NULL_SHA256" );
- N(0x00B1, "TLS_PSK_WITH_NULL_SHA384" );
- B8(0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256" );
- B8(0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384" );
- N(0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256" );
- N(0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384" );
- B8(0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256" );
- B8(0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384" );
- N(0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256" );
- N(0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384" );
- B8(0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256" );
- B8(0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256" );
- B8(0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256" );
- B8(0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256" );
- B8(0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256" );
- B8(0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256" );
- /* This one is a fake cipher suite which marks a
- renegotiation.
- N(0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV" );
- */
- N(0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA" );
- S8(0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA" );
- B8(0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA" );
- B8(0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA" );
- N(0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA" );
- S8(0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA" );
- B8(0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA" );
- B8(0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA" );
- N(0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA" );
- S8(0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA" );
- B8(0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA" );
- B8(0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA" );
- N(0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA" );
- S8(0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA" );
- B8(0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA" );
- B8(0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA" );
- N(0xC015, "TLS_ECDH_anon_WITH_NULL_SHA" );
- S8(0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA" );
- B8(0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA" );
- B8(0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA" );
- B8(0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA" );
- B8(0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA" );
- B8(0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA" );
- B8(0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA" );
- B8(0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA" );
- B8(0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA" );
- B8(0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256" );
- B8(0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384" );
- B8(0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256" );
- B8(0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384" );
- B8(0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256" );
- B8(0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384" );
- B8(0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256" );
- B8(0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384" );
- S8(0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" );
- S8(0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384" );
- S8(0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256" );
- S8(0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384" );
- S8(0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" );
- S8(0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384" );
- S8(0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256" );
- S8(0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384" );
- S8(0xC033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA" );
- B8(0xC034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA" );
- B8(0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA" );
- B8(0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA" );
- B8(0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256" );
- B8(0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384" );
- N(0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA" );
- N(0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256" );
- N(0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384" );
- B8(0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC03E, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC03F, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384" );
- S8(0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC05A, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC05B, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384" );
- B8(0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384" );
- S8(0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384" );
- S8(0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256" );
- S8(0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384" );
- B8(0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256" );
- B8(0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384" );
- B8(0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" );
- B8(0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384" );
- B8(0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384" );
- B8(0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384" );
- S8(0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC07E, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC07F, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384" );
- S8(0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256" );
- S8(0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384" );
- B8(0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384" );
- B8(0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" );
- B8(0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384" );
- B8(0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256" );
- B8(0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384" );
- S8(0xC09C, "TLS_RSA_WITH_AES_128_CCM" );
- S8(0xC09D, "TLS_RSA_WITH_AES_256_CCM" );
- S8(0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM" );
- S8(0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM" );
- S8(0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8" );
- S8(0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8" );
- S8(0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8" );
- S8(0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8" );
- S8(0xC0A4, "TLS_PSK_WITH_AES_128_CCM" );
- S8(0xC0A5, "TLS_PSK_WITH_AES_256_CCM" );
- S8(0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM" );
- S8(0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM" );
- S8(0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8" );
- S8(0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8" );
- S8(0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8" );
- S8(0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8" );
- }
- }
- class CipherSuite {
- internal int suite;
- internal string name;
- internal bool isCBC;
- internal int strength;
- }
- class M {
- internal const int CHANGE_CIPHER_SPEC = 20;
- internal const int ALERT = 21;
- internal const int HANDSHAKE = 22;
- internal const int APPLICATION = 23;
- internal static void Enc16be(int val, byte[] buf, int off)
- {
- buf[off] = (byte)(val >> 8);
- buf[off + 1] = (byte)val;
- }
- internal static void Enc24be(int val, byte[] buf, int off)
- {
- buf[off] = (byte)(val >> 16);
- buf[off + 1] = (byte)(val >> 8);
- buf[off + 2] = (byte)val;
- }
- internal static void Enc32be(int val, byte[] buf, int off)
- {
- buf[off] = (byte)(val >> 24);
- buf[off + 1] = (byte)(val >> 16);
- buf[off + 2] = (byte)(val >> 8);
- buf[off + 3] = (byte)val;
- }
- internal static int Dec16be(byte[] buf, int off)
- {
- return ((int)buf[off] << 8)
- | (int)buf[off + 1];
- }
- internal static int Dec24be(byte[] buf, int off)
- {
- return ((int)buf[off] << 16)
- | ((int)buf[off + 1] << 8)
- | (int)buf[off + 2];
- }
- internal static uint Dec32be(byte[] buf, int off)
- {
- return ((uint)buf[off] << 24)
- | ((uint)buf[off + 1] << 16)
- | ((uint)buf[off + 2] << 8)
- | (uint)buf[off + 3];
- }
- internal static void ReadFully(Stream s, byte[] buf)
- {
- ReadFully(s, buf, 0, buf.Length);
- }
- internal static void ReadFully(Stream s, byte[] buf, int off, int len)
- {
- while (len > 0) {
- int rlen = s.Read(buf, off, len);
- if (rlen <= 0) {
- throw new EndOfStreamException();
- }
- off += rlen;
- len -= rlen;
- }
- }
- static readonly DateTime Jan1st1970 =
- new DateTime(1970, 1, 1, 0, 0, 0, DateTimeKind.Utc);
- internal static long CurrentTimeMillis()
- {
- return (long)(DateTime.UtcNow - Jan1st1970).TotalMilliseconds;
- }
- /*
- * Compute the SHA-1 hash of some bytes, returning the hash
- * value in hexadecimal.
- */
- internal static string DoSHA1(byte[] buf)
- {
- return DoSHA1(buf, 0, buf.Length);
- }
- internal static string DoSHA1(byte[] buf, int off, int len)
- {
- byte[] hv = new SHA1Managed().ComputeHash(buf, off, len);
- StringBuilder sb = new StringBuilder();
- foreach (byte b in hv) {
- sb.AppendFormat("{0:x2}", b);
- }
- return sb.ToString();
- }
- /*
- * A constant SSLv2 CLIENT-HELLO message. Only one connection
- * is needed for SSLv2, since the server response will contain
- * _all_ the cipher suites that the server is willing to
- * support.
- *
- * Note: when (mis)interpreted as a SSLv3+ record, this message
- * apparently encodes some data of (invalid) 0x80 type, using
- * protocol version TLS 44.1, and record length of 2 bytes.
- * Thus, the receiving part will quickly conclude that it will
- * not support that, instead of stalling for more data from the
- * client.
- */
- internal static byte[] SSL2_CLIENT_HELLO = {
- 0x80, 0x2E, // header (record length)
- 0x01, // message type (CLIENT HELLO)
- 0x00, 0x02, // version (0x0002)
- 0x00, 0x15, // cipher specs list length
- 0x00, 0x00, // session ID length
- 0x00, 0x10, // challenge length
- 0x01, 0x00, 0x80, // SSL_CK_RC4_128_WITH_MD5
- 0x02, 0x00, 0x80, // SSL_CK_RC4_128_EXPORT40_WITH_MD5
- 0x03, 0x00, 0x80, // SSL_CK_RC2_128_CBC_WITH_MD5
- 0x04, 0x00, 0x80, // SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5
- 0x05, 0x00, 0x80, // SSL_CK_IDEA_128_CBC_WITH_MD5
- 0x06, 0x00, 0x40, // SSL_CK_DES_64_CBC_WITH_MD5
- 0x07, 0x00, 0xC0, // SSL_CK_DES_192_EDE3_CBC_WITH_MD5
- 0x54, 0x54, 0x54, 0x54, // challenge data (16 bytes)
- 0x54, 0x54, 0x54, 0x54,
- 0x54, 0x54, 0x54, 0x54,
- 0x54, 0x54, 0x54, 0x54
- };
- }
- // CanRead, CanSeek, CanWrite, Flush, Length, Position, Seek, SetLength
- class SSLRecord : Stream {
- const int MAX_RECORD_LEN = 16384;
- Stream sub;
- byte[] outBuf = new byte[MAX_RECORD_LEN + 5];
- int outPtr;
- int outVersion;
- int outType;
- byte[] inBuf = new byte[MAX_RECORD_LEN + 5];
- int inPtr;
- int inEnd;
- int inVersion;
- int inType;
- int inExpectedType;
- internal SSLRecord(Stream sub)
- {
- this.sub = sub;
- outPtr = 5;
- inPtr = 0;
- inEnd = 0;
- }
- public override bool CanRead { get { return true; } }
- public override bool CanSeek { get { return false; } }
- public override bool CanWrite { get { return true; } }
- public override long Length {
- get { throw new NotSupportedException(); }
- }
- public override long Position {
- get { throw new NotSupportedException(); }
- set { throw new NotSupportedException(); }
- }
- public override long Seek(long offset, SeekOrigin origin)
- {
- throw new NotSupportedException();
- }
- public override void SetLength(long value)
- {
- throw new NotSupportedException();
- }
- internal void SetOutType(int type)
- {
- this.outType = type;
- }
- internal void SetOutVersion(int version)
- {
- this.outVersion = version;
- }
- public override void Flush()
- {
- outBuf[0] = (byte)outType;
- M.Enc16be(outVersion, outBuf, 1);
- M.Enc16be(outPtr - 5, outBuf, 3);
- sub.Write(outBuf, 0, outPtr);
- sub.Flush();
- outPtr = 5;
- }
- public override void WriteByte(byte b)
- {
- outBuf[outPtr ++] = b;
- if (outPtr == outBuf.Length) {
- Flush();
- }
- }
- public void Write(byte[] buf)
- {
- Write(buf, 0, buf.Length);
- }
- public override void Write(byte[] buf, int off, int len)
- {
- while (len > 0) {
- int clen = Math.Min(outBuf.Length - outPtr, len);
- Array.Copy(buf, off, outBuf, outPtr, clen);
- outPtr += clen;
- off += clen;
- len -= clen;
- if (outPtr == outBuf.Length) {
- Flush();
- }
- }
- }
- internal void SetExpectedType(int expectedType)
- {
- this.inExpectedType = expectedType;
- }
- internal int GetInVersion()
- {
- return inVersion;
- }
- void Refill()
- {
- for (;;) {
- M.ReadFully(sub, inBuf, 0, 5);
- inType = inBuf[0];
- inVersion = M.Dec16be(inBuf, 1);
- inEnd = M.Dec16be(inBuf, 3);
- M.ReadFully(sub, inBuf, 0, inEnd);
- inPtr = 0;
- if (inType != inExpectedType) {
- if (inType == M.ALERT) {
- /*
- * We just ignore alert
- * messages.
- */
- continue;
- }
- throw new IOException(
- "unexpected record type: "
- + inType);
- }
- return;
- }
- }
- public override int ReadByte()
- {
- while (inPtr == inEnd) {
- Refill();
- }
- return inBuf[inPtr ++];
- }
- public override int Read(byte[] buf, int off, int len)
- {
- while (inPtr == inEnd) {
- Refill();
- }
- int clen = Math.Min(inEnd - inPtr, len);
- Array.Copy(inBuf, inPtr, buf, off, clen);
- inPtr += clen;
- return clen;
- }
- }
- /*
- * This class decodes a ServerHello message from the server. The
- * fields we are interested in are stored in the
- * package-accessible fields.
- */
- class ServerHello {
- internal int recordVersion;
- internal int protoVersion;
- internal long serverTime;
- internal int cipherSuite;
- internal int compression;
- internal string serverCertName;
- internal string serverCertHash;
- internal ServerHello(SSLRecord rec)
- {
- rec.SetExpectedType(M.HANDSHAKE);
- /*
- * First, get the handshake message header (4 bytes).
- * First byte should be 2 ("ServerHello"), then
- * comes the message size (over 3 bytes).
- */
- byte[] buf = new byte[4];
- M.ReadFully(rec, buf);
- recordVersion = rec.GetInVersion();
- if (buf[0] != 2) {
- throw new IOException("unexpected handshake"
- + " message type: " + buf[0]);
- }
- buf = new byte[M.Dec24be(buf, 1)];
- /*
- * Read the complete message in RAM.
- */
- M.ReadFully(rec, buf);
- int ptr = 0;
- /*
- * The protocol version which we will use.
- */
- if (ptr + 2 > buf.Length) {
- throw new IOException("invalid ServerHello");
- }
- protoVersion = M.Dec16be(buf, 0);
- ptr += 2;
- /*
- * The server random begins with the server's notion
- * of the current time.
- */
- if (ptr + 32 > buf.Length) {
- throw new IOException("invalid ServerHello");
- }
- serverTime = 1000L * (long)M.Dec32be(buf, ptr);
- ptr += 32;
- /*
- * We skip the session ID.
- */
- if (ptr + 1 > buf.Length) {
- throw new IOException("invalid ServerHello");
- }
- ptr += 1 + buf[ptr];
- /*
- * The cipher suite and compression follow.
- */
- if (ptr + 3 > buf.Length) {
- throw new IOException("invalid ServerHello");
- }
- cipherSuite = M.Dec16be(buf, ptr);
- compression = buf[ptr + 2];
- /*
- * The ServerHello could include some extensions
- * here, which we ignore.
- */
- /*
- * We now read a few extra messages, until we
- * reach the server's Certificate message, or
- * ServerHelloDone.
- */
- for (;;) {
- buf = new byte[4];
- M.ReadFully(rec, buf);
- int mt = buf[0];
- buf = new byte[M.Dec24be(buf, 1)];
- M.ReadFully(rec, buf);
- switch (mt) {
- case 11:
- ProcessCertificate(buf);
- return;
- case 14:
- // ServerHelloDone
- return;
- }
- }
- }
- private void ProcessCertificate(byte[] buf)
- {
- if (buf.Length <= 6) {
- return;
- }
- int len1 = M.Dec24be(buf, 0);
- if (len1 != buf.Length - 3) {
- return;
- }
- int len2 = M.Dec24be(buf, 3);
- if (len2 > buf.Length - 6) {
- return;
- }
- byte[] ec = new byte[len2];
- Array.Copy(buf, 6, ec, 0, len2);
- try {
- X509Certificate2 xc = new X509Certificate2(ec);
- serverCertName = xc.SubjectName.Name;
- } catch (Exception) {
- // ignored
- return;
- }
- serverCertHash = M.DoSHA1(ec);
- }
- }
- /*
- * This class represents the response of a server which knows
- $ SSLv2. It includes the list of cipher suites and the
- * identification of the server certificate.
- */
- class ServerHelloSSLv2 {
- internal int[] cipherSuites;
- internal string serverCertName;
- internal string serverCertHash;
- internal ServerHelloSSLv2(Stream ss)
- {
- // Record length
- byte[] buf = new byte[2];
- M.ReadFully(ss, buf);
- int len = M.Dec16be(buf, 0);
- if ((len & 0x8000) == 0) {
- throw new IOException("not a SSLv2 record");
- }
- len &= 0x7FFF;
- if (len < 11) {
- throw new IOException(
- "not a SSLv2 server hello");
- }
- buf = new byte[11];
- M.ReadFully(ss, buf);
- if (buf[0] != 0x04) {
- throw new IOException(
- "not a SSLv2 server hello");
- }
- int certLen = M.Dec16be(buf, 5);
- int csLen = M.Dec16be(buf, 7);
- int connIdLen = M.Dec16be(buf, 9);
- if (len != 11 + certLen + csLen + connIdLen) {
- throw new IOException(
- "not a SSLv2 server hello");
- }
- if (csLen == 0 || csLen % 3 != 0) {
- throw new IOException(
- "not a SSLv2 server hello");
- }
- byte[] cert = new byte[certLen];
- M.ReadFully(ss, cert);
- byte[] cs = new byte[csLen];
- M.ReadFully(ss, cs);
- byte[] connId = new byte[connIdLen];
- M.ReadFully(ss, connId);
- cipherSuites = new int[csLen / 3];
- for (int i = 0, j = 0; i < csLen; i += 3, j ++) {
- cipherSuites[j] = M.Dec24be(cs, i);
- }
- try {
- X509Certificate2 xc = new X509Certificate2(cert);
- serverCertName = xc.SubjectName.Name;
- } catch (Exception) {
- // ignored
- return;
- }
- serverCertHash = M.DoSHA1(cert);
- }
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement