Greetings,

The Tor project has uncovered an issue with the new support for TLS 1.1 
and 1.2 in OpenSSL 1.0.1. It is reproducible with the s_client utility. 
There does not appear to be any obvious security impact, but it does 
represent a failure to interoperate.

The bug relates to the implementation of renegotiation (both client- and 
server-initiated). If an OpenSSL client has negotiated the use of TLS >= 
1.1, when he sends the renegotiating Client Hello it carries the wrong 
version number on the handshake record. It always has TLS 1.0 instead of 
the actual negotiated version current on the connection.

This behavior would appear to be in conflict with RFC 5246 which states 
in section 7.4.1. Hello Messages: "The current connection state is used 
for renegotiation messages."

When the problem occurs, this error is generated on both the client and 
the server:
> error:1408F10B:SSL routines:SSL3_GET_RECORD:wrong version number:s3_pkt.c:340

Attached is a pcap of the problem occurring with s_client and s_server 
and a patch that seems to fix it. As the record version field is sent in 
the clear, decryption of the pcap isn't necessary to see the problem.

In response to failed connection attempts, the short-term workaround 
being deployed by the Tor project is simply to disable the use of TLS 
1.1 and 1.2. In order for this protocol support to be un-disabled there 
will likely need be a positive indication of the fix available at 
compile time. As there are some widely used Linux distros that are fond 
of backporting patches without incrementing the version number, ideally 
they could get a preprocessor definition to indicate TLS > 1.0 was safe 
to use with renegotiation.

Let me know if I can provide any additional info.

Thanks,

- Marsh

For reference, the Tor trac ticket:
https://trac.torproject.org/projects/tor/ticket/6033

Attachment: openssl-1.0.1c-client-initiated-renego.pcap
Description: application/vnd.tcpdump.pcap

diff -u openssl-1.0.1c/ssl/s3_pkt.c openssl-1.0.1c-patch/ssl/s3_pkt.c
--- openssl-1.0.1c/ssl/s3_pkt.c	2012-04-17 08:20:19.000000000 -0500
+++ openssl-1.0.1c-patch/ssl/s3_pkt.c	2012-06-03 00:37:53.656411137 -0500
@@ -740,10 +740,11 @@
 	wr->type=type;
 
 	*(p++)=(s->version>>8);
-	/* Some servers hang if iniatial client hello is larger than 256
+	/* Some servers hang if initial client hello is larger than 256
 	 * bytes and record version number > TLS 1.0
 	 */
 	if (s->state == SSL3_ST_CW_CLNT_HELLO_B
+				&& !SSL_renegotiate_pending(s)
 				&& TLS1_get_version(s) > TLS1_VERSION)
 		*(p++) = 0x1;
 	else
diff -u openssl-1.0.1c/ssl/ssl.h openssl-1.0.1c-patch/ssl/ssl.h
--- openssl-1.0.1c/ssl/ssl.h	2012-04-25 18:08:44.000000000 -0500
+++ openssl-1.0.1c-patch/ssl/ssl.h	2012-06-03 01:07:22.456505267 -0500
@@ -221,6 +221,9 @@
 #define SSL_MAX_KEY_ARG_LENGTH			8
 #define SSL_MAX_MASTER_KEY_LENGTH		48
 
+/* Early TLS 1.1 and 1.2 support in OpenSSL didn't allow renegotiation.
+ * This definition indicates at compile time that renegotiation support
+ * support is available in these protocol versions. */
+#define SSL_TLSV1_1_AND_V1_2_CAN_RENEGOTIATE 1
 
 /* These are used to specify which ciphers to use and not to use */
 

Reply via email to