golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
122.94k stars 17.53k forks source link

encoding/asn1: Unmarshalling implicitly tagged GeneralizedTime unmarshalls as UTCTime #28897

Open ChrisPortman opened 5 years ago

ChrisPortman commented 5 years ago

What version of Go are you using (go version)?

$ go version
go version go1.11.2 linux/amd64

Does this issue reproduce with the latest release?

Yes

What operating system and processor architecture are you using (go env)?

go env Output
$ go env
GOARCH="amd64"
GOBIN=""
GOCACHE="/home/chris/.cache/go-build"
GOEXE=""
GOFLAGS=""
GOHOSTARCH="amd64"
GOHOSTOS="linux"
GOOS="linux"
GOPATH="/home/chris/Git/gorims"
GOPROXY=""
GORACE=""
GOROOT="/usr/lib/go"
GOTMPDIR=""
GOTOOLDIR="/usr/lib/go/pkg/tool/linux_amd64"
GCCGO="gccgo"
CC="gcc"
CXX="g++"
CGO_ENABLED="1"
GOMOD=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -m64 -pthread -fmessage-length=0 -fdebug-prefix-map=/tmp/go-build216350556=/tmp/go-build -gno-record-gcc-switches"

What did you do?

Add an implicitly tagged field to a struct of type time.Time and tagged it with "generalized". Marshalled the struct and then unmarshalled it. Unmarshalling failed because it parses the time as a UTCTime.

https://play.golang.org/p/XOKSctdaYl5

What did you expect to see?

Unmarshalling observe the "generalized" attribute tag and parse the time as a Generalized Time

What did you see instead?

Unmarshalling parsed the time as a UTCTime which failed and produced the zero val for the time.

Looking at the current test suite, it appears that the implementation of the "generalized" attribute tag is incomplete:

func TestImplicitTaggedTime(t *testing.T) {
    // An implicitly tagged time value, that happens to have an implicit
    // tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
    // (There's no "timeType" in fieldParameters to determine what type of
    // time should be expected when implicitly tagged.)
    der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
    var result implicitTaggedTimeTest
    if _, err := Unmarshal(der, &result); err != nil {
        t.Fatalf("Error while parsing: %s", err)
    }
    if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
        t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
    }
}

But there IS a timeType set by the use of the "generalized" tag.

gopherbot commented 5 years ago

Change https://golang.org/cl/150601 mentions this issue: encoding/asn1: correctly parse GeneralizedTime

andybons commented 5 years ago

/cc @FiloSottile