perlsslverificationlwp-useragent

SSL_ca_path with IO::Socket::SSL doesn't use certs in directory


I would like to use the SSL_ca_path ssl option since it is more reliable. The problem it doesn't use the certificates in the given directory.

This code works:

  local $NET::HTTPS::SSL_SOCKET_CLASS = 'IO::Socket::SSL';
  my $ua = LWP::UserAgent->new(ssl_opts => {
    SSL_ca_file => "/etc/pki/tls/certs/ca-bundle.crt",
  #  SSL_ca_path => "/etc/pki/tls/certs/",
  });

But using SSL_ca_path instead of SSL_ca_file breaks the script.

Not working

  local $NET::HTTPS::SSL_SOCKET_CLASS = 'IO::Socket::SSL';
  my $ua = LWP::UserAgent->new(ssl_opts => {
  #  SSL_ca_file => "/etc/pki/tls/certs/ca-bundle.crt",
    SSL_ca_path => "/etc/pki/tls/certs/",
  });

Neither renaming the certificates to *.pem nor removing the trailing / in the path fixes the problem.

Permissions and owner of the directory and files are the same (770)

Complete script: https://github.com/Benedikt1992/nagios-jenkins-plugin/blob/master/check_jenkins_job_extended.pl#L71-L75


Solution

  • A certificate directory for use with OpenSSL (which is the TLS implementation used by IO::Socket::SSL) need to have a specific structure where the file names are based on hashes of the certificates subject. This means that it is not enough to just drop the certificates in the directory.

    For example you will find the following structure (taken from Ubuntu /etc/ssl/certs):

    lrwxrwxrwx 1 root root     41 Feb 25 10:19 f30dd6ad.0 -> USERTrust_ECC_Certification_Authority.pem
    lrwxrwxrwx 1 root root     34 Feb 25 10:19 f3377b1b.0 -> Security_Communication_Root_CA.pem
    

    This directory structure can be created using the OpenSSL rehash or c_rehash command. That command creates symbolic links starting with the hash (which, in some versions of OpenSSL, can be calculated using openssl x509 -noout -hash -in <certfile>) followed by a full stop and a number (starting with .0, and using .1, .2, .3 etc. if multiple certificates have the same hash). Note: the calculation of the hash for the name can be different for different versions of OpenSSL.