]> Cypherpunks repositories - gostls13.git/commitdiff
asn1: Stricter checks for DER encoded booleans
authorGerasimos Dimitriadis <gedimitr@gmail.com>
Fri, 24 May 2013 16:37:42 +0000 (12:37 -0400)
committerAdam Langley <agl@golang.org>
Fri, 24 May 2013 16:37:42 +0000 (12:37 -0400)
According to X.690, only 0 and 255 are allowed as values
for encoded booleans. Also added some test for parsing
booleans

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

src/pkg/encoding/asn1/asn1.go [changed mode: 0644->0755]
src/pkg/encoding/asn1/asn1_test.go [changed mode: 0644->0755]

old mode 100644 (file)
new mode 100755 (executable)
index cac9d64..a14df04
@@ -47,11 +47,23 @@ func (e SyntaxError) Error() string { return "ASN.1 syntax error: " + e.Msg }
 
 func parseBool(bytes []byte) (ret bool, err error) {
        if len(bytes) != 1 {
-               err = SyntaxError{"invalid boolean"}
+               err = SyntaxError{"encoding/asn1: invalid boolean"}
                return
        }
 
-       return bytes[0] != 0, nil
+       // DER demands that "If the encoding represents the boolean value TRUE,
+       // its single contents octet shall have all eight bits set to one."
+       // Thus only 0 and 255 are valid encoded values.
+       switch bytes[0] {
+       case 0:
+               ret = false
+       case 0xff:
+               ret = true
+       default:
+               err = SyntaxError{"encoding/asn1: invalid boolean"}
+       }
+
+       return
 }
 
 // INTEGER
old mode 100644 (file)
new mode 100755 (executable)
index 6e98dcf..fb82937
@@ -12,6 +12,32 @@ import (
        "time"
 )
 
+type boolTest struct {
+       in  []byte
+       ok  bool
+       out bool
+}
+
+var boolTestData = []boolTest{
+       {[]byte{0x00}, true, false},
+       {[]byte{0xff}, true, true},
+       {[]byte{0x00, 0x00}, false, false},
+       {[]byte{0xff, 0xff}, false, false},
+       {[]byte{0x01}, false, false},
+}
+
+func TestParseBool(t *testing.T) {
+       for i, test := range boolTestData {
+               ret, err := parseBool(test.in)
+               if (err == nil) != test.ok {
+                       t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
+               }
+               if test.ok && ret != test.out {
+                       t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
+               }
+       }
+}
+
 type int64Test struct {
        in  []byte
        ok  bool
@@ -378,7 +404,7 @@ var unmarshalTestData = []struct {
        {[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
        {[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
        {[]byte{0x01, 0x01, 0x00}, newBool(false)},
-       {[]byte{0x01, 0x01, 0x01}, newBool(true)},
+       {[]byte{0x01, 0x01, 0xff}, newBool(true)},
        {[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
        {[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
 }