From 1f98b97756b324159ff071cec31e92f6fc629133 Mon Sep 17 00:00:00 2001 From: Guus der Kinderen Date: Fri, 10 Nov 2017 19:47:07 +0100 Subject: [PATCH] Allow SSLv2 CLIENT-HELLO (without SSL 2.0) The existing TLS probe is documented to ignore SSL 2.0, citing RFC 6176 as a reason. RFC 6176 does prohibit the usage of SSL 2.0, but does allow for ClientHello messages in the version 2 CLIENT-HELLO format (as long as those are used to negotiate the use of a higher protocol). This commit extends the TLS probe, by making it accept SSL v2 ClientHello messages that negotiate a version of SSL/TLS 1.0 or higher (which is the same version range as the original code). --- probe.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/probe.c b/probe.c index 9b4a63e..8e12d53 100644 --- a/probe.c +++ b/probe.c @@ -236,14 +236,30 @@ static int is_sni_alpn_protocol(const char *p, int len, struct proto *proto) static int is_tls_protocol(const char *p, int len, struct proto *proto) { - if (len < 3) + if (len < 6) return PROBE_AGAIN; - /* TLS packet starts with a record "Hello" (0x16), followed by version - * (0x03 0x00-0x03) (RFC6101 A.1) - * This means we reject SSLv2 and lower, which is actually a good thing (RFC6176) + /* TLS packet starts with a record "Hello" (0x16), followed by the number of + * the highest version of SSL/TLS supported. + * + * A SSLv2 record header contains a two or three byte length code. If the + * most significant bit is set in the first byte of the record length code + * then the record has no padding and the total header length will be 2 + * bytes, otherwise the record has padding and the total header length will + * be 3 bytes. Next, a 1 char sized client-hello (0x01) is expected, + * followed by a 2 char sized version that indicates the highest version of + * TLS/SSL supported by the sender. [SSL2] Hickman, Kipp, "The SSL Protocol" + * + * We're checking the highest version of TLS/SSL supported against + * (0x03 0x00-0x03) (RFC6101 A.1). This means we reject the usage of SSLv2 + * and lower, which is actually a good thing (RFC6176). */ - return p[0] == 0x16 && p[1] == 0x03 && ( p[2] >= 0 && p[2] <= 0x03); + if (p[0] == 0x16) // TLS client-hello + return p[1] == 0x03 && ( p[2] >= 0 && p[2] <= 0x03); + if ((p[0] & 0x80) != 0) // SSLv2 client-hello, no padding + return p[2] == 0x01 && p[3] == 0x03 && ( p[4] >= 0 && p[4] <= 0x03); + else // SSLv2 client-hello, padded + return p[3] == 0x01 && p[4] == 0x03 && ( p[5] >= 0 && p[5] <= 0x03); } static int is_adb_protocol(const char *p, int len, struct proto *proto)