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