Verify that a KeyNub dongle is genuine, read and write the license records
it holds, use its hardware counters and seal data so that only a dongle can
open it.
The pack calls the SDK's flat C API (keynub_licdongle_flat) from the
native library, which its foreign module loads at run time on the first
call that needs it. Loading this module does not need the native library.
- Every failed call throws
error(keynub_error(Status, Code, Operation,
Detail), _): Status is an atom such as no_device, not_genuine or
auth_required (unknown for a code this pack does not know), Code the
raw status code, Operation the flat API function and Detail the
library's diagnostic text, which may be empty. A library that cannot be
loaded throws error(keynub_library_error(Message), _).
- Byte data (records, keys, sealed data) is a list of codes 0..255, as
read_file_to_codes/3 with
type(binary) returns it. Input may also be a
string or atom whose characters are all below 256.
- Text from the dongle (serials, device paths, record names, detail) is a
string; text input may be an atom, string or code list. Library file
paths are atoms.
- library_environment_variable(-Name) is det
- The environment variable that names the library file.
- library_basename(-File) is det
- The library's file name on this operating system.
- set_library_path(+Path) is det
- Names the library file to load. Call it before the first dongle call.
A process loads the library once; naming a different file after that
throws
error(keynub_library_error(Message), _).
- loaded_library_path(-Path) is semidet
- The path the library was loaded from. Fails before the first call that
loads it.
- library_path(-Path) is det
- The path in use, or the first candidate while nothing is loaded.
- library_candidates(-Paths) is det
- The paths tried, in order: the path given to set_library_path/1, else
the file named by KEYNUB_LICDONGLE_FLAT_LIBRARY, else every
natives/<platform>/<file> found in the program's folder, the working
directory or this module's folder or one of their parents, followed by
the bare file name for the system loader.
- library_version(-Version) is det
- The native library's version as
version(Major, Minor, Patch).
- status_name(?Code, ?Name) is nondet
- Name is the atom for the status code Code (
licd_status in the SDK's C
header).
- status_text(+Code, -Text) is det
- Human-readable text for a status code, as a string; needs no dongle.
- devices(-Devices) is det
- The attached dongles, as a list of
device(Serial, Path).
- is_dongle(@Term) is semidet
- True when Term is a dongle from dongle_open/1,2 or dongle_open_path/2,
open or closed.
- dongle_open(-Dongle) is det
- dongle_open(+Serial, -Dongle) is det
- Opens the dongle with this serial, or the first one found when Serial
is empty or not given. The dongle is closed by dongle_close/1, or when
it is garbage collected.
- dongle_open_path(+Path, -Dongle) is det
- Opens the dongle at this device path (from devices/1).
- dongle_is_open(+Dongle) is semidet
- True when dongle_close/1 has not been called on Dongle yet.
- dongle_close(+Dongle) is det
- Closes the dongle. Closing it again does nothing; other calls on it
throw a keynub_error with status
invalid_arg.
- with_dongle(-Dongle, :Goal) is semidet
- with_dongle(+Options, -Dongle, :Goal) is semidet
- Opens a dongle, calls Goal as once/1 and closes the dongle on every
exit path, exceptions included. Options select the dongle:
serial(Serial) or path(Path); without either, the first one found.
- dongle_serial(+Dongle, -Serial) is det
- The dongle's serial number (14 hex digits) as a string.
- dongle_info(+Dongle, -Info) is det
- Plaintext device information, as a dict with the keys
protocol_major, protocol_minor, firmware_major, firmware_minor,
firmware_patch and data_capacity, data_free (bytes), and the
booleans (true or false) secure_element_ready, provisioned,
watchdog_reboot, isolated and write_auth_rotated.
- dongle_verify_genuine(+Dongle) is det
- dongle_verify_genuine(+Dongle, -Serial, -ProvisionedDate) is det
- Proves the dongle is genuine: certificate chain to the trusted root
plus a live challenge-response. Succeeds only when it is and throws
otherwise. Serial is the verified serial; ProvisionedDate is the day
the unit was personalised ("YYYY-MM-DD"), or "" when it reports none.
- dongle_genuine(+Dongle) is semidet
- The test for a gate: succeeds only when dongle_verify_genuine/1
succeeds. Fails closed: every error makes it fail.
- set_dongle_trust_root(+Dongle, +Der) is det
- Overrides the CA root (DER bytes) that dongle_verify_genuine/1 checks
against. Applications do not need this: the library embeds the KeyNub
production root.
- dongle_last_error(+Dongle, -Detail) is det
- Diagnostic detail for the most recent failure on this dongle, as a
string; may be empty.
- session_open(+Dongle) is det
- Opens an authenticated session; records, counters and app encryption
need one.
- session_close(+Dongle) is det
- Closes the session.
- with_session(+Dongle, :Goal) is semidet
- Opens a session, calls Goal as once/1 and closes the session on every
exit path, exceptions included.
- authorize_write(+Dongle, +Key) is det
- Elevates the session to the write role with a write-auth key (P-256
PKCS#8 DER bytes).
- rotate_write_key(+Dongle, +Key) is det
- Replaces the dongle's write-auth key with Key (P-256 PKCS#8 DER
bytes). Call authorize_write/2 first. From the next session on, only
the new key elevates.
- dongle_records(+Dongle, -Records) is det
- The records on the dongle, as a list of
record(Name, Size).
- read_record(+Dongle, +Name, -Bytes) is det
- The content of a record, as a list of codes 0..255.
- write_record(+Dongle, +Name, +Bytes) is det
- Writes a record, replacing one of the same name. Needs the write role.
- erase_record(+Dongle, +Name) is det
- Erases the one record Name. Needs the write role.
- erase_all_records(+Dongle) is det
- Erases every record. Needs the write role.
- read_counter(+Dongle, +CounterId, -Value) is det
- The value of a hardware monotonic counter.
- increment_counter(+Dongle, +CounterId, -Value) is det
- Increments a counter and returns the new value. Needs the write role.
- app_encrypt(+Dongle, +Scope, +Plaintext, -Sealed) is det
- Seals Plaintext so that only a dongle can open it: this one (Scope
device) or any dongle issued by the same developer (Scope
developer). Sealed is a list of codes 0..255.
- app_decrypt(+Dongle, +Sealed, -Plaintext) is det
- Opens data sealed with app_encrypt/4. Plaintext is a list of codes
0..255.
Undocumented predicates
The following predicates are exported, but not or incorrectly documented.
- dongle_open(Arg1, Arg2)
- with_dongle(Arg1, Arg2, Arg3)
- dongle_verify_genuine(Arg1, Arg2, Arg3)