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