Compare commits
2 Commits
Author | SHA1 | Date | |
---|---|---|---|
8902f35028
|
|||
640491d424
|
90
sign.go
90
sign.go
@ -6,8 +6,8 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ugorji/go/codec"
|
||||
"hash/crc64"
|
||||
"strings"
|
||||
@ -17,7 +17,7 @@ const alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789
|
||||
|
||||
var b64 = base64.NewEncoding(alphabet).WithPadding(base64.NoPadding)
|
||||
|
||||
type linkData struct {
|
||||
type tokenData struct {
|
||||
Signature []byte `codec:"s"`
|
||||
Payload []byte `codec:"p"`
|
||||
}
|
||||
@ -51,21 +51,49 @@ func (tc TokenCoder) SeedHex() string {
|
||||
return hex.EncodeToString(tc.Seed())
|
||||
}
|
||||
|
||||
func NewTokenCoder(seed []byte, pubKeys ...[]byte) (tc TokenCoder, err error) {
|
||||
tc.pubKeys = make([]ed25519.PublicKey, len(pubKeys)+1, len(pubKeys)+1)
|
||||
if len(seed) == 0 {
|
||||
seed = make([]byte, ed25519.SeedSize, ed25519.SeedSize)
|
||||
_, err = rand.Read(seed)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
func Format(token string) (txt string, err error) {
|
||||
var payload any
|
||||
var data []byte
|
||||
data, err = b64.DecodeString(strings.TrimFunc(token, trim))
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buf := bytes.NewBuffer(nil)
|
||||
var handle codec.CborHandle
|
||||
|
||||
buf.Write(data)
|
||||
dec := codec.NewDecoder(buf, &handle)
|
||||
|
||||
var td tokenData
|
||||
err = dec.Decode(&td)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
buf.Write(td.Payload)
|
||||
|
||||
err = dec.Decode(&payload)
|
||||
|
||||
buf.Reset()
|
||||
buf.Write([]byte("SIGNATURE=" + hex.EncodeToString(td.Signature) + "\n"))
|
||||
|
||||
enc := json.NewEncoder(buf)
|
||||
enc.SetEscapeHTML(false)
|
||||
enc.SetIndent("", "\t")
|
||||
err = enc.Encode(payload)
|
||||
txt = buf.String()
|
||||
return
|
||||
}
|
||||
|
||||
func NewTokenCoderWithSeed(seed []byte, pubKeys ...[]byte) (tc TokenCoder, err error) {
|
||||
if len(seed) != ed25519.SeedSize {
|
||||
err = errors.New("Incorrect seed size")
|
||||
return
|
||||
}
|
||||
|
||||
tc.pubKeys = make([]ed25519.PublicKey, len(pubKeys)+1, len(pubKeys)+1)
|
||||
tc.privKey = ed25519.NewKeyFromSeed(seed)
|
||||
tc.pubKeys[len(pubKeys)] = tc.privKey.Public().(ed25519.PublicKey)
|
||||
|
||||
@ -80,7 +108,16 @@ func NewTokenCoder(seed []byte, pubKeys ...[]byte) (tc TokenCoder, err error) {
|
||||
return
|
||||
}
|
||||
|
||||
func NewTokenCoderHex(seed string, pubKeys ...string) (tc TokenCoder, err error) {
|
||||
func NewTokenCoder(pubKeys ...[]byte) (tc TokenCoder, err error) {
|
||||
seed := make([]byte, ed25519.SeedSize, ed25519.SeedSize)
|
||||
_, err = rand.Read(seed)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
return NewTokenCoderWithSeed(seed, pubKeys...)
|
||||
}
|
||||
|
||||
func NewTokenCoderHexWithSeed(seed string, pubKeys ...string) (tc TokenCoder, err error) {
|
||||
var rawSeed []byte
|
||||
rawPubKeys := make([][]byte, len(pubKeys), len(pubKeys))
|
||||
rawSeed, err = hex.DecodeString(seed)
|
||||
@ -93,7 +130,18 @@ func NewTokenCoderHex(seed string, pubKeys ...string) (tc TokenCoder, err error)
|
||||
return
|
||||
}
|
||||
}
|
||||
return NewTokenCoder(rawSeed, rawPubKeys...)
|
||||
return NewTokenCoderWithSeed(rawSeed, rawPubKeys...)
|
||||
}
|
||||
|
||||
func NewTokenCoderHex(pubKeys ...string) (tc TokenCoder, err error) {
|
||||
rawPubKeys := make([][]byte, len(pubKeys), len(pubKeys))
|
||||
for pos, pubKey := range pubKeys {
|
||||
rawPubKeys[pos], err = hex.DecodeString(pubKey)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
return NewTokenCoder(rawPubKeys...)
|
||||
}
|
||||
|
||||
func trim(r rune) bool {
|
||||
@ -112,11 +160,11 @@ func (tc TokenCoder) Encode(payload interface{}) (token string, err error) {
|
||||
enc := codec.NewEncoder(buf, &handle)
|
||||
enc.Encode(payload)
|
||||
|
||||
var ld linkData
|
||||
ld.Signature = ed25519.Sign(tc.privKey, buf.Bytes())
|
||||
ld.Payload = buf.Bytes()
|
||||
var td tokenData
|
||||
td.Signature = ed25519.Sign(tc.privKey, buf.Bytes())
|
||||
td.Payload = buf.Bytes()
|
||||
buf.Reset()
|
||||
enc.Encode(ld)
|
||||
enc.Encode(td)
|
||||
token = b64.EncodeToString(buf.Bytes())
|
||||
return
|
||||
}
|
||||
@ -139,15 +187,15 @@ func (tc TokenCoder) Decode(token string, payload interface{}) (sum string, err
|
||||
buf.Write(data)
|
||||
dec := codec.NewDecoder(buf, &handle)
|
||||
|
||||
var ld linkData
|
||||
err = dec.Decode(&ld)
|
||||
var td tokenData
|
||||
err = dec.Decode(&td)
|
||||
if err != nil {
|
||||
return
|
||||
}
|
||||
|
||||
ok := false
|
||||
for _, key := range tc.pubKeys {
|
||||
if ed25519.Verify(key, ld.Payload, ld.Signature) {
|
||||
if ed25519.Verify(key, td.Payload, td.Signature) {
|
||||
ok = true
|
||||
break
|
||||
}
|
||||
@ -159,10 +207,10 @@ func (tc TokenCoder) Decode(token string, payload interface{}) (sum string, err
|
||||
}
|
||||
|
||||
buf.Reset()
|
||||
buf.Write(ld.Payload)
|
||||
buf.Write(td.Payload)
|
||||
|
||||
hash := crc64.New(crc64.MakeTable(crc64.ISO))
|
||||
hash.Write(ld.Payload)
|
||||
hash.Write(td.Payload)
|
||||
|
||||
sum = hex.EncodeToString(hash.Sum(nil))
|
||||
err = dec.Decode(&payload)
|
||||
|
Reference in New Issue
Block a user