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