...
Run Format

Source file src/encoding/asn1/asn1_test.go

Documentation: encoding/asn1

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

View as plain text