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

I am trying to receive the ASN1 structure of a certificate with Convert::ASN1. I have my certificate in PEM format in a file.

This is what I did:

1. Read the PEM certificate

my $s_filename = 'path/to/file'; my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size, $atime, $mtim +e, $ctime, $blksize, $blocks) = stat $s_filename; open FILE, "<$s_filename" or die "no such file"; binmode FILE; my $pem_cert; read FILE, $pem_cert, $size; close FILE;

2. Remove 'BEGIN' and 'END'-CERTIFICATE

$pem_cert =~ /-----BEGIN CERTIFICATE-----(?:\r\n?|\n)(.+)(?:\r\n?|\n)- +----END CERTIFICATE-----/s; my $s_pem = $1;

3. Receive the DER format, because Convert::ASN1 works with DER or BER format

my $der   = MIME::Base64::decode($s_pem);

3. Create Convert::ASN1 object

my $asn = Convert::ASN1->new;

4. Configure the encoding of the object – to be DER, because by default Convert::ASN1 works with BER format

$asn->configure(encoding => 'DER');

5. Decode the DER format, which causes the problem

my $out = $asn->decode($der); if(!defined $out) { die $asn->error(); } print Dumper($out);

This is the output:

decode error 0 1918 at /.../Convert/ASN1/_decode.pm line 260.

When I tried to follow the execution using step-by-step debugger, I saw that there is nothing in ASN1's $self->{script}, but I can't understand what that variable stands for.

Can somebody help me?

Replies are listed 'Best First'.
Re: Receive certificate ASN1 structure
by haukex (Archbishop) on Sep 14, 2016 at 12:59 UTC

    Hi LoraIlieva,

    I haven't used this module before, but if you look at the Convert::ASN1 distribution, in the examples you'll find the script x509decode (in fact, part of your code looks like you got it from there). It contains a lot of supporting ASN.1 definitions that I'm assuming you can't do without; my guess is that's what your script is currently missing. However, it looks like the "x509decode" script will only process files in binary format. I took your MIME::Base64 decoding idea, inserted it into that script, tested it, and it looks like it is able to decode an example .pem file. My modified while loop looks like this:

    use MIME::Base64 qw/decode_base64/; while ( my $filename = shift ) { my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size, $atime,$mtime,$ctime,$blksize,$blocks) = stat $filename; open FILE, "<$filename" or die "no such file"; binmode FILE; my $pem_cert; read FILE, $pem_cert, $size; close FILE; $pem_cert =~ /-----BEGIN CERT\w*-----(.+?)-----END CERT\w*-----/s; my $der = decode_base64($1); decodeCert( $der ); }

    Hope this helps,
    -- Hauke D

    Updated wording slightly. Update 2: Replaced the regex to be a little more selective.

Re: Receive certificate ASN1 structure
by VinsWorldcom (Prior) on Sep 14, 2016 at 16:04 UTC

    I'm not an expert at Convert::ASN1 but I've used it in Net::SNMPTrapd. You may want to have a look at that for an example?

    I think you have to create a decode using the prepare() method. That's what I do in the SNMPTrap module above.

    Alternatively, after your Step 4) but before Step 5), try:

    Convert::ASN1::asn_dump($der); Convert::ASN1::asn_hexdump($der);