summaryrefslogtreecommitdiff
path: root/src/encoding
diff options
context:
space:
mode:
authorAdam Langley <agl@golang.org>2014-10-09 17:37:40 -0700
committerAdam Langley <agl@golang.org>2014-10-09 17:37:40 -0700
commit8c13bc63d348c5a6ad2188786594cd1bd9e772e5 (patch)
tree287cb6ab2c44efdec53352cf0333cbc85314749a /src/encoding
parent0fab6a60e66dd7b90ca0ff2e22ab9ee225a5a4e2 (diff)
downloadgo-8c13bc63d348c5a6ad2188786594cd1bd9e772e5.tar.gz
encoding/asn1: fix explicitly tagged Times.
https://codereview.appspot.com/153770043/ tried to fix the case where a implicitly tagged Time, that happened to have the same tag as GENERALIZEDTIME, shouldn't be parsed as a GENERALIZEDTIME. It did so, mistakenly, by testing whether params.tag != nil. But explicitly tagged values also have a non-nil tag and there the inner tag actually does encode the type of the value. This change instead tests whether the tag class is UNIVERSAL before assuming that the tag contains type information. LGTM=iant R=iant CC=golang-codereviews https://codereview.appspot.com/152380044
Diffstat (limited to 'src/encoding')
-rw-r--r--src/encoding/asn1/asn1.go4
-rw-r--r--src/encoding/asn1/asn1_test.go48
2 files changed, 50 insertions, 2 deletions
diff --git a/src/encoding/asn1/asn1.go b/src/encoding/asn1/asn1.go
index 3aeb3dcc4..8b3d1b341 100644
--- a/src/encoding/asn1/asn1.go
+++ b/src/encoding/asn1/asn1.go
@@ -640,7 +640,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
// when it sees a string, so if we see a different string type on the
// wire, we change the universal type to match.
if universalTag == tagPrintableString {
- if params.tag == nil {
+ if t.class == classUniversal {
switch t.tag {
case tagIA5String, tagGeneralString, tagT61String, tagUTF8String:
universalTag = t.tag
@@ -652,7 +652,7 @@ func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParam
// Special case for time: UTCTime and GeneralizedTime both map to the
// Go type time.Time.
- if universalTag == tagUTCTime && params.tag == nil && t.tag == tagGeneralizedTime {
+ if universalTag == tagUTCTime && t.tag == tagGeneralizedTime && t.class == classUniversal {
universalTag = tagGeneralizedTime
}
diff --git a/src/encoding/asn1/asn1_test.go b/src/encoding/asn1/asn1_test.go
index b94d59d36..4e864d08a 100644
--- a/src/encoding/asn1/asn1_test.go
+++ b/src/encoding/asn1/asn1_test.go
@@ -817,3 +817,51 @@ func TestStringSlice(t *testing.T) {
}
}
}
+
+type explicitTaggedTimeTest struct {
+ Time time.Time `asn1:"explicit,tag:0"`
+}
+
+var explicitTaggedTimeTestData = []struct {
+ in []byte
+ out explicitTaggedTimeTest
+}{
+ {[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
+ explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
+ {[]byte{0x30, 0x17, 0xa0, 0xf, 0x18, 0x13, '2', '0', '1', '0', '0', '1', '0', '2', '0', '3', '0', '4', '0', '5', '+', '0', '6', '0', '7'},
+ explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
+}
+
+func TestExplicitTaggedTime(t *testing.T) {
+ // Test that a time.Time will match either tagUTCTime or
+ // tagGeneralizedTime.
+ for i, test := range explicitTaggedTimeTestData {
+ var got explicitTaggedTimeTest
+ _, err := Unmarshal(test.in, &got)
+ if err != nil {
+ t.Errorf("Unmarshal failed at index %d %v", i, err)
+ }
+ if !got.Time.Equal(test.out.Time) {
+ t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
+ }
+ }
+}
+
+type implicitTaggedTimeTest struct {
+ Time time.Time `asn1:"tag:24"`
+}
+
+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)
+ }
+}