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

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