"""Produce LIC1-...-... keys the service would accept — used to verify the SDK parsers round-trip correctly. Emits two fixtures now: v1 (legacy fixed-74 payload) and v2 (variable-length payload with expires_at + entitlements). SDKs must accept both. Byte layout (matches licensing-service/src/crypto/mod.rs exactly): v1 (74 bytes, fixed): [0] version = 1 [1] flags [2..18] product_id (UUID BE, 16 bytes) [18..34] license_id (UUID BE, 16 bytes) [34..42] issued_at (u64 BE, unix seconds) [42..74] fingerprint_hash (SHA-256, zero if unbound) v2 (83 bytes + variable entitlements): [0] version = 2 [1] flags [2..18] product_id [18..34] license_id [34..42] issued_at (u64 BE) [42..50] expires_at (u64 BE, 0 = perpetual) [50..82] fingerprint_hash (SHA-256, zero if unbound) [82] num_entitlements (u8) [83..] for each: [u8 len][len bytes of UTF-8 slug] Signature: 64 bytes over the raw payload bytes. Encoding: LIC1-- RFC 4648 base32, uppercase, no padding. """ import base64 import hashlib import json import sys import uuid from cryptography.hazmat.primitives.asymmetric.ed25519 import Ed25519PrivateKey from cryptography.hazmat.primitives.serialization import ( Encoding, PrivateFormat, PublicFormat, NoEncryption, ) KEY_VERSION_V1 = 1 KEY_VERSION_V2 = 2 FLAG_FINGERPRINT_BOUND = 0b0000_0001 FLAG_TRIAL = 0b0000_0010 def b32nopad(b: bytes) -> str: return base64.b32encode(b).decode("ascii").rstrip("=") def make_payload_v1( flags: int, product_id: bytes, license_id: bytes, issued_at: int, fp_hash: bytes, ) -> bytes: assert len(product_id) == 16 assert len(license_id) == 16 assert len(fp_hash) == 32 payload = ( bytes([KEY_VERSION_V1, flags]) + product_id + license_id + issued_at.to_bytes(8, "big") + fp_hash ) assert len(payload) == 74, f"v1 payload is {len(payload)} bytes, expected 74" return payload def make_payload_v2( flags: int, product_id: bytes, license_id: bytes, issued_at: int, expires_at: int, fp_hash: bytes, entitlements: list[str], ) -> bytes: assert len(product_id) == 16 assert len(license_id) == 16 assert len(fp_hash) == 32 assert 0 <= len(entitlements) <= 255 tail = bytearray() for slug in entitlements: encoded = slug.encode("utf-8") assert len(encoded) <= 255, f"entitlement '{slug}' too long" tail.append(len(encoded)) tail.extend(encoded) head = ( bytes([KEY_VERSION_V2, flags]) + product_id + license_id + issued_at.to_bytes(8, "big") + expires_at.to_bytes(8, "big") + fp_hash + bytes([len(entitlements)]) ) assert len(head) == 83 return head + bytes(tail) def sign_and_encode(sk: Ed25519PrivateKey, payload: bytes) -> str: sig = sk.sign(payload) assert len(sig) == 64 return f"LIC1-{b32nopad(payload)}-{b32nopad(sig)}" def main(): # Deterministic test vector — fixed seeds so the output is stable. sk = Ed25519PrivateKey.from_private_bytes(bytes(range(32))) pk = sk.public_key() pub_pem = pk.public_bytes( Encoding.PEM, PublicFormat.SubjectPublicKeyInfo ).decode() product_id = uuid.UUID("6f46a4f6-0d2f-4a28-b6aa-3e8fbf6f28f0").bytes license_id_v1 = uuid.UUID("11111111-2222-3333-4444-555555555555").bytes license_id_v2 = uuid.UUID("aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee").bytes issued_at = 1_700_000_000 expires_at_v2 = 1_900_000_000 # ~2030 fingerprint_raw = "test-machine-fingerprint" fp_hash = hashlib.sha256(fingerprint_raw.encode()).digest() entitlements_v2 = ["pro", "multi-device"] # v1: legacy fingerprint-bound key. v1_payload = make_payload_v1( FLAG_FINGERPRINT_BOUND, product_id, license_id_v1, issued_at, fp_hash, ) v1_key = sign_and_encode(sk, v1_payload) # v2: trial + fingerprint-bound, with entitlements and expiry. v2_flags = FLAG_FINGERPRINT_BOUND | FLAG_TRIAL v2_payload = make_payload_v2( v2_flags, product_id, license_id_v2, issued_at, expires_at_v2, fp_hash, entitlements_v2, ) v2_key = sign_and_encode(sk, v2_payload) # v2 perpetual, unbound, no entitlements — the "happy path" for a normal # permanent license purchase. v2_plain_payload = make_payload_v2( 0, product_id, license_id_v2, issued_at, 0, bytes(32), [], ) v2_plain_key = sign_and_encode(sk, v2_plain_payload) out = { "publicKeyPem": pub_pem, "v1": { "licenseKey": v1_key, "expected": { "version": 1, "productUuid": "6f46a4f6-0d2f-4a28-b6aa-3e8fbf6f28f0", "licenseUuid": "11111111-2222-3333-4444-555555555555", "issuedAt": issued_at, "expiresAt": 0, "flags": FLAG_FINGERPRINT_BOUND, "isFingerprintBound": True, "isTrial": False, "entitlements": [], "fingerprintRaw": fingerprint_raw, "fingerprintHashHex": fp_hash.hex(), }, }, "v2": { "licenseKey": v2_key, "expected": { "version": 2, "productUuid": "6f46a4f6-0d2f-4a28-b6aa-3e8fbf6f28f0", "licenseUuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "issuedAt": issued_at, "expiresAt": expires_at_v2, "flags": v2_flags, "isFingerprintBound": True, "isTrial": True, "entitlements": entitlements_v2, "fingerprintRaw": fingerprint_raw, "fingerprintHashHex": fp_hash.hex(), }, }, "v2_perpetual_unbound": { "licenseKey": v2_plain_key, "expected": { "version": 2, "productUuid": "6f46a4f6-0d2f-4a28-b6aa-3e8fbf6f28f0", "licenseUuid": "aaaaaaaa-bbbb-cccc-dddd-eeeeeeeeeeee", "issuedAt": issued_at, "expiresAt": 0, "flags": 0, "isFingerprintBound": False, "isTrial": False, "entitlements": [], "fingerprintRaw": None, "fingerprintHashHex": "00" * 32, }, }, } json.dump(out, sys.stdout, indent=2) print() if __name__ == "__main__": main()