FILE / ScuroNeko/mtg

mtglib/secret.go

Исходный файл и его история в репозитории.
FILE 015f02c077f485ec08ffbb813991f0c03871b21f
Files
mtg/mtglib/secret.go
T
2021-03-10 11:48:44 +03:00

76 lines
1.3 KiB
Go

package mtglib
import (
"crypto/rand"
"encoding/base64"
"encoding/hex"
"fmt"
"strings"
)
const SecretKeyLength = 32
type Secret struct {
Key []byte
Host string
}
func (s *Secret) MarshalText() ([]byte, error) {
if s == nil {
return nil, nil
}
return []byte(s.String()), nil
}
func (s *Secret) UnmarshalText(data []byte) error {
text := string(data)
if text == "" {
return ErrSecretEmpty
}
decoded, err := base64.RawStdEncoding.DecodeString(text)
if err != nil && strings.HasPrefix(text, "ee") {
decoded, err = hex.DecodeString(strings.TrimPrefix(text, "ee"))
}
if err != nil {
return fmt.Errorf("incorrect secret format: %w", err)
}
if len(decoded) <= SecretKeyLength {
return fmt.Errorf("secret has incorrect length %d", len(text))
}
s.Key = decoded[:SecretKeyLength]
s.Host = string(decoded[SecretKeyLength:])
return nil
}
func (s Secret) Base64() string {
return base64.StdEncoding.EncodeToString(append(s.Key[:], s.Host...))
}
func (s Secret) String() string {
return s.Base64()
}
func (s Secret) EE() string {
return "ee" + hex.EncodeToString(append(s.Key[:], s.Host...))
}
func GenerateSecret(hostname string) Secret {
s := Secret{
Key: make([]byte, SecretKeyLength),
Host: hostname,
}
if _, err := rand.Read(s.Key); err != nil {
panic(err)
}
return s
}