libgo: update to Go 1.11
[official-gcc.git] / libgo / go / encoding / asn1 / asn1_test.go
blobf0a54e0cb2e6999b904c4bdb53a916867ab976a1
1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 package asn1
7 import (
8 "bytes"
9 "fmt"
10 "math"
11 "math/big"
12 "reflect"
13 "strings"
14 "testing"
15 "time"
18 type boolTest struct {
19 in []byte
20 ok bool
21 out bool
24 var boolTestData = []boolTest{
25 {[]byte{0x00}, true, false},
26 {[]byte{0xff}, true, true},
27 {[]byte{0x00, 0x00}, false, false},
28 {[]byte{0xff, 0xff}, false, false},
29 {[]byte{0x01}, false, false},
32 func TestParseBool(t *testing.T) {
33 for i, test := range boolTestData {
34 ret, err := parseBool(test.in)
35 if (err == nil) != test.ok {
36 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
38 if test.ok && ret != test.out {
39 t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
44 type int64Test struct {
45 in []byte
46 ok bool
47 out int64
50 var int64TestData = []int64Test{
51 {[]byte{0x00}, true, 0},
52 {[]byte{0x7f}, true, 127},
53 {[]byte{0x00, 0x80}, true, 128},
54 {[]byte{0x01, 0x00}, true, 256},
55 {[]byte{0x80}, true, -128},
56 {[]byte{0xff, 0x7f}, true, -129},
57 {[]byte{0xff}, true, -1},
58 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, true, -9223372036854775808},
59 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, false, 0},
60 {[]byte{}, false, 0},
61 {[]byte{0x00, 0x7f}, false, 0},
62 {[]byte{0xff, 0xf0}, false, 0},
65 func TestParseInt64(t *testing.T) {
66 for i, test := range int64TestData {
67 ret, err := parseInt64(test.in)
68 if (err == nil) != test.ok {
69 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
71 if test.ok && ret != test.out {
72 t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
77 type int32Test struct {
78 in []byte
79 ok bool
80 out int32
83 var int32TestData = []int32Test{
84 {[]byte{0x00}, true, 0},
85 {[]byte{0x7f}, true, 127},
86 {[]byte{0x00, 0x80}, true, 128},
87 {[]byte{0x01, 0x00}, true, 256},
88 {[]byte{0x80}, true, -128},
89 {[]byte{0xff, 0x7f}, true, -129},
90 {[]byte{0xff}, true, -1},
91 {[]byte{0x80, 0x00, 0x00, 0x00}, true, -2147483648},
92 {[]byte{0x80, 0x00, 0x00, 0x00, 0x00}, false, 0},
93 {[]byte{}, false, 0},
94 {[]byte{0x00, 0x7f}, false, 0},
95 {[]byte{0xff, 0xf0}, false, 0},
98 func TestParseInt32(t *testing.T) {
99 for i, test := range int32TestData {
100 ret, err := parseInt32(test.in)
101 if (err == nil) != test.ok {
102 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
104 if test.ok && int32(ret) != test.out {
105 t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
110 var bigIntTests = []struct {
111 in []byte
112 ok bool
113 base10 string
115 {[]byte{0xff}, true, "-1"},
116 {[]byte{0x00}, true, "0"},
117 {[]byte{0x01}, true, "1"},
118 {[]byte{0x00, 0xff}, true, "255"},
119 {[]byte{0xff, 0x00}, true, "-256"},
120 {[]byte{0x01, 0x00}, true, "256"},
121 {[]byte{}, false, ""},
122 {[]byte{0x00, 0x7f}, false, ""},
123 {[]byte{0xff, 0xf0}, false, ""},
126 func TestParseBigInt(t *testing.T) {
127 for i, test := range bigIntTests {
128 ret, err := parseBigInt(test.in)
129 if (err == nil) != test.ok {
130 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
132 if test.ok {
133 if ret.String() != test.base10 {
134 t.Errorf("#%d: bad result from %x, got %s want %s", i, test.in, ret.String(), test.base10)
136 e, err := makeBigInt(ret)
137 if err != nil {
138 t.Errorf("%d: err=%q", i, err)
139 continue
141 result := make([]byte, e.Len())
142 e.Encode(result)
143 if !bytes.Equal(result, test.in) {
144 t.Errorf("#%d: got %x from marshaling %s, want %x", i, result, ret, test.in)
150 type bitStringTest struct {
151 in []byte
152 ok bool
153 out []byte
154 bitLength int
157 var bitStringTestData = []bitStringTest{
158 {[]byte{}, false, []byte{}, 0},
159 {[]byte{0x00}, true, []byte{}, 0},
160 {[]byte{0x07, 0x00}, true, []byte{0x00}, 1},
161 {[]byte{0x07, 0x01}, false, []byte{}, 0},
162 {[]byte{0x07, 0x40}, false, []byte{}, 0},
163 {[]byte{0x08, 0x00}, false, []byte{}, 0},
166 func TestBitString(t *testing.T) {
167 for i, test := range bitStringTestData {
168 ret, err := parseBitString(test.in)
169 if (err == nil) != test.ok {
170 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
172 if err == nil {
173 if test.bitLength != ret.BitLength || !bytes.Equal(ret.Bytes, test.out) {
174 t.Errorf("#%d: Bad result: %v (expected %v %v)", i, ret, test.out, test.bitLength)
180 func TestBitStringAt(t *testing.T) {
181 bs := BitString{[]byte{0x82, 0x40}, 16}
182 if bs.At(0) != 1 {
183 t.Error("#1: Failed")
185 if bs.At(1) != 0 {
186 t.Error("#2: Failed")
188 if bs.At(6) != 1 {
189 t.Error("#3: Failed")
191 if bs.At(9) != 1 {
192 t.Error("#4: Failed")
194 if bs.At(-1) != 0 {
195 t.Error("#5: Failed")
197 if bs.At(17) != 0 {
198 t.Error("#6: Failed")
202 type bitStringRightAlignTest struct {
203 in []byte
204 inlen int
205 out []byte
208 var bitStringRightAlignTests = []bitStringRightAlignTest{
209 {[]byte{0x80}, 1, []byte{0x01}},
210 {[]byte{0x80, 0x80}, 9, []byte{0x01, 0x01}},
211 {[]byte{}, 0, []byte{}},
212 {[]byte{0xce}, 8, []byte{0xce}},
213 {[]byte{0xce, 0x47}, 16, []byte{0xce, 0x47}},
214 {[]byte{0x34, 0x50}, 12, []byte{0x03, 0x45}},
217 func TestBitStringRightAlign(t *testing.T) {
218 for i, test := range bitStringRightAlignTests {
219 bs := BitString{test.in, test.inlen}
220 out := bs.RightAlign()
221 if !bytes.Equal(out, test.out) {
222 t.Errorf("#%d got: %x want: %x", i, out, test.out)
227 type objectIdentifierTest struct {
228 in []byte
229 ok bool
230 out ObjectIdentifier // has base type[]int
233 var objectIdentifierTestData = []objectIdentifierTest{
234 {[]byte{}, false, []int{}},
235 {[]byte{85}, true, []int{2, 5}},
236 {[]byte{85, 0x02}, true, []int{2, 5, 2}},
237 {[]byte{85, 0x02, 0xc0, 0x00}, true, []int{2, 5, 2, 0x2000}},
238 {[]byte{0x81, 0x34, 0x03}, true, []int{2, 100, 3}},
239 {[]byte{85, 0x02, 0xc0, 0x80, 0x80, 0x80, 0x80}, false, []int{}},
242 func TestObjectIdentifier(t *testing.T) {
243 for i, test := range objectIdentifierTestData {
244 ret, err := parseObjectIdentifier(test.in)
245 if (err == nil) != test.ok {
246 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
248 if err == nil {
249 if !reflect.DeepEqual(test.out, ret) {
250 t.Errorf("#%d: Bad result: %v (expected %v)", i, ret, test.out)
255 if s := ObjectIdentifier([]int{1, 2, 3, 4}).String(); s != "1.2.3.4" {
256 t.Errorf("bad ObjectIdentifier.String(). Got %s, want 1.2.3.4", s)
260 type timeTest struct {
261 in string
262 ok bool
263 out time.Time
266 var utcTestData = []timeTest{
267 {"910506164540-0700", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", -7*60*60))},
268 {"910506164540+0730", true, time.Date(1991, 05, 06, 16, 45, 40, 0, time.FixedZone("", 7*60*60+30*60))},
269 {"910506234540Z", true, time.Date(1991, 05, 06, 23, 45, 40, 0, time.UTC)},
270 {"9105062345Z", true, time.Date(1991, 05, 06, 23, 45, 0, 0, time.UTC)},
271 {"5105062345Z", true, time.Date(1951, 05, 06, 23, 45, 0, 0, time.UTC)},
272 {"a10506234540Z", false, time.Time{}},
273 {"91a506234540Z", false, time.Time{}},
274 {"9105a6234540Z", false, time.Time{}},
275 {"910506a34540Z", false, time.Time{}},
276 {"910506334a40Z", false, time.Time{}},
277 {"91050633444aZ", false, time.Time{}},
278 {"910506334461Z", false, time.Time{}},
279 {"910506334400Za", false, time.Time{}},
280 /* These are invalid times. However, the time package normalises times
281 * and they were accepted in some versions. See #11134. */
282 {"000100000000Z", false, time.Time{}},
283 {"101302030405Z", false, time.Time{}},
284 {"100002030405Z", false, time.Time{}},
285 {"100100030405Z", false, time.Time{}},
286 {"100132030405Z", false, time.Time{}},
287 {"100231030405Z", false, time.Time{}},
288 {"100102240405Z", false, time.Time{}},
289 {"100102036005Z", false, time.Time{}},
290 {"100102030460Z", false, time.Time{}},
291 {"-100102030410Z", false, time.Time{}},
292 {"10-0102030410Z", false, time.Time{}},
293 {"10-0002030410Z", false, time.Time{}},
294 {"1001-02030410Z", false, time.Time{}},
295 {"100102-030410Z", false, time.Time{}},
296 {"10010203-0410Z", false, time.Time{}},
297 {"1001020304-10Z", false, time.Time{}},
300 func TestUTCTime(t *testing.T) {
301 for i, test := range utcTestData {
302 ret, err := parseUTCTime([]byte(test.in))
303 if err != nil {
304 if test.ok {
305 t.Errorf("#%d: parseUTCTime(%q) = error %v", i, test.in, err)
307 continue
309 if !test.ok {
310 t.Errorf("#%d: parseUTCTime(%q) succeeded, should have failed", i, test.in)
311 continue
313 const format = "Jan _2 15:04:05 -0700 2006" // ignore zone name, just offset
314 have := ret.Format(format)
315 want := test.out.Format(format)
316 if have != want {
317 t.Errorf("#%d: parseUTCTime(%q) = %s, want %s", i, test.in, have, want)
322 var generalizedTimeTestData = []timeTest{
323 {"20100102030405Z", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.UTC)},
324 {"20100102030405", false, time.Time{}},
325 {"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))},
326 {"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))},
327 /* These are invalid times. However, the time package normalises times
328 * and they were accepted in some versions. See #11134. */
329 {"00000100000000Z", false, time.Time{}},
330 {"20101302030405Z", false, time.Time{}},
331 {"20100002030405Z", false, time.Time{}},
332 {"20100100030405Z", false, time.Time{}},
333 {"20100132030405Z", false, time.Time{}},
334 {"20100231030405Z", false, time.Time{}},
335 {"20100102240405Z", false, time.Time{}},
336 {"20100102036005Z", false, time.Time{}},
337 {"20100102030460Z", false, time.Time{}},
338 {"-20100102030410Z", false, time.Time{}},
339 {"2010-0102030410Z", false, time.Time{}},
340 {"2010-0002030410Z", false, time.Time{}},
341 {"201001-02030410Z", false, time.Time{}},
342 {"20100102-030410Z", false, time.Time{}},
343 {"2010010203-0410Z", false, time.Time{}},
344 {"201001020304-10Z", false, time.Time{}},
347 func TestGeneralizedTime(t *testing.T) {
348 for i, test := range generalizedTimeTestData {
349 ret, err := parseGeneralizedTime([]byte(test.in))
350 if (err == nil) != test.ok {
351 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok)
353 if err == nil {
354 if !reflect.DeepEqual(test.out, ret) {
355 t.Errorf("#%d: Bad result: %q → %v (expected %v)", i, test.in, ret, test.out)
361 type tagAndLengthTest struct {
362 in []byte
363 ok bool
364 out tagAndLength
367 var tagAndLengthData = []tagAndLengthTest{
368 {[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}},
369 {[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}},
370 {[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}},
371 {[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}},
372 {[]byte{0x1f, 0x1f, 0x00}, true, tagAndLength{0, 31, 0, false}},
373 {[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}},
374 {[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}},
375 {[]byte{0x00, 0x81, 0x80}, true, tagAndLength{0, 0, 128, false}},
376 {[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}},
377 {[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}},
378 {[]byte{0x1f, 0x85}, false, tagAndLength{}},
379 {[]byte{0x30, 0x80}, false, tagAndLength{}},
380 // Superfluous zeros in the length should be an error.
381 {[]byte{0xa0, 0x82, 0x00, 0xff}, false, tagAndLength{}},
382 // Lengths up to the maximum size of an int should work.
383 {[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}},
384 // Lengths that would overflow an int should be rejected.
385 {[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}},
386 // Long length form may not be used for lengths that fit in short form.
387 {[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}},
388 // Tag numbers which would overflow int32 are rejected. (The value below is 2^31.)
389 {[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}},
390 // Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.)
391 {[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}},
392 // Long tag number form may not be used for tags that fit in short form.
393 {[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}},
396 func TestParseTagAndLength(t *testing.T) {
397 for i, test := range tagAndLengthData {
398 tagAndLength, _, err := parseTagAndLength(test.in, 0)
399 if (err == nil) != test.ok {
400 t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok)
402 if err == nil && !reflect.DeepEqual(test.out, tagAndLength) {
403 t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out)
408 type parseFieldParametersTest struct {
409 in string
410 out fieldParameters
413 func newInt(n int) *int { return &n }
415 func newInt64(n int64) *int64 { return &n }
417 func newString(s string) *string { return &s }
419 func newBool(b bool) *bool { return &b }
421 var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{
422 {"", fieldParameters{}},
423 {"ia5", fieldParameters{stringType: TagIA5String}},
424 {"generalized", fieldParameters{timeType: TagGeneralizedTime}},
425 {"utc", fieldParameters{timeType: TagUTCTime}},
426 {"printable", fieldParameters{stringType: TagPrintableString}},
427 {"numeric", fieldParameters{stringType: TagNumericString}},
428 {"optional", fieldParameters{optional: true}},
429 {"explicit", fieldParameters{explicit: true, tag: new(int)}},
430 {"application", fieldParameters{application: true, tag: new(int)}},
431 {"private", fieldParameters{private: true, tag: new(int)}},
432 {"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}},
433 {"default:42", fieldParameters{defaultValue: newInt64(42)}},
434 {"tag:17", fieldParameters{tag: newInt(17)}},
435 {"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}},
436 {"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}},
437 {"set", fieldParameters{set: true}},
440 func TestParseFieldParameters(t *testing.T) {
441 for i, test := range parseFieldParametersTestData {
442 f := parseFieldParameters(test.in)
443 if !reflect.DeepEqual(f, test.out) {
444 t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out)
449 type TestObjectIdentifierStruct struct {
450 OID ObjectIdentifier
453 type TestContextSpecificTags struct {
454 A int `asn1:"tag:1"`
457 type TestContextSpecificTags2 struct {
458 A int `asn1:"explicit,tag:1"`
459 B int
462 type TestContextSpecificTags3 struct {
463 S string `asn1:"tag:1,utf8"`
466 type TestElementsAfterString struct {
467 S string
468 A, B int
471 type TestBigInt struct {
472 X *big.Int
475 type TestSet struct {
476 Ints []int `asn1:"set"`
479 var unmarshalTestData = []struct {
480 in []byte
481 out interface{}
483 {[]byte{0x02, 0x01, 0x42}, newInt(0x42)},
484 {[]byte{0x05, 0x00}, &RawValue{0, 5, false, []byte{}, []byte{0x05, 0x00}}},
485 {[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}},
486 {[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}},
487 {[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}},
488 {[]byte{0x02, 0x01, 0x10}, newInt(16)},
489 {[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")},
490 {[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")},
491 // Ampersand is allowed in PrintableString due to mistakes by major CAs.
492 {[]byte{0x13, 0x05, 't', 'e', 's', 't', '&'}, newString("test&")},
493 {[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}},
494 {[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}},
495 {[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}},
496 {[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}},
497 {[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}},
498 {[]byte{0x01, 0x01, 0x00}, newBool(false)},
499 {[]byte{0x01, 0x01, 0xff}, newBool(true)},
500 {[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}},
501 {[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}},
502 {[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}},
503 {[]byte{0x12, 0x0b, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' '}, newString("0123456789 ")},
506 func TestUnmarshal(t *testing.T) {
507 for i, test := range unmarshalTestData {
508 pv := reflect.New(reflect.TypeOf(test.out).Elem())
509 val := pv.Interface()
510 _, err := Unmarshal(test.in, val)
511 if err != nil {
512 t.Errorf("Unmarshal failed at index %d %v", i, err)
514 if !reflect.DeepEqual(val, test.out) {
515 t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out)
520 type Certificate struct {
521 TBSCertificate TBSCertificate
522 SignatureAlgorithm AlgorithmIdentifier
523 SignatureValue BitString
526 type TBSCertificate struct {
527 Version int `asn1:"optional,explicit,default:0,tag:0"`
528 SerialNumber RawValue
529 SignatureAlgorithm AlgorithmIdentifier
530 Issuer RDNSequence
531 Validity Validity
532 Subject RDNSequence
533 PublicKey PublicKeyInfo
536 type AlgorithmIdentifier struct {
537 Algorithm ObjectIdentifier
540 type RDNSequence []RelativeDistinguishedNameSET
542 type RelativeDistinguishedNameSET []AttributeTypeAndValue
544 type AttributeTypeAndValue struct {
545 Type ObjectIdentifier
546 Value interface{}
549 type Validity struct {
550 NotBefore, NotAfter time.Time
553 type PublicKeyInfo struct {
554 Algorithm AlgorithmIdentifier
555 PublicKey BitString
558 func TestCertificate(t *testing.T) {
559 // This is a minimal, self-signed certificate that should parse correctly.
560 var cert Certificate
561 if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil {
562 t.Errorf("Unmarshal failed: %v", err)
564 if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) {
565 t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert)
569 func TestCertificateWithNUL(t *testing.T) {
570 // This is the paypal NUL-hack certificate. It should fail to parse because
571 // NUL isn't a permitted character in a PrintableString.
573 var cert Certificate
574 if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil {
575 t.Error("Unmarshal succeeded, should not have")
579 type rawStructTest struct {
580 Raw RawContent
581 A int
584 func TestRawStructs(t *testing.T) {
585 var s rawStructTest
586 input := []byte{0x30, 0x03, 0x02, 0x01, 0x50}
588 rest, err := Unmarshal(input, &s)
589 if len(rest) != 0 {
590 t.Errorf("incomplete parse: %x", rest)
591 return
593 if err != nil {
594 t.Error(err)
595 return
597 if s.A != 0x50 {
598 t.Errorf("bad value for A: got %d want %d", s.A, 0x50)
600 if !bytes.Equal([]byte(s.Raw), input) {
601 t.Errorf("bad value for Raw: got %x want %x", s.Raw, input)
605 type oiEqualTest struct {
606 first ObjectIdentifier
607 second ObjectIdentifier
608 same bool
611 var oiEqualTests = []oiEqualTest{
613 ObjectIdentifier{1, 2, 3},
614 ObjectIdentifier{1, 2, 3},
615 true,
618 ObjectIdentifier{1},
619 ObjectIdentifier{1, 2, 3},
620 false,
623 ObjectIdentifier{1, 2, 3},
624 ObjectIdentifier{10, 11, 12},
625 false,
629 func TestObjectIdentifierEqual(t *testing.T) {
630 for _, o := range oiEqualTests {
631 if s := o.first.Equal(o.second); s != o.same {
632 t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same)
637 var derEncodedSelfSignedCert = Certificate{
638 TBSCertificate: TBSCertificate{
639 Version: 0,
640 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}},
641 SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
642 Issuer: RDNSequence{
643 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
644 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
645 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
646 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
647 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
648 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
650 Validity: Validity{
651 NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC),
652 NotAfter: time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC),
654 Subject: RDNSequence{
655 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}},
656 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}},
657 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}},
658 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}},
659 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}},
660 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}},
662 PublicKey: PublicKeyInfo{
663 Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}},
664 PublicKey: BitString{
665 Bytes: []uint8{
666 0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7,
667 0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42,
668 0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4,
669 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2,
670 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f,
671 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec,
672 0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1,
674 BitLength: 592,
678 SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}},
679 SignatureValue: BitString{
680 Bytes: []uint8{
681 0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce,
682 0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c,
683 0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b,
684 0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8,
685 0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa,
686 0xfa, 0x88, 0x21, 0x49, 0x4, 0x35,
688 BitLength: 512,
692 var derEncodedSelfSignedCertBytes = []byte{
693 0x30, 0x82, 0x02, 0x18, 0x30,
694 0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c,
695 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01,
696 0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
697 0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55,
698 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74,
699 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43,
700 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13,
701 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64,
702 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31,
703 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c,
704 0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f,
705 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d,
706 0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78,
707 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d,
708 0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a,
709 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35,
710 0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04,
711 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04,
712 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65,
713 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69,
714 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18,
715 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67,
716 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a,
717 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73,
718 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d,
719 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01,
720 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61,
721 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06,
722 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03,
723 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78,
724 0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c,
725 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea,
726 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88,
727 0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45,
728 0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d,
729 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00,
730 0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4,
731 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd,
732 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4,
733 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14,
734 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49,
735 0x04, 0x35,
738 var derEncodedPaypalNULCertBytes = []byte{
739 0x30, 0x82, 0x06, 0x44, 0x30,
740 0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b,
741 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
742 0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55,
743 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55,
744 0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61,
745 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61,
746 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03,
747 0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74,
748 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74,
749 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e,
750 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65,
751 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d,
752 0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36,
753 0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03,
754 0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c,
755 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69,
756 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72,
757 0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13,
758 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
759 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69,
760 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31,
761 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09,
762 0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70,
763 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39,
764 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d,
765 0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a,
766 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13,
767 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13,
768 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16,
769 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20,
770 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f,
771 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69,
772 0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b,
773 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f,
774 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e,
775 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73,
776 0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65,
777 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d,
778 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00,
779 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69,
780 0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19,
781 0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e,
782 0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29,
783 0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41,
784 0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce,
785 0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96,
786 0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2,
787 0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10,
788 0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49,
789 0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00,
790 0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03,
791 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86,
792 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40,
793 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8,
794 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08,
795 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55,
796 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14,
797 0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e,
798 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14,
799 0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8,
800 0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d,
801 0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04,
802 0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40,
803 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09,
804 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63,
805 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20,
806 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e,
807 0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e,
808 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76,
809 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74,
810 0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68,
811 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
812 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60,
813 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68,
814 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70,
815 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
816 0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01,
817 0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70,
818 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61,
819 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30,
820 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c,
821 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09,
822 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37,
823 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69,
824 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
825 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74,
826 0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74,
827 0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8,
828 0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a,
829 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63,
830 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f,
831 0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41,
832 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86,
833 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74,
834 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73,
835 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32,
836 0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41,
837 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06,
838 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0,
839 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77,
840 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70,
841 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61,
842 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63,
843 0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74,
844 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69,
845 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63,
846 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30,
847 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c,
848 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04,
849 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07,
850 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63,
851 0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f,
852 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05,
853 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b,
854 0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa,
855 0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e,
856 0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d,
857 0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7,
858 0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1,
859 0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5,
860 0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07,
861 0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e,
862 0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43,
863 0x96, 0x07, 0xa8, 0xbb,
866 var stringSliceTestData = [][]string{
867 {"foo", "bar"},
868 {"foo", "\\bar"},
869 {"foo", "\"bar\""},
870 {"foo", "åäö"},
873 func TestStringSlice(t *testing.T) {
874 for _, test := range stringSliceTestData {
875 bs, err := Marshal(test)
876 if err != nil {
877 t.Error(err)
880 var res []string
881 _, err = Unmarshal(bs, &res)
882 if err != nil {
883 t.Error(err)
886 if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) {
887 t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test)
892 type explicitTaggedTimeTest struct {
893 Time time.Time `asn1:"explicit,tag:0"`
896 var explicitTaggedTimeTestData = []struct {
897 in []byte
898 out explicitTaggedTimeTest
900 {[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'},
901 explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}},
902 {[]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'},
903 explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}},
906 func TestExplicitTaggedTime(t *testing.T) {
907 // Test that a time.Time will match either tagUTCTime or
908 // tagGeneralizedTime.
909 for i, test := range explicitTaggedTimeTestData {
910 var got explicitTaggedTimeTest
911 _, err := Unmarshal(test.in, &got)
912 if err != nil {
913 t.Errorf("Unmarshal failed at index %d %v", i, err)
915 if !got.Time.Equal(test.out.Time) {
916 t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time)
921 type implicitTaggedTimeTest struct {
922 Time time.Time `asn1:"tag:24"`
925 func TestImplicitTaggedTime(t *testing.T) {
926 // An implicitly tagged time value, that happens to have an implicit
927 // tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime.
928 // (There's no "timeType" in fieldParameters to determine what type of
929 // time should be expected when implicitly tagged.)
930 der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}
931 var result implicitTaggedTimeTest
932 if _, err := Unmarshal(der, &result); err != nil {
933 t.Fatalf("Error while parsing: %s", err)
935 if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) {
936 t.Errorf("Wrong result. Got %v, want %v", result.Time, expected)
940 type truncatedExplicitTagTest struct {
941 Test int `asn1:"explicit,tag:0"`
944 func TestTruncatedExplicitTag(t *testing.T) {
945 // This crashed Unmarshal in the past. See #11154.
946 der := []byte{
947 0x30, // SEQUENCE
948 0x02, // two bytes long
949 0xa0, // context-specific, tag 0
950 0x30, // 48 bytes long
953 var result truncatedExplicitTagTest
954 if _, err := Unmarshal(der, &result); err == nil {
955 t.Error("Unmarshal returned without error")
959 type invalidUTF8Test struct {
960 Str string `asn1:"utf8"`
963 func TestUnmarshalInvalidUTF8(t *testing.T) {
964 data := []byte("0\x05\f\x03a\xc9c")
965 var result invalidUTF8Test
966 _, err := Unmarshal(data, &result)
968 const expectedSubstring = "UTF"
969 if err == nil {
970 t.Fatal("Successfully unmarshaled invalid UTF-8 data")
971 } else if !strings.Contains(err.Error(), expectedSubstring) {
972 t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error())
976 func TestMarshalNilValue(t *testing.T) {
977 nilValueTestData := []interface{}{
978 nil,
979 struct{ V interface{} }{},
981 for i, test := range nilValueTestData {
982 if _, err := Marshal(test); err == nil {
983 t.Fatalf("#%d: successfully marshaled nil value", i)
988 type unexported struct {
989 X int
990 y int
993 type exported struct {
994 X int
995 Y int
998 func TestUnexportedStructField(t *testing.T) {
999 want := StructuralError{"struct contains unexported fields"}
1001 _, err := Marshal(unexported{X: 5, y: 1})
1002 if err != want {
1003 t.Errorf("got %v, want %v", err, want)
1006 bs, err := Marshal(exported{X: 5, Y: 1})
1007 if err != nil {
1008 t.Fatal(err)
1010 var u unexported
1011 _, err = Unmarshal(bs, &u)
1012 if err != want {
1013 t.Errorf("got %v, want %v", err, want)
1017 func TestNull(t *testing.T) {
1018 marshaled, err := Marshal(NullRawValue)
1019 if err != nil {
1020 t.Fatal(err)
1022 if !bytes.Equal(NullBytes, marshaled) {
1023 t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled)
1026 unmarshaled := RawValue{}
1027 if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil {
1028 t.Fatal(err)
1031 unmarshaled.FullBytes = NullRawValue.FullBytes
1032 if len(unmarshaled.Bytes) == 0 {
1033 // DeepEqual considers a nil slice and an empty slice to be different.
1034 unmarshaled.Bytes = NullRawValue.Bytes
1037 if !reflect.DeepEqual(NullRawValue, unmarshaled) {
1038 t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled)
1042 func TestExplicitTagRawValueStruct(t *testing.T) {
1043 type foo struct {
1044 A RawValue `asn1:"optional,explicit,tag:5"`
1045 B []byte `asn1:"optional,explicit,tag:6"`
1047 before := foo{B: []byte{1, 2, 3}}
1048 derBytes, err := Marshal(before)
1049 if err != nil {
1050 t.Fatal(err)
1053 var after foo
1054 if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 {
1055 t.Fatal(err)
1058 got := fmt.Sprintf("%#v", after)
1059 want := fmt.Sprintf("%#v", before)
1060 if got != want {
1061 t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes)
1065 func TestTaggedRawValue(t *testing.T) {
1066 type taggedRawValue struct {
1067 A RawValue `asn1:"tag:5"`
1069 type untaggedRawValue struct {
1070 A RawValue
1072 const isCompound = 0x20
1073 const tag = 5
1075 tests := []struct {
1076 shouldMatch bool
1077 derBytes []byte
1079 {false, []byte{0x30, 3, TagInteger, 1, 1}},
1080 {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}},
1081 {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}},
1082 {false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}},
1083 {false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}},
1086 for i, test := range tests {
1087 var tagged taggedRawValue
1088 if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch {
1089 t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err)
1092 // An untagged RawValue should accept anything.
1093 var untagged untaggedRawValue
1094 if _, err := Unmarshal(test.derBytes, &untagged); err != nil {
1095 t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err)