]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/asn1: enforce use of short form lengths.
authorDavid Benjamin <davidben@google.com>
Sun, 1 Nov 2015 01:30:00 +0000 (21:30 -0400)
committerAdam Langley <agl@golang.org>
Wed, 18 Nov 2015 00:53:49 +0000 (00:53 +0000)
BER allows the sender to choose either short form or long form where
both are legal, but DER requires the minimal one be used. Enforce this
and add a test. Fix one test which was not minimally-encoded and another
which would not distinguish rejecting the input because the long form
length wasn't minimally-encoded from rejecting it because long form was
chosen when short form was allowed.

Change-Id: I1b56fcca594dcdeddea9378b4fab427cbe7cd26d
Reviewed-on: https://go-review.googlesource.com/16517
Reviewed-by: Adam Langley <agl@golang.org>
Run-TryBot: Adam Langley <agl@golang.org>

src/encoding/asn1/asn1.go
src/encoding/asn1/asn1_test.go

index 2ac411af8820b7c2c8f22f5f442307a3810ec27d..f836963fb725d04267a6ef80743d54380c85ca70 100644 (file)
@@ -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
index fbae7d9f085065409921a06beb911a6314411bd5..0c53442492a0559d8eafa7f5512d0948a22955dc 100644 (file)
@@ -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) {