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