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