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