LexActivator

LexActivator is the Cryptlex client library you embed in your app to implement node-locked licenses, trials, hosted floating licenses, and named user licenses. This page shows you how to add the library to your app, activate and verify a license, and handle the hosted floating, named user, and offline activation flows, with code samples for every supported language.

What LexActivator does for you

Under the hood, LexActivator is a libcurl based HTTP client that invokes the Cryptlex Web API endpoints from your application. You can invoke these endpoints with any HTTP library, but LexActivator does the hard parts for you:

  • Abstracts away the HTTPS layer, so you call functions like ActivateLicense() and ActivateTrial() instead of sending HTTPS requests.
  • Verifies the HTTPS response signature using an RSA public key.
  • Stores the HTTPS response on disk in encrypted form using AES encryption, in a per-user or system-wide location depending on the permission flag you pass to SetProductId(). Where disk writes are restricted, it can instead keep the license data in memory, which requires activating the license again on each app restart and is typical for hosted floating licenses with a per-instance leasing strategy.
  • Generates multiple fingerprints of the machine using an advanced device fingerprinting algorithm, which allows for different fingerprint matching strategies.
  • Detects virtual machines, so you can prevent users from activating your licenses in them (virtual machines can be cloned, which may result in the same fingerprint on different machines).
  • Detects system clock tampering, so users cannot extend a time-limited license or trial by turning back the machine's clock.
  • Periodically invokes the Cryptlex Web API endpoints in a separate thread to sync the server license data with the client.
  • Handles offline activations.

Minimum requirements

For the supported platforms, versions, and architectures, see minimum requirements.

Adding licensing to your app

Prerequisites

Before you integrate LexActivator, create a product for your app in the admin portal and create a license (node-locked or hosted floating) for it. Then, from the product's page, get the two things you will use in your code:

  • The Product ID identifies your product in your code.
  • The Product.dat file contains product data used by LexActivator. Download or copy it from the actions menu on the Products page.

For a complete, working integration in your language, refer to the example projects on GitHub.

Adding the library to your app

Download the LexActivator library for Windows, macOS, or Linux from the SDK downloads page. The package contains both the shared and static library.

Setting the product data and product ID

Embed the product data (the contents of the Product.dat file) in your app using the SetProductData() function. Then set your product ID using the SetProductId() function.

Call both functions once during your app's initialization, before any activation or verification.

SetProductData("PASTE_CONTENT_OF_PRODUCT.DAT_FILE");
SetProductId("PASTE_PRODUCT_ID", LA_USER);

The permission flag you pass to SetProductId() determines where the activation data is stored:

  • LA_USER (the default) stores the activation under the OS user who activated the license, so it is visible only to that user, and each OS user who runs the app activates separately. They all share the same seat. Enable OS user-locked to have each OS user consume a separate seat.
  • LA_ALL_USERS stores the activation system-wide and shares it across all OS users on the machine. It is supported on Windows and macOS; on Linux, achieve the same result by pointing LexActivator at a system-wide directory with SetDataDirectory() and passing the LA_ALL_USERS flag.
  • LA_IN_MEMORY keeps all data in memory instead of on disk. Use it when your app has no write access to the disk, and for hosted floating licenses with a per-instance leasing strategy. Note that the license must be activated again every time the app restarts.

License activation

Set the license key with SetLicenseKey(), then call ActivateLicense(). This assumes you have already set the product data and ID, as shown above. Call it when the user activates the license, for example on a button click. Use SetLicenseKey() and ActivateLicense() only in your activation flow, not during normal startup.

ActivateLicense() invokes the /v3/activations Web API endpoint and verifies the encrypted, digitally signed response to validate the license.

int status;
status = SetLicenseKey("PASTE_LICENSE_KEY");
if (LA_OK != status)
{
// handle error
}
status = ActivateLicense();
if (LA_OK == status || LA_EXPIRED == status || LA_SUSPENDED == status)
{
printf("License activated successfully: %d", status);
}
else
{
printf("License activation failed: %d", status);
}

Verifying license activation

Each time your app starts, verify whether the license is already activated with IsLicenseGenuine(). This assumes the product data and ID are already set during initialization.

The check runs locally by verifying the cryptographic signature of the stored activation, so it works offline. LexActivator also syncs with the Cryptlex servers periodically in the background to pick up server-side changes such as renewals, suspension, or revocation.

int status;
status = IsLicenseGenuine();
if (LA_OK == status || LA_EXPIRED == status || LA_SUSPENDED == status || LA_GRACE_PERIOD_OVER == status)
{
printf("License is genuinely activated: %d", status);
}
else
{
printf("License is not activated: %d", status);
}

Hosted floating licenses

LexActivator implements hosted floating licenses the same way as node-locked licenses; the only difference is how you activate and release seats. A floating seat is held while your app runs and must be released on exit, otherwise it becomes a zombie that keeps consuming a seat.

Validate the license first, activate based on the validation status, and release the seat on exit only for hosted floating licenses:

// On startup: check the license once, then act on the result
int status = IsLicenseGenuine();
if (status == LA_FAIL) {
// not activated yet
char licenseKey[256];
if (GetLicenseKey(licenseKey, sizeof(licenseKey)) == LA_OK) {
// a key is already stored
ActivateLicense();
} else {
// no key stored, prompt the user for one
SetLicenseKey(userKey);
ActivateLicense();
}
} else if (status == LA_OK) {
// license is valid (node-locked or floating), continue launching the app
}

// On exit: release the seat only for hosted floating licenses
char licenseType[256];
if (GetLicenseType(licenseType, sizeof(licenseType)) == LA_OK && strcmp(licenseType, "hosted-floating") == 0) {
DeactivateLicense();
}

For when to choose hosted floating and how to configure the license template, see hosted floating licenses.

Named user licenses

Named user licenses (also known as identity-based or user-locked licensing) can be implemented with LexActivator: the user logs in with their own credentials and their linked license is activated, instead of entering a license key. See named user licenses for the full activation flow and portal setup.

Offline activation

LexActivator can activate licenses on machines with no internet access, using an offline activation request and response file pair. For the full walkthrough, see offline activations.

Next steps

Need more help?

If you need more help adding LexActivator to your app, we'll be glad to help with the integration. Contact us through the contact page.

OverviewLexFloatClient
Last updated: