Getting Started with LIMAN SDK
1. Download the Distribution
Obtain the distribution file specific to your platform from our Downloads page. Available platforms:
| OS | Platform | Format | Filename |
|---|---|---|---|
| Windows 32-bit | win32x86 | Static (.lib) | liman_core-x.y.z-win32x86.tar.gz |
| Windows 64-bit | win64x86 | Static (.lib) | liman_core-x.y.z-win64x86.tar.gz |
| Windows 32-bit (MinGW) | mingw32 | Static (.a) | liman_core-x.y.z-mingw32.tar.gz |
| Windows 64-bit (MinGW) | mingw64 | Static (.a) | liman_core-x.y.z-mingw64.tar.gz |
| Linux 64-bit | linux64x86 | Static (.a) | liman_core-x.y.z-linux64x86.tar.gz |
| Linux 64-bit ARM | linux64arm | Static (.a) | liman_core-x.y.z-linux64arm.tar.gz |
| macOS 64-bit | osx64x86 | Static (.a) | liman_core-x.y.z-osx64x86.tar.gz |
| macOS 64-bit ARM (Apple Silicon) | osx64arm | Static (.a) | liman_core-x.y.z-osx64arm.tar.gz |
2. Extract and Setup
The following example assumes a 64-bit Linux installation. For other platforms, the steps are identical except for the filename.
Copy the distribution file to your installation directory:
$ cp liman_core-x.y.z-linux64x86.tar.gz /opt
Change to the installation directory and extract:
$ cd /opt $ tar -xzvf liman_core-x.y.z-linux64x86.tar.gz
Change to the platform library directory:
$ cd liman-x.y.z/lib/linux64x86
3. Generate Your Key Pair
Use limutil to generate a product-license-base consisting of:
- A product identifier (up to 12 characters)
- An RSA keypair (configurable key size) also referred to as product-specific keypair
Build the utility and generate a keypair for your product:
$ make limutil $ ./limutil --genkey --keysize=2048 --product=TESTAPP Product-id is 'TESTAPP'. Written private key in TESTAPP/TESTAPP_private.key. Written public key in TESTAPP/TESTAPP_public.key. Written private key as C/C++ code in TESTAPP/TESTAPP_private_key.c. Written public key as C/C++ code in TESTAPP/TESTAPP_public_key.c.
This creates a TESTAPP/ subdirectory containing:
| File | Description |
|---|---|
TESTAPP_private.key |
Product-specific private key (hex format) - keep secure, used to generate licenses |
TESTAPP_public.key |
Product-specific public key (hex format) - for runtime key loading |
TESTAPP_private_key.c |
Product-specific private key as C code - for license generator builds |
TESTAPP_public_key.c |
Product-specific public key as C code - compiled into product-specific SDK |
Run ./limutil --help to see all available options including host ID queries and custom key sizes.
4a. Build the Product-Agnostic Core SDK
Build the core LIMAN SDK - a product-agnostic library where product-specific public keys are loaded at runtime from files.
A LIMAN SDK license is required. Once obtained from info@baroks.com, copy it to ../../license/ (i.e., liman-x.y.z/license/) and build:
$ make
This creates:
| File | Description |
|---|---|
libliman_sdk.a |
Static library - product specific public key needs to be loaded via lim_read_public_key() |
libliman_sdk.so |
Shared library - product specific public key needs to be loaded via lim_read_public_key() |
limgen |
License generator utility |
ahostid |
Host ID utility |
Use libliman_sdk.a when building multi-product license management systems or when you prefer to load public keys from files at runtime.
4b. Build the Product-Specific Library
For application deployment, build a product-specific library with the product-specific public key (e.g. TESTAPP_public_key.c) compiled in. This eliminates the need for loading product-specific public key files and improves security.
$ make PRODUCT=TESTAPP product
This creates in the TESTAPP/ subdirectory:
| File | Description |
|---|---|
libliman_TESTAPP_sdk.a |
Static library with TESTAPP public key embedded |
libliman_TESTAPP_sdk.so |
Shared library with TESTAPP public key embedded |
Each product requires its own library. Do not reuse keypairs across products.
5a. Integration with Product-Specific Library
When using the product-specific library (built in step 4b), the public key is already embedded. Your code does not need to load the key file:
#include "liman.h"
int main() {
int err;
// Create environment with your key size and hash algorithm
pLIMENV env = lim_create_env(2048, 256, &err);
if (!env) {
printf("Failed to create environment: %d\n", err);
return 1;
}
// NOTE: No lim_read_public_key() call needed!
// The public key is already compiled into libliman_TESTAPP_sdk.a
// Load and verify a license file
pLIMLIC lic = lim_create_lic_fromfile(env, "license.key", &err);
if (!lic) {
printf("Invalid license: %d\n", err);
return 1;
}
// Check if license is valid
if (lim_is_verified(lic) && lim_assert_valid(lic) == LIM_OK) {
printf("License is valid!\n");
printf("Days to expiry: %d\n", lim_days_to_expiry(lic));
}
// Cleanup
lim_free_lic(&lic);
lim_free_env(&env);
return 0;
}
The product-specific library is the recommended approach for deployed applications. The embedded key cannot be easily extracted or replaced, improving security.
5b. Integration with Product-Agnostic Library
When using the product-agnostic library (built in step 4a), you must load the public key file at runtime using lim_read_public_key():
#include "liman.h"
int main() {
int err;
// Create environment with your key size and hash algorithm
pLIMENV env = lim_create_env(2048, 256, &err);
if (!env) {
printf("Failed to create environment: %d\n", err);
return 1;
}
// REQUIRED: Load the product-specific public key from file
// This step is mandatory when using libliman_sdk.a (product-agnostic)
err = lim_read_public_key(env, "TESTAPP/TESTAPP_public.key");
if (err != LIM_OK) {
printf("Failed to load public key: %d\n", err);
return 1;
}
// Load and verify a license file
pLIMLIC lic = lim_create_lic_fromfile(env, "license.key", &err);
if (!lic) {
printf("Invalid license: %d\n", err);
return 1;
}
// Check if license is valid
if (lim_is_verified(lic) && lim_assert_valid(lic) == LIM_OK) {
printf("License is valid!\n");
printf("Days to expiry: %d\n", lim_days_to_expiry(lic));
}
// Cleanup
lim_free_lic(&lic);
lim_free_env(&env);
return 0;
}
Do not mix approaches! If you link against libliman_sdk.a (product-agnostic) but forget to call lim_read_public_key(), license verification will fail. Conversely, if you link against libliman_TESTAPP_sdk.a (product-specific), calling lim_read_public_key() is unnecessary and the key file path is ignored.
Use this approach when building multi-product license management systems, development/testing tools, or when you need to switch between products at runtime without recompiling.
6a. Compile and Link (Product-Specific Library)
Link against the product-specific library (libliman_TESTAPP_sdk.a) for the code in section 5a:
# Linux/macOS (static) gcc -o myapp myapp.c -I./include ./lib/linux64x86/TESTAPP/libliman_TESTAPP_sdk.a -lm # Linux/macOS (shared) gcc -o myapp myapp.c -I./include -L./lib/linux64x86/TESTAPP -lliman_TESTAPP_sdk -lm # Windows (MSVC) cl myapp.c /I include lib\win64x86\TESTAPP\liman_TESTAPP_sdk.lib # Windows (MinGW) gcc -o myapp.exe myapp.c -I./include ./lib/mingw64/TESTAPP/libliman_TESTAPP_sdk.a -lm
6b. Compile and Link (Product-Agnostic Library)
Link against the product-agnostic library (libliman_sdk.a) for the code in section 5b:
# Linux/macOS (static) gcc -o myapp myapp.c -I./include ./lib/linux64x86/libliman_sdk.a -lm # Linux/macOS (shared) gcc -o myapp myapp.c -I./include -L./lib/linux64x86 -lliman_sdk -lm # Windows (MSVC) cl myapp.c /I include lib\win64x86\liman_sdk.lib # Windows (MinGW) gcc -o myapp.exe myapp.c -I./include ./lib/mingw64/libliman_sdk.a -lm
When deploying with the product-agnostic library, you must distribute the public key file (TESTAPP_public.key) alongside your application and ensure it is accessible at runtime.
7. License Generation and Distribution
The license generator limgen (built in step 4a) creates signed license files for your customers.
Floating License (No Hardware Lock)
For licenses that work on any machine:
$ ./limgen --product=TESTAPP --major=1 --minor=0 \
--serial=123456 --expiry=20261231 \
--privkeyfile=TESTAPP/TESTAPP_private.key \
--pubkeyfile=TESTAPP/TESTAPP_public.key
Node-Locked License (Hardware Bound)
For licenses tied to a specific machine, your customer must generate their host ID. Provide them with limutil (built in step 3) or include it with your application installer.
Step 1: Customer runs limutil on their target machine with your chosen host ID mask:
$ ./limutil --hostid=35 Host ID: 7A3F2E1D9C8B5A4F...
Depending on the host ID components selected, limutil may require elevated privileges (administrator/root) to access hardware identifiers such as CPU ID, Disk ID, or DMI/WMIC information.
The mask determines which hardware identifiers comprise the host ID:
| Bit | Value | Identifier |
|---|---|---|
| 0 | 1 | CPU ID |
| 1 | 2 | Disk ID |
| 2 | 4 | Hostname |
| 3 | 8 | User ID |
| 4 | 16 | DMI/WMIC |
| 5 | 32 | MAC address (1st) |
| 6 | 64 | MAC address (2nd) |
| 7 | 128 | MAC address (3rd) |
| 8 | 256 | MAC address (4th) |
Example: --hostid=35 combines CPU ID (1) + Disk ID (2) + MAC address (32) = 35.
Step 2: Customer emails you their host ID string.
Step 3: Generate the node-locked license using the same mask:
$ ./limgen --product=TESTAPP --major=1 --minor=0 \
--serial=123456 --expiry=20261231 \
--hostid=7A3F2E1D9C8B5A4F... --hostmask=35 \
--privkeyfile=TESTAPP/TESTAPP_private.key \
--pubkeyfile=TESTAPP/TESTAPP_public.key
The --hostmask value in license generation must match the mask your customer used when computing their host ID. Mismatched masks will cause license validation to fail.
Step 4: Send the generated license file to your customer.
Next Steps
- Read the API Reference for detailed documentation
- Learn about feature bitmasks for tiered licensing
- Contact info@baroks.com for support