github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/pkcs11/ecdsakey.go (about)

     1  /*
     2  Copyright (C) BABEC. All rights reserved.
     3  Copyright (C) THL A29 Limited, a Tencent company. All rights reserved.
     4  
     5  SPDX-License-Identifier: Apache-2.0
     6  */
     7  
     8  package pkcs11
     9  
    10  import (
    11  	"crypto"
    12  	"crypto/ecdsa"
    13  	"io"
    14  	"strconv"
    15  
    16  	"chainmaker.org/chainmaker/common/v2/crypto/hsm"
    17  
    18  	bccrypto "chainmaker.org/chainmaker/common/v2/crypto"
    19  	bcecdsa "chainmaker.org/chainmaker/common/v2/crypto/asym/ecdsa"
    20  	bcsm2 "chainmaker.org/chainmaker/common/v2/crypto/asym/sm2"
    21  	"chainmaker.org/chainmaker/common/v2/crypto/hash"
    22  	"github.com/miekg/pkcs11"
    23  	"github.com/pkg/errors"
    24  	"github.com/tjfoc/gmsm/sm2"
    25  )
    26  
    27  type ecdsaPrivateKey struct {
    28  	priv *p11EcdsaPrivateKey
    29  }
    30  
    31  func (e ecdsaPrivateKey) Public() crypto.PublicKey {
    32  	return e.priv.pubKey.ToStandardKey()
    33  }
    34  
    35  func (e ecdsaPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
    36  	return e.priv.SignWithOpts(digest, &bccrypto.SignOpts{Hash: bccrypto.HASH_TYPE_SM3})
    37  }
    38  
    39  // p11EcdsaPrivateKey represents pkcs11 ecdsa/sm2 private key
    40  type p11EcdsaPrivateKey struct {
    41  	p11Ctx    *P11Handle
    42  	pubKey    bccrypto.PublicKey
    43  	keyId     []byte
    44  	keyType   P11KeyType
    45  	keyObject pkcs11.ObjectHandle
    46  
    47  	signer crypto.Signer
    48  }
    49  
    50  func NewP11ECDSAPrivateKey(p11 *P11Handle, keyId []byte, keyType P11KeyType) (bccrypto.PrivateKey, error) {
    51  	if p11 == nil || keyId == nil {
    52  		return nil, errors.New("Invalid parameter, p11 or keyId is nil")
    53  	}
    54  
    55  	//find private key
    56  	id, err := strconv.Atoi(string(keyId))
    57  	if err != nil {
    58  		return nil, err
    59  	}
    60  	keyIdStr, err := hsm.GetHSMAdapter("").PKCS11_GetSM2KeyId(id, true)
    61  	if err != nil {
    62  		return nil, err
    63  	}
    64  	obj, err := p11.findPrivateKey([]byte(keyIdStr))
    65  	if err != nil {
    66  		return nil, errors.WithMessagef(err, "failed to find private key, keyId = %s", keyIdStr)
    67  	}
    68  
    69  	//export public key
    70  	keyIdStr, err = hsm.GetHSMAdapter("").PKCS11_GetSM2KeyId(id, false)
    71  	if err != nil {
    72  		return nil, err
    73  	}
    74  	pubKey, err := p11.ExportECDSAPublicKey([]byte(keyIdStr), keyType)
    75  	if err != nil {
    76  		return nil, errors.WithMessagef(err, "failed to export public key, keyId = %s", keyIdStr)
    77  	}
    78  
    79  	var bcPubKey bccrypto.PublicKey
    80  	switch keyType {
    81  	case SM2:
    82  		bcPubKey = &bcsm2.PublicKey{K: pubKey.(*sm2.PublicKey)}
    83  	case ECDSA:
    84  		bcPubKey = &bcecdsa.PublicKey{K: pubKey.(*ecdsa.PublicKey)}
    85  	default:
    86  		return nil, errors.New("unknown key type")
    87  	}
    88  
    89  	p11PrivateKey := &p11EcdsaPrivateKey{
    90  		p11Ctx:    p11,
    91  		pubKey:    bcPubKey,
    92  		keyId:     keyId,
    93  		keyType:   keyType,
    94  		keyObject: *obj,
    95  	}
    96  
    97  	p11PrivateKey.signer = &ecdsaPrivateKey{p11PrivateKey}
    98  
    99  	return p11PrivateKey, nil
   100  }
   101  
   102  func (sk *p11EcdsaPrivateKey) Type() bccrypto.KeyType {
   103  	return sk.PublicKey().Type()
   104  }
   105  
   106  func (sk *p11EcdsaPrivateKey) Bytes() ([]byte, error) {
   107  	return sk.keyId, nil
   108  }
   109  
   110  func (sk *p11EcdsaPrivateKey) String() (string, error) {
   111  	return string(sk.keyId), nil
   112  }
   113  
   114  func (sk *p11EcdsaPrivateKey) PublicKey() bccrypto.PublicKey {
   115  	return sk.pubKey
   116  }
   117  
   118  func (sk *p11EcdsaPrivateKey) Sign(data []byte) ([]byte, error) {
   119  	var mech uint
   120  	switch sk.Type() {
   121  	case bccrypto.SM2:
   122  		// test needed to verify correctness
   123  		//mech = CKM_SM3_SM2_APPID1_DER
   124  		//mech = CKM_SM3_SM2
   125  		mech = hsm.GetHSMAdapter("").PKCS11_GetSM3SM2CKM()
   126  		if mech == 0 {
   127  			mech = CKM_SM3_SM2
   128  		}
   129  	case bccrypto.ECC_Secp256k1, bccrypto.ECC_NISTP256, bccrypto.ECC_NISTP384, bccrypto.ECC_NISTP521:
   130  		mech = pkcs11.CKM_ECDSA
   131  	}
   132  
   133  	return sk.p11Ctx.Sign(sk.keyObject, pkcs11.NewMechanism(mech, nil), data)
   134  }
   135  
   136  func (sk *p11EcdsaPrivateKey) SignWithOpts(msg []byte, opts *bccrypto.SignOpts) ([]byte, error) {
   137  	if opts == nil {
   138  		return sk.Sign(msg)
   139  	}
   140  	if opts.Hash == bccrypto.HASH_TYPE_SM3 && sk.Type() == bccrypto.SM2 {
   141  		//pkSM2, ok := sk.PublicKey().ToStandardKey().(*sm2.PublicKey)
   142  		//if !ok {
   143  		//	return nil, fmt.Errorf("SM2 private key does not match the type it claims")
   144  		//}
   145  		//uid := opts.UID
   146  		//if len(uid) == 0 {
   147  		//	uid = bccrypto.CRYPTO_DEFAULT_UID
   148  		//}
   149  		//
   150  		//za, err := sm2.ZA(pkSM2, []byte(uid))
   151  		//if err != nil {
   152  		//	return nil, fmt.Errorf("PKCS11 error: fail to create SM3 digest for msg [%v]", err)
   153  		//}
   154  		//e := sm3.New()
   155  		//e.Write(za)
   156  		//e.Write(msg)
   157  		//dgst := e.Sum(nil)[:32]
   158  
   159  		return sk.Sign(msg)
   160  	}
   161  	dgst, err := hash.Get(opts.Hash, msg)
   162  	if err != nil {
   163  		return nil, err
   164  	}
   165  	return sk.Sign(dgst)
   166  }
   167  
   168  func (sk *p11EcdsaPrivateKey) ToStandardKey() crypto.PrivateKey {
   169  	return sk.signer
   170  }