Skip to content

Software License Dongle for Rust

The Rust binding is a safe wrapper over the same C ABI, with the unsafe FFI surface kept in one place rather than spread through your code.

crates.io version badge

cargo add keynub-licdongleCode language: Bash (bash)
use keynub_licdongle::Context;

let ctx = Context::new()?;
let dongle = ctx.open(None)?;            // first dongle, or Some("serial")
dongle.verify_genuine()?;                // errors unless genuine

let session = dongle.open_session()?;
let license: Vec<u8> = session.read_record("license")?;
// Drop closes the session, then the dongle, then the context.Code language: Rust (rust)

Fallible calls return Result, so the error paths are the ones the compiler already makes you handle, and Drop closes the device without a cleanup path to forget.

One Exception to the Result Pattern

is_genuine returns a plain bool rather than Result<bool>: a licence gate should fail closed when no dongle is present, not force you to decide what an error means at every call site.

And the rule that matters in every language: do not branch on a boolean. Encrypt data your program needs with appEncrypt at build time and decrypt it through the dongle at run time, so removing the check leaves the program with nothing to compute rather than a working unlicensed copy.

No Dependencies Beyond Std

The crate pulls in nothing but the standard library. A licensing crate is the last place you want a transitive dependency tree: each crate in it is another maintainer who can publish a release that changes what your check does, and another item for whoever signs off your build.

Lifetimes also carry weight here that the other bindings have to enforce at run time. A session borrows the dongle it came from and a dongle borrows its context, so the destructor ordering that would let a session outlive its device is not a bug you can write – it does not compile.

Shipping the Native Library with a Rust Application

The keynub-licdongle crate links the core library through its build script: KEYNUB_LIB_DIR names the folder with the platform’s library, and the crate has no dependencies beyond std. By default the shared library is linked and must be findable at run time, as for any other; KEYNUB_STATIC=1 links the static library and its platform dependencies instead, which gives one self-contained executable with nothing to deploy beside it.

Static linking is the usual choice for a shipped Rust product, and it removes the file a customer could otherwise swap. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.

Questions Rust Developers Ask

Which Rust Versions Does the Binding Support?

Rust 1.70 and later, edition 2021, on Windows, Linux and macOS, with no dependencies beyond the standard library.

Can the Dongle Library Be Linked Statically into a Rust Binary?

Yes. Set KEYNUB_STATIC=1 when building and the crate links keynub_licdongle_static together with the platform libraries it needs; the executable then has no run-time dependency on a shared library.

Does a Rust Application Need Administrator Rights to Talk to the Dongle?

No, and no driver either: the dongle is a USB HID device that the operating systems handle with their built-in class drivers. On Linux, install the shipped udev rule once so that ordinary users may open it; without the rule the SDK reports access denied and names the cause in its error detail.

Does a Rust License Check Need an Internet Connection?

No. Verification is a local exchange between your program and the dongle over USB: the SDK checks the dongle’s certificate chain to KeyNub’s root and runs a live challenge-response. There is no activation server and no account, so the check works on air-gapped machines.

Does It Run on ARM: Windows on ARM, Apple Silicon, aarch64 Linux?

Yes. The SDK ships native libraries for Windows x64, x86 and ARM64, Linux x86_64 and aarch64, and universal macOS binaries for Intel and Apple silicon.

Can a License Written from Rust Be Read by a Program in Another Language?

Yes. Every binding drives the same core library and the same dongle, and records and sealed data are language-neutral bytes. Your issuing tool can be written in one language and your product in another.

Code

Runnable sample: rust/verify_and_read. Binding source: bindings/rust. Both are Apache-2.0, in the public SDK repository; the prebuilt native libraries are in the repository’s natives/ folder, one per platform.

All supported languages · All industries · Buy a KeyNub · Ask us something