github.com/bigzoro/my_simplechain@v0.0.0-20240315012955-8ad0a2a29bb9/core/access_contoller/crypto/pkcs11/rsakey.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/rsa"
    13  	"fmt"
    14  	"io"
    15  	"strconv"
    16  
    17  	"chainmaker.org/chainmaker/common/v2/crypto/hsm"
    18  
    19  	bcrsa "chainmaker.org/chainmaker/common/v2/crypto/asym/rsa"
    20  
    21  	"github.com/pkg/errors"
    22  
    23  	bccrypto "chainmaker.org/chainmaker/common/v2/crypto"
    24  	"github.com/miekg/pkcs11"
    25  )
    26  
    27  type rsaPrivateKey struct {
    28  	priv *p11RsaPrivateKey
    29  }
    30  
    31  func (r rsaPrivateKey) Public() crypto.PublicKey {
    32  	return r.priv.pubKey.ToStandardKey()
    33  }
    34  
    35  func (r rsaPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) {
    36  	if opts == nil {
    37  		return r.priv.Sign(digest)
    38  	}
    39  	if _, ok := opts.(*rsa.PSSOptions); ok {
    40  		return r.priv.SignWithOpts(digest, &bccrypto.SignOpts{
    41  			EncodingType: bcrsa.RSA_PSS,
    42  			Hash:         bccrypto.HashType(opts.HashFunc())})
    43  	}
    44  	return r.priv.SignWithOpts(digest, &bccrypto.SignOpts{Hash: bccrypto.HashType(opts.HashFunc())})
    45  }
    46  
    47  // p11RsaPrivateKey represents pkcs11 rsa private key
    48  type p11RsaPrivateKey struct {
    49  	p11Ctx    *P11Handle
    50  	pubKey    bccrypto.PublicKey
    51  	keyId     []byte
    52  	keyType   P11KeyType
    53  	keyObject pkcs11.ObjectHandle
    54  
    55  	signer crypto.Signer
    56  }
    57  
    58  func NewP11RSAPrivateKey(p11 *P11Handle, keyId []byte, keyType P11KeyType) (bccrypto.PrivateKey, error) {
    59  	if p11 == nil || keyId == nil {
    60  		return nil, errors.New("Invalid parameter, p11 or keyId is nil")
    61  	}
    62  
    63  	//find private key
    64  	id, err := strconv.Atoi(string(keyId))
    65  	if err != nil {
    66  		return nil, err
    67  	}
    68  	keyIdStr, err := hsm.GetHSMAdapter("").PKCS11_GetRSAKeyId(id, true)
    69  	if err != nil {
    70  		return nil, err
    71  	}
    72  	obj, err := p11.findPrivateKey([]byte(keyIdStr))
    73  	if err != nil {
    74  		return nil, errors.WithMessagef(err, "failed to find private key, keyId = %s", keyIdStr)
    75  	}
    76  	//export public key
    77  	keyIdStr, err = hsm.GetHSMAdapter("").PKCS11_GetRSAKeyId(id, false)
    78  	if err != nil {
    79  		return nil, err
    80  	}
    81  	pubKey, err := p11.ExportRSAPublicKey([]byte(keyIdStr))
    82  	if err != nil {
    83  		return nil, errors.WithMessagef(err, "failed to export rsa public key, keyId = %s", keyIdStr)
    84  	}
    85  
    86  	p11PrivateKey := &p11RsaPrivateKey{
    87  		p11Ctx:    p11,
    88  		pubKey:    &bcrsa.PublicKey{K: pubKey},
    89  		keyId:     keyId,
    90  		keyType:   keyType,
    91  		keyObject: *obj,
    92  	}
    93  
    94  	p11PrivateKey.signer = &rsaPrivateKey{p11PrivateKey}
    95  
    96  	return p11PrivateKey, nil
    97  }
    98  
    99  func (sk *p11RsaPrivateKey) Type() bccrypto.KeyType {
   100  	return sk.PublicKey().Type()
   101  }
   102  
   103  func (sk *p11RsaPrivateKey) Bytes() ([]byte, error) {
   104  	return sk.keyId, nil
   105  }
   106  
   107  func (sk *p11RsaPrivateKey) String() (string, error) {
   108  	return string(sk.keyId), nil
   109  }
   110  
   111  func (sk *p11RsaPrivateKey) PublicKey() bccrypto.PublicKey {
   112  	return sk.pubKey
   113  }
   114  
   115  func (sk *p11RsaPrivateKey) Sign(data []byte) ([]byte, error) {
   116  	mech := uint(pkcs11.CKM_SHA256_RSA_PKCS)
   117  	sig, err := sk.p11Ctx.Sign(sk.keyObject, pkcs11.NewMechanism(mech, nil), data)
   118  	if err != nil {
   119  		return nil, fmt.Errorf("PKCS11 error: fail to sign [%s]", err)
   120  	}
   121  
   122  	return sig, nil
   123  }
   124  
   125  func (sk *p11RsaPrivateKey) SignWithOpts(msg []byte, opts *bccrypto.SignOpts) ([]byte, error) {
   126  	if opts == nil {
   127  		return sk.Sign(msg)
   128  	}
   129  	var mech uint
   130  
   131  	switch opts.EncodingType {
   132  	case bcrsa.RSA_PSS:
   133  		//mech = pkcs11.CKM_SHA256_RSA_PKCS_PSS
   134  		return nil, errors.New("rsa_pss not supported, todo")
   135  	default:
   136  		switch opts.Hash {
   137  		case bccrypto.HASH_TYPE_SHA256:
   138  			mech = pkcs11.CKM_SHA256_RSA_PKCS
   139  		case bccrypto.HASH_TYPE_SHA3_256:
   140  			mech = pkcs11.CKM_SHA3_256_RSA_PKCS
   141  		default:
   142  			return nil, fmt.Errorf("PKCS11 error: unsupported hash type [%v]", opts.Hash)
   143  		}
   144  	}
   145  
   146  	sig, err := sk.p11Ctx.Sign(sk.keyObject, pkcs11.NewMechanism(mech, nil), msg)
   147  	if err != nil {
   148  		return nil, fmt.Errorf("PKCS11 error: fail to sign [%s]", err)
   149  	}
   150  
   151  	return sig, nil
   152  }
   153  
   154  func (sk *p11RsaPrivateKey) ToStandardKey() crypto.PrivateKey {
   155  	return sk.signer
   156  }