Subject: | SSL parameters auto-detection has problems |
On some systems, F</etc/ssl/certs> is not the best place to get
certificates from (CentOS 6.4 is an example, where we should be
looking at C</etc/pki/tls/certs>). L<IO::Socket::SSL> provides a
function, C<default_ca()>, that returns the best path to use. It is
also the default path used if no options are passed in. So, on my
machine,
my $client = IO::Socket::SSL->new(
PeerHost => 'wwwcie.ups.com',
PeerPort => 'https',
) or die "failed connect or ssl handshake: $!,$SSL_ERROR";
works, but
my $client = IO::Socket::SSL->new(
PeerHost => 'wwwcie.ups.com',
PeerPort => 'https',
SSL_ca_path => '/etc/ssl/certs',
) or die "failed connect or ssl handshake: $!,$SSL_ERROR";
fails. The main reason seems to be that the CA bundle is called
F</etc/ssl/certs/ca-bundle.crt>, but something is looking for a file
called F<cert.pem> (there's a symlink from F</etc/pki/tls/cert.pem> to
F</etc/ssl/certs/ca-bundle.crt>)
In addition, looking at C<default_ca()> at
https://metacpan.org/source/SULLR/IO-Socket-SSL-1.993/lib/IO/Socket/SSL.pm#L308
we see that it already delegates to L<Mozilla::CA>.
Given all this, the logic in L<IO::Async::SSL> could be simplified to:
%SSL_ca_args = IO::Socket::SSL::default_ca();
unless (%SSL_ca_args) {
carp "Unable to set SSL_VERIFY_PEER because Mozilla::CA is unavailable and your SSL configuration is wonky";
$SSL_ca_args{SSL_verify_mode} = IO::Socket::SSL::SSL_VERIFY_NONE();
}
I have not actually tested this code, but I have verified that if I
pass C<< SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_PEER(), >>
explicitly (thus disabling the auto-detect code in L<IO::Async::SSL>),
server verification works.
Hope this helps.