Apache-2.0 licensed by KeyNub
Maintained by [email protected]
This version can be pinned in stack with:keynub-licdongle-1.1.1@sha256:b092f95166712f0a2cb07c11e202415d532c43669a91fe17246bd2b6857199f1,1839

Module documentation for 1.1.1

KeyNub License Dongle — Haskell package

import KeyNub.LicDongle

main :: IO ()
main = withDongle open $ \d -> do            -- first dongle, or openSerial "..."
  _ <- verifyGenuine d                        -- throws unless genuine
  secret <- withSession d $                   -- closed on every exit path
    appDecrypt d sealed                       -- <- build the licence check on this
  ...

Pure Haskell. The package calls the SDK’s flat companion API through function pointers resolved at run time, so nothing is linked at build time, there is no C to compile and nothing sits in the path of the check that a customer could substitute. base, bytestring, directory, filepath and the platform’s loader package (unix, or Win32 on Windows) are the dependencies. GHC 9.4 or later, on Windows, Linux and macOS.

Setup

cabal install keynub-licdongle

or keynub-licdongle in build-depends. 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:

setLibraryPath "/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 process loads the library once; loadedLibraryPath tells which. On Linux, install the udev rule described in NATIVES.md so the dongle is accessible without root.

Notes

  • Results are records (Info, GenuineResult, Device, RecordInfo); byte data is ByteString. The package calls the SDK’s flat API: integer handles and caller-provided buffers, no C structures and no hand-written layouts.
  • Failures throw LicDongleError with errorStatus (NoDevice, NotGenuine, AuthRequired, …), errorCode, errorOperation and errorDetail; loading problems throw LibraryError.
  • isGenuine is the non-throwing form for a gate and fails closed: every failure gives False.
  • withDongle and withSession are brackets: the dongle and the session are closed on every exit path, exceptions included.
  • eraseAllRecords is deliberately separate from eraseRecord: an accidentally empty name must not wipe the dongle.
  • Records are transferred in one call; the flat API has no progress reporting.

Read docs/integration-security.md before writing the check. ok <- isGenuine d; unless ok exitFailure is one conditional branch, and patching one of those in a release binary is a beginner exercise. Route something the program needs through appEncrypt and appDecrypt, so removing the check removes the data.

Tests

cabal 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. In a package taken from Hackage the SDK sources are not present; point KEYNUB_SDK_ROOT at a clone, or KEYNUB_LICDONGLE_FLAT_LIBRARY at a compiled stand-in.

Links

Changes

1.1.1

  • First release on Hackage, at the version of the SDK it belongs to.