// SM2Sign signs
func SM2Sign(signKey interface{}, msg []byte) ([]byte, error) {
sm2Eckey := signKey.(*Sm2EcKey)
hash := sm3.New()
hash.Write(msg)
h := hash.Sum(nil)
sig := make([]byte, 128, 128)
var sigLength uint32
var csigLength C.uint
res := C.SM2Sign(C.int(0), unsafe.Pointer(&h[0]), C.int(len(h)),
unsafe.Pointer(&sig[0]), &csigLength, unsafe.Pointer(sm2Eckey.ecKey)) // <-- sm2Eckey.ecKey 为0
sigLength = uint32(csigLength)
if res == 0 {
return nil, fmt.Errorf("SM2Sign error")
}
return sig[:sigLength], nil
}
panic 栈:
github.com/hyperledger/fabric/sm/sm2._Cfunc_SM2Sign(0x0, 0xc004fe2bc0, 0x20, 0xc017bd6c00, 0xc00774c4b8, 0x7f8d38000f90, 0x0) ,最后一个参数为0,
/**
* Computes ECDSA signature of a given hash value using the supplied private key
* [IN] type: this parameter is ignored
* [IN] dgst: pointer to the hash value to sign
* [IN] dLen: length of the hash value
* [OUT] sig: buffer to hold the DER encoded signature. sig must point to ECDSA_size(eckey) bytes of memory.
* [OUT]sigLen: pointer to the length of the returned signature
* [IN]eckey: EC_KEY object containing a private EC key
* [RET] int: return 1 on success and 0 otherwise
*/
EXPORTDLL int SM2Sign(int type, void* dgst, int dLen, void* sig, unsigned int* sigLen, void * eckey)
最后1个参数不应该为0。
func (s *sm2Signer) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
keyBytes, _ := k.Bytes()
key, err := sm2.LoadSM2PrivKeyFromBytes(keyBytes) // 获取key
if err != nil {
return nil, err
}
defer sm2.FreeSm2EcKey(key) // 退出时释放C资源
sig, err := sm2.SM2Sign(key, digest)
return sig, err
}
func LoadSM2PrivKeyFromBytes(priv []byte) (*Sm2EcKey, error) {
sm2EcKey := &Sm2EcKey{}
sm2EcKey.ecKey = C.LoadSM2PrivKeyFromBytes(unsafe.Pointer(&priv[0]), C.int(len(priv)))
if sm2EcKey.ecKey == nil { // ecKey为nil时会返回错误
return nil, fmt.Errorf("LoadSM2PrivKeyFromByte error")
}
return sm2EcKey, nil
}
type Sm2EcKey struct {
ecKey *C.EC_KEY // 保存C分配的内存指针
}