46 lines
1.5 KiB
Go
46 lines
1.5 KiB
Go
package dsig
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/rand"
|
|
"fmt"
|
|
"io"
|
|
)
|
|
|
|
// cryptosign is a low-level function that signs a payload using a crypto.Signer.
|
|
// If hash is crypto.Hash(0), the payload is signed directly without hashing.
|
|
// Otherwise, the payload is hashed using the specified hash function before signing.
|
|
//
|
|
// rr is an io.Reader that provides randomness for signing. If rr is nil, it defaults to rand.Reader.
|
|
func cryptosign(signer crypto.Signer, payload []byte, hash crypto.Hash, opts crypto.SignerOpts, rr io.Reader) ([]byte, error) {
|
|
if rr == nil {
|
|
rr = rand.Reader
|
|
}
|
|
|
|
var digest []byte
|
|
if hash == crypto.Hash(0) {
|
|
digest = payload
|
|
} else {
|
|
h := hash.New()
|
|
if _, err := h.Write(payload); err != nil {
|
|
return nil, fmt.Errorf(`failed to write payload to hash: %w`, err)
|
|
}
|
|
digest = h.Sum(nil)
|
|
}
|
|
return signer.Sign(rr, digest, opts)
|
|
}
|
|
|
|
// SignCryptoSigner generates a signature using a crypto.Signer interface.
|
|
// This function can be used for hardware security modules, smart cards,
|
|
// and other implementations of the crypto.Signer interface.
|
|
//
|
|
// rr is an io.Reader that provides randomness for signing. If rr is nil, it defaults to rand.Reader.
|
|
//
|
|
// Returns the signature bytes or an error if signing fails.
|
|
func SignCryptoSigner(signer crypto.Signer, raw []byte, h crypto.Hash, opts crypto.SignerOpts, rr io.Reader) ([]byte, error) {
|
|
if signer == nil {
|
|
return nil, fmt.Errorf("dsig.SignCryptoSigner: signer is nil")
|
|
}
|
|
return cryptosign(signer, raw, h, opts, rr)
|
|
}
|