license.h
Dependency-free offline licence verification.
#include <sonore/license.h>- 2types
- 9other declarations
- Guides: Getting started, Parameters and state, Presets
On this page
Design notes
The Sonorie server signs a licence KEY ("SNRE1-") and a device TOKEN ("SNRA1-") with a 2048-bit RSA key; the plugin embeds the public key and the product code and verifies BOTH offline (embedded key, local .lic, no network on the audio or the UI path). This header provides the four pieces that takes -- SHA-256, base64, big-integer modular exponentiation and the blob layout -- from scratch, because the SDK has no framework to borrow them from.
The scheme is RAW modular exponentiation, which is what the original build used and therefore what the server already signs. Kept deliberately: changing it would invalidate every key and token minted so far, and a signature made server-side has to verify here byte for byte (src/lib/license/rsa-core.ts, format.ts):
verify(msg) : SHA256(msg) == sig ^ e mod n
where SHA256(msg) is the 32-byte digest read as a big-endian integer, e/n are the public exponent/modulus (hex, from the embedded "e_hex,n_hex" key), and sig is the hex signature carried inside the base64 licence blob.
Layout MUST match src/lib/license/format.ts:
KEY "SNRE1-" + base64({lid,iat,sig}), signs "<product>:<lid>:<emailLower>:<iat>"
TOKEN "SNRA1-" + base64({lid,mid,exp,sig}), signs "SNRA1:<product>:<lid>:<midLower>:<exp>"Types 2
A plain, well-known implementation; the digest is the 32-byte big-endian hash.
No comment on this one in the header yet; the source says the rest.
Functions 9
- fn
inline void sha256(const std::string& msg, uint8_t out[32])license::sha256 · license.h:120 - fn
inline bool base64Decode(const std::string& in, std::string& out)license::base64Decode · license.h:127 - fn
inline bool verifySignature(const std::string& message, const std::string& sigHex, const std::string& publicKey)publicKey is "e_hex,n_hex" (the embedded public-key form).license::verifySignature · license.h:291 - fn
inline std::string asciiLower(const std::string& s)license::asciiLower · license.h:315 - fn
inline bool jsonString(const std::string& json, const std::string& key, std::string& out)Pull one flat JSON field. The blobs are machine-generated and contain no nested objects or escaped quotes, so a scan for "key": is sufficient and safe.license::jsonString · license.h:324 - fn
inline bool jsonNumber(const std::string& json, const std::string& key, long long& out)license::jsonNumber · license.h:337 - fn
inline std::string stripWhitespace(const std::string& s)license::stripWhitespace · license.h:354 - fn
inline bool verifyKey(const std::string& key, const std::string& productCode, const std::string& email, const std::string& publicKey)Verify a purchase KEY offline: signature over "<product>:<lid>:<emailLower>:<iat>".license::verifyKey · license.h:363 - fn
inline bool verifyToken(const std::string& token, const std::string& productCode, const std::string& machineId, long long nowSec, const std::string& publicKey)Verify a device TOKEN offline: this machine, unexpired, and a valid signature over "SNRA1:<product>:<lid>:<midLower>:<exp>".license::verifyToken · license.h:382machineIdis this device's id andnowSecthe current unix time.