2

As the title says, I'm attempting to POST some JSON to a REST API using a pretty old version of perl, specifically 5.10.1. I'm working in a pretty old legacy codebase on RHEL 6. The handshake fails with error 500 because the server has sslv3 disabled. However I'm using versions of LWP and IO::Socket::SSL that I believe nominally support at least TLSv1, which the server supports so I'm unsure why the connection fails as it should just use an acceptable cipher. The server appears to be behind a cloudfront reverse proxy which may be relevant. I don't know enough about SSL to say for certain, but it appears that the issue is in the way the server I care about is set up and how the version of perl and libraries in use implement the cipher. Using an online tool I noticed that the handshake fails on several browsers that do not support SNI. The version of openssl available should support this, but neither of the perl SSL implementations appear to. Is there a way around this?

this question seems to be dealing with a similar issue, but they solve it by installing a newer version of perl, which I'm not sure I can do given that this would likely break large portions of the codebase.

This unresolved bug seems to accidentally document this behavior my problem is identical to the one listed, but I can also connect to the openssl host. I'm not sure that it's the same problem but I am on the same version of redhat with the same software and the same inconsistent behavior so it seems valuable. If it helps my software versions are as follows

openssl-1.0.1e-58.el6_10.i686
perl-Crypt-SSLeay-0.57-17.el6.x86_64
perl-IO-Socket-SSL-1.31-3.el6_8.2.noarch
perl-Net-SSLeay-1.35-10.el6_8.1.x86_64

If I run

printf 'HTTP/1.0 200 Ok\r\n\r\n' | openssl s_server -accept 2000 -cert certificate.pem -key key.pem -no_ssl2 -no_ssl3 -no_tls1

the following script (test.pl) is able to connect using the same libraries

my $ua = LWP::UserAgent->new(timeout => 600);
my $req = HTTP::Request->new(POST => $ARGV[0]);
$req->content_type('application/json');
$req->content_encoding('gzip');
$req->content('');
my $res = $ua->request($req);
print $res->status_line, "\n";
>perl5.10.1 test.pl https://localhost:2000/
200 Ok

However, when I run an only slightly more complicated program using the same libraries and perl version I get errors relating to the sslv3 handshake

500 Can't connect to dev.superquoteapi.fis.rcuh.com:443 (SSL connect attempt failed with unknown errorerror:14077410:SSL routines:SSL23_GET_SERVER_HELLO:sslv3 alert handshake failure)

I've even tried to force the program to use only TLSv1, but to no avail, the following line seems to have no impact

my $ua = LWP::UserAgent->new(ssl_opts => {verify_hostname => 0}, SSL_version => '!TLSv12:TLSv1:!SSLv2:!SSLv3', allowed_protocols => ['https']);

The program I am actually working with is listed below

use LWP;
use IO::Socket::SSL;
my $ua = LWP::UserAgent->new(ssl_opts => {verify_hostname => 0}, SSL_version => '!TLSv12:TLSv1:!SSLv2:!SSLv3', allowed_protocols => ['https']);

my $req = HTTP::Request->new('POST', 'https://dev.superquoteapi.fis.rcuh.com:443/api/quote');

$req->header('Content-Type' => 'application/json');
$req->header('Accept' => 'application/json');
#an api key is required and set in a header, but I won't list that here

open(my $fd, '<', 'data,json') 
    or die "Unable to open file, $!";
my @json=<$fd>;
close($fd)
    or warn "Unable to close the file handle: $!";
$req->content(@json);
my $resp = $ua->request($req);
print $resp->as_string;

I have tried removing IO::Socket::SSL and replacing it with Net::SSL as is referenced in this question How do I force LWP to use Crypt::SSLeay for HTTPS requests? but this does not seem to help. The code I used was

use Net::SSL ();
BEGIN {
  $Net::HTTPS::SSL_SOCKET_CLASS = "Net::SSL"; # Force use of Net::SSL
}

The two programs are more or less identical. The issue seems to be in the way the specific server https://dev.superquoteapi.fis.rcuh.com handles ssl requests. However I do not know enough about SSL/TLS to verify this meaningfully, so I have included both for completeness.

I apologize if this question is a bit rambling, but I really need help, and I just want to provide as much information as I can. If I can provide further information, or remove unhelpful information please let me know, I am absolutely at my wits end.

ragingSloth
  • 1,094
  • 8
  • 22
  • 1
    Does adding `use IO::Socket::SSL;` to the working program break it? – ikegami Aug 31 '19 at 08:17
  • It does not. Nor does removing it and forcing the use of Net::SSLeay fix things, I've added information reflecting this – ragingSloth Aug 31 '19 at 08:30
  • I'm having difficulty seeing the difference between the working and the non-working program. What does it take to make the working program stop working? – ikegami Aug 31 '19 at 08:36
  • Swapping the url, is what does it. I'm unsure exactly how, but the server I actually care about differs from the openssl setup somehow that causes this error. However the fact that I can connect to a local server as proof of concept seems to imply that it is not because the library cannot use the necessary ciphers. This is what I find so confusing, as it is reported as if the cipher is unsupported. I probably don't need to include both programs, but I don't know enough about ssl to really say much more so I included them. Would you recommend I alter the question? – ragingSloth Aug 31 '19 at 08:38
  • ah ok. Sorry, I can't help you. I don't know how to debug SSL. – ikegami Aug 31 '19 at 08:44
  • https://github.com/noxxi/p5-ssl-tools could reveal more. – daxim Aug 31 '19 at 12:08
  • the version of IO::Socket::SSL available in the repositories is not sufficient to run those tools. I've online tools to examine the endpoint, but nothing stands out to me. Is there something in particular you think I should be looking for @daxim – ragingSloth Aug 31 '19 at 18:34

0 Answers0