Initial QSfera import
This commit is contained in:
+63
@@ -0,0 +1,63 @@
|
||||
package dsig
|
||||
|
||||
import (
|
||||
"crypto"
|
||||
"crypto/rsa"
|
||||
"fmt"
|
||||
"io"
|
||||
)
|
||||
|
||||
func rsaGetSignerCryptoSignerKey(key any) (crypto.Signer, bool, error) {
|
||||
if !isValidRSAKey(key) {
|
||||
return nil, false, fmt.Errorf(`invalid key type %T for RSA algorithm`, key)
|
||||
}
|
||||
cs, isCryptoSigner := key.(crypto.Signer)
|
||||
if isCryptoSigner {
|
||||
return cs, true, nil
|
||||
}
|
||||
return nil, false, nil
|
||||
}
|
||||
|
||||
// rsaPSSOptions returns the PSS options for RSA-PSS signatures with the specified hash.
|
||||
// The salt length is set to equal the hash length as per RFC 7518.
|
||||
func rsaPSSOptions(h crypto.Hash) rsa.PSSOptions {
|
||||
return rsa.PSSOptions{
|
||||
Hash: h,
|
||||
SaltLength: rsa.PSSSaltLengthEqualsHash,
|
||||
}
|
||||
}
|
||||
|
||||
// SignRSA generates an RSA signature for the given payload using the specified private key and options.
|
||||
// The raw parameter should be the pre-computed signing input (typically header.payload).
|
||||
// If pss is true, RSA-PSS is used; otherwise, PKCS#1 v1.5 is used.
|
||||
//
|
||||
// The rr parameter is an optional io.Reader that can be used to provide randomness for signing.
|
||||
// If rr is nil, it defaults to rand.Reader.
|
||||
func SignRSA(key *rsa.PrivateKey, payload []byte, h crypto.Hash, pss bool, rr io.Reader) ([]byte, error) {
|
||||
if !isValidRSAKey(key) {
|
||||
return nil, fmt.Errorf(`invalid key type %T for RSA algorithm`, key)
|
||||
}
|
||||
var opts crypto.SignerOpts = h
|
||||
if pss {
|
||||
rsaopts := rsaPSSOptions(h)
|
||||
opts = &rsaopts
|
||||
}
|
||||
return cryptosign(key, payload, h, opts, rr)
|
||||
}
|
||||
|
||||
// VerifyRSA verifies an RSA signature for the given payload and header.
|
||||
// This function constructs the signing input by encoding the header and payload according to JWS specification,
|
||||
// then verifies the signature using the specified public key and hash algorithm.
|
||||
// If pss is true, RSA-PSS verification is used; otherwise, PKCS#1 v1.5 verification is used.
|
||||
func VerifyRSA(key *rsa.PublicKey, payload, signature []byte, h crypto.Hash, pss bool) error {
|
||||
if !isValidRSAKey(key) {
|
||||
return fmt.Errorf(`invalid key type %T for RSA algorithm`, key)
|
||||
}
|
||||
hasher := h.New()
|
||||
hasher.Write(payload)
|
||||
digest := hasher.Sum(nil)
|
||||
if pss {
|
||||
return rsa.VerifyPSS(key, h, digest, signature, &rsa.PSSOptions{Hash: h, SaltLength: rsa.PSSSaltLengthEqualsHash})
|
||||
}
|
||||
return rsa.VerifyPKCS1v15(key, h, digest, signature)
|
||||
}
|
||||
Reference in New Issue
Block a user