]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/asn1: allow lengths up to the maximum int value.
authorAdam Langley <agl@golang.org>
Wed, 18 Apr 2012 17:41:11 +0000 (13:41 -0400)
committerAdam Langley <agl@golang.org>
Wed, 18 Apr 2012 17:41:11 +0000 (13:41 -0400)
Previously we capped lengths at 2**24 rather than 2**31.

R=golang-dev, r, r
CC=golang-dev
https://golang.org/cl/6050050

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

index 3bf81a68cf4f73fdf043252ed9cc1c1f1eefa55c..ac2b5f8daa6cb63ce1d2b689c85eb8a9c76d22cb 100644 (file)
@@ -377,11 +377,6 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
        } else {
                // Bottom 7 bits give the number of length bytes to follow.
                numBytes := int(b & 0x7f)
-               // We risk overflowing a signed 32-bit number if we accept more than 3 bytes.
-               if numBytes > 3 {
-                       err = StructuralError{"length too large"}
-                       return
-               }
                if numBytes == 0 {
                        err = SyntaxError{"indefinite length found (not DER)"}
                        return
@@ -394,8 +389,19 @@ func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset i
                        }
                        b = bytes[offset]
                        offset++
+                       if ret.length >= 1<<23 {
+                               // We can't shift ret.length up without
+                               // overflowing.
+                               err = StructuralError{"length too large"}
+                               return
+                       }
                        ret.length <<= 8
                        ret.length |= int(b)
+                       if ret.length == 0 {
+                               // DER requires that lengths be minimal.
+                               err = StructuralError{"superfluous leading zeros in length"}
+                               return
+                       }
                }
        }
 
index 93803f43532938bf27894d714651646b04236498..eb848bdb4afda1ca5cd747451ea8d3db84dad6e9 100644 (file)
@@ -283,6 +283,12 @@ var tagAndLengthData = []tagAndLengthTest{
        {[]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{}},
+       // 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{}},
 }
 
 func TestParseTagAndLength(t *testing.T) {