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 }