Skip to content

crypto/tls: no support for SSLv2 handshake #3930

@gopherbot

Description

@gopherbot

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:

  1. tls_echo.go (1002 bytes)
  2. 0001-Allow-SSLv2-compatible-client-hello-so-SSLv2-compati.patch (5479 bytes)

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions