Javascript Libraries (CS)
The JavaScript libraries are designed to work with browser-based applications and facilitate communication with a SafeKey device. They're constructed using TypeScript and bundled with the parcel tool.
Source: https://github.com/SAFETECHio/SafeKey_Libs_JS
This is a pre-release. All is subject to change. Some of the files and settings are redundant/obsolete. Communication over FIDO2 was not thoroughly tested. The demo application should not be run with the production devices - it can destroy data stored there.
Configuration
Setting up on Linux OS
To use the device on the Udev-enabled Linux distributions, please install the Udev rules provided within the firmware repository. Otherwise access to the device might be forbidden. Debian-based distributions, including Ubuntu, need this. Fedora does not.
Device preparation
To log in to the CS session, a PIN has to be set first. It can be done using the
CS_PIN_SET()
function, and can be done only once per device's life-cycle. This is the only required operation to make device working with the Custom Storage. It can be done as well using FIDO2 actions (e.g. via the Windows 10 tool).Further PIN changes are done through
CS_PIN_CHANGE()
function, or proper FIDO2 command.Device can be reset to uninitialized state, with user data removed, by executing the
CS_FACTORY_RESET()
- then theCS_PIN_SET()
is required to be called once again.If the
CS_UNLOCK_GENERATE()
was called ever on the device, it starts operating in thePROTECTED
mode. This means, that CS data are no longer removed on the FIDO2 reset operation, and login is impossible until theCS_UNLOCK()
function is called with the previously generated passphrase (which are 16 bytes of random, device's HWRNG-sourced data). Please keep in mind, that device can never leave thePROTECTED
mode, once activated (with the current implementation).
Please refer to manual about the details of the commands' internals.
Development
Here is a brief guide for running the development setup.
Required tools installed: npm
.
Setup
To install all required npm
packages (while being in the main directory):
Run
To build the JavaScript sources, and run the local server to host them with the parcel
tool:
Error handling
On each error encountered, whether this is a browser, or device sourced, the library throws an Exception with a proper type, as in table below:
Exception type name | code property | source |
---|---|---|
|
| browser |
|
| device |
Cause is available indirectly by the Exception
message as well.
It is expected that both exception types are taken care by the caller of the library. Both have error code properties, which defines the cause. The browser's exception codes are described in detail here: Error codes.
The CommandExecutionError/ERR_USER_NOT_PRESENT
is handled by the library, by repeating the request asking user confirmation for 20 times, with 1 second delay in-between. This active polling is required, because device does not wait for the user to touch, and returns immediately without waiting for the user feedback. In the future device's firmware releases this might be changed to have the active loop on the device, if would prove to be more useful for the users.
The device's error codes are described in the technical manual for the SafeKey.
Common errors
These are the common errors returned by the library:
CommandExecutionError/ERR_USER_NOT_PRESENT
- this error shows up, when the user will not confirm the request for given command by pressing the touch button.CommandExecutionError/INVALID_PIN
- PIN is not set or invalid. The demo needs device to have PIN set up already. The demo actions should make sure the device is initialized.DOMException: "The request is not allowed by the user agent or the platform in the current context, possibly because the user denied permission."
orDOMException/NotAllowedError
(message from the Firefox, might be different on Chrome) - the browser main window was not the active one (on the foreground) during the communication, hence the requests were never sent to the device due to security policy. The same error is as well shown, when users press the cancel in the pop-up. Tabbing away to another windows also causes this exception, as it makes the browser denying the requests to the device.
Handling exceptions
Common code for handling errors is as follows:
Please refer to the API docs for all the error types to handle.
Source files description
./packaged.ts
- NPM package configuration for the SafeKey JS API distribution;./js/safekey.ts
- SafeKey JS API, meant to be used for the development;./js/cbor.d.ts
- CBOR Typescript definitions;./js/ext_storage.ts
- low-level internals: sending and receiving;./js/ctaphid.ts
- low-level internals: transport via the CTAP/Webauthn;./js/exceptions.ts
- device errors exception definition;./js/helpers.ts
- helper functions placeholder;./js/constants.ts
- constants: names and identifiers for errors and commands;./js/test.ts
- demo application tests implementation;./index.ts
- demo application running script.
Configuration used
Following is the configuration used during the development: - Fedora 29 - VS Code 1.39.2 - npm version 6.9.0 - Firefox 69.0.1 (64-bit) - Chromium Version 77.0.3865.90 (Developer Build) Fedora Project (64-bit)
Additionally following were tested (on Fedora 29): - Firefox Nightly 71.0a1 (2019-10-17) (64-bit) - Google Chrome Version 79.0.3941.4 (Official Build) dev (64-bit)
Repository contains configured debugging for both Firefox and Chromium for the VS Code - see .vscode/launch.json
path.
Demo application and common pitfalls
Please make sure the device is connected, and press the touch button of the device whenever the site will ask to do so.
Do not use production devices! All data on device should be consider lost or altered, including FIDO U2F / FIDO2 credentials.
Device can be initialized with a PIN only once per life-cycle - later PIN can be only changed, or the factory reset has to be called to get device back to 'uninitialized' state. For changing the PIN, please provide input in format: CURRPIN;NEWPIN
, that is current and new PIN should be divided by semicolon. Please do not use ';' character in your PIN, for the sake of the demo application usefulness (it is allowed otherwise). The PIN minimal length is 4 bytes, and maximum is 63. UTF-8 characters are allowed by FIDO2 specification (device accepts binary data).
Demo actions expect to have the PIN set to 01234567890123456. If the wrong PIN was used more than 3 times in the given power cycle, the device will stop accepting the requests, which might result in the DOMException-NotAllowed error. Please reinsert the device in such case. Device has a total of 8 invalid PIN attempts allowed, after which only a factory reset (either CS or FIDO2 action) could reinstate its working state.
Constantly pressing the touch button to accept all requests will not work. Each confirmation has to be done separately, with the finger releasing the touch button, and pressing again on each request. This is by design to not mass-confirm malicious requests.
Browser has to be constantly in the foreground during the action calls, or the requests to the device will be canceled by the browser, and the DomException error will be thrown.
Please note, that write/read tests (via the Run demo button) will fail on Chrome, since it sends requests to CS over FIDO2. Changing the PIN, and other non-data related commands will work though.
ERR_NOT_ALLOWED
error on LOGIN
action means, that the device is locked, either temporary for the current power-cycle, or permanently after using all PIN attempts, until FIDO2 factory reset will be called.
Using this library in another project
The packaged.ts
file is the entrypoint for this library. If you add new functionality that should be exposed in the library to users, please make sure to include the new functionality in the packaged.ts
file.
Last updated