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