mirror of
https://github.com/luxfi/license.git
synced 2026-10-30 16:21:14 +00:00
- Stdlib-only deterministic binary token format (no JWT / CBOR dep). - Go API: VerifyToken, LoadFromEnv, HasFeature, HasFeatureOrDie. - Stable C ABI + C++17 RAII wrapper for non-Go commercial binaries (luxcpp/cevm). - cmd/lux-license: keygen / issue / inspect / verify. - Embedded development key; warns once at runtime until production key swap. - 22 Go tests + 1 cgo round-trip test, all passing.
86 lines
3.2 KiB
Go
86 lines
3.2 KiB
Go
// Copyright (C) 2020-2026, Lux Industries Inc. All rights reserved.
|
|
// See the file LICENSE for licensing terms.
|
|
|
|
package license
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/ed25519"
|
|
"fmt"
|
|
"os"
|
|
"sync"
|
|
)
|
|
|
|
// IssuerPublicKey is the 32-byte Ed25519 public key whose private counterpart
|
|
// signs all production Lux commercial license tokens.
|
|
//
|
|
// REPLACE WITH PRODUCTION KEY BEFORE FIRST CUSTOMER ISSUANCE.
|
|
//
|
|
// The current value is the *development* key derived deterministically from
|
|
// the seed "lux-license-development-seed-001" (see TestDevKeyMatchesSeed in
|
|
// pubkey_test.go). Tokens signed with the matching development private key
|
|
// will verify against builds compiled with this constant. When a real customer
|
|
// token must be issued:
|
|
//
|
|
// 1. Generate a fresh Ed25519 keypair on an air-gapped machine, or inside
|
|
// the Lux KMS / HashiCorp Vault transit engine. (Never via the dev seed.)
|
|
// 2. Store the *private* key inside that vault. Never commit it.
|
|
// 3. Replace the bytes below with the corresponding 32-byte public key.
|
|
// 4. Tag a new release; downstream consumers re-build to pick up the rotated
|
|
// public key.
|
|
var IssuerPublicKey = ed25519.PublicKey{
|
|
0xd1, 0x1a, 0x95, 0xe3, 0xf1, 0x77, 0x89, 0x38,
|
|
0x6f, 0xc4, 0x4b, 0x34, 0xde, 0xf7, 0x0b, 0xdc,
|
|
0x16, 0xcf, 0xff, 0xcc, 0xc0, 0x37, 0xa2, 0x03,
|
|
0x59, 0xf5, 0xb1, 0xea, 0x1c, 0x36, 0x36, 0x73,
|
|
}
|
|
|
|
// devSeed is the 32-byte deterministic seed used to derive the development
|
|
// keypair embedded above. Never use this seed in production: anyone with this
|
|
// repository can mint tokens that verify against IssuerPublicKey until the
|
|
// production key is swapped in.
|
|
const devSeed = "lux-license-development-seed-001"
|
|
|
|
// DevPublicKey returns the development public key derived from devSeed. Equal
|
|
// to IssuerPublicKey until the production key is installed.
|
|
func DevPublicKey() ed25519.PublicKey {
|
|
priv := ed25519.NewKeyFromSeed([]byte(devSeed))
|
|
return priv.Public().(ed25519.PublicKey)
|
|
}
|
|
|
|
// DevPrivateKey returns the development private key derived from devSeed. Used
|
|
// by tests and by `lux-license issue --dev`.
|
|
func DevPrivateKey() ed25519.PrivateKey {
|
|
return ed25519.NewKeyFromSeed([]byte(devSeed))
|
|
}
|
|
|
|
// IsUsingDevKey reports whether the embedded IssuerPublicKey is still the
|
|
// development key. Production builds should swap the key before shipping.
|
|
func IsUsingDevKey() bool {
|
|
return bytes.Equal(IssuerPublicKey, DevPublicKey())
|
|
}
|
|
|
|
// EnvSuppressDevKeyWarning silences the once-per-process warning emitted at
|
|
// init when IssuerPublicKey is still the development key. Set this only in
|
|
// internal Lux test environments.
|
|
const EnvSuppressDevKeyWarning = "LUX_LICENSE_SUPPRESS_DEV_WARNING"
|
|
|
|
var devKeyWarnOnce sync.Once
|
|
|
|
// warnIfDevKey writes a single stderr line per process if the binary is using
|
|
// the development public key. Called from VerifyToken on the first verify, so
|
|
// silent (no-op) builds that never check a license never emit anything.
|
|
func warnIfDevKey() {
|
|
if !IsUsingDevKey() {
|
|
return
|
|
}
|
|
devKeyWarnOnce.Do(func() {
|
|
if os.Getenv(EnvSuppressDevKeyWarning) != "" {
|
|
return
|
|
}
|
|
fmt.Fprintln(os.Stderr,
|
|
"warning: luxfi/license is using the DEVELOPMENT public key. "+
|
|
"Production binaries must replace pubkey.go:IssuerPublicKey before issuing customer tokens.")
|
|
})
|
|
}
|