Provides a high level API that transaltes to low level APDU interface of EstEID cards, in JavaScript.
For NodeJS and browsers.
Requires the availability of a reliable Promise based BIBO (Bytes-go-In, Bytes-come-Out) transmit function. That is, a function that takes an APDU and returns a Promise that would resolve to the response from the card, that with a mix of PC/SC and JavaScript would look something like:
function transmit(Buffer apdu) {
return new Promise((resolve, reject) => resolve(SCardTransmit(apdu)))
}
Three implementations are provided:
- Node PC/SC interface, provided by node-pcsclite (in
node-pcsc.js
) - Node RPC interface via Web eID app WebSocket protocol (in
node-web-eid-ws.js
) - Browser app interface via web-eid.js (TBD, in
web.js
andweb.html
)
You need a recent NodeJS and developer tools for native code compilation. On Windows also OpenSSL 1.0.X that matches the architecture of NodeJS.
git clone https://github.com/martinpaljak/esteid.js
cd esteid.js
npm install
npm test
Give the target you want to test as parameter to npm test
First
npm install --save-dev esteid
then
const esteid = require('esteid')
Creates an instance of EstEID, bound to the transmit channel. Takes the BIBO-Promise-function as the parameter.
var EstEID = esteid.connect(transmit)
Returns a Promise that resolves to the personal data file contents. Takes a field name (string) or a list of field names as a parameter. By default reads all fields.
EstEID.getPersonalData().then(
(data) => console.log(JSON.stringify(data, null, 2))
)
Would show
{
"SURNAME": "PALJAK",
"GIVEN_NAMES1": "MARTIN",
"GIVEN_NAMES2": "",
"SEX": "M",
"CITIZENSHIP": "EST",
"DATE_OF_BIRTH": "16.07.1982",
"PERSONAL_ID": "38207162722",
"DOCUMENT_NR": "AA044XXXX",
"EXPIRY_DATE": "23.11.2017",
"PLACE_OF_BIRTH": "EESTI / EST",
"ISSUING_DATE": "08.05.2013",
"PERMIT_TYPE": "",
"REMARK1": "",
"REMARK2": "",
"REMARK3": "",
"REMARK4": ""
}
Returns a Promise that resolves if PIN verification succeeds. Use EstEID.PIN1
, EstEID.PIN2
and EstEID.PUK
to indicate PIN type. valuepromise
must resolve to the PIN value, as an ASCII string.
var pin = Promise.resolve('1234')
EstEID.verify(EstEID.PIN1, pin).then(
() => console.log('PIN verified'),
(e) => console.log('PIN verification failed', e)
)
There is a handy PIN wrapper for CLI application in cli.js
const cli = require('./cli.js')
EstEID.verify(EstEID.PIN1, cli.PIN('Please enter PIN1')).then(
() => console.log('PIN verified'),
(e) => console.log('PIN verification failed', e)
)
Returns a Promise that resolves to the certificate as a Buffer. Use EstEID.AUTH
and EstEID.SIGN
to indicate certificate type.
EstEID.getCertificate(EstEID.AUTH).then((cert) => {
// do something with the certificate
})
Returns a Promise that resolves to the result of RSA signature operation with the authentication key, as a Buffer. PIN promise, if provided, is resolved only if the card is in unauthenticated state.
EstEID.authenticate(challenge).then((cryptogram) => {
// do something with the cryptogram
})
Returns a Promise that resolves to the result of RSA signature operation with the signing key, as a Buffer. PIN promise is required and is always resolved.
EstEID.sign(dtbs, Promise.resolve('12345')).then((signature) => {
// do something with the signature
})
Returns a Promise that resolves to the result of RSA decryption operation with the authentication key, as a Buffer. PIN promise, if provided, is resolved only if the card is in unauthenticated state.
EstEID.decrypt(cryptogram).then((plaintext) => {
// do something with the plaintext
})
Returns a Promise that resolves to the remaining PIN tries for all PIN-s or the PIN specified. By default all remaining retries are returned in an array ([PIN1, PIN2, PUK]
). If a single pin is given as a parameter, a single counter is returned.
EstEID.getPINCounters().then((triesleft) => {
// do something with the tries left information
})
Returns a Promise that resolves to the key usage counters. By default both counters returned in an array ([AUTH, SIGN]
). If a single key is given as a parameter, a single counter is returned.
EstEID.getKeyCounters().then((counters) => {
// do something with the counters
})