0

Please bear with me. I'm no SSL encrpytion expert. I just want to make connections to a server, using their API. I am unable to. When I use this api as indicated in the documentation, the following error occurs:

[Errno 1] _ssl.c:510: error:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure

This API seems to be hosted on an AWS server somewhere, and the support person for it has referred me to this AWS document with the added information that their server uses TLSv1_2016. I'm not sure that that's correct, but that's what I was told.

This version of TLS is not supported by the OpenSSL that ships with Ubuntu 14.0.4 (openssl v1.0.1f). Version 1.2 IS supported. I upgrade my system on a regular basis, and it doesn't seem that there is any approved Ubuntu release that supports this protocol. I've been advised to upgrade, but it's not clear to what.

This is all Greek to me. Can someone tell me what upgrade I might be able to do my system to solve this?

UPDATE problem persists after installing Ubuntu-18.04, which comes with openssl 1.1.0g.

Steve Cohen
  • 4,679
  • 9
  • 51
  • 89
  • 1
    TLSv1_2016 is not a version of TLS, but according to that page a **policy in Cloudfront** that maps to multiple TLS versions and ciphersuites, enough of which OpenSSL 1.0.1 supports. handshake_failure on hello can be caused other things besides protocol version and ciphersuite(s), Is this your code or a closed library from someone else? If the latter debugging will be harder. Try connecting with `openssl s_client -connect $host:$port` and if that is rejected try adding `-servername $host`; if either of those works it is not your OpenSSL at fault but their library. ... – dave_thompson_085 May 04 '18 at 21:34
  • 1
    ... If the server is available on 443 (and public, which Cloudfront obviously is) but you can't let us look for ourselves, try getting the analysis by https://www.ssllabs.com/ssltest/ -- that conveniently tests and helpfully describes quite a few _possible_ problems. – dave_thompson_085 May 04 '18 at 21:37
  • okay, openssl s_client -connect $host:$port -servername $host works – Steve Cohen May 05 '18 at 00:52
  • I think this must mean that there is some configuration of openssl that would allow this connection to be made but that this is not the default configuration that is used for a random connection attempt. Perhaps another version would help, even though the problem could also be solved by a reconfiguration of the server, – Steve Cohen May 05 '18 at 04:46
  • @dave_thompson_085 Thanks for all your help. My last post was wrong. I upgraded to Ubuntu-18.04-LTS, which ships with OpenSSL 1.1.0g , and the same problem occurs; openssl s_client -connect $host:$port FAILS while openssl s_client -connect $host:$port -servername $host SUCCEEDS. My guess that upgrading openssl has been proven wrong. The problem is a misconfigured server. Hopefully, the people running this server can fix it, although they say it works for many others. I'll make another wild guess that none of their other users are using Ubuntu, and possibly they all use Windows. – Steve Cohen May 05 '18 at 19:27
  • @dave_thompson_085 what is your trick for putting formatting in Stack Overflow comments? Never seen that done before. – Steve Cohen May 05 '18 at 19:31
  • 1
    If `s_client` fails without `-servername` and succeeds with it, then the server requires the SNI extension (Server Name Indication). In recent years many servers require or prefer SNI, and it is sometimes the only way to handle multiple domains on shared server(s), as a CDN like CloudFront must. OpenSSL (back to 0.9.8 at least) can send SNI, but only if the code that calls OpenSSL specifies it; you still haven't said if that is your code or 'theirs'. If 'theirs' and closed, see if there is a newer version of it, or any relevant config option(s). ... – dave_thompson_085 May 07 '18 at 09:56
  • ... If you have the code, call `SSL_ctrl (sslcb, SSL_CTRL_SET_TLSEXT_HOSTNAME, TLSEXT_NAMETYPE_host_name, hostname)` where hostname is the name of the host as a null-terminated string. If you can't fix the code that calls OpenSSL, but you control the truststore it uses, as a sledgehammer fix you could route your traffic through a proxy that terminates and recreates the TLS connection adding SNI. Stack comments support some but not all markdown; click the word help to the right of the comment box and follow the link to the help page. – dave_thompson_085 May 07 '18 at 10:00
  • No code calls openssl that I am aware of. The call to the API server is made with the python 2.7 requests library. I assume it is calling the OS, which uses openssl. If that's not right I'm barking up the wrong tree, but somewhere along the line I was recommended to check openSSL. – Steve Cohen May 08 '18 at 20:10
  • @dave_thompson_085: I've read your answer above more deeply. It sounds like I have to specify the SNI. The code that calls this is on GitHub in python. I don't know how to make python code send the SNI but I'd be willing to give it a go in a fork of that code if you can point me in the right direction. I'm guessing the original python code was written for a different server that did not require SNI. Thanks! – Steve Cohen May 09 '18 at 01:00
  • @dave_thompson_085 Make the comment I upvoted an answer and I'll credit you. Thanks so much. SNI wasn't a name to me until your answer. Once I knew what this was called, the fix was relatively easy. – Steve Cohen May 09 '18 at 02:27

1 Answers1

1

Answer mostly from comments.

The problem is apparently that the server, like many SSL/TLS servers today especially those handling multiple domains like Cloudfront, requires the SNI (Server Name Indication) extension in SSL/TLS. This was (and easily is) checked with openssl s_client which (unlike most programs) has an option that controls whether to send SNI.

You didn't previously say that this code is Python. It is Python that links to and invokes OpenSSL. (The OS is not involved in SSL/TLS, only in the lower-level TCP/IP protocols.) According to http://docs.python-requests.org/en/master/community/faq/ (at the bottom)

Python3 and Python 2.7.9+ include native support for SNI in their SSL modules. For information on using SNI with Requests on Python < 2.7.9 refer to this Stack Overflow answer.

linking to using requests with TLS doesn't give SNI support which has several answers that appear to consist mostly of updating various things (and I am not in a position to test even if you gave details of your Python and Requests which you didn't).

dave_thompson_085
  • 34,712
  • 6
  • 50
  • 70
  • This is it. I had not previously heard of SNI, nor understood the importance of the openssl test with the servername parameter. Once I knew what it was called, it was easy to google SNI and find the answer. – Steve Cohen May 10 '18 at 16:11