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