From af48543c5458086435c92f63677723217900c1b5 Mon Sep 17 00:00:00 2001 From: Gerasimos Dimitriadis Date: Fri, 24 May 2013 12:37:42 -0400 Subject: [PATCH] asn1: Stricter checks for DER encoded booleans 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 | 16 ++++++++++++++-- src/pkg/encoding/asn1/asn1_test.go | 28 +++++++++++++++++++++++++++- 2 files changed, 41 insertions(+), 3 deletions(-) mode change 100644 => 100755 src/pkg/encoding/asn1/asn1.go mode change 100644 => 100755 src/pkg/encoding/asn1/asn1_test.go diff --git a/src/pkg/encoding/asn1/asn1.go b/src/pkg/encoding/asn1/asn1.go old mode 100644 new mode 100755 index cac9d64b5e..a14df04eff --- a/src/pkg/encoding/asn1/asn1.go +++ b/src/pkg/encoding/asn1/asn1.go @@ -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 diff --git a/src/pkg/encoding/asn1/asn1_test.go b/src/pkg/encoding/asn1/asn1_test.go old mode 100644 new mode 100755 index 6e98dcf0b9..fb82937b7e --- a/src/pkg/encoding/asn1/asn1_test.go +++ b/src/pkg/encoding/asn1/asn1_test.go @@ -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)}}, } -- 2.48.1