Skip to content

Software License Dongle for Common Lisp

Common Lisp reaches the dongle through the SDK’s flat C API with CFFI, loading the native library at run time on the first call, so nothing is linked and nothing sits in the path of the check that a customer could substitute for something more agreeable. Loading the system needs no library, and it depends on cffi only. The ASDF system keynub-licdongle, SBCL 2.1.11 or later, on Windows, Linux and macOS.

;; from a clone of the SDK repository
(push #p"/path/to/KeyNub-SDK/bindings/common-lisp/" asdf:*central-registry*)
(ql:quickload "keynub-licdongle")Code language: Lisp (lisp)

Reading a License

(defvar *license*
  (licdongle:with-dongle (d)              ; first dongle, or (d :serial "...")
    (licdongle:dongle-verify-genuine d)   ; signals unless genuine
    (licdongle:with-session (d)           ; closed on every exit path
      (licdongle:read-record d "license"))))Code language: Lisp (lisp)

What You Are Protecting

Common Lisp software that is sold ships as a saved image or an executable from save-lisp-and-die: a design or engineering tool, a planning system, a rules engine on a customer’s server. A check that returns t or nil is one conditional in that image, and patching one of those is a beginner exercise.

So the strong pattern is the one to reach for: the data the program needs only exists when the dongle is present.

;; Weak: one patched branch.
(unless (licdongle:dongle-genuine-p d) (uiop:quit 1))

;; Strong: the parameters only exist with the dongle present.
(defvar *parameters*
  (licdongle:with-session (d)
    (decode-parameters
     (licdongle:app-decrypt d *sealed-blob-shipped-with-your-program*))))Code language: Lisp (lisp)

Every failed call signals licdongle-error with the status (:no-device, :not-genuine, :auth-required, …), the raw code, the operation and the library’s detail, and a library that cannot be loaded signals licdongle-library-error; dongle-genuine-p fails closed. with-dongle and with-session release the dongle and the session on every exit path, non-local exits included. The system calls the SDK’s flat companion API, the one designed for foreign function interfaces: integer handles and buffers, no hand-written structure layouts.

Shipping the Native Library with a Common Lisp Application

The keynub-licdongle system calls the SDK’s flat API through CFFI from the library it loads at run time, on the first call, so loading the system needs no library and nothing is linked. A saved image or an executable takes keynub_licdongle_flat for its platform in natives/<platform>/ beside it, or names it with licdongle:set-library-path or KEYNUB_LICDONGLE_FLAT_LIBRARY; the system also looks in natives/ above the program, the current directory and its own folder, then asks the system loader.

The prebuilt libraries for every platform are in the SDK repository’s natives/<platform>/ folder, with a SHA-256 manifest: Windows x64, x86 and ARM64, Linux x86_64 and aarch64, and universal macOS binaries for Intel and Apple silicon. On Linux, install the udev rule from NATIVES.md once, so that ordinary users may open the device.

Questions Common Lisp Developers Ask

Which Common Lisp Versions Does the System Support?

SBCL 2.1.11 and later, on Windows, Linux and macOS. The system depends on cffi only, with the babel and uiop that cffi brings along.

How Do I Load the Common Lisp System from a Clone?

Put bindings/common-lisp/ where ASDF looks, as a link in ~/quicklisp/local-projects/ or by pushing the folder onto asdf:*central-registry*, and load it with ql:quickload or asdf:load-system. ASDF has to find cffi, as it does once Quicklisp is loaded.

Does a Common Lisp 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 Common Lisp 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.

Who Can Read the License Records on a Dongle?

Anyone holding the dongle: a program opens a session and reads records, and can decrypt data sealed for that dongle. Writing records, erasing them and incrementing counters need your write key. What the dongle guarantees is that none of it is available without the dongle present.

Can a License Written from Common Lisp 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: common-lisp/verify-and-read.lisp. Binding source: bindings/common-lisp. 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