Source file src/encoding/asn1/asn1_test.go

     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 && 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.123456Z", true, time.Date(2010, 01, 02, 03, 04, 05, 123456e3, time.UTC)},
   327  	{"20100102030405.123456", false, time.Time{}},
   328  	{"20100102030405.Z", false, time.Time{}},
   329  	{"20100102030405.", false, time.Time{}},
   330  	{"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
   331  	{"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
   332  	/* These are invalid times. However, the time package normalises times
   333  	 * and they were accepted in some versions. See #11134. */
   334  	{"00000100000000Z", false, time.Time{}},
   335  	{"20101302030405Z", false, time.Time{}},
   336  	{"20100002030405Z", false, time.Time{}},
   337  	{"20100100030405Z", false, time.Time{}},
   338  	{"20100132030405Z", false, time.Time{}},
   339  	{"20100231030405Z", false, time.Time{}},
   340  	{"20100102240405Z", false, time.Time{}},
   341  	{"20100102036005Z", false, time.Time{}},
   342  	{"20100102030460Z", false, time.Time{}},
   343  	{"-20100102030410Z", false, time.Time{}},
   344  	{"2010-0102030410Z", false, time.Time{}},
   345  	{"2010-0002030410Z", false, time.Time{}},
   346  	{"201001-02030410Z", false, time.Time{}},
   347  	{"20100102-030410Z", false, time.Time{}},
   348  	{"2010010203-0410Z", false, time.Time{}},
   349  	{"201001020304-10Z", false, time.Time{}},
   350  }
   351  
   352  func TestGeneralizedTime(t *testing.T) {
   353  	for i, test := range generalizedTimeTestData {
   354  		ret, err := parseGeneralizedTime([]byte(test.in))
   355  		if (err == nil) != test.ok {
   356  			t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
   357  		}
   358  		if err == nil {
   359  			if !reflect.DeepEqual(test.out, ret) {
   360  				t.Errorf("#%d: Bad result: %q → %v (expected %v)", i, test.in, ret, test.out)
   361  			}
   362  		}
   363  	}
   364  }
   365  
   366  type tagAndLengthTest struct {
   367  	in  []byte
   368  	ok  bool
   369  	out tagAndLength
   370  }
   371  
   372  var tagAndLengthData = []tagAndLengthTest{
   373  	{[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
   374  	{[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
   375  	{[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
   376  	{[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
   377  	{[]byte{0x1f, 0x1f, 0x00}, true, tagAndLength{0, 31, 0, false}},
   378  	{[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
   379  	{[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
   380  	{[]byte{0x00, 0x81, 0x80}, true, tagAndLength{0, 0, 128, false}},
   381  	{[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
   382  	{[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
   383  	{[]byte{0x1f, 0x85}, false, tagAndLength{}},
   384  	{[]byte{0x30, 0x80}, false, tagAndLength{}},
   385  	// Superfluous zeros in the length should be an error.
   386  	{[]byte{0xa0, 0x82, 0x00, 0xff}, false, tagAndLength{}},
   387  	// Lengths up to the maximum size of an int should work.
   388  	{[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
   389  	// Lengths that would overflow an int should be rejected.
   390  	{[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
   391  	// Long length form may not be used for lengths that fit in short form.
   392  	{[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}},
   393  	// Tag numbers which would overflow int32 are rejected. (The value below is 2^31.)
   394  	{[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}},
   395  	// Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.)
   396  	{[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}},
   397  	// Long tag number form may not be used for tags that fit in short form.
   398  	{[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}},
   399  }
   400  
   401  func TestParseTagAndLength(t *testing.T) {
   402  	for i, test := range tagAndLengthData {
   403  		tagAndLength, _, err := parseTagAndLength(test.in, 0)
   404  		if (err == nil) != test.ok {
   405  			t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
   406  		}
   407  		if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
   408  			t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
   409  		}
   410  	}
   411  }
   412  
   413  type parseFieldParametersTest struct {
   414  	in  string
   415  	out fieldParameters
   416  }
   417  
   418  func newInt(n int) *int { return &n }
   419  
   420  func newInt64(n int64) *int64 { return &n }
   421  
   422  func newString(s string) *string { return &s }
   423  
   424  func newBool(b bool) *bool { return &b }
   425  
   426  var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
   427  	{"", fieldParameters{}},
   428  	{"ia5", fieldParameters{stringType: TagIA5String}},
   429  	{"generalized", fieldParameters{timeType: TagGeneralizedTime}},
   430  	{"utc", fieldParameters{timeType: TagUTCTime}},
   431  	{"printable", fieldParameters{stringType: TagPrintableString}},
   432  	{"numeric", fieldParameters{stringType: TagNumericString}},
   433  	{"optional", fieldParameters{optional: true}},
   434  	{"explicit", fieldParameters{explicit: true, tag: new(int)}},
   435  	{"application", fieldParameters{application: true, tag: new(int)}},
   436  	{"private", fieldParameters{private: true, tag: new(int)}},
   437  	{"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
   438  	{"default:42", fieldParameters{defaultValue: newInt64(42)}},
   439  	{"tag:17", fieldParameters{tag: newInt(17)}},
   440  	{"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
   441  	{"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}},
   442  	{"set", fieldParameters{set: true}},
   443  }
   444  
   445  func TestParseFieldParameters(t *testing.T) {
   446  	for i, test := range parseFieldParametersTestData {
   447  		f := parseFieldParameters(test.in)
   448  		if !reflect.DeepEqual(f, test.out) {
   449  			t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
   450  		}
   451  	}
   452  }
   453  
   454  type TestObjectIdentifierStruct struct {
   455  	OID ObjectIdentifier
   456  }
   457  
   458  type TestContextSpecificTags struct {
   459  	A int `asn1:"tag:1"`
   460  }
   461  
   462  type TestContextSpecificTags2 struct {
   463  	A int `asn1:"explicit,tag:1"`
   464  	B int
   465  }
   466  
   467  type TestContextSpecificTags3 struct {
   468  	S string `asn1:"tag:1,utf8"`
   469  }
   470  
   471  type TestElementsAfterString struct {
   472  	S    string
   473  	A, B int
   474  }
   475  
   476  type TestBigInt struct {
   477  	X *big.Int
   478  }
   479  
   480  type TestSet struct {
   481  	Ints []int `asn1:"set"`
   482  }
   483  
   484  var unmarshalTestData = []struct {
   485  	in  []byte
   486  	out any
   487  }{
   488  	{[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
   489  	{[]byte{0x05, 0x00}, &RawValue{0, 5, false, []byte{}, []byte{0x05, 0x00}}},
   490  	{[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
   491  	{[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
   492  	{[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
   493  	{[]byte{0x02, 0x01, 0x10}, newInt(16)},
   494  	{[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
   495  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
   496  	// Ampersand is allowed in PrintableString due to mistakes by major CAs.
   497  	{[]byte{0x13, 0x05, 't', 'e', 's', 't', '&'}, newString("test&")},
   498  	{[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
   499  	{[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
   500  	{[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
   501  	{[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
   502  	{[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}},
   503  	{[]byte{0x01, 0x01, 0x00}, newBool(false)},
   504  	{[]byte{0x01, 0x01, 0xff}, newBool(true)},
   505  	{[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
   506  	{[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
   507  	{[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
   508  	{[]byte{0x12, 0x0b, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' '}, newString("0123456789 ")},
   509  	{[]byte{0x14, 0x03, 0xbf, 0x61, 0x3f}, newString("¿a?")},
   510  }
   511  
   512  func TestUnmarshal(t *testing.T) {
   513  	for i, test := range unmarshalTestData {
   514  		pv := reflect.New(reflect.TypeOf(test.out).Elem())
   515  		val := pv.Interface()
   516  		_, err := Unmarshal(test.in, val)
   517  		if err != nil {
   518  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   519  		}
   520  		if !reflect.DeepEqual(val, test.out) {
   521  			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
   522  		}
   523  	}
   524  }
   525  
   526  func TestUnmarshalWithNilOrNonPointer(t *testing.T) {
   527  	tests := []struct {
   528  		b    []byte
   529  		v    any
   530  		want string
   531  	}{
   532  		{b: []byte{0x05, 0x00}, v: nil, want: "asn1: Unmarshal recipient value is nil"},
   533  		{b: []byte{0x05, 0x00}, v: RawValue{}, want: "asn1: Unmarshal recipient value is non-pointer asn1.RawValue"},
   534  		{b: []byte{0x05, 0x00}, v: (*RawValue)(nil), want: "asn1: Unmarshal recipient value is nil *asn1.RawValue"},
   535  	}
   536  
   537  	for _, test := range tests {
   538  		_, err := Unmarshal(test.b, test.v)
   539  		if err == nil {
   540  			t.Errorf("Unmarshal expecting error, got nil")
   541  			continue
   542  		}
   543  		if g, w := err.Error(), test.want; g != w {
   544  			t.Errorf("InvalidUnmarshalError mismatch\nGot:  %q\nWant: %q", g, w)
   545  		}
   546  	}
   547  }
   548  
   549  type Certificate struct {
   550  	TBSCertificate     TBSCertificate
   551  	SignatureAlgorithm AlgorithmIdentifier
   552  	SignatureValue     BitString
   553  }
   554  
   555  type TBSCertificate struct {
   556  	Version            int `asn1:"optional,explicit,default:0,tag:0"`
   557  	SerialNumber       RawValue
   558  	SignatureAlgorithm AlgorithmIdentifier
   559  	Issuer             RDNSequence
   560  	Validity           Validity
   561  	Subject            RDNSequence
   562  	PublicKey          PublicKeyInfo
   563  }
   564  
   565  type AlgorithmIdentifier struct {
   566  	Algorithm ObjectIdentifier
   567  }
   568  
   569  type RDNSequence []RelativeDistinguishedNameSET
   570  
   571  type RelativeDistinguishedNameSET []AttributeTypeAndValue
   572  
   573  type AttributeTypeAndValue struct {
   574  	Type  ObjectIdentifier
   575  	Value any
   576  }
   577  
   578  type Validity struct {
   579  	NotBefore, NotAfter time.Time
   580  }
   581  
   582  type PublicKeyInfo struct {
   583  	Algorithm AlgorithmIdentifier
   584  	PublicKey BitString
   585  }
   586  
   587  func TestCertificate(t *testing.T) {
   588  	// This is a minimal, self-signed certificate that should parse correctly.
   589  	var cert Certificate
   590  	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
   591  		t.Errorf("Unmarshal failed: %v", err)
   592  	}
   593  	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
   594  		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
   595  	}
   596  }
   597  
   598  func TestCertificateWithNUL(t *testing.T) {
   599  	// This is the paypal NUL-hack certificate. It should fail to parse because
   600  	// NUL isn't a permitted character in a PrintableString.
   601  
   602  	var cert Certificate
   603  	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
   604  		t.Error("Unmarshal succeeded, should not have")
   605  	}
   606  }
   607  
   608  type rawStructTest struct {
   609  	Raw RawContent
   610  	A   int
   611  }
   612  
   613  func TestRawStructs(t *testing.T) {
   614  	var s rawStructTest
   615  	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
   616  
   617  	rest, err := Unmarshal(input, &s)
   618  	if len(rest) != 0 {
   619  		t.Errorf("incomplete parse: %x", rest)
   620  		return
   621  	}
   622  	if err != nil {
   623  		t.Error(err)
   624  		return
   625  	}
   626  	if s.A != 0x50 {
   627  		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
   628  	}
   629  	if !bytes.Equal([]byte(s.Raw), input) {
   630  		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
   631  	}
   632  }
   633  
   634  type oiEqualTest struct {
   635  	first  ObjectIdentifier
   636  	second ObjectIdentifier
   637  	same   bool
   638  }
   639  
   640  var oiEqualTests = []oiEqualTest{
   641  	{
   642  		ObjectIdentifier{1, 2, 3},
   643  		ObjectIdentifier{1, 2, 3},
   644  		true,
   645  	},
   646  	{
   647  		ObjectIdentifier{1},
   648  		ObjectIdentifier{1, 2, 3},
   649  		false,
   650  	},
   651  	{
   652  		ObjectIdentifier{1, 2, 3},
   653  		ObjectIdentifier{10, 11, 12},
   654  		false,
   655  	},
   656  }
   657  
   658  func TestObjectIdentifierEqual(t *testing.T) {
   659  	for _, o := range oiEqualTests {
   660  		if s := o.first.Equal(o.second); s != o.same {
   661  			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
   662  		}
   663  	}
   664  }
   665  
   666  var derEncodedSelfSignedCert = Certificate{
   667  	TBSCertificate: TBSCertificate{
   668  		Version:            0,
   669  		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}},
   670  		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   671  		Issuer: RDNSequence{
   672  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   673  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   674  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   675  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   676  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   677  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   678  		},
   679  		Validity: Validity{
   680  			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
   681  			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
   682  		},
   683  		Subject: RDNSequence{
   684  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   685  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   686  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   687  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   688  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   689  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   690  		},
   691  		PublicKey: PublicKeyInfo{
   692  			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
   693  			PublicKey: BitString{
   694  				Bytes: []uint8{
   695  					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
   696  					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
   697  					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
   698  					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
   699  					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
   700  					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
   701  					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
   702  				},
   703  				BitLength: 592,
   704  			},
   705  		},
   706  	},
   707  	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   708  	SignatureValue: BitString{
   709  		Bytes: []uint8{
   710  			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
   711  			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
   712  			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
   713  			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
   714  			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
   715  			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
   716  		},
   717  		BitLength: 512,
   718  	},
   719  }
   720  
   721  var derEncodedSelfSignedCertBytes = []byte{
   722  	0x30, 0x82, 0x02, 0x18, 0x30,
   723  	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
   724  	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
   725  	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   726  	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
   727  	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
   728  	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
   729  	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
   730  	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
   731  	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
   732  	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
   733  	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
   734  	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
   735  	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
   736  	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
   737  	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
   738  	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
   739  	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
   740  	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
   741  	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
   742  	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
   743  	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
   744  	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
   745  	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
   746  	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
   747  	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
   748  	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
   749  	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
   750  	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
   751  	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
   752  	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
   753  	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
   754  	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
   755  	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
   756  	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
   757  	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
   758  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
   759  	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
   760  	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
   761  	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
   762  	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
   763  	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
   764  	0x04, 0x35,
   765  }
   766  
   767  var derEncodedPaypalNULCertBytes = []byte{
   768  	0x30, 0x82, 0x06, 0x44, 0x30,
   769  	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
   770  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   771  	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   772  	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
   773  	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
   774  	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
   775  	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
   776  	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
   777  	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
   778  	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
   779  	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
   780  	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
   781  	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
   782  	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
   783  	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
   784  	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
   785  	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
   786  	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
   787  	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   788  	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
   789  	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
   790  	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
   791  	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
   792  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
   793  	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
   794  	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
   795  	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
   796  	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
   797  	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
   798  	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
   799  	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
   800  	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
   801  	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
   802  	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
   803  	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
   804  	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
   805  	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
   806  	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
   807  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
   808  	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
   809  	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
   810  	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
   811  	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
   812  	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
   813  	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
   814  	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
   815  	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
   816  	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
   817  	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
   818  	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
   819  	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
   820  	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
   821  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
   822  	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
   823  	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
   824  	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
   825  	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
   826  	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
   827  	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
   828  	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
   829  	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
   830  	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
   831  	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
   832  	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
   833  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
   834  	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
   835  	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
   836  	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
   837  	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
   838  	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
   839  	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
   840  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   841  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
   842  	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
   843  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   844  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   845  	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
   846  	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
   847  	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
   848  	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
   849  	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
   850  	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
   851  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
   852  	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
   853  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   854  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
   855  	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
   856  	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
   857  	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
   858  	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
   859  	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
   860  	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   861  	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
   862  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
   863  	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
   864  	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
   865  	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
   866  	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
   867  	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
   868  	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
   869  	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
   870  	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   871  	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
   872  	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
   873  	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
   874  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   875  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
   876  	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
   877  	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
   878  	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
   879  	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
   880  	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
   881  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   882  	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
   883  	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
   884  	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
   885  	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
   886  	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
   887  	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
   888  	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
   889  	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
   890  	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
   891  	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
   892  	0x96, 0x07, 0xa8, 0xbb,
   893  }
   894  
   895  var stringSliceTestData = [][]string{
   896  	{"foo", "bar"},
   897  	{"foo", "\\bar"},
   898  	{"foo", "\"bar\""},
   899  	{"foo", "åäö"},
   900  }
   901  
   902  func TestStringSlice(t *testing.T) {
   903  	for _, test := range stringSliceTestData {
   904  		bs, err := Marshal(test)
   905  		if err != nil {
   906  			t.Error(err)
   907  		}
   908  
   909  		var res []string
   910  		_, err = Unmarshal(bs, &res)
   911  		if err != nil {
   912  			t.Error(err)
   913  		}
   914  
   915  		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
   916  			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
   917  		}
   918  	}
   919  }
   920  
   921  type explicitTaggedTimeTest struct {
   922  	Time time.Time `asn1:"explicit,tag:0"`
   923  }
   924  
   925  var explicitTaggedTimeTestData = []struct {
   926  	in  []byte
   927  	out explicitTaggedTimeTest
   928  }{
   929  	{[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
   930  		explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
   931  	{[]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'},
   932  		explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
   933  }
   934  
   935  func TestExplicitTaggedTime(t *testing.T) {
   936  	// Test that a time.Time will match either tagUTCTime or
   937  	// tagGeneralizedTime.
   938  	for i, test := range explicitTaggedTimeTestData {
   939  		var got explicitTaggedTimeTest
   940  		_, err := Unmarshal(test.in, &got)
   941  		if err != nil {
   942  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   943  		}
   944  		if !got.Time.Equal(test.out.Time) {
   945  			t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
   946  		}
   947  	}
   948  }
   949  
   950  type implicitTaggedTimeTest struct {
   951  	Time time.Time `asn1:"tag:24"`
   952  }
   953  
   954  func TestImplicitTaggedTime(t *testing.T) {
   955  	// An implicitly tagged time value, that happens to have an implicit
   956  	// tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
   957  	// (There's no "timeType" in fieldParameters to determine what type of
   958  	// time should be expected when implicitly tagged.)
   959  	der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
   960  	var result implicitTaggedTimeTest
   961  	if _, err := Unmarshal(der, &result); err != nil {
   962  		t.Fatalf("Error while parsing: %s", err)
   963  	}
   964  	if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
   965  		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
   966  	}
   967  }
   968  
   969  type truncatedExplicitTagTest struct {
   970  	Test int `asn1:"explicit,tag:0"`
   971  }
   972  
   973  func TestTruncatedExplicitTag(t *testing.T) {
   974  	// This crashed Unmarshal in the past. See #11154.
   975  	der := []byte{
   976  		0x30, // SEQUENCE
   977  		0x02, // two bytes long
   978  		0xa0, // context-specific, tag 0
   979  		0x30, // 48 bytes long
   980  	}
   981  
   982  	var result truncatedExplicitTagTest
   983  	if _, err := Unmarshal(der, &result); err == nil {
   984  		t.Error("Unmarshal returned without error")
   985  	}
   986  }
   987  
   988  type invalidUTF8Test struct {
   989  	Str string `asn1:"utf8"`
   990  }
   991  
   992  func TestUnmarshalInvalidUTF8(t *testing.T) {
   993  	data := []byte("0\x05\f\x03a\xc9c")
   994  	var result invalidUTF8Test
   995  	_, err := Unmarshal(data, &result)
   996  
   997  	const expectedSubstring = "UTF"
   998  	if err == nil {
   999  		t.Fatal("Successfully unmarshaled invalid UTF-8 data")
  1000  	} else if !strings.Contains(err.Error(), expectedSubstring) {
  1001  		t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
  1002  	}
  1003  }
  1004  
  1005  func TestMarshalNilValue(t *testing.T) {
  1006  	nilValueTestData := []any{
  1007  		nil,
  1008  		struct{ V any }{},
  1009  	}
  1010  	for i, test := range nilValueTestData {
  1011  		if _, err := Marshal(test); err == nil {
  1012  			t.Fatalf("#%d: successfully marshaled nil value", i)
  1013  		}
  1014  	}
  1015  }
  1016  
  1017  type unexported struct {
  1018  	X int
  1019  	y int
  1020  }
  1021  
  1022  type exported struct {
  1023  	X int
  1024  	Y int
  1025  }
  1026  
  1027  func TestUnexportedStructField(t *testing.T) {
  1028  	want := StructuralError{"struct contains unexported fields"}
  1029  
  1030  	_, err := Marshal(unexported{X: 5, y: 1})
  1031  	if err != want {
  1032  		t.Errorf("got %v, want %v", err, want)
  1033  	}
  1034  
  1035  	bs, err := Marshal(exported{X: 5, Y: 1})
  1036  	if err != nil {
  1037  		t.Fatal(err)
  1038  	}
  1039  	var u unexported
  1040  	_, err = Unmarshal(bs, &u)
  1041  	if err != want {
  1042  		t.Errorf("got %v, want %v", err, want)
  1043  	}
  1044  }
  1045  
  1046  func TestNull(t *testing.T) {
  1047  	marshaled, err := Marshal(NullRawValue)
  1048  	if err != nil {
  1049  		t.Fatal(err)
  1050  	}
  1051  	if !bytes.Equal(NullBytes, marshaled) {
  1052  		t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled)
  1053  	}
  1054  
  1055  	unmarshaled := RawValue{}
  1056  	if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil {
  1057  		t.Fatal(err)
  1058  	}
  1059  
  1060  	unmarshaled.FullBytes = NullRawValue.FullBytes
  1061  	if len(unmarshaled.Bytes) == 0 {
  1062  		// DeepEqual considers a nil slice and an empty slice to be different.
  1063  		unmarshaled.Bytes = NullRawValue.Bytes
  1064  	}
  1065  
  1066  	if !reflect.DeepEqual(NullRawValue, unmarshaled) {
  1067  		t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled)
  1068  	}
  1069  }
  1070  
  1071  func TestExplicitTagRawValueStruct(t *testing.T) {
  1072  	type foo struct {
  1073  		A RawValue `asn1:"optional,explicit,tag:5"`
  1074  		B []byte   `asn1:"optional,explicit,tag:6"`
  1075  	}
  1076  	before := foo{B: []byte{1, 2, 3}}
  1077  	derBytes, err := Marshal(before)
  1078  	if err != nil {
  1079  		t.Fatal(err)
  1080  	}
  1081  
  1082  	var after foo
  1083  	if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 {
  1084  		t.Fatal(err)
  1085  	}
  1086  
  1087  	got := fmt.Sprintf("%#v", after)
  1088  	want := fmt.Sprintf("%#v", before)
  1089  	if got != want {
  1090  		t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes)
  1091  	}
  1092  }
  1093  
  1094  func TestTaggedRawValue(t *testing.T) {
  1095  	type taggedRawValue struct {
  1096  		A RawValue `asn1:"tag:5"`
  1097  	}
  1098  	type untaggedRawValue struct {
  1099  		A RawValue
  1100  	}
  1101  	const isCompound = 0x20
  1102  	const tag = 5
  1103  
  1104  	tests := []struct {
  1105  		shouldMatch bool
  1106  		derBytes    []byte
  1107  	}{
  1108  		{false, []byte{0x30, 3, TagInteger, 1, 1}},
  1109  		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
  1110  		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
  1111  		{false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
  1112  		{false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}},
  1113  	}
  1114  
  1115  	for i, test := range tests {
  1116  		var tagged taggedRawValue
  1117  		if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch {
  1118  			t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err)
  1119  		}
  1120  
  1121  		// An untagged RawValue should accept anything.
  1122  		var untagged untaggedRawValue
  1123  		if _, err := Unmarshal(test.derBytes, &untagged); err != nil {
  1124  			t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err)
  1125  		}
  1126  	}
  1127  }
  1128  
  1129  var bmpStringTests = []struct {
  1130  	name       string
  1131  	decoded    string
  1132  	encodedHex string
  1133  	invalid    bool
  1134  }{
  1135  	{"empty string", "", "0000", false},
  1136  	// Example from https://tools.ietf.org/html/rfc7292#appendix-B.
  1137  	{"rfc7292 example", "Beavis", "0042006500610076006900730000", false},
  1138  	// Some characters from the "Letterlike Symbols Unicode block".
  1139  	{"letterlike symbols", "\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000", false},
  1140  	{"invalid length", "", "ff", true},
  1141  	{"invalid surrogate", "", "5051d801", true},
  1142  	{"invalid noncharacter 0xfdd1", "", "5051fdd1", true},
  1143  	{"invalid noncharacter 0xffff", "", "5051ffff", true},
  1144  	{"invalid noncharacter 0xfffe", "", "5051fffe", true},
  1145  }
  1146  
  1147  func TestBMPString(t *testing.T) {
  1148  	for _, test := range bmpStringTests {
  1149  		t.Run(test.name, func(t *testing.T) {
  1150  			encoded, err := hex.DecodeString(test.encodedHex)
  1151  			if err != nil {
  1152  				t.Fatalf("failed to decode from hex string: %s", err)
  1153  			}
  1154  
  1155  			decoded, err := parseBMPString(encoded)
  1156  
  1157  			if err != nil && !test.invalid {
  1158  				t.Errorf("parseBMPString failed: %s", err)
  1159  			} else if test.invalid && err == nil {
  1160  				t.Error("parseBMPString didn't fail as expected")
  1161  			}
  1162  
  1163  			if decoded != test.decoded {
  1164  				t.Errorf("parseBMPString(%q): got %q, want %q", encoded, decoded, test.decoded)
  1165  			}
  1166  		})
  1167  	}
  1168  }
  1169  
  1170  func TestNonMinimalEncodedOID(t *testing.T) {
  1171  	h, err := hex.DecodeString("060a2a80864886f70d01010b")
  1172  	if err != nil {
  1173  		t.Fatalf("failed to decode from hex string: %s", err)
  1174  	}
  1175  	var oid ObjectIdentifier
  1176  	_, err = Unmarshal(h, &oid)
  1177  	if err == nil {
  1178  		t.Fatalf("accepted non-minimally encoded oid")
  1179  	}
  1180  }
  1181  
  1182  func BenchmarkObjectIdentifierString(b *testing.B) {
  1183  	oidPublicKeyRSA := ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
  1184  	for i := 0; i < b.N; i++ {
  1185  		_ = oidPublicKeyRSA.String()
  1186  	}
  1187  }
  1188  
  1189  func TestImplicitTypeRoundtrip(t *testing.T) {
  1190  	type tagged struct {
  1191  		IA5         string    `asn1:"tag:1,ia5"`
  1192  		Printable   string    `asn1:"tag:2,printable"`
  1193  		UTF8        string    `asn1:"tag:3,utf8"`
  1194  		Numeric     string    `asn1:"tag:4,numeric"`
  1195  		UTC         time.Time `asn1:"tag:5,utc"`
  1196  		Generalized time.Time `asn1:"tag:6,generalized"`
  1197  	}
  1198  	a := tagged{
  1199  		IA5:         "ia5",
  1200  		Printable:   "printable",
  1201  		UTF8:        "utf8",
  1202  		Numeric:     "123 456",
  1203  		UTC:         time.Now().UTC().Truncate(time.Second),
  1204  		Generalized: time.Now().UTC().Truncate(time.Second),
  1205  	}
  1206  	enc, err := Marshal(a)
  1207  	if err != nil {
  1208  		t.Fatalf("Marshal failed: %s", err)
  1209  	}
  1210  	var b tagged
  1211  	if _, err := Unmarshal(enc, &b); err != nil {
  1212  		t.Fatalf("Unmarshal failed: %s", err)
  1213  	}
  1214  
  1215  	if !reflect.DeepEqual(a, b) {
  1216  		t.Fatalf("Unexpected diff after roundtripping struct\na: %#v\nb: %#v", a, b)
  1217  	}
  1218  }
  1219  

View as plain text