KeyNub License Dongle — Elixir package

alias KeyNub.LicDongle
{:ok, secret} =
LicDongle.with_dongle(fn d -> # first dongle, or with_dongle("serial", fn ...)
LicDongle.verify_genuine!(d) # raises unless genuine
LicDongle.with_session!(d, fn -> # closed on every exit path
LicDongle.app_decrypt!(d, sealed) # <- build the licence check on this
end)
end)

A small NIF, nothing linked. The package calls the SDK's flat companion API through a NIF of two hundred lines (c_src/) that loads the native library at run time and resolves the functions by name, so nothing is linked at build time and nothing sits in the path of the check that a customer could substitute. The NIF is compiled when the package is (elixir_make: a C compiler on Linux and macOS, Visual C++ with nmake on Windows). Every dongle call runs on a dirty I/O scheduler. Elixir 1.13 or later, on Windows, Linux and macOS.

Setup

def deps do
[{:keynub_licdongle, "~> 1.1"}]
end

The package does not carry the native library. Take keynub_licdongle_flat 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:

KeyNub.LicDongle.set_library_path("/opt/keynub/libkeynub_licdongle_flat.so")

KEYNUB_LICDONGLE_FLAT_LIBRARY in the environment does the same. In a clone of the SDK repository the package finds natives/<platform>/ on its own, from the working directory upwards, so the samples run with nothing set. A VM loads the library once; loaded_library_path/0 tells which. On Linux, install the udev rule described in NATIVES.md so the dongle is accessible without root.

Notes

Read docs/integration-security.md before writing the check. unless LicDongle.genuine?(d), do: System.halt(1) is one conditional branch, and patching one of those in a release binary is a beginner exercise. Route something the program needs through app_encrypt/3 and app_decrypt/2, so removing the check removes the data.

Tests

mix test runs without a dongle: it compiles a stand-in for the flat C API (bindings/flat/licd_flat.c over bindings/julia/test/stub/licd_stub.c) with the C compiler on the path and exercises every call against it. KEYNUB_SDK_ROOT names the SDK sources when the package is not inside a clone; KEYNUB_LICDONGLE_FLAT_LIBRARY names a compiled stand-in instead.