Initial QSfera import
This commit is contained in:
+224
@@ -0,0 +1,224 @@
|
||||
// Package dsig provides digital signature operations for Go.
|
||||
// It contains low-level signature generation and verification tools that
|
||||
// can be used by other signing libraries
|
||||
//
|
||||
// The package follows these design principles:
|
||||
// 1. Does minimal checking of input parameters (for performance); callers need to ensure that the parameters are valid.
|
||||
// 2. All exported functions are strongly typed (i.e. they do not take `any` types unless they absolutely have to).
|
||||
// 3. Does not rely on other high-level packages (standalone, except for internal packages).
|
||||
package dsig
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/sha256"
|
||||
"crypto/sha512"
|
||||
"fmt"
|
||||
"hash"
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Family represents the cryptographic algorithm family
|
||||
type Family int
|
||||
|
||||
const (
|
||||
InvalidFamily Family = iota
|
||||
HMAC
|
||||
RSA
|
||||
ECDSA
|
||||
EdDSAFamily
|
||||
maxFamily
|
||||
)
|
||||
|
||||
// String returns the string representation of the Family
|
||||
func (f Family) String() string {
|
||||
switch f {
|
||||
case HMAC:
|
||||
return "HMAC"
|
||||
case RSA:
|
||||
return "RSA"
|
||||
case ECDSA:
|
||||
return "ECDSA"
|
||||
case EdDSAFamily:
|
||||
return "EdDSA"
|
||||
default:
|
||||
return "InvalidFamily"
|
||||
}
|
||||
}
|
||||
|
||||
// AlgorithmInfo contains metadata about a digital signature algorithm
|
||||
type AlgorithmInfo struct {
|
||||
Family Family // The cryptographic family (HMAC, RSA, ECDSA, EdDSA)
|
||||
Meta any // Family-specific metadata
|
||||
}
|
||||
|
||||
// HMACFamilyMeta contains metadata specific to HMAC algorithms
|
||||
type HMACFamilyMeta struct {
|
||||
HashFunc func() hash.Hash // Hash function constructor
|
||||
}
|
||||
|
||||
// RSAFamilyMeta contains metadata specific to RSA algorithms
|
||||
type RSAFamilyMeta struct {
|
||||
Hash crypto.Hash // Hash algorithm
|
||||
PSS bool // Whether to use PSS padding (false = PKCS#1 v1.5)
|
||||
}
|
||||
|
||||
// ECDSAFamilyMeta contains metadata specific to ECDSA algorithms
|
||||
type ECDSAFamilyMeta struct {
|
||||
Hash crypto.Hash // Hash algorithm
|
||||
}
|
||||
|
||||
// EdDSAFamilyMeta contains metadata specific to EdDSA algorithms
|
||||
// Currently EdDSA doesn't need specific metadata, but this provides extensibility
|
||||
type EdDSAFamilyMeta struct {
|
||||
// Reserved for future use
|
||||
}
|
||||
|
||||
var algorithms = make(map[string]AlgorithmInfo)
|
||||
var muAlgorithms sync.RWMutex
|
||||
|
||||
// RegisterAlgorithm registers a new digital signature algorithm with the specified family and metadata.
|
||||
//
|
||||
// info.Meta should contain extra metadata for some algorithms. Currently HMAC, RSA,
|
||||
// and ECDSA family of algorithms need their respective metadata (HMACFamilyMeta,
|
||||
// RSAFamilyMeta, and ECDSAFamilyMeta). Metadata for other families are ignored.
|
||||
func RegisterAlgorithm(name string, info AlgorithmInfo) error {
|
||||
muAlgorithms.Lock()
|
||||
defer muAlgorithms.Unlock()
|
||||
|
||||
// Validate the metadata matches the family
|
||||
switch info.Family {
|
||||
case HMAC:
|
||||
if _, ok := info.Meta.(HMACFamilyMeta); !ok {
|
||||
return fmt.Errorf("invalid HMAC metadata for algorithm %s", name)
|
||||
}
|
||||
case RSA:
|
||||
if _, ok := info.Meta.(RSAFamilyMeta); !ok {
|
||||
return fmt.Errorf("invalid RSA metadata for algorithm %s", name)
|
||||
}
|
||||
case ECDSA:
|
||||
if _, ok := info.Meta.(ECDSAFamilyMeta); !ok {
|
||||
return fmt.Errorf("invalid ECDSA metadata for algorithm %s", name)
|
||||
}
|
||||
case EdDSAFamily:
|
||||
// EdDSA metadata is optional for now
|
||||
default:
|
||||
return fmt.Errorf("unsupported algorithm family %s for algorithm %s", info.Family, name)
|
||||
}
|
||||
|
||||
algorithms[name] = info
|
||||
return nil
|
||||
}
|
||||
|
||||
// GetAlgorithmInfo retrieves the algorithm information for a given algorithm name.
|
||||
// Returns the info and true if found, zero value and false if not found.
|
||||
func GetAlgorithmInfo(name string) (AlgorithmInfo, bool) {
|
||||
muAlgorithms.RLock()
|
||||
defer muAlgorithms.RUnlock()
|
||||
|
||||
info, ok := algorithms[name]
|
||||
return info, ok
|
||||
}
|
||||
|
||||
func init() {
|
||||
// Register all standard algorithms with their metadata
|
||||
toRegister := map[string]AlgorithmInfo{
|
||||
// HMAC algorithms
|
||||
HMACWithSHA256: {
|
||||
Family: HMAC,
|
||||
Meta: HMACFamilyMeta{
|
||||
HashFunc: sha256.New,
|
||||
},
|
||||
},
|
||||
HMACWithSHA384: {
|
||||
Family: HMAC,
|
||||
Meta: HMACFamilyMeta{
|
||||
HashFunc: sha512.New384,
|
||||
},
|
||||
},
|
||||
HMACWithSHA512: {
|
||||
Family: HMAC,
|
||||
Meta: HMACFamilyMeta{
|
||||
HashFunc: sha512.New,
|
||||
},
|
||||
},
|
||||
|
||||
// RSA PKCS#1 v1.5 algorithms
|
||||
RSAPKCS1v15WithSHA256: {
|
||||
Family: RSA,
|
||||
Meta: RSAFamilyMeta{
|
||||
Hash: crypto.SHA256,
|
||||
PSS: false,
|
||||
},
|
||||
},
|
||||
RSAPKCS1v15WithSHA384: {
|
||||
Family: RSA,
|
||||
Meta: RSAFamilyMeta{
|
||||
Hash: crypto.SHA384,
|
||||
PSS: false,
|
||||
},
|
||||
},
|
||||
RSAPKCS1v15WithSHA512: {
|
||||
Family: RSA,
|
||||
Meta: RSAFamilyMeta{
|
||||
Hash: crypto.SHA512,
|
||||
PSS: false,
|
||||
},
|
||||
},
|
||||
|
||||
// RSA PSS algorithms
|
||||
RSAPSSWithSHA256: {
|
||||
Family: RSA,
|
||||
Meta: RSAFamilyMeta{
|
||||
Hash: crypto.SHA256,
|
||||
PSS: true,
|
||||
},
|
||||
},
|
||||
RSAPSSWithSHA384: {
|
||||
Family: RSA,
|
||||
Meta: RSAFamilyMeta{
|
||||
Hash: crypto.SHA384,
|
||||
PSS: true,
|
||||
},
|
||||
},
|
||||
RSAPSSWithSHA512: {
|
||||
Family: RSA,
|
||||
Meta: RSAFamilyMeta{
|
||||
Hash: crypto.SHA512,
|
||||
PSS: true,
|
||||
},
|
||||
},
|
||||
|
||||
// ECDSA algorithms
|
||||
ECDSAWithP256AndSHA256: {
|
||||
Family: ECDSA,
|
||||
Meta: ECDSAFamilyMeta{
|
||||
Hash: crypto.SHA256,
|
||||
},
|
||||
},
|
||||
ECDSAWithP384AndSHA384: {
|
||||
Family: ECDSA,
|
||||
Meta: ECDSAFamilyMeta{
|
||||
Hash: crypto.SHA384,
|
||||
},
|
||||
},
|
||||
ECDSAWithP521AndSHA512: {
|
||||
Family: ECDSA,
|
||||
Meta: ECDSAFamilyMeta{
|
||||
Hash: crypto.SHA512,
|
||||
},
|
||||
},
|
||||
|
||||
// EdDSA algorithm
|
||||
EdDSA: {
|
||||
Family: EdDSAFamily,
|
||||
Meta: EdDSAFamilyMeta{},
|
||||
},
|
||||
}
|
||||
|
||||
for name, info := range toRegister {
|
||||
if err := RegisterAlgorithm(name, info); err != nil {
|
||||
panic(fmt.Sprintf("failed to register algorithm %s: %v", name, err))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user