From: Constantin Konstantinidis Date: Sat, 19 May 2018 11:59:29 +0000 (+0200) Subject: encoding/asn1: fix returned type for an Object Identifier X-Git-Tag: go1.11beta1~246 X-Git-Url: http://www.git.cypherpunks.su/?a=commitdiff_plain;h=6b4828a206c2c5a5b6bf3cd4bd92b9530ecca5e5;p=gostls13.git encoding/asn1: fix returned type for an Object Identifier Unmarshal/Marshal/Unmarshal was not idempotent as the Object Identifier type was not returned through the interface. The limit case OID = 0 returns an error. The zero OID is 0.0 A test is fixed to use the Object Identifier type. Other related test are added. Fixes #11130 Change-Id: I15483a3126066c9b99cf5bd9c4b0cc15ec1d61ca Reviewed-on: https://go-review.googlesource.com/113837 Run-TryBot: Brad Fitzpatrick TryBot-Result: Gobot Gobot Reviewed-by: Filippo Valsorda --- diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go index ae382ee6bf..1ed357adff 100644 --- a/src/encoding/asn1/asn1.go +++ b/src/encoding/asn1/asn1.go @@ -250,7 +250,7 @@ func (oi ObjectIdentifier) String() string { // parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and // returns it. An object identifier is a sequence of variable length integers // that are assigned in a hierarchy. -func parseObjectIdentifier(bytes []byte) (s []int, err error) { +func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) { if len(bytes) == 0 { err = SyntaxError{"zero length OBJECT IDENTIFIER"} return diff --git a/src/encoding/asn1/asn1_test.go b/src/encoding/asn1/asn1_test.go index 185349773f..f0a54e0cb2 100644 --- a/src/encoding/asn1/asn1_test.go +++ b/src/encoding/asn1/asn1_test.go @@ -227,7 +227,7 @@ func TestBitStringRightAlign(t *testing.T) { type objectIdentifierTest struct { in []byte ok bool - out []int + out ObjectIdentifier // has base type[]int } var objectIdentifierTestData = []objectIdentifierTest{ diff --git a/src/encoding/asn1/marshal_test.go b/src/encoding/asn1/marshal_test.go index f20ccdc8e9..b19b08b352 100644 --- a/src/encoding/asn1/marshal_test.go +++ b/src/encoding/asn1/marshal_test.go @@ -11,6 +11,7 @@ import ( "strings" "testing" "time" + "reflect" ) type intStruct struct { @@ -253,6 +254,62 @@ func TestInvalidUTF8(t *testing.T) { } } +func TestMarshalOID(t *testing.T) { + var marshalTestsOID = []marshalTest{ + {[]byte("\x06\x01\x30"), "0403060130"}, // bytes format returns a byte sequence \x04 + // {ObjectIdentifier([]int{0}), "060100"}, // returns an error as OID 0.0 has the same encoding + {[]byte("\x06\x010"), "0403060130"}, // same as above "\x06\x010" = "\x06\x01" + "0" + {ObjectIdentifier([]int{2,999,3}), "0603883703"}, // Example of ITU-T X.690 + {ObjectIdentifier([]int{0,0}), "060100"}, // zero OID + } + for i, test := range marshalTestsOID { + data, err := Marshal(test.in) + if err != nil { + t.Errorf("#%d failed: %s", i, err) + } + out, _ := hex.DecodeString(test.out) + if !bytes.Equal(out, data) { + t.Errorf("#%d got: %x want %x\n\t%q\n\t%q", i, data, out, data, out) + } + } +} + +func TestIssue11130(t *testing.T) { + data := []byte("\x06\x010") // == \x06\x01\x30 == OID = 0 (the figure) + var v interface{} + // v has Zero value here and Elem() would panic + _, err := Unmarshal(data, &v) + if err != nil { + t.Errorf("%v", err) + return + } + if reflect.TypeOf(v).String() != reflect.TypeOf(ObjectIdentifier{}).String() { + t.Errorf("marshal OID returned an invalid type") + return + } + + data1, err := Marshal(v) + if err != nil { + t.Errorf("%v", err) + return + } + + if !bytes.Equal(data,data1) { + t.Errorf("got: %q, want: %q \n", data1, data) + return + } + + var v1 interface{} + _, err = Unmarshal(data1, &v1) + if err != nil { + t.Errorf("%v", err) + return + } + if !reflect.DeepEqual(v, v1) { + t.Errorf("got: %#v data=%q , want : %#v data=%q\n ", v1, data1, v, data) + } +} + func BenchmarkMarshal(b *testing.B) { b.ReportAllocs()