by ian.ragsdale:
To reproduce, run the attached TLS echo server and try to connect using the openssl
s_client utility:
> openssl s_client -quiet -connect localhost:50000
95052:error:140773F2:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert unexpected
message:/SourceCache/OpenSSL098/OpenSSL098-47/src/ssl/s23_clnt.c:602:
> openssl s_client -quiet -connect localhost:50000 -ssl3
depth=0
/CN=relay.cloudsmtp.com/O=Datran/OU=CapThought/ST=Texas/C=US/L=Austin/emailAddress=ian.ragsdale@gmail.com
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0
/CN=relay.cloudsmtp.com/O=Datran/OU=CapThought/ST=Texas/C=US/L=Austin/emailAddress=ian.ragsdale@gmail.com
verify error:num=21:unable to verify the first certificate
verify return:1
hi
>> hi
Note that the s_client is unable to connect with its default settings, but can connect
by specifying a version.
This is because TLS-capable clients that also support connecting to SSLv2 servers start
off by sending a SSLv2 formatted CLIENT-HELLO packet instead of a TLS ClientHello. The
crypto/tls package does not recognize these packets and so terminates the handshake,
making it impossible to use these clients. However, these ARE compliant TLS clients, and
they set the TLS version correctly in the CLIENT-HELLO packet in order to signify that
they support TLS. This makes it possible for the crypto/tls code to read these packets,
recognize TLS compliance, and send back a TLS-compliant ServerHello packet, at which
point the entire rest of the conversation is exactly like any other TLS session.
So, in order to support these clients, the only thing that needs to be done is to
recognize a SSLv2 compliant packet correctly and begin a standard TLS conversation.
Since it seemed fairly simple to do so, I've attached a fairly simple patch to allow
communicating with these clients. I'm sure it's unacceptable in its current form, but
it functions for me and illustrates the changes that are needed to support this
functionality.
I completely understand (and agree with) the aversion to supporting older versions of
SSL, but this is actually TLS behavior documented in at least the 1.0 and 1.1 RFCs, and
is a fairly minor change, which should greatly improve interop. Lots of common clients
(recent versions of Java and Ruby at least) do this by default. I can easily configure
my own clients to not do this, but it isn't easy for a lot of people.
Attachments:
- tls_echo.go (1002 bytes)
- 0001-Allow-SSLv2-compatible-client-hello-so-SSLv2-compati.patch (5479 bytes)
by ian.ragsdale:
To reproduce, run the attached TLS echo server and try to connect using the openssl s_client utility: > openssl s_client -quiet -connect localhost:50000 95052:error:140773F2:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert unexpected message:/SourceCache/OpenSSL098/OpenSSL098-47/src/ssl/s23_clnt.c:602: > openssl s_client -quiet -connect localhost:50000 -ssl3 depth=0 /CN=relay.cloudsmtp.com/O=Datran/OU=CapThought/ST=Texas/C=US/L=Austin/emailAddress=ian.ragsdale@gmail.com verify error:num=20:unable to get local issuer certificate verify return:1 depth=0 /CN=relay.cloudsmtp.com/O=Datran/OU=CapThought/ST=Texas/C=US/L=Austin/emailAddress=ian.ragsdale@gmail.com verify error:num=21:unable to verify the first certificate verify return:1 hi >> hi Note that the s_client is unable to connect with its default settings, but can connect by specifying a version. This is because TLS-capable clients that also support connecting to SSLv2 servers start off by sending a SSLv2 formatted CLIENT-HELLO packet instead of a TLS ClientHello. The crypto/tls package does not recognize these packets and so terminates the handshake, making it impossible to use these clients. However, these ARE compliant TLS clients, and they set the TLS version correctly in the CLIENT-HELLO packet in order to signify that they support TLS. This makes it possible for the crypto/tls code to read these packets, recognize TLS compliance, and send back a TLS-compliant ServerHello packet, at which point the entire rest of the conversation is exactly like any other TLS session. So, in order to support these clients, the only thing that needs to be done is to recognize a SSLv2 compliant packet correctly and begin a standard TLS conversation. Since it seemed fairly simple to do so, I've attached a fairly simple patch to allow communicating with these clients. I'm sure it's unacceptable in its current form, but it functions for me and illustrates the changes that are needed to support this functionality. I completely understand (and agree with) the aversion to supporting older versions of SSL, but this is actually TLS behavior documented in at least the 1.0 and 1.1 RFCs, and is a fairly minor change, which should greatly improve interop. Lots of common clients (recent versions of Java and Ruby at least) do this by default. I can easily configure my own clients to not do this, but it isn't easy for a lot of people.Attachments: