I am trying to build a correctly formatted GET PROCESSING OPTIONS command to be sent to a contactless EMV card. This post has been very helpful but I just need to know a little more detail.
When parsing the PDOL, is it safe to assume that each tag is 2 bytes in length, followed by the size of the data expected in return?
For example, the PDOL 9F66049F02069F37049F1A02
is broken into
9F66 04
, 9F02 06
, etc. each with 2 byte tags and 1 byte for the expected length of the data value.
Is it safe to assume that each tag is 2 bytes in length when parsing?
No, you can't expect that each tag consists of two bytes (though most tags do). Tag-Length-Value (TLV) structures in EMV follow ASN.1 encoding rules (basic encoding rules, BER). See the following documents for further information:
- ITU-T X.690: ASN.1 encoding rules:
Specification of Basic Encoding Rules (BER),
Canonical Encoding Rules (CER) and
Distinguished Encoding Rules (DER)
- A Layman's Guide to a Subset of ASN.1, BER, and DER (by Burton S. Kaliski Jr.)
The latter is a really good introduction that helped me getting started.
A TLV structure (data object) consists of a tag value, a length value, and a data payload (value):
+-----------+-----------+-----------+
| Tag | Length | Value |
| (N Bytes) | (M Bytes) | (L bytes) |
+-----------+-----------+-----------+
The PDOL (and any other data object list, DOL) contains the tag and the length part of one or more such data objects. Similarly, the PDOL related data contains the value parts of the DOs referenced in the PDOL. Both, the tag and the length part can consist of one or more bytes.
For the tag part, the rules are about like this (for more details see the above references):
- If the lower 5 bits of the first tag byte are all ones (
tag[0] & 0x01F == 0x01F
), then the tag consists of at least two bytes.
- If the upper bit of the next tag byte is one (
tag[i] & 0x080 == 0x080
), then the tag consists of one more byte. This is repeated for each subsequent byte.
For the length part, the rules are about like this (for more details see the above references):
- If the upper bit of the first length byte is zero (
length[0] & 0x080 == 0
), then the remaining seven bits encode the length value (length[0] & 0x07F
).
- If the upper bit of the first length byte is one (
length[0] & 0x080 == 0x080
), then the remaining seven bits encode the number of remaining bytes of the length part (length[0] & 0x07F
). The remaining bytes represent the length value as unsigned integer with MSB first.