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.
- * ----------------------------------------------------------------------
- */
- import java.io.ByteArrayInputStream;
- import java.io.ByteArrayOutputStream;
- import java.io.EOFException;
- import java.io.InputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.net.InetSocketAddress;
- import java.net.Socket;
- import java.security.MessageDigest;
- import java.security.NoSuchAlgorithmException;
- import java.security.SecureRandom;
- import java.security.cert.CertificateException;
- import java.security.cert.CertificateFactory;
- import java.security.cert.X509Certificate;
- import java.util.ArrayList;
- import java.util.Collection;
- import java.util.Formatter;
- import java.util.List;
- import java.util.Map;
- import java.util.Set;
- import java.util.TreeMap;
- import java.util.TreeSet;
- public class TestSSLServer {
- static void usage()
- {
- System.err.println("usage: TestSSLServer servername [ port ]");
- System.exit(1);
- }
- public static void main(String[] args)
- throws IOException
- {
- if (args.length == 0 || args.length > 2) {
- usage();
- }
- String name = args[0];
- int port = 443;
- if (args.length == 2) {
- try {
- port = Integer.parseInt(args[1]);
- } catch (NumberFormatException nfe) {
- usage();
- }
- if (port <= 0 || port > 65535) {
- usage();
- }
- }
- InetSocketAddress isa = new InetSocketAddress(name, port);
- Set<Integer> sv = new TreeSet<Integer>();
- boolean compress = false;
- for (int v = 0x0300; v <= 0x0303; v ++) {
- ServerHello sh = connect(isa,
- v, CIPHER_SUITES.keySet());
- if (sh == null) {
- continue;
- }
- sv.add(sh.protoVersion);
- if (sh.compression == 1) {
- compress = true;
- }
- }
- ServerHelloSSLv2 sh2 = connectV2(isa);
- if (sh2 != null) {
- sv.add(0x0200);
- }
- if (sv.size() == 0) {
- System.out.println("No SSL/TLS server at " + isa);
- System.exit(1);
- }
- System.out.print("Supported versions:");
- for (int v : sv) {
- System.out.print(" ");
- System.out.print(versionString(v));
- }
- System.out.println();
- System.out.println("Deflate compression: "
- + (compress ? "YES" : "no"));
- System.out.println("Supported cipher suites"
- + " (ORDER IS NOT SIGNIFICANT):");
- Set<Integer> lastSuppCS = null;
- Map<Integer, Set<Integer>> suppCS =
- new TreeMap<Integer, Set<Integer>>();
- Set<String> certID = new TreeSet<String>();
- if (sh2 != null) {
- System.out.println(" " + versionString(0x0200));
- Set<Integer> vc2 = new TreeSet<Integer>();
- for (int c : sh2.cipherSuites) {
- vc2.add(c);
- }
- for (int c : vc2) {
- System.out.println(" "
- + cipherSuiteStringV2(c));
- }
- suppCS.put(0x0200, vc2);
- if (sh2.serverCertName != null) {
- certID.add(sh2.serverCertHash
- + ": " + sh2.serverCertName);
- }
- }
- for (int v : sv) {
- if (v == 0x0200) {
- continue;
- }
- Set<Integer> vsc = supportedSuites(isa, v, certID);
- suppCS.put(v, vsc);
- if (lastSuppCS == null || !lastSuppCS.equals(vsc)) {
- System.out.println(" " + versionString(v));
- for (int c : vsc) {
- System.out.println(" "
- + cipherSuiteString(c));
- }
- lastSuppCS = vsc;
- } else {
- System.out.println(" (" + versionString(v)
- + ": idem)");
- }
- }
- System.out.println("----------------------");
- if (certID.size() == 0) {
- System.out.println("No server certificate !");
- } else {
- System.out.println("Server certificate(s):");
- for (String cc : certID) {
- System.out.println(" " + cc);
- }
- }
- System.out.println("----------------------");
- int agMaxStrength = STRONG;
- int agMinStrength = STRONG;
- boolean vulnBEAST = false;
- for (int v : sv) {
- Set<Integer> vsc = suppCS.get(v);
- agMaxStrength = Math.min(
- maxStrength(vsc), agMaxStrength);
- agMinStrength = Math.min(
- minStrength(vsc), agMinStrength);
- if (!vulnBEAST) {
- vulnBEAST = testBEAST(isa, v, vsc);
- }
- }
- System.out.println("Minimal encryption strength: "
- + strengthString(agMinStrength));
- System.out.println("Achievable encryption strength: "
- + strengthString(agMaxStrength));
- System.out.println("BEAST status: "
- + (vulnBEAST ? "vulnerable" : "protected"));
- System.out.println("CRIME status: "
- + (compress ? "vulnerable" : "protected"));
- }
- /*
- * 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 Set<Integer> supportedSuites(InetSocketAddress isa, int version,
- Set<String> serverCertID)
- {
- Set<Integer> cs = new TreeSet<Integer>(CIPHER_SUITES.keySet());
- Set<Integer> rs = new TreeSet<Integer>();
- for (;;) {
- ServerHello sh = connect(isa, version, cs);
- if (sh == null) {
- break;
- }
- if (!cs.contains(sh.cipherSuite)) {
- System.err.printf("[ERR: server wants to use"
- + " cipher suite 0x%04X which client"
- + " did not announce]", sh.cipherSuite);
- System.err.println();
- break;
- }
- cs.remove(sh.cipherSuite);
- rs.add(sh.cipherSuite);
- if (sh.serverCertName != null) {
- serverCertID.add(sh.serverCertHash
- + ": " + sh.serverCertName);
- }
- }
- return rs;
- }
- static int minStrength(Set<Integer> supp)
- {
- int m = STRONG;
- for (int suite : supp) {
- CipherSuite cs = CIPHER_SUITES.get(suite);
- if (cs == null) {
- continue;
- }
- if (cs.strength < m) {
- m = cs.strength;
- }
- }
- return m;
- }
- static int maxStrength(Set<Integer> supp)
- {
- int m = CLEAR;
- for (int suite : supp) {
- CipherSuite cs = CIPHER_SUITES.get(suite);
- if (cs == null) {
- continue;
- }
- if (cs.strength > m) {
- m = cs.strength;
- }
- }
- return m;
- }
- static boolean testBEAST(InetSocketAddress isa,
- int version, Set<Integer> 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.
- */
- List<Integer> strongCBC = new ArrayList<Integer>();
- List<Integer> strongStream = new ArrayList<Integer>();
- for (int suite : supp) {
- CipherSuite cs = CIPHER_SUITES.get(suite);
- if (cs == null) {
- continue;
- }
- if (cs.strength < STRONG) {
- continue;
- }
- if (cs.isCBC) {
- strongCBC.add(suite);
- } else {
- strongStream.add(suite);
- }
- }
- if (strongCBC.size() == 0) {
- return false;
- }
- if (strongStream.size() == 0) {
- return true;
- }
- List<Integer> ns = new ArrayList<Integer>(strongCBC);
- ns.addAll(strongStream);
- ServerHello sh = connect(isa, version, ns);
- return !strongStream.contains(sh.cipherSuite);
- }
- static String versionString(int version)
- {
- if (version == 0x0200) {
- return "SSLv2";
- } else if (version == 0x0300) {
- return "SSLv3";
- } else if ((version >>> 8) == 0x03) {
- return "TLSv1." + ((version & 0xFF) - 1);
- } else {
- return String.format("UNKNOWN_VERSION:0x%04X", version);
- }
- }
- /*
- * Connect to the server, send a ClientHello, and decode the
- * response (ServerHello). On error, null is returned.
- */
- static ServerHello connect(InetSocketAddress isa,
- int version, Collection<Integer> cipherSuites)
- {
- Socket s = null;
- try {
- s = new Socket();
- try {
- s.connect(isa);
- } catch (IOException ioe) {
- System.err.println("could not connect to "
- + isa + ": " + ioe.toString());
- return null;
- }
- byte[] ch = makeClientHello(version, cipherSuites);
- OutputRecord orec = new OutputRecord(
- s.getOutputStream());
- orec.setType(HANDSHAKE);
- orec.setVersion(version);
- orec.write(ch);
- orec.flush();
- return new ServerHello(s.getInputStream());
- } catch (IOException ioe) {
- // ignored
- } finally {
- try {
- s.close();
- } catch (IOException ioe) {
- // 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(InetSocketAddress isa)
- {
- Socket s = null;
- try {
- s = new Socket();
- try {
- s.connect(isa);
- } catch (IOException ioe) {
- System.err.println("could not connect to "
- + isa + ": " + ioe.toString());
- return null;
- }
- s.getOutputStream().write(SSL2_CLIENT_HELLO);
- return new ServerHelloSSLv2(s.getInputStream());
- } catch (IOException ioe) {
- // ignored
- } finally {
- try {
- s.close();
- } catch (IOException ioe) {
- // ignored
- }
- }
- return null;
- }
- static final void enc16be(int val, byte[] buf, int off)
- {
- buf[off] = (byte)(val >>> 8);
- buf[off + 1] = (byte)val;
- }
- static final void enc24be(int val, byte[] buf, int off)
- {
- buf[off] = (byte)(val >>> 16);
- buf[off + 1] = (byte)(val >>> 8);
- buf[off + 2] = (byte)val;
- }
- static final 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;
- }
- static final int dec16be(byte[] buf, int off)
- {
- return ((buf[off] & 0xFF) << 8)
- | (buf[off + 1] & 0xFF);
- }
- static final int dec24be(byte[] buf, int off)
- {
- return ((buf[off] & 0xFF) << 16)
- | ((buf[off + 1] & 0xFF) << 8)
- | (buf[off + 2] & 0xFF);
- }
- static final int dec32be(byte[] buf, int off)
- {
- return ((buf[off] & 0xFF) << 24)
- | ((buf[off + 1] & 0xFF) << 16)
- | ((buf[off + 2] & 0xFF) << 8)
- | (buf[off + 3] & 0xFF);
- }
- static final int CHANGE_CIPHER_SPEC = 20;
- static final int ALERT = 21;
- static final int HANDSHAKE = 22;
- static final int APPLICATION = 23;
- static final int MAX_RECORD_LEN = 16384;
- /*
- * A custom stream which encodes data bytes into SSL/TLS records
- * (no encryption).
- */
- static class OutputRecord extends OutputStream {
- private OutputStream out;
- private byte[] buffer = new byte[MAX_RECORD_LEN + 5];
- private int ptr;
- private int version;
- private int type;
- OutputRecord(OutputStream out)
- {
- this.out = out;
- ptr = 5;
- }
- void setType(int type)
- {
- this.type = type;
- }
- void setVersion(int version)
- {
- this.version = version;
- }
- public void flush()
- throws IOException
- {
- buffer[0] = (byte)type;
- enc16be(version, buffer, 1);
- enc16be(ptr - 5, buffer, 3);
- out.write(buffer, 0, ptr);
- out.flush();
- ptr = 5;
- }
- public void write(int b)
- throws IOException
- {
- buffer[ptr ++] = (byte)b;
- if (ptr == buffer.length) {
- flush();
- }
- }
- public void write(byte[] buf, int off, int len)
- throws IOException
- {
- while (len > 0) {
- int clen = Math.min(buffer.length - ptr, len);
- System.arraycopy(buf, off, buffer, ptr, clen);
- ptr += clen;
- off += clen;
- len -= clen;
- if (ptr == buffer.length) {
- flush();
- }
- }
- }
- }
- static void readFully(InputStream in, byte[] buf)
- throws IOException
- {
- readFully(in, buf, 0, buf.length);
- }
- static void readFully(InputStream in, byte[] buf, int off, int len)
- throws IOException
- {
- while (len > 0) {
- int rlen = in.read(buf, off, len);
- if (rlen < 0) {
- throw new EOFException();
- }
- off += rlen;
- len -= rlen;
- }
- }
- /*
- * A custom stream which expects SSL/TLS records (no encryption)
- * and rebuilds the encoded data stream. Incoming records MUST
- * have the expected type (e.g. "handshake"); alert messages
- * are skipped.
- */
- static class InputRecord extends InputStream {
- private InputStream in;
- private byte[] buffer = new byte[MAX_RECORD_LEN + 5];
- private int ptr, end;
- private int version;
- private int type;
- private int expectedType;
- InputRecord(InputStream in)
- {
- this.in = in;
- ptr = 0;
- end = 0;
- }
- void setExpectedType(int expectedType)
- {
- this.expectedType = expectedType;
- }
- int getVersion()
- {
- return version;
- }
- private void refill()
- throws IOException
- {
- for (;;) {
- readFully(in, buffer, 0, 5);
- type = buffer[0] & 0xFF;
- version = dec16be(buffer, 1);
- end = dec16be(buffer, 3);
- readFully(in, buffer, 0, end);
- ptr = 0;
- if (type != expectedType) {
- if (type == ALERT) {
- /*
- * We just ignore alert
- * messages.
- */
- continue;
- }
- throw new IOException(
- "unexpected record type: "
- + type);
- }
- return;
- }
- }
- public int read()
- throws IOException
- {
- while (ptr == end) {
- refill();
- }
- return buffer[ptr ++] & 0xFF;
- }
- public int read(byte[] buf, int off, int len)
- throws IOException
- {
- while (ptr == end) {
- refill();
- }
- int clen = Math.min(end - ptr, len);
- System.arraycopy(buffer, ptr, buf, off, clen);
- ptr += clen;
- return clen;
- }
- }
- private static final SecureRandom RNG = new SecureRandom();
- /*
- * Build a ClientHello message, with the specified maximum
- * supported version, and list of cipher suites.
- */
- static byte[] makeClientHello(int version,
- Collection<Integer> cipherSuites)
- {
- try {
- return makeClientHello0(version, cipherSuites);
- } catch (IOException ioe) {
- throw new RuntimeException(ioe);
- }
- }
- static byte[] makeClientHello0(int version,
- Collection<Integer> cipherSuites)
- throws IOException
- {
- ByteArrayOutputStream b = new ByteArrayOutputStream();
- /*
- * Message header:
- * message type: one byte (1 = "ClientHello")
- * message length: three bytes (this will be adjusted
- * at the end of this method).
- */
- b.write(1);
- b.write(0);
- b.write(0);
- b.write(0);
- /*
- * The maximum version that we intend to support.
- */
- b.write(version >>> 8);
- b.write(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.nextBytes(rand);
- enc32be((int)(System.currentTimeMillis() / 1000), rand, 0);
- b.write(rand);
- /*
- * We send an empty session ID.
- */
- b.write(0);
- /*
- * The list of cipher suites (list of 16-bit values; the
- * list length in bytes is written first).
- */
- int num = cipherSuites.size();
- byte[] cs = new byte[2 + num * 2];
- enc16be(num * 2, cs, 0);
- int j = 2;
- for (int s : cipherSuites) {
- enc16be(s, cs, j);
- j += 2;
- }
- b.write(cs);
- /*
- * Compression methods: we claim to support Deflate (1)
- * and the standard no-compression (0), with Deflate
- * being preferred.
- */
- b.write(2);
- b.write(1);
- b.write(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.toByteArray();
- enc24be(msg.length - 4, msg, 1);
- return msg;
- }
- /*
- * Compute the SHA-1 hash of some bytes, returning the hash
- * value in hexadecimal.
- */
- static String doSHA1(byte[] buf)
- {
- return doSHA1(buf, 0, buf.length);
- }
- static String doSHA1(byte[] buf, int off, int len)
- {
- try {
- MessageDigest md = MessageDigest.getInstance("SHA1");
- md.update(buf, off, len);
- byte[] hv = md.digest();
- Formatter f = new Formatter();
- for (byte b : hv) {
- f.format("%02x", b & 0xFF);
- }
- return f.toString();
- } catch (NoSuchAlgorithmException nsae) {
- throw new Error(nsae);
- }
- }
- /*
- * This class decodes a ServerHello message from the server. The
- * fields we are interested in are stored in the
- * package-accessible fields.
- */
- static class ServerHello {
- int recordVersion;
- int protoVersion;
- long serverTime;
- int cipherSuite;
- int compression;
- String serverCertName;
- String serverCertHash;
- ServerHello(InputStream in)
- throws IOException
- {
- InputRecord rec = new InputRecord(in);
- rec.setExpectedType(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];
- readFully(rec, buf);
- recordVersion = rec.getVersion();
- if (buf[0] != 2) {
- throw new IOException("unexpected handshake"
- + " message type: " + (buf[0] & 0xFF));
- }
- buf = new byte[dec24be(buf, 1)];
- /*
- * Read the complete message in RAM.
- */
- readFully(rec, buf);
- int ptr = 0;
- /*
- * The protocol version which we will use.
- */
- if (ptr + 2 > buf.length) {
- throw new IOException("invalid ServerHello");
- }
- protoVersion = 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 * (dec32be(buf, ptr) & 0xFFFFFFFFL);
- ptr += 32;
- /*
- * We skip the session ID.
- */
- if (ptr + 1 > buf.length) {
- throw new IOException("invalid ServerHello");
- }
- ptr += 1 + (buf[ptr] & 0xFF);
- /*
- * The cipher suite and compression follow.
- */
- if (ptr + 3 > buf.length) {
- throw new IOException("invalid ServerHello");
- }
- cipherSuite = dec16be(buf, ptr);
- compression = buf[ptr + 2] & 0xFF;
- /*
- * 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];
- readFully(rec, buf);
- int mt = buf[0] & 0xFF;
- buf = new byte[dec24be(buf, 1)];
- 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 = dec24be(buf, 0);
- if (len1 != buf.length - 3) {
- return;
- }
- int len2 = dec24be(buf, 3);
- if (len2 > buf.length - 6) {
- return;
- }
- byte[] ec = new byte[len2];
- System.arraycopy(buf, 6, ec, 0, len2);
- try {
- CertificateFactory cf =
- CertificateFactory.getInstance("X.509");
- X509Certificate xc =
- (X509Certificate)cf.generateCertificate(
- new ByteArrayInputStream(ec));
- serverCertName =
- xc.getSubjectX500Principal().toString();
- serverCertHash = doSHA1(ec);
- } catch (CertificateException e) {
- // ignored
- return;
- }
- }
- }
- /*
- * 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.
- */
- private static final byte[] SSL2_CLIENT_HELLO = {
- (byte)0x80, (byte)0x2E, // header (record length)
- (byte)0x01, // message type (CLIENT HELLO)
- (byte)0x00, (byte)0x02, // version (0x0002)
- (byte)0x00, (byte)0x15, // cipher specs list length
- (byte)0x00, (byte)0x00, // session ID length
- (byte)0x00, (byte)0x10, // challenge length
- 0x01, 0x00, (byte)0x80, // SSL_CK_RC4_128_WITH_MD5
- 0x02, 0x00, (byte)0x80, // SSL_CK_RC4_128_EXPORT40_WITH_MD5
- 0x03, 0x00, (byte)0x80, // SSL_CK_RC2_128_CBC_WITH_MD5
- 0x04, 0x00, (byte)0x80, // SSL_CK_RC2_128_CBC_EXPORT40_WITH_MD5
- 0x05, 0x00, (byte)0x80, // SSL_CK_IDEA_128_CBC_WITH_MD5
- 0x06, 0x00, (byte)0x40, // SSL_CK_DES_64_CBC_WITH_MD5
- 0x07, 0x00, (byte)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
- };
- /*
- * 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.
- */
- static class ServerHelloSSLv2 {
- int[] cipherSuites;
- String serverCertName;
- String serverCertHash;
- ServerHelloSSLv2(InputStream in)
- throws IOException
- {
- // Record length
- byte[] buf = new byte[2];
- readFully(in, buf);
- int len = 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];
- readFully(in, buf);
- if (buf[0] != 0x04) {
- throw new IOException(
- "not a SSLv2 server hello");
- }
- int certLen = dec16be(buf, 5);
- int csLen = dec16be(buf, 7);
- int connIdLen = 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];
- readFully(in, cert);
- byte[] cs = new byte[csLen];
- readFully(in, cs);
- byte[] connId = new byte[connIdLen];
- readFully(in, connId);
- cipherSuites = new int[csLen / 3];
- for (int i = 0, j = 0; i < csLen; i += 3, j ++) {
- cipherSuites[j] = dec24be(cs, i);
- }
- try {
- CertificateFactory cf =
- CertificateFactory.getInstance("X.509");
- X509Certificate xc =
- (X509Certificate)cf.generateCertificate(
- new ByteArrayInputStream(cert));
- serverCertName =
- xc.getSubjectX500Principal().toString();
- serverCertHash = doSHA1(cert);
- } catch (CertificateException e) {
- // ignored
- }
- }
- }
- static Map<Integer, CipherSuite> CIPHER_SUITES =
- new TreeMap<Integer, CipherSuite>();
- static class CipherSuite {
- int suite;
- String name;
- boolean isCBC;
- int strength;
- }
- static final int CLEAR = 0; // no encryption
- static final int WEAK = 1; // weak encryption: 40-bit key
- static final int MEDIUM = 2; // medium encryption: 56-bit key
- static final int STRONG = 3; // strong encryption
- static final 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 Error("strange strength: " + strength);
- }
- }
- static final String cipherSuiteString(int suite)
- {
- CipherSuite cs = CIPHER_SUITES.get(suite);
- if (cs == null) {
- return String.format("UNKNOWN_SUITE:0x%04X", cs);
- } else {
- return cs.name;
- }
- }
- static final String cipherSuiteStringV2(int suite)
- {
- CipherSuite cs = CIPHER_SUITES.get(suite);
- if (cs == null) {
- return String.format("UNKNOWN_SUITE:%02X,%02X,%02X",
- suite >> 16, (suite >> 8) & 0xFF, suite & 0XFF);
- } else {
- return cs.name;
- }
- }
- private static final void makeCS(int suite, String name,
- boolean isCBC, int strength)
- {
- CipherSuite cs = new CipherSuite();
- cs.suite = suite;
- cs.name = name;
- cs.isCBC = isCBC;
- cs.strength = strength;
- CIPHER_SUITES.put(suite, cs);
- /*
- * Consistency test: the strength and CBC status can normally
- * be inferred from the name itself.
- */
- boolean 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 RuntimeException(
- "wrong classification: " + name);
- }
- }
- private static final void N(int suite, String name)
- {
- makeCS(suite, name, false, CLEAR);
- }
- private static final void S4(int suite, String name)
- {
- makeCS(suite, name, false, WEAK);
- }
- private static final void S8(int suite, String name)
- {
- makeCS(suite, name, false, STRONG);
- }
- private static final void B4(int suite, String name)
- {
- makeCS(suite, name, true, WEAK);
- }
- private static final void B5(int suite, String name)
- {
- makeCS(suite, name, true, MEDIUM);
- }
- private static final void B8(int suite, String name)
- {
- makeCS(suite, name, true, STRONG);
- }
- static {
- /*
- * 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" );
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement