From 1b94d427702abd935f6d0ce21ccc91dc4d297368 Mon Sep 17 00:00:00 2001 From: Brian Gitonga Marete <1977446+desdeel2d0m@users.noreply.github.com> Date: Mon, 27 Jul 2015 01:25:02 +0300 Subject: [PATCH] openpgp: Fix panic on opaque subpackets with length 0. Some invalid input may be parsed so that the length of an opaque subpacket turns out to be 0. In such cases, arrange for a StructuralError to be returned indicating truncation. Found using gofuzz. Fixes golang/go#11503 Change-Id: Ib9ce8c604f35a31f852adfcd56a22dfd143a9443 Reviewed-on: https://go-review.googlesource.com/12634 Reviewed-by: Adam Langley --- openpgp/packet/opaque.go | 5 +++-- openpgp/read_test.go | 26 +++++++++++++++++++++++++- 2 files changed, 28 insertions(+), 3 deletions(-) diff --git a/openpgp/packet/opaque.go b/openpgp/packet/opaque.go index f2e00b9..456d807 100644 --- a/openpgp/packet/opaque.go +++ b/openpgp/packet/opaque.go @@ -6,9 +6,10 @@ package packet import ( "bytes" - "golang.org/x/crypto/openpgp/errors" "io" "io/ioutil" + + "golang.org/x/crypto/openpgp/errors" ) // OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is @@ -138,7 +139,7 @@ func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacke uint32(contents[4]) contents = contents[5:] } - if subLen > uint32(len(contents)) { + if subLen > uint32(len(contents)) || subLen == 0 { goto Truncated } subPacket.SubType = contents[0] diff --git a/openpgp/read_test.go b/openpgp/read_test.go index 03bf5d8..0f08313 100644 --- a/openpgp/read_test.go +++ b/openpgp/read_test.go @@ -8,11 +8,12 @@ import ( "bytes" _ "crypto/sha512" "encoding/hex" - "golang.org/x/crypto/openpgp/errors" "io" "io/ioutil" "strings" "testing" + + "golang.org/x/crypto/openpgp/errors" ) func readerFromHex(s string) io.Reader { @@ -368,6 +369,29 @@ func TestNoArmoredData(t *testing.T) { } } +func TestIssue11503(t *testing.T) { + data := "8c040402000aa430aa8228b9248b01fc899a91197130303030" + + buf, err := hex.DecodeString(data) + if err != nil { + t.Errorf("hex.DecodeSting(): %v", err) + } + + kr, err := ReadKeyRing(new(bytes.Buffer)) + if err != nil { + t.Errorf("ReadKeyring(): %v", err) + } + + _, err = ReadMessage(bytes.NewBuffer(buf), kr, + func([]Key, bool) ([]byte, error) { + return []byte("insecure"), nil + }, nil) + + if err == nil { + t.Errorf("ReadMessage(): Unexpected nil error") + } +} + const testKey1KeyId = 0xA34D7E18C20C31BB const testKey3KeyId = 0x338934250CCC0360