libcurl with OpenSSLUnknown SSL protocol error in connection - (no Server Hello) - why?

10,030

I did more testing and debugging, and found that there are a couple of sites that consistently failed with either default or TLSv1 using Curl (curl.exe -k -v --tlsv1 , or no --tlsv1), but ok with SSLv3. I am pretty the version is not the problem, as IE connect using TLSv1 and openSSL is ok using TLSv1 also. But I ran out of time so SSLv3 will be used as workaround.

The real problem can be the cipher list being sent out in Client Hello. After specifying a cipher that would for sure work, SSL is ok:

curl.exe -k -v <site>                     # failed
curl.exe -k -v --ciphers RC4-MD5 <site>   # now will connect

If you have similar problem, this article has been very useful for me troubleshooting "SSL Unknown SSL protocol error" issue:

http://blog.techstacks.com/2010/03/3-common-causes-of-unknown-ssl-protocol-errors-with-curl.html

Share:
10,030
M W
Author by

M W

Updated on June 04, 2022

Comments

  • M W
    M W almost 2 years

    I am working on an app that needs to talk to different HTTPS servers. There are cases where server simply ignore SSL/TLS Client Hello (no Server Hello is returned).

    The problem would exhibit itself in code as such:

    >curl32.exe -v -k --tlsv1 https://...
    * timeout on name lookup is not supported
    * About to connect() to <server> port 443 (#0)
    *   Trying <IP>...
    * connected
    * Connected to <server> (<IP>) port 443 (#0)
    * successfully set certificate verify locations:
    *   CAfile: ./cacert.test.pem
      CApath: none
    * Unknown SSL protocol error in connection to <Server>:443
    
    * Closing connection #0
    ===> CURLcode is: 35
    

    The returned code is: CURLE_SSL_CONNECT_ERROR

    When running from OpenSsl directly, this would be ok:

    OpenSSL> s_client -tls1 -connect <server>:443
    

    I have tried various combination (specify TLS, SSL or not specify). The only common thing when problem happens is when the SSL/TLS version is inconsistent. So in WireShark I will see, under TCP, Secure Socket Layer:

    • SSL Record Layer: Handshake Protocol: Client Hello <===
      • Version: TLS 1.0 (0x0301)
      • ...
      • Handshake Protocol: Client Hello
        • ...
        • Version: TLS 1.0 (0x0301)

    In the correct case where I will see Server Hello from server I will see:

    • TLSv1 Record Layer: Handshake Protocol: Client Hello <===
      • Version: TLS 1.0 (0x0301)
      • ...
      • Handshake Protocol: Client Hello
        • ...
        • Version: TLS 1.0 (0x0301)

    I am not completely sure it is the libcurl issue, or maybe the WireShark is not decoding it correctly (as the Record Layer in both cases look almost identical, and the 2 Version fields are correct), making libcurl appears to be the problem.

    Any thoughts? Ideas? Similar experience? Any help much appreciated!!

    • Admin
      Admin over 11 years
      Typo? They look exactly the same (at least from what you have pasted). Both are TLS 1.0 as far as the client is concerned. Wireshark defaults to printing SSL in the first case as the server did not send a Hello.
    • Daniel Stenberg
      Daniel Stenberg over 11 years
      It could be a case where --ssl-allow-beast would make a difference...
    • M W
      M W over 11 years
      Thanks @Rajesh. Ok so I got sidetracked by the WireShark display. I have updated the question accordingly.
    • M W
      M W over 11 years
      @DanielStenberg Thanks for the tips! I tried but unfortunately it does not work for me.
    • Admin
      Admin over 11 years
      @MW It's far easier if you can show us the wireshark capture.