LIMAN SDK Documentation
Introduction
This section provides an overview of the LIMAN SDK, instructions for getting started, sample applications, and details concerning contact and support information. It introduces two utility applications that illustrate:
- Generation of product-specific LIMAN library
- License generation for a specific product
Directory Structure
After a successful setup, the following directories will be created within the root directory of LIMAN SDK. Assuming liman-x.y.z is the root directory:
lib/<platform>- Product-agnostic LIMAN library (libliman_sdk.a/.so), utility executables, and jar files for Java applicationslib/<platform>/<product>- Product-specific LIMAN library (libliman_<product>_sdk.a/.so) with the product's public key embedded, plus keypair filesinclude- Header files defining function prototypes for different programming languageslicense- License file (e.g., usr_liman_lic.c) required to use LIMAN SDKapps/<lang>- Project and source files for sample applicationsdoc- Documentation files
You will need to generate a keypair and build a product-specific library for each product you want to protect. In a hypothetical 3-product business (PRODUCT_A, PRODUCT_B, PRODUCT_C), the directory structure would be:
lib/
linux64x86/
libliman_sdk.a # Product-agnostic library (static)
libliman_sdk.so # Product-agnostic library (shared)
limgen # License generator
limutil # Utility tool
ahostid # Host ID utility
PRODUCT_A/
PRODUCT_A_private.key # Keep secure - for license generation
PRODUCT_A_private_key.c
PRODUCT_A_public.key # For runtime key loading (if using product-agnostic)
PRODUCT_A_public_key.c
libliman_PRODUCT_A_sdk.a # Product-specific library (public key embedded)
libliman_PRODUCT_A_sdk.so
PRODUCT_B/
PRODUCT_B_private.key
PRODUCT_B_private_key.c
PRODUCT_B_public.key
PRODUCT_B_public_key.c
libliman_PRODUCT_B_sdk.a
libliman_PRODUCT_B_sdk.so
PRODUCT_C/
PRODUCT_C_private.key
PRODUCT_C_private_key.c
PRODUCT_C_public.key
PRODUCT_C_public_key.c
libliman_PRODUCT_C_sdk.a
libliman_PRODUCT_C_sdk.so
Each product must have its own unique keypair. Never reuse keypairs across different products. The private key must be kept secure and is only used by limgen to create licenses.
Library Types
LIMAN SDK provides two library variants to accommodate different deployment scenarios:
Product-Specific Library (Recommended)
Built with make PRODUCT=<name> product, this library has the product's public key compiled in.
| File | Description |
|---|---|
libliman_<PRODUCT>_sdk.a |
Static library with embedded public key |
libliman_<PRODUCT>_sdk.so |
Shared library with embedded public key |
Advantages:
- No external key file required at runtime
- Better security - key cannot be easily replaced
- Simpler deployment - single library file
Usage: Link directly against the library. No lim_read_public_key() call needed.
Product-Agnostic Library
Built with make, this library requires loading the public key at runtime.
| File | Description |
|---|---|
libliman_sdk.a |
Static library - requires lim_read_public_key() |
libliman_sdk.so |
Shared library - requires lim_read_public_key() |
Advantages:
- Single library can validate licenses for multiple products
- Useful for license management tools and development/testing
- Can switch products at runtime without recompiling
Usage: Must call lim_read_public_key(env, "path/to/public.key") before license validation.
Do not mix approaches! If you link against the product-agnostic library but forget to call lim_read_public_key(), license verification will fail. Conversely, if you link against the product-specific library, calling lim_read_public_key() is unnecessary.
API Reference
The following functions are defined in include/liman.h.
Environment Functions
| Function | Description |
|---|---|
lim_create_env(keysize, hashsize, &err) |
Create LIMAN environment. Returns pLIMENV or NULL on error. |
lim_free_env(&env) |
Free environment and release resources. |
lim_read_public_key(env, filepath) |
Load public key from file. Required for product-agnostic library only. |
lim_read_private_key(env, filepath) |
Load private key from file. Used by license generators. |
License Creation Functions
| Function | Description |
|---|---|
lim_create_lic(env, &err) |
Create empty license object for generation. |
lim_create_lic_fromfile(env, filepath, &err) |
Load and parse license from file. |
lim_create_lic_fromkey(env, keystring, &err) |
Load and parse license from key string. |
lim_free_lic(&lic) |
Free license object and release resources. |
License Validation Functions
| Function | Description |
|---|---|
lim_is_verified(lic) |
Returns true if license signature is valid. |
lim_assert_valid(lic) |
Returns LIM_OK if license is currently valid (not expired, correct host, etc.). |
lim_days_to_expiry(lic) |
Returns days until expiration, or negative if expired. |
lim_has_feature(lic, byte_index, bitmask) |
Check if specific feature bits are enabled. |
License Property Functions
| Function | Description |
|---|---|
lim_get_product(lic) |
Get product code string. |
lim_get_major(lic) |
Get major version number. |
lim_get_minor(lic) |
Get minor version number. |
lim_get_serial(lic) |
Get serial number string. |
lim_get_expiry(lic) |
Get expiry date (YYYYMMDD format). |
lim_get_seats(lic) |
Get number of seats/users allowed. |
lim_get_type(lic) |
Get license type code. |
lim_get_features(lic, feature_array) |
Copy feature bitmask array (4 bytes). |
Host ID Functions
| Function | Description |
|---|---|
lim_get_hostid(env, mask, buffer, bufsize) |
Get current machine's host ID using specified mask. |
lim_validate_host(lic, mask) |
Validate license against current host. |
License Generation Functions
| Function | Description |
|---|---|
lim_load_lic(lic, params) |
Load license parameters into license object. |
lim_write_lickey(lic, filepath) |
Export signed license to file. |
lim_get_lickey(lic, buffer, bufsize) |
Export signed license to string buffer. |
License Generation
License generation involves creating an encrypted license key containing the following information:
- Product ID - String (max LIMPAR_MAX_LEN_PRODUCTID chars) that uniquely identifies a product
- Platform - Integer (0-255) specifying target platform
- Major Version - Integer (0-255)
- Minor Version - Integer (0-255)
- Size - Integer specifying license size (for capability tiers)
- Type - Integer constant specifying license type (educational, trial, commercial)
- Seats - Integer specifying concurrent users allowed
- Expiry Date - Date in YYYYMMDD format (optional)
- Serial Number - String (max LIMPAR_MAX_LEN_SERIAL chars, optional)
- UUID - Unique identifier string (optional)
- Host ID - Host machine identifier for node-locked licenses (optional)
- Features - 4-byte array for feature bitmasks (optional)
Data Types
LIMAN SDK has two data types that must be initialized before any license operation:
pLIMENV- LIMAN SDK environment object, created withlim_create_env()pLIMLIC- License object, created with:lim_create_lic()lim_create_lic_fromfile()lim_create_lic_fromkey()
License Creation Steps
- Create environment instance:
lim_create_env() - Read the private key:
lim_read_private_key() - Create empty license:
lim_create_lic() - Call
lim_load_lic()with license parameters - Export license:
lim_write_lickey() - Cleanup:
lim_free_lic()andlim_free_env() - Send the license key to your customer
limgen Command Line Tool
Build the license generator with make limgen. Available options:
$ limgen --help
Liman Version: 1.2.9 (Linux64x86 Release Build)
Usage: limgen [options]
-A, --platform=PLATFORM_ID Platform identifier (0..255)
-P, --product=PRODUCT_CODE Product code (12 chars max)
-M, --major=MAJOR Major version (0..255)
-J, --minor=MINOR Minor version (0..255)
-S, --size=SIZE_ID License size identifier (0..255)
-t, --type=TYPE_ID License type identifier (0..255)
-o, --seats=NSEATS Number of seats/users allowed
-e, --expiry=YYYYMMDD Expiry date
-r, --serial=SERIAL Serial code (24 chars max)
-H, --hostid=HOSTID Target machine hostid
-u, --userid=USERID Customer userid
-i, --uuid=UUID Unique identifier (32 chars max)
-f, --features=FEATURES Feature bitmask (comma delimited)
-I, --privkeyfile=PRIVKEYF Private key file
-U, --pubkeyfile=PUBKEYF Public key file
-k, --keysize=KEYSIZE Key size in bits
-Z, --hashsize=HASHSIZE Hash size in bits
-s, --seed=SEED Random seed
-m, --hostmask=HOSTMASK Host identifier mask (1,2,4,8,16)
-L, --licinfo Display license information
-g, --genkey Generate keypair
-D, --genuuid Generate UUID
-h, --help Show help
Examples
# Generate license with features and expiry
$ limgen --product=PRODUCT1 --major=2 --minor=1 --serial=123456 \
--expiry=20260401 --features=37,3,3,5
# Generate license with custom keypair
$ limgen --platform=8 --product=PRODUCT1 --major=2 --minor=1 \
--serial=123456 \
--privkeyfile=/path/to/priv/key \
--pubkeyfile=/path/to/pub/key
Using Bitmasks for Optional Features
Your application may have different features that need to be licensed separately. LIMAN SDK allows up to 32 optional features using a 4-byte array. Each byte is an 8-bit bitmask (0-255).
Example: Sorting Algorithms
Suppose your application offers 8 sorting techniques:
7 6 5 4 3 2 1 0
_______ _______ _______ _______ _______ _______ _______ _______
| | | | | | | | |
|_______|_______|_______|_______|_______|_______|_______|_______|
| | | | | | | |
| | | | | | | +---> Quick Sort
| | | | | | +-----------> Merge Sort
| | | | | +-------------------> Heap Sort
| | | | +---------------------------> Insertion Sort
| | | +-----------------------------------> Intro Sort
| | +-------------------------------------------> Block Sort
| +---------------------------------------------------> Shell Sort
+-----------------------------------------------------------> Bubble Sort
For a license with Quick Sort, Heap Sort, and Block Sort enabled:
binary: 00100101 = 2^0 + 2^2 + 2^5 = 1 + 4 + 32 = 37
Feature Constants
#define LIMOPT_FEATURE_0 1 // 2^0, bit 0 #define LIMOPT_FEATURE_1 2 // 2^1, bit 1 #define LIMOPT_FEATURE_2 4 // 2^2, bit 2 #define LIMOPT_FEATURE_3 8 // 2^3, bit 3 #define LIMOPT_FEATURE_4 16 // 2^4, bit 4 #define LIMOPT_FEATURE_5 32 // 2^5, bit 5 #define LIMOPT_FEATURE_6 64 // 2^6, bit 6 #define LIMOPT_FEATURE_7 128 // 2^7, bit 7
Setting Features
void set_features(char feature[4]) {
feature[0] = 0;
feature[0] |= LIMOPT_FEATURE_0; // Quick Sort
feature[0] |= LIMOPT_FEATURE_2; // Heap Sort
feature[0] |= LIMOPT_FEATURE_5; // Block Sort
feature[1] = 0;
feature[2] = 0;
feature[3] = 0;
}
Checking Features
if (lim_has_feature(pLic, 0, LIMOPT_FEATURE_0)) {
printf("Quick Sort is available\n");
}
if (lim_has_feature(pLic, 0, LIMOPT_FEATURE_2)) {
printf("Heap Sort is available\n");
}
if (lim_has_feature(pLic, 0, LIMOPT_FEATURE_5)) {
printf("Block Sort is available\n");
}
License Key Format
License keys are encrypted strings containing all license properties. Creation requires your private key (keep secret); validation uses the public key either embedded in the product-specific library (libliman_<PRODUCT>_sdk.a) or loaded at runtime via lim_read_public_key() when using the product-agnostic library.
#----- BEGIN LICENSE KEY (Id:0F1BBCE44015) ----- UjP8kPXFXl82y97eTAgCbOMLTyDOK9o8p9USut/zkanO+Mhs10E3dMT5ceqpDefr I5NDb/1bGkaTI/Nue6u6LGZ4azJEOcjT1b1tqVSAU60vgSeyUTEJUj2ujDjxofGl 2ybdpdbkdUsyb6jEFpn2t+zEOwNolmeEXnq1yZHkTW+ta8hymvnv31B3z21rmuu5 QQKAhGkTTdEpXga0bMYR55oNmTwx83KufRHFGbSLd+kSBAiqIuiTpzcQe0fT+2wM 5C20vpWyKeW0k9wknY+r1fw7lD/oQCB7Rv9g+DHYqKmT+1e4GpGxuRMgJf125gCc kfZ0rja6blhocnM+3GYrzg== #----- END LICENSE KEY -----
Contact and Support
For sales inquiries and licensing: info@baroks.com
For technical support: info@baroks.com
Error Codes
The following error codes are defined in include/liman.h:
| Constant | Description |
|---|---|
| LIM_OK | No error, operation successful |
| LIMERR_MEMORY | Error in allocating memory |
| LIMERR_FILE_NOT_FOUND | Specified file was not found |
| LIMERR_INVALID_NULL | Specified reference is invalid or null |
| LIMERR_INVALID_LICENSE | Specified license is invalid |
| LIMERR_ENVAR_NOT_FOUND | Environment variable not found |
| LIMERR_LICENSE_EXPIRED | License has expired |
| LIMERR_LICENSE_NOT_LOADED | License is not loaded |
| LIMERR_INVALID_DOMAIN | Domain parameters are invalid |
| LIMERR_INVALID_PRODUCT_CODE | Product code invalid for license |
| LIMERR_INVALID_USER | Current user invalid for license |
| LIMERR_INVALID_PRODUCT_VERSION | Product version invalid for license |
| LIMERR_INVALID_PLATFORM | Platform code invalid for license |
| LIMERR_INVALID_ENVAR | Environment variable is invalid |
| LIMERR_INVALID_ENV | Environment is invalid |
| LIMERR_INVALID_INPUT | Input is invalid |
| LIMERR_UNABLE_TO_OPEN_FILE | Failed to open file |
| LIMERR_INVALID_LICENSE_FILE_NAME | License filename is invalid |
| LIMERR_OPERATION_FAILED | Internal operation failed |
| LIMERR_PRIVKEY_FILE_NOT_FOUND | Private key not found |
| LIMERR_PUBKEY_FILE_NOT_FOUND | Public key not found |
| LIMERR_NOT_SUPPORTED | Feature not supported |
| LIMERR_INVALID_KEYLEN | Key length is invalid |
| LIMERR_NOT_AVAILABLE | Information not available |
| LIMERR_INVALID_KEY | Key is invalid |
| LIMERR_SHORT_KEY | Key is too short |
| LIMERR_BAD_ERRORCODE | Error code is invalid |
| LIMERR_INTERNAL | Internal error - contact vendor |
| LIMERR_ENV_NOT_READY | Environment not ready |
| LIMERR_ALREADY_LOADED | Object already loaded |
| LIMERR_SYSTEM | Platform-specific system error |
| LIMERR_CLOCK_SETBACK | Clock setback detected |
| LIMERR_INVALID_HOST | Host invalid or hardware changed |
| LIMERR_KEYS_NOT_LOADED | Keys not loaded |
| LIMERR_PRIVKEY_FILE_EXISTS | Private key file already exists |
| LIMERR_PUBKEY_FILE_EXISTS | Public key file already exists |
| LIMERR_KEYSIZE_MISMATCH_ENV | Key size doesn't match environment |
| LIMERR_RANGE_TYPE_CODE | Type code out of range |
| LIMERR_RANGE_PRODUCT_CODE | Product code out of range |
| LIMERR_RANGE_MAJOR_VERSION | Major version out of range |
| LIMERR_RANGE_MINOR_VERSION | Minor version out of range |
| LIMERR_RANGE_SIZE_CODE | Size code out of range |
| LIMERR_RANGE_PLATFORM_CODE | Platform code out of range |