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