Home | History | Annotate | Download | only in asn1
      1 // Copyright 2009 The Go Authors. All rights reserved.
      2 // Use of this source code is governed by a BSD-style
      3 // license that can be found in the LICENSE file.
      4 
      5 package asn1
      6 
      7 import (
      8 	"bytes"
      9 	"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 (a] 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 (a] 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