The above is hex bytes of a DER-encoded X.509 certificate subject.
when it is decoded, it should return string "Fake" which is certificate subject. How to do it in perl.
$_ = pack('H*', '300f310d300b0603550403130446616b65');
s@^\x30.\x31.\x30.\x06(.)@@s or die;
length >= ord($1) or die;
substr($_, 0, ord($1)) = "";
s@^\x13.@@s or die;
print "$_\n"; #: Fake
Let's try to parse it with the Perl DER parser library Convert::ASN1. For that we need type definitions for the ->prepare(...) method. Let's try to guess the types.
The keywords like tbsCertificate and CertificateSerialNumber pointed me to https://www.rfc-editor.org/rfc/rfc5280, but I noticed that the types above were autodetected incorrectly, because CertificateSerialNumber is an INTEGER there. By looking at the RFC document, I guessed these types:
RDNSequence = SEQUENCE (1 elem)
RelativeDistinguishedName = SET (1 elem)
AttributeTypeAndValue = SEQUENCE (2 elem)
type OBJECT IDENTIFIER = 2.5.4.3 commonName (X.520 DN component)
value PrintableString = Fake
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
RelativeDistinguishedName ::= SET SIZE (1..MAX) OF AttributeTypeAndValue
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue
}
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= ANY -- DEFINED BY AttributeType
use warnings;
use strict;
use Convert::ASN1; # sudo apt-get install libconvert-asn1-perl
use Data::Dumper qw();
my $asn = Convert::ASN1->new;
die "fatal: ASN.1 prepare: " . $asn->error unless $asn->prepare(q<
-- ASN.1 from RFC2459 and X.509(2001)
-- Adapted for use with Convert::ASN1
-- attribute data types --
Attribute ::= SEQUENCE {
type AttributeType,
values SET OF AttributeValue
-- at least one value is required --
}
AttributeType ::= OBJECT IDENTIFIER
AttributeValue ::= DirectoryString --ANY
AttributeTypeAndValue ::= SEQUENCE {
type AttributeType,
value AttributeValue
}
-- naming data types --
Name ::= CHOICE { -- only one possibility for now
rdnSequence RDNSequence
}
RDNSequence ::= SEQUENCE OF RelativeDistinguishedName
DistinguishedName ::= RDNSequence
RelativeDistinguishedName ::=
SET OF AttributeTypeAndValue --SET SIZE (1 .. MAX) OF
-- Directory string type --
DirectoryString ::= CHOICE {
teletexString TeletexString, --(SIZE (1..MAX)),
printableString PrintableString, --(SIZE (1..MAX)),
bmpString BMPString, --(SIZE (1..MAX)),
universalString UniversalString, --(SIZE (1..MAX)),
utf8String UTF8String, --(SIZE (1..MAX)),
ia5String IA5String --added for EmailAddress
}
>);
my $asn_rdns = $asn->find('RDNSequence');
my $der = $_ = pack('H*', '300f310d300b0603550403130446616b65');
my $value = $asn_rdns->decode($der);
die "fatal: ASN.1 decode: " . $asn_rdns->error unless $value;
print Data::Dumper::Dumper($value);
This is easy to decode manually:
"Fake"
Just to double-check, the output of
perl -e "print pack qw/H* 300f310d300b0603550403130446616b65/" | openssl asn1parse -inform DER
is:Here is an ad hoc parser:
Let's try to parse it with the Perl DER parser library Convert::ASN1. For that we need type definitions for the
->prepare(...)
method. Let's try to guess the types.I copy-pasted
300f310d300b0603550403130446616b65
to an online ASN.1 decoder: https://lapo.it/asn1js/#MA8xDTALBgNVBAMTBEZha2U , with the following result:The keywords like tbsCertificate and CertificateSerialNumber pointed me to https://www.rfc-editor.org/rfc/rfc5280, but I noticed that the types above were autodetected incorrectly, because CertificateSerialNumber is an INTEGER there. By looking at the RFC document, I guessed these types:
The corresponding ASN.1 type definitions extracted from the RFC document https://www.rfc-editor.org/rfc/rfc5280:
Let's try to feed these types to the
->prepare(...)
method of the Perl module Convert::ASN1. With a Google search forConvert::ASN1 RDNSequence
, I've found this example code: https://github.com/gbarr/perl-Convert-ASN1/blob/master/examples/x509decode , based on this and the Convert::ASN1 documentation I wrote the following Perl script:Output:
Here you go.