keynub_licdongle 1.1.1
keynub_licdongle: ^1.1.1 copied to clipboard
Client for the KeyNub USB license dongle: verify that a dongle is genuine, read and write its license records, use its counters and encrypt data so that only a dongle can decrypt it. Pure Dart over th [...]
KeyNub License Dongle — Dart package #
import 'package:keynub_licdongle/keynub_licdongle.dart';
final ctx = Context();
final dongle = ctx.open(); // first dongle, or ctx.open(serial: ...)
dongle.verifyGenuine(); // throws unless genuine
final data = dongle.withSession((s) => // closed on every exit path
s.appDecrypt(sealed)); // <- build the licence check on this
dongle.close();
ctx.close();
Pure Dart. The package is dart:ffi over the SDK's C library, and the
library is loaded at run time, so there is no build step, no plugin glue and
nothing in the path of the check that a customer could substitute. It works in
Dart command-line programs and in Flutter desktop applications on Windows,
Linux and macOS alike; package:ffi is the one dependency, for memory the C
side reads.
Setup #
dart pub add keynub_licdongle
The package does not carry the native library. Take keynub_licdongle for
your platform from the SDK's
natives folder
and either put it where the operating system finds libraries (next to the
executable, or on PATH, LD_LIBRARY_PATH, DYLD_LIBRARY_PATH), or name it
before the first call:
LicDongleLibrary.path = '/opt/keynub/libkeynub_licdongle.so';
KEYNUB_LICDONGLE_LIBRARY in the environment does the same. In a clone of the
SDK repository the package finds natives/<platform>/ on its own, from the
script's directory and the working directory upwards, so the samples run with
nothing set. A process loads the library once; LicDongleLibrary.loadedPath
tells which. For a Flutter application, bundle the library with the platform
build (the Windows and Linux runners take it as a CMake install target, macOS
as a framework or dylib in the bundle) and set LicDongleLibrary.path from
Platform.resolvedExecutable. On Linux, install the udev rule described in
NATIVES.md
so the dongle is accessible without root.
Notes #
- Results are plain classes (
Info,GenuineResult,DeviceInfo,RecordInfo); byte data isUint8List, and every call taking bytes also takes aStringfor its UTF-8. The C structures aredart:ffiStructs whose field types mirror the header, so Dart computes the padding. - Failures throw
LicenseDongleErrorwithstatus(Status.noDevice,.notGenuine,.authRequired, ...),operationanddetail; loading problems throwLibraryLoadError. dongle.isGenuineis the non-throwing form for a gate and fails closed.dongle.withSession((s) => ...)closes the session afterwards, whatever happens;openSession()gives aSessionto close yourself.readRecordandwriteRecordtakeprogress: (done, total) => bool; returningfalsecancels. An exception thrown inside the callback cancels the transfer and is rethrown after the C frames have unwound, never through them.eraseAllRecords()is deliberately separate fromeraseRecord(name): to the C library a null name means "erase every record", and an accidentally empty string must not do that.- Close what you open: a context closes the dongles still open on it, and a dongle closes when its context does.
Read
docs/integration-security.mdbefore writing the check.if (!dongle.isGenuine) exit(1)is one line to delete, and a Dart or Flutter application ships as an AOT snapshot that tools read well enough to find it. Route something the program needs throughappEncrypt/appDecrypt, so removing the check removes the data.
Tests #
dart test runs without a dongle: it compiles a stand-in for the C ABI
(bindings/julia/test/stub/licd_stub.c of the SDK repository) with a C
compiler from the path and exercises every call against it.
Links #
- KeyNub License Dongle for Dart and Flutter: the product, and how to order one
- Source, samples and issue tracker on GitHub
- Native library for your platform