Files
onix/pkg/plugin/implementation/signer/signer.go
2025-03-20 11:33:20 +05:30

78 lines
2.1 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, s.Close, 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.PrivateKeySize {
return nil, errors.New("invalid private key length")
}
privateKey := ed25519.PrivateKey(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
}
// Close releases resources (mock implementation returning nil).
func (s *Signer) Close() error {
return nil
}