API reference

@wellknown-id/emrtd

Reads and checks passports and ID cards (ICAO 9303 eMRTDs) over any card transport: BAC or PACE, the data groups, passive authentication against country signing certificates, and Chip or Active Authentication. Nothing here knows the hardware: native NFC, a USB reader or the virtual passport in testing implement CardTransport.

Classes

CardError

A card answered with an error: sw is its status word (0x6982: security status not satisfied, and so on).

Extends

  • Error

Constructors

Constructor
new CardError(message, sw): CardError;
Parameters
ParameterType
messagestring
swnumber
Returns

CardError

Overrides
Error.constructor

Properties

PropertyModifierType
swreadonlynumber

Interfaces

CardTransport

The port: send one APDU, get the response data followed by the two status-word bytes.

Methods

transceive()
transceive(apdu): Promise<Uint8Array<ArrayBufferLike>>;
Parameters
ParameterType
apduUint8Array
Returns

Promise<Uint8Array<ArrayBufferLike>>


TrustStore

The port: where CSCA certificates come from.

Methods

cscas()
cscas(country?): Promise<Certificate[]>;

Candidate CSCAs for a country (ISO 3166 alpha-2 or alpha-3 as in the MRZ), or all of them.

Parameters
ParameterType
country?string
Returns

Promise<Certificate[]>

Type Aliases

Access

type Access = 
  | {
  cardAccess: "absent" | "present";
  paceOffered?: string[];
  protocol: "BAC";
  status?: string;
}
  | {
  cipher: PaceCipher;
  curve: string;
  password: "MRZ" | "CAN";
  protocol: "PACE";
};

How the chip was unlocked. For BAC, what EF.CardAccess said: absent (with the chip's status), or the PACE variants it offered that this library can't run yet.


AccessKey

type AccessKey = 
  | BacKey
  | {
  can: string;
};

What unlocks the chip: the MRZ details (as for BAC), or the card access number.


BacKey

type BacKey = object;

What the BAC keys come from: document number, date of birth and date of expiry.

Properties

PropertyType
dateOfBirthstring
dateOfExpirystring
documentNumberstring

Certificate

type Certificate = object;

An X.509 certificate, parsed as far as checking a document signer's chain needs.

Properties

PropertyTypeDescription
authorityKeyId?Uint8Array-
country?string-
derUint8Array-
issuerUint8Array-
notAfterDate-
notBeforeDate-
publicKeyPublicKeyInfo-
signatureUint8Array-
signatureAlgorithmAlgorithmId-
subjectUint8Array-
subjectKeyId?Uint8Array-
subjectTextstring-
tbsUint8ArrayThe DER of tbsCertificate: what the issuer signed.

ChipResult

type ChipResult = object;

Whether the chip proved it's genuine, and how (Chip Authentication, or Active Authentication).

Properties

PropertyType
detailstring
method?"chip-authentication" | "active-authentication"
status"valid" | "invalid" | "not-checked"

Mrz

type Mrz = object;

A document's machine-readable zone, parsed: the fields as printed, and whether each check digit holds.

Properties

PropertyType
checksobject
checks.compositeboolean
checks.dateOfBirthboolean
checks.dateOfExpiryboolean
checks.documentNumberboolean
dateOfBirthstring
dateOfExpirystring
documentCodestring
documentNumberstring
format"TD3" | "TD1"
givenNamesstring
issuingStatestring
nationalitystring
optionalDatastring
sexstring
surnamestring

MrzScan

type MrzScan = object;

An MRZ read off a camera frame: enough to unlock the chip (the BAC key), and what kind of document it is.

Properties

PropertyTypeDescription
documentCodestringP for passports; I, A or C for identity cards.
format"TD3" | "TD1"-
issuingState?string-
keyBacKey-

PassiveAuthentication

type PassiveAuthentication = object;

Whether the issuing state signed the data (passive authentication): the SOD's signature and its certificate chain.

Properties

PropertyTypeDescription
chain"valid" | "invalid" | "no-csca" | "country-mismatch"-
csca?object-
csca.country?string-
csca.subjectstring-
documentSigner?object-
documentSigner.country?string-
documentSigner.notAfterDate-
documentSigner.notBeforeDate-
documentSigner.subjectstring-
reason?string-
sodSignature"valid" | "invalid"-
status"valid" | "invalid" | "unverified"Overall: valid only when the SOD's signature, the DS certificate's chain and the countries all check out.

PassportRead

type PassportRead = object;

What a read found, and how far each check got.

Properties

PropertyTypeDescription
accessAccessHow the chip was unlocked.
chipChipResultIs the chip genuine, not a copy (Chip or Active Authentication)?
face?objectThe face image from DG2, if asked for.
face.imageUint8Array-
face.mimestring-
filesMap<number, Uint8Array>Raw files as read, by data-group number (0 = the SOD), for storage and later re-verification.
integrityobjectWhether each data group read matches its hash in the SOD.
integrity.allMatchboolean-
integrity.dataGroupsMap<number, boolean>-
integrity.hashAlgorithmstring-
mrzMrzThe document's data, from DG1.
passivePassiveAuthenticationWas the data signed by the issuing state (passive authentication)?

Progress

type Progress = (step, detail?) => void;

Called as a read goes: the step, and for reads the file and how much of it has come.

Parameters

ParameterType
stepStep
detail?{ bytes?: number; file?: string; total?: number; }
detail.bytes?number
detail.file?string
detail.total?number

Returns

void


ReadOptions

type ReadOptions = object;

What to read, and how to check it.

Properties

PropertyTypeDescription
face?booleanAlso read DG2, the face image (tens of kilobytes; a few seconds over NFC).
onProgress?ProgressTold how the read is going.
random?(bytes) => Uint8ArrayWhere randomness comes from. Defaults to crypto.getRandomValues.
trust?TrustStoreCountry signing certificates, for passive authentication. Without them the SOD's signature is still checked.

Scene

type Scene = 
  | {
  kind: "mrz";
  scan: MrzScan;
}
  | {
  kind: "mrz-partial";
}
  | {
  kind: "passport-other-page";
}
  | {
  kind: "card-front";
}
  | {
  kind: "driving-licence";
}
  | {
  kind: "nothing";
};

What a camera frame shows, for guiding the holder: an MRZ, part of one, or another page or side.


SecurityObject

type SecurityObject = object;

The document's security object (EF.SOD): each data group's hash, and the issuer's signature over them.

Properties

PropertyTypeDescription
hashAlgorithmstring-
hashesMap<number, Uint8Array>-
signedDataUint8ArrayThe DER of the whole SignedData, for signature verification (passive authentication).

Step

type Step = "select" | "authenticate" | "read" | "verify" | "done";

Where a read has got to, for a progress display.

Variables

FILES

const FILES: object;

The elementary files an eMRTD read uses, by their file identifiers.

Type Declaration

NameTypeDefault value
COM2860x011e
DG12570x0101
DG142700x010e
DG152710x010f
DG22580x0102
SOD2850x011d

GERMAN_CSCA_SHA256

const GERMAN_CSCA_SHA256: "20:84:AE:D7:A9:91:B3:15:8E:63:AD:75:0D:3D:C3:8B:C6:C9:DC:F5:95:8F:28:D1:16:2F:49:88:4E:91:AD:A8" = '20:84:AE:D7:A9:91:B3:15:8E:63:AD:75:0D:3D:C3:8B:C6:C9:DC:F5:95:8F:28:D1:16:2F:49:88:4E:91:AD:A8';

The German CSCA (certificate 10/24), as the BSI publishes its SHA-256 fingerprint: the anchor for the BSI's master list. Never taken from the list itself.


PASSPORT_AID

const PASSPORT_AID: Uint8Array<ArrayBuffer>;

The eMRTD application's AID (ICAO 9303-10): what a transport selects, and what an app declares for NFC.


readPassport

const readPassport: (transport, key, options) => Promise<PassportRead> = readDocument;

The old name: reads with BAC or PACE alike.

Reads a passport or ID card: PACE when the chip offers it (with the MRZ or the CAN), otherwise BAC (MRZ only). Then DG1, optionally DG2, and the SOD, checked against each other.

Parameters

ParameterType
transportCardTransport
keyAccessKey
optionsReadOptions

Returns

Promise<PassportRead>

Functions

alpha2()

function alpha2(mrzState): string | undefined;

The two-letter code for an MRZ issuing state, or undefined if it isn't a state we know.

Parameters

ParameterType
mrzStatestring

Returns

string | undefined


checkDigit()

function checkDigit(field): string;

The ICAO 9303 check digit for a field.

Parameters

ParameterType
fieldstring

Returns

string


checkHashes()

function checkHashes(sod, groups): Map<number, boolean>;

Hashes each data group read and compares it with the SOD. Detects altered data; the SOD's signature is checked separately.

Parameters

ParameterType
sodSecurityObject
groupsMap<number, Uint8Array<ArrayBufferLike>>

Returns

Map<number, boolean>


classify()

function classify(lines): Scene;

What the camera is looking at, from all the text it read, and so what the holder should do next.

Parameters

ParameterType
linesstring[]

Returns

Scene


findMrz()

function findMrz(lines): MrzScan | undefined;

Finds a readable MRZ in OCR text lines, trying every alignment near the expected line lengths.

Parameters

ParameterType
linesstring[]

Returns

MrzScan | undefined


fromHex()

function fromHex(text): Uint8Array;

Hex (either case; whitespace ignored) as bytes. Throws on anything else.

Parameters

ParameterType
textstring

Returns

Uint8Array


hex()

function hex(bytes): string;

Bytes as uppercase hex.

Parameters

ParameterType
bytesUint8Array

Returns

string


hint()

function hint(scene): string;

What to tell the holder for each scene.

Parameters

ParameterType
sceneScene

Returns

string


isCan()

function isCan(key): key is { can: string };

Whether an access key is a card access number (CAN) rather than the MRZ's BAC key.

Parameters

ParameterType
keyAccessKey

Returns

key is { can: string }


mrzInformation()

function mrzInformation(__namedParameters): string;

The "MRZ information" string (ICAO 9303-11 §9.7.1.1): each field followed by its check digit.

Parameters

ParameterType
__namedParametersBacKey

Returns

string


normalise()

function normalise(line): string;

Uppercase, '<' look-alikes to '<', everything outside the MRZ alphabet dropped.

Parameters

ParameterType
linestring

Returns

string


parseCertificate()

function parseCertificate(der): Certificate;

Parses a DER certificate. Throws on one it can't read.

Parameters

ParameterType
derUint8Array

Returns

Certificate


parseDg1()

function parseDg1(dg1): Mrz;

DG1: the MRZ, as stored on the chip (tag 61 { 5F1F <MRZ> }).

Parameters

ParameterType
dg1Uint8Array

Returns

Mrz


parseDg2()

function parseDg2(dg2): 
  | {
  image: Uint8Array;
  mime: "image/jpeg" | "image/jp2";
}
  | undefined;

DG2: the facial image. Returns the first image and its type (JPEG, or JPEG 2000, which few browsers show).

Parameters

ParameterType
dg2Uint8Array

Returns

| { image: Uint8Array; mime: "image/jpeg" | "image/jp2"; } | undefined


parseMasterList()

function parseMasterList(bytes): Certificate[];

Reads the CSCA certificates out of a CSCA master list (a CMS SignedData over a CscaMasterList).

Parameters

ParameterType
bytesUint8Array

Returns

Certificate[]


parseMrz()

function parseMrz(text): Mrz;

Parses a TD3 (passport, 2 × 44) or TD1 (ID card, 3 × 30) MRZ. Whitespace and line breaks are ignored between lines.

Parameters

ParameterType
textstring

Returns

Mrz


parseSod()

function parseSod(sod): SecurityObject;

Reads the LDS security object out of EF.SOD (77 { ContentInfo { signedData, [0] SignedData } }).

Parameters

ParameterType
sodUint8Array

Returns

SecurityObject


passiveAuthentication()

function passiveAuthentication(
   sod, 
   issuingState, 
   trust?
): Promise<PassiveAuthentication>;

Passive authentication of an SOD, for a document whose MRZ names issuingState. The data-group hashes are checked separately (lds.ts checkHashes): together they say the data is what the state signed.

Parameters

ParameterType
sodUint8Array
issuingStatestring
trust?TrustStore

Returns

Promise<PassiveAuthentication>


readDocument()

function readDocument(
   transport, 
   key, 
   options?
): Promise<PassportRead>;

Reads a passport or ID card: PACE when the chip offers it (with the MRZ or the CAN), otherwise BAC (MRZ only). Then DG1, optionally DG2, and the SOD, checked against each other.

Parameters

ParameterType
transportCardTransport
keyAccessKey
optionsReadOptions

Returns

Promise<PassportRead>


trustStore()

function trustStore(certificates): TrustStore;

A TrustStore over certificates in memory, e.g. from master lists.

Parameters

ParameterType
certificatesCertificate[]

Returns

TrustStore


verifyMasterList()

function verifyMasterList(bytes, anchors): object;

Verifies a CSCA master list before trusting what's in it: its CMS signature, and its signer certificate signed by an anchor, a CSCA pinned by the SHA-256 fingerprint its issuer publishes (for Germany's list, on the BSI's website). Returns the CSCAs it carries, or throws.

Parameters

ParameterType
bytesUint8Array
anchorsstring[]

Returns

object

NameType
anchorstring
cscasCertificate[]
signerstring