79 lines
2.2 KiB
Go
79 lines
2.2 KiB
Go
/*
|
|
Copyright IBM Corp. All Rights Reserved.
|
|
|
|
SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
package signer
|
|
|
|
import (
|
|
"crypto"
|
|
"crypto/x509"
|
|
"io"
|
|
|
|
"github.com/hyperledger/fabric/bccsp"
|
|
"github.com/pkg/errors"
|
|
)
|
|
|
|
// bccspCryptoSigner is the BCCSP-based implementation of a crypto.Signer
|
|
type bccspCryptoSigner struct {
|
|
csp bccsp.BCCSP
|
|
key bccsp.Key
|
|
pk interface{}
|
|
}
|
|
|
|
// New returns a new BCCSP-based crypto.Signer
|
|
// for the given BCCSP instance and key.
|
|
func New(csp bccsp.BCCSP, key bccsp.Key) (crypto.Signer, error) {
|
|
// Validate arguments
|
|
if csp == nil {
|
|
return nil, errors.New("bccsp instance must be different from nil.")
|
|
}
|
|
if key == nil {
|
|
return nil, errors.New("key must be different from nil.")
|
|
}
|
|
if key.Symmetric() {
|
|
return nil, errors.New("key must be asymmetric.")
|
|
}
|
|
|
|
// Marshall the bccsp public key as a crypto.PublicKey
|
|
pub, err := key.PublicKey()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed getting public key")
|
|
}
|
|
|
|
raw, err := pub.Bytes()
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed marshalling public key")
|
|
}
|
|
|
|
pk, err := x509.ParsePKIXPublicKey(raw)
|
|
if err != nil {
|
|
return nil, errors.Wrap(err, "failed marshalling der to public key")
|
|
}
|
|
|
|
return &bccspCryptoSigner{csp, key, pk}, nil
|
|
}
|
|
|
|
// Public returns the public key corresponding to the opaque,
|
|
// private key.
|
|
func (s *bccspCryptoSigner) Public() crypto.PublicKey {
|
|
return s.pk
|
|
}
|
|
|
|
// Sign signs digest with the private key, possibly using entropy from rand.
|
|
// For an (EC)DSA key, it should be a DER-serialised, ASN.1 signature
|
|
// structure.
|
|
//
|
|
// Hash implements the SignerOpts interface and, in most cases, one can
|
|
// simply pass in the hash function used as opts. Sign may also attempt
|
|
// to type assert opts to other types in order to obtain algorithm
|
|
// specific values. See the documentation in each package for details.
|
|
//
|
|
// Note that when a signature of a hash of a larger message is needed,
|
|
// the caller is responsible for hashing the larger message and passing
|
|
// the hash (as digest) and the hash function (as opts) to Sign.
|
|
func (s *bccspCryptoSigner) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error) {
|
|
return s.csp.Sign(s.key, digest, opts)
|
|
}
|