encoding/asn1: slice is lost during marshal/unmarshal
dvyukov opened this issue · comments
The following program:
package main
import (
"encoding/asn1"
"fmt"
"reflect"
)
func main() {
data := []byte("\x06\x010")
var v interface{}
_, err := asn1.Unmarshal(data, &v)
if err != nil {
return
}
data1, err := asn1.Marshal(v)
if err != nil {
panic(err)
}
var v1 interface{}
_, err = asn1.Unmarshal(data1, &v1)
if err != nil {
panic(err)
}
if !reflect.DeepEqual(v, v1) {
fmt.Printf("v0: %#v data=%q\n", v, data)
fmt.Printf("v1: %#v data=%q\n", v1, data1)
panic("not equal")
}
}
prints:
v0: []int{1, 8} data="\x06\x010"
v1: <nil> data="0\x06\x02\x01\x01\x02\x01\b"
panic: not equal
The slice should not get lost during marshal/unmarshal.
on commit b0532a9
Change https://golang.org/cl/113837 mentions this issue: 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}
If bytes are transmitted to Marshal, a sequence of bytes is returned and not an OID and this is the intended behavior. Object Identifier is a list of int and the example submitted translates to
\x06\x010 = \x06\x01 + "0"
which is OID {1,8}
coded as \x06\x01\x30