...

Source file src/encoding/asn1/asn1_test.go

Documentation: encoding/asn1

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

View as plain text