I am completely new to Perl. I have written a web service in C# running on a Windows box and am calling it from a Perl script on a Linux box using SOAP::Lite. My code works fine using the http://
handler. I'm now trying to get it to work with https://
The code is:
use SOAP::Lite;
use POSIX;
#Tell Perl to trust the testserver's cert
#$ENV{HTTPS_CA_DIR} = '/usr/local/share/ca-certificates';
$ENV{HTTPS_CA_FILE} = '/home/myusername/TestServer_CA_Cert.cer';
#$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
my $uri = 'http://Automation/';
my $proxy = 'https://TestServer/ToolsAutomation/AutomationInterface.asmx';
my $method = SOAP::Data->name('SubmitAutomationJob')->attr({xmlns => $uri});
#-Code that sets us @params deleted for readability-
my $myServer = SOAP::Lite
-> on_action(sub {join '', $uri, $_[1]})
-> proxy($proxy)
# -> proxy($proxy, ssl_opts => [ SSL_verify_mode => 0 ] )
# -> proxy($proxy, ssl_opts => [SSL_ca_file => $ServerCACert])
;
my $myCALL = $myServer #This is line 36 in the original script
-> call($method => @params);
print 'Result: ' . $myCALL->result;
When I run the code as posted, I get error "500 Can't connect to TestServer:443 at line 36." A network trace on the server side shows the client sends a SYN, server sends a SYN/ACK, client sends and ACK, then the client immediately sends a FIN/ACK.
I have tried various things to get this to work. I have tried:
- Uncommenting the line
#$ENV{PERL_LWP_SSL_VERIFY_HOSTNAME} = 0;
results in "500 Can't connect to TestServer:443 (certificate verify failed). Network trace shows that at least part of HTTPS negotiation is working. - Uncommenting the line
proxy($proxy, ssl_opts => [ SSL_verify_mode => 0 ] )
works, but of course this doesn't verify the server's identity. - Uncommenting the line
-> proxy($proxy, ssl_opts => [SSL_ca_file => $ServerCACert])
also gives a "certificate verify failed" error. - Changing the path to
$ENV{HTTPS_CA_FILE}
gives an error "SSL_ca_file /home/myusername/TestServer_CA_cert.ceeer does not exist" at the line 36. I take this as a good sign; the code is finding the certificate I tell it to use for server auth. - Uncommenting both the
$ENV{HTTPS_CA_DIR}
and the$ENV{HTTPS_CA_FILE}
lines gives the error "only SSL_ca_path or SSL_ca_file should be given."
I have imported my CA's cert into Firefox on the Linux machine and have successfully browsed to my testserver without getting an SSL warning, and then removed the cert from Firefox and browsed back and received the SSL warning, so I'm reasonably confident that the cert file I have is good.
Does anyone have any ideas on how to fix this code? Is there some attribute of the CA's cert itself that I should check? I find it puzzling that Firefox has no problem trusting a server whose SSL cert is signed with this CA's cert, but I can't convince Perl to do the same.
Any feedback is appreciated. And do remember: I'm an absolute Perl n00b. Before I Googled how to call a web service from Perl, the only think I knew about Perl was "Larry Wall."
Thanks!
UPDATE:
At the request of Steffen Ullrich below, I ran the following:
perl -MIO::Socket::SSL=debug4 program.pl
The output I received is:
me@myMachine:~$ perl -MIO::Socket::SSL=debug4 ./program.pl
DEBUG: .../IO/Socket/SSL.pm:402: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:404: socket connected
DEBUG: .../IO/Socket/SSL.pm:422: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:1388: SSL structure creation failed