Skip to content

WebSocket API v2

The WebSocket API enables live eMRTD verification with full security coverage:

The eMRTD Connector Android / eMRTD Connector iOS handle the WebSocket communication with the DocVal Server automatically.

Protocol Reference

This section describes the internal communication protocol between mobile applications and the DocVal Server. Typically, you do not need to understand this protocol to use the DocVal Server. However, being familiar with it may provide a deeper understanding of how the DocVal Server operates under the hood.

WebSocket Endpoint

Clients connect to the DocVal Server via:

wss://<server-host>/ws2/validate

By default, the DocVal Server only posts the final verification result to the configured Result Server, ensuring no sensitive eMRTD data is stored on the DocVal Server. If the client wishes to receive the finalized result as well, it must indicate this via the FINISH message (see below).

General Concept

The goal is to read an eMRTD chip as fast and securely as possible. Most of the chip access takes place locally on the client device. However, certain critical tasks (e.g., generating an Active Authentication challenge, performing Chip Authentication, and doing Passive Authentication checks) happen on the server, because the client device is not fully trusted.

On iOS, the NFC connection has a timeout (around 20 seconds), so the protocol is designed to minimize server round-trips during the NFC session. Hence, most interactions with the server occur before or after the short NFC session.

At a high level, the communication flow is:

  1. WebSocket Connection The client opens a WebSocket connection.

  2. Start The client sends a START message, which includes identification and other fields.

  3. Accept The server responds with an ACCEPT message containing an Active Authentication challenge.

  4. NFC Session and Data Reading

    • The client opens the NFC connection to the chip.
    • The client reads initial data (e.g., SOD, DG14) and may hand over Chip Authentication to the server (CA_HANDOVER).
    • After the server completes Chip Authentication, it returns CA_HANDBACK.
  5. Complete Reading The client finishes reading the chip, closes NFC, and then sends FINISH.

  6. Server Authentication Checks The server finalizes Passive Authentication and any other verifications.

  7. Result

    • The server posts the final passport result to the configured Result Server.
      • The server will retry up to 3 times (with 3-second timeout per attempt) if the POST fails due to network/connection errors.
      • HTTP error responses other than 408, 429, and 5xx are not retried.
    • If the client requested it, the server also sends RESULT back over the WebSocket.
  8. Close The server sends a CLOSE message or closes the WebSocket with the appropriate code and reason.

Active Authentication

Active Authentication (AA) ensures that an eMRTD chip is not cloned. It relies on a cryptographic challenge–response approach that proves the chip holds a private key which cannot be read or extracted from the chip. The flow is as follows:

  1. The server creates an 8-byte random challenge and sends it to the client in the ACCEPT message.
  2. During the NFC session, the client provides this challenge to the eMRTD chip. The chip signs the challenge using its internal private key.
  3. The client includes the signature it in the FINISH message sent to the server. The server verifies the signature against the chip's public key.

Chip Authentication

Chip Authentication (CA) ensures that an eMRTD chip is not cloned by confirming it holds a private key known only to the chip. It uses a Diffie-Hellman key exchange to establish new secure messaging keys, then checks whether the chip can successfully communicate using those keys. The client device is considered untrusted, so the server must perform the critical CA steps.

The sequence in this protocol is:

  1. The client establishes NFC communication with the chip (e.g., performing Access Control) and reads Data Group 14 (dg14), which contains security information for CA.
  2. The client sends dg14 to the server in a binary FILE message, then follows up with a CA_HANDOVER text message, handing control of the CA process to the server.
  3. The server generates an ephemeral Diffie-Hellman key pair and orchestrates the key exchange with the chip by sending APDU messages (binary) to the client, which the client relays to the chip.
  4. The server confirms the chip can use the newly established secure messaging keys by reading Data Group 1 (dg1). A successful read indicates that the chip holds the correct private key and is not a clone.
  5. After verifying the chip's authenticity, the server returns dg1 in a FILE message and then sends a CA_HANDBACK text message containing the new SecureMessagingInfo. This allows the client to resume reading the remaining data groups under secure messaging.

Text Messages

All text messages are sent over the WebSocket as UTF-8 JSON objects. Each message includes a type field and may contain additional message-specific fields. An example structure is:

json
{
  "type": "<MESSAGE_TYPE>"
  // other message-specific fields...
}

Below is a description of each message type.

START (Client → Server)

The client starts the protocol by sending a START message.

FieldTypeDescription
validationIdstringUnique identifier used to map the result to a user or session.
clientIdstringAPI access key identifying the client, and used to determine the target result server.
platformstringPlatform identifier (e.g., "android", ios).
nfcAdapterSupportsExtendedLengthbooleanIndicates if the NFC adapter supports extended-length APDUs.
enableDiagnosticsbooleanIf true, the DocVal Server collects additional debugging information (useful for troubleshooting).

Example

json
{
  "type": "START",
  "validationId": "cf847daa-a548-4509-bdeb-4edd51aee448",
  "clientId": "YOUR CLIENT ID",
  "platform": "android",
  "nfcAdapterSupportsExtendedLength": true,
  "enableDiagnostics": true
}

ACCEPT (Server → Client)

Response to the START message.

FieldTypeDescription
activeAuthenticationChallengestringBase64-encoded 8-byte challenge used for Active Authentication.

Example

json
{
  "type": "ACCEPT",
  "activeAuthenticationChallenge": "BK69zyH/nsA="
}

CA_HANDOVER (Client → Server)

Indicates that the client is handing over Chip Authentication to the server.

FieldTypeDescription
maxTransceiveLengthForSecureMessagingintThe maximum supported APDU length (bytes) for secure messaging.
maxBlockSizeintMaximum data block size that can be handled.
secureMessagingInfoSecureMessagingInfoInformation required for secure messaging.

The structure for secureMessagingInfo is described below.

Example

json
{
  "type": "CA_HANDOVER",
  "maxTransceiveLengthForSecureMessaging": 1534,
  "maxBlockSize": 4096,
  "secureMessagingInfo": {
    // ...
  }
}

CA_HANDBACK (Server → Client)

Sent by the server after completing Chip Authentication.

FieldTypeDescription
checkResultstringCA Result: SUCCESS, FAILED, or UNAVAILABLE
secureMessagingInfoSecureMessagingInfoNew secure messaging information.

Example

json
{
  "type": "CA_HANDBACK",
  "checkResult": "SUCCESS",
  "secureMessagingInfo": {
    // ...
  }
}

FINISH (Client → Server)

Sent by the client to indicate that it has finished reading the eMRTD chip and has transmitted all required files.

FieldTypeDescription
sendResultbooleanIf true, the client requests the server to also return the final result that is also sent to the result server.
activeAuthenticationSignaturestring | nullBase64-encoded signature for the challenge received in the ACCEPT message (i.e., the solved challenge).

Example

json
{
  "type": "FINISH",
  "sendResult": true
}

RESULT (Server → Client)

Returned by the server if sendResult in the FINISH message was true. Contains the final passport data.

FieldTypeDescription
passportobjectThe same JSON that is sent to the result server.

Example

json
{
  "type": "RESULT",
  "passport": {
    // ...
  }
}

MONITORING (Client → Server)

Can be used by the client to send monitoring messages that are then logged by the DocVal Server. Used during diagnostic sessions.

FieldTypeDescription
messagestringThe message to log.

Example

json
{
  "type": "MONITORING",
  "message": "Starting PACE protocol with CAN"
}

CLOSE (Server → Client)

Indicates that the server is about to close the WebSocket connection.

FieldTypeDescription
codeintThe WebSocket close code.
reasonstringA textual reason for the closure.

Example

json
{
  "type": "CLOSE",
  "code": 1008,
  "reason": "INVALID_START_MESSAGE"
}

SecureMessagingInfo Object

The SecureMessagingInfo object contains data needed for performing secure messaging with the eMRTD chip. The fields are:

FieldTypeDescription
algorithmstringAES or DESede.
encKeystringBase64-encoded private encryption key.
macKeystringBase64-encoded private MAC key.
sscintThe send sequence counter (SSC).
json
{
  "algorithm": "AES",
  "encKey": "",
  "macKey": "",
  "ssc": 5
}

Binary Messages

All binary messages have a 1-byte type identifier, followed by message type–specific data.

FILE Message

Used by both the client and the server to exchange binary files such as the SOD file or data groups (DG1, DG2, etc.).

FieldSize
Type1 B
Name Len1 B
Namevar
Datavar
  • Type: Always 0x01 for file messages.
  • Name Length: A single byte indicating the length of the file name (0–255).
  • Name: UTF-8–encoded file name, matching the length stated.
  • Data: The binary content of the file.

Common file names in this protocol include:

  • sod for the SOD file.
  • dg<number> for data groups (e.g., dg1, dg2, etc.).

APDU Message (Type: 0x02)

Used for sending and receiving APDU commands and responses. The server typically sends an APDU command, which the client forwards to the chip. The client then sends back an APDU response.

FieldSize
Type1 B
Datavar
  • Type: Always 0x02 for APDU messages.
  • Data: The raw data to be sent to the chip or received from the chip

Connection Closure and Errors

After the process completes successfully, the server closes the WebSocket connection with code 1000 (Normal Closure). If an error occurs, the server closes the connection with a suitable RFC6455 close code and an error reason phrase.

iOS 13 & 14 Quirk

On iOS 13 and 14, an issue exists in the native URLSessionWebSocketTask where the standard close delegate is not reliably called. To ensure the client receives closure information, the server also sends a CLOSE text message (with type = "CLOSE") containing the code and reason just before closing.

Possible Error Reasons

Below are common close-reason phrases you might receive (along with an appropriate code). These phrases indicate why the server is terminating the session:

Close-Reason-Phrase used by the DocVal ServerDescription
TIMEOUT_WHILE_WAITING_FOR_START_MESSAGENo Start Message received in time.
TIMEOUT_WHILE_WAITING_FOR_RESPONSENo APDU Response received in time.
INVALID_CLIENT_IDInvalid Client ID provided.
INVALID_START_MESSAGEIncorrectly encoded Start Message.
UNEXPECTED_MESSAGEUnexpected Text Message received.
INVALID_ACCESS_KEY_VALUESWrong Access Key values provided.
ACCESS_CONTROL_FAILEDAn Error occurred during Access Control.
EMRTD_PASSPORT_READER_ERRORAn Error during the eMRTD session.
FILE_READ_ERRORAn Error occurred while reading a file.
COMMUNICATION_FAILEDWebSocket communication (network) failure.
POST_TO_RESULT_SERVER_FAILEDFailed to post result to Result Server after 3 retry attempts.
PROTOCOL_ERRORThe protocol was violated, indicating an implementation error.
SERVER_ERRORServer side exception occurred.
MAX_SESSION_TIME_EXCEEDEDSession exceeded maximum time.
MALFORMED_JSONClient send malformed JSON.

Appendix A: Security of Chip Authentication

This appendix details the security model behind the Chip Authentication (CA) process. It explains how the DocVal Server v2 protocol maintains robust security while offloading most of the chip communication to the client application.

The Challenge: Untrusted Clients

The primary goal of Chip Authentication is to verify that an eMRTD chip is genuine and not a clone. This is achieved through a cryptographic protocol based on a Diffie-Hellman key exchange. The server, as the trusted inspection system, must perform the security-critical steps. However, the physical NFC communication happens on the client's device, which is considered untrusted.

The challenge is to execute the CA protocol across three parties (Server, Client App, Chip) without compromising security. The protocol is designed to prevent the untrusted client app from being able to simulate a chip.

The Handover/Handback Protocol Flow

The protocol splits the Chip Authentication process into distinct phases, ensuring the server remains in control of all sensitive operations. The client acts as a simple relay for specific, encrypted APDUs during the critical exchange, and only regains the ability to communicate directly with the chip after the server has verified the chip's authenticity.

The sequence, which maps directly to the WebSocket messages, is as follows:

  1. Client-Side Preparation: The client application initiates the NFC session, performs Access Control, and reads the initial data required for Chip Authentication. This is primarily Data Group 14 (dg14), which contains the chip's static public key ($PK_{IC}$).
  2. Handover to Server:
    • The client sends dg14 to the server in a binary FILE message.
    • The client then sends a CA_HANDOVER text message, signaling that the server should take control.
  3. Server-Side Authentication:
    • The server generates its own ephemeral Diffie-Hellman key pair and computes the shared secret, K.
    • The server now needs to verify that the chip can also compute the same shared secret K, which is only possible if it possesses the corresponding private key ($SK_{IC}$). To do this, the server crafts APDU commands to complete the key exchange and test the new secure channel.
  4. Controlled APDU Exchange:
    • The server sends these APDU commands (e.g., to deliver its public key to the chip, and then to read dg1) to the client, encapsulated in binary APDU messages.
    • The client forwards these APDUs to the chip.
    • The chip's encrypted responses are relayed back to the server, again inside binary APDU messages.
  5. Verification and Handback:
    • The server decrypts the chip's response using the shared secret K. A successful decryption proves that the chip is genuine, as a clone would not know the private key ($SK_{IC}$) needed to generate K.
    • Crucially, only after this successful verification, the server sends the CA_HANDBACK message to the client. This message contains the new SecureMessagingInfo (session keys and sequence counter) derived from the shared secret K.
  6. Client Resumes Control: With the new session keys, the client can now resume reading the remaining Data Groups ( e.g., DG2, DG7) from the chip directly, without further server round-trips for each APDU.
  7. Final Server-Side Checks: After the client sends the FINISH message, the server performs final security checks, including Passive Authentication, which cryptographically validates the authenticity of the chip's public key used in step 3.

Security

The server never sends the session keys (SecureMessagingInfo) to the client app until after the chip has proven possession of its private key. The client app is never privy to the chip's static private key or the server's ephemeral private key. It only acts as a temporary, blind relay for the end-to-end encrypted communication between the server and the chip. This ensures that even a malicious client cannot interfere with the authentication itself or establish a secure session with a cloned chip.