web-eid
Version:
Web eID client library
200 lines (149 loc) • 11.6 kB
Markdown
# web-eid.js · [](https://www.npmjs.com/package/web-eid) [](https://github.com/web-eid/web-eid.js)
[`web-eid.js`](./web-eid.js) is a ultrathin wrapper on top of the [messaging interface](https://github.com/web-eid/web-eid/wiki/MessagingAPI) provided by the [Web eID app](https://github.com/web-eid/web-eid), either via [`web-eid-extension`](https://github.com/web-eid/web-eid-extension) [HTML5 postMessage](https://developer.mozilla.org/en-US/docs/Web/API/Window/postMessage) interface or [WebSockets](https://developer.mozilla.org/en-US/docs/Web/API/WebSockets_API) or some other message transport in the future (like Android Intents)
It makes using the features provided by Web eID installation as available via [web-eid.com](https://web-eid.com) super-easy:
- provides an asynchronous, Promise-based DWIM interface
- listens to incoming messages and turns them into resolved Promises
## Installation
### Browser installation
Just download the file and use it in a script tag
<script src="web-eid.js"></script>
Functionality shall be bound to `window.webeid`
## Bower
$ bower install --save web-eid
## Webpack & Browserify
$ npm install --save web-eid
And simply
webeid = require('web-eid');
### Note for IE users
IE 11 does not have [`Promise` support](http://caniuse.com/#search=promise), thus a polyfill is required.
# API
- All calls are asynchronous in nature and return a Promise
- While asynchronous, the API is still sequential - only one call can be serviced by a smart card (reader) at a time. If a call can not be serviced because this reason, the promise shall be rejected
- The `message` property of a rejected promise (an [Error](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error)) shall contain a symbolic error code that can be parsed
- Conformance to https://www.w3.org/2001/tag/doc/promises-guide is intended
## Note about API and stability
At this point of time no API stability is assured. Please note that if `window.hwcrypto` from [hwcrypto.js](https://github.com/hwcrypto/hwcrypto.js) is detected, `hwcrypto.getCertificate()` and `hwcrypto.sign()` are monkeypatched.
#### Timeouts
By default the execution time of a call depends on the underlying hardware and timeout is infinite. A timeout can be set for some calls, so that the operations that depend on user action would fail sooner (e.g. do not wait forever but fail in 2 minutes, if the user does not connect a card reader and insert a card in time) or set to `0` to get an instant error code. Please note that not all calls are cancelable on all platforms, due to unerlying platform limitations.
### `isAvailable`
```javascript
webeid.isAvailable(object options)
```
| parameter | type | |
|------------|-------------|---------------------------------|
| `options` | object | additional options (_optional_) |
| `options` | |
|-----------|-------------------------------------------------|
| `timeout` | timeout in seconds or `Infinity`. Default is `0`|
- resolves to `false` if client software is not available or to a string that describes the connection type of the application (`webextension` or `websocket`)
- if `false`, the recommended action is to display a notice with a link to https://web-eid.com
- if called with `timeout = Infinity`, the recommended action is to display a dynamic notice during the call that asks the user to install or start the client app
- recommended use: guard function before dynamicallly showing login button; general client availability check before calling rest of the API etc
## PKI operations
If a PKI call fails, the promise shall be rejected with an `Error` object, which `message` property shall be a string from [CKR_* series](http://docs.oasis-open.org/pkcs11/pkcs11-base/v2.40/pkcs11-base-v2.40.html#_Toc385057886) (PKCS#11, CNG/CryptoAPI return codes are mapped)
### `authenticate`
```javascript
webeid.authenticate(string nonce, object options)
```
| parameter | type | |
|------------|-------------|--------------------------------------|
| `nonce` | string | nonce for the session (**required**) |
| `options` | object | additional options (_optional_) |
| `options` | |
|-----------|--------------------------------------------------------|
| `timeout` | timeout in seconds or `Infinity`. Default is `Infinity`|
- resolves to a `string` containing the JWT token. JWT token description: https://github.com/martinpaljak/x509-webauth/wiki/OpenID-X509-ID-Token
- possible reasons for rejection: timeout or user cancels authentication, no certificates available, some other technical error
- used certificate is available in the `x5c` header field of the JWT token.
- expected behavior: user is instructed though the process of attaching a reader and a card, if necessary
- possible changes: resolving to `undefined` when no certificates are available
### `getCertificate`
```javascript
webeid.getCertificate(object options)
```
| parameter | type | |
|------------|-------------|---------------------------------|
| `options` | object | additional options (_optional_) |
| `options` | |
|-----------|--------------------------------------------------------|
| `filter` | type of certificate to return. Default is `sign` |
| `timeout` | timeout in seconds or `Infinity`. Default is `Infinity`|
- resolves to an `ArrayBuffer` with the certificate
- intended to be used with the following `webeid.sign()` operation
- expected behavior: user is instructed though the process of attaching a reader and a card, if necessary
- possible reasons for rejection: user cancels certificate selection, no certificates available, some other technical error
- possible changes: resolving to `undefined` when no certificates available
### `sign`
```javascript
webeid.sign(ArrayBuffer certificate, ArrayBuffer hash, object options)
```
| parameter | type | |
|---------------|-------------|-----------------------------------|
| `certificate` | ArrayBuffer | certificate to use (**required**) |
| `hash` | ArrayBuffer | hash to sign (**required**) |
| `options` | object | additional options (_optional_) |
| `options` | |
|------------|--------------------------------------------------------|
| `hashalgo` | hash algorithm type (`"SHA-256"` etc). (**required**) |
| `timeout` | timeout in seconds or `Infinity`. Default is `Infinity`|
- resolves to a `ArrayBuffer` containing the signature of the `hash` parameter (ArrayBuffer) generated with the private key belonging to the `certificate` (ArrayBuffer). Hash type is specified in `options.hashalgo` (`string`) and is one of "SHA-256", "SHA-384", "SHA-512"
- possible reasons for rejection: user cancels/refuses signing, user PIN is blocked, some other technical error
- possible changes: support for "last round on card" hashing
## WebSocket operations
### `authenticatedWebSocket`
```javascript
webeid.authenticatedWebSocket(string url, object options)
```
| parameter | type | |
|---------------|-------------|-----------------------------------|
| `url` | string | URL to connect to (**required**) |
| `options` | object | additional options (_optional_) |
| `options` | |
|---------------------|------------------------------------------------------------|
| `autoclose` | set to `true` to close the socket when the card is removed |
| `timeout` | timeout in seconds or `Infinity`. Default is `Infinity` |
- the first message from the service MUST be JSON and MUST contain the nonce `{"nonce": "noncevalue"}`
- `authenticate()` is called with the nonce
- the authentication token is sent back to the service as JSON `{"token": "authenticationtoken"}`
- promise is resolved with the WebSocket object
- if a card remove event is detected and autoclose is enabled, the socket is closed
## PC/SC operations
- if rejected, the message of the Error object for PC/SC operations shall be a [PC/SC API error code](https://pcsclite.alioth.debian.org/api/group__ErrorCodes.html) as a string (e.g. `"SCARD_E_NOT_TRANSACTED"`)
### `connect`
```
webeid.connect(object options)
```
| parameter | type | |
|------------|-------------|---------------------------------|
| `options` | object | additional options (_optional_) |
| `options` | |
|-----------|--------------------------------------------------------|
| `atrs` | list of expected ATR-s in base64. Default is `[]` |
| `protocol`| protocol to use (`T=0`, `T=1`, `*`. Default is `*` |
| `timeout` | timeout in seconds or `Infinity`. Default is `Infinity`|
- resolves to a `Reader` object
- `name` - `string` - name of the reader
- `protocol` - `string` - protocol of the connection (`T=0` or `T=1`)
- `atr` - `ArrayBuffer` - ATR of the card, as reported by the host PC/SC API
- `transmit(ArrayBuffer)` - `function` - transmits the APDU to the card, returns a Promise that resolves to the response
- `disconnect()` - `function`- disconnects the card, returns a Promise
- `reconnect(string protocol)` - `function` - reconnects with the specified protocol, returns a Promise
- equivalent for [`SCardConnect`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379474(v=vs.85).aspx) in the PC/SC API
- `SCardConnect` is called with `SCARD_SHARE_EXCLUSIVE` or if it is not possible, with `SCARD_SHARE_SHARED` and a `SCardBeginTransaction()` on non-Windows machines
### `Reader.transmit(bytes)`
- resolves to `ArrayBuffer` of the response
- equivalent of [`SCardTransmit`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379804(v=vs.85).aspx) in PC/SC API
- resembles [transmitRaw](https://globalplatform.github.io/WebApis-for-SE/doc/#dom-channel-transmitraw), without the tidbits of channels or `61XX`/`6CXX` handling
- comparable for [transceive()](https://developer.android.com/reference/android/nfc/tech/IsoDep.html#transceive(byte[])) in Android IsoDep API
### `Reader.control(code, bytes)`
- resolves to `ArrayBuffer` of the response
- equivalent for [`SCardControl`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379474(v=vs.85).aspx) in PC/SC API
### `Reader.reconnect(protocol)`
- resolves to `true`. `Reader` object properties `protocol` and `atr` might have changed
- equivalent for [`SCardReconnect`](hhttps://msdn.microsoft.com/en-us/library/windows/desktop/aa379797(v=vs.85).aspx) in PC/SC API
### `Reader.disconnect()`
- equivalent for [`SCardDisconnect`](https://msdn.microsoft.com/en-us/library/windows/desktop/aa379475(v=vs.85).aspx) in PC/SC API
- `SCardDisconnect` is called with `SCARD_RESET_CARD` argument
## Error codes
- `SCARD_E_READER_UNAVAILABLE` - if `webeid.connect()` has not been called or the reader has disappeared
- `SCARD_E_SHARING_VIOLATION` - if `webeid.connect()` can not establish a reliable (no interference from other applications on the computer) connection to the card