Skip to content
ecdsa.com

mdoc / mDL Inspector

Paste an mdoc presentation — a DeviceResponse, a Document, IssuerSigned data or an OpenID4VP vp_token — as hex, base64 or base64url. Add the IACA certificate and the session details to verify it end to end.

100% local — everything runs in your browser, nothing is sent to any server

Source: openwallet-foundation-labs/identity-common-ts test vectors (Apache-2.0): the ISO/IEC 18013-5 Annex D example and two real wallet presentations, with their issuer certificates and session transcripts. Checked as of their issue dates.

DeviceResponse, Document, IssuerSigned or vp_token
Trust
PEM or base64 DER; from the issuing authority or a VICAL
If the document signer chain needs them
Check as ofTimes are in UTC.
Session

Device authentication signs the session transcript, which the verifier rebuilds from the protocol it used

A credential made of signed digests

An mdoc is the credential format of ISO/IEC 18013-5, first written for the mobile driving licence and now one of the two formats of the European Digital Identity Wallet (the other is SD-JWT VC). It is CBOR all the way down, and its idea is close to selective disclosure in SD-JWT: the issuer never signs the data elements themselves. For each element — family_name, birth_date, portrait, driving_privileges — it builds an IssuerSignedItem with a random salt, hashes it, and signs only the list of digests, the Mobile Security Object (MSO), with COSE_Sign1. The holder's wallet can then release any subset of the items; the verifier hashes what it received and finds each digest in the signed MSO.

What the inspector verifies

  1. Structure. A DeviceResponse (version, documents, status, documentErrors), or a single Document, IssuerSigned data or IssuerAuth; an OpenID4VP vp_token — a JSON object whose value is the base64url DeviceResponse — is unwrapped first.
  2. Every disclosed element against the MSO, with the digest algorithm the MSO names, over the IssuerSignedItem bytes exactly as received inside their tag-24 wrapper: re-encoding the CBOR would change the bytes and the digest. A changed value, an element whose digest ID is missing, an element of a namespace the MSO does not cover — each is an error. Digests the holder did not disclose are counted per namespace.
  3. The issuer signature on the MSO with the document signer certificate from its x5chain header, and the MSO's own docType against the document's.
  4. The certificate chain from the document signer to the IACA (Issuing Authority Certificate Authority) roots you trust — the country or state certificates published by issuing authorities, or collected in a VICAL list. Without a root you give, the chain is not judged.
  5. Validity: signed, validFrom, validUntil and expectedUpdate against the check time, as ISO dates without fractional seconds.
  6. Device authentication. The MSO also carries the device key, held by the phone's secure hardware. In each presentation the device signs (or MACs) a DeviceAuthentication structure that includes the session transcript — the context of this one exchange. A copied presentation therefore fails anywhere else.

The session transcript

The verifier does not receive the session transcript; it rebuilds it from the protocol it ran, which is why the inspector asks which protocol was used. Over OpenID4VP 1.0 with a response_uri, the handover hashes the client_id, the nonce, the thumbprint of the verifier's encryption key and the response_uri; over the browser's Digital Credentials API it binds the web origin of the verifier page instead; earlier drafts and ISO 18013-7 Annex B used other arrangements, and in-person ISO 18013-5 exchanges use device and reader engagement data, which you can paste as SessionTranscript bytes. Enter the same values the verifier used, and a valid device signature proves that this presentation was made for that exchange. When the device authenticated with a MAC, the session key comes from an ephemeral key agreement the inspector cannot see, and the report says so.

The examples are the Annex D DeviceResponse of ISO/IEC 18013-5 and two real wallet presentations collected by the OpenWallet Foundation's test suite: Google Wallet over the Digital Credentials API and the French mDL playground, each with its issuer certificate and session parameters. For the other credential format of the EU Digital Identity Wallet, read SD-JWT and SD-JWT VC: selective disclosure for EUDI wallets.