kgoess has asked for the wisdom of the Perl Monks concerning the following question:

How do you validate an cert given a root cert that signed it? I've got this far:
$root_x509 = Crypt::OpenSSL::X509->new_from_string( $root_key_data, FORMAT_ASN1 ); $root_key = Crypt::OpenSSL::RSA->new_public_key( $x509->pubkey() ); $other_x509 = Crypt::OpenSSL::X509->new_from_string( $other_key_data, FORMAT_ASN1 ); $other_key = Crypt::OpenSSL::RSA->new_public_key( $x509->pubkey() );
Ok, then what? I'm not seeing an obvious method like $root_key->verify_certificate($other_x509) but not seeing one anywhere. Is Crypt::OpenSSL::VerifyX509 the only/best answer? That module fails unit tests on various platforms, but I'll continue in that vein if it's the way to go. But I feel like I must be missing something since it's such a common task.

Replies are listed 'Best First'.
Re: How to validate signature of a RSA/x509 cert in Perl
by beech (Parson) on Mar 27, 2018 at 21:26 UTC

    Hi,

    Can you install Net::SSLeay? It seems to provide "X509_verify_cert" which Crypt::OpenSSL::VerifyX509 seems to use

      Indeed! I just found that myself, and am looking into it. That function was only added to Net::SSLeay in January, so I'll need to upgrade. Unfortunately, the usage information for those low-level functions is quiet terse. I'm currently puzzling over this, and how to get a "value corresponding to openssl's X509 structure"
      my $rv = Net::SSLeay::X509_STORE_add_cert($store, $x); # $store - value corresponding to openssl's X509_STORE structure # $x - value corresponding to openssl's X509 structure
Re: How to validate signature of a RSA/x509 cert in Perl
by kgoess (Beadle) on Mar 29, 2018 at 18:37 UTC
    After extensive research, the closest thing we have to that is in Net::SSLeay, which has bindings to a ton of low-level openssl functions. In v1.83 2018-01-06 they added these:
    X509_STORE_CTX_new and X509_verify_cert
    but I couldn't get past related segfaults and there's not much documentation on there. So I ended up doing:
    1. use Convert::ASN1 to re-encode the tbsCertificate data I had decoded in my PKCS#7 file ("tbs" it turns out is "to-be-signed")
    2. get the signature from the PCKS#7 file
    3. get the subjectPublicKeyInfo.subjectPublic Key from the cert that signed this cert
    4. feed that to $signer_key = Crypt::OpenSSL::RSA->new_public_key($signer_key_pem);
    5. and then do $signer_key->verify($cert_as_signed, $signature)
    and wash, rinse, repeat for each of the certs in the chain.