apc-p15-tool/pkg/tools/asn1obj/generalizedtime.go

86 lines
1.9 KiB
Go
Raw Permalink Normal View History

package asn1obj
import (
"encoding/asn1"
"time"
)
// GeneralizedTime returns the specified time as a GeneralizedTime
func GeneralizedTime(t time.Time) []byte {
// should never error
asn1result, err := asn1.MarshalWithParams(t, "generalized")
if err != nil {
panic(err)
}
return asn1result
}
// helper funcs from golang asn1 package
func appendTwoDigits(dst []byte, v int) []byte {
return append(dst, byte('0'+(v/10)%10), byte('0'+v%10))
}
func appendFourDigits(dst []byte, v int) []byte {
var bytes [4]byte
for i := range bytes {
bytes[3-i] = '0' + byte(v%10)
v /= 10
}
return append(dst, bytes[:]...)
}
// generalizedTimevalue returns the specified time encoded as a
// GeneralizedTime but WITHOUT the ASN.1 headers (class/tag/length)
func generalizedTimevalue(t time.Time) []byte {
dst := []byte{}
year := t.Year()
if year < 0 || year > 9999 {
panic("cannot represent time as GeneralizedTime (invalid year)")
}
dst = appendFourDigits(dst, year)
_, month, day := t.Date()
dst = appendTwoDigits(dst, int(month))
dst = appendTwoDigits(dst, day)
hour, min, sec := t.Clock()
dst = appendTwoDigits(dst, hour)
dst = appendTwoDigits(dst, min)
dst = appendTwoDigits(dst, sec)
_, offset := t.Zone()
switch {
case offset/60 == 0:
return append(dst, 'Z')
case offset > 0:
dst = append(dst, '+')
case offset < 0:
dst = append(dst, '-')
}
offsetMinutes := offset / 60
if offsetMinutes < 0 {
offsetMinutes = -offsetMinutes
}
dst = appendTwoDigits(dst, offsetMinutes/60)
dst = appendTwoDigits(dst, offsetMinutes%60)
return dst
}
// helper funcs from golang asn1 package - END
// GeneralizedTimeExplicitValue returns t encoded as a GeneralizedTime, however
// instead of tagging it with GeneralizedTime it is instead tagged with an
// explicit tag of the specified tag number
func GeneralizedTimeExplicitValue(explicitTagNumber int, t time.Time) []byte {
return ExplicitValue(explicitTagNumber, generalizedTimevalue(t))
}