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