blog/go-license/license.go
2025-02-27 17:06:37 +00:00

89 lines
1.4 KiB
Go

package golicense
import (
"crypto/hmac"
"crypto/sha256"
"encoding/base64"
"encoding/json"
"errors"
"time"
)
var (
secret = []byte("superDuperSecret123!")
ErrorHmacMismatch = errors.New("checksum mismatch - not a valid license key")
)
type Data struct {
Feature1 bool
Feature2 int
ValidTill time.Time
CreatedAt time.Time
}
type Envelope struct {
Data Data
Checksum []byte
}
func (e *Envelope) String() (string, error) {
d, err := json.Marshal(e)
if err != nil {
return "", err
}
str := base64.StdEncoding.EncodeToString(d)
return str, nil
}
func New(feature1 bool, feature2 int, expire int) (*Envelope, error) {
d := Data{
Feature1: feature1,
Feature2: feature2,
ValidTill: time.Now().AddDate(0, 0, expire),
}
e := Envelope{
Data: d,
}
db, err := json.Marshal(&d)
if err != nil {
return nil, err
}
hmac := hmac.New(sha256.New, secret)
hmac.Write(db)
dh := hmac.Sum(nil)
e.Checksum = dh
return &e, nil
}
func Verify(in string) (*Envelope, error) {
d, err := base64.StdEncoding.DecodeString(in)
if err != nil {
return nil, err
}
var e Envelope
if err := json.Unmarshal(d, &e); err != nil {
return nil, err
}
db, err := json.Marshal(e.Data)
if err != nil {
return nil, err
}
hm := hmac.New(sha256.New, secret)
hm.Write(db)
dh := hm.Sum(nil)
if !hmac.Equal(e.Checksum, dh) {
return nil, ErrorHmacMismatch
}
return &e, nil
}