github.com/c12o16h1/go/src@v0.0.0-20200114212001-5a151c0f00ed/encoding/asn1/asn1_test.go (about) 1 // Copyright 2009 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package asn1 6 7 import ( 8 "bytes" 9 "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 // has base type[]int 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 /* These are invalid times. However, the time package normalises times 282 * and they were accepted in some versions. See #11134. */ 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" // ignore zone name, just offset 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 /* These are invalid times. However, the time package normalises times 329 * and they were accepted in some versions. See #11134. */ 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 // Superfluous zeros in the length should be an error. 382 {[]byte{0xa0, 0x82, 0x00, 0xff}, false, tagAndLength{}}, 383 // Lengths up to the maximum size of an int should work. 384 {[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}}, 385 // Lengths that would overflow an int should be rejected. 386 {[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}}, 387 // Long length form may not be used for lengths that fit in short form. 388 {[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}}, 389 // Tag numbers which would overflow int32 are rejected. (The value below is 2^31.) 390 {[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}}, 391 // Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.) 392 {[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}}, 393 // Long tag number form may not be used for tags that fit in short form. 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 // Ampersand is allowed in PrintableString due to mistakes by major CAs. 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 type Certificate struct { 522 TBSCertificate TBSCertificate 523 SignatureAlgorithm AlgorithmIdentifier 524 SignatureValue BitString 525 } 526 527 type TBSCertificate struct { 528 Version int `asn1:"optional,explicit,default:0,tag:0"` 529 SerialNumber RawValue 530 SignatureAlgorithm AlgorithmIdentifier 531 Issuer RDNSequence 532 Validity Validity 533 Subject RDNSequence 534 PublicKey PublicKeyInfo 535 } 536 537 type AlgorithmIdentifier struct { 538 Algorithm ObjectIdentifier 539 } 540 541 type RDNSequence []RelativeDistinguishedNameSET 542 543 type RelativeDistinguishedNameSET []AttributeTypeAndValue 544 545 type AttributeTypeAndValue struct { 546 Type ObjectIdentifier 547 Value interface{} 548 } 549 550 type Validity struct { 551 NotBefore, NotAfter time.Time 552 } 553 554 type PublicKeyInfo struct { 555 Algorithm AlgorithmIdentifier 556 PublicKey BitString 557 } 558 559 func TestCertificate(t *testing.T) { 560 // This is a minimal, self-signed certificate that should parse correctly. 561 var cert Certificate 562 if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil { 563 t.Errorf("Unmarshal failed: %v", err) 564 } 565 if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) { 566 t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert) 567 } 568 } 569 570 func TestCertificateWithNUL(t *testing.T) { 571 // This is the paypal NUL-hack certificate. It should fail to parse because 572 // NUL isn't a permitted character in a PrintableString. 573 574 var cert Certificate 575 if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil { 576 t.Error("Unmarshal succeeded, should not have") 577 } 578 } 579 580 type rawStructTest struct { 581 Raw RawContent 582 A int 583 } 584 585 func TestRawStructs(t *testing.T) { 586 var s rawStructTest 587 input := []byte{0x30, 0x03, 0x02, 0x01, 0x50} 588 589 rest, err := Unmarshal(input, &s) 590 if len(rest) != 0 { 591 t.Errorf("incomplete parse: %x", rest) 592 return 593 } 594 if err != nil { 595 t.Error(err) 596 return 597 } 598 if s.A != 0x50 { 599 t.Errorf("bad value for A: got %d want %d", s.A, 0x50) 600 } 601 if !bytes.Equal([]byte(s.Raw), input) { 602 t.Errorf("bad value for Raw: got %x want %x", s.Raw, input) 603 } 604 } 605 606 type oiEqualTest struct { 607 first ObjectIdentifier 608 second ObjectIdentifier 609 same bool 610 } 611 612 var oiEqualTests = []oiEqualTest{ 613 { 614 ObjectIdentifier{1, 2, 3}, 615 ObjectIdentifier{1, 2, 3}, 616 true, 617 }, 618 { 619 ObjectIdentifier{1}, 620 ObjectIdentifier{1, 2, 3}, 621 false, 622 }, 623 { 624 ObjectIdentifier{1, 2, 3}, 625 ObjectIdentifier{10, 11, 12}, 626 false, 627 }, 628 } 629 630 func TestObjectIdentifierEqual(t *testing.T) { 631 for _, o := range oiEqualTests { 632 if s := o.first.Equal(o.second); s != o.same { 633 t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same) 634 } 635 } 636 } 637 638 var derEncodedSelfSignedCert = Certificate{ 639 TBSCertificate: TBSCertificate{ 640 Version: 0, 641 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}}, 642 SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}}, 643 Issuer: RDNSequence{ 644 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}}, 645 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}}, 646 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}}, 647 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}}, 648 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}}, 649 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}}, 650 }, 651 Validity: Validity{ 652 NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC), 653 NotAfter: time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC), 654 }, 655 Subject: RDNSequence{ 656 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}}, 657 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}}, 658 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}}, 659 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}}, 660 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}}, 661 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}}, 662 }, 663 PublicKey: PublicKeyInfo{ 664 Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}}, 665 PublicKey: BitString{ 666 Bytes: []uint8{ 667 0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7, 668 0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 669 0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 670 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 671 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f, 672 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec, 673 0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1, 674 }, 675 BitLength: 592, 676 }, 677 }, 678 }, 679 SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}}, 680 SignatureValue: BitString{ 681 Bytes: []uint8{ 682 0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce, 683 0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 684 0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b, 685 0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 686 0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 687 0xfa, 0x88, 0x21, 0x49, 0x4, 0x35, 688 }, 689 BitLength: 512, 690 }, 691 } 692 693 var derEncodedSelfSignedCertBytes = []byte{ 694 0x30, 0x82, 0x02, 0x18, 0x30, 695 0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 696 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 697 0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 698 0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 699 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 700 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 701 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 702 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 703 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 704 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 705 0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 706 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 707 0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 708 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 709 0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a, 710 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 711 0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 712 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 713 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 714 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69, 715 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 716 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 717 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a, 718 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73, 719 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 720 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 721 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61, 722 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 723 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 724 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78, 725 0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c, 726 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 727 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 728 0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 729 0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 730 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 731 0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4, 732 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd, 733 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4, 734 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14, 735 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49, 736 0x04, 0x35, 737 } 738 739 var derEncodedPaypalNULCertBytes = []byte{ 740 0x30, 0x82, 0x06, 0x44, 0x30, 741 0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b, 742 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 743 0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 744 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 745 0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 746 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61, 747 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 748 0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74, 749 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 750 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e, 751 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65, 752 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 753 0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36, 754 0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 755 0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 756 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 757 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 758 0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 759 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 760 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 761 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 762 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 763 0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 764 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 765 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d, 766 0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 767 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 768 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 769 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 770 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20, 771 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f, 772 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 773 0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b, 774 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f, 775 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e, 776 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73, 777 0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 778 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d, 779 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 780 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69, 781 0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19, 782 0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e, 783 0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29, 784 0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41, 785 0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce, 786 0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96, 787 0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2, 788 0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10, 789 0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49, 790 0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00, 791 0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03, 792 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 793 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 794 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8, 795 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 796 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 797 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14, 798 0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e, 799 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 800 0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8, 801 0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 802 0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04, 803 0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 804 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09, 805 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63, 806 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 807 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 808 0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e, 809 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76, 810 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 811 0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 0x20, 0x68, 812 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 813 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x30, 0x2f, 0x06, 0x09, 0x60, 814 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68, 815 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 816 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 817 0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 818 0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 819 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 820 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 821 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 822 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09, 823 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37, 824 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 825 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 826 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 827 0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 828 0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 829 0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 830 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 831 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 832 0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 833 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86, 834 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74, 835 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 836 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 837 0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41, 838 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06, 839 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0, 840 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 841 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 842 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 843 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 844 0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74, 845 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69, 846 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 847 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 848 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 849 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 850 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 851 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 852 0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 853 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 854 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b, 855 0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa, 856 0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e, 857 0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d, 858 0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7, 859 0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1, 860 0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5, 861 0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07, 862 0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e, 863 0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43, 864 0x96, 0x07, 0xa8, 0xbb, 865 } 866 867 var stringSliceTestData = [][]string{ 868 {"foo", "bar"}, 869 {"foo", "\\bar"}, 870 {"foo", "\"bar\""}, 871 {"foo", "åäö"}, 872 } 873 874 func TestStringSlice(t *testing.T) { 875 for _, test := range stringSliceTestData { 876 bs, err := Marshal(test) 877 if err != nil { 878 t.Error(err) 879 } 880 881 var res []string 882 _, err = Unmarshal(bs, &res) 883 if err != nil { 884 t.Error(err) 885 } 886 887 if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) { 888 t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test) 889 } 890 } 891 } 892 893 type explicitTaggedTimeTest struct { 894 Time time.Time `asn1:"explicit,tag:0"` 895 } 896 897 var explicitTaggedTimeTestData = []struct { 898 in []byte 899 out explicitTaggedTimeTest 900 }{ 901 {[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}, 902 explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}}, 903 {[]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'}, 904 explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}}, 905 } 906 907 func TestExplicitTaggedTime(t *testing.T) { 908 // Test that a time.Time will match either tagUTCTime or 909 // tagGeneralizedTime. 910 for i, test := range explicitTaggedTimeTestData { 911 var got explicitTaggedTimeTest 912 _, err := Unmarshal(test.in, &got) 913 if err != nil { 914 t.Errorf("Unmarshal failed at index %d %v", i, err) 915 } 916 if !got.Time.Equal(test.out.Time) { 917 t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time) 918 } 919 } 920 } 921 922 type implicitTaggedTimeTest struct { 923 Time time.Time `asn1:"tag:24"` 924 } 925 926 func TestImplicitTaggedTime(t *testing.T) { 927 // An implicitly tagged time value, that happens to have an implicit 928 // tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime. 929 // (There's no "timeType" in fieldParameters to determine what type of 930 // time should be expected when implicitly tagged.) 931 der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'} 932 var result implicitTaggedTimeTest 933 if _, err := Unmarshal(der, &result); err != nil { 934 t.Fatalf("Error while parsing: %s", err) 935 } 936 if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) { 937 t.Errorf("Wrong result. Got %v, want %v", result.Time, expected) 938 } 939 } 940 941 type truncatedExplicitTagTest struct { 942 Test int `asn1:"explicit,tag:0"` 943 } 944 945 func TestTruncatedExplicitTag(t *testing.T) { 946 // This crashed Unmarshal in the past. See #11154. 947 der := []byte{ 948 0x30, // SEQUENCE 949 0x02, // two bytes long 950 0xa0, // context-specific, tag 0 951 0x30, // 48 bytes long 952 } 953 954 var result truncatedExplicitTagTest 955 if _, err := Unmarshal(der, &result); err == nil { 956 t.Error("Unmarshal returned without error") 957 } 958 } 959 960 type invalidUTF8Test struct { 961 Str string `asn1:"utf8"` 962 } 963 964 func TestUnmarshalInvalidUTF8(t *testing.T) { 965 data := []byte("0\x05\f\x03a\xc9c") 966 var result invalidUTF8Test 967 _, err := Unmarshal(data, &result) 968 969 const expectedSubstring = "UTF" 970 if err == nil { 971 t.Fatal("Successfully unmarshaled invalid UTF-8 data") 972 } else if !strings.Contains(err.Error(), expectedSubstring) { 973 t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error()) 974 } 975 } 976 977 func TestMarshalNilValue(t *testing.T) { 978 nilValueTestData := []interface{}{ 979 nil, 980 struct{ V interface{} }{}, 981 } 982 for i, test := range nilValueTestData { 983 if _, err := Marshal(test); err == nil { 984 t.Fatalf("#%d: successfully marshaled nil value", i) 985 } 986 } 987 } 988 989 type unexported struct { 990 X int 991 y int 992 } 993 994 type exported struct { 995 X int 996 Y int 997 } 998 999 func TestUnexportedStructField(t *testing.T) { 1000 want := StructuralError{"struct contains unexported fields"} 1001 1002 _, err := Marshal(unexported{X: 5, y: 1}) 1003 if err != want { 1004 t.Errorf("got %v, want %v", err, want) 1005 } 1006 1007 bs, err := Marshal(exported{X: 5, Y: 1}) 1008 if err != nil { 1009 t.Fatal(err) 1010 } 1011 var u unexported 1012 _, err = Unmarshal(bs, &u) 1013 if err != want { 1014 t.Errorf("got %v, want %v", err, want) 1015 } 1016 } 1017 1018 func TestNull(t *testing.T) { 1019 marshaled, err := Marshal(NullRawValue) 1020 if err != nil { 1021 t.Fatal(err) 1022 } 1023 if !bytes.Equal(NullBytes, marshaled) { 1024 t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled) 1025 } 1026 1027 unmarshaled := RawValue{} 1028 if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil { 1029 t.Fatal(err) 1030 } 1031 1032 unmarshaled.FullBytes = NullRawValue.FullBytes 1033 if len(unmarshaled.Bytes) == 0 { 1034 // DeepEqual considers a nil slice and an empty slice to be different. 1035 unmarshaled.Bytes = NullRawValue.Bytes 1036 } 1037 1038 if !reflect.DeepEqual(NullRawValue, unmarshaled) { 1039 t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled) 1040 } 1041 } 1042 1043 func TestExplicitTagRawValueStruct(t *testing.T) { 1044 type foo struct { 1045 A RawValue `asn1:"optional,explicit,tag:5"` 1046 B []byte `asn1:"optional,explicit,tag:6"` 1047 } 1048 before := foo{B: []byte{1, 2, 3}} 1049 derBytes, err := Marshal(before) 1050 if err != nil { 1051 t.Fatal(err) 1052 } 1053 1054 var after foo 1055 if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 { 1056 t.Fatal(err) 1057 } 1058 1059 got := fmt.Sprintf("%#v", after) 1060 want := fmt.Sprintf("%#v", before) 1061 if got != want { 1062 t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes) 1063 } 1064 } 1065 1066 func TestTaggedRawValue(t *testing.T) { 1067 type taggedRawValue struct { 1068 A RawValue `asn1:"tag:5"` 1069 } 1070 type untaggedRawValue struct { 1071 A RawValue 1072 } 1073 const isCompound = 0x20 1074 const tag = 5 1075 1076 tests := []struct { 1077 shouldMatch bool 1078 derBytes []byte 1079 }{ 1080 {false, []byte{0x30, 3, TagInteger, 1, 1}}, 1081 {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}}, 1082 {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}}, 1083 {false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}}, 1084 {false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}}, 1085 } 1086 1087 for i, test := range tests { 1088 var tagged taggedRawValue 1089 if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch { 1090 t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err) 1091 } 1092 1093 // An untagged RawValue should accept anything. 1094 var untagged untaggedRawValue 1095 if _, err := Unmarshal(test.derBytes, &untagged); err != nil { 1096 t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err) 1097 } 1098 } 1099 } 1100 1101 var bmpStringTests = []struct { 1102 decoded string 1103 encodedHex string 1104 }{ 1105 {"", "0000"}, 1106 // Example from https://tools.ietf.org/html/rfc7292#appendix-B. 1107 {"Beavis", "0042006500610076006900730000"}, 1108 // Some characters from the "Letterlike Symbols Unicode block". 1109 {"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000"}, 1110 } 1111 1112 func TestBMPString(t *testing.T) { 1113 for i, test := range bmpStringTests { 1114 encoded, err := hex.DecodeString(test.encodedHex) 1115 if err != nil { 1116 t.Fatalf("#%d: failed to decode from hex string", i) 1117 } 1118 1119 decoded, err := parseBMPString(encoded) 1120 1121 if err != nil { 1122 t.Errorf("#%d: decoding output gave an error: %s", i, err) 1123 continue 1124 } 1125 1126 if decoded != test.decoded { 1127 t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, decoded, test.decoded) 1128 continue 1129 } 1130 } 1131 }