Wiki: Tutorial for accessing deep inside of ASN.1 structure by using new ASN1HEX.getIdxbyListEx

TOP | static wiki | wiki | DOWNLOADS | TUTORIALS | API REFERENCE | DEMOS |

ASN.1 DER encoded data parsing by ASN1HEX class is one of the most powerful feature in jsrsasign library. Most of other ASN.1 libraries require to parse whole ASN.1 structured data to access deep inside of the structure such as SEQUENCE or SET. However it's not necessary for jsrsasign. Jsrsasign can easily point a ASN.1 object by a list of object index. From jsrsasign 8.0.21, more flexible methods getIdxbyListEx, getTLVbyListEx and getVbyListEx have been provided.

What is ASN.1?

ASN.1 is a structured binary data representation defined in ITU-T X.680 standard. Here is features of ASN.1

asn1-1

asn1-2

If you are new in ASN.1, you may see introduction video or page.

What is ASN1HEX?

ASN1HEX class is a simple ASN.1 parser. A hexadecimal string of ASN.1 DER data will be parsed and a string index, length bytes, value or TLV bytes will be returned by it.

asn1hex-1

asn1hex-2

What is ASN.1 context specific tag?

Here is a ASN.1 schema of Certificate, TBSCertificate and Validity in RFC 5280.

Certificate  ::=  SEQUENCE  {
     tbsCertificate       TBSCertificate,
     signatureAlgorithm   AlgorithmIdentifier,
     signatureValue       BIT STRING  }

TBSCertificate  ::=  SEQUENCE  {
     version         [0]  EXPLICIT Version DEFAULT v1,
     serialNumber         CertificateSerialNumber,
     signature            AlgorithmIdentifier,
     issuer               Name,
     validity             Validity,
     subject              Name,
     subjectPublicKeyInfo SubjectPublicKeyInfo,
     issuerUniqueID  [1]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3
     subjectUniqueID [2]  IMPLICIT UniqueIdentifier OPTIONAL,
                          -- If present, version MUST be v2 or v3
     extensions      [3]  EXPLICIT Extensions OPTIONAL
                          -- If present, version MUST be v3 }

Validity ::= SEQUENCE {
     notBefore      Time,
     notAfter       Time }

In above, "[0]", "[1]", "[2]" and "[3]" are called "context-specific" tag. In general, context-specific tag represents optional item. Pre-defined tag such as "PrintableString", "INTEGER" or "SEQUENCE" is called "universal tag" which has a value from 0x00 to 0x1f. Context-specific simple tag has a value from 0x80 to 0x9f represented from "[0]" to "[31]" respectively. Context-specific structured tag has a value from 0xa0 to 0xbf also represented from "[0]" to "[31]" respectively.

To learn "context-specific" tag further, please see this guide.

difference between getIdxbyList and getIdxbyListEx

In above ASN.1 schema definition, note the version field is OPTIONAL using a context specific tag [0]. So the position index of Validity will be 4 for X.509v3 certificate or 3 for X.509v1 certificate. To get netBefore value from entire hexadecimal ASN.1 string of certificate, you can use old getIdxbyList as follows. It depends on X.509 v1 or v3:

//For X.509v3
ASN1HEX.getVbyList(<<CERTHEX>>, 0, [0, 4, 0])
//Or for X.509v1
ASN1HEX.getVbyList(<<CERTHEX>>, 0, [0, 3, 0])

When you use new getIdxbyListEx, position index will be always 3 since all context specific tag will be treated as a optional item and skipped to count index:

ASN1HEX.getVbyListEx(<<CERTHEX>>, 0, [0, 3, 0])

To access context specific tag in new getIdxbyListEx use a tag string (ex. "[3]") instead of index number. You can refer extension field as follows. You don't need to care about optional field such as version or issuerUniqueID:

ASN1HEX.getIdxbyListEx(<<CERTHEX>>, 0, [0, "[3]"])

I hope you can handle context-specific tag more easily by new getIdxbyListEx. You can also dig into "OctetString Encapsulated", "BitString Encapsulated" or "Explicit Context Specific Tag" which has a ASN.1 TLV structure in its ASN.1 value(V) by the same way as above.