github.com/twelsh-aw/go/src@v0.0.0-20230516233729-a56fe86a7c81/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 && 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.123456Z", true, time.Date(2010, 01, 02, 03, 04, 05, 123456e3, time.UTC)}, 327 {"20100102030405.123456", false, time.Time{}}, 328 {"20100102030405.Z", false, time.Time{}}, 329 {"20100102030405.", false, time.Time{}}, 330 {"20100102030405+0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}, 331 {"20100102030405-0607", true, time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", -6*60*60-7*60))}, 332 /* These are invalid times. However, the time package normalises times 333 * and they were accepted in some versions. See #11134. */ 334 {"00000100000000Z", false, time.Time{}}, 335 {"20101302030405Z", false, time.Time{}}, 336 {"20100002030405Z", false, time.Time{}}, 337 {"20100100030405Z", false, time.Time{}}, 338 {"20100132030405Z", false, time.Time{}}, 339 {"20100231030405Z", false, time.Time{}}, 340 {"20100102240405Z", false, time.Time{}}, 341 {"20100102036005Z", false, time.Time{}}, 342 {"20100102030460Z", false, time.Time{}}, 343 {"-20100102030410Z", false, time.Time{}}, 344 {"2010-0102030410Z", false, time.Time{}}, 345 {"2010-0002030410Z", false, time.Time{}}, 346 {"201001-02030410Z", false, time.Time{}}, 347 {"20100102-030410Z", false, time.Time{}}, 348 {"2010010203-0410Z", false, time.Time{}}, 349 {"201001020304-10Z", false, time.Time{}}, 350 } 351 352 func TestGeneralizedTime(t *testing.T) { 353 for i, test := range generalizedTimeTestData { 354 ret, err := parseGeneralizedTime([]byte(test.in)) 355 if (err == nil) != test.ok { 356 t.Errorf("#%d: Incorrect error result (did fail? %v, expected: %v)", i, err == nil, test.ok) 357 } 358 if err == nil { 359 if !reflect.DeepEqual(test.out, ret) { 360 t.Errorf("#%d: Bad result: %q → %v (expected %v)", i, test.in, ret, test.out) 361 } 362 } 363 } 364 } 365 366 type tagAndLengthTest struct { 367 in []byte 368 ok bool 369 out tagAndLength 370 } 371 372 var tagAndLengthData = []tagAndLengthTest{ 373 {[]byte{0x80, 0x01}, true, tagAndLength{2, 0, 1, false}}, 374 {[]byte{0xa0, 0x01}, true, tagAndLength{2, 0, 1, true}}, 375 {[]byte{0x02, 0x00}, true, tagAndLength{0, 2, 0, false}}, 376 {[]byte{0xfe, 0x00}, true, tagAndLength{3, 30, 0, true}}, 377 {[]byte{0x1f, 0x1f, 0x00}, true, tagAndLength{0, 31, 0, false}}, 378 {[]byte{0x1f, 0x81, 0x00, 0x00}, true, tagAndLength{0, 128, 0, false}}, 379 {[]byte{0x1f, 0x81, 0x80, 0x01, 0x00}, true, tagAndLength{0, 0x4001, 0, false}}, 380 {[]byte{0x00, 0x81, 0x80}, true, tagAndLength{0, 0, 128, false}}, 381 {[]byte{0x00, 0x82, 0x01, 0x00}, true, tagAndLength{0, 0, 256, false}}, 382 {[]byte{0x00, 0x83, 0x01, 0x00}, false, tagAndLength{}}, 383 {[]byte{0x1f, 0x85}, false, tagAndLength{}}, 384 {[]byte{0x30, 0x80}, false, tagAndLength{}}, 385 // Superfluous zeros in the length should be an error. 386 {[]byte{0xa0, 0x82, 0x00, 0xff}, false, tagAndLength{}}, 387 // Lengths up to the maximum size of an int should work. 388 {[]byte{0xa0, 0x84, 0x7f, 0xff, 0xff, 0xff}, true, tagAndLength{2, 0, 0x7fffffff, true}}, 389 // Lengths that would overflow an int should be rejected. 390 {[]byte{0xa0, 0x84, 0x80, 0x00, 0x00, 0x00}, false, tagAndLength{}}, 391 // Long length form may not be used for lengths that fit in short form. 392 {[]byte{0xa0, 0x81, 0x7f}, false, tagAndLength{}}, 393 // Tag numbers which would overflow int32 are rejected. (The value below is 2^31.) 394 {[]byte{0x1f, 0x88, 0x80, 0x80, 0x80, 0x00, 0x00}, false, tagAndLength{}}, 395 // Tag numbers that fit in an int32 are valid. (The value below is 2^31 - 1.) 396 {[]byte{0x1f, 0x87, 0xFF, 0xFF, 0xFF, 0x7F, 0x00}, true, tagAndLength{tag: math.MaxInt32}}, 397 // Long tag number form may not be used for tags that fit in short form. 398 {[]byte{0x1f, 0x1e, 0x00}, false, tagAndLength{}}, 399 } 400 401 func TestParseTagAndLength(t *testing.T) { 402 for i, test := range tagAndLengthData { 403 tagAndLength, _, err := parseTagAndLength(test.in, 0) 404 if (err == nil) != test.ok { 405 t.Errorf("#%d: Incorrect error result (did pass? %v, expected: %v)", i, err == nil, test.ok) 406 } 407 if err == nil && !reflect.DeepEqual(test.out, tagAndLength) { 408 t.Errorf("#%d: Bad result: %v (expected %v)", i, tagAndLength, test.out) 409 } 410 } 411 } 412 413 type parseFieldParametersTest struct { 414 in string 415 out fieldParameters 416 } 417 418 func newInt(n int) *int { return &n } 419 420 func newInt64(n int64) *int64 { return &n } 421 422 func newString(s string) *string { return &s } 423 424 func newBool(b bool) *bool { return &b } 425 426 var parseFieldParametersTestData []parseFieldParametersTest = []parseFieldParametersTest{ 427 {"", fieldParameters{}}, 428 {"ia5", fieldParameters{stringType: TagIA5String}}, 429 {"generalized", fieldParameters{timeType: TagGeneralizedTime}}, 430 {"utc", fieldParameters{timeType: TagUTCTime}}, 431 {"printable", fieldParameters{stringType: TagPrintableString}}, 432 {"numeric", fieldParameters{stringType: TagNumericString}}, 433 {"optional", fieldParameters{optional: true}}, 434 {"explicit", fieldParameters{explicit: true, tag: new(int)}}, 435 {"application", fieldParameters{application: true, tag: new(int)}}, 436 {"private", fieldParameters{private: true, tag: new(int)}}, 437 {"optional,explicit", fieldParameters{optional: true, explicit: true, tag: new(int)}}, 438 {"default:42", fieldParameters{defaultValue: newInt64(42)}}, 439 {"tag:17", fieldParameters{tag: newInt(17)}}, 440 {"optional,explicit,default:42,tag:17", fieldParameters{optional: true, explicit: true, defaultValue: newInt64(42), tag: newInt(17)}}, 441 {"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}}, 442 {"set", fieldParameters{set: true}}, 443 } 444 445 func TestParseFieldParameters(t *testing.T) { 446 for i, test := range parseFieldParametersTestData { 447 f := parseFieldParameters(test.in) 448 if !reflect.DeepEqual(f, test.out) { 449 t.Errorf("#%d: Bad result: %v (expected %v)", i, f, test.out) 450 } 451 } 452 } 453 454 type TestObjectIdentifierStruct struct { 455 OID ObjectIdentifier 456 } 457 458 type TestContextSpecificTags struct { 459 A int `asn1:"tag:1"` 460 } 461 462 type TestContextSpecificTags2 struct { 463 A int `asn1:"explicit,tag:1"` 464 B int 465 } 466 467 type TestContextSpecificTags3 struct { 468 S string `asn1:"tag:1,utf8"` 469 } 470 471 type TestElementsAfterString struct { 472 S string 473 A, B int 474 } 475 476 type TestBigInt struct { 477 X *big.Int 478 } 479 480 type TestSet struct { 481 Ints []int `asn1:"set"` 482 } 483 484 var unmarshalTestData = []struct { 485 in []byte 486 out any 487 }{ 488 {[]byte{0x02, 0x01, 0x42}, newInt(0x42)}, 489 {[]byte{0x05, 0x00}, &RawValue{0, 5, false, []byte{}, []byte{0x05, 0x00}}}, 490 {[]byte{0x30, 0x08, 0x06, 0x06, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d}, &TestObjectIdentifierStruct{[]int{1, 2, 840, 113549}}}, 491 {[]byte{0x03, 0x04, 0x06, 0x6e, 0x5d, 0xc0}, &BitString{[]byte{110, 93, 192}, 18}}, 492 {[]byte{0x30, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &[]int{1, 2, 3}}, 493 {[]byte{0x02, 0x01, 0x10}, newInt(16)}, 494 {[]byte{0x13, 0x04, 't', 'e', 's', 't'}, newString("test")}, 495 {[]byte{0x16, 0x04, 't', 'e', 's', 't'}, newString("test")}, 496 // Ampersand is allowed in PrintableString due to mistakes by major CAs. 497 {[]byte{0x13, 0x05, 't', 'e', 's', 't', '&'}, newString("test&")}, 498 {[]byte{0x16, 0x04, 't', 'e', 's', 't'}, &RawValue{0, 22, false, []byte("test"), []byte("\x16\x04test")}}, 499 {[]byte{0x04, 0x04, 1, 2, 3, 4}, &RawValue{0, 4, false, []byte{1, 2, 3, 4}, []byte{4, 4, 1, 2, 3, 4}}}, 500 {[]byte{0x30, 0x03, 0x81, 0x01, 0x01}, &TestContextSpecificTags{1}}, 501 {[]byte{0x30, 0x08, 0xa1, 0x03, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02}, &TestContextSpecificTags2{1, 2}}, 502 {[]byte{0x30, 0x03, 0x81, 0x01, '@'}, &TestContextSpecificTags3{"@"}}, 503 {[]byte{0x01, 0x01, 0x00}, newBool(false)}, 504 {[]byte{0x01, 0x01, 0xff}, newBool(true)}, 505 {[]byte{0x30, 0x0b, 0x13, 0x03, 0x66, 0x6f, 0x6f, 0x02, 0x01, 0x22, 0x02, 0x01, 0x33}, &TestElementsAfterString{"foo", 0x22, 0x33}}, 506 {[]byte{0x30, 0x05, 0x02, 0x03, 0x12, 0x34, 0x56}, &TestBigInt{big.NewInt(0x123456)}}, 507 {[]byte{0x30, 0x0b, 0x31, 0x09, 0x02, 0x01, 0x01, 0x02, 0x01, 0x02, 0x02, 0x01, 0x03}, &TestSet{Ints: []int{1, 2, 3}}}, 508 {[]byte{0x12, 0x0b, '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', ' '}, newString("0123456789 ")}, 509 } 510 511 func TestUnmarshal(t *testing.T) { 512 for i, test := range unmarshalTestData { 513 pv := reflect.New(reflect.TypeOf(test.out).Elem()) 514 val := pv.Interface() 515 _, err := Unmarshal(test.in, val) 516 if err != nil { 517 t.Errorf("Unmarshal failed at index %d %v", i, err) 518 } 519 if !reflect.DeepEqual(val, test.out) { 520 t.Errorf("#%d:\nhave %#v\nwant %#v", i, val, test.out) 521 } 522 } 523 } 524 525 func TestUnmarshalWithNilOrNonPointer(t *testing.T) { 526 tests := []struct { 527 b []byte 528 v any 529 want string 530 }{ 531 {b: []byte{0x05, 0x00}, v: nil, want: "asn1: Unmarshal recipient value is nil"}, 532 {b: []byte{0x05, 0x00}, v: RawValue{}, want: "asn1: Unmarshal recipient value is non-pointer asn1.RawValue"}, 533 {b: []byte{0x05, 0x00}, v: (*RawValue)(nil), want: "asn1: Unmarshal recipient value is nil *asn1.RawValue"}, 534 } 535 536 for _, test := range tests { 537 _, err := Unmarshal(test.b, test.v) 538 if err == nil { 539 t.Errorf("Unmarshal expecting error, got nil") 540 continue 541 } 542 if g, w := err.Error(), test.want; g != w { 543 t.Errorf("InvalidUnmarshalError mismatch\nGot: %q\nWant: %q", g, w) 544 } 545 } 546 } 547 548 type Certificate struct { 549 TBSCertificate TBSCertificate 550 SignatureAlgorithm AlgorithmIdentifier 551 SignatureValue BitString 552 } 553 554 type TBSCertificate struct { 555 Version int `asn1:"optional,explicit,default:0,tag:0"` 556 SerialNumber RawValue 557 SignatureAlgorithm AlgorithmIdentifier 558 Issuer RDNSequence 559 Validity Validity 560 Subject RDNSequence 561 PublicKey PublicKeyInfo 562 } 563 564 type AlgorithmIdentifier struct { 565 Algorithm ObjectIdentifier 566 } 567 568 type RDNSequence []RelativeDistinguishedNameSET 569 570 type RelativeDistinguishedNameSET []AttributeTypeAndValue 571 572 type AttributeTypeAndValue struct { 573 Type ObjectIdentifier 574 Value any 575 } 576 577 type Validity struct { 578 NotBefore, NotAfter time.Time 579 } 580 581 type PublicKeyInfo struct { 582 Algorithm AlgorithmIdentifier 583 PublicKey BitString 584 } 585 586 func TestCertificate(t *testing.T) { 587 // This is a minimal, self-signed certificate that should parse correctly. 588 var cert Certificate 589 if _, err := Unmarshal(derEncodedSelfSignedCertBytes, &cert); err != nil { 590 t.Errorf("Unmarshal failed: %v", err) 591 } 592 if !reflect.DeepEqual(cert, derEncodedSelfSignedCert) { 593 t.Errorf("Bad result:\ngot: %+v\nwant: %+v", cert, derEncodedSelfSignedCert) 594 } 595 } 596 597 func TestCertificateWithNUL(t *testing.T) { 598 // This is the paypal NUL-hack certificate. It should fail to parse because 599 // NUL isn't a permitted character in a PrintableString. 600 601 var cert Certificate 602 if _, err := Unmarshal(derEncodedPaypalNULCertBytes, &cert); err == nil { 603 t.Error("Unmarshal succeeded, should not have") 604 } 605 } 606 607 type rawStructTest struct { 608 Raw RawContent 609 A int 610 } 611 612 func TestRawStructs(t *testing.T) { 613 var s rawStructTest 614 input := []byte{0x30, 0x03, 0x02, 0x01, 0x50} 615 616 rest, err := Unmarshal(input, &s) 617 if len(rest) != 0 { 618 t.Errorf("incomplete parse: %x", rest) 619 return 620 } 621 if err != nil { 622 t.Error(err) 623 return 624 } 625 if s.A != 0x50 { 626 t.Errorf("bad value for A: got %d want %d", s.A, 0x50) 627 } 628 if !bytes.Equal([]byte(s.Raw), input) { 629 t.Errorf("bad value for Raw: got %x want %x", s.Raw, input) 630 } 631 } 632 633 type oiEqualTest struct { 634 first ObjectIdentifier 635 second ObjectIdentifier 636 same bool 637 } 638 639 var oiEqualTests = []oiEqualTest{ 640 { 641 ObjectIdentifier{1, 2, 3}, 642 ObjectIdentifier{1, 2, 3}, 643 true, 644 }, 645 { 646 ObjectIdentifier{1}, 647 ObjectIdentifier{1, 2, 3}, 648 false, 649 }, 650 { 651 ObjectIdentifier{1, 2, 3}, 652 ObjectIdentifier{10, 11, 12}, 653 false, 654 }, 655 } 656 657 func TestObjectIdentifierEqual(t *testing.T) { 658 for _, o := range oiEqualTests { 659 if s := o.first.Equal(o.second); s != o.same { 660 t.Errorf("ObjectIdentifier.Equal: got: %t want: %t", s, o.same) 661 } 662 } 663 } 664 665 var derEncodedSelfSignedCert = Certificate{ 666 TBSCertificate: TBSCertificate{ 667 Version: 0, 668 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}}, 669 SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}}, 670 Issuer: RDNSequence{ 671 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}}, 672 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}}, 673 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}}, 674 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}}, 675 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}}, 676 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}}, 677 }, 678 Validity: Validity{ 679 NotBefore: time.Date(2009, 10, 8, 00, 25, 53, 0, time.UTC), 680 NotAfter: time.Date(2010, 10, 8, 00, 25, 53, 0, time.UTC), 681 }, 682 Subject: RDNSequence{ 683 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 6}, Value: "XX"}}, 684 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 8}, Value: "Some-State"}}, 685 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 7}, Value: "City"}}, 686 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 10}, Value: "Internet Widgits Pty Ltd"}}, 687 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{2, 5, 4, 3}, Value: "false.example.com"}}, 688 RelativeDistinguishedNameSET{AttributeTypeAndValue{Type: ObjectIdentifier{1, 2, 840, 113549, 1, 9, 1}, Value: "false@example.com"}}, 689 }, 690 PublicKey: PublicKeyInfo{ 691 Algorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1}}, 692 PublicKey: BitString{ 693 Bytes: []uint8{ 694 0x30, 0x48, 0x2, 0x41, 0x0, 0xcd, 0xb7, 695 0x63, 0x9c, 0x32, 0x78, 0xf0, 0x6, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 696 0x90, 0x2b, 0x59, 0x2d, 0x8c, 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 697 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 698 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 0x96, 0x57, 0x72, 0x2a, 0x4f, 699 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 0xdc, 0x8f, 0xde, 0xec, 700 0x35, 0x7d, 0x2, 0x3, 0x1, 0x0, 0x1, 701 }, 702 BitLength: 592, 703 }, 704 }, 705 }, 706 SignatureAlgorithm: AlgorithmIdentifier{Algorithm: ObjectIdentifier{1, 2, 840, 113549, 1, 1, 5}}, 707 SignatureValue: BitString{ 708 Bytes: []uint8{ 709 0xa6, 0x7b, 0x6, 0xec, 0x5e, 0xce, 710 0x92, 0x77, 0x2c, 0xa4, 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 711 0x7b, 0x45, 0x11, 0xcd, 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x4, 0x2, 0xdf, 0x2b, 712 0x99, 0x8b, 0xb9, 0xa4, 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 713 0xd9, 0x1e, 0xde, 0x14, 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 714 0xfa, 0x88, 0x21, 0x49, 0x4, 0x35, 715 }, 716 BitLength: 512, 717 }, 718 } 719 720 var derEncodedSelfSignedCertBytes = []byte{ 721 0x30, 0x82, 0x02, 0x18, 0x30, 722 0x82, 0x01, 0xc2, 0x02, 0x09, 0x00, 0x8c, 0xc3, 0x37, 0x92, 0x10, 0xec, 0x2c, 723 0x98, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 724 0x05, 0x05, 0x00, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 725 0x04, 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 726 0x04, 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 727 0x65, 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 728 0x69, 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 729 0x18, 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 730 0x67, 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 731 0x1a, 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 732 0x73, 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 733 0x6d, 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 734 0x01, 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 735 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 736 0x30, 0x39, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 0x33, 0x5a, 737 0x17, 0x0d, 0x31, 0x30, 0x31, 0x30, 0x30, 0x38, 0x30, 0x30, 0x32, 0x35, 0x35, 738 0x33, 0x5a, 0x30, 0x81, 0x92, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 739 0x06, 0x13, 0x02, 0x58, 0x58, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 740 0x08, 0x13, 0x0a, 0x53, 0x6f, 0x6d, 0x65, 0x2d, 0x53, 0x74, 0x61, 0x74, 0x65, 741 0x31, 0x0d, 0x30, 0x0b, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x04, 0x43, 0x69, 742 0x74, 0x79, 0x31, 0x21, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x18, 743 0x49, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x65, 0x74, 0x20, 0x57, 0x69, 0x64, 0x67, 744 0x69, 0x74, 0x73, 0x20, 0x50, 0x74, 0x79, 0x20, 0x4c, 0x74, 0x64, 0x31, 0x1a, 745 0x30, 0x18, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x11, 0x66, 0x61, 0x6c, 0x73, 746 0x65, 0x2e, 0x65, 0x78, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 747 0x31, 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 748 0x09, 0x01, 0x16, 0x11, 0x66, 0x61, 0x6c, 0x73, 0x65, 0x40, 0x65, 0x78, 0x61, 749 0x6d, 0x70, 0x6c, 0x65, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x5c, 0x30, 0x0d, 0x06, 750 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 751 0x4b, 0x00, 0x30, 0x48, 0x02, 0x41, 0x00, 0xcd, 0xb7, 0x63, 0x9c, 0x32, 0x78, 752 0xf0, 0x06, 0xaa, 0x27, 0x7f, 0x6e, 0xaf, 0x42, 0x90, 0x2b, 0x59, 0x2d, 0x8c, 753 0xbc, 0xbe, 0x38, 0xa1, 0xc9, 0x2b, 0xa4, 0x69, 0x5a, 0x33, 0x1b, 0x1d, 0xea, 754 0xde, 0xad, 0xd8, 0xe9, 0xa5, 0xc2, 0x7e, 0x8c, 0x4c, 0x2f, 0xd0, 0xa8, 0x88, 755 0x96, 0x57, 0x72, 0x2a, 0x4f, 0x2a, 0xf7, 0x58, 0x9c, 0xf2, 0xc7, 0x70, 0x45, 756 0xdc, 0x8f, 0xde, 0xec, 0x35, 0x7d, 0x02, 0x03, 0x01, 0x00, 0x01, 0x30, 0x0d, 757 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 758 0x03, 0x41, 0x00, 0xa6, 0x7b, 0x06, 0xec, 0x5e, 0xce, 0x92, 0x77, 0x2c, 0xa4, 759 0x13, 0xcb, 0xa3, 0xca, 0x12, 0x56, 0x8f, 0xdc, 0x6c, 0x7b, 0x45, 0x11, 0xcd, 760 0x40, 0xa7, 0xf6, 0x59, 0x98, 0x04, 0x02, 0xdf, 0x2b, 0x99, 0x8b, 0xb9, 0xa4, 761 0xa8, 0xcb, 0xeb, 0x34, 0xc0, 0xf0, 0xa7, 0x8c, 0xf8, 0xd9, 0x1e, 0xde, 0x14, 762 0xa5, 0xed, 0x76, 0xbf, 0x11, 0x6f, 0xe3, 0x60, 0xaa, 0xfa, 0x88, 0x21, 0x49, 763 0x04, 0x35, 764 } 765 766 var derEncodedPaypalNULCertBytes = []byte{ 767 0x30, 0x82, 0x06, 0x44, 0x30, 768 0x82, 0x05, 0xad, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x03, 0x00, 0xf0, 0x9b, 769 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 770 0x05, 0x00, 0x30, 0x82, 0x01, 0x12, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 771 0x04, 0x06, 0x13, 0x02, 0x45, 0x53, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 772 0x04, 0x08, 0x13, 0x09, 0x42, 0x61, 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 773 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x09, 0x42, 0x61, 774 0x72, 0x63, 0x65, 0x6c, 0x6f, 0x6e, 0x61, 0x31, 0x29, 0x30, 0x27, 0x06, 0x03, 775 0x55, 0x04, 0x0a, 0x13, 0x20, 0x49, 0x50, 0x53, 0x20, 0x43, 0x65, 0x72, 0x74, 776 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 777 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x20, 0x73, 0x2e, 0x6c, 0x2e, 0x31, 0x2e, 778 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x14, 0x25, 0x67, 0x65, 0x6e, 0x65, 779 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 780 0x20, 0x43, 0x2e, 0x49, 0x2e, 0x46, 0x2e, 0x20, 0x20, 0x42, 0x2d, 0x42, 0x36, 781 0x32, 0x32, 0x31, 0x30, 0x36, 0x39, 0x35, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 782 0x55, 0x04, 0x0b, 0x13, 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 783 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 784 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 785 0x69, 0x74, 0x79, 0x31, 0x2e, 0x30, 0x2c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 786 0x25, 0x69, 0x70, 0x73, 0x43, 0x41, 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 787 0x31, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x69, 788 0x6f, 0x6e, 0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x31, 789 0x20, 0x30, 0x1e, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x09, 790 0x01, 0x16, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 0x69, 0x70, 791 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x39, 792 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 0x17, 0x0d, 793 0x31, 0x31, 0x30, 0x32, 0x32, 0x34, 0x32, 0x33, 0x30, 0x34, 0x31, 0x37, 0x5a, 794 0x30, 0x81, 0x94, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 795 0x02, 0x55, 0x53, 0x31, 0x13, 0x30, 0x11, 0x06, 0x03, 0x55, 0x04, 0x08, 0x13, 796 0x0a, 0x43, 0x61, 0x6c, 0x69, 0x66, 0x6f, 0x72, 0x6e, 0x69, 0x61, 0x31, 0x16, 797 0x30, 0x14, 0x06, 0x03, 0x55, 0x04, 0x07, 0x13, 0x0d, 0x53, 0x61, 0x6e, 0x20, 798 0x46, 0x72, 0x61, 0x6e, 0x63, 0x69, 0x73, 0x63, 0x6f, 0x31, 0x11, 0x30, 0x0f, 799 0x06, 0x03, 0x55, 0x04, 0x0a, 0x13, 0x08, 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 800 0x74, 0x79, 0x31, 0x14, 0x30, 0x12, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x13, 0x0b, 801 0x53, 0x65, 0x63, 0x75, 0x72, 0x65, 0x20, 0x55, 0x6e, 0x69, 0x74, 0x31, 0x2f, 802 0x30, 0x2d, 0x06, 0x03, 0x55, 0x04, 0x03, 0x13, 0x26, 0x77, 0x77, 0x77, 0x2e, 803 0x70, 0x61, 0x79, 0x70, 0x61, 0x6c, 0x2e, 0x63, 0x6f, 0x6d, 0x00, 0x73, 0x73, 804 0x6c, 0x2e, 0x73, 0x65, 0x63, 0x75, 0x72, 0x65, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 805 0x63, 0x74, 0x69, 0x6f, 0x6e, 0x2e, 0x63, 0x63, 0x30, 0x81, 0x9f, 0x30, 0x0d, 806 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 807 0x03, 0x81, 0x8d, 0x00, 0x30, 0x81, 0x89, 0x02, 0x81, 0x81, 0x00, 0xd2, 0x69, 808 0xfa, 0x6f, 0x3a, 0x00, 0xb4, 0x21, 0x1b, 0xc8, 0xb1, 0x02, 0xd7, 0x3f, 0x19, 809 0xb2, 0xc4, 0x6d, 0xb4, 0x54, 0xf8, 0x8b, 0x8a, 0xcc, 0xdb, 0x72, 0xc2, 0x9e, 810 0x3c, 0x60, 0xb9, 0xc6, 0x91, 0x3d, 0x82, 0xb7, 0x7d, 0x99, 0xff, 0xd1, 0x29, 811 0x84, 0xc1, 0x73, 0x53, 0x9c, 0x82, 0xdd, 0xfc, 0x24, 0x8c, 0x77, 0xd5, 0x41, 812 0xf3, 0xe8, 0x1e, 0x42, 0xa1, 0xad, 0x2d, 0x9e, 0xff, 0x5b, 0x10, 0x26, 0xce, 813 0x9d, 0x57, 0x17, 0x73, 0x16, 0x23, 0x38, 0xc8, 0xd6, 0xf1, 0xba, 0xa3, 0x96, 814 0x5b, 0x16, 0x67, 0x4a, 0x4f, 0x73, 0x97, 0x3a, 0x4d, 0x14, 0xa4, 0xf4, 0xe2, 815 0x3f, 0x8b, 0x05, 0x83, 0x42, 0xd1, 0xd0, 0xdc, 0x2f, 0x7a, 0xe5, 0xb6, 0x10, 816 0xb2, 0x11, 0xc0, 0xdc, 0x21, 0x2a, 0x90, 0xff, 0xae, 0x97, 0x71, 0x5a, 0x49, 817 0x81, 0xac, 0x40, 0xf3, 0x3b, 0xb8, 0x59, 0xb2, 0x4f, 0x02, 0x03, 0x01, 0x00, 818 0x01, 0xa3, 0x82, 0x03, 0x21, 0x30, 0x82, 0x03, 0x1d, 0x30, 0x09, 0x06, 0x03, 819 0x55, 0x1d, 0x13, 0x04, 0x02, 0x30, 0x00, 0x30, 0x11, 0x06, 0x09, 0x60, 0x86, 820 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x01, 0x04, 0x04, 0x03, 0x02, 0x06, 0x40, 821 0x30, 0x0b, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x04, 0x04, 0x03, 0x02, 0x03, 0xf8, 822 0x30, 0x13, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 823 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x30, 0x1d, 0x06, 0x03, 0x55, 824 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x61, 0x8f, 0x61, 0x34, 0x43, 0x55, 0x14, 825 0x7f, 0x27, 0x09, 0xce, 0x4c, 0x8b, 0xea, 0x9b, 0x7b, 0x19, 0x25, 0xbc, 0x6e, 826 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18, 0x30, 0x16, 0x80, 0x14, 827 0x0e, 0x07, 0x60, 0xd4, 0x39, 0xc9, 0x1b, 0x5b, 0x5d, 0x90, 0x7b, 0x23, 0xc8, 828 0xd2, 0x34, 0x9d, 0x4a, 0x9a, 0x46, 0x39, 0x30, 0x09, 0x06, 0x03, 0x55, 0x1d, 829 0x11, 0x04, 0x02, 0x30, 0x00, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x1d, 0x12, 0x04, 830 0x15, 0x30, 0x13, 0x81, 0x11, 0x67, 0x65, 0x6e, 0x65, 0x72, 0x61, 0x6c, 0x40, 831 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x30, 0x72, 0x06, 0x09, 832 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x0d, 0x04, 0x65, 0x16, 0x63, 833 0x4f, 0x72, 0x67, 0x61, 0x6e, 0x69, 0x7a, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 834 0x49, 0x6e, 0x66, 0x6f, 0x72, 0x6d, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x20, 0x4e, 835 0x4f, 0x54, 0x20, 0x56, 0x41, 0x4c, 0x49, 0x44, 0x41, 0x54, 0x45, 0x44, 0x2e, 836 0x20, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x20, 0x53, 0x65, 0x72, 0x76, 837 0x65, 0x72, 0x20, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 838 0x65, 0x20, 0x69, 0x73, 0x73, 0x75, 0x65, 0x64, 0x20, 0x62, 0x79, 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, 0x30, 0x2f, 0x06, 0x09, 0x60, 841 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x02, 0x04, 0x22, 0x16, 0x20, 0x68, 842 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 843 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 844 0x32, 0x30, 0x30, 0x32, 0x2f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 845 0x86, 0xf8, 0x42, 0x01, 0x04, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 846 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 847 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 848 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 849 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 0x30, 0x46, 0x06, 0x09, 850 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x03, 0x04, 0x39, 0x16, 0x37, 851 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 852 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 853 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x72, 0x65, 0x76, 0x6f, 0x63, 0x61, 0x74, 854 0x69, 0x6f, 0x6e, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 855 0x6d, 0x6c, 0x3f, 0x30, 0x43, 0x06, 0x09, 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 856 0x42, 0x01, 0x07, 0x04, 0x36, 0x16, 0x34, 0x68, 0x74, 0x74, 0x70, 0x73, 0x3a, 857 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 858 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 859 0x72, 0x65, 0x6e, 0x65, 0x77, 0x61, 0x6c, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 860 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x3f, 0x30, 0x41, 0x06, 0x09, 0x60, 0x86, 861 0x48, 0x01, 0x86, 0xf8, 0x42, 0x01, 0x08, 0x04, 0x34, 0x16, 0x32, 0x68, 0x74, 862 0x74, 0x70, 0x73, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x2e, 0x69, 0x70, 0x73, 863 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 864 0x30, 0x30, 0x32, 0x2f, 0x70, 0x6f, 0x6c, 0x69, 0x63, 0x79, 0x43, 0x4c, 0x41, 865 0x53, 0x45, 0x41, 0x31, 0x2e, 0x68, 0x74, 0x6d, 0x6c, 0x30, 0x81, 0x83, 0x06, 866 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x7c, 0x30, 0x7a, 0x30, 0x39, 0xa0, 0x37, 0xa0, 867 0x35, 0x86, 0x33, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 868 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 869 0x73, 0x63, 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 870 0x32, 0x30, 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 871 0x72, 0x6c, 0x30, 0x3d, 0xa0, 0x3b, 0xa0, 0x39, 0x86, 0x37, 0x68, 0x74, 0x74, 872 0x70, 0x3a, 0x2f, 0x2f, 0x77, 0x77, 0x77, 0x62, 0x61, 0x63, 0x6b, 0x2e, 0x69, 873 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x69, 0x70, 0x73, 0x63, 874 0x61, 0x32, 0x30, 0x30, 0x32, 0x2f, 0x69, 0x70, 0x73, 0x63, 0x61, 0x32, 0x30, 875 0x30, 0x32, 0x43, 0x4c, 0x41, 0x53, 0x45, 0x41, 0x31, 0x2e, 0x63, 0x72, 0x6c, 876 0x30, 0x32, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x01, 0x01, 0x04, 877 0x26, 0x30, 0x24, 0x30, 0x22, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 878 0x30, 0x01, 0x86, 0x16, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x6f, 0x63, 879 0x73, 0x70, 0x2e, 0x69, 0x70, 0x73, 0x63, 0x61, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 880 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 881 0x05, 0x00, 0x03, 0x81, 0x81, 0x00, 0x68, 0xee, 0x79, 0x97, 0x97, 0xdd, 0x3b, 882 0xef, 0x16, 0x6a, 0x06, 0xf2, 0x14, 0x9a, 0x6e, 0xcd, 0x9e, 0x12, 0xf7, 0xaa, 883 0x83, 0x10, 0xbd, 0xd1, 0x7c, 0x98, 0xfa, 0xc7, 0xae, 0xd4, 0x0e, 0x2c, 0x9e, 884 0x38, 0x05, 0x9d, 0x52, 0x60, 0xa9, 0x99, 0x0a, 0x81, 0xb4, 0x98, 0x90, 0x1d, 885 0xae, 0xbb, 0x4a, 0xd7, 0xb9, 0xdc, 0x88, 0x9e, 0x37, 0x78, 0x41, 0x5b, 0xf7, 886 0x82, 0xa5, 0xf2, 0xba, 0x41, 0x25, 0x5a, 0x90, 0x1a, 0x1e, 0x45, 0x38, 0xa1, 887 0x52, 0x58, 0x75, 0x94, 0x26, 0x44, 0xfb, 0x20, 0x07, 0xba, 0x44, 0xcc, 0xe5, 888 0x4a, 0x2d, 0x72, 0x3f, 0x98, 0x47, 0xf6, 0x26, 0xdc, 0x05, 0x46, 0x05, 0x07, 889 0x63, 0x21, 0xab, 0x46, 0x9b, 0x9c, 0x78, 0xd5, 0x54, 0x5b, 0x3d, 0x0c, 0x1e, 890 0xc8, 0x64, 0x8c, 0xb5, 0x50, 0x23, 0x82, 0x6f, 0xdb, 0xb8, 0x22, 0x1c, 0x43, 891 0x96, 0x07, 0xa8, 0xbb, 892 } 893 894 var stringSliceTestData = [][]string{ 895 {"foo", "bar"}, 896 {"foo", "\\bar"}, 897 {"foo", "\"bar\""}, 898 {"foo", "åäö"}, 899 } 900 901 func TestStringSlice(t *testing.T) { 902 for _, test := range stringSliceTestData { 903 bs, err := Marshal(test) 904 if err != nil { 905 t.Error(err) 906 } 907 908 var res []string 909 _, err = Unmarshal(bs, &res) 910 if err != nil { 911 t.Error(err) 912 } 913 914 if fmt.Sprintf("%v", res) != fmt.Sprintf("%v", test) { 915 t.Errorf("incorrect marshal/unmarshal; %v != %v", res, test) 916 } 917 } 918 } 919 920 type explicitTaggedTimeTest struct { 921 Time time.Time `asn1:"explicit,tag:0"` 922 } 923 924 var explicitTaggedTimeTestData = []struct { 925 in []byte 926 out explicitTaggedTimeTest 927 }{ 928 {[]byte{0x30, 0x11, 0xa0, 0xf, 0x17, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'}, 929 explicitTaggedTimeTest{time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC)}}, 930 {[]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'}, 931 explicitTaggedTimeTest{time.Date(2010, 01, 02, 03, 04, 05, 0, time.FixedZone("", 6*60*60+7*60))}}, 932 } 933 934 func TestExplicitTaggedTime(t *testing.T) { 935 // Test that a time.Time will match either tagUTCTime or 936 // tagGeneralizedTime. 937 for i, test := range explicitTaggedTimeTestData { 938 var got explicitTaggedTimeTest 939 _, err := Unmarshal(test.in, &got) 940 if err != nil { 941 t.Errorf("Unmarshal failed at index %d %v", i, err) 942 } 943 if !got.Time.Equal(test.out.Time) { 944 t.Errorf("#%d: got %v, want %v", i, got.Time, test.out.Time) 945 } 946 } 947 } 948 949 type implicitTaggedTimeTest struct { 950 Time time.Time `asn1:"tag:24"` 951 } 952 953 func TestImplicitTaggedTime(t *testing.T) { 954 // An implicitly tagged time value, that happens to have an implicit 955 // tag equal to a GENERALIZEDTIME, should still be parsed as a UTCTime. 956 // (There's no "timeType" in fieldParameters to determine what type of 957 // time should be expected when implicitly tagged.) 958 der := []byte{0x30, 0x0f, 0x80 | 24, 0xd, '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'} 959 var result implicitTaggedTimeTest 960 if _, err := Unmarshal(der, &result); err != nil { 961 t.Fatalf("Error while parsing: %s", err) 962 } 963 if expected := time.Date(1991, 05, 06, 16, 45, 40, 0, time.UTC); !result.Time.Equal(expected) { 964 t.Errorf("Wrong result. Got %v, want %v", result.Time, expected) 965 } 966 } 967 968 type truncatedExplicitTagTest struct { 969 Test int `asn1:"explicit,tag:0"` 970 } 971 972 func TestTruncatedExplicitTag(t *testing.T) { 973 // This crashed Unmarshal in the past. See #11154. 974 der := []byte{ 975 0x30, // SEQUENCE 976 0x02, // two bytes long 977 0xa0, // context-specific, tag 0 978 0x30, // 48 bytes long 979 } 980 981 var result truncatedExplicitTagTest 982 if _, err := Unmarshal(der, &result); err == nil { 983 t.Error("Unmarshal returned without error") 984 } 985 } 986 987 type invalidUTF8Test struct { 988 Str string `asn1:"utf8"` 989 } 990 991 func TestUnmarshalInvalidUTF8(t *testing.T) { 992 data := []byte("0\x05\f\x03a\xc9c") 993 var result invalidUTF8Test 994 _, err := Unmarshal(data, &result) 995 996 const expectedSubstring = "UTF" 997 if err == nil { 998 t.Fatal("Successfully unmarshaled invalid UTF-8 data") 999 } else if !strings.Contains(err.Error(), expectedSubstring) { 1000 t.Fatalf("Expected error to mention %q but error was %q", expectedSubstring, err.Error()) 1001 } 1002 } 1003 1004 func TestMarshalNilValue(t *testing.T) { 1005 nilValueTestData := []any{ 1006 nil, 1007 struct{ V any }{}, 1008 } 1009 for i, test := range nilValueTestData { 1010 if _, err := Marshal(test); err == nil { 1011 t.Fatalf("#%d: successfully marshaled nil value", i) 1012 } 1013 } 1014 } 1015 1016 type unexported struct { 1017 X int 1018 y int 1019 } 1020 1021 type exported struct { 1022 X int 1023 Y int 1024 } 1025 1026 func TestUnexportedStructField(t *testing.T) { 1027 want := StructuralError{"struct contains unexported fields"} 1028 1029 _, err := Marshal(unexported{X: 5, y: 1}) 1030 if err != want { 1031 t.Errorf("got %v, want %v", err, want) 1032 } 1033 1034 bs, err := Marshal(exported{X: 5, Y: 1}) 1035 if err != nil { 1036 t.Fatal(err) 1037 } 1038 var u unexported 1039 _, err = Unmarshal(bs, &u) 1040 if err != want { 1041 t.Errorf("got %v, want %v", err, want) 1042 } 1043 } 1044 1045 func TestNull(t *testing.T) { 1046 marshaled, err := Marshal(NullRawValue) 1047 if err != nil { 1048 t.Fatal(err) 1049 } 1050 if !bytes.Equal(NullBytes, marshaled) { 1051 t.Errorf("Expected Marshal of NullRawValue to yield %x, got %x", NullBytes, marshaled) 1052 } 1053 1054 unmarshaled := RawValue{} 1055 if _, err := Unmarshal(NullBytes, &unmarshaled); err != nil { 1056 t.Fatal(err) 1057 } 1058 1059 unmarshaled.FullBytes = NullRawValue.FullBytes 1060 if len(unmarshaled.Bytes) == 0 { 1061 // DeepEqual considers a nil slice and an empty slice to be different. 1062 unmarshaled.Bytes = NullRawValue.Bytes 1063 } 1064 1065 if !reflect.DeepEqual(NullRawValue, unmarshaled) { 1066 t.Errorf("Expected Unmarshal of NullBytes to yield %v, got %v", NullRawValue, unmarshaled) 1067 } 1068 } 1069 1070 func TestExplicitTagRawValueStruct(t *testing.T) { 1071 type foo struct { 1072 A RawValue `asn1:"optional,explicit,tag:5"` 1073 B []byte `asn1:"optional,explicit,tag:6"` 1074 } 1075 before := foo{B: []byte{1, 2, 3}} 1076 derBytes, err := Marshal(before) 1077 if err != nil { 1078 t.Fatal(err) 1079 } 1080 1081 var after foo 1082 if rest, err := Unmarshal(derBytes, &after); err != nil || len(rest) != 0 { 1083 t.Fatal(err) 1084 } 1085 1086 got := fmt.Sprintf("%#v", after) 1087 want := fmt.Sprintf("%#v", before) 1088 if got != want { 1089 t.Errorf("got %s, want %s (DER: %x)", got, want, derBytes) 1090 } 1091 } 1092 1093 func TestTaggedRawValue(t *testing.T) { 1094 type taggedRawValue struct { 1095 A RawValue `asn1:"tag:5"` 1096 } 1097 type untaggedRawValue struct { 1098 A RawValue 1099 } 1100 const isCompound = 0x20 1101 const tag = 5 1102 1103 tests := []struct { 1104 shouldMatch bool 1105 derBytes []byte 1106 }{ 1107 {false, []byte{0x30, 3, TagInteger, 1, 1}}, 1108 {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag, 1, 1}}, 1109 {true, []byte{0x30, 3, (ClassContextSpecific << 6) | tag | isCompound, 1, 1}}, 1110 {false, []byte{0x30, 3, (ClassApplication << 6) | tag | isCompound, 1, 1}}, 1111 {false, []byte{0x30, 3, (ClassPrivate << 6) | tag | isCompound, 1, 1}}, 1112 } 1113 1114 for i, test := range tests { 1115 var tagged taggedRawValue 1116 if _, err := Unmarshal(test.derBytes, &tagged); (err == nil) != test.shouldMatch { 1117 t.Errorf("#%d: unexpected result parsing %x: %s", i, test.derBytes, err) 1118 } 1119 1120 // An untagged RawValue should accept anything. 1121 var untagged untaggedRawValue 1122 if _, err := Unmarshal(test.derBytes, &untagged); err != nil { 1123 t.Errorf("#%d: unexpected failure parsing %x with untagged RawValue: %s", i, test.derBytes, err) 1124 } 1125 } 1126 } 1127 1128 var bmpStringTests = []struct { 1129 decoded string 1130 encodedHex string 1131 }{ 1132 {"", "0000"}, 1133 // Example from https://tools.ietf.org/html/rfc7292#appendix-B. 1134 {"Beavis", "0042006500610076006900730000"}, 1135 // Some characters from the "Letterlike Symbols Unicode block". 1136 {"\u2115 - Double-struck N", "21150020002d00200044006f00750062006c0065002d00730074007200750063006b0020004e0000"}, 1137 } 1138 1139 func TestBMPString(t *testing.T) { 1140 for i, test := range bmpStringTests { 1141 encoded, err := hex.DecodeString(test.encodedHex) 1142 if err != nil { 1143 t.Fatalf("#%d: failed to decode from hex string", i) 1144 } 1145 1146 decoded, err := parseBMPString(encoded) 1147 1148 if err != nil { 1149 t.Errorf("#%d: decoding output gave an error: %s", i, err) 1150 continue 1151 } 1152 1153 if decoded != test.decoded { 1154 t.Errorf("#%d: decoding output resulted in %q, but it should have been %q", i, decoded, test.decoded) 1155 continue 1156 } 1157 } 1158 } 1159 1160 func TestNonMinimalEncodedOID(t *testing.T) { 1161 h, err := hex.DecodeString("060a2a80864886f70d01010b") 1162 if err != nil { 1163 t.Fatalf("failed to decode from hex string: %s", err) 1164 } 1165 var oid ObjectIdentifier 1166 _, err = Unmarshal(h, &oid) 1167 if err == nil { 1168 t.Fatalf("accepted non-minimally encoded oid") 1169 } 1170 } 1171 1172 func BenchmarkObjectIdentifierString(b *testing.B) { 1173 oidPublicKeyRSA := ObjectIdentifier{1, 2, 840, 113549, 1, 1, 1} 1174 for i := 0; i < b.N; i++ { 1175 _ = oidPublicKeyRSA.String() 1176 } 1177 }