iPlus.gip.core.licensing
5.0.0-preview.5
dotnet add package iPlus.gip.core.licensing --version 5.0.0-preview.5
NuGet\Install-Package iPlus.gip.core.licensing -Version 5.0.0-preview.5
<PackageReference Include="iPlus.gip.core.licensing" Version="5.0.0-preview.5" />
<PackageVersion Include="iPlus.gip.core.licensing" Version="5.0.0-preview.5" />
<PackageReference Include="iPlus.gip.core.licensing" />
paket add iPlus.gip.core.licensing --version 5.0.0-preview.5
#r "nuget: iPlus.gip.core.licensing, 5.0.0-preview.5"
#:package iPlus.gip.core.licensing@5.0.0-preview.5
#addin nuget:?package=iPlus.gip.core.licensing&version=5.0.0-preview.5&prerelease
#tool nuget:?package=iPlus.gip.core.licensing&version=5.0.0-preview.5&prerelease
gip.core.licensing
Software-based licensing for the iPlus framework — replaces the V4 USB dongle validation with offline, signed license files.
Why
V4 required a hardware dongle (TDi Matrix32/Matrix64) for developer and product licenses. That is a blocker for open-source distribution, containers, Linux and cloud deployments. This library keeps the semantics of the V4 license model (three divisions: gip → developers → end users, per-database product licenses) but replaces the dongle with asymmetric cryptography. The dongle code path has been removed from the framework entirely.
Model
| License kind | Value | Issued by | Bound to | Grants |
|---|---|---|---|---|
DeveloperIssuer |
10 | gip | nothing (or machine) | Development environment + right to issue Product licenses. Embeds the developer's public key. |
DeveloperEndUser |
20 | gip | machine | Development/engineering features only |
Product |
30 | developer or gip | database (+ optional machine) | The listed packages on that database. Only effective when a FrameworkRuntime license is present. |
FrameworkRuntime |
40 | gip | database | The commercial iPlus runtime edition, per concurrent user (MaxUsers). Required for any Product license to take effect. |
Two-level PKI chain
gip private key ──signs──> DeveloperIssuer license
└─ embeds developer public key + IssuerKeyId
developer private key ──signs──> Product license
└─ stamps IssuerKeyId
FrameworkRuntime license ──signed by gip private key──> commercial edition
LicenseVerifier tries the framework public key first. Only for Product
licenses with a non-empty IssuerKeyId does it resolve the developer key
through the issuerKeyResolver passed to
FrameworkLicenseKeys.CreateVerifier(resolver). A developer therefore cannot
issue a DeveloperIssuer license for itself — that would require gip's private
key.
LicenseKeys.ComputeKeyId returns the first 16 hex chars of the SHA-256 hash
over the DER-encoded SubjectPublicKeyInfo; that is the value stored in
IssuerKeyId.
File format
IPLUS-LICENSE
<base64 RSA-SHA256 signature>
{ ...json payload... }
The signature covers the exact UTF-8 bytes of the JSON payload that follow the second line, so verification never has to re-canonicalize the JSON.
Usage
Verify (framework side)
LicenseVerifier verifier = FrameworkLicenseKeys.CreateVerifier();
var context = new LicenseBindingContext
{
DatabaseFingerprint = DatabaseFingerprint.Compute(createDate, brokerGuid, dbGuid),
MachineFingerprint = MachineFingerprint.ComputeCurrent(),
RequiredPackage = "gip.VarioSystem"
};
LicenseValidationResult result = verifier.VerifyFile("Customer-license.gip", context);
if (!result.IsValid)
Console.WriteLine($"{result.Error}: {result.Message}");
Issue (developer / gip side)
LicenseIssuer issuer = LicenseIssuer.FromPrivateKeyFile("issuer-private.pem");
var payload = new LicensePayload
{
Kind = LicenseKind.Product,
CustomerName = "ACME GmbH",
ProjectNo = "P-2026-001",
IssuerName = "ACME GmbH",
Packages = { "ACME.Mes", "ACME.Mes.Extension" },
DatabaseFingerprint = "<fingerprint of the customer database>"
};
issuer.IssueToFile(payload, "ACME-license.gip");
Key management
- The framework public key is embedded in this assembly
(
FrameworkPublicKey.pem) and also shipped as package content. - The framework private key is never committed. It lives offline with gip
and is only used by
gip.tool.licenseIssuerto sign developer licenses. - Developers get their own key pair. Their public key is embedded in the
DeveloperIssuerlicense that gip signs for them (IssuerPublicKey), so the framework can validateProductlicenses offline without a central service. Additional trusted keys can be dropped into<LicenseFolder>/Issuers/*.pem. - For development, set
IPLUS_LICENSE_PUBLIC_KEYto a path of a test public key.
Package license metadata (GPL / commercial mixing)
Every assembly declares its license as an assembly attribute:
[assembly: AssemblyMetadata("iPlusLicense", "GPL-3.0-or-later OR LicenseRef-Commercial")]
The attribute is generated by the GenerateIPlusLicenseAttribute target in
Directory.Build.targets from PackageLicenseExpression, so a project only has
to set the NuGet property. PackageLicenseExpression classifies the expression:
| Expression | LicenseCompatibility |
Commercial runtime | Open runtime |
|---|---|---|---|
GPL-3.0-or-later |
OpenOnly |
blocked | allowed |
GPL-3.0-or-later OR LicenseRef-Commercial |
Both |
allowed | allowed |
LicenseRef-Commercial / Commercial |
CommercialOnly |
needs a Product license |
blocked |
MIT, Apache-2.0, BSD-3-Clause |
Both |
allowed | allowed |
| unknown / missing | Unknown |
allowed (fail-open) | allowed |
PackageLicenseRegistry (in gip.core.datamodel) maps ACPackageName →
expression; it is filled by ACClassManager.RegisterAssemblyTypes and consulted
by License.IsPackageLicensed.
Grace period
A license problem does not stop the program immediately (V4 parity):
| Stage | Default | Effect |
|---|---|---|
| Warning | 30 minutes | Client shows Warning50025 once; system fully usable |
| Block | 1.5 days | ACComponent.ACUrlCommand returns null for unlicensed packages |
Both periods are configurable through License.WarningGracePeriod and
License.BlockGracePeriod. The clock itself is implemented by
LicenseGracePeriod — a dependency-free, unit-tested
class that License exposes as GracePeriod. The start time is persisted to
<LicenseFolder>/.licensegrace, so restarting the service does not reset the
grace window.
Migration from V4
gip.core.datamodel.Licensing.License keeps its public API surface
(IsPackageLicensed, IsComponentLicensed, ActivateLicense,
GenerateLicenseFile, remote-login code exchange). Dongle reads are replaced by
file validation. The V4 dongle path is removed: Mxapi.cs, Mxtea.cs,
matrix.ini, MATRIX32.DLL/MATRIX64.DLL and the gip.tool.devLicense /
gip.tool.devLicenseProvider projects no longer exist. V4 dongle licenses
(VBSystem.SystemName = "VBD") are rejected by CheckActivateLicense; developers
must install a signed DeveloperIssuer *.gip file instead.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
-
net10.0
- No dependencies.
NuGet packages (1)
Showing the top 1 NuGet packages that depend on iPlus.gip.core.licensing:
| Package | Downloads |
|---|---|
|
iPlus.gip.core.datamodel
Dual-licensed: usable under GPL-3.0-or-later or under a commercial license from iplus-framework (https://iplus-framework.com/). |
GitHub repositories
This package is not used by any popular GitHub repositories.
| Version | Downloads | Last Updated |
|---|---|---|
| 5.0.0-preview.5 | 0 | 11/9/2026 |