SoftActivate Licensing SDK Documentation
Contents
- About SoftActivate Licensing SDK
-
Using SoftActivate Licensing SDK
- Using the Samples
- Installing and using SoftActivate Licensing Server
- Compiling and Linking
- Initializing and registering the SDK
- Adding licensing and activation to your software with only one line of source code (BETA)
- Creating License Key Templates
- Generating License Keys
- Validating License Keys
- Obtaining Stored Data from License Keys
- Understanding and Using Software Activation
- Understanding and Using Hardware Id (Hardware Fingerprint) Strings
- Implementing Trial Versions in Your Software Application
- Detecting Clock Manipulation Attempts
- Integrating SoftActivate Licensing Server with Payment Services
- Security Guidelines
- Uninstalling SoftActivate Licensing SDK
-
Programming Reference
- KeyGenerator Class
- KeyValidator Class
-
LicenseTemplate Class
- Constructor
- SetVersion
- GetVersion
- SetNumberOfGroups
- GetNumberOfGroups
- SetCharactersPerGroup
- GetCharactersPerGroup
- SetGroupSeparator
- GetGroupSeparator
- SetEncoding
- GetEncoding
- SetHeader
- GetHeader
- SetFooter
- GetFooter
- SetDataSize
- GetDataSize
- AddDataField
- EnumDataFields
- SetValidationDataSize
- GetValidationDataSize
- AddValidationField
- EnumValidationFields
- SetSignatureSize
- GetSignatureSize
- LoadXml
- SaveXml
- SetPublicKeyCertificate
- GetPublicKeyCertificate
- SetPrivateKey
- GetPrivateKey
- LoadJson
- SaveJson
- SetLicensingServiceUrl
- GetLicensingServiceUrl
- SetTemplateId
- GetTemplateId
- GenerateSigningKeyPair
-
LicensingClient Class
- Constructor
- SetLicensingServiceUrl
- SetLicenseTemplate
- SetLicenseKey
- SetActivationKey
- GetActivationKey
- SetHardwareId
- GetHardwareId
- SetLicenseKeyValidationData
- SetLicenseTemplateId
- AcquireLicense
- ValidateLicense
- IsLicenseValid
- GetLicenseActivationStatus
- GetLicenseExpirationDate
- SetTimeValidationMethod
- License Class
- LicenseValidationArgs Class
- LicenseValidationResult Class
- KeyHelper Class
- SDKRegistration Class
- Glossary
About SoftActivate Licensing SDK
SoftActivate Licensing SDK uses the latest advances in elliptic curve cryptography to provide you with one of the most secure and flexible license key generation and license management software solutions on the market. It supports short, easy to read license key generation, license key validation and software activation. It has native C, C++ and .NET interfaces. It has a fully managed implementation written in C# in addtition to the C/C++ native implementation. For more information on features, please see our website product page.
Using SoftActivate Licensing SDK
Using the Samples
Many sample applications written in various languages (C++/C/C#/VB.NET) are provided with SoftActivate Licensing SDK in order to help you use the technology correctly and efficiently.
-
Key generators and validators in C, C++, and C#
-
Activation samples in C++ and C#
-
Hardware Id generation samples
The samples are found in the samples\C, samples\C++, Samples\C# and samples\VB.NET folders
Installing and Using the Licensing Server
Please note: you do not need to install the licensing server in order to use the source code samples. They already use a demo licensing server installed on SoftActivate web site.
SoftActivate Licensing Server is a composed of two web applications:
It has two versions. The Node.js version, written in Javascript, and the .NET version, written in C#/ASP.NET Core. Both versions can be installed on either shared hosting accounts or full servers running NodeJS or Microsoft IIS respectively. Both servers use SQLite3 (for development purposes) and MySQL or SQL Server for production.
Installing the .NET SoftActivate Licensing Server on Windows with IIS
- Make sure IIS is installed on your machine (more here)
- Install ASP.NET Core hosting bundle for IIS from Microsoft (choose the ASP.NET Core Runtime hosting bundle)
- Restart IIS
- Using IIS Manager, create two application pools, one named LicensingService with binding to port 3001, and one named LicensingControlPanel with binding to port 3000
- Using IIS Manager, create two web sites: LicensingService pointing to ./bin/server/dotnet/LicensingService SDK folder and using the LicensingService app pool, and LicensingControlPanel pointing to ./bin/server/dotnet/LicensingControlPanel SDK folder and using the LicensingControlPanel app pool
In the server's appsettings.json files from the LicensingService and LicensingControlPanel folders, you will have to enter your purchased SDK license key (or leave the included demo key). Otherwise the server will run in demo mode.
Installing the NodeJS version of the SoftActivate Licensing Server
SoftActivate Licensing SDK includes a NodeJS licensing server. The NodeJS licensing server is written in Javascript and uses Sqlite3 (for development), MySQL or SQL Server (for production purposes).
Server installation steps on Linux (our example assumes a fresh instance of Amazon Linux - a popular choice for Amazon EC2 Linux virtual machines):
- Install NodeJS on the test machine using the installer specific to your Linux distribution (or Windows installation). This may include commands like "yum install nodejs" or "rpm install nodejs" or downloading and running the Windows MSI installer from NodeJS website. npm (Node Package Manager) will usually also be installed along with NodeJS. If not, also install npm. On Windows, make sure Node.exe and npm are in the PATH so you can easily run them from any folder.
- Go to the ./bin/server/nodejs/lms subfolder of the SDK and run "npm install". This will install required dependency packages.
- Go to the ./bin/server/nodejs/lms-admin subfolder of the server and run "npm install". This will install required dependency packages.
- Go to the ./bin/server/nodejs/lms-console subfolder and run "npm install". This will install required dependency packages.
- To run the LMS server, go to the lms folder of the server, and type "node index.js". This will start the server which (by default) will be listening on port 3001. If successful, the message "Licensing server started" should appear in the console.
- To run the LMS admin console, go to the lms-admin folder of the server, and type "node index.js". This will start the web management console which will be listening on port 3000.
- In order to access the LMS admin console, open a web browser and go to "http://localhost:3000". The console should appear asking you to login. The default username and password are "admin" and "SoftActivate".
The samples "ActivationCS", "ActivationCPP", "EasyLicensingCS", "WinFormsAppCS" and "WinFormsAppVB" from the Licensing SDK connect to the server and perform sample product activations and show how to use the trial versions feature. For more information about how the activation is performed, please see the section "Understanding and Using Product Activation" in this document.
Compiling and Linking
Choosing the Correct Libraries
The following libraries are provided in precompiled form by the SoftActivate Licensing SDK for each of the x86-windows, x64-windows, x64-linux and .NET platforms. Please note, you can additionally compile the SDK on a variety of platforms including Linux, MacOS with Intel, Apple and ARM-based hardware
-
Dynamic library (.dll\.so) (bin\client\x86-windows|x64-windows|x64-linux\licensing.dll|liblicensing.so)
This is a dynamically linked library containing support for product key generation/validation and activation. It should only be used in-house for license key generation/validation and server-side software activation. A corresponding import library is supplied, named lib\win32|x64\Release\licensing.lib. -
Static library using the C runtime as static library (lib\x86-windows-mt|x64-windows-mt\licensing.lib)
This is the recommended way to embed the Licensing SDK into your application, because it will be directly embedded into your main binary (or you could embed the relevant source code directly). License key software binary code should never be put in a separate module, like a DLL, for entry point security purposes. This library is intended to use when you are linking your application with the static version of CRT libraries ( the /MT compiler option ). -
Static library using the C runtime as shared DLL (lib\x86-windows|x64-windows\licensing.lib
This is the recommended way to embed the Licensing SDK into your application, because it will be directly embedded into your main binary (or you could embed the relevant source code directly). Licensing code should never be put in a separate binary, like a DLL, for entry point security purposes. This library is intended to use when you are linking your application with the dynamic version of CRT libraries ( the /MD compiler option ). -
.NET library (bin\client\dotnet\Licensing.Net.dll)
This library contains the pure .NET code for the library. It supports key generation, validation and software activation. However, this is not a recommended and secure way to include the Licensing SDK in your .NET application. The most secure way is to embed the source code of the SDK directly into the source tree for your main executable. The .NET SDK source code is lightweight enough to not add significant bulk or complexity to your application.
Static Linking
Static Linking refers to using the static Licensing SDK libraries in your application. In Visual Studio, you can accomplish this by editing your project properties and adding the library to Linker->Input->Additional Dependencies. Also, you have to define the preprocessor symbol LICENSING_STATIC. To do this, edit your application properties by going to C/C++->Preprocessor->Preprocessor Definitions and add the LICENSING_STATIC symbol. Static linking is the preferred way to use SoftActivate Licensing SDK libraries in your applications. Another secure way is to embed the SDK source code directly into your application.
Dynamic Linking
Dynamic linking refers to using the DLL versions of the Licensing SDK libraries. It is the easiest and the most compatible way to use the SDK libraries. You just have to link with the corresponding import library. In Visual Studio, you can accomplish this by editing your project properties and adding the import library to Linker->Input->Additional Dependencies.
Initializing and registering the SDKInitializing and Registering the SDK
There is no initialization required (and neither is it recommended) for the SDK if it will be used for license key validation, or client-side software activation. Thus, in your end-user application there is no initialization required. If the SDK will be used for license key generation or public/private key pair generation (for example in your key generator application),the first required step is initializing the SDK by entering the purchased SDK license key. This is done via SDKRegistration::SetLicenseKey(). If this license key is not entered, the SDK will function in demo mode. This means that only certain, pre-defined private/public keys for license key generation are generated/accepted for use by the SDK. Since the predefined private keys are known by anyone and can be generated by anyone, these cannot be securely used to sign the generated license keys. Initializing the SDK by calling SDKRegistration::SetLicenseKey() and setting your purchased developer license key into your end-user application is NOT recommended.
Adding licensing and activation to your software with only one line of source code (BETA)Adding licensing and activation to your software with only one line of source code (BETA)
Starting with version 3.1, SoftActivate Licensing SDK includes a new .NET component called UILicenseManager and located in LicensingUI.Net.dll assembly. This component provides all the registration logic, including a customizable HTML-based user interface. This component has only one method: UILicenseManager.Run(). For more information, please see the EasyLicensingCS sample in the SDK's Samples\CS subfolder.
Creating License Key Templates
SoftActivate license keys are very flexible in their format, security and contents. You can choose your own format for your application, based on your needs. A license key template is a collection of properties used to define a license key's format, security and contents.
Currently, the following properties are available in a license key template:
-
License Key Format
- Number of character groups.This is the number of groups of characters a license key has. The key 3XTZWJ-V5N4JB-MXDBAA-K9CYK7-2XUWSU has 5 character groups.
- Number of characters per group.This is the number of characters contained by each character group. The key 3XTZWJ-V5N4JB-MXDBAA-K9CYK7-2XUWSU has 6 characters per group.
- Group separator.This is a string of characters used to separate character groups. The key 3XTZWJ-V5N4JB-MXDBAA-K9CYK7-2XUWSU has uses "-" as string separator. The new line character can also be used, causing key groups to be split one on each line. This is useful for very long license keys.
-
Character encoding.This specifies what encoding is used to convert the license keys from their binary format into an easy to handle text format. Currently two encodings are available: BASE32X and BASE64X.
The BASE32X encoding is a variation of the BASE32 with some modifications in order to ensure that license key's characters are not confused with similar-looking characters. The BASE64X format is a variation of BASE64, and it's typically used in very long license keys, like this:
--BEGIN LICENSE--
XUWCNDfqhlzPxhAnr
sdvPOCf77FgGfP4ip
BwnruQKOQjJdIftPQ
0topIPEJcWtPLhbVE
fF8Wy/V7W69qAocpU
--END LICENSE--
- License Key Header. This is a line of text preceding the actual license key. See "--BEGIN LICENSE--" from the above example. It is typically used on very long license keys.
- License Key Header. This is a line of text ending the actual license key. See "--END LICENSE--" from the above example. It is typically used on very long license keys.
-
License Key Security
- Signature size. This parameter chooses the license key signature size in bits, and thus is has an impact on key security. The allowed sizes are currently between 76 and 322. The bigger the signature size, the stronger the key security. But also the bigger the signature size, the longer the license key must be. So you must make a compromise here (see below).
-
License Key Data Contents
- Embedded Data A license key can contain various informations. The information is divided into fields. Each field can contain one of three types of data: integer, string or raw. It is up to the developer's choice what data fields does a key contain. The key contents are digitally signed, so they cannot be altered. The embedded data size is limited by the license key size.
- Validation Data In addition to the data embedded in the license key, supplemental information can be used to validate a license key. This information is not embedded in the key. For example, you may want to use a registration name or a hardware id to validate a license key against. The registration name is regarded as validation data. The validation data is not embedded in the key, so it can be any information, of any size or type.
Choosing the Right Template for Your Application
Since not any combination of license key length, license key security and license key contents can be used (due to size constrains), you must make a compromise between license key ease of use, security and the contained information. The BASE32X format stores 5 bits for each license key character (excluding separators), so the license key 3XTZWJ-V5N4JB-MXDBAA-K9CYK7-2XUWSU can store 150 bits. From these, a part is taken up by the digital signature, and the remaining part can be used to store various information. For example, if you choose a 130-bit signature (which is quite secure), you have 20 bits left to store data.
Generating License Keys Linked to Registration Names
Often, in order to limit illegal license key distribution developers opt to require the registration name used when purchasing in order to validate the license key. Thus, if someone distributes a license key, he must also distribute the registration name together with the key (otherwise the key would be useless since it could not be validated by others). This creates an additional barrier for potential software pirates, because no one wants his name associated with violating the law. A good license key software must provide for this sceanario. With SoftActivate Licensing SDK, linking lincese keys to registration names can be done by adding a validation field of type string to the license key template. Linking license keys to registration names has some drawbacks, however. You cannot generate license keys to be used for retail boxes or printing on CD's, for example, because you don't know in advance the name of the customer who buys a particular box. Thus, this approach is mostly used for online distribution.
Generating License Keys Linked to Specific Hardware
Sometimes, in order to drastically limit illegal license key distribution or using a license key on more than one computer, developers may want particular license keys to only validate on particular computers. Each key is generated for a specific computer, and it cannot be used on other computers. With SoftActivate Licensing SDK, linking license keys to particular computers can be done by adding a validation field of type string (or binary) to the license key template. The Licesing SDK includes a helper API to help you determine a unique hardware id for a computer in the form of a string. This id can then be used to generate a license key, and to validate it. Linking license keys to specific hardware id's requires knowing the hardware id at key generation time. So a customer must supply his hardware id, the software vendor must generate the license key and send it back to the customer. In order for the customer to supply his hardware id, the software vendor must make available a tool by which the customer can find his computer's hardware id. This tool can use SoftActivate Licensing SDK helper API for hardware id management. Linking license keys to specific hardware has some drawbacks, since the customer must take additional steps to purchase a product. Also, keys of this type cannot be distributed in large quantities, like in retail boxes or CD prints.
Using XML License Key Templates
SoftActivate Licensing SDK provides a convenient way to store license key validation/generation information in XML templates.
Using JSON License Key Templates
In addition to XML templates, SoftActivate Licensing SDK also supports JSON templates for storing license key validation/generation information.
JSON templates provide a more modern and lightweight alternative to XML, with easier readability and parsing. The SDK provides both
LoadJson and SaveJson methods for working with JSON-formatted templates.
Generating License Keys
The following steps must be taken in order to generate license keys:
- Create a license key template object.
- Initialize the license key template object either from an XML template or programatically. Specify the license key format, security, content fields and optionally validation fields.
- Create a license key generator object.
- Specify the template to the license key generator object.
- Set license key content data.
- Optionally, set license key validation data (for example, if you need to link the license key to a registration name).
- Generate the license key
Validating License Keys
The following steps must be taken in order to validate license keys:
- Create a license key template object.
- Initialize the license key template object either from an XML template or programatically. Specify the license key format, security, content fields and optionally validation fields.
- Create a license key validator object.
- Specify the template to the license key validator object.
- Set the license key to the validator object
- Optionally, set license key validation data (for example, if the key was linked to a registration name or email).
- Validate the license key (by calling KeyValidator::IsKeyValid() )
- If the key is valid, retrieve the data from the license key and also validate this data (for example, check if the product id from the key matches your product)
Obtaining Stored Data from License Keys
Embedded key data can be read using LicenseKeyValidator::QueryKeyData method
Understanding and Using Software Activation
Software activation is a way to make sure that a software product can only be used on a specific computer. It involves an activation server to which your software connects (once) in order to activate the product.
The activation server receives the product key (issued when the user purchased the product) and a hardware id (a special string generated by the Licensing SDK which is unique to each computer) and returns an activation key. The activation key si a signed piece of information, similar to a license key except for the fact that it can only be validated in the presence of the hardware id string used to generate it. When checking if a product is activated, the LicensingClient class first makes sure that the activation key is valid and was signed by the activation server, and then compares the hardware id with the actual computer's hardware id. The activation key also contains an expiration date information, which is also checked. If all three conditions are met (signature verification, hardware id match, current date earlier than the expiration date) then the product is considered activated. Please note that the activation verification does not involve connecting to the activation server because it is not necessary. Since the public verification key is embedded into the product, the activation key signature can be validated using the stored public key. Activation by phone is also possible: the customer transmits the license key and hardware id to the phone operator, and the phone operator generates the activation key and transmits it to the customer. The customer enters this activation key into the product, and the product is activated. The license key, hardware id and activation key are all easy to read strings that can easily be transmitted in a phone conversation.
In summary, there are three pieces of information that make up the activation data: license key, hardware id and activation key. The LicensingClient class is used to verify the software activation status and perform activation if necessary.
Understanding and Using Hardware Id (Hardware Fingerprint) Strings
Sometimes the need arises to generate strings that uniquely identify the hardware configuration of a computer. One such example is software activation. SoftActivate Licensing SDK makes it possible to generate such strings, called hardware id strings.
SoftActivate Licensing SDK generates hardware id strings taking into consideration the following computer parameters: MAC addresses, fixed disk serial numbers, processor type and the amount of RAM memory. All this information is combined into an easy to use/type/dictate string, of the form XXXXX-XXXXX-XXXXX-XXXXX-XXXXX (5 character groups of 5 characters each). This string can then be matched to a computer in order to find out if the computer is the same computer for which the hardware id string was previously generated. The KeyHelper class contains methods for both hardware id generation and verification (matching).
Implementing Trial Versions in Your Software Application
A common scenario in commercial software development is the one in which a trial version of an application must be provided to customers so that they can try the application first before purchasing it. You may want your potential customers to be able to try the product at no charge for a certain number of days.
SoftActivate Licensing SDK achieves this by using online software activation. This is a very secure process which does not involve hiding the product expiration date on a computer. Basically, your product includes a "trial license key" which is specially marked as such on the licensing service database. After installing a product on a certain computer, when a user presses the "Start Trial" button, the licensing server receives the trial license key and hardware id of the computer, and it will issue a digitally signed activation key containing the absolute (not relative) expiration date of the trial version. This activation key is also linked to the hardware id of that computer. At each startup, the product verifies the license key, activation key and hardware id using the LicensingClient class. After the activation key is deemed valid, the product can query the trial expiration date of the product. If the expiration date is less than the current date, the product is allowed to run. If not, a message can be displayed to the user informing that the trial period has expired and he needs to enter a purchased license key, etc.
With SoftActivate Licensing SDK, you can achieve goal via the following steps:
- Designate a certain license key as a "trial license key". Usually, this license key is a regular license key, it does not need to contain certain bits of data to mark it as trial.
-
Using SQL Server Management Studio or other similar tool, enter this license key into the LicenseKeys table of the licensing service, and set the database columns for this key as follows:
- Set MaxUniqueHardwareIds to 0. This means that any number of computers can activate this key (this trial key will be used by all your potential customers).
- Set MaxActivationsPerHardwareId to 1. This means that each computer can activate this license key only once.
- Set MaxActivations to 0. This means that there is no limit of overall activation count for this license key
- Set LicenseDuration to the number of trial days that you desire (example: use "30" for one-month trial).
- Set LicenseHistoryDuration to a number of days after which you want to allow a computer to trial your product again after the initial trial period expires. Example: you may want that after 12 months (365 days) a computer to be allowed again to trial your product for one month. If you set this column to 0 or NULL, a computer is never allowed again to trial your product after the trial period expires. This is not recommended.
Detecting Clock Manipulation Attempts
SoftActivate Licensing SDK provides specific methods for detecting clock manipulation attempts. The SDK scans the system for evidence that the system clock was deliberately turned back in order to avoid license expiration.
The specific method to call is KeyHelper::DetectClockManipulation(). This method is usually called after the IsLicenseValid() method returns true (whether in "trial" or "full" licenses) in order to ensure that the clock was not deliberately changed in order to extend the license validity interval.
For more information, please see the sample code included in the ActivationCPP, ActivationCS, WinFormsAppCS and WinFormsAppVB samples
Integrating SoftActivate Licensing Server with Payment Services
SoftActivate Licensing Server now fully supports integration with the most popular payment services: PayPal, RegNow, ShareIt. What does this mean ? It means that the server can be used to automatically generate license keys for the products sold via these payment services. Each payment service has a method to call a specified URL (sometimes called "CGI") to generate license keys for a particular product. Since PayPal does not support sending emails with license keys to customers, SoftActivate Licensing Server can send customizable emails to customers, containing automatically generated license keys. The LicensingService.mdf database contains some new tables:
-
The Products table contains information about your products. You can edit this table and add one row for each product sold.
Each row contains the following columns:
- Id. This column specifies the product id. This id can optionally be embedded in the generated license keys
- PayPalId. This column specifies the item number from the PayPal "Buy Now" button used to sell this product. When you create a PayPal "Buy Now" button to sell a product, PayPal asks for an optional "item number". The item number you enter when creating the button must also be inserted in this column.
- RegNowId. This column specifies the RegNow product identifier for your product (eg. "12168-5"). You can get this identifier from the RegNow control panel.
- ShareItId. This column specifies the ShareIt product identifier for your product (eg. "300001285"). You can get this identifier from the ShareIt control panel.
- ProductName. This column specifies the name of your product
- LicenseExpirationDays. If you want your license keys to include an expiration date, set this integer to the number of days after which the license keys will expire. Setting it to 365 means 1 year. The generated license keys will contain an expiration date obtained by adding this number of days to the current date. Note that in order to use this feature you must also insert an appropriate license key template in the LicenseKeyTemplate column: the license key template must contain a data field named "ExpirationDate" with a size of at least 14 bits.
-
LicenseKeyTemplate. This field specifies the XML license key template used for generating license keys. The XML template must be on one line of text, so remove all the newlines from the XML before inserting it into the database. This template's fields specify what is included in the generated license keys.
- If a ProductId integer data field is present, then the Id column value is embedded in the generated license keys.
- If an "ExpirationDate" named integer data field at least 14 bits long is present, then an expiration date (between 01/01/2010 and 12/31/2041) is included in the license key. This expiration date is calculated by adding the value from the LicenseExpirationDays column to the current date. For information about how the expiration date is packed into the 14-bit value and how it can be unpacked, please see samples KeyGenCS (C#) or KeyGenCPP (C++).
- If a "RegistrationName" validation field is present, then the customer name (first name + " " + last name) is used as validation data for key generation, and therefore must be provided at validation time for successful license key validation (for more information please see the documentation for license key validation fields).
- If a "RegistrationEmail" validation field is present, then the customer email (trimmed and lowercased) is used as validation data for key generation, and therefore must be provided at validation time for successful license key validation.
- SupportEmail. In PayPal integration, all the email messages sent to customers appear to come from this email address.
- The Purchases table contains logged information about each product sale. Logged information includes product id, license key, license expiration date, customer name, customer email, customer country, payment amount and payment currency. This table can be used to create sales statistics, to run email marketing campaigns for existing customers, etc.
-
The LicenseKeys table contains information about how certain license keys are behaving when they are used for activation.
The following columns are included in this table:
- Id. Self-incrementing counter for referencing this column.
- ProductId. The product id for which this license key is generated. When a license key is sent from an application to the licensing server, the corresponding product information is looked up using this column.
- LicenseKey. The license key
- MaxUniqueHardwareIds. This specifies the maximum number of distinct computers which can use this license key for activation purposes. Usually best set to NULL for commercial, non-trial license keys (and let the MaxActivations column enforce this limit) and 0 for trial keys, since a trial key is used by many computers. Setting it to 0 means unlimted computers, setting it to NULL causes the DefaultMaxUniqueHardwareIdsPerLicenseKey column for the corresponding product from the Products table to be govern this limit.
- MaxActivationsPerHardwareId. This specifies the maximum number of activations allowed for the same computer. Usually best set to NULL for non-trial license keys (and let the MaxActivations column enforce the limit), and "1" for trial keys. Setting it to 0 means unlimited activations for the same computer, setting it to NULL causes the DefaultMaxUniqueHardwareIdsPerHardwareId for the corresponding product from the Products table to govern this limit.
- MaxActivations. This specifies the maximum total number of activations for a license key, regardless of which computer. Best set to 5-10 for commercial, non-trial license keys (in order to allow for a small number of product and OS reinstallations), and "0" for trial license keys. Setting it to 0 means unlimited number of activations, setting to NULL causes the DefaultMaxActivationsPerLicenseKey column for the corresponding product from the Products table to govern this limit.
- LicenseDuration. This specifies the number of days after which an activation key issued for this license key, expires. For trial keys, set it to the number of trial days (eg. "30"). For commercial keys, set it to how long should this license be valid (eg. "365"). Setting it to 0 means the license will never expire. Setting it to NULL means the DefaultLicenseDuration column for the corresponding product from the Products table to govern this limit.
- LicenseHistoryDuration. This specifies the number of days after which an expired license is not taken into account anymore when limits are calculated (even if a record if this license is still kept in the Activations table). For example, if for a trial license key we set this column to "180" (days) it means that even if that license key was activated once for a certain computer, it will still be allowed a new activation after 180 days (even if the MaxActivationsPerHardwareId was set to "1").
- The LicenseKeysPool table. In case you don't want the license keys to be automatically generated by the licensing server for each sale, you can insert a list of license keys here and for each sale a license key is removed from this table and returned to the payment service (or in the PayPal case, emailed to the customer). This table can be of use if license key generation is very strictly controlled within a company and keys are generated on a secure server not connected to the Internet. If the LicenseKeyTemplate column does not contain a license key template (value is NULL), the server tries to get the license keys from this table.
PayPal Integration
The SoftActivate Licensing Server uses PayPal IPN (Instant Payment Notification) API to both generate license keys for products sold via PayPal, and also send these license keys to customers via customizable email templates. In order to have the SoftActivate Licensing Server automatically generate license keys for your PayPal product:
- Insert a new product into the licensing server database using the licensing server's web control panel, with a chosen product id, product name, license key template, email template, etc.
- Create a "Buy Now" button in your PayPal account, setting the item number to the same product id inserted in the Products table;
- Set the "notify_url" custom variable of the Buy Now button to the following URL: <licensing server url>\PayPal.ashx (example: http://www.mycompany.com/licensingservice/PayPal.ashx )
- Replace the sample SMTP settings with valid settings in the appsettings.json (for .NET) or config.json (for NodeJS) file of the licensing server (set server, port, username, password, ssl yes/no)
- Test the system by setting the product price of the Buy Now button to 0.01 USD (also set the same price of 0.01 in the PaymentAmount of the Products table, don't forget to set the PaymentCurrency column to 'USD') and then place the button on a test web page and effectively press the button and complete a transaction. You should receive an email with a license key.
- Look for any exceptions in the licensing server's control panel, in the 'Event Log' section
RegNow Integration
In order to have the SoftActivate Licensing Server automatically generate license keys for your RegNow products, simply edit the product properties in the RegNow control panel and select the remote CGI license generator option, setting the license key generator URL to: <licensing server url>\RegNow.ashx (example: http://www.mycompany.com/licensingservice/RegNow.ashx ). You must also insert a corresponding product into the licensing server database using the licensing server's web control panel. You can then complete a test order and check if everything works. Look for any exeptions in the licensing server's control panel, in the 'Event Log' section.
ShareIt Integration
In order to have the SoftActivate Licensing Server automatically generate license keys for your ShareIt products, simply edit the product properties in the ShareIt control panel and select the remote CGI license generator option, setting the license key generator URL to: <licensing server url>\ShareIt.ashx (example: http://www.mycompany.com/licensingservice/ShareIt.ashx ). You must also insert a corresponding product into the licensing server database using the licensing server's web control panel. You can then complete a test order and check if everything works. Look for any exeptions in the licensing server's control panel, in the 'Event Log' section.
Preventing unauthorized parties from generating license keys via the payment services handlers
Access to the pages RegNow.ashx and ShareIt.ashx should be restricted in web.config file to only certain IP addresses (see ASP.NET documentation for how to achieve this). Only the authorized IP addresses of the RegNow and ShareIt servers should be allowed to access these pages. These payment services publish their IP addresses in their respective documentation. PayPal already supports a reliable authentication mechanism so accessing the PayPal.ashx page by unauthorized parties is not possible. We will develop this section more in the near future.
Security Guidelines
Using SoftActivate Licensing SDK does not guarantee a complete stop of software piracy or complete license enforcement if some basic security guidelines are not followed. Make sure you follow these guidelines in order to make you application as secure as possible:
- Keep the signing private keys secret. By knowing the private keys used to generate product keys, an unauthorized party can generate keys for your products. It is important to keep your private keys secret, and only distribute you public keys with your application for license key validation purposes.
- Make sure your executable code cannot be altered. By altering your executable code, a malicious user can completely bypass your licensing mechanism. This is a rule to be followed for any licensing solution you would use. There are some professionally available tools that can help in this regard by making it very difficult for unauthorized users to alter the code, but the security is not 100% guaranteed. However, with the arrival of the new hardware-based trusted computing platforms in the near future, preventing executable code altering should become an achievable goal.
- For native code (win32 and x64): Prefer statically linking with the SDK libraries. You should NOT keep your license management software into a separate binary module which can be targeted by malicious parties. Or, if you prefer dynamic linking, make sure you are calling a legitimate dll. The most secure ways to integrate the SDK into your application is via static linking or direct source code embedding.
-
For .NET code: We strongly recommend merging the Licensing.Net.Dll assembly into your main executable and obfuscating your resulting assembly.
Merging can be accomplished using Microsoft ILMerge tool, which is a free tool available here:
http://www.microsoft.com/en-us/download/details.aspx?id=17630.For .NET assembly obfuscation, we recommend the free Eazfuscator.NET tool, available for download here:
http://www.foss.kharkov.ua/g1/projects/eazfuscator/dotnet/Default.aspx. - Perform license checking in different parts of the code, at diffrent program execution times. Ideally, you should not keep your license management software code into a separate binary module which can be targeted by hackers. Or, if you prefer dynamic linking, make sure you are calling a legitimate dll. You could, as a simple example, verify a signature of the licensing library dll before attempting library calls. Of course this rule is to be followed with any licensing solution.
Uninstalling SoftActivate Licensing SDK
To uninstall the SDK, please go to Control Panel -> Add/Remove Programs, right-click on the "SoftActivate Licensing SDK" software and choose "Uninstall"
Programming Reference
KeyGenerator Class
KeyGenerator::KeyGenerator
Initializes a KeyGenerator object.
Prototype
KeyGenerator::KeyGenerator();
Parameters
None.
Return Values
None.
KeyGenerator::~KeyGenerator
Destroys a KeyGenerator object, freeing all associated resources.
Prototype
KeyGenerator::~KeyGenerator();
Parameters
None.
Return Values
None.
KeyGenerator::SetKeyTemplate
Sets the template used to generate license keys.
Prototype
void KeyGenerator::SetKeyTemplate(LicenseTemplate & keyTemplate);
Parameters
-
keyTemplate
[in] The template used to generate license keys.
Return Values
None.
Remarks
None.
KeyGenerator::SetKeyData
Sets the contents of a data field.
Prototype
void KeyGenerator::SetKeyData(const char_t * fieldName, const void * rawData, unsigned len);
void KeyGenerator::SetKeyData(const char_t * fieldName, unsigned intData);
void KeyGenerator::SetKeyData(const char_t * fieldName, const char_t * stringData);
Parameters
-
fieldName
[in] The name of the field for which to set the data. -
rawData
[in] Pointer to a buffer containing the field data. -
len
[in] Length of the rawData buffer. -
intData
[in] An int value to set for the field. -
stringData
[in] A string value to set for the field.
Return Values
None.
Remarks
If the field size (as specified in the template) is smaller than the data size, the data is truncated to fit the field.
KeyGenerator::SetValidationData
Sets the contents of a validation field.
Prototype
void KeyGenerator::SetValidationData(const char_t * fieldName, const void * rawData, unsigned len);
void KeyGenerator::SetValidationData(const char_t * fieldName, unsigned intData);
void KeyGenerator::SetValidationData(const char_t * fieldName, const char_t * stringData);
Parameters
-
fieldName
[in] The name of the field for which to set the data. -
rawData
[in] Pointer to a buffer containing the field data. -
len
[in] Length of the rawData buffer. -
intData
[in] An int value to set for the field. -
stringData
[in] A string value to set for the field.
Return Values
None.
Remarks
If the field size (as specified in the template) is smaller than the data size, the data is truncated to fit the field.
KeyGenerator::GenerateKey
Generates a license key.
Prototype
const char_t * LicenseTemplate::GenerateKey();
Parameters
None.
Return Values
Pointer to a NULL-terminated string containing the license key. This string is statically allocated, do not attempt to free it.
KeyValidator Class
KeyValidator::KeyValidator
Initializes a KeyValidator object.
Prototype
KeyValidator::KeyValidator();
Parameters
None.
Return Values
None.
KeyValidator::~KeyValidator
Destroys a KeyValidator object, freeing all associated resources.
Prototype
KeyValidator::~KeyValidator();
Parameters
None.
Return Values
None.
KeyValidator::SetKeyTemplate
Sets the template used to generate license keys.
Prototype
void KeyValidator::SetKeyTemplate(LicenseTemplate & keyTemplate);
Parameters
-
keyTemplate
[in] The template used to generate license keys.
Return Values
None.
Remarks
None.
KeyValidator::SetValidationData
Sets the contents of a validation field.
Prototype
void KeyValidator::SetValidationData(const char_t * fieldName, const void * rawData, unsigned len);
void KeyValidator::SetValidationData(const char_t * fieldName, unsigned intData);
void KeyValidator::SetValidationData(const char_t * fieldName, const char_t * stringData);
Parameters
-
fieldName
[in] The name of the field for which to set the data. -
rawData
[in] Pointer to a buffer containing the field data. -
len
[in] Length of the rawData buffer. -
intData
[in] An int value to set for the field. -
stringData
[in] A string value to set for the field.
Return Values
None.
Remarks
If the field size (as specified in the template) is smaller than the data size, the data is truncated to fit the field.
KeyValidator::SetKey
Sets the license key to validate and to query data from.
Prototype
void KeyValidator::SetKey(const char_t * licenseKey);
Parameters
-
licenseKey
[in] A NULL-terminated string containing the license key.
Return Values
None.
Remarks
None.
KeyValidator::IsKeyValid
Validates the license key set using KeyValidator::SetKey().
Prototype
bool KeyValidator::IsKeyValid();
Parameters
None.
Return Values
Returns true if the license key is valid, false if not.
Remarks
None.
KeyValidator::QueryKeyData
Obtains data from the license key.
Prototype
void KeyValidator::QueryKeyData(const char_t * fieldName, void * buf, unsigned * len);
Parameters
-
fieldName
[in] The name of the field to query the data from. -
buf
[out] Pointer to a buffer receiving the field data. -
len
[in, out] Pointer to an integer receiving the data size in bytes. At input, this must contain the buffer size in bytes.
Return Values
None.
Remarks
None.
LicensingClient Class
LicensingClient::LicensingClient
Constructs a LicensingClient object.
Prototype
LicensingClient::LicensingClient();
Parameters
None.
Return Values
None.
LicensingClient::SetLicensingServiceUrl
This method is used to set the url of the licensing service.
Prototype
void LicensingClient::SetLicensingServiceUrl(const char * url);
Parameters
-
url
[in] The URL of the licensing service
Return Values
None.
Remarks
None.
LicensingClient::SetLicenseTemplate
This method is used to set the license template for the licensing client. The template defines the license key format, validation parameters, and cryptographic settings that will be used for license validation and activation.
Prototype
void LicensingClient::SetLicenseTemplate(LicenseTemplate * tmpl);
Parameters
-
tmpl
[in] Pointer to the license template object containing the license key format and validation settings
Return Values
None.
Remarks
The license template must be properly configured with the public key certificate and other validation parameters before being set.
LicensingClient::SetActivationKey
This method is used to set the activation key used in the activation verification process.
Prototype
void LicensingClient::SetActivationKey(const char * key);
Parameters
-
key
[in] The activation key that was returned by the activation server at activation time.
Return Values
None.
Remarks
None.
LicensingClient::GetActivationKey
This method is used to retrieve the activation key returned by the licensing service after software activation.
Prototype
const char * LicensingClient::GetActivationKey();
Parameters
None.
Return Values
Returns a pointer to the activation key string, or NULL if no activation key has been acquired yet.
Remarks
This method should be called after a successful license acquisition to retrieve the activation key for storage.
LicensingClient::SetLicenseKey
This method is used to set the product key (license key) of the product. The activation server needs the key in order to generate an activation key. The product key is also used when validating the activation key.
Prototype
void LicensingClient::SetLicenseKey(const char * key);
Parameters
-
key
[in] The license key.
Return Values
None.
Remarks
None.
LicensingClient::SetHardwareId
This method is used to set the hardware id string previously saved after the product's activation process. This string is used during activation validation.
Prototype
void LicensingClient::SetHardwareId(const char * hwid);
Parameters
-
hwid
[in] The hardware id string that identifies the current machine.
Return Values
None.
Remarks
If not set explicitly, the hardware ID will be automatically generated using the current system's hardware characteristics.
LicensingClient::GetHardwareId
This method is used to retrieve the hardware id generated by the SDK or previously set, which is used in the activation process.
Prototype
const char * LicensingClient::GetHardwareId();
Parameters
None.
Return Values
Returns a pointer to the hardware id string that uniquely identifies the current machine.
Remarks
This hardware ID is automatically generated based on the machine's characteristics and should remain consistent across application runs on the same machine.
LicensingClient::AcquireLicense
This method sends the product key and hardware id to the licensing service, and receives the signed activation key.
Prototype
void LicensingClient::AcquireLicense();
Parameters
None.
Return Values
None.
Remarks
This method contacts the licensing service over the internet to validate the license and obtain an activation key.
LicensingClient::SetLicenseKeyValidationData
This method is used to set additional validation data required for license key validation, such as registration names or other customer-specific information.
Prototype
void LicensingClient::SetLicenseKeyValidationData(void * buf, int len);
Parameters
-
buf
[in] Pointer to a buffer containing the validation data. -
len
[in] Length of the validation data buffer in bytes.
Return Values
None.
Remarks
This validation data must match what was used during license key generation.
LicensingClient::SetLicenseTemplateId
This method is used to set the template ID that identifies the specific license template configuration on the licensing service.
Prototype
void LicensingClient::SetLicenseTemplateId(const char * templateId);
Parameters
-
templateId
[in] The template ID string that identifies the license configuration.
Return Values
None.
Remarks
This template ID must correspond to a valid template configured on the licensing service.
LicensingClient::ValidateLicense
This method validates a license using the provided validation arguments and returns detailed validation results.
Prototype
LicenseValidationResult * LicensingClient::ValidateLicense(LicenseValidationArgs * args);
Parameters
-
args
[in] Pointer to a LicenseValidationArgs object containing the license key and validation data.
Return Values
Returns a pointer to a LicenseValidationResult object containing detailed validation information, or NULL if validation fails.
Remarks
This method provides more detailed validation results than the simple IsLicenseValid method.
Remarks
None.
LicensingClient::IsLicenseValid
This method checks if the activation key signature and then checks if the hardware id matches this computer.
Prototype
void LicensingClient::IsLicenseValid();
Parameters
None.
Return Values
true if the activation key is valid, the hardware id matches this computer and the license is not expired. false otherwise.
Remarks
None.
LicensingClient::GetLicenseActivationStatus
This method retrieves the activation status after a call to IsLicenseValid().
Prototype
int LicensingClient::GetLicenseActivationStatus();
Parameters
None.
Return Values
A LICENSE_STATUS value which can be: Valid (0), Invalid (1), InvalidHardwareId (12), Expired (13), InvalidActivationKey (14), PaymentRequired (15)
Remarks
This method should be called after IsLicenseValid() to get detailed information about why validation failed.
LicensingClient::GetLicenseExpirationDate
This method retrieves the expiration date of the license if it has one.
Prototype
void LicensingClient::GetLicenseExpirationDate(int * year, int * month, int * day);
Parameters
-
year
[out] Pointer to an integer receiving the expiration year. -
month
[out] Pointer to an integer receiving the expiration month (1-12). -
day
[out] Pointer to an integer receiving the expiration day (1-31).
Return Values
None.
Remarks
If the license has no expiration date, all values will be set to 0.
LicensingClient::SetTimeValidationMethod
This method sets how the SDK should validate time-based license restrictions such as expiration dates.
Prototype
void LicensingClient::SetTimeValidationMethod(int method);
Parameters
-
method
[in] Time validation method: PREFER_INTERNET_TIME (0, default), USE_INTERNET_TIME (1), or USE_LOCAL_TIME (2).
Return Values
None.
Remarks
PREFER_INTERNET_TIME tries to get time from an NTP server but falls back to local time if unavailable. USE_INTERNET_TIME requires successful NTP time retrieval. USE_LOCAL_TIME only uses the system clock.
LicenseTemplate Class
LicenseTemplate::LicenseTemplate
Constructs a LicenseTemplate object.
Prototype
LicenseTemplate::LicenseTemplate();
Parameters
None.
Return Values
None.
LicenseTemplate::~LicenseTemplate
Destroys a LicenseTemplate object freeing all associated resources.
Prototype
LicenseTemplate::~LicenseTemplate();
Parameters
None.
Return Values
None.
LicenseTemplate::SetNumberOfGroups
This method is used to set the number of character groups a license key contains.
Prototype
void LicenseTemplate::SetNumberOfGroups(unsigned numGroups);
Parameters
-
numGroups
[in] The number of character groups in the license key.
Return Values
None.
Remarks
None.
LicenseTemplate::GetNumberOfGroups
Gets the number of character groups contained by a license key.
Prototype
unsigned LicenseTemplate::GetNumberOfGroups();
Parameters
None.
Return Values
The number of groups.
Remarks
None.
LicenseTemplate::SetCharactersPerGroup
Sets the number of characters in each license key character group.
Prototype
void LicenseTemplate::SetCharactersPerGroup(unsigned charsPerGroup);
Parameters
-
charsPerGroup
[in] The number of characters per group.
Return Values
None.
Remarks
None.
LicenseTemplate::GetCharactersPerGroup
Gets the number of characters in each license key character group.
Prototype
unsigned LicenseTemplate::GetCharactersPerGroup();
Parameters
None.
Return Values
The number of characters per group.
Remarks
None.
LicenseTemplate::SetVersion
Sets the license key template version.
Prototype
void LicenseTemplate::SetVersion(unsigned version);
Parameters
-
version
[in] The template version.
Return Values
None.
Remarks
The default version is 1. In this SDK version, specifying any other version than 1 will cause an exception to be thrown.
LicenseTemplate::GetVersion
Retrieves the license key template version.
Prototype
unsigned LicenseTemplate::GetVersion();
Parameters
None.
Return Values
The license key template version. Currently, a value of 1 is returned.
Remarks
None.
LicenseTemplate::SetGroupSeparator
Sets the string or character that separates license key character groups.
Prototype
void LicenseTemplate::SetGroupSeparator(const char_t * groupSeparator);
Parameters
-
groupSeparator
[in] The group separator string.
Return Values
None.
Remarks
The default group separator is the character '-'.
LicenseTemplate::GetGroupSeparator
Sets the string or character that separates license key character groups.
Prototype
const char_t * LicenseTemplate::GetGroupSeparator();
Parameters
None.
Return Values
Pointer to a string containing the license key group separator string.
Remarks
The returned string is statically allocated and must not be freed.
LicenseTemplate::SetEncoding
Sets the character encoding for the license key.
Prototype
void LicenseTemplate::SetEncoding(LICENSE_KEY_ENCODING encoding);
Parameters
-
encoding
[in] The character encoding. This can be on of ENCODING_BASE32X or ENCODING_BASE64X.
Return Values
None.
Remarks
None.
LicenseTemplate::GetEncoding
Gets the encoding used for the license keys.
Prototype
LICENSE_KEY_ENCODING LicenseTemplate::GetEncoding();
Parameters
None.
Return Values
The encoding used. This can be either ENCODING_BASE32X or ENCODING_BASE64X.
Remarks
None.
LicenseTemplate::SetHeader
Sets the contents of an optional line of text preceding the license key.
Prototype
void LicenseTemplate::SetHeader(const char_t * header);
Parameters
-
header
[in] The header string.
Return Values
None.
Remarks
None.
LicenseTemplate::GetHeader
Gets the encoding used for the license keys.
Prototype
const char_t * LicenseTemplate::GetHeader();
Parameters
None.
Return Values
The license key header.
Remarks
The returned string is statically allocated and must not be freed.
LicenseTemplate::SetFooter
Sets the contents of an optional line following the license key.
Prototype
void LicenseTemplate::SetFooter(const char_t * header);
Parameters
-
header
[in] The header string.
Return Values
None.
Remarks
None.
LicenseTemplate::GetFooter
Gets the encoding used for the license keys.
Prototype
const char_t * LicenseTemplate::GetFooter();
Parameters
None.
Return Values
The license key footer.
Remarks
The returned string is statically allocated and must not be freed.
LicenseTemplate::SetDataSize
Sets the size of data embedded in the license key.
Prototype
void LicenseTemplate::SetDataSize(unsigned dataSize);
Parameters
-
dataSize
[in] The size of data in bits.
Return Values
None.
Remarks
This method could throw an exception if the data size is too big for the chosen key format parameters and signature size.
LicenseTemplate::GetDataSize
Retrieves the size of data embedded in the license key.
Prototype
unsigned LicenseTemplate::GetDataSize();
Parameters
None.
Return Values
The size in bits of the embedded license key data.
Remarks
None.
LicenseTemplate::AddDataField
Adds a field of data which will be included in the license key.
Prototype
void LicenseTemplate::AddDataField(const char_t * fieldName, FIELD_TYPE fieldType, unsigned sizeInBits, unsigned startPos = -1);
Parameters
-
fieldName
[in] The name of the data field. -
fieldType
[in] The type of the data field. It can be one of FIELD_TYPE_INTEGER, FIELD_TYPE_STRING, FIELD_TYPE_RAW. -
sizeInBits
[in] The size of the data field in bits. -
startPos
[in] The starting position (relative to bit 0) of the field in the license key data. Omitting this value adds the field to the next available position.
Return Values
None.
Remarks
This method could throw an exception if the field size is too big for the chosen data size.
LicenseTemplate::EnumDataFields
Enumerates license key data fields.
Prototype
bool EnumDataFields(void **enumHandle, char_t * fieldName, unsigned * fieldNameSize, FIELD_TYPE * fieldType, unsigned * fieldSize, unsigned * startPos);
Parameters
-
enumHandle
[in, out] Pointer to a pointer used to store a handle to the enumeration state. A pointer to a NULL handle must be passed at the first call. -
fieldName
[in, out] Pointer to a buffer which will be filled with the field name. -
fieldNameSize
[in, out] Pointer to an unsigned which will receive the size of the field name string. At input this must contain the size of the buffer. -
fieldType
[out] Pointer who will receive the type of the field. -
fieldSize
[out] Pointer to an unsigned who will receive the field size in bits. -
startPos
[out] Pointer to an unsigned who will receive the field start position in license key data.
Return Values
If the enumeration is over, returns false and the output parameters are not filled. Otherwise returns true.
Remarks
None.
LicenseTemplate::SetValidationDataSize
Sets the size of the data used to validate the license key.
Prototype
void LicenseTemplate::SetValidationDataSize(unsigned sizeInBits);
Parameters
-
sizeInBits
[in] The size of validation data in bits.
Return Values
None.
Remarks
None.
LicenseTemplate::GetValidationDataSize
Retrieves the size of the data used to validate the license key.
Prototype
unsigned LicenseTemplate::GetValidationDataSize();
Parameters
None.
Return Values
The size in bits of the validation data.
Remarks
None.
LicenseTemplate::AddValidationDataField
Adds a field of data used for license key validation. Validation fields are not included in the license key, but they are used for validation.
Prototype
void LicenseTemplate::AddValidationDataField(const char_t * fieldName, FIELD_TYPE fieldType, unsigned sizeInBits, unsigned startPos = -1);
Parameters
-
fieldName
[in] The name of the data field. -
fieldType
[in] The type of the field. It can be one of FIELD_TYPE_INTEGER, FIELD_TYPE_STRING, FIELD_TYPE_RAW. -
sizeInBits
[in] The size of the field in bits. -
startPos
[in] The starting position (relative to bit 0) of the field in the license key validation data. Omitting this value adds the field to the next available position.
Return Values
None.
Remarks
This method could throw an exception if the field size is too big for the chosen validation data size.
LicenseTemplate::EnumDataFields
Enumerates the fields of data used for license key validation.
Prototype
bool EnumValidationFields(void **enumHandle, char_t * fieldName, unsigned * fieldNameSize, FIELD_TYPE * fieldType, unsigned * fieldSize, unsigned * startPos);
Parameters
-
enumHandle
[in, out] Pointer to a pointer used to store a handle to the enumeration state. A pointer to a NULL handle must be passed at the first call. -
fieldName
[in, out] Pointer to a buffer which will be filled with the field name. -
fieldNameSize
[in, out] Pointer to an unsigned which will receive the size of the field name string. At input this must contain the size of the buffer. -
fieldType
[out] Pointer who will receive the type of the field. -
fieldSize
[out] Pointer to an unsigned who will receive the field size in bits. -
startPos
[out] Pointer to an unsigned who will receive the field start position in license key data.
Return Values
If the enumeration is over, returns false and the output parameters are not filled. Otherwise returns true.
Remarks
None.
LicenseTemplate::SetSignatureSize
This method is used to set the license key signature size.
Prototype
void LicenseTemplate::SetSignatureSize(unsigned size);
Parameters
-
size
[in] The desired size for the license key signature. The size must be in the 76-322 range.
Return Values
None.
Remarks
The license key signature size governs license key security. Care must be taken when choosing the signature size.
LicenseTemplate::GetSignatureSize
Retrieves the size of the data used to validate the license key.
Prototype
unsigned LicenseTemplate::GetSignatureSize();
Parameters
None.
Return Values
The signature size in bits.
Remarks
None.
LicenseTemplate::LoadXml
Loads license key template parameters from an XML string.
Prototype
void LicenseTemplate::LoadXml(char * xmlString);
Parameters
-
xmlString
[in] The XML template representation string, UTF-8 encoded.
Return Values
None.
Remarks
This method throws an exception if the template string is invalid.
LicenseTemplate::SaveXml
Saves the XML representation of the template into a string.
Prototype
const char * LicenseTemplate::SaveXml(bool savePrivateKey = true);
Parameters
-
savePrivateKey
[in] Whether to include the private key in the XML output.
Return Values
Pointer to a string containing an UTF-8 encoded XML representation of the template parameters.
Remarks
The returned string is statically allocated and should not be freed.
LicenseTemplate::LoadJson
Loads the template parameters from a JSON string.
Prototype
void LicenseTemplate::LoadJson(const char * jsonTemplate);
Parameters
-
jsonTemplate
[in] A JSON string containing the template parameters.
Return Values
None.
Remarks
This method throws an exception if the JSON template string is invalid.
LicenseTemplate::SaveJson
Saves the JSON representation of the template into a string.
Prototype
const char * LicenseTemplate::SaveJson(bool savePrivateKey = true);
Parameters
-
savePrivateKey
[in] Whether to include the private key in the JSON output.
Return Values
Pointer to a string containing a UTF-8 encoded JSON representation of the template parameters.
Remarks
The returned string is statically allocated and should not be freed.
LicenseTemplate::SetPublicKeyCertificate
Sets the public key certificate used for license key validation.
Prototype
void LicenseTemplate::SetPublicKeyCertificate(const char * base64Certificate);
Parameters
-
base64Certificate
[in] Base64-encoded public key certificate string.
Return Values
None.
Remarks
The public key certificate is used to verify the digital signatures of license keys.
LicenseTemplate::GetPublicKeyCertificate
Gets the public key certificate.
Prototype
const char * LicenseTemplate::GetPublicKeyCertificate();
Parameters
None.
Return Values
Returns a pointer to the Base64-encoded public key certificate string.
Remarks
The returned string is statically allocated and should not be freed.
LicenseTemplate::SetPrivateKey
Sets the private key used for license key generation and signing.
Prototype
void LicenseTemplate::SetPrivateKey(const char * base64PrivateKey);
Parameters
-
base64PrivateKey
[in] Base64-encoded private key string.
Return Values
None.
Remarks
The private key is only needed for license key generation. Keep the private key secret and secure.
LicenseTemplate::GetPrivateKey
Gets the private key.
Prototype
const char * LicenseTemplate::GetPrivateKey();
Parameters
None.
Return Values
Returns a pointer to the Base64-encoded private key string.
Remarks
The returned string is statically allocated and should not be freed.
LicenseTemplate::SetLicensingServiceUrl
Sets the URL of the licensing service used for license activation.
Prototype
void LicenseTemplate::SetLicensingServiceUrl(const char * url);
Parameters
-
url
[in] The URL of the licensing service.
Return Values
None.
LicenseTemplate::GetLicensingServiceUrl
Gets the URL of the licensing service.
Prototype
const char * LicenseTemplate::GetLicensingServiceUrl();
Parameters
None.
Return Values
Returns a pointer to the licensing service URL string.
LicenseTemplate::SetTemplateId
Sets the template ID that identifies this template configuration on the licensing service.
Prototype
void LicenseTemplate::SetTemplateId(const char * templateId);
Parameters
-
templateId
[in] The template ID string.
Return Values
None.
LicenseTemplate::GetTemplateId
Gets the template ID.
Prototype
const char * LicenseTemplate::GetTemplateId();
Parameters
None.
Return Values
Returns a pointer to the template ID string.
LicenseTemplate::GenerateSigningKeyPair
Generates a pair of private/public keys used for license key generation/validation.
Prototype
void LicenseTemplate::GenerateSigningKeyPair();
Parameters
None.
Return Values
None.
Remarks
The signing key pair is generated according to the signature size, so you must call LicenseTemplate::SetSignatureSize() first. You can retrieve the generated keys using LicenseTemplate::GetPrivateKey(), LicenseTemplate::GetPublicKeyCertificate() or LicenseTemplate::SaveXml().
KeyHelper Class
KeyHelper::GetCurrentHardwareId
Returns a string which uniquely identifies the device (computer) on which the method is called.
Prototype
static string KeyHelper::GetCurrentHardwareId();
Parameters
None.
Return Values
The hardware id string.
Note that this method is not thread safe.
KeyHelper::MatchCurrentHardwareId
Checks if the supplied harware id string matches this computer. Note that there are certain hardware components changes permitted until this method returns false.
Prototype
static bool KeyHelper::MatchCurrentHardwareId(string hardwareId);
Parameters
-
hardwareId
[in] The hardware id to be matched to the current hardware state of this computer.
Return Values
A bool value specifying if the computer matches the supplied hardware id
KeyHelper::DetectClockManipulation
This method is used to find evidence that the clock was deliberately turned back with the purpose of prolonging license validity.
Prototype
bool KeyHelper::DetectClockManipulation(DateTime thresholdDate);
Parameters
-
thresholdDate
[in] The method searches for evidence that the system time was once set after the threshold date
Return Values
A bool value indicating if evidence was found that the system clock was deliberately turned back.
Remarks
This method may take a few seconds to complete so it is best to call it on a worker thread.
License Class
License::License
Constructs a License object.
Prototype
License::License();
Parameters
None.
Return Values
None.
License::LoadXml
Loads license information from an XML string.
Prototype
void License::LoadXml(const char * xml);
Parameters
-
xml
[in] XML string containing the license data.
Return Values
None.
License::SaveXml
Saves the license information to an XML string.
Prototype
const char * License::SaveXml();
Parameters
None.
Return Values
Returns a pointer to an XML string containing the license data.
License::LoadJson
Loads license information from a JSON string.
Prototype
void License::LoadJson(const char * json);
Parameters
-
json
[in] JSON string containing the license data.
Return Values
None.
License::SaveJson
Saves the license information to a JSON string.
Prototype
const char * License::SaveJson();
Parameters
None.
Return Values
Returns a pointer to a JSON string containing the license data.
LicenseValidationArgs Class
LicenseValidationArgs::LicenseValidationArgs
Constructs a LicenseValidationArgs object with a license and license key.
Prototype
LicenseValidationArgs::LicenseValidationArgs(License * license, const char * licenseKey);
Parameters
-
license
[in] Pointer to the License object. -
licenseKey
[in] The license key string to validate.
Return Values
None.
LicenseValidationArgs::SetIntLicenseKeyValidationData
Sets integer validation data for the license key.
Prototype
void LicenseValidationArgs::SetIntLicenseKeyValidationData(const char * fieldName, int fieldValue);
Parameters
-
fieldName
[in] The name of the validation field. -
fieldValue
[in] The integer value for the validation field.
Return Values
None.
LicenseValidationArgs::SetStringLicenseKeyValidationData
Sets string validation data for the license key.
Prototype
void LicenseValidationArgs::SetStringLicenseKeyValidationData(const char * fieldName, const char * fieldValue);
Parameters
-
fieldName
[in] The name of the validation field. -
fieldValue
[in] The string value for the validation field.
Return Values
None.
LicenseValidationArgs::SetDateLicenseKeyValidationData
Sets date validation data for the license key.
Prototype
void LicenseValidationArgs::SetDateLicenseKeyValidationData(const char * fieldName, int year, int month, int day);
Parameters
-
fieldName
[in] The name of the validation field. -
year
[in] The year component of the date. -
month
[in] The month component of the date (1-12). -
day
[in] The day component of the date (1-31).
Return Values
None.
LicenseValidationArgs::SetLicenseKeyValidationData
Sets raw binary validation data for the license key.
Prototype
void LicenseValidationArgs::SetLicenseKeyValidationData(const char * fieldName, void * data, int len);
Parameters
-
fieldName
[in] The name of the validation field. -
data
[in] Pointer to the binary data. -
len
[in] Length of the binary data in bytes.
Return Values
None.
LicenseValidationResult Class
LicenseValidationResult::GetLicense
Retrieves the License object associated with this validation result.
Prototype
License * LicenseValidationResult::GetLicense();
Parameters
None.
Return Values
Returns a pointer to the License object.
LicenseValidationResult::IsLicenseExpired
Checks if the license has expired.
Prototype
bool LicenseValidationResult::IsLicenseExpired();
Parameters
None.
Return Values
Returns true if the license has expired, false otherwise.
LicenseValidationResult::IsPaymentRequired
Checks if payment is required for this license.
Prototype
bool LicenseValidationResult::IsPaymentRequired();
Parameters
None.
Return Values
Returns true if payment is required, false otherwise.
LicenseValidationResult::GetLicenseValidityDays
Gets the number of days the license remains valid.
Prototype
int LicenseValidationResult::GetLicenseValidityDays();
Parameters
None.
Return Values
Returns the number of days remaining until expiration, or -1 if the license has no expiration date.
LicenseValidationResult::GetLicenseExpirationDate
Gets the expiration date of the license.
Prototype
void LicenseValidationResult::GetLicenseExpirationDate(int * year, int * month, int * day);
Parameters
-
year
[out] Pointer to receive the expiration year. -
month
[out] Pointer to receive the expiration month (1-12). -
day
[out] Pointer to receive the expiration day (1-31).
Return Values
None.
Remarks
If the license has no expiration date, all values will be set to 0.
SDKRegistration Class
SDKRegistration::SetLicenseKey
Initializes the SDK by entering the purchased SDK license key. This method must NOT be called if the SDK will only be used for license key validation or client-side software activation, as for example in your end-user application. This should be the first method called before using the SDK for license key generation or public/private key pair generation, as for example in your key generator application. If this method is not called when the SDK will be used for license key generation or public/private key pair generation, the SDK will function in DEMO mode, which means that only certain private/public keys are generated and accepted by the SDK for generating license keys. Since the predefined demo private keys can be generated by anyone, these are not secure to use in generating license keys.
Prototype
static void SDKRegistration::SetLicenseKey(const char * licenseKey); (C++)
SDKRegistration.SetLicenseKey(string licenseKey) (C#)
Parameters
-
licenseKey
[in] The purchased license key
Return Values
None.
SDKRegistration::IsRegistered
Checks if the SDK has been registered with a valid license key.
Prototype
static bool SDKRegistration::IsRegistered(); (C++)
SDKRegistration.IsRegistered() (C#)
Parameters
None.
Return Values
Returns true if the SDK has been successfully registered with a valid license key, false otherwise.
Quick Start Guide
This section provides step-by-step examples for common licensing scenarios to help you get started quickly.
Basic License Key Validation
Here's how to implement basic license key validation in your application:
C# Example
using SoftActivate.Licensing;
// Create a license template (use your own keys in production)
LicenseTemplate template = new LicenseTemplate();
template.LoadXml("<LicenseTemplate version=\"5\">...</LicenseTemplate>");
// Validate a license key
KeyValidator validator = new KeyValidator(template);
validator.SetKey("YOUR-LICENSE-KEY-HERE");
if (validator.IsValid())
{
Console.WriteLine("License is valid!");
// Get validation data
string productName = validator.GetValidationDataString("ProductName");
int version = validator.GetValidationDataInteger("Version");
Console.WriteLine($"Product: {productName}, Version: {version}");
}
else
{
Console.WriteLine("Invalid license key");
}
C++ Example
#include "licensing.h"
// Create template and validator
LicenseTemplate* pTemplate = CreateLicenseTemplate();
pTemplate->LoadXml("<LicenseTemplate version=\"5\">...</LicenseTemplate>");
KeyValidator* pValidator = CreateKeyValidator(pTemplate);
pValidator->SetKey("YOUR-LICENSE-KEY-HERE");
if (pValidator->IsValid())
{
printf("License is valid!\n");
// Get validation data
const char* productName = pValidator->GetValidationDataString("ProductName");
int version = pValidator->GetValidationDataInteger("Version");
printf("Product: %s, Version: %d\n", productName, version);
}
else
{
printf("Invalid license key\n");
}
// Clean up
pValidator->Release();
pTemplate->Release();
Trial License Implementation
Implement trial versions with grace periods and expiration handling:
using SoftActivate.Licensing;
public class TrialManager
{
private LicenseTemplate template;
private KeyValidator validator;
public bool IsTrialValid()
{
// Check if trial period has expired
validator = new KeyValidator(template);
validator.SetKey(GetStoredTrialKey());
if (!validator.IsValid())
return false;
// Check expiration date
DateTime expiryDate = validator.GetValidationDataDateTime("ExpiryDate");
if (DateTime.Now > expiryDate)
{
// Grace period check
TimeSpan gracePeriod = TimeSpan.FromDays(7);
if (DateTime.Now > expiryDate.Add(gracePeriod))
return false;
// Show grace period warning
ShowGracePeriodWarning(expiryDate.Add(gracePeriod) - DateTime.Now);
}
return true;
}
public int GetRemainingTrialDays()
{
DateTime expiryDate = validator.GetValidationDataDateTime("ExpiryDate");
TimeSpan remaining = expiryDate - DateTime.Now;
return Math.Max(0, remaining.Days);
}
}
UI Integration with UILicenseManager
For easy UI integration, use the UILicenseManager class:
using SoftActivate.Licensing.UI;
public partial class MainForm : Form
{
private UILicenseManager licenseManager;
public MainForm()
{
InitializeComponent();
InitializeLicensing();
}
private void InitializeLicensing()
{
// Create license template
LicenseTemplate template = new LicenseTemplate();
template.LoadXml(GetEmbeddedTemplate()); // Load from resources
// Initialize UI license manager
licenseManager = new UILicenseManager(template);
licenseManager.LicenseAcquired += OnLicenseAcquired;
licenseManager.LicenseExpired += OnLicenseExpired;
// Check license on startup
if (!licenseManager.IsLicenseValid())
{
licenseManager.ShowLicenseDialog();
}
}
private void OnLicenseAcquired(object sender, EventArgs e)
{
// License successfully acquired/validated
EnableFullFeatures();
}
private void OnLicenseExpired(object sender, EventArgs e)
{
// Handle license expiration
ShowExpirationDialog();
}
}
Server Integration for Online Activation
Implement online activation using the LicensingClient class:
using SoftActivate.Licensing;
public class OnlineActivation
{
private LicensingClient client;
private string hardwareId;
public async Task<bool> ActivateLicense(string licenseKey)
{
try
{
// Get hardware ID
hardwareId = KeyHelper.GetHardwareId();
// Create licensing client
LicenseTemplate template = LoadTemplate();
client = new LicensingClient(
"https://your-server.com/activate",
template,
licenseKey,
null,
hardwareId
);
// Set up event handlers
client.LicensingComplete += OnActivationComplete;
client.LicensingException += OnActivationError;
// Start activation process
client.BeginAcquireLicense();
return true;
}
catch (Exception ex)
{
HandleActivationError(ex);
return false;
}
}
private void OnActivationComplete()
{
// Store activation data
SaveActivationData(client.ActivationKey, client.HardwareId);
MessageBox.Show("License activated successfully!");
}
private void OnActivationError(Exception ex)
{
MessageBox.Show($"Activation failed: {ex.Message}");
}
}
Common Integration Patterns
This section covers common patterns and best practices for integrating the SDK into different types of applications.
Subscription License Handling
Handle subscription-based licenses with automatic renewal checks:
public class SubscriptionManager
{
private Timer renewalTimer;
private LicensingClient client;
public void StartSubscriptionMonitoring()
{
// Check renewal every 24 hours
renewalTimer = new Timer(24 * 60 * 60 * 1000);
renewalTimer.Elapsed += CheckRenewal;
renewalTimer.Start();
}
private void CheckRenewal(object sender, ElapsedEventArgs e)
{
try
{
// Validate current license
LicenseValidationArgs args = new LicenseValidationArgs
{
LicenseKey = GetStoredLicenseKey(),
ValidateExpiration = true,
ConnectToServer = true
};
LicenseValidationResult result = client.ValidateLicense(args);
if (!result.IsValid)
{
if (result.Status == LICENSE_STATUS.EXPIRED)
{
HandleSubscriptionExpired();
}
else if (result.Status == LICENSE_STATUS.SERVER_ERROR)
{
// Retry later on server errors
ScheduleRetry();
}
}
else
{
// Update local license data
UpdateLocalLicenseData(result);
}
}
catch (Exception ex)
{
LogError($"Subscription check failed: {ex.Message}");
}
}
}
Hardware Locking Implementation
Implement hardware locking to prevent license key sharing:
public class HardwareLockingManager
{
public bool ValidateHardwareLock(string licenseKey, string storedHardwareId)
{
// Get current hardware ID
string currentHardwareId = KeyHelper.GetHardwareId();
// Compare with stored hardware ID
if (storedHardwareId != currentHardwareId)
{
// Hardware has changed - validate with server
return ValidateHardwareChange(licenseKey, currentHardwareId);
}
return true;
}
private bool ValidateHardwareChange(string licenseKey, string newHardwareId)
{
try
{
// Contact server to validate hardware change
LicensingClient client = new LicensingClient(
serverUrl, template, licenseKey, null, newHardwareId
);
// Server will decide if hardware change is allowed
client.AcquireLicense();
// Update stored hardware ID
UpdateStoredHardwareId(newHardwareId);
return true;
}
catch (Exception ex)
{
// Hardware change not allowed or server error
ShowHardwareChangeError(ex.Message);
return false;
}
}
}
Error Handling and Validation Best Practices
Implement robust error handling for various failure scenarios:
public class LicenseValidator
{
public ValidationResult ValidateLicense(string licenseKey)
{
ValidationResult result = new ValidationResult();
try
{
KeyValidator validator = new KeyValidator(template);
validator.SetKey(licenseKey);
if (!validator.IsValid())
{
result.IsValid = false;
result.ErrorCode = "INVALID_KEY";
result.Message = "The license key format is invalid";
return result;
}
// Check expiration
if (validator.HasValidationData("ExpiryDate"))
{
DateTime expiry = validator.GetValidationDataDateTime("ExpiryDate");
if (DateTime.Now > expiry)
{
result.IsValid = false;
result.ErrorCode = "EXPIRED";
result.Message = $"License expired on {expiry:yyyy-MM-dd}";
return result;
}
}
// Check hardware lock
if (validator.HasValidationData("HardwareId"))
{
string expectedHw = validator.GetValidationDataString("HardwareId");
string currentHw = KeyHelper.GetHardwareId();
if (expectedHw != currentHw)
{
result.IsValid = false;
result.ErrorCode = "HARDWARE_MISMATCH";
result.Message = "License is locked to different hardware";
return result;
}
}
result.IsValid = true;
result.Message = "License is valid";
}
catch (LicensingException ex)
{
result.IsValid = false;
result.ErrorCode = "LICENSING_ERROR";
result.Message = ex.Message;
}
catch (Exception ex)
{
result.IsValid = false;
result.ErrorCode = "UNEXPECTED_ERROR";
result.Message = "An unexpected error occurred during validation";
}
return result;
}
}
Troubleshooting and Common Issues
This section covers common problems developers encounter and their solutions.
License Generation Issues
- SDK Registration Required: Ensure your SDK license key is properly registered using
SDKRegistration.SetLicenseKey() - Template Configuration: Verify your license template XML/JSON is valid and matches between generation and validation
- Private Key Access: Make sure the private key is accessible for key generation (not needed for validation)
- Validation Data Fields: Ensure all required data fields are set before generating keys
License Validation Failures
- Template Mismatch: The template used for validation must exactly match the one used for generation
- Public Key Certificate: Verify the public key certificate is correctly embedded in client applications
- Validation Data: Check that validation data values match what was used during key generation
- Clock Manipulation: The SDK includes protection against clock manipulation - ensure system time is correct
Server Connection Problems
- Network Connectivity: Check firewall settings and network connectivity to licensing server
- SSL/TLS Issues: Ensure server SSL certificate is valid and trusted
- Server URL: Verify the licensing server URL is correct and accessible
- API Endpoints: Test server API endpoints manually using tools like Postman
Performance Optimization
- Template Caching: Cache LicenseTemplate objects instead of recreating them
- Validation Frequency: Don't validate licenses too frequently - cache results when appropriate
- Offline Mode: Implement offline license validation to avoid network delays
- Background Validation: Use background threads for server communication to avoid UI blocking
Security Best Practices
Follow these security guidelines to protect your licensing implementation:
Key Management Security
- Private Key Protection: Never include private keys in client applications - they should only be used for license generation
- Public Key Embedding: Embed public keys securely in client applications for license validation
- SDK License Key: Keep your SDK license key secret and never include it in distributed applications
- Key Rotation: Consider implementing key rotation for long-term security
Application Protection
- Code Obfuscation: Use code obfuscation tools for .NET assemblies to prevent reverse engineering
- Static Linking: Use static linking for native applications to prevent DLL replacement attacks
- Multiple Validation Points: Perform license checking at multiple points throughout your application
- Tamper Detection: Implement additional tamper detection mechanisms in critical applications
Communication Security
- HTTPS Only: Always use HTTPS for communication with licensing servers
- Certificate Validation: Implement proper SSL certificate validation in client applications
- IP Restrictions: Restrict access to payment service handlers to authorized IP addresses only
- Authentication: Implement proper authentication for server-side license management tools