noxxi / p5-io-socket-ssl

IO::Socket::SSL Perl Module
36 stars 59 forks source link

PEM_file2cert etc. for multiple certificates #101

Closed rovo89 closed 3 years ago

rovo89 commented 3 years ago

I have an application in which I read all certificate information at startup before switching to a very restricted user which doesn't have access to the files. I do this with IO::Socket::SSL::Utils::PEM_file2cert, then use the value later for the SSL_cert / SSL_ca / SSL_client_ca attributes.

Unfortunately, the helper only reads the first certificate from the file. In many cases, e.g. for certificate chains, it will actually contain multiple concatenated certificates though. I didn't find any builtin way to read all certificates from a file/string, so I came up with this modified version:

use constant PEM_R_NO_START_LINE => 0x0906D06C;
sub PEM_file2certs {
    my $file = shift;
    my $bio = Net::SSLeay::BIO_new_file($file,'r') or
        croak "cannot read $file: $!";
    my @certs;
    while (1) {
      if (my $cert = Net::SSLeay::PEM_read_bio_X509($bio)) {
        push @certs, $cert;
      } else {
        Net::SSLeay::BIO_free($bio);
        my $error = Net::SSLeay::ERR_get_error();
        last if $error == PEM_R_NO_START_LINE && @certs;
        croak "cannot parse $file as PEM X509 cert: " . Net::SSLeay::ERR_error_string($error);
      }
    }
    return \@certs;
}

The same algorithm is used in OpenSSL and it's working fine for me.

Could you please consider adding such variants of PEM_file2cert and PEM_string2cert upstream? Obviously, the constant shouldn't be hardcoded. I also don't know your preferences on returning an array reference vs. a list, separate functions vs. wantarray detection and code style in general, that's why I just paste my code rather than trying to open a PR.

noxxi commented 3 years ago

Thanks for the feedback. I've added this functionality (and some more) in 5169dc6 based on your code.

rovo89 commented 3 years ago

Thank you! 👍 This didn't make it into 2.071, right? Any timeline for 2.072 yet? 😉

noxxi commented 3 years ago

2.072 is now released