1
2
3
4
5
6
7
8
9
10 package asn1
11
12
13
14
15
16
17
18
19
20
21
22 import (
23 "errors"
24 "fmt"
25 "internal/saferio"
26 "math"
27 "math/big"
28 "reflect"
29 "slices"
30 "strconv"
31 "strings"
32 "time"
33 "unicode/utf16"
34 "unicode/utf8"
35 )
36
37
38
39 type StructuralError struct {
40 Msg string
41 }
42
43 func (e StructuralError) Error() string { return "asn1: structure error: " + e.Msg }
44
45
46 type SyntaxError struct {
47 Msg string
48 }
49
50 func (e SyntaxError) Error() string { return "asn1: syntax error: " + e.Msg }
51
52
53
54
55
56 func parseBool(bytes []byte) (ret bool, err error) {
57 if len(bytes) != 1 {
58 err = SyntaxError{"invalid boolean"}
59 return
60 }
61
62
63
64
65 switch bytes[0] {
66 case 0:
67 ret = false
68 case 0xff:
69 ret = true
70 default:
71 err = SyntaxError{"invalid boolean"}
72 }
73
74 return
75 }
76
77
78
79
80
81 func checkInteger(bytes []byte) error {
82 if len(bytes) == 0 {
83 return StructuralError{"empty integer"}
84 }
85 if len(bytes) == 1 {
86 return nil
87 }
88 if (bytes[0] == 0 && bytes[1]&0x80 == 0) || (bytes[0] == 0xff && bytes[1]&0x80 == 0x80) {
89 return StructuralError{"integer not minimally-encoded"}
90 }
91 return nil
92 }
93
94
95
96 func parseInt64(bytes []byte) (ret int64, err error) {
97 err = checkInteger(bytes)
98 if err != nil {
99 return
100 }
101 if len(bytes) > 8 {
102
103 err = StructuralError{"integer too large"}
104 return
105 }
106 for bytesRead := 0; bytesRead < len(bytes); bytesRead++ {
107 ret <<= 8
108 ret |= int64(bytes[bytesRead])
109 }
110
111
112 ret <<= 64 - uint8(len(bytes))*8
113 ret >>= 64 - uint8(len(bytes))*8
114 return
115 }
116
117
118
119 func parseInt32(bytes []byte) (int32, error) {
120 if err := checkInteger(bytes); err != nil {
121 return 0, err
122 }
123 ret64, err := parseInt64(bytes)
124 if err != nil {
125 return 0, err
126 }
127 if ret64 != int64(int32(ret64)) {
128 return 0, StructuralError{"integer too large"}
129 }
130 return int32(ret64), nil
131 }
132
133 var bigOne = big.NewInt(1)
134
135
136
137 func parseBigInt(bytes []byte) (*big.Int, error) {
138 if err := checkInteger(bytes); err != nil {
139 return nil, err
140 }
141 ret := new(big.Int)
142 if len(bytes) > 0 && bytes[0]&0x80 == 0x80 {
143
144 notBytes := make([]byte, len(bytes))
145 for i := range notBytes {
146 notBytes[i] = ^bytes[i]
147 }
148 ret.SetBytes(notBytes)
149 ret.Add(ret, bigOne)
150 ret.Neg(ret)
151 return ret, nil
152 }
153 ret.SetBytes(bytes)
154 return ret, nil
155 }
156
157
158
159
160
161
162 type BitString struct {
163 Bytes []byte
164 BitLength int
165 }
166
167
168
169 func (b BitString) At(i int) int {
170 if i < 0 || i >= b.BitLength {
171 return 0
172 }
173 x := i / 8
174 y := 7 - uint(i%8)
175 return int(b.Bytes[x]>>y) & 1
176 }
177
178
179
180 func (b BitString) RightAlign() []byte {
181 shift := uint(8 - (b.BitLength % 8))
182 if shift == 8 || len(b.Bytes) == 0 {
183 return b.Bytes
184 }
185
186 a := make([]byte, len(b.Bytes))
187 a[0] = b.Bytes[0] >> shift
188 for i := 1; i < len(b.Bytes); i++ {
189 a[i] = b.Bytes[i-1] << (8 - shift)
190 a[i] |= b.Bytes[i] >> shift
191 }
192
193 return a
194 }
195
196
197 func parseBitString(bytes []byte) (ret BitString, err error) {
198 if len(bytes) == 0 {
199 err = SyntaxError{"zero length BIT STRING"}
200 return
201 }
202 paddingBits := int(bytes[0])
203 if paddingBits > 7 ||
204 len(bytes) == 1 && paddingBits > 0 ||
205 bytes[len(bytes)-1]&((1<<bytes[0])-1) != 0 {
206 err = SyntaxError{"invalid padding bits in BIT STRING"}
207 return
208 }
209 ret.BitLength = (len(bytes)-1)*8 - paddingBits
210 ret.Bytes = bytes[1:]
211 return
212 }
213
214
215
216
217 var NullRawValue = RawValue{Tag: TagNull}
218
219
220 var NullBytes = []byte{TagNull, 0}
221
222
223
224
225 type ObjectIdentifier []int
226
227
228 func (oi ObjectIdentifier) Equal(other ObjectIdentifier) bool {
229 return slices.Equal(oi, other)
230 }
231
232 func (oi ObjectIdentifier) String() string {
233 var s strings.Builder
234 s.Grow(32)
235
236 buf := make([]byte, 0, 19)
237 for i, v := range oi {
238 if i > 0 {
239 s.WriteByte('.')
240 }
241 s.Write(strconv.AppendInt(buf, int64(v), 10))
242 }
243
244 return s.String()
245 }
246
247
248
249
250 func parseObjectIdentifier(bytes []byte) (s ObjectIdentifier, err error) {
251 if len(bytes) == 0 {
252 err = SyntaxError{"zero length OBJECT IDENTIFIER"}
253 return
254 }
255
256
257
258 s = make([]int, len(bytes)+1)
259
260
261
262
263
264 v, offset, err := parseBase128Int(bytes, 0)
265 if err != nil {
266 return
267 }
268 if v < 80 {
269 s[0] = v / 40
270 s[1] = v % 40
271 } else {
272 s[0] = 2
273 s[1] = v - 80
274 }
275
276 i := 2
277 for ; offset < len(bytes); i++ {
278 v, offset, err = parseBase128Int(bytes, offset)
279 if err != nil {
280 return
281 }
282 s[i] = v
283 }
284 s = s[0:i]
285 return
286 }
287
288
289
290
291 type Enumerated int
292
293
294
295
296 type Flag bool
297
298
299
300 func parseBase128Int(bytes []byte, initOffset int) (ret, offset int, err error) {
301 offset = initOffset
302 var ret64 int64
303 for shifted := 0; offset < len(bytes); shifted++ {
304
305
306 if shifted == 5 {
307 err = StructuralError{"base 128 integer too large"}
308 return
309 }
310 ret64 <<= 7
311 b := bytes[offset]
312
313
314 if shifted == 0 && b == 0x80 {
315 err = SyntaxError{"integer is not minimally encoded"}
316 return
317 }
318 ret64 |= int64(b & 0x7f)
319 offset++
320 if b&0x80 == 0 {
321 ret = int(ret64)
322
323 if ret64 > math.MaxInt32 {
324 err = StructuralError{"base 128 integer too large"}
325 }
326 return
327 }
328 }
329 err = SyntaxError{"truncated base 128 integer"}
330 return
331 }
332
333
334
335 func parseUTCTime(bytes []byte) (ret time.Time, err error) {
336 s := string(bytes)
337
338 formatStr := "0601021504Z0700"
339 ret, err = time.Parse(formatStr, s)
340 if err != nil {
341 formatStr = "060102150405Z0700"
342 ret, err = time.Parse(formatStr, s)
343 }
344 if err != nil {
345 return
346 }
347
348 if serialized := ret.Format(formatStr); serialized != s {
349 err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
350 return
351 }
352
353 if ret.Year() >= 2050 {
354
355 ret = ret.AddDate(-100, 0, 0)
356 }
357
358 return
359 }
360
361
362
363 func parseGeneralizedTime(bytes []byte) (ret time.Time, err error) {
364 const formatStr = "20060102150405.999999999Z0700"
365 s := string(bytes)
366
367 if ret, err = time.Parse(formatStr, s); err != nil {
368 return
369 }
370
371 if serialized := ret.Format(formatStr); serialized != s {
372 err = fmt.Errorf("asn1: time did not serialize back to the original value and may be invalid: given %q, but serialized as %q", s, serialized)
373 }
374
375 return
376 }
377
378
379
380
381
382 func parseNumericString(bytes []byte) (ret string, err error) {
383 for _, b := range bytes {
384 if !isNumeric(b) {
385 return "", SyntaxError{"NumericString contains invalid character"}
386 }
387 }
388 return string(bytes), nil
389 }
390
391
392 func isNumeric(b byte) bool {
393 return '0' <= b && b <= '9' ||
394 b == ' '
395 }
396
397
398
399
400
401 func parsePrintableString(bytes []byte) (ret string, err error) {
402 for _, b := range bytes {
403 if !isPrintable(b, allowAsterisk, allowAmpersand) {
404 err = SyntaxError{"PrintableString contains invalid character"}
405 return
406 }
407 }
408 ret = string(bytes)
409 return
410 }
411
412 type asteriskFlag bool
413 type ampersandFlag bool
414
415 const (
416 allowAsterisk asteriskFlag = true
417 rejectAsterisk asteriskFlag = false
418
419 allowAmpersand ampersandFlag = true
420 rejectAmpersand ampersandFlag = false
421 )
422
423
424
425
426 func isPrintable(b byte, asterisk asteriskFlag, ampersand ampersandFlag) bool {
427 return 'a' <= b && b <= 'z' ||
428 'A' <= b && b <= 'Z' ||
429 '0' <= b && b <= '9' ||
430 '\'' <= b && b <= ')' ||
431 '+' <= b && b <= '/' ||
432 b == ' ' ||
433 b == ':' ||
434 b == '=' ||
435 b == '?' ||
436
437
438
439 (bool(asterisk) && b == '*') ||
440
441
442
443
444 (bool(ampersand) && b == '&')
445 }
446
447
448
449
450
451 func parseIA5String(bytes []byte) (ret string, err error) {
452 for _, b := range bytes {
453 if b >= utf8.RuneSelf {
454 err = SyntaxError{"IA5String contains invalid character"}
455 return
456 }
457 }
458 ret = string(bytes)
459 return
460 }
461
462
463
464
465
466 func parseT61String(bytes []byte) (ret string, err error) {
467
468
469
470
471
472
473
474
475
476 buf := make([]byte, 0, len(bytes))
477 for _, v := range bytes {
478
479 buf = utf8.AppendRune(buf, rune(v))
480 }
481 return string(buf), nil
482 }
483
484
485
486
487
488 func parseUTF8String(bytes []byte) (ret string, err error) {
489 if !utf8.Valid(bytes) {
490 return "", errors.New("asn1: invalid UTF-8 string")
491 }
492 return string(bytes), nil
493 }
494
495
496
497
498
499 func parseBMPString(bmpString []byte) (string, error) {
500
501
502
503
504
505
506
507
508 if len(bmpString)%2 != 0 {
509 return "", errors.New("invalid BMPString")
510 }
511
512
513 if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 {
514 bmpString = bmpString[:l-2]
515 }
516
517 s := make([]uint16, 0, len(bmpString)/2)
518 for len(bmpString) > 0 {
519 point := uint16(bmpString[0])<<8 + uint16(bmpString[1])
520
521
522
523 if point == 0xfffe || point == 0xffff ||
524 (point >= 0xfdd0 && point <= 0xfdef) ||
525 (point >= 0xd800 && point <= 0xdfff) {
526 return "", errors.New("invalid BMPString")
527 }
528 s = append(s, point)
529 bmpString = bmpString[2:]
530 }
531
532 return string(utf16.Decode(s)), nil
533 }
534
535
536 type RawValue struct {
537 Class, Tag int
538 IsCompound bool
539 Bytes []byte
540 FullBytes []byte
541 }
542
543
544
545
546 type RawContent []byte
547
548
549
550
551
552
553
554 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
555 offset = initOffset
556
557
558 if offset >= len(bytes) {
559 err = errors.New("asn1: internal error in parseTagAndLength")
560 return
561 }
562 b := bytes[offset]
563 offset++
564 ret.class = int(b >> 6)
565 ret.isCompound = b&0x20 == 0x20
566 ret.tag = int(b & 0x1f)
567
568
569
570 if ret.tag == 0x1f {
571 ret.tag, offset, err = parseBase128Int(bytes, offset)
572 if err != nil {
573 return
574 }
575
576 if ret.tag < 0x1f {
577 err = SyntaxError{"non-minimal tag"}
578 return
579 }
580 }
581 if offset >= len(bytes) {
582 err = SyntaxError{"truncated tag or length"}
583 return
584 }
585 b = bytes[offset]
586 offset++
587 if b&0x80 == 0 {
588
589 ret.length = int(b & 0x7f)
590 } else {
591
592 numBytes := int(b & 0x7f)
593 if numBytes == 0 {
594 err = SyntaxError{"indefinite length found (not DER)"}
595 return
596 }
597 ret.length = 0
598 for i := 0; i < numBytes; i++ {
599 if offset >= len(bytes) {
600 err = SyntaxError{"truncated tag or length"}
601 return
602 }
603 b = bytes[offset]
604 offset++
605 if ret.length >= 1<<23 {
606
607
608 err = StructuralError{"length too large"}
609 return
610 }
611 ret.length <<= 8
612 ret.length |= int(b)
613 if ret.length == 0 {
614
615 err = StructuralError{"superfluous leading zeros in length"}
616 return
617 }
618 }
619
620 if ret.length < 0x80 {
621 err = StructuralError{"non-minimal length"}
622 return
623 }
624 }
625
626 return
627 }
628
629
630
631
632 func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
633 matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
634 if !ok {
635 err = StructuralError{"unknown Go type for slice"}
636 return
637 }
638
639
640
641 numElements := 0
642 for offset := 0; offset < len(bytes); {
643 var t tagAndLength
644 t, offset, err = parseTagAndLength(bytes, offset)
645 if err != nil {
646 return
647 }
648 switch t.tag {
649 case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
650
651
652
653 t.tag = TagPrintableString
654 case TagGeneralizedTime, TagUTCTime:
655
656 t.tag = TagUTCTime
657 }
658
659 if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
660 err = StructuralError{"sequence tag mismatch"}
661 return
662 }
663 if invalidLength(offset, t.length, len(bytes)) {
664 err = SyntaxError{"truncated sequence"}
665 return
666 }
667 offset += t.length
668 numElements++
669 }
670 elemSize := uint64(elemType.Size())
671 safeCap := saferio.SliceCapWithSize(elemSize, uint64(numElements))
672 if safeCap < 0 {
673 err = SyntaxError{fmt.Sprintf("%s slice too big: %d elements of %d bytes", elemType.Kind(), numElements, elemSize)}
674 return
675 }
676 ret = reflect.MakeSlice(sliceType, 0, safeCap)
677 params := fieldParameters{}
678 offset := 0
679 for i := 0; i < numElements; i++ {
680 ret = reflect.Append(ret, reflect.Zero(elemType))
681 offset, err = parseField(ret.Index(i), bytes, offset, params)
682 if err != nil {
683 return
684 }
685 }
686 return
687 }
688
689 var (
690 bitStringType = reflect.TypeFor[BitString]()
691 objectIdentifierType = reflect.TypeFor[ObjectIdentifier]()
692 enumeratedType = reflect.TypeFor[Enumerated]()
693 flagType = reflect.TypeFor[Flag]()
694 timeType = reflect.TypeFor[time.Time]()
695 rawValueType = reflect.TypeFor[RawValue]()
696 rawContentsType = reflect.TypeFor[RawContent]()
697 bigIntType = reflect.TypeFor[*big.Int]()
698 )
699
700
701
702 func invalidLength(offset, length, sliceLength int) bool {
703 return offset+length < offset || offset+length > sliceLength
704 }
705
706
707
708
709 func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
710 offset = initOffset
711 fieldType := v.Type()
712
713
714 if offset == len(bytes) {
715 if !setDefaultValue(v, params) {
716 err = SyntaxError{"sequence truncated"}
717 }
718 return
719 }
720
721
722 if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
723 var t tagAndLength
724 t, offset, err = parseTagAndLength(bytes, offset)
725 if err != nil {
726 return
727 }
728 if invalidLength(offset, t.length, len(bytes)) {
729 err = SyntaxError{"data truncated"}
730 return
731 }
732 var result any
733 if !t.isCompound && t.class == ClassUniversal {
734 innerBytes := bytes[offset : offset+t.length]
735 switch t.tag {
736 case TagBoolean:
737 result, err = parseBool(innerBytes)
738 case TagPrintableString:
739 result, err = parsePrintableString(innerBytes)
740 case TagNumericString:
741 result, err = parseNumericString(innerBytes)
742 case TagIA5String:
743 result, err = parseIA5String(innerBytes)
744 case TagT61String:
745 result, err = parseT61String(innerBytes)
746 case TagUTF8String:
747 result, err = parseUTF8String(innerBytes)
748 case TagInteger:
749 result, err = parseInt64(innerBytes)
750 case TagBitString:
751 result, err = parseBitString(innerBytes)
752 case TagOID:
753 result, err = parseObjectIdentifier(innerBytes)
754 case TagUTCTime:
755 result, err = parseUTCTime(innerBytes)
756 case TagGeneralizedTime:
757 result, err = parseGeneralizedTime(innerBytes)
758 case TagOctetString:
759 result = innerBytes
760 case TagBMPString:
761 result, err = parseBMPString(innerBytes)
762 default:
763
764 }
765 }
766 offset += t.length
767 if err != nil {
768 return
769 }
770 if result != nil {
771 v.Set(reflect.ValueOf(result))
772 }
773 return
774 }
775
776 t, offset, err := parseTagAndLength(bytes, offset)
777 if err != nil {
778 return
779 }
780 if params.explicit {
781 expectedClass := ClassContextSpecific
782 if params.application {
783 expectedClass = ClassApplication
784 }
785 if offset == len(bytes) {
786 err = StructuralError{"explicit tag has no child"}
787 return
788 }
789 if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
790 if fieldType == rawValueType {
791
792 } else if t.length > 0 {
793 t, offset, err = parseTagAndLength(bytes, offset)
794 if err != nil {
795 return
796 }
797 } else {
798 if fieldType != flagType {
799 err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
800 return
801 }
802 v.SetBool(true)
803 return
804 }
805 } else {
806
807 ok := setDefaultValue(v, params)
808 if ok {
809 offset = initOffset
810 } else {
811 err = StructuralError{"explicitly tagged member didn't match"}
812 }
813 return
814 }
815 }
816
817 matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
818 if !ok1 {
819 err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
820 return
821 }
822
823
824
825
826
827 if universalTag == TagPrintableString {
828 if t.class == ClassUniversal {
829 switch t.tag {
830 case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
831 universalTag = t.tag
832 }
833 } else if params.stringType != 0 {
834 universalTag = params.stringType
835 }
836 }
837
838
839
840
841
842
843 if universalTag == TagUTCTime {
844 if t.class == ClassUniversal {
845 if t.tag == TagGeneralizedTime {
846 universalTag = t.tag
847 }
848 } else if params.timeType != 0 {
849 universalTag = params.timeType
850 }
851 }
852
853 if params.set {
854 universalTag = TagSet
855 }
856
857 matchAnyClassAndTag := matchAny
858 expectedClass := ClassUniversal
859 expectedTag := universalTag
860
861 if !params.explicit && params.tag != nil {
862 expectedClass = ClassContextSpecific
863 expectedTag = *params.tag
864 matchAnyClassAndTag = false
865 }
866
867 if !params.explicit && params.application && params.tag != nil {
868 expectedClass = ClassApplication
869 expectedTag = *params.tag
870 matchAnyClassAndTag = false
871 }
872
873 if !params.explicit && params.private && params.tag != nil {
874 expectedClass = ClassPrivate
875 expectedTag = *params.tag
876 matchAnyClassAndTag = false
877 }
878
879
880 if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
881 (!matchAny && t.isCompound != compoundType) {
882
883 ok := setDefaultValue(v, params)
884 if ok {
885 offset = initOffset
886 } else {
887 err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
888 }
889 return
890 }
891 if invalidLength(offset, t.length, len(bytes)) {
892 err = SyntaxError{"data truncated"}
893 return
894 }
895 innerBytes := bytes[offset : offset+t.length]
896 offset += t.length
897
898
899 switch v := v.Addr().Interface().(type) {
900 case *RawValue:
901 *v = RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
902 return
903 case *ObjectIdentifier:
904 *v, err = parseObjectIdentifier(innerBytes)
905 return
906 case *BitString:
907 *v, err = parseBitString(innerBytes)
908 return
909 case *time.Time:
910 if universalTag == TagUTCTime {
911 *v, err = parseUTCTime(innerBytes)
912 return
913 }
914 *v, err = parseGeneralizedTime(innerBytes)
915 return
916 case *Enumerated:
917 parsedInt, err1 := parseInt32(innerBytes)
918 if err1 == nil {
919 *v = Enumerated(parsedInt)
920 }
921 err = err1
922 return
923 case *Flag:
924 *v = true
925 return
926 case **big.Int:
927 parsedInt, err1 := parseBigInt(innerBytes)
928 if err1 == nil {
929 *v = parsedInt
930 }
931 err = err1
932 return
933 }
934 switch val := v; val.Kind() {
935 case reflect.Bool:
936 parsedBool, err1 := parseBool(innerBytes)
937 if err1 == nil {
938 val.SetBool(parsedBool)
939 }
940 err = err1
941 return
942 case reflect.Int, reflect.Int32, reflect.Int64:
943 if val.Type().Size() == 4 {
944 parsedInt, err1 := parseInt32(innerBytes)
945 if err1 == nil {
946 val.SetInt(int64(parsedInt))
947 }
948 err = err1
949 } else {
950 parsedInt, err1 := parseInt64(innerBytes)
951 if err1 == nil {
952 val.SetInt(parsedInt)
953 }
954 err = err1
955 }
956 return
957
958 case reflect.Struct:
959 structType := fieldType
960
961 for i := 0; i < structType.NumField(); i++ {
962 if !structType.Field(i).IsExported() {
963 err = StructuralError{"struct contains unexported fields"}
964 return
965 }
966 }
967
968 if structType.NumField() > 0 &&
969 structType.Field(0).Type == rawContentsType {
970 bytes := bytes[initOffset:offset]
971 val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
972 }
973
974 innerOffset := 0
975 for i := 0; i < structType.NumField(); i++ {
976 field := structType.Field(i)
977 if i == 0 && field.Type == rawContentsType {
978 continue
979 }
980 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
981 if err != nil {
982 return
983 }
984 }
985
986
987
988 return
989 case reflect.Slice:
990 sliceType := fieldType
991 if sliceType.Elem().Kind() == reflect.Uint8 {
992 val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
993 reflect.Copy(val, reflect.ValueOf(innerBytes))
994 return
995 }
996 newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
997 if err1 == nil {
998 val.Set(newSlice)
999 }
1000 err = err1
1001 return
1002 case reflect.String:
1003 var v string
1004 switch universalTag {
1005 case TagPrintableString:
1006 v, err = parsePrintableString(innerBytes)
1007 case TagNumericString:
1008 v, err = parseNumericString(innerBytes)
1009 case TagIA5String:
1010 v, err = parseIA5String(innerBytes)
1011 case TagT61String:
1012 v, err = parseT61String(innerBytes)
1013 case TagUTF8String:
1014 v, err = parseUTF8String(innerBytes)
1015 case TagGeneralString:
1016
1017
1018
1019
1020 v, err = parseT61String(innerBytes)
1021 case TagBMPString:
1022 v, err = parseBMPString(innerBytes)
1023
1024 default:
1025 err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
1026 }
1027 if err == nil {
1028 val.SetString(v)
1029 }
1030 return
1031 }
1032 err = StructuralError{"unsupported: " + v.Type().String()}
1033 return
1034 }
1035
1036
1037
1038 func canHaveDefaultValue(k reflect.Kind) bool {
1039 switch k {
1040 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1041 return true
1042 }
1043
1044 return false
1045 }
1046
1047
1048
1049
1050 func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
1051 if !params.optional {
1052 return
1053 }
1054 ok = true
1055 if params.defaultValue == nil {
1056 return
1057 }
1058 if canHaveDefaultValue(v.Kind()) {
1059 v.SetInt(*params.defaultValue)
1060 }
1061 return
1062 }
1063
1064
1065
1066
1067
1068
1069
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
1086
1087
1088
1089
1090
1091
1092
1093
1094
1095
1096
1097
1098
1099
1100
1101
1102
1103
1104
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140 func Unmarshal(b []byte, val any) (rest []byte, err error) {
1141 return UnmarshalWithParams(b, val, "")
1142 }
1143
1144
1145
1146 type invalidUnmarshalError struct {
1147 Type reflect.Type
1148 }
1149
1150 func (e *invalidUnmarshalError) Error() string {
1151 if e.Type == nil {
1152 return "asn1: Unmarshal recipient value is nil"
1153 }
1154
1155 if e.Type.Kind() != reflect.Pointer {
1156 return "asn1: Unmarshal recipient value is non-pointer " + e.Type.String()
1157 }
1158 return "asn1: Unmarshal recipient value is nil " + e.Type.String()
1159 }
1160
1161
1162
1163 func UnmarshalWithParams(b []byte, val any, params string) (rest []byte, err error) {
1164 v := reflect.ValueOf(val)
1165 if v.Kind() != reflect.Pointer || v.IsNil() {
1166 return nil, &invalidUnmarshalError{reflect.TypeOf(val)}
1167 }
1168 offset, err := parseField(v.Elem(), b, 0, parseFieldParameters(params))
1169 if err != nil {
1170 return nil, err
1171 }
1172 return b[offset:], nil
1173 }
1174
View as plain text