gitee.com/lh-her-team/common@v1.5.1/crypto/sdf/ecdsakey.go (about)

     1  package sdf
     2  
     3  import (
     4  	"crypto"
     5  	"fmt"
     6  	"io"
     7  	"strconv"
     8  
     9  	"gitee.com/lh-her-team/common/crypto/hsm"
    10  
    11  	"github.com/tjfoc/gmsm/sm3"
    12  
    13  	"github.com/tjfoc/gmsm/sm2"
    14  
    15  	bccrypto "gitee.com/lh-her-team/common/crypto"
    16  	bcsm2 "gitee.com/lh-her-team/common/crypto/asym/sm2"
    17  	"gitee.com/lh-her-team/common/crypto/hash"
    18  	"github.com/pkg/errors"
    19  )
    20  
    21  type ecdsaPrivateKey struct {
    22  	priv *sdfEcdsaPrivateKey
    23  }
    24  
    25  func (e ecdsaPrivateKey) Public() crypto.PublicKey {
    26  	return e.priv.pubKey.ToStandardKey()
    27  }
    28  
    29  func (e ecdsaPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
    30  	return e.priv.SignWithOpts(digest, &bccrypto.SignOpts{Hash: bccrypto.HASH_TYPE_SM3})
    31  }
    32  
    33  // sdfEcdsaPrivateKey represents pkcs11 ecdsa/sm2 private key
    34  type sdfEcdsaPrivateKey struct {
    35  	sdfHandle *SDFHandle
    36  	pubKey    bccrypto.PublicKey
    37  	keyId     uint
    38  	keyPwd    []byte
    39  	keyType   SDFKeyType
    40  	signer    crypto.Signer
    41  }
    42  
    43  func NewPrivateKey(sdf *SDFHandle, keyId string, keyPwd []byte, tp bccrypto.KeyType) (bccrypto.PrivateKey, error) {
    44  	if sdf == nil || len(keyId) == 0 {
    45  		return nil, errors.New("Invalid parameter, sdfHandle or keyId is nil")
    46  	}
    47  	keyType := convertToSDFKeyType(tp)
    48  	session, err := sdf.getSession()
    49  	if err != nil {
    50  		return nil, err
    51  	}
    52  	defer sdf.returnSession(err, session)
    53  	//check keyId
    54  	keyIndex, err := strconv.Atoi(keyId)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	{
    59  		/*
    60  			check pwd
    61  			this depends on HSM vendors :-(
    62  		*/
    63  		accessKeyId, need := hsm.GetHSMAdapter("").SDF_GetSM2KeyAccessRight(keyIndex)
    64  		if need {
    65  			err = sdf.ctx.SDFGetPrivateKeyAccessRight(session, uint(accessKeyId), keyPwd, uint(len(keyPwd)))
    66  			if err != nil {
    67  				return nil, errors.WithMessagef(err, "failed to geGetPrivateKeyAccessRight, accessKeyId = %d", accessKeyId)
    68  			}
    69  		}
    70  	}
    71  	//export pub
    72  	pub, err := sdf.ExportECDSAPublicKey(SDFKey{uint(keyIndex), keyPwd, SM2})
    73  	if err != nil {
    74  		return nil, errors.WithMessagef(err, "failed to ExportECDSAPublicKey, keyId = %d", keyIndex)
    75  	}
    76  	var bcPubKey bccrypto.PublicKey
    77  	switch keyType {
    78  	case SM2:
    79  		bcPubKey = &bcsm2.PublicKey{K: pub.(*sm2.PublicKey)}
    80  	default:
    81  		return nil, errors.New("unknown key type, keyType = " + string(keyType))
    82  	}
    83  	sdfPrivateKey := &sdfEcdsaPrivateKey{
    84  		sdfHandle: sdf,
    85  		pubKey:    bcPubKey,
    86  		keyId:     uint(keyIndex),
    87  		keyPwd:    keyPwd,
    88  		keyType:   keyType,
    89  	}
    90  	sdfPrivateKey.signer = &ecdsaPrivateKey{sdfPrivateKey}
    91  	return sdfPrivateKey, nil
    92  }
    93  
    94  func (sk *sdfEcdsaPrivateKey) Type() bccrypto.KeyType {
    95  	return sk.PublicKey().Type()
    96  }
    97  
    98  func (sk *sdfEcdsaPrivateKey) Bytes() ([]byte, error) {
    99  	return []byte(fmt.Sprintf("%d", sk.keyId)), nil
   100  }
   101  
   102  func (sk *sdfEcdsaPrivateKey) String() (string, error) {
   103  	return fmt.Sprintf("%d", sk.keyId), nil
   104  }
   105  
   106  func (sk *sdfEcdsaPrivateKey) PublicKey() bccrypto.PublicKey {
   107  	return sk.pubKey
   108  }
   109  
   110  func (sk *sdfEcdsaPrivateKey) Sign(data []byte) ([]byte, error) {
   111  	switch sk.Type() {
   112  	case bccrypto.SM2:
   113  		return sk.sdfHandle.ECCInternalSign(SDFKey{sk.keyId, sk.keyPwd, sk.keyType}, data)
   114  	default:
   115  		return nil, errors.New("Not supported")
   116  	}
   117  }
   118  
   119  func (sk *sdfEcdsaPrivateKey) SignWithOpts(msg []byte, opts *bccrypto.SignOpts) ([]byte, error) {
   120  	if opts == nil {
   121  		return sk.Sign(msg)
   122  	}
   123  	if opts.Hash == bccrypto.HASH_TYPE_SM3 && sk.Type() == bccrypto.SM2 {
   124  		pkSM2, ok := sk.PublicKey().ToStandardKey().(*sm2.PublicKey)
   125  		if !ok {
   126  			return nil, fmt.Errorf("SM2 private key does not match the type it claims")
   127  		}
   128  		uid := opts.UID
   129  		if len(uid) == 0 {
   130  			uid = bccrypto.CRYPTO_DEFAULT_UID
   131  		}
   132  		za, err := sm2.ZA(pkSM2, []byte(uid))
   133  		if err != nil {
   134  			return nil, fmt.Errorf("PKCS11 error: fail to create SM3 digest for msg [%v]", err)
   135  		}
   136  		e := sm3.New()
   137  		e.Write(za)
   138  		e.Write(msg)
   139  		dgst := e.Sum(nil)[:32]
   140  		return sk.Sign(dgst)
   141  	}
   142  	dgst, err := hash.Get(opts.Hash, msg)
   143  	if err != nil {
   144  		return nil, err
   145  	}
   146  	return sk.Sign(dgst)
   147  }
   148  
   149  func (sk *sdfEcdsaPrivateKey) ToStandardKey() crypto.PrivateKey {
   150  	return sk.signer
   151  }