diff --git a/sm2/sm2.go b/sm2/sm2.go index ab3977b..549f3b6 100644 --- a/sm2/sm2.go +++ b/sm2/sm2.go @@ -581,6 +581,10 @@ func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) { for len(bytes) > 1 && bytes[0] == 0 { bytes = bytes[1:] } + if len(bytes) == 0 { + b.SetError(errors.New("invalid integer")) + return + } b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) { if bytes[0]&0x80 != 0 { c.AddUint8(0) diff --git a/sm2/sm2_legacy.go b/sm2/sm2_legacy.go index efd1bea..c540e5b 100644 --- a/sm2/sm2_legacy.go +++ b/sm2/sm2_legacy.go @@ -157,6 +157,9 @@ func SignWithSM2(rand io.Reader, priv *ecdsa.PrivateKey, uid, msg []byte) (r, s // Compliance with GB/T 32918.2-2016 regardless it's SM2 curve or not. // Caller should make sure the hash's correctness. func Verify(pub *ecdsa.PublicKey, hash []byte, r, s *big.Int) bool { + if r.Sign() <= 0 || s.Sign() <= 0 { + return false + } sig, err := encodeSignature(r.Bytes(), s.Bytes()) if err != nil { return false diff --git a/sm2/sm2_test.go b/sm2/sm2_test.go index 891e9c4..a068644 100644 --- a/sm2/sm2_test.go +++ b/sm2/sm2_test.go @@ -449,6 +449,70 @@ func TestZeroHashSignature(t *testing.T) { } } +func TestZeroSignature(t *testing.T) { + privKey, err := GenerateKey(rand.Reader) + if err != nil { + panic(err) + } + if Verify(&privKey.PublicKey, make([]byte, 64), big.NewInt(0), big.NewInt(0)) { + t.Error("Verify with r,s=0 succeeded") + } +} + +func TestNegtativeSignature(t *testing.T) { + zeroHash := make([]byte, 64) + + privKey, err := GenerateKey(rand.Reader) + if err != nil { + panic(err) + } + r, s, err := Sign(rand.Reader, &privKey.PrivateKey, zeroHash) + if err != nil { + panic(err) + } + + r = r.Neg(r) + if Verify(&privKey.PublicKey, zeroHash, r, s) { + t.Error("Verify with r=-r succeeded") + } +} + +func TestRPlusNSignature(t *testing.T) { + zeroHash := make([]byte, 64) + + privKey, err := GenerateKey(rand.Reader) + if err != nil { + panic(err) + } + r, s, err := Sign(rand.Reader, &privKey.PrivateKey, zeroHash) + if err != nil { + panic(err) + } + + r = r.Add(r, P256().Params().N) + if Verify(&privKey.PublicKey, zeroHash, r, s) { + t.Error("Verify with r=r+n succeeded") + } +} + +func TestRMinusNSignature(t *testing.T) { + zeroHash := make([]byte, 64) + + privKey, err := GenerateKey(rand.Reader) + if err != nil { + panic(err) + } + r, s, err := Sign(rand.Reader, &privKey.PrivateKey, zeroHash) + if err != nil { + panic(err) + } + + r = r.Sub(r, P256().Params().N) + if Verify(&privKey.PublicKey, zeroHash, r, s) { + t.Error("Verify with r=r-n succeeded") + } +} + func TestEqual(t *testing.T) { private, _ := GenerateKey(rand.Reader) public := &private.PublicKey