(2024/01/09) This website is currently WORK IN PROGRESS. I am still performing tests and preparing the full source code to be published on github, soon.
ASN.1 path
ASN.1 BER or DER encoded content is nothing else than a tree-like structure with ′next′ and ′child′ nodes. Each node is an ASN.1 element of type BOOLEAN, INTEGER, OBJECT IDENTIFIER (OID), UTF8String, BIT STRING, OCTET STRING, SEQUENCE, SET, etc.
To select a specifc node (e.g. for manipulation or just dumping), I defined the first version of ASN.1 path (the most simpliest one) as follows:
- ASN.1 path is just a string;
- Either the empty string "" or a single dot "." denote the root ASN.1 node (the dot as an alternative to the empty string was introduced to ease its specification on the command line);
- To select the next ASN.1 element, use a plus character ′+′;
- To select the child ASN.1 element, use an asterisk character ′*′;
- Several plus and asterisk characters in a row may be compacted by counting the characters and prefixing a plus or an asterisk by the number of consecutive characters, respectively.
Examples:
- "." selects the root node;
- "*++*" means ′select the child node, then two times the next node, then again the child node;
- "*3+2*" means: child - three times next - two times child.
Notes:
- If a specifc ASN.1 node does not have a next or child element, then an error is returned;
- In DER-encoded data, the ASN.1 path expression evaluation is straightforward;
- In BER-encoded data, with possible infinite length elements, all end-markers (tag=0x00, length=0x00) do NOT count and are automatically skipped when evaluating a path expression;
- This especially means that you cannot select any of the BER end-markers using ASN.1 path (why should you? they do not carry any kind of information).
ASN.1 path and ′a1sh′
The ASN.1 shell ′a1sh′ is a good example for the implementation of ASN.1 path: After having parsed e.g. DER-encoded input data, you can select a specific node in the ASN.1 element tree using ASN.1 path. After that, you could insert new elements there, delete the currently selected node, etc.
After that, you could save the modified ASN.1 element tree as a new DER-encoded, binary file. Or you could just modify the content of a selected ASN.1 node.
A really big example is:
- read an X.509v3 certificate that you had created before as a template;
- select the ′serialNumber′ ASN.1 element using ASN.1 path;
- patch a new serial number into it;
- select the subject distinguished name of the certificate using ASN.1 path;
- modify the content according to a new certificate holder;
- select the SubjectPublicKeyInfo ASN.1 node;
- patch the public key (RSA, ECC, Edwards curve, DSA, DH) into that node;
- compute the hash (e.g. SHA-256) of the TBSCertificate (also selectable via ASN.1 path);
- create a certificate signature using that hash;
- patch the computed digital signature into the ′signature′ element of the certificate;
- save the DER element tree to disk.
Of course, this example is simplified because you would have to do more (e.g. modify the SubjectKeyIdentifier X.509v3 certificate extension - if applicable) but in general, this is the ′easy′ version of a full certification authority!