Description
Go version
1.21.5
What operating system and processor architecture are you using (go env
)?
GO111MODULE='on'
GOARCH='arm64'
GOBIN=''
GOCACHE='/Users/ian/Library/Caches/go-build'
GOENV='/Users/ian/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFLAGS=''
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMODCACHE='/Users/ian/Developer/go/pkg/mod'
GOOS='darwin'
GOPATH='/Users/ian/Developer/go'
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go/current'
GOSUMDB='sum.golang.org'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/current/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.21.5'
GCCGO='gccgo'
AR='ar'
CC='clang'
CXX='clang++'
CGO_ENABLED='1'
GOMOD='/dev/null'
GOWORK=''
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
PKG_CONFIG='pkg-config'
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/72/2kjqjqwd61d83xhhzwptf_sc0000gn/T/go-build3674955566=/tmp/go-build -gno-record-gcc-switches -fno-common'
What did you do?
The encoding/asn1
package supports marshalling time.Time
structures to either a ASN.1 UTCTime
or GeneralizedTime
. The behaviour is controlled by using struct tags or passing parameters with asn1.MarshalWithParams
, but by default the package will use UTCTime. (Aside: this seems to be a really poor choice for a default behaviour, considering UTCTime is not Y2K compliant)
However, it's possible for the asn1 package to encode an invalid GeneralizedTime value without producing an error.
Take the following example:
t := time.Date(2023, 12, 28, 16, 49, 55, 00, time.UTC)
tVal, err := asn1.MarshalWithParams(t, "tag:24")
if err != nil {
panic(err)
}
// tVal = 98 0d 32 33 31 32 32 38 31 36 34 39 35 35 5a (..231228164955Z)
Here, we're passing the ASN1 tag for GeneralizedTime (24), but the value of tVal only uses 2 digits for the year because it's actually being encoded as UTCTime.
Despite me telling the package that I want to use GeneralizedTime, I have to explicitly tell it with a second parameter:
t := time.Date(2023, 12, 28, 16, 49, 55, 00, time.UTC)
tVal, err := asn1.MarshalWithParams(t, "tag:24,generalized")
if err != nil {
panic(err)
}
// tVal = 18 0f 32 30 32 33 31 32 32 38 31 36 34 39 35 35 5a (..20231228164955Z)
Go playground: https://go.dev/play/p/WSxtB5cOMaQ
What did you expect to see?
I expected the asn1 package to encode the time using GeneralizedTime as I had specified using the ASN1 tag value. I also expected that the default encoding would be the Y2K-compliant GeneralizedTime. Perhaps a separate discussion is needed as to if this should be changed going forward.
What did you see instead?
A confusion between a ASN1 field that is tagged as GeneralizedTime but actually has a UTCTime value.