0

This has me stumped. I am trying to use Ruby HTTPClient to connect to an API using a certificate. The certificate works well in SoapUI tool to connect to this API, but it results in a handshake error when using it with HTTPClient.

The code:

require 'httparty'

class ExternalApi

  include HTTParty
  pkcs12 File.read("#{File.expand_path('.')}/certs/999.p12"), 'apipasswd'
  ssl_version :TLSv1

  def get_session

    payload = { 'typeInfo': 'uk.xxx.ess.xapi.dto.v1.session.UserSession',
                'token': '021600556514 x x x' }    

    HTTParty.post('https://esspro:83/ess-api/v1/UserSession',
      {
        headers: {
        'XAPI_ASID': '999',
        'Content-Type': 'application/json'
        },
        :body => [ payload ],
        :verify => false
      }    
    )

  end    
end

The error is:

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server session ticket A: sslv3 alert handshake failure

Unfortunately I don't have experience of debugging TLS connections and could do with a few tips on how to investigate this. I have come across a few posts talking about SSLv3 being a default in httparty and complaining that you can't change it. I don't know if that holds true today as they were quite old posts.

I have also tried converting this key to a PEM and adding it to my MAC using the keytool, but it has made no difference to the error. Also I'm not sure if it is necessary to do so as SoapUI seems to be happy to connect without it being in the keystore.

One other thing I am unsure of is if there are more than one key store on a MAC.

Why is the Ruby code experiencing an alert handshake failure?

Any help in investigating this gratefully received.

=====================================================================

Thanks jww, I have managed to set the correct openssl version now. I already had a higher version from brew but the OS was using the old one. So I just updated the path and now:

openssl version
OpenSSL 1.0.2k  26 Jan 2017

I still get the same handshake error in Rubymine though...

OpenSSL::SSL::SSLError: SSL_connect returned=1 errno=0 state=SSLv3 read server session ticket A: sslv3 alert handshake failure

It still seems to be using SSLv3 for some reason and looking around on the net, there are quite a few posts complaining about it doing this and ignoring the instruction to use TLSv1.

Using openssl to connect seems to suggest that the server is using TLSv1:

openssl s_client -connect erspro:83 -prexit -verify false -tls1 -CAfile ./999000000045.p12 -CApath .
verify depth is 0
CONNECTED(00000003)
depth=1 C = UK, ST = Yorkshire, L = Leeds, O = BJSS, OU = eRS, CN = all.ers-api.com, emailAddress = ers@bjss.com
verify error:num=19:self signed certificate in certificate chain
140736904315912:error:14090086:SSL routines:ssl3_get_server_certificate:certificate verify failed:s3_clnt.c:1264:
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 1612 bytes and written 7 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1488111301
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---
---
no peer certificate available
---
No client certificate CA names sent
---
SSL handshake has read 1612 bytes and written 14 bytes
---
New, (NONE), Cipher is (NONE)
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
No ALPN negotiated
SSL-Session:
    Protocol  : TLSv1
    Cipher    : 0000
    Session-ID:
    Session-ID-ctx:
    Master-Key:
    Key-Arg   : None
    PSK identity: None
    PSK identity hint: None
    SRP username: None
    Start Time: 1488111301
    Timeout   : 7200 (sec)
    Verify return code: 0 (ok)
---

Although I'm not sure of most of what is said in this output. The complaint about the self signed cert is flagged as an error, would that be the cause of the handshake failure I'm seeing in Rubymine?

Perhaps I should just look around for a different Ruby http client...

Kaliklipper
  • 355
  • 5
  • 19
  • Its been my experience the cause of handshake alerts in 2016 is lack of TLS 1.0 and above (i.e., SSLv3), and lack of [Server Name Indication (SNI)](http://en.wikipedia.org/wiki/Server_Name_Indication). Can you confirm Ruby is using both of them? Also, OpenSSL on OS X is 0.9.8. You need to investigate the version you are using, and update it as necessary. – jww Feb 25 '17 at 19:10
  • If you need to update OpenSSL on OS X, you usually use Homebrew or MacPorts. That will lead you to [Brew refusing to link openssl](http://stackoverflow.com/q/38670295), [Update OpenSSL on OS X with Homebrew](http://stackoverflow.com/q/15185661), [How to install latest version of openssl Mac OS X El Capitan](http://stackoverflow.com/q/35129977), [How to upgrade OpenSSL in OS X?](http://apple.stackexchange.com/q/126830), [Openssl installation using HomeBrew fails](http://superuser.com/q/486389), etc. – jww Feb 25 '17 at 21:33

0 Answers0