gitee.com/lh-her-team/common@v1.5.1/crypto/sdf/ecdsakey.go (about) 1 package sdf 2 3 import ( 4 "crypto" 5 "fmt" 6 "io" 7 "strconv" 8 9 "gitee.com/lh-her-team/common/crypto/hsm" 10 11 "github.com/tjfoc/gmsm/sm3" 12 13 "github.com/tjfoc/gmsm/sm2" 14 15 bccrypto "gitee.com/lh-her-team/common/crypto" 16 bcsm2 "gitee.com/lh-her-team/common/crypto/asym/sm2" 17 "gitee.com/lh-her-team/common/crypto/hash" 18 "github.com/pkg/errors" 19 ) 20 21 type ecdsaPrivateKey struct { 22 priv *sdfEcdsaPrivateKey 23 } 24 25 func (e ecdsaPrivateKey) Public() crypto.PublicKey { 26 return e.priv.pubKey.ToStandardKey() 27 } 28 29 func (e ecdsaPrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) (signature []byte, err error) { 30 return e.priv.SignWithOpts(digest, &bccrypto.SignOpts{Hash: bccrypto.HASH_TYPE_SM3}) 31 } 32 33 // sdfEcdsaPrivateKey represents pkcs11 ecdsa/sm2 private key 34 type sdfEcdsaPrivateKey struct { 35 sdfHandle *SDFHandle 36 pubKey bccrypto.PublicKey 37 keyId uint 38 keyPwd []byte 39 keyType SDFKeyType 40 signer crypto.Signer 41 } 42 43 func NewPrivateKey(sdf *SDFHandle, keyId string, keyPwd []byte, tp bccrypto.KeyType) (bccrypto.PrivateKey, error) { 44 if sdf == nil || len(keyId) == 0 { 45 return nil, errors.New("Invalid parameter, sdfHandle or keyId is nil") 46 } 47 keyType := convertToSDFKeyType(tp) 48 session, err := sdf.getSession() 49 if err != nil { 50 return nil, err 51 } 52 defer sdf.returnSession(err, session) 53 //check keyId 54 keyIndex, err := strconv.Atoi(keyId) 55 if err != nil { 56 return nil, err 57 } 58 { 59 /* 60 check pwd 61 this depends on HSM vendors :-( 62 */ 63 accessKeyId, need := hsm.GetHSMAdapter("").SDF_GetSM2KeyAccessRight(keyIndex) 64 if need { 65 err = sdf.ctx.SDFGetPrivateKeyAccessRight(session, uint(accessKeyId), keyPwd, uint(len(keyPwd))) 66 if err != nil { 67 return nil, errors.WithMessagef(err, "failed to geGetPrivateKeyAccessRight, accessKeyId = %d", accessKeyId) 68 } 69 } 70 } 71 //export pub 72 pub, err := sdf.ExportECDSAPublicKey(SDFKey{uint(keyIndex), keyPwd, SM2}) 73 if err != nil { 74 return nil, errors.WithMessagef(err, "failed to ExportECDSAPublicKey, keyId = %d", keyIndex) 75 } 76 var bcPubKey bccrypto.PublicKey 77 switch keyType { 78 case SM2: 79 bcPubKey = &bcsm2.PublicKey{K: pub.(*sm2.PublicKey)} 80 default: 81 return nil, errors.New("unknown key type, keyType = " + string(keyType)) 82 } 83 sdfPrivateKey := &sdfEcdsaPrivateKey{ 84 sdfHandle: sdf, 85 pubKey: bcPubKey, 86 keyId: uint(keyIndex), 87 keyPwd: keyPwd, 88 keyType: keyType, 89 } 90 sdfPrivateKey.signer = &ecdsaPrivateKey{sdfPrivateKey} 91 return sdfPrivateKey, nil 92 } 93 94 func (sk *sdfEcdsaPrivateKey) Type() bccrypto.KeyType { 95 return sk.PublicKey().Type() 96 } 97 98 func (sk *sdfEcdsaPrivateKey) Bytes() ([]byte, error) { 99 return []byte(fmt.Sprintf("%d", sk.keyId)), nil 100 } 101 102 func (sk *sdfEcdsaPrivateKey) String() (string, error) { 103 return fmt.Sprintf("%d", sk.keyId), nil 104 } 105 106 func (sk *sdfEcdsaPrivateKey) PublicKey() bccrypto.PublicKey { 107 return sk.pubKey 108 } 109 110 func (sk *sdfEcdsaPrivateKey) Sign(data []byte) ([]byte, error) { 111 switch sk.Type() { 112 case bccrypto.SM2: 113 return sk.sdfHandle.ECCInternalSign(SDFKey{sk.keyId, sk.keyPwd, sk.keyType}, data) 114 default: 115 return nil, errors.New("Not supported") 116 } 117 } 118 119 func (sk *sdfEcdsaPrivateKey) SignWithOpts(msg []byte, opts *bccrypto.SignOpts) ([]byte, error) { 120 if opts == nil { 121 return sk.Sign(msg) 122 } 123 if opts.Hash == bccrypto.HASH_TYPE_SM3 && sk.Type() == bccrypto.SM2 { 124 pkSM2, ok := sk.PublicKey().ToStandardKey().(*sm2.PublicKey) 125 if !ok { 126 return nil, fmt.Errorf("SM2 private key does not match the type it claims") 127 } 128 uid := opts.UID 129 if len(uid) == 0 { 130 uid = bccrypto.CRYPTO_DEFAULT_UID 131 } 132 za, err := sm2.ZA(pkSM2, []byte(uid)) 133 if err != nil { 134 return nil, fmt.Errorf("PKCS11 error: fail to create SM3 digest for msg [%v]", err) 135 } 136 e := sm3.New() 137 e.Write(za) 138 e.Write(msg) 139 dgst := e.Sum(nil)[:32] 140 return sk.Sign(dgst) 141 } 142 dgst, err := hash.Get(opts.Hash, msg) 143 if err != nil { 144 return nil, err 145 } 146 return sk.Sign(dgst) 147 } 148 149 func (sk *sdfEcdsaPrivateKey) ToStandardKey() crypto.PrivateKey { 150 return sk.signer 151 }