bosun.org@v0.0.0-20210513094433-e25bc3e69a1f/snmp/asn1/asn1_test.go (about)

     1  // Copyright 2009 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package asn1
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"math/big"
    11  	"reflect"
    12  	"strings"
    13  	"testing"
    14  	"time"
    15  )
    16  
    17  type boolTest struct {
    18  	in  []byte
    19  	ok  bool
    20  	out bool
    21  }
    22  
    23  var boolTestData = []boolTest{
    24  	{[]byte{0x00}, true, false},
    25  	{[]byte{0xff}, true, true},
    26  	{[]byte{0x00, 0x00}, false, false},
    27  	{[]byte{0xff, 0xff}, false, false},
    28  	{[]byte{0x01}, false, false},
    29  }
    30  
    31  func TestParseBool(t *testing.T) {
    32  	for i, test := range boolTestData {
    33  		ret, err := parseBool(test.in)
    34  		if (err == nil) != test.ok {
    35  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    36  		}
    37  		if test.ok && ret != test.out {
    38  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
    39  		}
    40  	}
    41  }
    42  
    43  type int64Test struct {
    44  	in  []byte
    45  	ok  bool
    46  	out int64
    47  }
    48  
    49  var int64TestData = []int64Test{
    50  	{[]byte{0x00}, true, 0},
    51  	{[]byte{0x7f}, true, 127},
    52  	{[]byte{0x00, 0x80}, true, 128},
    53  	{[]byte{0x01, 0x00}, true, 256},
    54  	{[]byte{0x80}, true, -128},
    55  	{[]byte{0xff, 0x7f}, true, -129},
    56  	{[]byte{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}, true, -1},
    57  	{[]byte{0xff}, true, -1},
    58  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, true, -9223372036854775808},
    59  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, false, 0},
    60  }
    61  
    62  func TestParseInt64(t *testing.T) {
    63  	for i, test := range int64TestData {
    64  		ret, err := parseInt64(test.in)
    65  		if (err == nil) != test.ok {
    66  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    67  		}
    68  		if test.ok && ret != test.out {
    69  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
    70  		}
    71  	}
    72  }
    73  
    74  type int32Test struct {
    75  	in  []byte
    76  	ok  bool
    77  	out int32
    78  }
    79  
    80  var int32TestData = []int32Test{
    81  	{[]byte{0x00}, true, 0},
    82  	{[]byte{0x7f}, true, 127},
    83  	{[]byte{0x00, 0x80}, true, 128},
    84  	{[]byte{0x01, 0x00}, true, 256},
    85  	{[]byte{0x80}, true, -128},
    86  	{[]byte{0xff, 0x7f}, true, -129},
    87  	{[]byte{0xff, 0xff, 0xff, 0xff}, true, -1},
    88  	{[]byte{0xff}, true, -1},
    89  	{[]byte{0x80, 0x00, 0x00, 0x00}, true, -2147483648},
    90  	{[]byte{0x80, 0x00, 0x00, 0x00, 0x00}, false, 0},
    91  }
    92  
    93  func TestParseInt32(t *testing.T) {
    94  	for i, test := range int32TestData {
    95  		ret, err := parseInt32(test.in)
    96  		if (err == nil) != test.ok {
    97  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
    98  		}
    99  		if test.ok && int32(ret) != test.out {
   100  			t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   101  		}
   102  	}
   103  }
   104  
   105  var bigIntTests = []struct {
   106  	in     []byte
   107  	base10 string
   108  }{
   109  	{[]byte{0xff}, "-1"},
   110  	{[]byte{0x00}, "0"},
   111  	{[]byte{0x01}, "1"},
   112  	{[]byte{0x00, 0xff}, "255"},
   113  	{[]byte{0xff, 0x00}, "-256"},
   114  	{[]byte{0x01, 0x00}, "256"},
   115  }
   116  
   117  func TestParseBigInt(t *testing.T) {
   118  	for i, test := range bigIntTests {
   119  		ret := parseBigInt(test.in)
   120  		if ret.String() != test.base10 {
   121  			t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
   122  		}
   123  		fw := newForkableWriter()
   124  		marshalBigInt(fw, ret)
   125  		result := fw.Bytes()
   126  		if !bytes.Equal(result, test.in) {
   127  			t.Errorf("#%d: got %x from marshaling %s, want %x", i, result, ret, test.in)
   128  		}
   129  	}
   130  }
   131  
   132  type bitStringTest struct {
   133  	in        []byte
   134  	ok        bool
   135  	out       []byte
   136  	bitLength int
   137  }
   138  
   139  var bitStringTestData = []bitStringTest{
   140  	{[]byte{}, false, []byte{}, 0},
   141  	{[]byte{0x00}, true, []byte{}, 0},
   142  	{[]byte{0x07, 0x00}, true, []byte{0x00}, 1},
   143  	{[]byte{0x07, 0x01}, false, []byte{}, 0},
   144  	{[]byte{0x07, 0x40}, false, []byte{}, 0},
   145  	{[]byte{0x08, 0x00}, false, []byte{}, 0},
   146  }
   147  
   148  func TestBitString(t *testing.T) {
   149  	for i, test := range bitStringTestData {
   150  		ret, err := parseBitString(test.in)
   151  		if (err == nil) != test.ok {
   152  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   153  		}
   154  		if err == nil {
   155  			if test.bitLength != ret.BitLength || !bytes.Equal(ret.Bytes, test.out) {
   156  				t.Errorf("#%d: Bad result: %v (expected %v %v)", i, ret, test.out, test.bitLength)
   157  			}
   158  		}
   159  	}
   160  }
   161  
   162  func TestBitStringAt(t *testing.T) {
   163  	bs := BitString{[]byte{0x82, 0x40}, 16}
   164  	if bs.At(0) != 1 {
   165  		t.Error("#1: Failed")
   166  	}
   167  	if bs.At(1) != 0 {
   168  		t.Error("#2: Failed")
   169  	}
   170  	if bs.At(6) != 1 {
   171  		t.Error("#3: Failed")
   172  	}
   173  	if bs.At(9) != 1 {
   174  		t.Error("#4: Failed")
   175  	}
   176  	if bs.At(-1) != 0 {
   177  		t.Error("#5: Failed")
   178  	}
   179  	if bs.At(17) != 0 {
   180  		t.Error("#6: Failed")
   181  	}
   182  }
   183  
   184  type bitStringRightAlignTest struct {
   185  	in    []byte
   186  	inlen int
   187  	out   []byte
   188  }
   189  
   190  var bitStringRightAlignTests = []bitStringRightAlignTest{
   191  	{[]byte{0x80}, 1, []byte{0x01}},
   192  	{[]byte{0x80, 0x80}, 9, []byte{0x01, 0x01}},
   193  	{[]byte{}, 0, []byte{}},
   194  	{[]byte{0xce}, 8, []byte{0xce}},
   195  	{[]byte{0xce, 0x47}, 16, []byte{0xce, 0x47}},
   196  	{[]byte{0x34, 0x50}, 12, []byte{0x03, 0x45}},
   197  }
   198  
   199  func TestBitStringRightAlign(t *testing.T) {
   200  	for i, test := range bitStringRightAlignTests {
   201  		bs := BitString{test.in, test.inlen}
   202  		out := bs.RightAlign()
   203  		if !bytes.Equal(out, test.out) {
   204  			t.Errorf("#%d got: %x want: %x", i, out, test.out)
   205  		}
   206  	}
   207  }
   208  
   209  type objectIdentifierTest struct {
   210  	in  []byte
   211  	ok  bool
   212  	out []int
   213  }
   214  
   215  var objectIdentifierTestData = []objectIdentifierTest{
   216  	{[]byte{}, false, []int{}},
   217  	{[]byte{85}, true, []int{2, 5}},
   218  	{[]byte{85, 0x02}, true, []int{2, 5, 2}},
   219  	{[]byte{85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
   220  	{[]byte{0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
   221  	{[]byte{85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
   222  }
   223  
   224  func TestObjectIdentifier(t *testing.T) {
   225  	for i, test := range objectIdentifierTestData {
   226  		ret, err := parseObjectIdentifier(test.in)
   227  		if (err == nil) != test.ok {
   228  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   229  		}
   230  		if err == nil {
   231  			if !reflect.DeepEqual(test.out, ret) {
   232  				t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
   233  			}
   234  		}
   235  	}
   236  
   237  	if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
   238  		t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
   239  	}
   240  }
   241  
   242  type timeTest struct {
   243  	in  string
   244  	ok  bool
   245  	out time.Time
   246  }
   247  
   248  var utcTestData = []timeTest{
   249  	{"910506164540-0700", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", -7*60*60))},
   250  	{"910506164540+0730", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", 7*60*60+30*60))},
   251  	{"910506234540Z", true, time.Date(1991, 05, 06, 23, 45, 40, 0, time.UTC)},
   252  	{"9105062345Z", true, time.Date(1991, 05, 06, 23, 45, 0, 0, time.UTC)},
   253  	{"5105062345Z", true, time.Date(1951, 05, 06, 23, 45, 0, 0, time.UTC)},
   254  	{"a10506234540Z", false, time.Time{}},
   255  	{"91a506234540Z", false, time.Time{}},
   256  	{"9105a6234540Z", false, time.Time{}},
   257  	{"910506a34540Z", false, time.Time{}},
   258  	{"910506334a40Z", false, time.Time{}},
   259  	{"91050633444aZ", false, time.Time{}},
   260  	{"910506334461Z", false, time.Time{}},
   261  	{"910506334400Za", false, time.Time{}},
   262  	/* These are invalid times. However, the time package normalises times
   263  	 * and they were accepted in some versions. See #11134. */
   264  	{"000100000000Z", false, time.Time{}},
   265  	{"101302030405Z", false, time.Time{}},
   266  	{"100002030405Z", false, time.Time{}},
   267  	{"100100030405Z", false, time.Time{}},
   268  	{"100132030405Z", false, time.Time{}},
   269  	{"100231030405Z", false, time.Time{}},
   270  	{"100102240405Z", false, time.Time{}},
   271  	{"100102036005Z", false, time.Time{}},
   272  	{"100102030460Z", false, time.Time{}},
   273  	{"-100102030410Z", false, time.Time{}},
   274  	{"10-0102030410Z", false, time.Time{}},
   275  	{"10-0002030410Z", false, time.Time{}},
   276  	{"1001-02030410Z", false, time.Time{}},
   277  	{"100102-030410Z", false, time.Time{}},
   278  	{"10010203-0410Z", false, time.Time{}},
   279  	{"1001020304-10Z", false, time.Time{}},
   280  }
   281  
   282  func TestUTCTime(t *testing.T) {
   283  	for i, test := range utcTestData {
   284  		ret, err := parseUTCTime([]byte(test.in))
   285  		if err != nil {
   286  			if test.ok {
   287  				t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
   288  			}
   289  			continue
   290  		}
   291  		if !test.ok {
   292  			t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
   293  			continue
   294  		}
   295  		const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
   296  		have := ret.Format(format)
   297  		want := test.out.Format(format)
   298  		if have != want {
   299  			t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
   300  		}
   301  	}
   302  }
   303  
   304  var generalizedTimeTestData = []timeTest{
   305  	{"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
   306  	{"20100102030405", false, time.Time{}},
   307  	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
   308  	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
   309  	/* These are invalid times. However, the time package normalises times
   310  	 * and they were accepted in some versions. See #11134. */
   311  	{"00000100000000Z", false, time.Time{}},
   312  	{"20101302030405Z", false, time.Time{}},
   313  	{"20100002030405Z", false, time.Time{}},
   314  	{"20100100030405Z", false, time.Time{}},
   315  	{"20100132030405Z", false, time.Time{}},
   316  	{"20100231030405Z", false, time.Time{}},
   317  	{"20100102240405Z", false, time.Time{}},
   318  	{"20100102036005Z", false, time.Time{}},
   319  	{"20100102030460Z", false, time.Time{}},
   320  	{"-20100102030410Z", false, time.Time{}},
   321  	{"2010-0102030410Z", false, time.Time{}},
   322  	{"2010-0002030410Z", false, time.Time{}},
   323  	{"201001-02030410Z", false, time.Time{}},
   324  	{"20100102-030410Z", false, time.Time{}},
   325  	{"2010010203-0410Z", false, time.Time{}},
   326  	{"201001020304-10Z", false, time.Time{}},
   327  }
   328  
   329  func TestGeneralizedTime(t *testing.T) {
   330  	for i, test := range generalizedTimeTestData {
   331  		ret, err := parseGeneralizedTime([]byte(test.in))
   332  		if (err == nil) != test.ok {
   333  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   334  		}
   335  		if err == nil {
   336  			if !reflect.DeepEqual(test.out, ret) {
   337  				t.Errorf("#%d: Bad result: %q → %v (expected %v)", i, test.in, ret, test.out)
   338  			}
   339  		}
   340  	}
   341  }
   342  
   343  type tagAndLengthTest struct {
   344  	in  []byte
   345  	ok  bool
   346  	out tagAndLength
   347  }
   348  
   349  var tagAndLengthData = []tagAndLengthTest{
   350  	{[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
   351  	{[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
   352  	{[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
   353  	{[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
   354  	{[]byte{0x1f, 0x01, 0x00}, true, tagAndLength{0, 1, 0, false}},
   355  	{[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
   356  	{[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
   357  	{[]byte{0x00, 0x81, 0x01}, true, tagAndLength{0, 0, 1, false}},
   358  	{[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
   359  	{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
   360  	{[]byte{0x1f, 0x85}, false, tagAndLength{}},
   361  	{[]byte{0x30, 0x80}, false, tagAndLength{}},
   362  	// Superfluous zeros in the length are technically invalid, but are still parsable.
   363  	{[]byte{0x00, 0x82, 0x00, 0x01}, true, tagAndLength{0, 0, 1, false}},
   364  	// Zero length should be an error
   365  	{[]byte{0xa0, 0x82, 0x00, 0x00}, false, tagAndLength{}},
   366  	// Lengths up to the maximum size of an int should work.
   367  	{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
   368  	// Lengths that would overflow an int should be rejected.
   369  	{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
   370  }
   371  
   372  func TestParseTagAndLength(t *testing.T) {
   373  	for i, test := range tagAndLengthData {
   374  		tagAndLength, _, err := parseTagAndLength(test.in, 0)
   375  		if (err == nil) != test.ok {
   376  			t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
   377  		}
   378  		if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
   379  			t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
   380  		}
   381  	}
   382  }
   383  
   384  type parseFieldParametersTest struct {
   385  	in  string
   386  	out fieldParameters
   387  }
   388  
   389  func newInt(n int) *int { return &n }
   390  
   391  func newInt64(n int64) *int64 { return &n }
   392  
   393  func newString(s string) *string { return &s }
   394  
   395  func newBool(b bool) *bool { return &b }
   396  
   397  var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
   398  	{"", fieldParameters{}},
   399  	{"ia5", fieldParameters{stringType: tagIA5String}},
   400  	{"generalized", fieldParameters{timeType: tagGeneralizedTime}},
   401  	{"utc", fieldParameters{timeType: tagUTCTime}},
   402  	{"printable", fieldParameters{stringType: tagPrintableString}},
   403  	{"optional", fieldParameters{optional: true}},
   404  	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
   405  	{"application", fieldParameters{application: true, tag: new(int)}},
   406  	{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
   407  	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
   408  	{"tag:17", fieldParameters{tag: newInt(17)}},
   409  	{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
   410  	{"optional,explicit,default:42,tag:17,rubbish1", fieldParameters{true, true, false, newInt64(42), newInt(17), 0, 0, false, false}},
   411  	{"set", fieldParameters{set: true}},
   412  }
   413  
   414  func TestParseFieldParameters(t *testing.T) {
   415  	for i, test := range parseFieldParametersTestData {
   416  		f := parseFieldParameters(test.in)
   417  		if !reflect.DeepEqual(f, test.out) {
   418  			t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
   419  		}
   420  	}
   421  }
   422  
   423  type TestObjectIdentifierStruct struct {
   424  	OID ObjectIdentifier
   425  }
   426  
   427  type TestContextSpecificTags struct {
   428  	A int `asn1:"tag:1"`
   429  }
   430  
   431  type TestContextSpecificTags2 struct {
   432  	A int `asn1:"explicit,tag:1"`
   433  	B int
   434  }
   435  
   436  type TestContextSpecificTags3 struct {
   437  	S string `asn1:"tag:1,utf8"`
   438  }
   439  
   440  type TestElementsAfterString struct {
   441  	S    string
   442  	A, B int
   443  }
   444  
   445  type TestBigInt struct {
   446  	X *big.Int
   447  }
   448  
   449  type TestSet struct {
   450  	Ints []int `asn1:"set"`
   451  }
   452  
   453  var unmarshalTestData = []struct {
   454  	in  []byte
   455  	out interface{}
   456  }{
   457  	{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
   458  	{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
   459  	{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
   460  	{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
   461  	{[]byte{0x02, 0x01, 0x10}, newInt(16)},
   462  	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
   463  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
   464  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
   465  	{[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
   466  	{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
   467  	{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
   468  	{[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}},
   469  	{[]byte{0x01, 0x01, 0x00}, newBool(false)},
   470  	{[]byte{0x01, 0x01, 0xff}, newBool(true)},
   471  	{[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
   472  	{[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
   473  	{[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
   474  }
   475  
   476  func TestUnmarshal(t *testing.T) {
   477  	for i, test := range unmarshalTestData {
   478  		pv := reflect.New(reflect.TypeOf(test.out).Elem())
   479  		val := pv.Interface()
   480  		_, err := Unmarshal(test.in, val)
   481  		if err != nil {
   482  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   483  		}
   484  		if !reflect.DeepEqual(val, test.out) {
   485  			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
   486  		}
   487  	}
   488  }
   489  
   490  type Certificate struct {
   491  	TBSCertificate     TBSCertificate
   492  	SignatureAlgorithm AlgorithmIdentifier
   493  	SignatureValue     BitString
   494  }
   495  
   496  type TBSCertificate struct {
   497  	Version            int `asn1:"optional,explicit,default:0,tag:0"`
   498  	SerialNumber       RawValue
   499  	SignatureAlgorithm AlgorithmIdentifier
   500  	Issuer             RDNSequence
   501  	Validity           Validity
   502  	Subject            RDNSequence
   503  	PublicKey          PublicKeyInfo
   504  }
   505  
   506  type AlgorithmIdentifier struct {
   507  	Algorithm ObjectIdentifier
   508  }
   509  
   510  type RDNSequence []RelativeDistinguishedNameSET
   511  
   512  type RelativeDistinguishedNameSET []AttributeTypeAndValue
   513  
   514  type AttributeTypeAndValue struct {
   515  	Type  ObjectIdentifier
   516  	Value interface{}
   517  }
   518  
   519  type Validity struct {
   520  	NotBefore, NotAfter time.Time
   521  }
   522  
   523  type PublicKeyInfo struct {
   524  	Algorithm AlgorithmIdentifier
   525  	PublicKey BitString
   526  }
   527  
   528  func TestCertificate(t *testing.T) {
   529  	// This is a minimal, self-signed certificate that should parse correctly.
   530  	var cert Certificate
   531  	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
   532  		t.Errorf("Unmarshal failed: %v", err)
   533  	}
   534  	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
   535  		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
   536  	}
   537  }
   538  
   539  func TestCertificateWithNUL(t *testing.T) {
   540  	// This is the paypal NUL-hack certificate. It should fail to parse because
   541  	// NUL isn't a permitted character in a PrintableString.
   542  
   543  	var cert Certificate
   544  	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
   545  		t.Error("Unmarshal succeeded, should not have")
   546  	}
   547  }
   548  
   549  type rawStructTest struct {
   550  	Raw RawContent
   551  	A   int
   552  }
   553  
   554  func TestRawStructs(t *testing.T) {
   555  	var s rawStructTest
   556  	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
   557  
   558  	rest, err := Unmarshal(input, &s)
   559  	if len(rest) != 0 {
   560  		t.Errorf("incomplete parse: %x", rest)
   561  		return
   562  	}
   563  	if err != nil {
   564  		t.Error(err)
   565  		return
   566  	}
   567  	if s.A != 0x50 {
   568  		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
   569  	}
   570  	if !bytes.Equal([]byte(s.Raw), input) {
   571  		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
   572  	}
   573  }
   574  
   575  type oiEqualTest struct {
   576  	first  ObjectIdentifier
   577  	second ObjectIdentifier
   578  	same   bool
   579  }
   580  
   581  var oiEqualTests = []oiEqualTest{
   582  	{
   583  		ObjectIdentifier{1, 2, 3},
   584  		ObjectIdentifier{1, 2, 3},
   585  		true,
   586  	},
   587  	{
   588  		ObjectIdentifier{1},
   589  		ObjectIdentifier{1, 2, 3},
   590  		false,
   591  	},
   592  	{
   593  		ObjectIdentifier{1, 2, 3},
   594  		ObjectIdentifier{10, 11, 12},
   595  		false,
   596  	},
   597  }
   598  
   599  func TestObjectIdentifierEqual(t *testing.T) {
   600  	for _, o := range oiEqualTests {
   601  		if s := o.first.Equal(o.second); s != o.same {
   602  			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
   603  		}
   604  	}
   605  }
   606  
   607  var derEncodedSelfSignedCert = Certificate{
   608  	TBSCertificate: TBSCertificate{
   609  		Version:            0,
   610  		SerialNumber:       RawValue{Class: 0, Tag: 2, IsCompound: false, Bytes: []uint8{0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}, FullBytes: []byte{2, 9, 0x0, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 0x98}},
   611  		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   612  		Issuer: RDNSequence{
   613  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   614  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   615  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   616  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   617  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   618  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   619  		},
   620  		Validity: Validity{
   621  			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
   622  			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
   623  		},
   624  		Subject: RDNSequence{
   625  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   626  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   627  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   628  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   629  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   630  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   631  		},
   632  		PublicKey: PublicKeyInfo{
   633  			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
   634  			PublicKey: BitString{
   635  				Bytes: []uint8{
   636  					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
   637  					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
   638  					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
   639  					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
   640  					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
   641  					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
   642  					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
   643  				},
   644  				BitLength: 592,
   645  			},
   646  		},
   647  	},
   648  	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   649  	SignatureValue: BitString{
   650  		Bytes: []uint8{
   651  			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
   652  			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
   653  			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
   654  			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
   655  			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
   656  			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
   657  		},
   658  		BitLength: 512,
   659  	},
   660  }
   661  
   662  var derEncodedSelfSignedCertBytes = []byte{
   663  	0x30, 0x82, 0x02, 0x18, 0x30,
   664  	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
   665  	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
   666  	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   667  	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
   668  	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
   669  	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
   670  	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
   671  	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
   672  	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
   673  	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
   674  	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
   675  	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
   676  	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
   677  	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
   678  	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
   679  	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
   680  	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
   681  	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
   682  	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
   683  	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
   684  	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
   685  	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
   686  	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
   687  	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
   688  	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
   689  	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
   690  	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
   691  	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
   692  	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
   693  	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
   694  	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
   695  	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
   696  	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
   697  	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
   698  	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
   699  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
   700  	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
   701  	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
   702  	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
   703  	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
   704  	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
   705  	0x04, 0x35,
   706  }
   707  
   708  var derEncodedPaypalNULCertBytes = []byte{
   709  	0x30, 0x82, 0x06, 0x44, 0x30,
   710  	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
   711  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   712  	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   713  	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
   714  	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
   715  	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
   716  	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
   717  	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
   718  	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
   719  	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
   720  	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
   721  	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
   722  	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
   723  	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
   724  	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
   725  	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
   726  	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
   727  	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
   728  	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   729  	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
   730  	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
   731  	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
   732  	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
   733  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
   734  	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
   735  	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
   736  	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
   737  	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
   738  	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
   739  	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
   740  	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
   741  	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
   742  	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
   743  	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
   744  	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
   745  	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
   746  	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
   747  	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
   748  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
   749  	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
   750  	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
   751  	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
   752  	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
   753  	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
   754  	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
   755  	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
   756  	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
   757  	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
   758  	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
   759  	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
   760  	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
   761  	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
   762  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
   763  	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
   764  	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
   765  	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
   766  	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
   767  	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
   768  	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
   769  	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
   770  	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
   771  	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
   772  	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
   773  	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
   774  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
   775  	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
   776  	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
   777  	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
   778  	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
   779  	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
   780  	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
   781  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   782  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
   783  	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
   784  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   785  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   786  	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
   787  	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
   788  	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
   789  	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
   790  	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
   791  	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
   792  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
   793  	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
   794  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   795  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
   796  	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
   797  	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
   798  	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
   799  	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
   800  	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
   801  	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   802  	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
   803  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
   804  	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
   805  	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
   806  	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
   807  	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
   808  	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
   809  	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
   810  	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
   811  	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   812  	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
   813  	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
   814  	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
   815  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   816  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
   817  	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
   818  	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
   819  	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
   820  	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
   821  	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
   822  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   823  	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
   824  	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
   825  	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
   826  	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
   827  	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
   828  	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
   829  	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
   830  	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
   831  	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
   832  	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
   833  	0x96, 0x07, 0xa8, 0xbb,
   834  }
   835  
   836  var stringSliceTestData = [][]string{
   837  	{"foo", "bar"},
   838  	{"foo", "\\bar"},
   839  	{"foo", "\"bar\""},
   840  	{"foo", "åäö"},
   841  }
   842  
   843  func TestStringSlice(t *testing.T) {
   844  	for _, test := range stringSliceTestData {
   845  		bs, err := Marshal(test)
   846  		if err != nil {
   847  			t.Error(err)
   848  		}
   849  
   850  		var res []string
   851  		_, err = Unmarshal(bs, &res)
   852  		if err != nil {
   853  			t.Error(err)
   854  		}
   855  
   856  		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
   857  			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
   858  		}
   859  	}
   860  }
   861  
   862  type explicitTaggedTimeTest struct {
   863  	Time time.Time `asn1:"explicit,tag:0"`
   864  }
   865  
   866  var explicitTaggedTimeTestData = []struct {
   867  	in  []byte
   868  	out explicitTaggedTimeTest
   869  }{
   870  	{[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
   871  		explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
   872  	{[]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'},
   873  		explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
   874  }
   875  
   876  func TestExplicitTaggedTime(t *testing.T) {
   877  	// Test that a time.Time will match either tagUTCTime or
   878  	// tagGeneralizedTime.
   879  	for i, test := range explicitTaggedTimeTestData {
   880  		var got explicitTaggedTimeTest
   881  		_, err := Unmarshal(test.in, &got)
   882  		if err != nil {
   883  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   884  		}
   885  		if !got.Time.Equal(test.out.Time) {
   886  			t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
   887  		}
   888  	}
   889  }
   890  
   891  type implicitTaggedTimeTest struct {
   892  	Time time.Time `asn1:"tag:24"`
   893  }
   894  
   895  func TestImplicitTaggedTime(t *testing.T) {
   896  	// An implicitly tagged time value, that happens to have an implicit
   897  	// tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
   898  	// (There's no "timeType" in fieldParameters to determine what type of
   899  	// time should be expected when implicitly tagged.)
   900  	der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
   901  	var result implicitTaggedTimeTest
   902  	if _, err := Unmarshal(der, &result); err != nil {
   903  		t.Fatalf("Error while parsing: %s", err)
   904  	}
   905  	if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
   906  		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
   907  	}
   908  }
   909  
   910  type truncatedExplicitTagTest struct {
   911  	Test int `asn1:"explicit,tag:0"`
   912  }
   913  
   914  func TestTruncatedExplicitTag(t *testing.T) {
   915  	// This crashed Unmarshal in the past. See #11154.
   916  	der := []byte{
   917  		0x30, // SEQUENCE
   918  		0x02, // two bytes long
   919  		0xa0, // context-specific, tag 0
   920  		0x30, // 48 bytes long
   921  	}
   922  
   923  	var result truncatedExplicitTagTest
   924  	if _, err := Unmarshal(der, &result); err == nil {
   925  		t.Error("Unmarshal returned without error")
   926  	}
   927  }
   928  
   929  type invalidUTF8Test struct {
   930  	Str string `asn1:"utf8"`
   931  }
   932  
   933  func TestUnmarshalInvalidUTF8(t *testing.T) {
   934  	data := []byte("0\x05\f\x03a\xc9c")
   935  	var result invalidUTF8Test
   936  	_, err := Unmarshal(data, &result)
   937  
   938  	const expectedSubstring = "UTF"
   939  	if err == nil {
   940  		t.Fatal("Successfully unmarshaled invalid UTF-8 data")
   941  	} else if !strings.Contains(err.Error(), expectedSubstring) {
   942  		t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
   943  	}
   944  }