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 return string(bytes), nil
468 }
469
470
471
472
473
474 func parseUTF8String(bytes []byte) (ret string, err error) {
475 if !utf8.Valid(bytes) {
476 return "", errors.New("asn1: invalid UTF-8 string")
477 }
478 return string(bytes), nil
479 }
480
481
482
483
484
485 func parseBMPString(bmpString []byte) (string, error) {
486 if len(bmpString)%2 != 0 {
487 return "", errors.New("pkcs12: odd-length BMP string")
488 }
489
490
491 if l := len(bmpString); l >= 2 && bmpString[l-1] == 0 && bmpString[l-2] == 0 {
492 bmpString = bmpString[:l-2]
493 }
494
495 s := make([]uint16, 0, len(bmpString)/2)
496 for len(bmpString) > 0 {
497 s = append(s, uint16(bmpString[0])<<8+uint16(bmpString[1]))
498 bmpString = bmpString[2:]
499 }
500
501 return string(utf16.Decode(s)), nil
502 }
503
504
505 type RawValue struct {
506 Class, Tag int
507 IsCompound bool
508 Bytes []byte
509 FullBytes []byte
510 }
511
512
513
514
515 type RawContent []byte
516
517
518
519
520
521
522
523 func parseTagAndLength(bytes []byte, initOffset int) (ret tagAndLength, offset int, err error) {
524 offset = initOffset
525
526
527 if offset >= len(bytes) {
528 err = errors.New("asn1: internal error in parseTagAndLength")
529 return
530 }
531 b := bytes[offset]
532 offset++
533 ret.class = int(b >> 6)
534 ret.isCompound = b&0x20 == 0x20
535 ret.tag = int(b & 0x1f)
536
537
538
539 if ret.tag == 0x1f {
540 ret.tag, offset, err = parseBase128Int(bytes, offset)
541 if err != nil {
542 return
543 }
544
545 if ret.tag < 0x1f {
546 err = SyntaxError{"non-minimal tag"}
547 return
548 }
549 }
550 if offset >= len(bytes) {
551 err = SyntaxError{"truncated tag or length"}
552 return
553 }
554 b = bytes[offset]
555 offset++
556 if b&0x80 == 0 {
557
558 ret.length = int(b & 0x7f)
559 } else {
560
561 numBytes := int(b & 0x7f)
562 if numBytes == 0 {
563 err = SyntaxError{"indefinite length found (not DER)"}
564 return
565 }
566 ret.length = 0
567 for i := 0; i < numBytes; i++ {
568 if offset >= len(bytes) {
569 err = SyntaxError{"truncated tag or length"}
570 return
571 }
572 b = bytes[offset]
573 offset++
574 if ret.length >= 1<<23 {
575
576
577 err = StructuralError{"length too large"}
578 return
579 }
580 ret.length <<= 8
581 ret.length |= int(b)
582 if ret.length == 0 {
583
584 err = StructuralError{"superfluous leading zeros in length"}
585 return
586 }
587 }
588
589 if ret.length < 0x80 {
590 err = StructuralError{"non-minimal length"}
591 return
592 }
593 }
594
595 return
596 }
597
598
599
600
601 func parseSequenceOf(bytes []byte, sliceType reflect.Type, elemType reflect.Type) (ret reflect.Value, err error) {
602 matchAny, expectedTag, compoundType, ok := getUniversalType(elemType)
603 if !ok {
604 err = StructuralError{"unknown Go type for slice"}
605 return
606 }
607
608
609
610 numElements := 0
611 for offset := 0; offset < len(bytes); {
612 var t tagAndLength
613 t, offset, err = parseTagAndLength(bytes, offset)
614 if err != nil {
615 return
616 }
617 switch t.tag {
618 case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
619
620
621
622 t.tag = TagPrintableString
623 case TagGeneralizedTime, TagUTCTime:
624
625 t.tag = TagUTCTime
626 }
627
628 if !matchAny && (t.class != ClassUniversal || t.isCompound != compoundType || t.tag != expectedTag) {
629 err = StructuralError{"sequence tag mismatch"}
630 return
631 }
632 if invalidLength(offset, t.length, len(bytes)) {
633 err = SyntaxError{"truncated sequence"}
634 return
635 }
636 offset += t.length
637 numElements++
638 }
639 elemSize := uint64(elemType.Size())
640 safeCap := saferio.SliceCapWithSize(elemSize, uint64(numElements))
641 if safeCap < 0 {
642 err = SyntaxError{fmt.Sprintf("%s slice too big: %d elements of %d bytes", elemType.Kind(), numElements, elemSize)}
643 return
644 }
645 ret = reflect.MakeSlice(sliceType, 0, safeCap)
646 params := fieldParameters{}
647 offset := 0
648 for i := 0; i < numElements; i++ {
649 ret = reflect.Append(ret, reflect.Zero(elemType))
650 offset, err = parseField(ret.Index(i), bytes, offset, params)
651 if err != nil {
652 return
653 }
654 }
655 return
656 }
657
658 var (
659 bitStringType = reflect.TypeFor[BitString]()
660 objectIdentifierType = reflect.TypeFor[ObjectIdentifier]()
661 enumeratedType = reflect.TypeFor[Enumerated]()
662 flagType = reflect.TypeFor[Flag]()
663 timeType = reflect.TypeFor[time.Time]()
664 rawValueType = reflect.TypeFor[RawValue]()
665 rawContentsType = reflect.TypeFor[RawContent]()
666 bigIntType = reflect.TypeFor[*big.Int]()
667 )
668
669
670
671 func invalidLength(offset, length, sliceLength int) bool {
672 return offset+length < offset || offset+length > sliceLength
673 }
674
675
676
677
678 func parseField(v reflect.Value, bytes []byte, initOffset int, params fieldParameters) (offset int, err error) {
679 offset = initOffset
680 fieldType := v.Type()
681
682
683 if offset == len(bytes) {
684 if !setDefaultValue(v, params) {
685 err = SyntaxError{"sequence truncated"}
686 }
687 return
688 }
689
690
691 if ifaceType := fieldType; ifaceType.Kind() == reflect.Interface && ifaceType.NumMethod() == 0 {
692 var t tagAndLength
693 t, offset, err = parseTagAndLength(bytes, offset)
694 if err != nil {
695 return
696 }
697 if invalidLength(offset, t.length, len(bytes)) {
698 err = SyntaxError{"data truncated"}
699 return
700 }
701 var result any
702 if !t.isCompound && t.class == ClassUniversal {
703 innerBytes := bytes[offset : offset+t.length]
704 switch t.tag {
705 case TagBoolean:
706 result, err = parseBool(innerBytes)
707 case TagPrintableString:
708 result, err = parsePrintableString(innerBytes)
709 case TagNumericString:
710 result, err = parseNumericString(innerBytes)
711 case TagIA5String:
712 result, err = parseIA5String(innerBytes)
713 case TagT61String:
714 result, err = parseT61String(innerBytes)
715 case TagUTF8String:
716 result, err = parseUTF8String(innerBytes)
717 case TagInteger:
718 result, err = parseInt64(innerBytes)
719 case TagBitString:
720 result, err = parseBitString(innerBytes)
721 case TagOID:
722 result, err = parseObjectIdentifier(innerBytes)
723 case TagUTCTime:
724 result, err = parseUTCTime(innerBytes)
725 case TagGeneralizedTime:
726 result, err = parseGeneralizedTime(innerBytes)
727 case TagOctetString:
728 result = innerBytes
729 case TagBMPString:
730 result, err = parseBMPString(innerBytes)
731 default:
732
733 }
734 }
735 offset += t.length
736 if err != nil {
737 return
738 }
739 if result != nil {
740 v.Set(reflect.ValueOf(result))
741 }
742 return
743 }
744
745 t, offset, err := parseTagAndLength(bytes, offset)
746 if err != nil {
747 return
748 }
749 if params.explicit {
750 expectedClass := ClassContextSpecific
751 if params.application {
752 expectedClass = ClassApplication
753 }
754 if offset == len(bytes) {
755 err = StructuralError{"explicit tag has no child"}
756 return
757 }
758 if t.class == expectedClass && t.tag == *params.tag && (t.length == 0 || t.isCompound) {
759 if fieldType == rawValueType {
760
761 } else if t.length > 0 {
762 t, offset, err = parseTagAndLength(bytes, offset)
763 if err != nil {
764 return
765 }
766 } else {
767 if fieldType != flagType {
768 err = StructuralError{"zero length explicit tag was not an asn1.Flag"}
769 return
770 }
771 v.SetBool(true)
772 return
773 }
774 } else {
775
776 ok := setDefaultValue(v, params)
777 if ok {
778 offset = initOffset
779 } else {
780 err = StructuralError{"explicitly tagged member didn't match"}
781 }
782 return
783 }
784 }
785
786 matchAny, universalTag, compoundType, ok1 := getUniversalType(fieldType)
787 if !ok1 {
788 err = StructuralError{fmt.Sprintf("unknown Go type: %v", fieldType)}
789 return
790 }
791
792
793
794
795
796 if universalTag == TagPrintableString {
797 if t.class == ClassUniversal {
798 switch t.tag {
799 case TagIA5String, TagGeneralString, TagT61String, TagUTF8String, TagNumericString, TagBMPString:
800 universalTag = t.tag
801 }
802 } else if params.stringType != 0 {
803 universalTag = params.stringType
804 }
805 }
806
807
808
809 if universalTag == TagUTCTime && t.tag == TagGeneralizedTime && t.class == ClassUniversal {
810 universalTag = TagGeneralizedTime
811 }
812
813 if params.set {
814 universalTag = TagSet
815 }
816
817 matchAnyClassAndTag := matchAny
818 expectedClass := ClassUniversal
819 expectedTag := universalTag
820
821 if !params.explicit && params.tag != nil {
822 expectedClass = ClassContextSpecific
823 expectedTag = *params.tag
824 matchAnyClassAndTag = false
825 }
826
827 if !params.explicit && params.application && params.tag != nil {
828 expectedClass = ClassApplication
829 expectedTag = *params.tag
830 matchAnyClassAndTag = false
831 }
832
833 if !params.explicit && params.private && params.tag != nil {
834 expectedClass = ClassPrivate
835 expectedTag = *params.tag
836 matchAnyClassAndTag = false
837 }
838
839
840 if !matchAnyClassAndTag && (t.class != expectedClass || t.tag != expectedTag) ||
841 (!matchAny && t.isCompound != compoundType) {
842
843 ok := setDefaultValue(v, params)
844 if ok {
845 offset = initOffset
846 } else {
847 err = StructuralError{fmt.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag, t, params, fieldType.Name(), offset)}
848 }
849 return
850 }
851 if invalidLength(offset, t.length, len(bytes)) {
852 err = SyntaxError{"data truncated"}
853 return
854 }
855 innerBytes := bytes[offset : offset+t.length]
856 offset += t.length
857
858
859 switch v := v.Addr().Interface().(type) {
860 case *RawValue:
861 *v = RawValue{t.class, t.tag, t.isCompound, innerBytes, bytes[initOffset:offset]}
862 return
863 case *ObjectIdentifier:
864 *v, err = parseObjectIdentifier(innerBytes)
865 return
866 case *BitString:
867 *v, err = parseBitString(innerBytes)
868 return
869 case *time.Time:
870 if universalTag == TagUTCTime {
871 *v, err = parseUTCTime(innerBytes)
872 return
873 }
874 *v, err = parseGeneralizedTime(innerBytes)
875 return
876 case *Enumerated:
877 parsedInt, err1 := parseInt32(innerBytes)
878 if err1 == nil {
879 *v = Enumerated(parsedInt)
880 }
881 err = err1
882 return
883 case *Flag:
884 *v = true
885 return
886 case **big.Int:
887 parsedInt, err1 := parseBigInt(innerBytes)
888 if err1 == nil {
889 *v = parsedInt
890 }
891 err = err1
892 return
893 }
894 switch val := v; val.Kind() {
895 case reflect.Bool:
896 parsedBool, err1 := parseBool(innerBytes)
897 if err1 == nil {
898 val.SetBool(parsedBool)
899 }
900 err = err1
901 return
902 case reflect.Int, reflect.Int32, reflect.Int64:
903 if val.Type().Size() == 4 {
904 parsedInt, err1 := parseInt32(innerBytes)
905 if err1 == nil {
906 val.SetInt(int64(parsedInt))
907 }
908 err = err1
909 } else {
910 parsedInt, err1 := parseInt64(innerBytes)
911 if err1 == nil {
912 val.SetInt(parsedInt)
913 }
914 err = err1
915 }
916 return
917
918 case reflect.Struct:
919 structType := fieldType
920
921 for i := 0; i < structType.NumField(); i++ {
922 if !structType.Field(i).IsExported() {
923 err = StructuralError{"struct contains unexported fields"}
924 return
925 }
926 }
927
928 if structType.NumField() > 0 &&
929 structType.Field(0).Type == rawContentsType {
930 bytes := bytes[initOffset:offset]
931 val.Field(0).Set(reflect.ValueOf(RawContent(bytes)))
932 }
933
934 innerOffset := 0
935 for i := 0; i < structType.NumField(); i++ {
936 field := structType.Field(i)
937 if i == 0 && field.Type == rawContentsType {
938 continue
939 }
940 innerOffset, err = parseField(val.Field(i), innerBytes, innerOffset, parseFieldParameters(field.Tag.Get("asn1")))
941 if err != nil {
942 return
943 }
944 }
945
946
947
948 return
949 case reflect.Slice:
950 sliceType := fieldType
951 if sliceType.Elem().Kind() == reflect.Uint8 {
952 val.Set(reflect.MakeSlice(sliceType, len(innerBytes), len(innerBytes)))
953 reflect.Copy(val, reflect.ValueOf(innerBytes))
954 return
955 }
956 newSlice, err1 := parseSequenceOf(innerBytes, sliceType, sliceType.Elem())
957 if err1 == nil {
958 val.Set(newSlice)
959 }
960 err = err1
961 return
962 case reflect.String:
963 var v string
964 switch universalTag {
965 case TagPrintableString:
966 v, err = parsePrintableString(innerBytes)
967 case TagNumericString:
968 v, err = parseNumericString(innerBytes)
969 case TagIA5String:
970 v, err = parseIA5String(innerBytes)
971 case TagT61String:
972 v, err = parseT61String(innerBytes)
973 case TagUTF8String:
974 v, err = parseUTF8String(innerBytes)
975 case TagGeneralString:
976
977
978
979
980 v, err = parseT61String(innerBytes)
981 case TagBMPString:
982 v, err = parseBMPString(innerBytes)
983
984 default:
985 err = SyntaxError{fmt.Sprintf("internal error: unknown string type %d", universalTag)}
986 }
987 if err == nil {
988 val.SetString(v)
989 }
990 return
991 }
992 err = StructuralError{"unsupported: " + v.Type().String()}
993 return
994 }
995
996
997
998 func canHaveDefaultValue(k reflect.Kind) bool {
999 switch k {
1000 case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
1001 return true
1002 }
1003
1004 return false
1005 }
1006
1007
1008
1009
1010 func setDefaultValue(v reflect.Value, params fieldParameters) (ok bool) {
1011 if !params.optional {
1012 return
1013 }
1014 ok = true
1015 if params.defaultValue == nil {
1016 return
1017 }
1018 if canHaveDefaultValue(v.Kind()) {
1019 v.SetInt(*params.defaultValue)
1020 }
1021 return
1022 }
1023
1024
1025
1026
1027
1028
1029
1030
1031
1032
1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048
1049
1050
1051
1052
1053
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 func Unmarshal(b []byte, val any) (rest []byte, err error) {
1094 return UnmarshalWithParams(b, val, "")
1095 }
1096
1097
1098
1099 type invalidUnmarshalError struct {
1100 Type reflect.Type
1101 }
1102
1103 func (e *invalidUnmarshalError) Error() string {
1104 if e.Type == nil {
1105 return "asn1: Unmarshal recipient value is nil"
1106 }
1107
1108 if e.Type.Kind() != reflect.Pointer {
1109 return "asn1: Unmarshal recipient value is non-pointer " + e.Type.String()
1110 }
1111 return "asn1: Unmarshal recipient value is nil " + e.Type.String()
1112 }
1113
1114
1115
1116 func UnmarshalWithParams(b []byte, val any, params string) (rest []byte, err error) {
1117 v := reflect.ValueOf(val)
1118 if v.Kind() != reflect.Pointer || v.IsNil() {
1119 return nil, &invalidUnmarshalError{reflect.TypeOf(val)}
1120 }
1121 offset, err := parseField(v.Elem(), b, 0, parseFieldParameters(params))
1122 if err != nil {
1123 return nil, err
1124 }
1125 return b[offset:], nil
1126 }
1127
View as plain text