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