]> Cypherpunks repositories - gostls13.git/commitdiff
encoding/asn1: fix returned type for an Object Identifier
authorConstantin Konstantinidis <constantinkonstantinidis@gmail.com>
Sat, 19 May 2018 11:59:29 +0000 (13:59 +0200)
committerFilippo Valsorda <filippo@golang.org>
Thu, 31 May 2018 15:24:46 +0000 (15:24 +0000)
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 <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Filippo Valsorda <filippo@golang.org>
src/encoding/asn1/asn1.go
src/encoding/asn1/asn1_test.go
src/encoding/asn1/marshal_test.go

index ae382ee6bf52e08906d21f1d38fcf8c9cc941bd3..1ed357adfffccdf5c2d71ca97d339c5752ffc291 100644 (file)
@@ -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
index 185349773f5937edf388600c1ab8cf4f4fd77d05..f0a54e0cb2e6999b904c4bdb53a916867ab976a1 100644 (file)
@@ -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{
index f20ccdc8e98c56cc32b3787331fc7ec356d2c397..b19b08b35243cc8aaa6dfa9fe4c7aadd663c982a 100644 (file)
@@ -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()