Advertisement
opexxx

TestSSLServer.java

Nov 18th, 2014
262
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 48.19 KB | None | 0 0
  1. /*
  2.  * Command-line tool to test a SSL/TLS server for some vulnerabilities.
  3.  * =====================================================================
  4.  *
  5.  * This application connects to the provided SSL/TLS server (by name and
  6.  * port) and extracts the following information:
  7.  * - supported versions (SSL 2.0, SSL 3.0, TLS 1.0 to 1.2)
  8.  * - support of Deflate compression
  9.  * - list of supported cipher suites (for each protocol version)
  10.  * - BEAST/CRIME vulnerabilities.
  11.  *
  12.  * BEAST and CRIME are client-side attack, but the server can protect the
  13.  * client by refusing to use the feature combinations which can be
  14.  * attacked. For CRIME, the weakness is Deflate compression. For BEAST,
  15.  * the attack conditions are more complex: it works with CBC ciphers with
  16.  * SSL 3.0 and TLS 1.0. Hence, a server fails to protect the client against
  17.  * BEAST if it does not enforce usage of RC4 over CBC ciphers under these
  18.  * protocol versions, if given the choice.
  19.  *
  20.  * (The BEAST test considers only the cipher suites with strong
  21.  * encryption; if the server supports none, then there are bigger
  22.  * problems. We also assume that all clients support RC4-128; thus, the
  23.  * server protects the client if it selects RC4-128 even if some strong
  24.  * CBC-based ciphers are announced as supported by the client with a
  25.  * higher preference level.)
  26.  *
  27.  * ----------------------------------------------------------------------
  28.  * Copyright (c) 2012  Thomas Pornin <pornin@bolet.org>
  29.  *
  30.  * Permission is hereby granted, free of charge, to any person obtaining
  31.  * a copy of this software and associated documentation files (the
  32.  * "Software"), to deal in the Software without restriction, including
  33.  * without limitation the rights to use, copy, modify, merge, publish,
  34.  * distribute, sublicense, and/or sell copies of the Software, and to
  35.  * permit persons to whom the Software is furnished to do so, subject to
  36.  * the following conditions:
  37.  *
  38.  * The above copyright notice and this permission notice shall be
  39.  * included in all copies or substantial portions of the Software.
  40.  *
  41.  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  42.  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  43.  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  44.  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
  45.  * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
  46.  * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
  47.  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  48.  * SOFTWARE.
  49.  * ----------------------------------------------------------------------
  50.  */
  51.  
  52. import java.io.ByteArrayInputStream;
  53. import java.io.ByteArrayOutputStream;
  54. import java.io.EOFException;
  55. import java.io.InputStream;
  56. import java.io.IOException;
  57. import java.io.OutputStream;
  58. import java.net.InetSocketAddress;
  59. import java.net.Socket;
  60. import java.security.MessageDigest;
  61. import java.security.NoSuchAlgorithmException;
  62. import java.security.SecureRandom;
  63. import java.security.cert.CertificateException;
  64. import java.security.cert.CertificateFactory;
  65. import java.security.cert.X509Certificate;
  66. import java.util.ArrayList;
  67. import java.util.Collection;
  68. import java.util.Formatter;
  69. import java.util.List;
  70. import java.util.Map;
  71. import java.util.Set;
  72. import java.util.TreeMap;
  73. import java.util.TreeSet;
  74.  
  75. public class TestSSLServer {
  76.  
  77.     static void usage()
  78.     {
  79.         System.err.println("usage: TestSSLServer servername [ port ]");
  80.         System.exit(1);
  81.     }
  82.  
  83.     public static void main(String[] args)
  84.         throws IOException
  85.     {
  86.         if (args.length == 0 || args.length > 2) {
  87.             usage();
  88.         }
  89.         String name = args[0];
  90.         int port = 443;
  91.         if (args.length == 2) {
  92.             try {
  93.                 port = Integer.parseInt(args[1]);
  94.             } catch (NumberFormatException nfe) {
  95.                 usage();
  96.             }
  97.             if (port <= 0 || port > 65535) {
  98.                 usage();
  99.             }
  100.         }
  101.         InetSocketAddress isa = new InetSocketAddress(name, port);
  102.  
  103.         Set<Integer> sv = new TreeSet<Integer>();
  104.         boolean compress = false;
  105.         for (int v = 0x0300; v <= 0x0303; v ++) {
  106.             ServerHello sh = connect(isa,
  107.                 v, CIPHER_SUITES.keySet());
  108.             if (sh == null) {
  109.                 continue;
  110.             }
  111.             sv.add(sh.protoVersion);
  112.             if (sh.compression == 1) {
  113.                 compress = true;
  114.             }
  115.         }
  116.  
  117.         ServerHelloSSLv2 sh2 = connectV2(isa);
  118.  
  119.         if (sh2 != null) {
  120.             sv.add(0x0200);
  121.         }
  122.  
  123.         if (sv.size() == 0) {
  124.             System.out.println("No SSL/TLS server at " + isa);
  125.             System.exit(1);
  126.         }
  127.         System.out.print("Supported versions:");
  128.         for (int v : sv) {
  129.             System.out.print(" ");
  130.             System.out.print(versionString(v));
  131.         }
  132.         System.out.println();
  133.         System.out.println("Deflate compression: "
  134.             + (compress ? "YES" : "no"));
  135.  
  136.         System.out.println("Supported cipher suites"
  137.             + " (ORDER IS NOT SIGNIFICANT):");
  138.         Set<Integer> lastSuppCS = null;
  139.         Map<Integer, Set<Integer>> suppCS =
  140.             new TreeMap<Integer, Set<Integer>>();
  141.         Set<String> certID = new TreeSet<String>();
  142.  
  143.         if (sh2 != null) {
  144.             System.out.println("  " + versionString(0x0200));
  145.             Set<Integer> vc2 = new TreeSet<Integer>();
  146.             for (int c : sh2.cipherSuites) {
  147.                 vc2.add(c);
  148.             }
  149.             for (int c : vc2) {
  150.                 System.out.println("     "
  151.                     + cipherSuiteStringV2(c));
  152.             }
  153.             suppCS.put(0x0200, vc2);
  154.             if (sh2.serverCertName != null) {
  155.                 certID.add(sh2.serverCertHash
  156.                     + ": " + sh2.serverCertName);
  157.             }
  158.         }
  159.  
  160.         for (int v : sv) {
  161.             if (v == 0x0200) {
  162.                 continue;
  163.             }
  164.             Set<Integer> vsc = supportedSuites(isa, v, certID);
  165.             suppCS.put(v, vsc);
  166.             if (lastSuppCS == null || !lastSuppCS.equals(vsc)) {
  167.                 System.out.println("  " + versionString(v));
  168.                 for (int c : vsc) {
  169.                     System.out.println("     "
  170.                         + cipherSuiteString(c));
  171.                 }
  172.                 lastSuppCS = vsc;
  173.             } else {
  174.                 System.out.println("  (" + versionString(v)
  175.                     + ": idem)");
  176.             }
  177.         }
  178.         System.out.println("----------------------");
  179.         if (certID.size() == 0) {
  180.             System.out.println("No server certificate !");
  181.         } else {
  182.             System.out.println("Server certificate(s):");
  183.             for (String cc : certID) {
  184.                 System.out.println("  " + cc);
  185.             }
  186.         }
  187.         System.out.println("----------------------");
  188.         int agMaxStrength = STRONG;
  189.         int agMinStrength = STRONG;
  190.         boolean vulnBEAST = false;
  191.         for (int v : sv) {
  192.             Set<Integer> vsc = suppCS.get(v);
  193.             agMaxStrength = Math.min(
  194.                 maxStrength(vsc), agMaxStrength);
  195.             agMinStrength = Math.min(
  196.                 minStrength(vsc), agMinStrength);
  197.             if (!vulnBEAST) {
  198.                 vulnBEAST = testBEAST(isa, v, vsc);
  199.             }
  200.         }
  201.         System.out.println("Minimal encryption strength:     "
  202.             + strengthString(agMinStrength));
  203.         System.out.println("Achievable encryption strength:  "
  204.             + strengthString(agMaxStrength));
  205.         System.out.println("BEAST status: "
  206.             + (vulnBEAST ? "vulnerable" : "protected"));
  207.         System.out.println("CRIME status: "
  208.             + (compress ? "vulnerable" : "protected"));
  209.     }
  210.  
  211.     /*
  212.      * Get cipher suites supported by the server. This is done by
  213.      * repeatedly contacting the server, each time removing from our
  214.      * list of supported suites the suite which the server just
  215.      * selected. We keep on until the server can no longer respond
  216.      * to us with a ServerHello.
  217.      */
  218.     static Set<Integer> supportedSuites(InetSocketAddress isa, int version,
  219.         Set<String> serverCertID)
  220.     {
  221.         Set<Integer> cs = new TreeSet<Integer>(CIPHER_SUITES.keySet());
  222.         Set<Integer> rs = new TreeSet<Integer>();
  223.         for (;;) {
  224.             ServerHello sh = connect(isa, version, cs);
  225.             if (sh == null) {
  226.                 break;
  227.             }
  228.             if (!cs.contains(sh.cipherSuite)) {
  229.                 System.err.printf("[ERR: server wants to use"
  230.                     + " cipher suite 0x%04X which client"
  231.                     + " did not announce]", sh.cipherSuite);
  232.                 System.err.println();
  233.                 break;
  234.             }
  235.             cs.remove(sh.cipherSuite);
  236.             rs.add(sh.cipherSuite);
  237.             if (sh.serverCertName != null) {
  238.                 serverCertID.add(sh.serverCertHash
  239.                     + ": " + sh.serverCertName);
  240.             }
  241.         }
  242.         return rs;
  243.     }
  244.  
  245.     static int minStrength(Set<Integer> supp)
  246.     {
  247.         int m = STRONG;
  248.         for (int suite : supp) {
  249.             CipherSuite cs = CIPHER_SUITES.get(suite);
  250.             if (cs == null) {
  251.                 continue;
  252.             }
  253.             if (cs.strength < m) {
  254.                 m = cs.strength;
  255.             }
  256.         }
  257.         return m;
  258.     }
  259.  
  260.     static int maxStrength(Set<Integer> supp)
  261.     {
  262.         int m = CLEAR;
  263.         for (int suite : supp) {
  264.             CipherSuite cs = CIPHER_SUITES.get(suite);
  265.             if (cs == null) {
  266.                 continue;
  267.             }
  268.             if (cs.strength > m) {
  269.                 m = cs.strength;
  270.             }
  271.         }
  272.         return m;
  273.     }
  274.  
  275.     static boolean testBEAST(InetSocketAddress isa,
  276.         int version, Set<Integer> supp)
  277.     {
  278.         /*
  279.          * TLS 1.1+ is not vulnerable to BEAST.
  280.          * We do not test SSLv2 either.
  281.          */
  282.         if (version < 0x0300 || version > 0x0301) {
  283.             return false;
  284.         }
  285.  
  286.         /*
  287.          * BEAST attack works if the server allows the client to
  288.          * use a CBC cipher. Existing clients also supports RC4,
  289.          * so we consider that a server protects the clients if
  290.          * it chooses RC4 over CBC streams when given the choice.
  291.          * We only consider strong cipher suites here.
  292.          */
  293.         List<Integer> strongCBC = new ArrayList<Integer>();
  294.         List<Integer> strongStream = new ArrayList<Integer>();
  295.         for (int suite : supp) {
  296.             CipherSuite cs = CIPHER_SUITES.get(suite);
  297.             if (cs == null) {
  298.                 continue;
  299.             }
  300.             if (cs.strength < STRONG) {
  301.                 continue;
  302.             }
  303.             if (cs.isCBC) {
  304.                 strongCBC.add(suite);
  305.             } else {
  306.                 strongStream.add(suite);
  307.             }
  308.         }
  309.         if (strongCBC.size() == 0) {
  310.             return false;
  311.         }
  312.         if (strongStream.size() == 0) {
  313.             return true;
  314.         }
  315.         List<Integer> ns = new ArrayList<Integer>(strongCBC);
  316.         ns.addAll(strongStream);
  317.         ServerHello sh = connect(isa, version, ns);
  318.         return !strongStream.contains(sh.cipherSuite);
  319.     }
  320.  
  321.     static String versionString(int version)
  322.     {
  323.         if (version == 0x0200) {
  324.             return "SSLv2";
  325.         } else if (version == 0x0300) {
  326.             return "SSLv3";
  327.         } else if ((version >>> 8) == 0x03) {
  328.             return "TLSv1." + ((version & 0xFF) - 1);
  329.         } else {
  330.             return String.format("UNKNOWN_VERSION:0x%04X", version);
  331.         }
  332.     }
  333.  
  334.     /*
  335.      * Connect to the server, send a ClientHello, and decode the
  336.      * response (ServerHello). On error, null is returned.
  337.      */
  338.     static ServerHello connect(InetSocketAddress isa,
  339.         int version, Collection<Integer> cipherSuites)
  340.     {
  341.         Socket s = null;
  342.         try {
  343.             s = new Socket();
  344.             try {
  345.                 s.connect(isa);
  346.             } catch (IOException ioe) {
  347.                 System.err.println("could not connect to "
  348.                     + isa + ": " + ioe.toString());
  349.                 return null;
  350.             }
  351.             byte[] ch = makeClientHello(version, cipherSuites);
  352.             OutputRecord orec = new OutputRecord(
  353.                 s.getOutputStream());
  354.             orec.setType(HANDSHAKE);
  355.             orec.setVersion(version);
  356.             orec.write(ch);
  357.             orec.flush();
  358.             return new ServerHello(s.getInputStream());
  359.         } catch (IOException ioe) {
  360.             // ignored
  361.         } finally {
  362.             try {
  363.                 s.close();
  364.             } catch (IOException ioe) {
  365.                 // ignored
  366.             }
  367.         }
  368.         return null;
  369.     }
  370.  
  371.     /*
  372.      * Connect to the server, send a SSLv2 CLIENT HELLO, and decode
  373.      * the response (SERVER HELLO). On error, null is returned.
  374.      */
  375.     static ServerHelloSSLv2 connectV2(InetSocketAddress isa)
  376.     {
  377.         Socket s = null;
  378.         try {
  379.             s = new Socket();
  380.             try {
  381.                 s.connect(isa);
  382.             } catch (IOException ioe) {
  383.                 System.err.println("could not connect to "
  384.                     + isa + ": " + ioe.toString());
  385.                 return null;
  386.             }
  387.             s.getOutputStream().write(SSL2_CLIENT_HELLO);
  388.             return new ServerHelloSSLv2(s.getInputStream());
  389.         } catch (IOException ioe) {
  390.             // ignored
  391.         } finally {
  392.             try {
  393.                 s.close();
  394.             } catch (IOException ioe) {
  395.                 // ignored
  396.             }
  397.         }
  398.         return null;
  399.     }
  400.  
  401.     static final void enc16be(int val, byte[] buf, int off)
  402.     {
  403.         buf[off] = (byte)(val >>> 8);
  404.         buf[off + 1] = (byte)val;
  405.     }
  406.  
  407.     static final void enc24be(int val, byte[] buf, int off)
  408.     {
  409.         buf[off] = (byte)(val >>> 16);
  410.         buf[off + 1] = (byte)(val >>> 8);
  411.         buf[off + 2] = (byte)val;
  412.     }
  413.  
  414.     static final void enc32be(int val, byte[] buf, int off)
  415.     {
  416.         buf[off] = (byte)(val >>> 24);
  417.         buf[off + 1] = (byte)(val >>> 16);
  418.         buf[off + 2] = (byte)(val >>> 8);
  419.         buf[off + 3] = (byte)val;
  420.     }
  421.  
  422.     static final int dec16be(byte[] buf, int off)
  423.     {
  424.         return ((buf[off] & 0xFF) << 8)
  425.             | (buf[off + 1] & 0xFF);
  426.     }
  427.  
  428.     static final int dec24be(byte[] buf, int off)
  429.     {
  430.         return ((buf[off] & 0xFF) << 16)
  431.             | ((buf[off + 1] & 0xFF) << 8)
  432.             | (buf[off + 2] & 0xFF);
  433.     }
  434.  
  435.     static final int dec32be(byte[] buf, int off)
  436.     {
  437.         return ((buf[off] & 0xFF) << 24)
  438.             | ((buf[off + 1] & 0xFF) << 16)
  439.             | ((buf[off + 2] & 0xFF) << 8)
  440.             | (buf[off + 3] & 0xFF);
  441.     }
  442.  
  443.     static final int CHANGE_CIPHER_SPEC = 20;
  444.     static final int ALERT              = 21;
  445.     static final int HANDSHAKE          = 22;
  446.     static final int APPLICATION        = 23;
  447.  
  448.     static final int MAX_RECORD_LEN = 16384;
  449.  
  450.     /*
  451.      * A custom stream which encodes data bytes into SSL/TLS records
  452.      * (no encryption).
  453.      */
  454.     static class OutputRecord extends OutputStream {
  455.  
  456.         private OutputStream out;
  457.         private byte[] buffer = new byte[MAX_RECORD_LEN + 5];
  458.         private int ptr;
  459.         private int version;
  460.         private int type;
  461.  
  462.         OutputRecord(OutputStream out)
  463.         {
  464.             this.out = out;
  465.             ptr = 5;
  466.         }
  467.  
  468.         void setType(int type)
  469.         {
  470.             this.type = type;
  471.         }
  472.  
  473.         void setVersion(int version)
  474.         {
  475.             this.version = version;
  476.         }
  477.  
  478.         public void flush()
  479.             throws IOException
  480.         {
  481.             buffer[0] = (byte)type;
  482.             enc16be(version, buffer, 1);
  483.             enc16be(ptr - 5, buffer, 3);
  484.             out.write(buffer, 0, ptr);
  485.             out.flush();
  486.             ptr = 5;
  487.         }
  488.  
  489.         public void write(int b)
  490.             throws IOException
  491.         {
  492.             buffer[ptr ++] = (byte)b;
  493.             if (ptr == buffer.length) {
  494.                 flush();
  495.             }
  496.         }
  497.  
  498.         public void write(byte[] buf, int off, int len)
  499.             throws IOException
  500.         {
  501.             while (len > 0) {
  502.                 int clen = Math.min(buffer.length - ptr, len);
  503.                 System.arraycopy(buf, off, buffer, ptr, clen);
  504.                 ptr += clen;
  505.                 off += clen;
  506.                 len -= clen;
  507.                 if (ptr == buffer.length) {
  508.                     flush();
  509.                 }
  510.             }
  511.         }
  512.     }
  513.  
  514.     static void readFully(InputStream in, byte[] buf)
  515.         throws IOException
  516.     {
  517.         readFully(in, buf, 0, buf.length);
  518.     }
  519.  
  520.     static void readFully(InputStream in, byte[] buf, int off, int len)
  521.         throws IOException
  522.     {
  523.         while (len > 0) {
  524.             int rlen = in.read(buf, off, len);
  525.             if (rlen < 0) {
  526.                 throw new EOFException();
  527.             }
  528.             off += rlen;
  529.             len -= rlen;
  530.         }
  531.     }
  532.  
  533.     /*
  534.      * A custom stream which expects SSL/TLS records (no encryption)
  535.      * and rebuilds the encoded data stream. Incoming records MUST
  536.      * have the expected type (e.g. "handshake"); alert messages
  537.      * are skipped.
  538.      */
  539.     static class InputRecord extends InputStream {
  540.  
  541.         private InputStream in;
  542.         private byte[] buffer = new byte[MAX_RECORD_LEN + 5];
  543.         private int ptr, end;
  544.         private int version;
  545.         private int type;
  546.         private int expectedType;
  547.  
  548.         InputRecord(InputStream in)
  549.         {
  550.             this.in = in;
  551.             ptr = 0;
  552.             end = 0;
  553.         }
  554.  
  555.         void setExpectedType(int expectedType)
  556.         {
  557.             this.expectedType = expectedType;
  558.         }
  559.  
  560.         int getVersion()
  561.         {
  562.             return version;
  563.         }
  564.  
  565.         private void refill()
  566.             throws IOException
  567.         {
  568.             for (;;) {
  569.                 readFully(in, buffer, 0, 5);
  570.                 type = buffer[0] & 0xFF;
  571.                 version = dec16be(buffer, 1);
  572.                 end = dec16be(buffer, 3);
  573.                 readFully(in, buffer, 0, end);
  574.                 ptr = 0;
  575.                 if (type != expectedType) {
  576.                     if (type == ALERT) {
  577.                         /*
  578.                          * We just ignore alert
  579.                          * messages.
  580.                          */
  581.                         continue;
  582.                     }
  583.                     throw new IOException(
  584.                         "unexpected record type: "
  585.                         + type);
  586.                 }
  587.                 return;
  588.             }
  589.         }
  590.  
  591.         public int read()
  592.             throws IOException
  593.         {
  594.             while (ptr == end) {
  595.                 refill();
  596.             }
  597.             return buffer[ptr ++] & 0xFF;
  598.         }
  599.  
  600.         public int read(byte[] buf, int off, int len)
  601.             throws IOException
  602.         {
  603.             while (ptr == end) {
  604.                 refill();
  605.             }
  606.             int clen = Math.min(end - ptr, len);
  607.             System.arraycopy(buffer, ptr, buf, off, clen);
  608.             ptr += clen;
  609.             return clen;
  610.         }
  611.     }
  612.  
  613.     private static final SecureRandom RNG = new SecureRandom();
  614.  
  615.     /*
  616.      * Build a ClientHello message, with the specified maximum
  617.      * supported version, and list of cipher suites.
  618.      */
  619.     static byte[] makeClientHello(int version,
  620.         Collection<Integer> cipherSuites)
  621.     {
  622.         try {
  623.             return makeClientHello0(version, cipherSuites);
  624.         } catch (IOException ioe) {
  625.             throw new RuntimeException(ioe);
  626.         }
  627.     }
  628.  
  629.     static byte[] makeClientHello0(int version,
  630.         Collection<Integer> cipherSuites)
  631.         throws IOException
  632.     {
  633.         ByteArrayOutputStream b = new ByteArrayOutputStream();
  634.  
  635.         /*
  636.          * Message header:
  637.          *   message type: one byte (1 = "ClientHello")
  638.          *   message length: three bytes (this will be adjusted
  639.          *   at the end of this method).
  640.          */
  641.         b.write(1);
  642.         b.write(0);
  643.         b.write(0);
  644.         b.write(0);
  645.  
  646.         /*
  647.          * The maximum version that we intend to support.
  648.          */
  649.         b.write(version >>> 8);
  650.         b.write(version);
  651.  
  652.         /*
  653.          * The client random has length 32 bytes, but begins with
  654.          * the client's notion of the current time, over 32 bits
  655.          * (seconds since 1970/01/01 00:00:00 UTC, not counting
  656.          * leap seconds).
  657.          */
  658.         byte[] rand = new byte[32];
  659.         RNG.nextBytes(rand);
  660.         enc32be((int)(System.currentTimeMillis() / 1000), rand, 0);
  661.         b.write(rand);
  662.  
  663.         /*
  664.          * We send an empty session ID.
  665.          */
  666.         b.write(0);
  667.  
  668.         /*
  669.          * The list of cipher suites (list of 16-bit values; the
  670.          * list length in bytes is written first).
  671.          */
  672.         int num = cipherSuites.size();
  673.         byte[] cs = new byte[2 + num * 2];
  674.         enc16be(num * 2, cs, 0);
  675.         int j = 2;
  676.         for (int s : cipherSuites) {
  677.             enc16be(s, cs, j);
  678.             j += 2;
  679.         }
  680.         b.write(cs);
  681.  
  682.         /*
  683.          * Compression methods: we claim to support Deflate (1)
  684.          * and the standard no-compression (0), with Deflate
  685.          * being preferred.
  686.          */
  687.         b.write(2);
  688.         b.write(1);
  689.         b.write(0);
  690.  
  691.         /*
  692.          * If we had extensions to add, they would go here.
  693.          */
  694.  
  695.         /*
  696.          * We now get the message as a blob. The message length
  697.          * must be adjusted in the header.
  698.          */
  699.         byte[] msg = b.toByteArray();
  700.         enc24be(msg.length - 4, msg, 1);
  701.         return msg;
  702.     }
  703.  
  704.     /*
  705.      * Compute the SHA-1 hash of some bytes, returning the hash
  706.      * value in hexadecimal.
  707.      */
  708.     static String doSHA1(byte[] buf)
  709.     {
  710.         return doSHA1(buf, 0, buf.length);
  711.     }
  712.  
  713.     static String doSHA1(byte[] buf, int off, int len)
  714.     {
  715.         try {
  716.             MessageDigest md = MessageDigest.getInstance("SHA1");
  717.             md.update(buf, off, len);
  718.             byte[] hv = md.digest();
  719.             Formatter f = new Formatter();
  720.             for (byte b : hv) {
  721.                 f.format("%02x", b & 0xFF);
  722.             }
  723.             return f.toString();
  724.         } catch (NoSuchAlgorithmException nsae) {
  725.             throw new Error(nsae);
  726.         }
  727.     }
  728.  
  729.     /*
  730.      * This class decodes a ServerHello message from the server. The
  731.      * fields we are interested in are stored in the
  732.      * package-accessible fields.
  733.      */
  734.     static class ServerHello {
  735.  
  736.         int recordVersion;
  737.         int protoVersion;
  738.         long serverTime;
  739.         int cipherSuite;
  740.         int compression;
  741.         String serverCertName;
  742.         String serverCertHash;
  743.  
  744.         ServerHello(InputStream in)
  745.             throws IOException
  746.         {
  747.             InputRecord rec = new InputRecord(in);
  748.             rec.setExpectedType(HANDSHAKE);
  749.  
  750.             /*
  751.              * First, get the handshake message header (4 bytes).
  752.              * First byte should be 2 ("ServerHello"), then
  753.              * comes the message size (over 3 bytes).
  754.              */
  755.             byte[] buf = new byte[4];
  756.             readFully(rec, buf);
  757.             recordVersion = rec.getVersion();
  758.             if (buf[0] != 2) {
  759.                 throw new IOException("unexpected handshake"
  760.                     + " message type: " + (buf[0] & 0xFF));
  761.             }
  762.             buf = new byte[dec24be(buf, 1)];
  763.  
  764.             /*
  765.              * Read the complete message in RAM.
  766.              */
  767.             readFully(rec, buf);
  768.             int ptr = 0;
  769.  
  770.             /*
  771.              * The protocol version which we will use.
  772.              */
  773.             if (ptr + 2 > buf.length) {
  774.                 throw new IOException("invalid ServerHello");
  775.             }
  776.             protoVersion = dec16be(buf, 0);
  777.             ptr += 2;
  778.  
  779.             /*
  780.              * The server random begins with the server's notion
  781.              * of the current time.
  782.              */
  783.             if (ptr + 32 > buf.length) {
  784.                 throw new IOException("invalid ServerHello");
  785.             }
  786.             serverTime = 1000L * (dec32be(buf, ptr) & 0xFFFFFFFFL);
  787.             ptr += 32;
  788.  
  789.             /*
  790.              * We skip the session ID.
  791.              */
  792.             if (ptr + 1 > buf.length) {
  793.                 throw new IOException("invalid ServerHello");
  794.             }
  795.             ptr += 1 + (buf[ptr] & 0xFF);
  796.  
  797.             /*
  798.              * The cipher suite and compression follow.
  799.              */
  800.             if (ptr + 3 > buf.length) {
  801.                 throw new IOException("invalid ServerHello");
  802.             }
  803.             cipherSuite = dec16be(buf, ptr);
  804.             compression = buf[ptr + 2] & 0xFF;
  805.  
  806.             /*
  807.              * The ServerHello could include some extensions
  808.              * here, which we ignore.
  809.              */
  810.  
  811.             /*
  812.              * We now read a few extra messages, until we
  813.              * reach the server's Certificate message, or
  814.              * ServerHelloDone.
  815.              */
  816.             for (;;) {
  817.                 buf = new byte[4];
  818.                 readFully(rec, buf);
  819.                 int mt = buf[0] & 0xFF;
  820.                 buf = new byte[dec24be(buf, 1)];
  821.                 readFully(rec, buf);
  822.                 switch (mt) {
  823.                 case 11:
  824.                     processCertificate(buf);
  825.                     return;
  826.                 case 14:
  827.                     // ServerHelloDone
  828.                     return;
  829.                 }
  830.             }
  831.         }
  832.  
  833.         private void processCertificate(byte[] buf)
  834.         {
  835.             if (buf.length <= 6) {
  836.                 return;
  837.             }
  838.             int len1 = dec24be(buf, 0);
  839.             if (len1 != buf.length - 3) {
  840.                 return;
  841.             }
  842.             int len2 = dec24be(buf, 3);
  843.             if (len2 > buf.length - 6) {
  844.                 return;
  845.             }
  846.             byte[] ec = new byte[len2];
  847.             System.arraycopy(buf, 6, ec, 0, len2);
  848.             try {
  849.                 CertificateFactory cf =
  850.                     CertificateFactory.getInstance("X.509");
  851.                 X509Certificate xc =
  852.                     (X509Certificate)cf.generateCertificate(
  853.                         new ByteArrayInputStream(ec));
  854.                 serverCertName =
  855.                     xc.getSubjectX500Principal().toString();
  856.                 serverCertHash = doSHA1(ec);
  857.             } catch (CertificateException e) {
  858.                 // ignored
  859.                 return;
  860.             }
  861.         }
  862.     }
  863.  
  864.     /*
  865.      * A constant SSLv2 CLIENT-HELLO message. Only one connection
  866.      * is needed for SSLv2, since the server response will contain
  867.      * _all_ the cipher suites that the server is willing to
  868.      * support.
  869.      *
  870.      * Note: when (mis)interpreted as a SSLv3+ record, this message
  871.      * apparently encodes some data of (invalid) 0x80 type, using
  872.      * protocol version TLS 44.1, and record length of 2 bytes.
  873.      * Thus, the receiving part will quickly conclude that it will
  874.      * not support that, instead of stalling for more data from the
  875.      * client.
  876.      */
  877.     private static final byte[] SSL2_CLIENT_HELLO = {
  878.         (byte)0x80, (byte)0x2E,  // header (record length)
  879.         (byte)0x01,              // message type (CLIENT HELLO)
  880.         (byte)0x00, (byte)0x02,  // version (0x0002)
  881.         (byte)0x00, (byte)0x15,  // cipher specs list length
  882.         (byte)0x00, (byte)0x00,  // session ID length
  883.         (byte)0x00, (byte)0x10,  // challenge length
  884.         0x01, 0x00, (byte)0x80,  // SSL_CK_RC4_128_WITH_MD5
  885.         0x02, 0x00, (byte)0x80,  // SSL_CK_RC4_128_EXPORT40_WITH_MD5
  886.         0x03, 0x00, (byte)0x80,  // SSL_CK_RC2_128_CBC_WITH_MD5
  887.         0x04, 0x00, (byte)0x80,  // SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5
  888.         0x05, 0x00, (byte)0x80,  // SSL_CK_IDEA_128_CBC_WITH_MD5
  889.         0x06, 0x00, (byte)0x40,  // SSL_CK_DES_64_CBC_WITH_MD5
  890.         0x07, 0x00, (byte)0xC0,  // SSL_CK_DES_192_EDE3_CBC_WITH_MD5
  891.         0x54, 0x54, 0x54, 0x54,  // challenge data (16 bytes)
  892.         0x54, 0x54, 0x54, 0x54,
  893.         0x54, 0x54, 0x54, 0x54,
  894.         0x54, 0x54, 0x54, 0x54
  895.     };
  896.  
  897.     /*
  898.      * This class represents the response of a server which knows
  899.      $ SSLv2. It includes the list of cipher suites, and the
  900.      * identification of the server certificate.
  901.      */
  902.     static class ServerHelloSSLv2 {
  903.  
  904.         int[] cipherSuites;
  905.         String serverCertName;
  906.         String serverCertHash;
  907.  
  908.         ServerHelloSSLv2(InputStream in)
  909.             throws IOException
  910.         {
  911.             // Record length
  912.             byte[] buf = new byte[2];
  913.             readFully(in, buf);
  914.             int len = dec16be(buf, 0);
  915.             if ((len & 0x8000) == 0) {
  916.                 throw new IOException("not a SSLv2 record");
  917.             }
  918.             len &= 0x7FFF;
  919.             if (len < 11) {
  920.                 throw new IOException(
  921.                     "not a SSLv2 server hello");
  922.             }
  923.             buf = new byte[11];
  924.             readFully(in, buf);
  925.             if (buf[0] != 0x04) {
  926.                 throw new IOException(
  927.                     "not a SSLv2 server hello");
  928.             }
  929.             int certLen = dec16be(buf, 5);
  930.             int csLen = dec16be(buf, 7);
  931.             int connIdLen = dec16be(buf, 9);
  932.             if (len != 11 + certLen + csLen + connIdLen) {
  933.                 throw new IOException(
  934.                     "not a SSLv2 server hello");
  935.             }
  936.             if (csLen == 0 || csLen % 3 != 0) {
  937.                 throw new IOException(
  938.                     "not a SSLv2 server hello");
  939.             }
  940.             byte[] cert = new byte[certLen];
  941.             readFully(in, cert);
  942.             byte[] cs = new byte[csLen];
  943.             readFully(in, cs);
  944.             byte[] connId = new byte[connIdLen];
  945.             readFully(in, connId);
  946.             cipherSuites = new int[csLen / 3];
  947.             for (int i = 0, j = 0; i < csLen; i += 3, j ++) {
  948.                 cipherSuites[j] = dec24be(cs, i);
  949.             }
  950.             try {
  951.                 CertificateFactory cf =
  952.                     CertificateFactory.getInstance("X.509");
  953.                 X509Certificate xc =
  954.                     (X509Certificate)cf.generateCertificate(
  955.                         new ByteArrayInputStream(cert));
  956.                 serverCertName =
  957.                     xc.getSubjectX500Principal().toString();
  958.                 serverCertHash = doSHA1(cert);
  959.             } catch (CertificateException e) {
  960.                 // ignored
  961.             }
  962.         }
  963.     }
  964.  
  965.     static Map<Integer, CipherSuite> CIPHER_SUITES =
  966.         new TreeMap<Integer, CipherSuite>();
  967.  
  968.     static class CipherSuite {
  969.  
  970.         int suite;
  971.         String name;
  972.         boolean isCBC;
  973.         int strength;
  974.     }
  975.  
  976.     static final int CLEAR  = 0; // no encryption
  977.     static final int WEAK   = 1; // weak encryption: 40-bit key
  978.     static final int MEDIUM = 2; // medium encryption: 56-bit key
  979.     static final int STRONG = 3; // strong encryption
  980.  
  981.     static final String strengthString(int strength)
  982.     {
  983.         switch (strength) {
  984.         case CLEAR:  return "no encryption";
  985.         case WEAK:   return "weak encryption (40-bit)";
  986.         case MEDIUM: return "medium encryption (56-bit)";
  987.         case STRONG: return "strong encryption (96-bit or more)";
  988.         default:
  989.             throw new Error("strange strength: " + strength);
  990.         }
  991.     }
  992.  
  993.     static final String cipherSuiteString(int suite)
  994.     {
  995.         CipherSuite cs = CIPHER_SUITES.get(suite);
  996.         if (cs == null) {
  997.             return String.format("UNKNOWN_SUITE:0x%04X", cs);
  998.         } else {
  999.             return cs.name;
  1000.         }
  1001.     }
  1002.  
  1003.     static final String cipherSuiteStringV2(int suite)
  1004.     {
  1005.         CipherSuite cs = CIPHER_SUITES.get(suite);
  1006.         if (cs == null) {
  1007.             return String.format("UNKNOWN_SUITE:%02X,%02X,%02X",
  1008.                 suite >> 16, (suite >> 8) & 0xFF, suite & 0XFF);
  1009.         } else {
  1010.             return cs.name;
  1011.         }
  1012.     }
  1013.  
  1014.     private static final void makeCS(int suite, String name,
  1015.         boolean isCBC, int strength)
  1016.     {
  1017.         CipherSuite cs = new CipherSuite();
  1018.         cs.suite = suite;
  1019.         cs.name = name;
  1020.         cs.isCBC = isCBC;
  1021.         cs.strength = strength;
  1022.         CIPHER_SUITES.put(suite, cs);
  1023.  
  1024.         /*
  1025.          * Consistency test: the strength and CBC status can normally
  1026.          * be inferred from the name itself.
  1027.          */
  1028.         boolean inferredCBC = name.contains("_CBC_");
  1029.         int inferredStrength;
  1030.         if (name.contains("_NULL_")) {
  1031.             inferredStrength = CLEAR;
  1032.         } else if (name.contains("DES40") || name.contains("_40_")
  1033.             || name.contains("EXPORT40"))
  1034.         {
  1035.             inferredStrength = WEAK;
  1036.         } else if ((name.contains("_DES_") || name.contains("DES_64"))
  1037.             && !name.contains("DES_192"))
  1038.         {
  1039.             inferredStrength = MEDIUM;
  1040.         } else {
  1041.             inferredStrength = STRONG;
  1042.         }
  1043.         if (inferredStrength != strength || inferredCBC != isCBC) {
  1044.             throw new RuntimeException(
  1045.                 "wrong classification: " + name);
  1046.         }
  1047.     }
  1048.  
  1049.     private static final void N(int suite, String name)
  1050.     {
  1051.         makeCS(suite, name, false, CLEAR);
  1052.     }
  1053.  
  1054.     private static final void S4(int suite, String name)
  1055.     {
  1056.         makeCS(suite, name, false, WEAK);
  1057.     }
  1058.  
  1059.     private static final void S8(int suite, String name)
  1060.     {
  1061.         makeCS(suite, name, false, STRONG);
  1062.     }
  1063.  
  1064.     private static final void B4(int suite, String name)
  1065.     {
  1066.         makeCS(suite, name, true, WEAK);
  1067.     }
  1068.  
  1069.     private static final void B5(int suite, String name)
  1070.     {
  1071.         makeCS(suite, name, true, MEDIUM);
  1072.     }
  1073.  
  1074.     private static final void B8(int suite, String name)
  1075.     {
  1076.         makeCS(suite, name, true, STRONG);
  1077.     }
  1078.  
  1079.     static {
  1080.         /*
  1081.          * SSLv2 cipher suites.
  1082.          */
  1083.         S8(0x010080, "RC4_128_WITH_MD5"               );
  1084.         S4(0x020080, "RC4_128_EXPORT40_WITH_MD5"      );
  1085.         B8(0x030080, "RC2_128_CBC_WITH_MD5"           );
  1086.         B4(0x040080, "RC2_128_CBC_EXPORT40_WITH_MD5"  );
  1087.         B8(0x050080, "IDEA_128_CBC_WITH_MD5"          );
  1088.         B5(0x060040, "DES_64_CBC_WITH_MD5"            );
  1089.         B8(0x0700C0, "DES_192_EDE3_CBC_WITH_MD5"      );
  1090.  
  1091.         /*
  1092.          * Original suites (SSLv3, TLS 1.0).
  1093.          */
  1094.         N(0x0000, "NULL_WITH_NULL_NULL"                );
  1095.         N(0x0001, "RSA_WITH_NULL_MD5"                  );
  1096.         N(0x0002, "RSA_WITH_NULL_SHA"                  );
  1097.         S4(0x0003, "RSA_EXPORT_WITH_RC4_40_MD5"        );
  1098.         S8(0x0004, "RSA_WITH_RC4_128_MD5"              );
  1099.         S8(0x0005, "RSA_WITH_RC4_128_SHA"              );
  1100.         B4(0x0006, "RSA_EXPORT_WITH_RC2_CBC_40_MD5"    );
  1101.         B8(0x0007, "RSA_WITH_IDEA_CBC_SHA"             );
  1102.         B4(0x0008, "RSA_EXPORT_WITH_DES40_CBC_SHA"     );
  1103.         B5(0x0009, "RSA_WITH_DES_CBC_SHA"              );
  1104.         B8(0x000A, "RSA_WITH_3DES_EDE_CBC_SHA"         );
  1105.         B4(0x000B, "DH_DSS_EXPORT_WITH_DES40_CBC_SHA"  );
  1106.         B5(0x000C, "DH_DSS_WITH_DES_CBC_SHA"           );
  1107.         B8(0x000D, "DH_DSS_WITH_3DES_EDE_CBC_SHA"      );
  1108.         B4(0x000E, "DH_RSA_EXPORT_WITH_DES40_CBC_SHA"  );
  1109.         B5(0x000F, "DH_RSA_WITH_DES_CBC_SHA"           );
  1110.         B8(0x0010, "DH_RSA_WITH_3DES_EDE_CBC_SHA"      );
  1111.         B4(0x0011, "DHE_DSS_EXPORT_WITH_DES40_CBC_SHA" );
  1112.         B5(0x0012, "DHE_DSS_WITH_DES_CBC_SHA"          );
  1113.         B8(0x0013, "DHE_DSS_WITH_3DES_EDE_CBC_SHA"     );
  1114.         B4(0x0014, "DHE_RSA_EXPORT_WITH_DES40_CBC_SHA" );
  1115.         B5(0x0015, "DHE_RSA_WITH_DES_CBC_SHA"          );
  1116.         B8(0x0016, "DHE_RSA_WITH_3DES_EDE_CBC_SHA"     );
  1117.         S4(0x0017, "DH_anon_EXPORT_WITH_RC4_40_MD5"    );
  1118.         S8(0x0018, "DH_anon_WITH_RC4_128_MD5"          );
  1119.         B4(0x0019, "DH_anon_EXPORT_WITH_DES40_CBC_SHA" );
  1120.         B5(0x001A, "DH_anon_WITH_DES_CBC_SHA"          );
  1121.         B8(0x001B, "DH_anon_WITH_3DES_EDE_CBC_SHA"     );
  1122.  
  1123.         /*
  1124.          * FORTEZZA suites (SSLv3 only; see RFC 6101).
  1125.          */
  1126.         N(0x001C, "FORTEZZA_KEA_WITH_NULL_SHA"          );
  1127.         B8(0x001D, "FORTEZZA_KEA_WITH_FORTEZZA_CBC_SHA" );
  1128.  
  1129.         /* This one is deactivated since it conflicts with
  1130.            one of the Kerberos cipher suites.
  1131.         S8(0x001E, "FORTEZZA_KEA_WITH_RC4_128_SHA"      );
  1132.         */
  1133.  
  1134.         /*
  1135.          * Kerberos cipher suites (RFC 2712).
  1136.          */
  1137.         B5(0x001E, "KRB5_WITH_DES_CBC_SHA"             );
  1138.         B8(0x001F, "KRB5_WITH_3DES_EDE_CBC_SHA"        );
  1139.         S8(0x0020, "KRB5_WITH_RC4_128_SHA"             );
  1140.         B8(0x0021, "KRB5_WITH_IDEA_CBC_SHA"            );
  1141.         B5(0x0022, "KRB5_WITH_DES_CBC_MD5"             );
  1142.         B8(0x0023, "KRB5_WITH_3DES_EDE_CBC_MD5"        );
  1143.         S8(0x0024, "KRB5_WITH_RC4_128_MD5"             );
  1144.         B8(0x0025, "KRB5_WITH_IDEA_CBC_MD5"            );
  1145.         B4(0x0026, "KRB5_EXPORT_WITH_DES_CBC_40_SHA"   );
  1146.         B4(0x0027, "KRB5_EXPORT_WITH_RC2_CBC_40_SHA"   );
  1147.         S4(0x0028, "KRB5_EXPORT_WITH_RC4_40_SHA"       );
  1148.         B4(0x0029, "KRB5_EXPORT_WITH_DES_CBC_40_MD5"   );
  1149.         B4(0x002A, "KRB5_EXPORT_WITH_RC2_CBC_40_MD5"   );
  1150.         S4(0x002B, "KRB5_EXPORT_WITH_RC4_40_MD5"       );
  1151.  
  1152.         /*
  1153.          * Pre-shared key, no encryption cipher suites (RFC 4785).
  1154.          */
  1155.         N(0x002C, "PSK_WITH_NULL_SHA"                  );
  1156.         N(0x002D, "DHE_PSK_WITH_NULL_SHA"              );
  1157.         N(0x002E, "RSA_PSK_WITH_NULL_SHA"              );
  1158.  
  1159.         /*
  1160.          * AES-based suites (TLS 1.1).
  1161.          */
  1162.         B8(0x002F, "RSA_WITH_AES_128_CBC_SHA"          );
  1163.         B8(0x0030, "DH_DSS_WITH_AES_128_CBC_SHA"       );
  1164.         B8(0x0031, "DH_RSA_WITH_AES_128_CBC_SHA"       );
  1165.         B8(0x0032, "DHE_DSS_WITH_AES_128_CBC_SHA"      );
  1166.         B8(0x0033, "DHE_RSA_WITH_AES_128_CBC_SHA"      );
  1167.         B8(0x0034, "DH_anon_WITH_AES_128_CBC_SHA"      );
  1168.         B8(0x0035, "RSA_WITH_AES_256_CBC_SHA"          );
  1169.         B8(0x0036, "DH_DSS_WITH_AES_256_CBC_SHA"       );
  1170.         B8(0x0037, "DH_RSA_WITH_AES_256_CBC_SHA"       );
  1171.         B8(0x0038, "DHE_DSS_WITH_AES_256_CBC_SHA"      );
  1172.         B8(0x0039, "DHE_RSA_WITH_AES_256_CBC_SHA"      );
  1173.         B8(0x003A, "DH_anon_WITH_AES_256_CBC_SHA"      );
  1174.  
  1175.         /*
  1176.          * Suites with SHA-256 (TLS 1.2).
  1177.          */
  1178.         N(0x003B, "RSA_WITH_NULL_SHA256"               );
  1179.         B8(0x003C, "RSA_WITH_AES_128_CBC_SHA256"       );
  1180.         B8(0x003D, "RSA_WITH_AES_256_CBC_SHA256"       );
  1181.         B8(0x003E, "DH_DSS_WITH_AES_128_CBC_SHA256"    );
  1182.         B8(0x003F, "DH_RSA_WITH_AES_128_CBC_SHA256"    );
  1183.         B8(0x0040, "DHE_DSS_WITH_AES_128_CBC_SHA256"   );
  1184.         B8(0x0067, "DHE_RSA_WITH_AES_128_CBC_SHA256"   );
  1185.         B8(0x0068, "DH_DSS_WITH_AES_256_CBC_SHA256"    );
  1186.         B8(0x0069, "DH_RSA_WITH_AES_256_CBC_SHA256"    );
  1187.         B8(0x006A, "DHE_DSS_WITH_AES_256_CBC_SHA256"   );
  1188.         B8(0x006B, "DHE_RSA_WITH_AES_256_CBC_SHA256"   );
  1189.         B8(0x006C, "DH_anon_WITH_AES_128_CBC_SHA256"   );
  1190.         B8(0x006D, "DH_anon_WITH_AES_256_CBC_SHA256"   );
  1191.  
  1192.         /*
  1193.          * Camellia cipher suites (RFC 5932).
  1194.          */
  1195.         B8(0x0041, "RSA_WITH_CAMELLIA_128_CBC_SHA"     );
  1196.         B8(0x0042, "DH_DSS_WITH_CAMELLIA_128_CBC_SHA"  );
  1197.         B8(0x0043, "DH_RSA_WITH_CAMELLIA_128_CBC_SHA"  );
  1198.         B8(0x0044, "DHE_DSS_WITH_CAMELLIA_128_CBC_SHA" );
  1199.         B8(0x0045, "DHE_RSA_WITH_CAMELLIA_128_CBC_SHA" );
  1200.         B8(0x0046, "DH_anon_WITH_CAMELLIA_128_CBC_SHA" );
  1201.         B8(0x0084, "RSA_WITH_CAMELLIA_256_CBC_SHA"     );
  1202.         B8(0x0085, "DH_DSS_WITH_CAMELLIA_256_CBC_SHA"  );
  1203.         B8(0x0086, "DH_RSA_WITH_CAMELLIA_256_CBC_SHA"  );
  1204.         B8(0x0087, "DHE_DSS_WITH_CAMELLIA_256_CBC_SHA" );
  1205.         B8(0x0088, "DHE_RSA_WITH_CAMELLIA_256_CBC_SHA" );
  1206.         B8(0x0089, "DH_anon_WITH_CAMELLIA_256_CBC_SHA" );
  1207.  
  1208.         /*
  1209.          * Unsorted (yet), from the IANA TLS registry:
  1210.          * http://www.iana.org/assignments/tls-parameters/
  1211.          */
  1212.         S8(0x008A, "TLS_PSK_WITH_RC4_128_SHA"                        );
  1213.         B8(0x008B, "TLS_PSK_WITH_3DES_EDE_CBC_SHA"                   );
  1214.         B8(0x008C, "TLS_PSK_WITH_AES_128_CBC_SHA"                    );
  1215.         B8(0x008D, "TLS_PSK_WITH_AES_256_CBC_SHA"                    );
  1216.         S8(0x008E, "TLS_DHE_PSK_WITH_RC4_128_SHA"                    );
  1217.         B8(0x008F, "TLS_DHE_PSK_WITH_3DES_EDE_CBC_SHA"               );
  1218.         B8(0x0090, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA"                );
  1219.         B8(0x0091, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA"                );
  1220.         S8(0x0092, "TLS_RSA_PSK_WITH_RC4_128_SHA"                    );
  1221.         B8(0x0093, "TLS_RSA_PSK_WITH_3DES_EDE_CBC_SHA"               );
  1222.         B8(0x0094, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA"                );
  1223.         B8(0x0095, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA"                );
  1224.         B8(0x0096, "TLS_RSA_WITH_SEED_CBC_SHA"                       );
  1225.         B8(0x0097, "TLS_DH_DSS_WITH_SEED_CBC_SHA"                    );
  1226.         B8(0x0098, "TLS_DH_RSA_WITH_SEED_CBC_SHA"                    );
  1227.         B8(0x0099, "TLS_DHE_DSS_WITH_SEED_CBC_SHA"                   );
  1228.         B8(0x009A, "TLS_DHE_RSA_WITH_SEED_CBC_SHA"                   );
  1229.         B8(0x009B, "TLS_DH_anon_WITH_SEED_CBC_SHA"                   );
  1230.         S8(0x009C, "TLS_RSA_WITH_AES_128_GCM_SHA256"                 );
  1231.         S8(0x009D, "TLS_RSA_WITH_AES_256_GCM_SHA384"                 );
  1232.         S8(0x009E, "TLS_DHE_RSA_WITH_AES_128_GCM_SHA256"             );
  1233.         S8(0x009F, "TLS_DHE_RSA_WITH_AES_256_GCM_SHA384"             );
  1234.         S8(0x00A0, "TLS_DH_RSA_WITH_AES_128_GCM_SHA256"              );
  1235.         S8(0x00A1, "TLS_DH_RSA_WITH_AES_256_GCM_SHA384"              );
  1236.         S8(0x00A2, "TLS_DHE_DSS_WITH_AES_128_GCM_SHA256"             );
  1237.         S8(0x00A3, "TLS_DHE_DSS_WITH_AES_256_GCM_SHA384"             );
  1238.         S8(0x00A4, "TLS_DH_DSS_WITH_AES_128_GCM_SHA256"              );
  1239.         S8(0x00A5, "TLS_DH_DSS_WITH_AES_256_GCM_SHA384"              );
  1240.         S8(0x00A6, "TLS_DH_anon_WITH_AES_128_GCM_SHA256"             );
  1241.         S8(0x00A7, "TLS_DH_anon_WITH_AES_256_GCM_SHA384"             );
  1242.         S8(0x00A8, "TLS_PSK_WITH_AES_128_GCM_SHA256"                 );
  1243.         S8(0x00A9, "TLS_PSK_WITH_AES_256_GCM_SHA384"                 );
  1244.         S8(0x00AA, "TLS_DHE_PSK_WITH_AES_128_GCM_SHA256"             );
  1245.         S8(0x00AB, "TLS_DHE_PSK_WITH_AES_256_GCM_SHA384"             );
  1246.         S8(0x00AC, "TLS_RSA_PSK_WITH_AES_128_GCM_SHA256"             );
  1247.         S8(0x00AD, "TLS_RSA_PSK_WITH_AES_256_GCM_SHA384"             );
  1248.         B8(0x00AE, "TLS_PSK_WITH_AES_128_CBC_SHA256"                 );
  1249.         B8(0x00AF, "TLS_PSK_WITH_AES_256_CBC_SHA384"                 );
  1250.         N(0x00B0, "TLS_PSK_WITH_NULL_SHA256"                         );
  1251.         N(0x00B1, "TLS_PSK_WITH_NULL_SHA384"                         );
  1252.         B8(0x00B2, "TLS_DHE_PSK_WITH_AES_128_CBC_SHA256"             );
  1253.         B8(0x00B3, "TLS_DHE_PSK_WITH_AES_256_CBC_SHA384"             );
  1254.         N(0x00B4, "TLS_DHE_PSK_WITH_NULL_SHA256"                     );
  1255.         N(0x00B5, "TLS_DHE_PSK_WITH_NULL_SHA384"                     );
  1256.         B8(0x00B6, "TLS_RSA_PSK_WITH_AES_128_CBC_SHA256"             );
  1257.         B8(0x00B7, "TLS_RSA_PSK_WITH_AES_256_CBC_SHA384"             );
  1258.         N(0x00B8, "TLS_RSA_PSK_WITH_NULL_SHA256"                     );
  1259.         N(0x00B9, "TLS_RSA_PSK_WITH_NULL_SHA384"                     );
  1260.         B8(0x00BA, "TLS_RSA_WITH_CAMELLIA_128_CBC_SHA256"            );
  1261.         B8(0x00BB, "TLS_DH_DSS_WITH_CAMELLIA_128_CBC_SHA256"         );
  1262.         B8(0x00BC, "TLS_DH_RSA_WITH_CAMELLIA_128_CBC_SHA256"         );
  1263.         B8(0x00BD, "TLS_DHE_DSS_WITH_CAMELLIA_128_CBC_SHA256"        );
  1264.         B8(0x00BE, "TLS_DHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"        );
  1265.         B8(0x00BF, "TLS_DH_anon_WITH_CAMELLIA_128_CBC_SHA256"        );
  1266.         B8(0x00C0, "TLS_RSA_WITH_CAMELLIA_256_CBC_SHA256"            );
  1267.         B8(0x00C1, "TLS_DH_DSS_WITH_CAMELLIA_256_CBC_SHA256"         );
  1268.         B8(0x00C2, "TLS_DH_RSA_WITH_CAMELLIA_256_CBC_SHA256"         );
  1269.         B8(0x00C3, "TLS_DHE_DSS_WITH_CAMELLIA_256_CBC_SHA256"        );
  1270.         B8(0x00C4, "TLS_DHE_RSA_WITH_CAMELLIA_256_CBC_SHA256"        );
  1271.         B8(0x00C5, "TLS_DH_anon_WITH_CAMELLIA_256_CBC_SHA256"        );
  1272.         /* This one is a fake cipher suite which marks a
  1273.            renegotiation.
  1274.         N(0x00FF, "TLS_EMPTY_RENEGOTIATION_INFO_SCSV"                );
  1275.         */
  1276.         N(0xC001, "TLS_ECDH_ECDSA_WITH_NULL_SHA"                     );
  1277.         S8(0xC002, "TLS_ECDH_ECDSA_WITH_RC4_128_SHA"                 );
  1278.         B8(0xC003, "TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA"            );
  1279.         B8(0xC004, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA"             );
  1280.         B8(0xC005, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA"             );
  1281.         N(0xC006, "TLS_ECDHE_ECDSA_WITH_NULL_SHA"                    );
  1282.         S8(0xC007, "TLS_ECDHE_ECDSA_WITH_RC4_128_SHA"                );
  1283.         B8(0xC008, "TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA"           );
  1284.         B8(0xC009, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA"            );
  1285.         B8(0xC00A, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA"            );
  1286.         N(0xC00B, "TLS_ECDH_RSA_WITH_NULL_SHA"                       );
  1287.         S8(0xC00C, "TLS_ECDH_RSA_WITH_RC4_128_SHA"                   );
  1288.         B8(0xC00D, "TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA"              );
  1289.         B8(0xC00E, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA"               );
  1290.         B8(0xC00F, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA"               );
  1291.         N(0xC010, "TLS_ECDHE_RSA_WITH_NULL_SHA"                      );
  1292.         S8(0xC011, "TLS_ECDHE_RSA_WITH_RC4_128_SHA"                  );
  1293.         B8(0xC012, "TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA"             );
  1294.         B8(0xC013, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA"              );
  1295.         B8(0xC014, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA"              );
  1296.         N(0xC015, "TLS_ECDH_anon_WITH_NULL_SHA"                     );
  1297.         S8(0xC016, "TLS_ECDH_anon_WITH_RC4_128_SHA"                  );
  1298.         B8(0xC017, "TLS_ECDH_anon_WITH_3DES_EDE_CBC_SHA"             );
  1299.         B8(0xC018, "TLS_ECDH_anon_WITH_AES_128_CBC_SHA"              );
  1300.         B8(0xC019, "TLS_ECDH_anon_WITH_AES_256_CBC_SHA"              );
  1301.         B8(0xC01A, "TLS_SRP_SHA_WITH_3DES_EDE_CBC_SHA"               );
  1302.         B8(0xC01B, "TLS_SRP_SHA_RSA_WITH_3DES_EDE_CBC_SHA"           );
  1303.         B8(0xC01C, "TLS_SRP_SHA_DSS_WITH_3DES_EDE_CBC_SHA"           );
  1304.         B8(0xC01D, "TLS_SRP_SHA_WITH_AES_128_CBC_SHA"                );
  1305.         B8(0xC01E, "TLS_SRP_SHA_RSA_WITH_AES_128_CBC_SHA"            );
  1306.         B8(0xC01F, "TLS_SRP_SHA_DSS_WITH_AES_128_CBC_SHA"            );
  1307.         B8(0xC020, "TLS_SRP_SHA_WITH_AES_256_CBC_SHA"                );
  1308.         B8(0xC021, "TLS_SRP_SHA_RSA_WITH_AES_256_CBC_SHA"            );
  1309.         B8(0xC022, "TLS_SRP_SHA_DSS_WITH_AES_256_CBC_SHA"            );
  1310.         B8(0xC023, "TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256"         );
  1311.         B8(0xC024, "TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA384"         );
  1312.         B8(0xC025, "TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA256"          );
  1313.         B8(0xC026, "TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA384"          );
  1314.         B8(0xC027, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"           );
  1315.         B8(0xC028, "TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384"           );
  1316.         B8(0xC029, "TLS_ECDH_RSA_WITH_AES_128_CBC_SHA256"            );
  1317.         B8(0xC02A, "TLS_ECDH_RSA_WITH_AES_256_CBC_SHA384"            );
  1318.         S8(0xC02B, "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256"         );
  1319.         S8(0xC02C, "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"         );
  1320.         S8(0xC02D, "TLS_ECDH_ECDSA_WITH_AES_128_GCM_SHA256"          );
  1321.         S8(0xC02E, "TLS_ECDH_ECDSA_WITH_AES_256_GCM_SHA384"          );
  1322.         S8(0xC02F, "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"           );
  1323.         S8(0xC030, "TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384"           );
  1324.         S8(0xC031, "TLS_ECDH_RSA_WITH_AES_128_GCM_SHA256"            );
  1325.         S8(0xC032, "TLS_ECDH_RSA_WITH_AES_256_GCM_SHA384"            );
  1326.         S8(0xC033, "TLS_ECDHE_PSK_WITH_RC4_128_SHA"                  );
  1327.         B8(0xC034, "TLS_ECDHE_PSK_WITH_3DES_EDE_CBC_SHA"             );
  1328.         B8(0xC035, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA"              );
  1329.         B8(0xC036, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA"              );
  1330.         B8(0xC037, "TLS_ECDHE_PSK_WITH_AES_128_CBC_SHA256"           );
  1331.         B8(0xC038, "TLS_ECDHE_PSK_WITH_AES_256_CBC_SHA384"           );
  1332.         N(0xC039, "TLS_ECDHE_PSK_WITH_NULL_SHA"                      );
  1333.         N(0xC03A, "TLS_ECDHE_PSK_WITH_NULL_SHA256"                   );
  1334.         N(0xC03B, "TLS_ECDHE_PSK_WITH_NULL_SHA384"                   );
  1335.         B8(0xC03C, "TLS_RSA_WITH_ARIA_128_CBC_SHA256"                );
  1336.         B8(0xC03D, "TLS_RSA_WITH_ARIA_256_CBC_SHA384"                );
  1337.         B8(0xC03E, "TLS_DH_DSS_WITH_ARIA_128_CBC_SHA256"             );
  1338.         B8(0xC03F, "TLS_DH_DSS_WITH_ARIA_256_CBC_SHA384"             );
  1339.         B8(0xC040, "TLS_DH_RSA_WITH_ARIA_128_CBC_SHA256"             );
  1340.         B8(0xC041, "TLS_DH_RSA_WITH_ARIA_256_CBC_SHA384"             );
  1341.         B8(0xC042, "TLS_DHE_DSS_WITH_ARIA_128_CBC_SHA256"            );
  1342.         B8(0xC043, "TLS_DHE_DSS_WITH_ARIA_256_CBC_SHA384"            );
  1343.         B8(0xC044, "TLS_DHE_RSA_WITH_ARIA_128_CBC_SHA256"            );
  1344.         B8(0xC045, "TLS_DHE_RSA_WITH_ARIA_256_CBC_SHA384"            );
  1345.         B8(0xC046, "TLS_DH_anon_WITH_ARIA_128_CBC_SHA256"            );
  1346.         B8(0xC047, "TLS_DH_anon_WITH_ARIA_256_CBC_SHA384"            );
  1347.         B8(0xC048, "TLS_ECDHE_ECDSA_WITH_ARIA_128_CBC_SHA256"        );
  1348.         B8(0xC049, "TLS_ECDHE_ECDSA_WITH_ARIA_256_CBC_SHA384"        );
  1349.         B8(0xC04A, "TLS_ECDH_ECDSA_WITH_ARIA_128_CBC_SHA256"         );
  1350.         B8(0xC04B, "TLS_ECDH_ECDSA_WITH_ARIA_256_CBC_SHA384"         );
  1351.         B8(0xC04C, "TLS_ECDHE_RSA_WITH_ARIA_128_CBC_SHA256"          );
  1352.         B8(0xC04D, "TLS_ECDHE_RSA_WITH_ARIA_256_CBC_SHA384"          );
  1353.         B8(0xC04E, "TLS_ECDH_RSA_WITH_ARIA_128_CBC_SHA256"           );
  1354.         B8(0xC04F, "TLS_ECDH_RSA_WITH_ARIA_256_CBC_SHA384"           );
  1355.         S8(0xC050, "TLS_RSA_WITH_ARIA_128_GCM_SHA256"                );
  1356.         S8(0xC051, "TLS_RSA_WITH_ARIA_256_GCM_SHA384"                );
  1357.         S8(0xC052, "TLS_DHE_RSA_WITH_ARIA_128_GCM_SHA256"            );
  1358.         S8(0xC053, "TLS_DHE_RSA_WITH_ARIA_256_GCM_SHA384"            );
  1359.         S8(0xC054, "TLS_DH_RSA_WITH_ARIA_128_GCM_SHA256"             );
  1360.         S8(0xC055, "TLS_DH_RSA_WITH_ARIA_256_GCM_SHA384"             );
  1361.         S8(0xC056, "TLS_DHE_DSS_WITH_ARIA_128_GCM_SHA256"            );
  1362.         S8(0xC057, "TLS_DHE_DSS_WITH_ARIA_256_GCM_SHA384"            );
  1363.         S8(0xC058, "TLS_DH_DSS_WITH_ARIA_128_GCM_SHA256"             );
  1364.         S8(0xC059, "TLS_DH_DSS_WITH_ARIA_256_GCM_SHA384"             );
  1365.         S8(0xC05A, "TLS_DH_anon_WITH_ARIA_128_GCM_SHA256"            );
  1366.         S8(0xC05B, "TLS_DH_anon_WITH_ARIA_256_GCM_SHA384"            );
  1367.         S8(0xC05C, "TLS_ECDHE_ECDSA_WITH_ARIA_128_GCM_SHA256"        );
  1368.         S8(0xC05D, "TLS_ECDHE_ECDSA_WITH_ARIA_256_GCM_SHA384"        );
  1369.         S8(0xC05E, "TLS_ECDH_ECDSA_WITH_ARIA_128_GCM_SHA256"         );
  1370.         S8(0xC05F, "TLS_ECDH_ECDSA_WITH_ARIA_256_GCM_SHA384"         );
  1371.         S8(0xC060, "TLS_ECDHE_RSA_WITH_ARIA_128_GCM_SHA256"          );
  1372.         S8(0xC061, "TLS_ECDHE_RSA_WITH_ARIA_256_GCM_SHA384"          );
  1373.         S8(0xC062, "TLS_ECDH_RSA_WITH_ARIA_128_GCM_SHA256"           );
  1374.         S8(0xC063, "TLS_ECDH_RSA_WITH_ARIA_256_GCM_SHA384"           );
  1375.         B8(0xC064, "TLS_PSK_WITH_ARIA_128_CBC_SHA256"                );
  1376.         B8(0xC065, "TLS_PSK_WITH_ARIA_256_CBC_SHA384"                );
  1377.         B8(0xC066, "TLS_DHE_PSK_WITH_ARIA_128_CBC_SHA256"            );
  1378.         B8(0xC067, "TLS_DHE_PSK_WITH_ARIA_256_CBC_SHA384"            );
  1379.         B8(0xC068, "TLS_RSA_PSK_WITH_ARIA_128_CBC_SHA256"            );
  1380.         B8(0xC069, "TLS_RSA_PSK_WITH_ARIA_256_CBC_SHA384"            );
  1381.         S8(0xC06A, "TLS_PSK_WITH_ARIA_128_GCM_SHA256"                );
  1382.         S8(0xC06B, "TLS_PSK_WITH_ARIA_256_GCM_SHA384"                );
  1383.         S8(0xC06C, "TLS_DHE_PSK_WITH_ARIA_128_GCM_SHA256"            );
  1384.         S8(0xC06D, "TLS_DHE_PSK_WITH_ARIA_256_GCM_SHA384"            );
  1385.         S8(0xC06E, "TLS_RSA_PSK_WITH_ARIA_128_GCM_SHA256"            );
  1386.         S8(0xC06F, "TLS_RSA_PSK_WITH_ARIA_256_GCM_SHA384"            );
  1387.         B8(0xC070, "TLS_ECDHE_PSK_WITH_ARIA_128_CBC_SHA256"          );
  1388.         B8(0xC071, "TLS_ECDHE_PSK_WITH_ARIA_256_CBC_SHA384"          );
  1389.         B8(0xC072, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"    );
  1390.         B8(0xC073, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"    );
  1391.         B8(0xC074, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_CBC_SHA256"     );
  1392.         B8(0xC075, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_CBC_SHA384"     );
  1393.         B8(0xC076, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_CBC_SHA256"      );
  1394.         B8(0xC077, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_CBC_SHA384"      );
  1395.         B8(0xC078, "TLS_ECDH_RSA_WITH_CAMELLIA_128_CBC_SHA256"       );
  1396.         B8(0xC079, "TLS_ECDH_RSA_WITH_CAMELLIA_256_CBC_SHA384"       );
  1397.         S8(0xC07A, "TLS_RSA_WITH_CAMELLIA_128_GCM_SHA256"            );
  1398.         S8(0xC07B, "TLS_RSA_WITH_CAMELLIA_256_GCM_SHA384"            );
  1399.         S8(0xC07C, "TLS_DHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"        );
  1400.         S8(0xC07D, "TLS_DHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"        );
  1401.         S8(0xC07E, "TLS_DH_RSA_WITH_CAMELLIA_128_GCM_SHA256"         );
  1402.         S8(0xC07F, "TLS_DH_RSA_WITH_CAMELLIA_256_GCM_SHA384"         );
  1403.         S8(0xC080, "TLS_DHE_DSS_WITH_CAMELLIA_128_GCM_SHA256"        );
  1404.         S8(0xC081, "TLS_DHE_DSS_WITH_CAMELLIA_256_GCM_SHA384"        );
  1405.         S8(0xC082, "TLS_DH_DSS_WITH_CAMELLIA_128_GCM_SHA256"         );
  1406.         S8(0xC083, "TLS_DH_DSS_WITH_CAMELLIA_256_GCM_SHA384"         );
  1407.         S8(0xC084, "TLS_DH_anon_WITH_CAMELLIA_128_GCM_SHA256"        );
  1408.         S8(0xC085, "TLS_DH_anon_WITH_CAMELLIA_256_GCM_SHA384"        );
  1409.         S8(0xC086, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"    );
  1410.         S8(0xC087, "TLS_ECDHE_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"    );
  1411.         S8(0xC088, "TLS_ECDH_ECDSA_WITH_CAMELLIA_128_GCM_SHA256"     );
  1412.         S8(0xC089, "TLS_ECDH_ECDSA_WITH_CAMELLIA_256_GCM_SHA384"     );
  1413.         S8(0xC08A, "TLS_ECDHE_RSA_WITH_CAMELLIA_128_GCM_SHA256"      );
  1414.         S8(0xC08B, "TLS_ECDHE_RSA_WITH_CAMELLIA_256_GCM_SHA384"      );
  1415.         S8(0xC08C, "TLS_ECDH_RSA_WITH_CAMELLIA_128_GCM_SHA256"       );
  1416.         S8(0xC08D, "TLS_ECDH_RSA_WITH_CAMELLIA_256_GCM_SHA384"       );
  1417.         S8(0xC08E, "TLS_PSK_WITH_CAMELLIA_128_GCM_SHA256"            );
  1418.         S8(0xC08F, "TLS_PSK_WITH_CAMELLIA_256_GCM_SHA384"            );
  1419.         S8(0xC090, "TLS_DHE_PSK_WITH_CAMELLIA_128_GCM_SHA256"        );
  1420.         S8(0xC091, "TLS_DHE_PSK_WITH_CAMELLIA_256_GCM_SHA384"        );
  1421.         S8(0xC092, "TLS_RSA_PSK_WITH_CAMELLIA_128_GCM_SHA256"        );
  1422.         S8(0xC093, "TLS_RSA_PSK_WITH_CAMELLIA_256_GCM_SHA384"        );
  1423.         B8(0xC094, "TLS_PSK_WITH_CAMELLIA_128_CBC_SHA256"            );
  1424.         B8(0xC095, "TLS_PSK_WITH_CAMELLIA_256_CBC_SHA384"            );
  1425.         B8(0xC096, "TLS_DHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"        );
  1426.         B8(0xC097, "TLS_DHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"        );
  1427.         B8(0xC098, "TLS_RSA_PSK_WITH_CAMELLIA_128_CBC_SHA256"        );
  1428.         B8(0xC099, "TLS_RSA_PSK_WITH_CAMELLIA_256_CBC_SHA384"        );
  1429.         B8(0xC09A, "TLS_ECDHE_PSK_WITH_CAMELLIA_128_CBC_SHA256"      );
  1430.         B8(0xC09B, "TLS_ECDHE_PSK_WITH_CAMELLIA_256_CBC_SHA384"      );
  1431.         S8(0xC09C, "TLS_RSA_WITH_AES_128_CCM"                        );
  1432.         S8(0xC09D, "TLS_RSA_WITH_AES_256_CCM"                        );
  1433.         S8(0xC09E, "TLS_DHE_RSA_WITH_AES_128_CCM"                    );
  1434.         S8(0xC09F, "TLS_DHE_RSA_WITH_AES_256_CCM"                    );
  1435.         S8(0xC0A0, "TLS_RSA_WITH_AES_128_CCM_8"                      );
  1436.         S8(0xC0A1, "TLS_RSA_WITH_AES_256_CCM_8"                      );
  1437.         S8(0xC0A2, "TLS_DHE_RSA_WITH_AES_128_CCM_8"                  );
  1438.         S8(0xC0A3, "TLS_DHE_RSA_WITH_AES_256_CCM_8"                  );
  1439.         S8(0xC0A4, "TLS_PSK_WITH_AES_128_CCM"                        );
  1440.         S8(0xC0A5, "TLS_PSK_WITH_AES_256_CCM"                        );
  1441.         S8(0xC0A6, "TLS_DHE_PSK_WITH_AES_128_CCM"                    );
  1442.         S8(0xC0A7, "TLS_DHE_PSK_WITH_AES_256_CCM"                    );
  1443.         S8(0xC0A8, "TLS_PSK_WITH_AES_128_CCM_8"                      );
  1444.         S8(0xC0A9, "TLS_PSK_WITH_AES_256_CCM_8"                      );
  1445.         S8(0xC0AA, "TLS_PSK_DHE_WITH_AES_128_CCM_8"                  );
  1446.         S8(0xC0AB, "TLS_PSK_DHE_WITH_AES_256_CCM_8"                  );
  1447.     }
  1448. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement