Skip to content

Uruguayan eID: document how to decode the identity data objects - #34

Open
nicolasgutierrezdev wants to merge 3 commits into
OpenSC:masterfrom
nicolasgutierrezdev:uruguayan-eid-decoding-info
Open

Uruguayan eID: document how to decode the identity data objects#34
nicolasgutierrezdev wants to merge 3 commits into
OpenSC:masterfrom
nicolasgutierrezdev:uruguayan-eid-decoding-info

Conversation

@nicolasgutierrezdev

Copy link
Copy Markdown

Follow-up to #33, where @frankmorgner asked for an example of how to get the
face image and the ID data in human readable form instead of the raw encoding.

Adds a "Decoding the identity data objects" section covering the four PKCS#15
data objects (7001, 7002, 7004, 700B): tag, length form and value type
for each, the 1F xx field tags of the biographic data, how to get the portrait
out as a plain JPEG, and how to split the MRZ into TD1 or TD3 lines.

Two things worth flagging for anyone consuming this data: the biographic text fields
are UTF-8, not ASCII, and the surname split between 1F 01 and 1F 02 is not
reliable, some cards pack both surnames into 1F 01.

Layouts come from AGESIC's public technical documentation and from reading real
cards.

@carlosplanchon

Copy link
Copy Markdown
Contributor

Cross-checked this against AGESIC's technical documentation and against a v4
card, and opened nicolasgutierrezdev#1 against this branch with the
result. Merging that one updates this PR.

The TLV skeleton holds up exactly as written here: 5F 01 with a fixed length of
9, 1F 01 to 1F 06, 3F 01 with a long-form length, 7F 01, and the three
length forms with the same offsets. The document even carries the same worked
example for the portrait, T=0x3F01 L=0x8223FE.

The main find is that 1F 08 is the date of issue, four bytes of packed BCD
in DD MM YY YY order. The documentation mentions a date of issue exactly once,
to say it is the one value that is not ASCII, and never says which tag holds it.
That resolves both loose ends at the same time. It also deserves a warning, since
BCD bytes stay below 0x80: scanning for high bytes reports the field as ASCII,
and decoding it as text succeeds and returns punctuation instead of raising.

The rest is sourcing rather than corrections. The UTF-8 point now reads as
correcting the documentation, which does claim ASCII, instead of contradicting it
silently. Rows beyond 1F 06 are marked as read from cards, since the document
only specifies 1F 01 to 1F 06. The surname warning cites the document naming
1F 01 PrimerApellido, and the card I read has both surnames in 1F 01 with
1F 02 zero-length, so that case is real. There is also a note that these
objects are unverified data while EF 711D is not exposed.

One practical warning for anyone going to the source: the TLV tables in the PDF
are images, so pdftotext returns blank gaps where they should be. They have to
be rendered and read as images.

nicolasgutierrezdev and others added 3 commits August 3, 2026 22:49
Co-authored-by: Carlos Andrés Planchón Prestes <carlosandresplanchonprestes@gmail.com>
Cross-checks the decoding section against the official technical
documentation and against a card, and records where they disagree.

The TLV layouts hold up: 5F01 with a fixed length of 9, 1F01 to 1F06,
3F01 with a long-form length, 7F01, and the three length forms.

* The document describes the biographic values as ASCII. Cards store
  UTF-8, so the page now corrects the specification instead of
  contradicting it silently.
* 1F08 is the date of issue, four bytes of packed BCD. The document
  mentions a date of issue as its one non-ASCII value but never says
  which tag holds it. Adds a warning, since BCD bytes stay under 0x80
  and a non-ASCII check reports the field as text.
* The document only specifies 1F01 to 1F06, so the rows beyond that
  are marked as read from cards.
* The specification names 1F01 PrimerApellido, which is what makes the
  surname warning worth stating.

Also adds the technical documentation and AGESIC's reference code to the
resources, notes that the data objects are unverified when EF 711D is
absent, and renames the Path column, which held file IDs and not the
paths printed above it.
…yout

A v4 and a v5 card read for the page carry the same ten tags, 1F01 to
1F0A, in the same order, with 1F08 four bytes wide on both.

Both also came with 1F02 zero-length and both surnames in 1F01, so the
surname warning now says so instead of leaving it as something seen on
unspecified cards.

Tested-by: Nicolas Gutierrez <ngutierreztassano@gmail.com>
@nicolasgutierrezdev
nicolasgutierrezdev force-pushed the uruguayan-eid-decoding-info branch from f4739c9 to 56c8044 Compare August 4, 2026 01:53
@frankmorgner

Copy link
Copy Markdown
Member

Hmm, the text describes how to parse the output. For users, it would be more helpful to have a tool that actually prints the data in human readable form. Skimming through the documentation, it looks like opensc-asn1 or openssl asn1parse could be used to parse the data...

@nicolasgutierrezdev

nicolasgutierrezdev commented Aug 4, 2026

Copy link
Copy Markdown
Author

@frankmorgner opensc-asn1 has trouble parsing the data. For instance, MRZs Tag is 7F01, which sets constructed bit and the tool tries to look for nested TLVs, failing decoding. But looking at the OpenSC repo, eidenv seems to have tooling built for BELPIC parsing, maybe we could add support there.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants