Skip to content

2.2.0

Choose a tag to compare

@masterix21 masterix21 released this 24 Jun 21:08
· 2 commits to main since this release
695a4b5

Security

  • Offline token forgery via certificate/key substitution. verifyOffline()
    verified the signing certificate was root-signed, then verified the token using
    the signing public key embedded in the footer — without cross-checking that the
    certificate actually bound that key. An attacker could pair a legitimate
    (root-signed) certificate with their own signing key and have a forged token
    accepted. The verifier now constant-time compares the certificate's bound public
    key against the key used for verification and rejects on mismatch.
  • Audit chain now protects forensic attribution. calculateHash() omitted the
    actor, actor_type, actor_id, ip, user_agent and occurred_at columns,
    so a raw UPDATE could rewrite who performed an action and when while
    verifyChain() still reported the chain intact. These columns are now included
    in the hash. This changes the hash formula — see UPGRADE.md.

Fixed

  • Re-activating a deactivated device failed with FINGERPRINT_CONFLICT (409).
    Because the unique index is (license_id, usage_fingerprint) with no status
    column, a revoked usage row persisted and a subsequent registration of the same
    fingerprint tried to insert a duplicate. register() now re-activates the
    existing revoked row in place instead of inserting a colliding one.
  • Legacy v1 keys whose nonce started with the v2 marker byte failed to decrypt.
    decryptPrivateKey() selected the v1/v2 path from the first byte only, but a v1
    payload has no version marker, so ~1/256 of legacy keys were misread as v2. The
    decryptor now falls back to v1 when the v2 attempt fails.

Internal

  • Stabilized two non-deterministic tests that intermittently failed CI: the
    constant-time key-comparison test now asserts the hash_equals() invariant by
    reflection instead of wall-clock timing, and the legacy-key decryption test gained
    a deterministic case for the v2-marker nonce collision.

Credits

  • Thanks to Codexlabstudio for reporting and
    prototyping the offline-token, usage re-activation and audit-chain fixes.