github.com/q45/go@v0.0.0-20151101211701-a4fb8c13db3f/src/encoding/asn1/asn1_test.go (about)

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