diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go index 2ac411af88..f836963fb7 100644 --- a/src/encoding/asn1/asn1.go +++ b/src/encoding/asn1/asn1.go @@ -475,6 +475,11 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i return } } + // Short lengths must be encoded in short form. + if ret.length < 0x80 { + err = StructuralError{"non-minimal length"} + return + } } return diff --git a/src/encoding/asn1/asn1_test.go b/src/encoding/asn1/asn1_test.go index fbae7d9f08..0c53442492 100644 --- a/src/encoding/asn1/asn1_test.go +++ b/src/encoding/asn1/asn1_test.go @@ -354,17 +354,19 @@ var tagAndLengthData = []tagAndLengthTest{ {[]byte{0x1f, 0x01, 0x00}, true, tagAndLength{0, 1, 0, false}}, {[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}}, {[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}}, - {[]byte{0x00, 0x81, 0x01}, true, tagAndLength{0, 0, 1, false}}, + {[]byte{0x00, 0x81, 0x80}, true, tagAndLength{0, 0, 128, false}}, {[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}}, {[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}}, {[]byte{0x1f, 0x85}, false, tagAndLength{}}, {[]byte{0x30, 0x80}, false, tagAndLength{}}, // Superfluous zeros in the length should be an error. - {[]byte{0xa0, 0x82, 0x00, 0x01}, false, tagAndLength{}}, + {[]byte{0xa0, 0x82, 0x00, 0xff}, false, tagAndLength{}}, // Lengths up to the maximum size of an int should work. {[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}}, // Lengths that would overflow an int should be rejected. {[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}}, + // Long length form may not be used for lengths that fit in short form. + {[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}}, } func TestParseTagAndLength(t *testing.T) {