Setting up an EAC-PKI using OpenSCDP

This document explains how to set up an Extended Access Control Public Key Infrastructure (EAC-PKI) using tools from the OpenSCDP project.

EAC-PKIs are used for Machine Readable Travel Documents (MRTD), some national identification cards and electronic drivers licenses. As the name implies, it is used to control which terminal is allowed to access certain data on the chip embedded in an identification document.

The test setup described in this document stores private keys in PKCS#8 files on the server disk or in a SmartCard-HSM.

A life demo is available online.


An EAC-PKI consists of a three layer PKI:

  1. The Country Verifying Certification Authority (CVCA),
  2. the Document Verifier (DV) and
  3. the Inspection System (IS).

The CVCA is at the root of the PKI. It issues self-signed certificates as trust anchors and link certificates to connect subsequent trust anchors. The CVCA certifies subordinate Document Verifier.

A Document Verifier is responsible for terminals of a certain control sector. Beside other functional components, it contains the Document Verifier Certification Authority (DVCA) that issues certificates for inspections systems requiring access to data stored in the chip of the identification document.

Terminals hold a private key to authenticate against the chip in an identification document. To prove the authenticity of the key, it must present a chain of certificates, starting with a certificate issued by the trust anchor on the chip up to and including the terminals certificate.

Terminals can either be integrated or distributed. In an integrated terminal, the private key is stored in a secure cryptographic module integrated in the terminal. In a distributed terminal, the key is stored in a secure cryptographic module located in a terminal control center (TCC) to which terminals are attached.

An EAC-PKI uses self-descriptive Card Verifiable Certificates (CVC) rather than X.509 certificates. CVCs are much smaller than X.509 certificates. They are specifically designed for chips with limited memory and computing power. CVCs can be used with ECDSA and RSA, whereby ECDSA is more common due to its faster processing in the chip as well as the reduced size of signatures and public keys.


The EAC-PKI supplied as part of the script bundle for the SmartCard-HSM implements a CVCA, a DVCA and a terminal control center. It supports synchronous and asynchronous web services as defined in TR-03129 to request certificates and to sign requests for terminal authentication. It has a web interface for user interaction and automation of tests.


The EAC-PKI requires the Scripting Server runtime environment. For download and installation follow the instructions.

The EAC-PKI can be deployed on a running Scripting Server using the loadserver.cmd batch file supplied in the icao/cvca directory. The batch file is configured for installations on localhost. It installs all three components (CVCA, DVCA and TCC) on the same machine.

To store keys in a SmartCard-HSM rather than on disk, you will need to connect an initialized SmartCard-HSM and use the loadserver_hsm.cmd instead.


Each service offers a web user interface at the same URL at which the service responds to web service requests.

In the default configuration,

In an initial workflow you will need to

The EAC-PKI is now operational and will accept requests to obtain a signature for terminal authentication.

This can be tested using the tccconnection.js script located in the /icao directory. The script can be executed with the Smart Card Shell or using the Eclipse Plug-In. The scripts declares a class implementing the web service call. A simple test is performed by entering


If all is configured well, then the output should be:

Received certificates:
CVC id-IS DV (official domestic) CAR=UTCVCA00001 CHR=UTDVCA00001 CED=27. Mai 2010 CXD=30
CVC id-IS Terminal CAR=UTDVCA00001 CHR=UTTERM00001 CED=27. Mai 2010 CXD=28. Mai 2010 
Signature: 0D 44 A2 1F 10 1A 34 C2 65 FB 68 01 9A 1A E4 58 F9 73 41 76 B7 81 30 F7 ...
Message: 48 65 6C 6C 6F 20 57 6F 72 6C 64
Hash: A5 91 A6 D4 0B F4 20 40 4A 01 17 33 CF B7 B1 90 D6 2C 65 BF 0B CD A3 2B 57 B2 ...
Signature: 30 46 02 21 00 0D 44 A2 1F 10 1A 34 C2 65 FB 68 01 9A 1A E4 58 F9 73 41 ...
Signature verification: true


The default configuration provides for a reasonable setup for testing on localhost. It uses short certificate expiration times and maximum rights.

All configuration is done in the configureservices.js script. The script is run on the server as part of the deployment process and creates the requires services.

To create your own configuration, you will need to create your own configuration script and adapt the loadserver.cmd batch file accordingly.

The default configuration contains four sections, a global settings section and one section for CVCA, DVCA and TCC.

Global settings

The datadir variable defines the directory that is used to store persistent data. It is set to c:\data\eacpki by default. Each service instance uses it's own directory starting with this base name.

The url variable defines the base URL at which services are available. It is set to http://localhost:8080 in the default configuration.

CVCA section

A CVCA (or DVCA/TCC) service is created using the three lines

var cvca = new CVCAService(datadir +  "/cvca", "UTCVCA");
var cvcaui = new CVCAUI(cvca);
SOAPServer.registerService("cvca", cvca, cvcaui);

The first statement creates a CVCA service with the certificate holder name "UTCVCA", storing data in the /cvca directory of the data store.

The second statement creates a user interface for this service.

The final statement registers the service and it's user interface with the SOAPServer under the relative URL "cvca". The SOAP server is a Scripting Server component listening at http://localhost:8080/se for incoming requests.

To issue certificates, a CVCA requires three policies, one for self-signed root certificates, one for link certificates and a finale one for DV certificates.

A certificate policy is defined as JavaScript object using the following notation:

// The policy used to issue DV certificates
var dVPolicy = { certificateValidityDays: 4,
				   chatRoleOID: new ByteString("id-IS", OID),
				   chatRights: new ByteString("A3", HEX),
				   includeDomainParameter: false,
				   extensions: null,
				   authenticatedRequestsApproved: false,
				   initialRequestsApproved: false,
				   declineExpiredAuthenticatedRequest: true

certificateValidityDays defines the number of days a newly issued certificate will be valid, starting this the current date.

chatRoleOID is a ByteString containing the object identifier to be used in the Certificate Holder Authorization Template (CHAT) to identify the terminal type and format of the template.

chatRights is a ByteString containing the object identifier to be used in the Certificate Holder Authorization Template (CHAT) to identity the role and rights of the entity to which the certificate is issued.

shellModelForExpirationDate limits expiration date of issued certificate to expiration date of issuing certificate.

includeDomainParameter selects whether domain parameters are included as part of the public key or not.

extensions is an array of ASN1 objects that are added as Certificate Extensions.

authenticatedRequestsApproved allows to select, if authenticated certificate requests (requests signed by the valid current key of the subordinate instance) are automatically approved and certified. If not approved and if asynchronous processing is allowed, such requests are added to a list of pending requests and need explicit approval by an operator.

initialRequestsApproved allows to select, if initial requests are approved without operator action.

declineExpiredAuthenticatedRequests allows to select, if authenticated requests with a signature based on an expired certificate should be declined (failure_expired). If set to false, such requests are added to the pending requests list and can be approved manually.

shellModelForExpirationDate if set to true, then the expiration date of a certificate issued by this CA will be limited to the expiration date of the CA's certificate. This must be set to false for issuing root or link certificates.