From 57d01255e8ab08a59b7e557f879f24e3ef5f6861 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Fri, 28 Oct 2022 09:31:41 +0800 Subject: [PATCH] handle padding zero, #90 --- sm2/sm2.go | 2 +- sm2/sm2_test.go | 24 ++++++++++++++++++++++++ sm9/sm9.go | 2 +- 3 files changed, 26 insertions(+), 2 deletions(-) diff --git a/sm2/sm2.go b/sm2/sm2.go index c0e2fa7..f165588 100644 --- a/sm2/sm2.go +++ b/sm2/sm2.go @@ -457,7 +457,7 @@ func unmarshalASN1Ciphertext(ciphertext []byte) (*big.Int, *big.Int, []byte, []b ) input := cryptobyte.String(ciphertext) if !input.ReadASN1(&inner, asn1.SEQUENCE) || - !input.Empty() || + (!input.Empty() && !subtle.ConstantTimeAllZero(input)) || !inner.ReadASN1Integer(x1) || !inner.ReadASN1Integer(y1) || !inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) || diff --git a/sm2/sm2_test.go b/sm2/sm2_test.go index afacb51..ef76ace 100644 --- a/sm2/sm2_test.go +++ b/sm2/sm2_test.go @@ -5,11 +5,16 @@ import ( "crypto/ecdsa" "crypto/elliptic" "crypto/rand" + "encoding/hex" + "math/big" "reflect" "testing" + "github.com/emmansun/gmsm/internal/subtle" "github.com/emmansun/gmsm/sm2/sm2ec" "github.com/emmansun/gmsm/sm3" + "golang.org/x/crypto/cryptobyte" + "golang.org/x/crypto/cryptobyte/asn1" ) func Test_SplicingOrder(t *testing.T) { @@ -324,6 +329,25 @@ func TestEqual(t *testing.T) { } } +func TestCipherASN1WithInvalidBytes(t *testing.T) { + var ( + x1, y1 = &big.Int{}, &big.Int{} + c2, c3 []byte + inner cryptobyte.String + ) + ciphertext, _ := hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A0000") + input := cryptobyte.String(ciphertext) + if !input.ReadASN1(&inner, asn1.SEQUENCE) || + (!input.Empty() && !subtle.ConstantTimeAllZero(input)) || + !inner.ReadASN1Integer(x1) || + !inner.ReadASN1Integer(y1) || + !inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) || + !inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) || + !inner.Empty() { + t.Fatalf("invalid cipher text") + } +} + func BenchmarkGenerateKey_SM2(b *testing.B) { b.ReportAllocs() b.ResetTimer() diff --git a/sm9/sm9.go b/sm9/sm9.go index ccba988..ef52d7b 100644 --- a/sm9/sm9.go +++ b/sm9/sm9.go @@ -408,7 +408,7 @@ func DecryptASN1(priv *EncryptPrivateKey, uid, ciphertext []byte) ([]byte, error ) input := cryptobyte.String(ciphertext) if !input.ReadASN1(&inner, asn1.SEQUENCE) || - !input.Empty() || + (!input.Empty() && !subtle.ConstantTimeAllZero(input)) || !inner.ReadASN1Integer(&encType) || !inner.ReadASN1BitStringAsBytes(&c1Bytes) || !inner.ReadASN1Bytes(&c3Bytes, asn1.OCTET_STRING) ||