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...