Files
GoTunnel-Plugins/tools/signtool/sign/payload.go
Flik dd52c48351 feat: add signtool to plugin repository
- Migrate signing tool from GoTunnel main project
- Self-contained, no external dependencies
- Updated CI workflow to build locally
2025-12-29 19:05:56 +08:00

71 lines
1.7 KiB
Go

package sign
import (
"crypto/ed25519"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"fmt"
"strings"
"time"
)
// PluginPayload 插件签名载荷
type PluginPayload struct {
Name string `json:"name"`
Version string `json:"version"`
SourceHash string `json:"source_hash"`
KeyID string `json:"key_id"`
Timestamp int64 `json:"timestamp"`
}
// SignedPlugin 已签名的插件
type SignedPlugin struct {
Payload PluginPayload `json:"payload"`
Signature string `json:"signature"`
}
// NormalizeSource 规范化源码
func NormalizeSource(source string) string {
normalized := strings.ReplaceAll(source, "\r\n", "\n")
normalized = strings.ReplaceAll(normalized, "\r", "\n")
return strings.TrimRight(normalized, " \t\n")
}
// HashSource 计算源码哈希
func HashSource(source string) string {
normalized := NormalizeSource(source)
hash := sha256.Sum256([]byte(normalized))
return hex.EncodeToString(hash[:])
}
// CreatePayload 创建签名载荷
func CreatePayload(name, version, source, keyID string) *PluginPayload {
return &PluginPayload{
Name: name,
Version: version,
SourceHash: HashSource(source),
KeyID: keyID,
Timestamp: time.Now().Unix(),
}
}
// SignPlugin 签名插件
func SignPlugin(priv ed25519.PrivateKey, payload *PluginPayload) (*SignedPlugin, error) {
data, err := json.Marshal(payload)
if err != nil {
return nil, fmt.Errorf("marshal payload: %w", err)
}
sig := SignBase64(priv, data)
return &SignedPlugin{Payload: *payload, Signature: sig}, nil
}
// EncodeSignedPlugin 编码为 JSON
func EncodeSignedPlugin(sp *SignedPlugin) (string, error) {
data, err := json.Marshal(sp)
if err != nil {
return "", err
}
return string(data), nil
}