Thanks I replaced: IO::Socket::SSL->require();by use IO::Socket::SSL qw(debug3);And it works. I am not sure if the USE statement instead of the require function makes a difference, but it hasn't had an effect I can see, other than that qw(debug) produced what is closer to what I need. The output looks like the following:
DEBUG: .../IO/Socket/SSL.pm:2503: new ctx 50492112
DEBUG: .../IO/Socket/SSL.pm:526: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:528: socket connected
DEBUG: .../IO/Socket/SSL.pm:550: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:583: using SNI with hostname gremlin.site
DEBUG: .../IO/Socket/SSL.pm:634: set socket to non-blocking to enforce
+ timeout=180
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:2384: ok=1 cert=46355584
DEBUG: .../IO/Socket/SSL.pm:2384: ok=1 cert=50404096
DEBUG: .../IO/Socket/SSL.pm:1539: scheme=www cert=50404096
DEBUG: .../IO/Socket/SSL.pm:1549: identity=gremlin.site cn=gremlin.sit
+e alt=
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> 1
DEBUG: .../IO/Socket/SSL.pm:702: ssl handshake done
The above is a communication with a server that behaves properly. The following is from a server that is not, and SSL handshaking fails: DEBUG: .../IO/Socket/SSL.pm:2503: new ctx 50487248
DEBUG: .../IO/Socket/SSL.pm:526: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:528: socket connected
DEBUG: .../IO/Socket/SSL.pm:550: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:586: not using SNI because hostname is unk
+nown
DEBUG: .../IO/Socket/SSL.pm:634: set socket to non-blocking to enforce
+ timeout=180
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:2384: ok=0 cert=50477104
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:1757: SSL connect attempt failed
DEBUG: .../IO/Socket/SSL.pm:653: fatal SSL error: SSL connect attempt
+failed error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certif
+icate verify failed
DEBUG: .../IO/Socket/SSL.pm:2537: free ctx 50487248 open=50487248
DEBUG: .../IO/Socket/SSL.pm:2542: free ctx 50487248 callback
DEBUG: .../IO/Socket/SSL.pm:2549: OK free ctx 50487248
What is missing is something that distinguishes what was sent to the server from what was received from the server. I can't tell if the problem lies with the server or the client, or what that problem is. All I know, beyond what I show here is that "openssl s_client" with the appropriate arguments times out, and simply does not get the certificate from the server (alas, I do not control the sever). Is it possible to get that, e.g. by using some debug level other than 3, or perhaps trace, or some other means? Thanks Ted | [reply] [d/l] [select] |
...ted.byers...
Wow, dude, its me again :)
Same deal, it means IO::Socket::SSL couldn't verify the certificate authority of the gremlin.site
It means your local certificate authority .crt bundle (Mozilla::CA or something else) is missing the authority that gremlin.site uses (because not all CA can be trusted, LWP , Mozilla::CA, and Phony SSL Certificates )
Debugging SSL communications has more info on using openssl client to debug ssl communications (like get more info, rule perl out...)
Like if you go into firefox and go to https://rt.perl.org, if you don't have Certificate Authority - Develooper LLC certificate installed, firefox will warn you bad example, they don't use develooper anymore
See, all these "Client-" headers are put there by LWP+helpers, try it on your gremlin.site, hopefully it will say something like unrecognized root authority
$ lwp-request -UuSsEd https://rt.perl.org
GET https://rt.perl.org
User-Agent: lwp-request/6.03 libwww-perl/6.08
200 OK
Cache-Control: no-cache
Connection: close
Date: Sun, 03 Aug 2014 22:52:33 GMT
Pragma: no-cache
Server: Plack::Handler::Starlet
Content-Type: text/html; charset=utf-8
Client-Date: Sun, 03 Aug 2014 23:00:30 GMT
Client-Peer: 207.171.7.176:443
Client-Response-Num: 1
Client-SSL-Cert-Issuer: /C=US/O=GeoTrust, Inc./CN=RapidSSL CA
Client-SSL-Cert-Subject: /serialNumber=KOhlTc3Vbi/3MxmsaSvic2A8i8jTkaB
+z/C=US/O=rt.perl.org/OU=GT87157338/OU=See www.rapidssl.com/resources/
+cps (c)11/OU=Domain Control Validated - RapidSSL(R)/CN=rt.perl.org
Client-SSL-Cipher: AES128-SHA256
Client-SSL-Socket-Class: IO::Socket::SSL
Client-Transfer-Encoding: chunked
Link: </NoAuth/images/favicon.png>; rel="shortcut icon"; type="image/p
+ng"
Link: </NoAuth/css/aileron-squished-09504fd500c0b721310b79cd2eb67ac0.c
+ss>; media="all"; rel="stylesheet"; type="text/css"
Link: </NoAuth/css/print.css>; media="print"; rel="stylesheet"; type="
+text/css"
Set-Cookie: RT_SID_perl.443=15287ecac634a287f31aaa7154f0d7da; path=/;
+secure; HttpOnly
Title: Login
X-Frame-Options: DENY
X-UA-Compatible: IE=edge
| [reply] [d/l] |
$rp{'ca_cert_file'} = 'rootCA.pem';
$rp{'ca_cert_dir'} = '.';
$rp{'SSL_cert_file'} = 'client.crt';
$rp{'SSL_key_file'} = 'client.key';
That is actually the initialization of the hash passed to my package's function new, which uses it thusly: my $self = {
logger => '',
user => $params{user},
password => $params{password},
timeout => $params{timeout} || 180,
ssl_set => 0,
no_ssl_check => $params{no_ssl_check},
ca_cert_dir => $params{ca_cert_dir},
ca_cert_file => $params{ca_cert_file},
SSL_cert_file => $params{SSL_cert_file},
SSL_key_file => $params{SSL_key_file},
};
bless $self, $class;
and the the request function, uses the values stored, like so: $self->{ua}->ssl_opts(SSL_ca_file => $self->{ca_cert_file}
+)
if $self->{ca_cert_file};
$self->{ua}->ssl_opts(SSL_ca_path => $self->{ca_cert_dir})
if $self->{ca_cert_dir};
$self->{ua}->ssl_opts(SSL_cert_file => $self->{SSL_cert_fi
+le})
if $self->{SSL_cert_file};
$self->{ua}->ssl_opts(SSL_key_file => $self->{SSL_key_file
+})
if $self->{SSL_key_file};
The 'ua' member of $self holds the user agent. The log quote I provided that showed a successful connection was for gremlin.site. The one showing a failed connection, was for another site, and one which I expected to fail because the certificate it has, while adequate for https when host names are not checked, was not signed by any CA anyone in his right mind would trust. My reason for this is that, RSN I hope to be buying a domain name and proper certificates from a recognized vendor. I used it only to show that the log itself does not actually tell you which data transfer, or message , came from the client and which came from the server, and which of the two was actually responsible for the failure. This is in preparation for dealing with a server that I do not control and behaves in the same way as this second server (not gremlin.site). Now, how would I change that commandline you showed to inform LWP of the CA's root crt that can be used to verify the server's crt file and my client crt? Also, I noticed that in the session log you showed, the client seemed to be doing most of the work, and that was hardly anything done by the server. I need details that will let me distinguish between a certificate validation failure because the known CA's weren't involved in any way in the creation of the server's certificate from the same failure message being due to the server not sending it's certificate in the first place (maybe an error in the configuration of the server). I set up my two servers specifically to let me see what I get when everything ought to work fine and when there ought to be a failure because the server's certificate could not be verified. I was hoping to see the sort of dialog between machines that one can get, e.g. from Wireshark. I'd use Wireshark to get the dialog I need, except I do not know how to get only the dialog between my workstation and the server I am trying to connect to, without all the other traffic (which seems to be significant), or how to save all that glorious detail to a file that I can send to the administrator of a misbehaving server. And, in Wireshark, I do not know if the server is seeing me at my non-routable IP address or my public IP address (I am connecting to this misbehaving server through a VPN (whose administration remains a mystery to me) Actually, while we're at it, is there an introductory web page that illustrates the steps in the SSL/TLS handshaking that must occure in order to have a secure channel properly opened? Thanks Ted | [reply] [d/l] [select] |
SSL debugging is a pain. IO::Socket::SSL debug output does not make it better, i.e. you get only meaningful information out of it if you already understand SSL and openssl.
To get better help please with your problem please
- provide the version number of IO::Socket::SSL you are using.
- give example code which triggers your problem.
- provide information about the certificate of the server, e.g. issuer, common name, subject alternative names and chain certificates. These information are needed to check why the verification could fail.
As for integrating the debug output with Log4Perl: $IO::Socket::SSL::DEBUG controls both debugging from IO::Socket::SSL and Net::SSLeay (it is an alias to $Net::SSLeay::trace) and both modules simply write to STDERR. So you need to capture this.
| [reply] |
DEBUG: .../IO/Socket/SSL.pm:2503: new ctx 54371264
DEBUG: .../IO/Socket/SSL.pm:526: socket not yet connected
DEBUG: .../IO/Socket/SSL.pm:528: socket connected
DEBUG: .../IO/Socket/SSL.pm:550: ssl handshake not started
DEBUG: .../IO/Socket/SSL.pm:586: not using SNI because hostname is unk
+nown
DEBUG: .../IO/Socket/SSL.pm:634: set socket to non-blocking to enforce
+ timeout=180
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:657: ssl handshake in progress
DEBUG: .../IO/Socket/SSL.pm:667: waiting for fd to become ready: SSL w
+ants a read first
DEBUG: .../IO/Socket/SSL.pm:687: socket ready, retrying connect
DEBUG: .../IO/Socket/SSL.pm:2384: ok=0 cert=54354928
DEBUG: .../IO/Socket/SSL.pm:647: Net::SSLeay::connect -> -1
DEBUG: .../IO/Socket/SSL.pm:1757: SSL connect attempt failed
DEBUG: .../IO/Socket/SSL.pm:653: fatal SSL error: SSL connect attempt
+failed error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certif
+icate verify failed
DEBUG: .../IO/Socket/SSL.pm:2537: free ctx 54371264 open=54371264
DEBUG: .../IO/Socket/SSL.pm:2542: free ctx 54371264 callback
DEBUG: .../IO/Socket/SSL.pm:2549: OK free ctx 54371264
2014/08/04 16:40:45> [http client] communication error: 500 Can't conn
+ect to 195.160.170.115:8443 (certificate verify failed)
500 Can't connect to 195.160.170.115:8443 (certificate verify failed)
I see two disconcerting things. First, I see "not using SNI because hostname is unknown". I do not know if this is a fatal error, or if there is anything I can do about it. Second, and what is the main, the fatal error, I see: "fatal SSL error: SSL connect attempt failed error:14090086:SSL routines:SSL3_GET_SERVER_CERTIFICATE:certificate verify failed" Would I be right in assuming that the three lines "waiting for fd to become ready: SSL wants a read first" represent three attempts to get the server's certificate? Would I be right in thinking that this is due to the sever not sending it's certificate? If so, what reasons may be behind that certificate not being sent? Is this exchange supposed to happen before or after the client sends the client certificate? I ask because I do not see anything that obviously related to the client sending it's own certificate. I have also succeeded in getting the server's certificate. Here is most of what openssl tells me about it: ted@linux-jp04:~/Work/Projects/FirstData> openssl s_client -connect 19
+5.160.170.115:8443 -showcerts
CONNECTED(00000003)
depth=1 C = LV, ST = Latvia, L = Riga, O = xxxxxxxxxxxx CN = ECOMM-tes
+t, emailAddress = xxxxxxxxxxx
verify error:num=19:self signed certificate in certificate chain
verify return:0
139748861212304:error:14094412:SSL routines:SSL3_READ_BYTES:sslv3 aler
+t bad certificate:s3_pkt.c:1275:SSL alert number 42
139748861212304:error:140790E5:SSL routines:SSL23_WRITE:ssl handshake
+failure:s23_lib.c:177:
---
Certificate chain
0 s:/C=LV/O=FDL/CN=lv-rtps-proxy-test.ne.1dc.com
i:/C=LV/ST=Latvia/L=Riga/O=xxxxxxxxxx/CN=ECOMM-test/emailAddress=xx
+xxxxxxxxxxxxx
-----BEGIN CERTIFICATE-----
DELETED
-----END CERTIFICATE-----
1 s:/C=LV/ST=Latvia/L=Riga/O=xxxxxxxxxxxxxx/CN=ECOMM-test/emailAddres
+s=xxxxxxxxxxxxx
i:/C=LV/ST=Latvia/L=Riga/O=xxxxxxxxxxxxxxxxxxx/CN=ECOMM-test/emailA
+ddress=xxxxxxxxxxxxxxxxxx
-----BEGIN CERTIFICATE-----
DELETED
-----END CERTIFICATE-----
---
Server certificate
subject=/C=LV/O=FDL/CN=lv-rtps-proxy-test.ne.1dc.com
issuer=/C=LV/ST=Latvia/L=Riga/O=xxxxxxxxxxxxxxx/CN=ECOMM-test/emailAdd
+ress=xxxxxxxxxxxxxxx
---
Acceptable client certificate CA names
/C=LV/ST=Latvia/L=Riga/O=xxxxxxxxxxxxx/CN=ECOMM-test/emailAddress=xxxx
+xxxxxxxxxxxxxxx
/C=LV/O=FDL/CN=lv-rtps-proxy-test.ne.1dc.com
---
SSL handshake has read 3646 bytes and written 170 bytes
---
New, TLSv1/SSLv3, Cipher is EDH-RSA-DES-CBC3-SHA
Server public key is 2048 bit
Secure Renegotiation IS supported
Compression: NONE
Expansion: NONE
SSL-Session:
Protocol : TLSv1
Cipher : EDH-RSA-DES-CBC3-SHA
Session-ID: 53DFFBFBC58875853342EDD1EE387FCE42F0D98DE61F3C24D37FC5
+792C5AC3C2
Session-ID-ctx:
Master-Key: DELETED
Key-Arg : None
PSK identity: None
PSK identity hint: None
SRP username: None
Start Time: 1407187961
Timeout : 300 (sec)
Verify return code: 19 (self signed certificate in certificate cha
+in)
---
ted@linux-jp04:~/Work/Projects/FirstData>
Of course I masked out the site operator's name and email address for obvious reasons Alas, I just noticed a couple errors right at the beginning of the output, but I do not yet know what they mean. I do not think the presence of a self signed certificate in the mix is an issue as the operators of this site established their own CA, and use that to sign both their own server certificates and the client side certificates that their clients are to use when connecting, and, as I said, connection is possible ONLY through a VPN to their site. But, is this going to result in a verification failure (even though I have the root CA certificates for THEIR CA)? Does this help? Thanks Ted | [reply] [d/l] [select] |
How do I get that version number? I tried running cpan, as root, and in it's help, it does not seem to give an option for viewing the version number of those packages that are installed. I them executed the command to upgrade IO::Socket::SSL, and cpan told me that all packages for it are up to date, if that helps. I would expect that result to depend on what platform I am using (OpenSuse 13.1, if that matters). I can't get the server certificate, even with openssl s_client (it times out), though that happily gets the server certificate from every other server I need to communicate with using https. The operators of that site have sent me their root CA certificates (in two files, so I have to figure out how to tell LWP's useragent to use both of them, or so they say -- they went so far as to suggest I put them both in Java's keystore, as if that helps when writing Perl). Here is my package, which is intended to encapsulate the complexities of using LWP with HTTPS:
package REJBlibUA::client;
use strict;
use warnings;
#use Net::SSL ();
use English qw(-no_match_vars);
use HTTP::Status;
use LWP::UserAgent;
use LWP::Protocol::https;
use HTTP::Request;
use HTTP::Request::Common;
use HTTP::Response;
use Log::Log4perl qw(:easy get_logger);
use UNIVERSAL::require;
use Encode qw(decode encode);
my $log_prefix = "[http client] ";
sub new {
my ($class, %params) = @_;
die "non-existing certificate file $params{ca_cert_file}"
if $params{ca_cert_file} && ! -f $params{ca_cert_file};
die "non-existing certificate directory $params{ca_cert_dir}"
if $params{ca_cert_dir} && ! -d $params{ca_cert_dir};
my $self = {
logger => '',
user => $params{user},
password => $params{password},
timeout => $params{timeout} || 180,
ssl_set => 0,
no_ssl_check => $params{no_ssl_check},
ca_cert_dir => $params{ca_cert_dir},
ca_cert_file => $params{ca_cert_file},
SSL_cert_file => $params{SSL_cert_file},
SSL_key_file => $params{SSL_key_file},
};
bless $self, $class;
my $conf = q(
log4perl.logger = INFO, FileApp, ScreenApp
# log4perl.logger = TRACE, FileApp, ScreenAp
+p
log4perl.appender.FileApp = Log::Log4perl::Appender::
+File
log4perl.appender.FileApp.filename = lwp.log
log4perl.appender.FileApp.layout = PatternLayout
log4perl.appender.FileApp.layout.ConversionPattern = %d> %m%n
log4perl.appender.ScreenApp = Log::Log4perl::Appender
+::Screen
log4perl.appender.ScreenApp.stderr = 0
log4perl.appender.ScreenApp.layout = PatternLayout
log4perl.appender.ScreenApp.layout.ConversionPattern = %d> %m%
+n
);
# Initialize logging behaviour
Log::Log4perl->init( \$conf );
# Log::Log4perl->infiltrate_lwp();
*trace = *INFO;
*conns = *DEBUG;
*debug = *DEBUG;
$self->{'logger'} = get_logger();
# create user agent
$self->{ua} = LWP::UserAgent->new(
parse_head => 0, # No need to parse HTML
keep_alive => 1,
requests_redirectable => ['POST', 'GET', 'HEAD']
);
$self->{ua}->ssl_opts(verify_hostname => 1, SSL_verify_mode => 1);
if ($params{proxy}) {
$self->{ua}->proxy(['http', 'https'], $params{proxy});
} else {
$self->{ua}->env_proxy();
}
$self->{ua}->timeout($self->{timeout});
return $self;
}
sub request {
my ($self, $request, $file) = @_;
# $request is a HTTP::Request object, created with only the URL
# $file is a message, normally an XML file
my $logger = $self->{logger};
my $url = $request->uri();
my $scheme = $url->scheme();
print "\$url = $url\n\t\$scheme = $scheme\n";
print "\t\$self->{ssl_set} = ",$self->{ssl_set},"\n";
print "\t\$self->{ca_cert_dir} = ",$self->{ca_cert_dir},"\n";
print "\t\$self->{ca_cert_file} = ",$self->{ca_cert_file},"\n";
$self->_setSSLOptions() if $scheme eq 'https' && !$self->{ssl_set}
+;
my $result = HTTP::Response->new( 500 );
eval {
$result = $self->{ua}->request($request, $file);
};
# check result first
if (!$result->is_success()) {
# authentication required
if ($result->code() == 401) {
if ($self->{user} && $self->{password}) {
$logger->debug(
$log_prefix .
"authentication required, submitting credentials"
);
# compute authentication parameters
my $header = $result->header('www-authenticate');
my ($realm) = $header =~ /^Basic realm="(.*)"/;
my $host = $url->host();
my $port = $url->port() ||
($scheme eq 'https' ? 443 : 80);
$self->{ua}->credentials(
"$host:$port",
$realm,
$self->{user},
$self->{password}
);
# replay request
eval {
if ($OSNAME eq 'MSWin32' && $scheme eq 'https') {
alarm $self->{timeout};
}
$result = $self->{ua}->request($request, $file);
};
if (!$result->is_success()) {
$logger->error(
$log_prefix .
"authentication required, wrong credentials"
);
}
} else {
# abort
$logger->error(
$log_prefix .
"authentication required, no credentials available
+"
);
}
} else {
$logger->error(
$log_prefix .
"communication error: " . $result->status_line()
);
}
}
return $result;
}
sub _setSSLOptions {
my ($self) = @_;
# SSL handling
$ENV{HTTPS_DEBUG} = 1;
if ($self->{no_ssl_check}) {
# LWP 6 default behaviour is to check hostname
# Fedora also backported this behaviour change in its LWP5 pack
+age, so
# just checking on LWP version is not enough
$self->{ua}->ssl_opts(verify_hostname => 0, SSL_verify_mode =>
+0)
if $self->{ua}->can('ssl_opts');
} else {
# only IO::Socket::SSL can perform full server certificate val
+idation,
# Net::SSL is only able to check certification authority, and
+not
# certificate hostname
# IO::Socket::SSL->require();
# IO::Socket::SSL->require('debug3');
use IO::Socket::SSL qw(debug3);
die
"failed to load IO::Socket::SSL, " .
"unable to perform SSL certificate validation.\n" .
"You can use 'no-ssl-check' option to disable it."
if $EVAL_ERROR;
# if ($self->{logger}{debug} >= 3) {
# $Net::SSLeay::trace = 2;
# }
print "\t\t\$LWP::VERSION = $LWP::VERSION\n";
if ($LWP::VERSION >= 6) {
print "\t\tSetting cert dir and file if available\n";
$self->{ua}->ssl_opts(SSL_ca_file => $self->{ca_cert_file}
+)
if $self->{ca_cert_file};
$self->{ua}->ssl_opts(SSL_ca_path => $self->{ca_cert_dir})
if $self->{ca_cert_dir};
$self->{ua}->ssl_opts(SSL_cert_file => $self->{SSL_cert_fi
+le})
if $self->{SSL_cert_file};
$self->{ua}->ssl_opts(SSL_key_file => $self->{SSL_key_file
+})
if $self->{SSL_key_file};
}
}
$self->{ssl_set} = 1;
}
1;
And here is the calling code, used to test it: #!/usr/bin/perl
use HTTP::Request;
use HTTP::Response;
use lib './Work';
use REJBlibUA::client;
my $method = "POST";
my @requests = (HTTP::Request->new( $method,'https://www.google.ca'),
HTTP::Request->new( $method,'https://gremlin.site/cgi-
+bin/printenv.pl'),
HTTP::Request->new( $method,'https://byerspublishing.com'),
HTTP::Request->new( $method,'https://195.160.170.115:8443/soap
+proxy/PaymentServer'));
my $cnt = 0;
foreach my $r (@requests) {
my %rp;
if ($cnt == 1) {
$rp{'ca_cert_file'} = 'rootCA.pem';
$rp{'ca_cert_dir'} = '.';
$rp{'SSL_cert_file'} = 'client.crt';
$rp{'SSL_key_file'} = 'client.key';
}
if ($cnt == 3) {
#next;
$rp{'ca_cert_file'} = 'ECOMM_old_test.pem';
$rp{'ca_cert_dir'} = '.';
$rp{'SSL_cert_file'} = 'OnsoftArch_test.pem';
$rp{'SSL_key_file'} = 'onsoftarch_test.key';
}
my $c = REJBlibUA::client->new(%rp);
my $resp = $c->request($r);
if ($resp->is_success) {
print $resp->decoded_content;
} else {
print STDERR $resp->status_line, "\n";
}
$cnt += 1;
}
https://gremlin.site/cgi-bin/printenv.pl works perfectly. https://byerspublishing.com fails because it uses only the default certificate Apache comes with (until I buy a proper certificate for it), and thus the server certificate is not trusted. https://195.160.170.115:8443/soapproxy/PaymentServer is the real problem, but it is accessable only through a VPN to the operator's site. I can ping that server, but openssl times out when I try to get the server's certificate. I suspect their server is not sending it's certificate, for whatever reason. But then, I don't know the sequence of events that must happen when the handshaking is to involve both client and server side certificate validation. Is the client supposed to send it's certificate first, and is it supposed to send the certificate for the CA that signed it (even if the server already has that CA certificate), before the server sends it's certificate, or after? I suppose the fact the problem server is accessable only through a VPN makes diagnosing the problem, and that I can't seem to get it's certificate, makes diagnosing the problem more challenging. How do I use $IO::Socket::SSL::DEBUG? Thanks Ted | [reply] [d/l] [select] |