github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/sdf/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 sdf
     9  
    10  import (
    11  	"crypto"
    12  	"fmt"
    13  	"io"
    14  	"strconv"
    15  
    16  	"chainmaker.org/chainmaker/common/v2/crypto/hsm"
    17  
    18  	"github.com/tjfoc/gmsm/sm3"
    19  
    20  	"github.com/tjfoc/gmsm/sm2"
    21  
    22  	bccrypto "chainmaker.org/chainmaker/common/v2/crypto"
    23  	bcsm2 "chainmaker.org/chainmaker/common/v2/crypto/asym/sm2"
    24  	"chainmaker.org/chainmaker/common/v2/crypto/hash"
    25  	"github.com/pkg/errors"
    26  )
    27  
    28  type ecdsaPrivateKey struct {
    29  	priv *sdfEcdsaPrivateKey
    30  }
    31  
    32  func (e ecdsaPrivateKey) Public() crypto.PublicKey {
    33  	return e.priv.pubKey.ToStandardKey()
    34  }
    35  
    36  func (e ecdsaPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
    37  	return e.priv.SignWithOpts(digest, &bccrypto.SignOpts{Hash: bccrypto.HASH_TYPE_SM3})
    38  }
    39  
    40  // sdfEcdsaPrivateKey represents pkcs11 ecdsa/sm2 private key
    41  type sdfEcdsaPrivateKey struct {
    42  	sdfHandle *SDFHandle
    43  	pubKey    bccrypto.PublicKey
    44  	keyId     uint
    45  	keyPwd    []byte
    46  	keyType   SDFKeyType
    47  
    48  	signer crypto.Signer
    49  }
    50  
    51  func NewPrivateKey(sdf *SDFHandle, keyId string, keyPwd []byte, tp bccrypto.KeyType) (bccrypto.PrivateKey, error) {
    52  	if sdf == nil || len(keyId) == 0 {
    53  		return nil, errors.New("Invalid parameter, sdfHandle or keyId is nil")
    54  	}
    55  
    56  	keyType := convertToSDFKeyType(tp)
    57  
    58  	session, err := sdf.getSession()
    59  	if err != nil {
    60  		return nil, err
    61  	}
    62  	defer sdf.returnSession(err, session)
    63  
    64  	//check keyId
    65  	keyIndex, err := strconv.Atoi(keyId)
    66  	if err != nil {
    67  		return nil, err
    68  	}
    69  
    70  	{
    71  		/*
    72  			check pwd
    73  			this depends on HSM vendors :-(
    74  		*/
    75  		accessKeyId, need := hsm.GetHSMAdapter("").SDF_GetSM2KeyAccessRight(keyIndex)
    76  		if need {
    77  			err = sdf.ctx.SDFGetPrivateKeyAccessRight(session, uint(accessKeyId), keyPwd, uint(len(keyPwd)))
    78  			if err != nil {
    79  				return nil, errors.WithMessagef(err, "failed to geGetPrivateKeyAccessRight, accessKeyId = %d", accessKeyId)
    80  			}
    81  		}
    82  	}
    83  
    84  	//export pub
    85  	pub, err := sdf.ExportECDSAPublicKey(SDFKey{uint(keyIndex), keyPwd, SM2})
    86  	if err != nil {
    87  		return nil, errors.WithMessagef(err, "failed to ExportECDSAPublicKey, keyId = %d", keyIndex)
    88  	}
    89  
    90  	var bcPubKey bccrypto.PublicKey
    91  	switch keyType {
    92  	case SM2:
    93  		bcPubKey = &bcsm2.PublicKey{K: pub.(*sm2.PublicKey)}
    94  	default:
    95  		return nil, errors.New("unknown key type, keyType = " + string(keyType))
    96  	}
    97  
    98  	sdfPrivateKey := &sdfEcdsaPrivateKey{
    99  		sdfHandle: sdf,
   100  		pubKey:    bcPubKey,
   101  		keyId:     uint(keyIndex),
   102  		keyPwd:    keyPwd,
   103  		keyType:   keyType,
   104  	}
   105  
   106  	sdfPrivateKey.signer = &ecdsaPrivateKey{sdfPrivateKey}
   107  
   108  	return sdfPrivateKey, nil
   109  }
   110  
   111  func (sk *sdfEcdsaPrivateKey) Type() bccrypto.KeyType {
   112  	return sk.PublicKey().Type()
   113  }
   114  
   115  func (sk *sdfEcdsaPrivateKey) Bytes() ([]byte, error) {
   116  	return []byte(fmt.Sprintf("%d", sk.keyId)), nil
   117  }
   118  
   119  func (sk *sdfEcdsaPrivateKey) String() (string, error) {
   120  	return fmt.Sprintf("%d", sk.keyId), nil
   121  }
   122  
   123  func (sk *sdfEcdsaPrivateKey) PublicKey() bccrypto.PublicKey {
   124  	return sk.pubKey
   125  }
   126  
   127  func (sk *sdfEcdsaPrivateKey) Sign(data []byte) ([]byte, error) {
   128  	switch sk.Type() {
   129  	case bccrypto.SM2:
   130  		return sk.sdfHandle.ECCInternalSign(SDFKey{sk.keyId, sk.keyPwd, sk.keyType}, data)
   131  	default:
   132  		return nil, errors.New("Not supported")
   133  	}
   134  }
   135  
   136  func (sk *sdfEcdsaPrivateKey) 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(dgst)
   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 *sdfEcdsaPrivateKey) ToStandardKey() crypto.PrivateKey {
   169  	return sk.signer
   170  }