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  	"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  	{[]byte{0x14, 0x03, 0xbf, 0x61, 0x3f}, newString("¿a?")},
   512  }
   513  
   514  func TestUnmarshal(t *testing.T) {
   515  	for i, test := range unmarshalTestData {
   516  		pv := reflect.New(reflect.TypeOf(test.out).Elem())
   517  		val := pv.Interface()
   518  		_, err := Unmarshal(test.in, val)
   519  		if err != nil {
   520  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   521  		}
   522  		if !reflect.DeepEqual(val, test.out) {
   523  			t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
   524  		}
   525  	}
   526  }
   527  
   528  func TestUnmarshalWithNilOrNonPointer(t *testing.T) {
   529  	tests := []struct {
   530  		b    []byte
   531  		v    any
   532  		want string
   533  	}{
   534  		{b: []byte{0x05, 0x00}, v: nil, want: "asn1: Unmarshal recipient value is nil"},
   535  		{b: []byte{0x05, 0x00}, v: RawValue{}, want: "asn1: Unmarshal recipient value is non-pointer asn1.RawValue"},
   536  		{b: []byte{0x05, 0x00}, v: (*RawValue)(nil), want: "asn1: Unmarshal recipient value is nil *asn1.RawValue"},
   537  	}
   538  
   539  	for _, test := range tests {
   540  		_, err := Unmarshal(test.b, test.v)
   541  		if err == nil {
   542  			t.Errorf("Unmarshal expecting error, got nil")
   543  			continue
   544  		}
   545  		if g, w := err.Error(), test.want; g != w {
   546  			t.Errorf("InvalidUnmarshalError mismatch\nGot:  %q\nWant: %q", g, w)
   547  		}
   548  	}
   549  }
   550  
   551  type Certificate struct {
   552  	TBSCertificate     TBSCertificate
   553  	SignatureAlgorithm AlgorithmIdentifier
   554  	SignatureValue     BitString
   555  }
   556  
   557  type TBSCertificate struct {
   558  	Version            int `asn1:"optional,explicit,default:0,tag:0"`
   559  	SerialNumber       RawValue
   560  	SignatureAlgorithm AlgorithmIdentifier
   561  	Issuer             RDNSequence
   562  	Validity           Validity
   563  	Subject            RDNSequence
   564  	PublicKey          PublicKeyInfo
   565  }
   566  
   567  type AlgorithmIdentifier struct {
   568  	Algorithm ObjectIdentifier
   569  }
   570  
   571  type RDNSequence []RelativeDistinguishedNameSET
   572  
   573  type RelativeDistinguishedNameSET []AttributeTypeAndValue
   574  
   575  type AttributeTypeAndValue struct {
   576  	Type  ObjectIdentifier
   577  	Value any
   578  }
   579  
   580  type Validity struct {
   581  	NotBefore, NotAfter time.Time
   582  }
   583  
   584  type PublicKeyInfo struct {
   585  	Algorithm AlgorithmIdentifier
   586  	PublicKey BitString
   587  }
   588  
   589  func TestCertificate(t *testing.T) {
   590  	// This is a minimal, self-signed certificate that should parse correctly.
   591  	var cert Certificate
   592  	if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
   593  		t.Errorf("Unmarshal failed: %v", err)
   594  	}
   595  	if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
   596  		t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
   597  	}
   598  }
   599  
   600  func TestCertificateWithNUL(t *testing.T) {
   601  	// This is the paypal NUL-hack certificate. It should fail to parse because
   602  	// NUL isn't a permitted character in a PrintableString.
   603  
   604  	var cert Certificate
   605  	if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
   606  		t.Error("Unmarshal succeeded, should not have")
   607  	}
   608  }
   609  
   610  type rawStructTest struct {
   611  	Raw RawContent
   612  	A   int
   613  }
   614  
   615  func TestRawStructs(t *testing.T) {
   616  	var s rawStructTest
   617  	input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
   618  
   619  	rest, err := Unmarshal(input, &s)
   620  	if len(rest) != 0 {
   621  		t.Errorf("incomplete parse: %x", rest)
   622  		return
   623  	}
   624  	if err != nil {
   625  		t.Error(err)
   626  		return
   627  	}
   628  	if s.A != 0x50 {
   629  		t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
   630  	}
   631  	if !bytes.Equal([]byte(s.Raw), input) {
   632  		t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
   633  	}
   634  }
   635  
   636  type oiEqualTest struct {
   637  	first  ObjectIdentifier
   638  	second ObjectIdentifier
   639  	same   bool
   640  }
   641  
   642  var oiEqualTests = []oiEqualTest{
   643  	{
   644  		ObjectIdentifier{1, 2, 3},
   645  		ObjectIdentifier{1, 2, 3},
   646  		true,
   647  	},
   648  	{
   649  		ObjectIdentifier{1},
   650  		ObjectIdentifier{1, 2, 3},
   651  		false,
   652  	},
   653  	{
   654  		ObjectIdentifier{1, 2, 3},
   655  		ObjectIdentifier{10, 11, 12},
   656  		false,
   657  	},
   658  }
   659  
   660  func TestObjectIdentifierEqual(t *testing.T) {
   661  	for _, o := range oiEqualTests {
   662  		if s := o.first.Equal(o.second); s != o.same {
   663  			t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
   664  		}
   665  	}
   666  }
   667  
   668  var derEncodedSelfSignedCert = Certificate{
   669  	TBSCertificate: TBSCertificate{
   670  		Version:            0,
   671  		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}},
   672  		SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   673  		Issuer: RDNSequence{
   674  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   675  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   676  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   677  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   678  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   679  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   680  		},
   681  		Validity: Validity{
   682  			NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
   683  			NotAfter:  time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
   684  		},
   685  		Subject: RDNSequence{
   686  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
   687  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
   688  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
   689  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
   690  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
   691  			RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
   692  		},
   693  		PublicKey: PublicKeyInfo{
   694  			Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
   695  			PublicKey: BitString{
   696  				Bytes: []uint8{
   697  					0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
   698  					0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
   699  					0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
   700  					0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
   701  					0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
   702  					0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
   703  					0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
   704  				},
   705  				BitLength: 592,
   706  			},
   707  		},
   708  	},
   709  	SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
   710  	SignatureValue: BitString{
   711  		Bytes: []uint8{
   712  			0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
   713  			0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
   714  			0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
   715  			0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
   716  			0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
   717  			0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
   718  		},
   719  		BitLength: 512,
   720  	},
   721  }
   722  
   723  var derEncodedSelfSignedCertBytes = []byte{
   724  	0x30, 0x82, 0x02, 0x18, 0x30,
   725  	0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
   726  	0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
   727  	0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   728  	0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
   729  	0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
   730  	0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
   731  	0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
   732  	0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
   733  	0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
   734  	0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
   735  	0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
   736  	0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
   737  	0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
   738  	0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
   739  	0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
   740  	0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
   741  	0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
   742  	0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
   743  	0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
   744  	0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
   745  	0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
   746  	0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
   747  	0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
   748  	0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
   749  	0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
   750  	0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
   751  	0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
   752  	0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
   753  	0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
   754  	0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
   755  	0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
   756  	0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
   757  	0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
   758  	0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
   759  	0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
   760  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
   761  	0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
   762  	0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
   763  	0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
   764  	0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
   765  	0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
   766  	0x04, 0x35,
   767  }
   768  
   769  var derEncodedPaypalNULCertBytes = []byte{
   770  	0x30, 0x82, 0x06, 0x44, 0x30,
   771  	0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
   772  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   773  	0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
   774  	0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
   775  	0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
   776  	0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
   777  	0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
   778  	0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
   779  	0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
   780  	0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
   781  	0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
   782  	0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
   783  	0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
   784  	0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
   785  	0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
   786  	0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
   787  	0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
   788  	0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
   789  	0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   790  	0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
   791  	0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
   792  	0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
   793  	0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
   794  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
   795  	0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
   796  	0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
   797  	0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
   798  	0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
   799  	0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
   800  	0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
   801  	0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
   802  	0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
   803  	0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
   804  	0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
   805  	0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
   806  	0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
   807  	0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
   808  	0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
   809  	0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
   810  	0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
   811  	0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
   812  	0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
   813  	0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
   814  	0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
   815  	0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
   816  	0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
   817  	0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
   818  	0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
   819  	0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
   820  	0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
   821  	0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
   822  	0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
   823  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
   824  	0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
   825  	0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
   826  	0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
   827  	0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
   828  	0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
   829  	0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
   830  	0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
   831  	0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
   832  	0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
   833  	0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
   834  	0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
   835  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
   836  	0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
   837  	0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
   838  	0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
   839  	0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
   840  	0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
   841  	0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
   842  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   843  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
   844  	0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
   845  	0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
   846  	0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   847  	0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
   848  	0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
   849  	0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
   850  	0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
   851  	0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
   852  	0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
   853  	0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
   854  	0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
   855  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   856  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
   857  	0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
   858  	0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
   859  	0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
   860  	0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
   861  	0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
   862  	0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
   863  	0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
   864  	0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
   865  	0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
   866  	0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
   867  	0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
   868  	0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
   869  	0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
   870  	0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
   871  	0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
   872  	0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
   873  	0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
   874  	0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
   875  	0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
   876  	0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
   877  	0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
   878  	0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
   879  	0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
   880  	0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
   881  	0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
   882  	0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
   883  	0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
   884  	0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
   885  	0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
   886  	0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
   887  	0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
   888  	0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
   889  	0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
   890  	0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
   891  	0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
   892  	0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
   893  	0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
   894  	0x96, 0x07, 0xa8, 0xbb,
   895  }
   896  
   897  var stringSliceTestData = [][]string{
   898  	{"foo", "bar"},
   899  	{"foo", "\\bar"},
   900  	{"foo", "\"bar\""},
   901  	{"foo", "åäö"},
   902  }
   903  
   904  func TestStringSlice(t *testing.T) {
   905  	for _, test := range stringSliceTestData {
   906  		bs, err := Marshal(test)
   907  		if err != nil {
   908  			t.Error(err)
   909  		}
   910  
   911  		var res []string
   912  		_, err = Unmarshal(bs, &res)
   913  		if err != nil {
   914  			t.Error(err)
   915  		}
   916  
   917  		if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
   918  			t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
   919  		}
   920  	}
   921  }
   922  
   923  type explicitTaggedTimeTest struct {
   924  	Time time.Time `asn1:"explicit,tag:0"`
   925  }
   926  
   927  var explicitTaggedTimeTestData = []struct {
   928  	in  []byte
   929  	out explicitTaggedTimeTest
   930  }{
   931  	{[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
   932  		explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
   933  	{[]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'},
   934  		explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
   935  }
   936  
   937  func TestExplicitTaggedTime(t *testing.T) {
   938  	// Test that a time.Time will match either tagUTCTime or
   939  	// tagGeneralizedTime.
   940  	for i, test := range explicitTaggedTimeTestData {
   941  		var got explicitTaggedTimeTest
   942  		_, err := Unmarshal(test.in, &got)
   943  		if err != nil {
   944  			t.Errorf("Unmarshal failed at index %d %v", i, err)
   945  		}
   946  		if !got.Time.Equal(test.out.Time) {
   947  			t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
   948  		}
   949  	}
   950  }
   951  
   952  type implicitTaggedTimeTest struct {
   953  	Time time.Time `asn1:"tag:24"`
   954  }
   955  
   956  func TestImplicitTaggedTime(t *testing.T) {
   957  	// An implicitly tagged time value, that happens to have an implicit
   958  	// tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
   959  	// (There's no "timeType" in fieldParameters to determine what type of
   960  	// time should be expected when implicitly tagged.)
   961  	der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
   962  	var result implicitTaggedTimeTest
   963  	if _, err := Unmarshal(der, &result); err != nil {
   964  		t.Fatalf("Error while parsing: %s", err)
   965  	}
   966  	if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
   967  		t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
   968  	}
   969  }
   970  
   971  type truncatedExplicitTagTest struct {
   972  	Test int `asn1:"explicit,tag:0"`
   973  }
   974  
   975  func TestTruncatedExplicitTag(t *testing.T) {
   976  	// This crashed Unmarshal in the past. See #11154.
   977  	der := []byte{
   978  		0x30, // SEQUENCE
   979  		0x02, // two bytes long
   980  		0xa0, // context-specific, tag 0
   981  		0x30, // 48 bytes long
   982  	}
   983  
   984  	var result truncatedExplicitTagTest
   985  	if _, err := Unmarshal(der, &result); err == nil {
   986  		t.Error("Unmarshal returned without error")
   987  	}
   988  }
   989  
   990  type invalidUTF8Test struct {
   991  	Str string `asn1:"utf8"`
   992  }
   993  
   994  func TestUnmarshalInvalidUTF8(t *testing.T) {
   995  	data := []byte("0\x05\f\x03a\xc9c")
   996  	var result invalidUTF8Test
   997  	_, err := Unmarshal(data, &result)
   998  
   999  	const expectedSubstring = "UTF"
  1000  	if err == nil {
  1001  		t.Fatal("Successfully unmarshaled invalid UTF-8 data")
  1002  	} else if !strings.Contains(err.Error(), expectedSubstring) {
  1003  		t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
  1004  	}
  1005  }
  1006  
  1007  func TestMarshalNilValue(t *testing.T) {
  1008  	nilValueTestData := []any{
  1009  		nil,
  1010  		struct{ V any }{},
  1011  	}
  1012  	for i, test := range nilValueTestData {
  1013  		if _, err := Marshal(test); err == nil {
  1014  			t.Fatalf("#%d: successfully marshaled nil value", i)
  1015  		}
  1016  	}
  1017  }
  1018  
  1019  type unexported struct {
  1020  	X int
  1021  	y int
  1022  }
  1023  
  1024  type exported struct {
  1025  	X int
  1026  	Y int
  1027  }
  1028  
  1029  func TestUnexportedStructField(t *testing.T) {
  1030  	want := StructuralError{"struct contains unexported fields"}
  1031  
  1032  	_, err := Marshal(unexported{X: 5, y: 1})
  1033  	if err != want {
  1034  		t.Errorf("got %v, want %v", err, want)
  1035  	}
  1036  
  1037  	bs, err := Marshal(exported{X: 5, Y: 1})
  1038  	if err != nil {
  1039  		t.Fatal(err)
  1040  	}
  1041  	var u unexported
  1042  	_, err = Unmarshal(bs, &u)
  1043  	if err != want {
  1044  		t.Errorf("got %v, want %v", err, want)
  1045  	}
  1046  }
  1047  
  1048  func TestNull(t *testing.T) {
  1049  	marshaled, err := Marshal(NullRawValue)
  1050  	if err != nil {
  1051  		t.Fatal(err)
  1052  	}
  1053  	if !bytes.Equal(NullBytes, marshaled) {
  1054  		t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled)
  1055  	}
  1056  
  1057  	unmarshaled := RawValue{}
  1058  	if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil {
  1059  		t.Fatal(err)
  1060  	}
  1061  
  1062  	unmarshaled.FullBytes = NullRawValue.FullBytes
  1063  	if len(unmarshaled.Bytes) == 0 {
  1064  		// DeepEqual considers a nil slice and an empty slice to be different.
  1065  		unmarshaled.Bytes = NullRawValue.Bytes
  1066  	}
  1067  
  1068  	if !reflect.DeepEqual(NullRawValue, unmarshaled) {
  1069  		t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled)
  1070  	}
  1071  }
  1072  
  1073  func TestExplicitTagRawValueStruct(t *testing.T) {
  1074  	type foo struct {
  1075  		A RawValue `asn1:"optional,explicit,tag:5"`
  1076  		B []byte   `asn1:"optional,explicit,tag:6"`
  1077  	}
  1078  	before := foo{B: []byte{1, 2, 3}}
  1079  	derBytes, err := Marshal(before)
  1080  	if err != nil {
  1081  		t.Fatal(err)
  1082  	}
  1083  
  1084  	var after foo
  1085  	if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 {
  1086  		t.Fatal(err)
  1087  	}
  1088  
  1089  	got := fmt.Sprintf("%#v", after)
  1090  	want := fmt.Sprintf("%#v", before)
  1091  	if got != want {
  1092  		t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes)
  1093  	}
  1094  }
  1095  
  1096  func TestTaggedRawValue(t *testing.T) {
  1097  	type taggedRawValue struct {
  1098  		A RawValue `asn1:"tag:5"`
  1099  	}
  1100  	type untaggedRawValue struct {
  1101  		A RawValue
  1102  	}
  1103  	const isCompound = 0x20
  1104  	const tag = 5
  1105  
  1106  	tests := []struct {
  1107  		shouldMatch bool
  1108  		derBytes    []byte
  1109  	}{
  1110  		{false, []byte{0x30, 3, TagInteger, 1, 1}},
  1111  		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
  1112  		{true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
  1113  		{false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
  1114  		{false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}},
  1115  	}
  1116  
  1117  	for i, test := range tests {
  1118  		var tagged taggedRawValue
  1119  		if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch {
  1120  			t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err)
  1121  		}
  1122  
  1123  		// An untagged RawValue should accept anything.
  1124  		var untagged untaggedRawValue
  1125  		if _, err := Unmarshal(test.derBytes, &untagged); err != nil {
  1126  			t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err)
  1127  		}
  1128  	}
  1129  }
  1130  
  1131  var bmpStringTests = []struct {
  1132  	name       string
  1133  	decoded    string
  1134  	encodedHex string
  1135  	invalid    bool
  1136  }{
  1137  	{"empty string", "", "0000", false},
  1138  	// Example from https://tools.ietf.org/html/rfc7292#appendix-B.
  1139  	{"rfc7292 example", "Beavis", "0042006500610076006900730000", false},
  1140  	// Some characters from the "Letterlike Symbols Unicode block".
  1141  	{"letterlike symbols", "\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000", false},
  1142  	{"invalid length", "", "ff", true},
  1143  	{"invalid surrogate", "", "5051d801", true},
  1144  	{"invalid noncharacter 0xfdd1", "", "5051fdd1", true},
  1145  	{"invalid noncharacter 0xffff", "", "5051ffff", true},
  1146  	{"invalid noncharacter 0xfffe", "", "5051fffe", true},
  1147  }
  1148  
  1149  func TestBMPString(t *testing.T) {
  1150  	for _, test := range bmpStringTests {
  1151  		t.Run(test.name, func(t *testing.T) {
  1152  			encoded, err := hex.DecodeString(test.encodedHex)
  1153  			if err != nil {
  1154  				t.Fatalf("failed to decode from hex string: %s", err)
  1155  			}
  1156  
  1157  			decoded, err := parseBMPString(encoded)
  1158  
  1159  			if err != nil && !test.invalid {
  1160  				t.Errorf("parseBMPString failed: %s", err)
  1161  			} else if test.invalid && err == nil {
  1162  				t.Error("parseBMPString didn't fail as expected")
  1163  			}
  1164  
  1165  			if decoded != test.decoded {
  1166  				t.Errorf("parseBMPString(%q): got %q, want %q", encoded, decoded, test.decoded)
  1167  			}
  1168  		})
  1169  	}
  1170  }
  1171  
  1172  func TestNonMinimalEncodedOID(t *testing.T) {
  1173  	h, err := hex.DecodeString("060a2a80864886f70d01010b")
  1174  	if err != nil {
  1175  		t.Fatalf("failed to decode from hex string: %s", err)
  1176  	}
  1177  	var oid ObjectIdentifier
  1178  	_, err = Unmarshal(h, &oid)
  1179  	if err == nil {
  1180  		t.Fatalf("accepted non-minimally encoded oid")
  1181  	}
  1182  }
  1183  
  1184  func BenchmarkObjectIdentifierString(b *testing.B) {
  1185  	oidPublicKeyRSA := ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}
  1186  	for i := 0; i < b.N; i++ {
  1187  		_ = oidPublicKeyRSA.String()
  1188  	}
  1189  }
  1190  
  1191  func TestImplicitTypeRoundtrip(t *testing.T) {
  1192  	type tagged struct {
  1193  		IA5         string    `asn1:"tag:1,ia5"`
  1194  		Printable   string    `asn1:"tag:2,printable"`
  1195  		UTF8        string    `asn1:"tag:3,utf8"`
  1196  		Numeric     string    `asn1:"tag:4,numeric"`
  1197  		UTC         time.Time `asn1:"tag:5,utc"`
  1198  		Generalized time.Time `asn1:"tag:6,generalized"`
  1199  	}
  1200  	a := tagged{
  1201  		IA5:         "ia5",
  1202  		Printable:   "printable",
  1203  		UTF8:        "utf8",
  1204  		Numeric:     "123 456",
  1205  		UTC:         time.Now().UTC().Truncate(time.Second),
  1206  		Generalized: time.Now().UTC().Truncate(time.Second),
  1207  	}
  1208  	enc, err := Marshal(a)
  1209  	if err != nil {
  1210  		t.Fatalf("Marshal failed: %s", err)
  1211  	}
  1212  	var b tagged
  1213  	if _, err := Unmarshal(enc, &b); err != nil {
  1214  		t.Fatalf("Unmarshal failed: %s", err)
  1215  	}
  1216  
  1217  	if !reflect.DeepEqual(a, b) {
  1218  		t.Fatalf("Unexpected diff after roundtripping struct\na: %#v\nb: %#v", a, b)
  1219  	}
  1220  }
  1221  
  1222  func TestParsingMemoryConsumption(t *testing.T) {
  1223  	// Craft a syntatically valid, but empty, ~10 MB DER bomb. A successful
  1224  	// unmarshal of this bomb should yield ~280 MB. However, the parsing should
  1225  	// fail due to the empty content; and, in such cases, we want to make sure
  1226  	// that we do not unnecessarily allocate memories.
  1227  	derBomb := make([]byte, 10_000_000)
  1228  	for i := range derBomb {
  1229  		derBomb[i] = 0x30
  1230  	}
  1231  	derBomb = append([]byte{0x30, 0x83, 0x98, 0x96, 0x80}, derBomb...)
  1232  
  1233  	var m runtime.MemStats
  1234  	runtime.GC()
  1235  	runtime.ReadMemStats(&m)
  1236  	memBefore := m.TotalAlloc
  1237  
  1238  	var out []struct {
  1239  		Id       []int
  1240  		Critical bool `asn1:"optional"`
  1241  		Value    []byte
  1242  	}
  1243  	_, err := Unmarshal(derBomb, &out)
  1244  	if !errors.As(err, &SyntaxError{}) {
  1245  		t.Fatalf("Incorrect error result: want (%v), but got (%v) instead", &SyntaxError{}, err)
  1246  	}
  1247  
  1248  	runtime.ReadMemStats(&m)
  1249  	memDiff := m.TotalAlloc - memBefore
  1250  
  1251  	// Ensure that the memory allocated does not exceed 10<<21 (~20 MB) when
  1252  	// the parsing fails.
  1253  	if memDiff > 10<<21 {
  1254  		t.Errorf("Too much memory allocated while parsing DER: %v MiB", memDiff/1024/1024)
  1255  	}
  1256  }
  1257  

View as plain text