74 lines
2.0 KiB
Go
74 lines
2.0 KiB
Go
package signer
|
|
|
|
import (
|
|
"context"
|
|
"crypto/ed25519"
|
|
"encoding/base64"
|
|
"errors"
|
|
"fmt"
|
|
|
|
"golang.org/x/crypto/blake2b"
|
|
)
|
|
|
|
// Config holds the configuration for the signing process.
|
|
type Config struct {
|
|
}
|
|
|
|
// Signer implements the Signer interface and handles the signing process.
|
|
type Signer struct {
|
|
config *Config
|
|
}
|
|
|
|
// New creates a new Signer instance with the given configuration.
|
|
func New(ctx context.Context, config *Config) (*Signer, func() error, error) {
|
|
s := &Signer{config: config}
|
|
|
|
return s, nil, nil
|
|
}
|
|
|
|
// hash generates a signing string using BLAKE-512 hashing.
|
|
func hash(payload []byte, createdAt, expiresAt int64) (string, error) {
|
|
hasher, _ := blake2b.New512(nil)
|
|
|
|
_, err := hasher.Write(payload)
|
|
if err != nil {
|
|
return "", fmt.Errorf("failed to hash payload: %w", err)
|
|
}
|
|
|
|
hashSum := hasher.Sum(nil)
|
|
digestB64 := base64.StdEncoding.EncodeToString(hashSum)
|
|
|
|
return fmt.Sprintf("(created): %d\n(expires): %d\ndigest: BLAKE-512=%s", createdAt, expiresAt, digestB64), nil
|
|
}
|
|
|
|
// generateSignature signs the given signing string using the provided private key.
|
|
func generateSignature(signingString []byte, privateKeyBase64 string) ([]byte, error) {
|
|
privateKeyBytes, err := base64.StdEncoding.DecodeString(privateKeyBase64)
|
|
if err != nil {
|
|
return nil, fmt.Errorf("error decoding private key: %w", err)
|
|
}
|
|
|
|
if len(privateKeyBytes) != ed25519.SeedSize {
|
|
return nil, errors.New("invalid seed length")
|
|
}
|
|
|
|
// Generate the private key from the seed
|
|
privateKey := ed25519.NewKeyFromSeed(privateKeyBytes)
|
|
return ed25519.Sign(privateKey, signingString), nil
|
|
}
|
|
|
|
// Sign generates a digital signature for the provided payload.
|
|
func (s *Signer) Sign(ctx context.Context, body []byte, privateKeyBase64 string, createdAt, expiresAt int64) (string, error) {
|
|
signingString, err := hash(body, createdAt, expiresAt)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
signature, err := generateSignature([]byte(signingString), privateKeyBase64)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return base64.StdEncoding.EncodeToString(signature), nil
|
|
}
|