1 // Copyright 2009 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // Package asn1 implements parsing of DER-encoded ASN.1 data structures,
6 // as defined in ITU-T Rec X.690.
8 // See also ``A Layman's Guide to a Subset of ASN.1, BER, and DER,''
9 // http://luca.ntop.org/Teaching/Appunti/asn1.html.
12 // ASN.1 is a syntax for specifying abstract objects and BER, DER, PER, XER etc
13 // are different encoding formats for those objects. Here, we'll be dealing
14 // with DER, the Distinguished Encoding Rules. DER is used in X.509 because
15 // it's fast to parse and, unlike BER, has a unique encoding for every object.
16 // When calculating hashes over objects, it's important that the resulting
17 // bytes be the same at both ends and DER removes this margin of error.
19 // ASN.1 is very complex and this package doesn't attempt to implement
20 // everything by any means.
30 // A StructuralError suggests that the ASN.1 data is valid, but the Go type
31 // which is receiving it doesn't match.
32 type StructuralError
struct {
36 func (e StructuralError
) Error() string { return "asn1: structure error: " + e
.Msg
}
38 // A SyntaxError suggests that the ASN.1 data is invalid.
39 type SyntaxError
struct {
43 func (e SyntaxError
) Error() string { return "asn1: syntax error: " + e
.Msg
}
45 // We start by dealing with each of the primitive types in turn.
49 func parseBool(bytes
[]byte) (ret
bool, err error
) {
51 err
= SyntaxError
{"invalid boolean"}
55 // DER demands that "If the encoding represents the boolean value TRUE,
56 // its single contents octet shall have all eight bits set to one."
57 // Thus only 0 and 255 are valid encoded values.
64 err
= SyntaxError
{"invalid boolean"}
72 // parseInt64 treats the given bytes as a big-endian, signed integer and
73 // returns the result.
74 func parseInt64(bytes
[]byte) (ret
int64, err error
) {
76 // We'll overflow an int64 in this case.
77 err
= StructuralError
{"integer too large"}
80 for bytesRead
:= 0; bytesRead
< len(bytes
); bytesRead
++ {
82 ret |
= int64(bytes
[bytesRead
])
85 // Shift up and down in order to sign extend the result.
86 ret
<<= 64 - uint8(len(bytes
))*8
87 ret
>>= 64 - uint8(len(bytes
))*8
91 // parseInt treats the given bytes as a big-endian, signed integer and returns
93 func parseInt32(bytes
[]byte) (int32, error
) {
94 ret64
, err
:= parseInt64(bytes
)
98 if ret64
!= int64(int32(ret64
)) {
99 return 0, StructuralError
{"integer too large"}
101 return int32(ret64
), nil
104 var bigOne
= big
.NewInt(1)
106 // parseBigInt treats the given bytes as a big-endian, signed integer and returns
108 func parseBigInt(bytes
[]byte) *big
.Int
{
110 if len(bytes
) > 0 && bytes
[0]&0x80 == 0x80 {
111 // This is a negative number.
112 notBytes
:= make([]byte, len(bytes
))
113 for i
:= range notBytes
{
114 notBytes
[i
] = ^bytes
[i
]
116 ret
.SetBytes(notBytes
)
127 // BitString is the structure to use when you want an ASN.1 BIT STRING type. A
128 // bit string is padded up to the nearest byte in memory and the number of
129 // valid bits is recorded. Padding bits will be zero.
130 type BitString
struct {
131 Bytes
[]byte // bits packed into bytes.
132 BitLength
int // length in bits.
135 // At returns the bit at the given index. If the index is out of range it
137 func (b BitString
) At(i
int) int {
138 if i
< 0 || i
>= b
.BitLength
{
143 return int(b
.Bytes
[x
]>>y
) & 1
146 // RightAlign returns a slice where the padding bits are at the beginning. The
147 // slice may share memory with the BitString.
148 func (b BitString
) RightAlign() []byte {
149 shift
:= uint(8 - (b
.BitLength
% 8))
150 if shift
== 8 ||
len(b
.Bytes
) == 0 {
154 a
:= make([]byte, len(b
.Bytes
))
155 a
[0] = b
.Bytes
[0] >> shift
156 for i
:= 1; i
< len(b
.Bytes
); i
++ {
157 a
[i
] = b
.Bytes
[i
-1] << (8 - shift
)
158 a
[i
] |
= b
.Bytes
[i
] >> shift
164 // parseBitString parses an ASN.1 bit string from the given byte slice and returns it.
165 func parseBitString(bytes
[]byte) (ret BitString
, err error
) {
167 err
= SyntaxError
{"zero length BIT STRING"}
170 paddingBits
:= int(bytes
[0])
171 if paddingBits
> 7 ||
172 len(bytes
) == 1 && paddingBits
> 0 ||
173 bytes
[len(bytes
)-1]&((1<<bytes
[0])-1) != 0 {
174 err
= SyntaxError
{"invalid padding bits in BIT STRING"}
177 ret
.BitLength
= (len(bytes
)-1)*8 - paddingBits
178 ret
.Bytes
= bytes
[1:]
184 // An ObjectIdentifier represents an ASN.1 OBJECT IDENTIFIER.
185 type ObjectIdentifier
[]int
187 // Equal reports whether oi and other represent the same identifier.
188 func (oi ObjectIdentifier
) Equal(other ObjectIdentifier
) bool {
189 if len(oi
) != len(other
) {
192 for i
:= 0; i
< len(oi
); i
++ {
193 if oi
[i
] != other
[i
] {
201 func (oi ObjectIdentifier
) String() string {
204 for i
, v
:= range oi
{
214 // parseObjectIdentifier parses an OBJECT IDENTIFIER from the given bytes and
215 // returns it. An object identifier is a sequence of variable length integers
216 // that are assigned in a hierarchy.
217 func parseObjectIdentifier(bytes
[]byte) (s
[]int, err error
) {
219 err
= SyntaxError
{"zero length OBJECT IDENTIFIER"}
223 // In the worst case, we get two elements from the first byte (which is
224 // encoded differently) and then every varint is a single byte long.
225 s
= make([]int, len(bytes
)+1)
227 // The first varint is 40*value1 + value2:
228 // According to this packing, value1 can take the values 0, 1 and 2 only.
229 // When value1 = 0 or value1 = 1, then value2 is <= 39. When value1 = 2,
230 // then there are no restrictions on value2.
231 v
, offset
, err
:= parseBase128Int(bytes
, 0)
244 for ; offset
< len(bytes
); i
++ {
245 v
, offset
, err
= parseBase128Int(bytes
, offset
)
257 // An Enumerated is represented as a plain int.
262 // A Flag accepts any data and is set to true if present.
265 // parseBase128Int parses a base-128 encoded int from the given offset in the
266 // given byte slice. It returns the value and the new offset.
267 func parseBase128Int(bytes
[]byte, initOffset
int) (ret
, offset
int, err error
) {
269 for shifted
:= 0; offset
< len(bytes
); shifted
++ {
271 err
= StructuralError
{"base 128 integer too large"}
282 err
= SyntaxError
{"truncated base 128 integer"}
288 func parseUTCTime(bytes
[]byte) (ret time
.Time
, err error
) {
290 ret
, err
= time
.Parse("0601021504Z0700", s
)
292 ret
, err
= time
.Parse("060102150405Z0700", s
)
294 if err
== nil && ret
.Year() >= 2050 {
295 // UTCTime only encodes times prior to 2050. See https://tools.ietf.org/html/rfc5280#section-4.1.2.5.1
296 ret
= ret
.AddDate(-100, 0, 0)
302 // parseGeneralizedTime parses the GeneralizedTime from the given byte slice
303 // and returns the resulting time.
304 func parseGeneralizedTime(bytes
[]byte) (ret time
.Time
, err error
) {
305 return time
.Parse("20060102150405Z0700", string(bytes
))
310 // parsePrintableString parses a ASN.1 PrintableString from the given byte
311 // array and returns it.
312 func parsePrintableString(bytes
[]byte) (ret
string, err error
) {
313 for _
, b
:= range bytes
{
315 err
= SyntaxError
{"PrintableString contains invalid character"}
323 // isPrintable returns true iff the given b is in the ASN.1 PrintableString set.
324 func isPrintable(b
byte) bool {
325 return 'a' <= b
&& b
<= 'z' ||
326 'A' <= b
&& b
<= 'Z' ||
327 '0' <= b
&& b
<= '9' ||
328 '\'' <= b
&& b
<= ')' ||
329 '+' <= b
&& b
<= '/' ||
334 // This is technically not allowed in a PrintableString.
335 // However, x509 certificates with wildcard strings don't
336 // always use the correct string type so we permit it.
342 // parseIA5String parses a ASN.1 IA5String (ASCII string) from the given
343 // byte slice and returns it.
344 func parseIA5String(bytes
[]byte) (ret
string, err error
) {
345 for _
, b
:= range bytes
{
347 err
= SyntaxError
{"IA5String contains invalid character"}
357 // parseT61String parses a ASN.1 T61String (8-bit clean string) from the given
358 // byte slice and returns it.
359 func parseT61String(bytes
[]byte) (ret
string, err error
) {
360 return string(bytes
), nil
365 // parseUTF8String parses a ASN.1 UTF8String (raw UTF-8) from the given byte
366 // array and returns it.
367 func parseUTF8String(bytes
[]byte) (ret
string, err error
) {
368 return string(bytes
), nil
371 // A RawValue represents an undecoded ASN.1 object.
372 type RawValue
struct {
376 FullBytes
[]byte // includes the tag and length
379 // RawContent is used to signal that the undecoded, DER data needs to be
380 // preserved for a struct. To use it, the first field of the struct must have
381 // this type. It's an error for any of the other fields to have this type.
382 type RawContent
[]byte
386 // parseTagAndLength parses an ASN.1 tag and length pair from the given offset
387 // into a byte slice. It returns the parsed data and the new offset. SET and
388 // SET OF (tag 17) are mapped to SEQUENCE and SEQUENCE OF (tag 16) since we
389 // don't distinguish between ordered and unordered objects in this code.
390 func parseTagAndLength(bytes
[]byte, initOffset
int) (ret tagAndLength
, offset
int, err error
) {
394 ret
.class
= int(b
>> 6)
395 ret
.isCompound
= b
&0x20 == 0x20
396 ret
.tag
= int(b
& 0x1f)
398 // If the bottom five bits are set, then the tag number is actually base 128
399 // encoded afterwards
401 ret
.tag
, offset
, err
= parseBase128Int(bytes
, offset
)
406 if offset
>= len(bytes
) {
407 err
= SyntaxError
{"truncated tag or length"}
413 // The length is encoded in the bottom 7 bits.
414 ret
.length
= int(b
& 0x7f)
416 // Bottom 7 bits give the number of length bytes to follow.
417 numBytes
:= int(b
& 0x7f)
419 err
= SyntaxError
{"indefinite length found (not DER)"}
423 for i
:= 0; i
< numBytes
; i
++ {
424 if offset
>= len(bytes
) {
425 err
= SyntaxError
{"truncated tag or length"}
430 if ret
.length
>= 1<<23 {
431 // We can't shift ret.length up without
433 err
= StructuralError
{"length too large"}
439 // DER requires that lengths be minimal.
440 err
= StructuralError
{"superfluous leading zeros in length"}
449 // parseSequenceOf is used for SEQUENCE OF and SET OF values. It tries to parse
450 // a number of ASN.1 values from the given byte slice and returns them as a
451 // slice of Go values of the given type.
452 func parseSequenceOf(bytes
[]byte, sliceType reflect
.Type
, elemType reflect
.Type
) (ret reflect
.Value
, err error
) {
453 expectedTag
, compoundType
, ok
:= getUniversalType(elemType
)
455 err
= StructuralError
{"unknown Go type for slice"}
459 // First we iterate over the input and count the number of elements,
460 // checking that the types are correct in each case.
462 for offset
:= 0; offset
< len(bytes
); {
464 t
, offset
, err
= parseTagAndLength(bytes
, offset
)
469 case tagIA5String
, tagGeneralString
, tagT61String
, tagUTF8String
:
470 // We pretend that various other string types are
471 // PRINTABLE STRINGs so that a sequence of them can be
472 // parsed into a []string.
473 t
.tag
= tagPrintableString
474 case tagGeneralizedTime
, tagUTCTime
:
475 // Likewise, both time types are treated the same.
479 if t
.class
!= classUniversal || t
.isCompound
!= compoundType || t
.tag
!= expectedTag
{
480 err
= StructuralError
{"sequence tag mismatch"}
483 if invalidLength(offset
, t
.length
, len(bytes
)) {
484 err
= SyntaxError
{"truncated sequence"}
490 ret
= reflect
.MakeSlice(sliceType
, numElements
, numElements
)
491 params
:= fieldParameters
{}
493 for i
:= 0; i
< numElements
; i
++ {
494 offset
, err
= parseField(ret
.Index(i
), bytes
, offset
, params
)
503 bitStringType
= reflect
.TypeOf(BitString
{})
504 objectIdentifierType
= reflect
.TypeOf(ObjectIdentifier
{})
505 enumeratedType
= reflect
.TypeOf(Enumerated(0))
506 flagType
= reflect
.TypeOf(Flag(false))
507 timeType
= reflect
.TypeOf(time
.Time
{})
508 rawValueType
= reflect
.TypeOf(RawValue
{})
509 rawContentsType
= reflect
.TypeOf(RawContent(nil))
510 bigIntType
= reflect
.TypeOf(new(big
.Int
))
513 // invalidLength returns true iff offset + length > sliceLength, or if the
514 // addition would overflow.
515 func invalidLength(offset
, length
, sliceLength
int) bool {
516 return offset
+length
< offset || offset
+length
> sliceLength
519 // parseField is the main parsing function. Given a byte slice and an offset
520 // into the array, it will try to parse a suitable ASN.1 value out and store it
521 // in the given Value.
522 func parseField(v reflect
.Value
, bytes
[]byte, initOffset
int, params fieldParameters
) (offset
int, err error
) {
524 fieldType
:= v
.Type()
526 // If we have run out of data, it may be that there are optional elements at the end.
527 if offset
== len(bytes
) {
528 if !setDefaultValue(v
, params
) {
529 err
= SyntaxError
{"sequence truncated"}
534 // Deal with raw values.
535 if fieldType
== rawValueType
{
537 t
, offset
, err
= parseTagAndLength(bytes
, offset
)
541 if invalidLength(offset
, t
.length
, len(bytes
)) {
542 err
= SyntaxError
{"data truncated"}
545 result
:= RawValue
{t
.class
, t
.tag
, t
.isCompound
, bytes
[offset
: offset
+t
.length
], bytes
[initOffset
: offset
+t
.length
]}
547 v
.Set(reflect
.ValueOf(result
))
551 // Deal with the ANY type.
552 if ifaceType
:= fieldType
; ifaceType
.Kind() == reflect
.Interface
&& ifaceType
.NumMethod() == 0 {
554 t
, offset
, err
= parseTagAndLength(bytes
, offset
)
558 if invalidLength(offset
, t
.length
, len(bytes
)) {
559 err
= SyntaxError
{"data truncated"}
562 var result
interface{}
563 if !t
.isCompound
&& t
.class
== classUniversal
{
564 innerBytes
:= bytes
[offset
: offset
+t
.length
]
566 case tagPrintableString
:
567 result
, err
= parsePrintableString(innerBytes
)
569 result
, err
= parseIA5String(innerBytes
)
571 result
, err
= parseT61String(innerBytes
)
573 result
, err
= parseUTF8String(innerBytes
)
575 result
, err
= parseInt64(innerBytes
)
577 result
, err
= parseBitString(innerBytes
)
579 result
, err
= parseObjectIdentifier(innerBytes
)
581 result
, err
= parseUTCTime(innerBytes
)
585 // If we don't know how to handle the type, we just leave Value as nil.
593 v
.Set(reflect
.ValueOf(result
))
597 universalTag
, compoundType
, ok1
:= getUniversalType(fieldType
)
599 err
= StructuralError
{fmt
.Sprintf("unknown Go type: %v", fieldType
)}
603 t
, offset
, err
:= parseTagAndLength(bytes
, offset
)
608 expectedClass
:= classContextSpecific
609 if params
.application
{
610 expectedClass
= classApplication
612 if t
.class
== expectedClass
&& t
.tag
== *params
.tag
&& (t
.length
== 0 || t
.isCompound
) {
614 t
, offset
, err
= parseTagAndLength(bytes
, offset
)
619 if fieldType
!= flagType
{
620 err
= StructuralError
{"zero length explicit tag was not an asn1.Flag"}
627 // The tags didn't match, it might be an optional element.
628 ok
:= setDefaultValue(v
, params
)
632 err
= StructuralError
{"explicitly tagged member didn't match"}
638 // Special case for strings: all the ASN.1 string types map to the Go
639 // type string. getUniversalType returns the tag for PrintableString
640 // when it sees a string, so if we see a different string type on the
641 // wire, we change the universal type to match.
642 if universalTag
== tagPrintableString
{
644 case tagIA5String
, tagGeneralString
, tagT61String
, tagUTF8String
:
649 // Special case for time: UTCTime and GeneralizedTime both map to the
650 // Go type time.Time.
651 if universalTag
== tagUTCTime
&& t
.tag
== tagGeneralizedTime
{
652 universalTag
= tagGeneralizedTime
656 universalTag
= tagSet
659 expectedClass
:= classUniversal
660 expectedTag
:= universalTag
662 if !params
.explicit
&& params
.tag
!= nil {
663 expectedClass
= classContextSpecific
664 expectedTag
= *params
.tag
667 if !params
.explicit
&& params
.application
&& params
.tag
!= nil {
668 expectedClass
= classApplication
669 expectedTag
= *params
.tag
672 // We have unwrapped any explicit tagging at this point.
673 if t
.class
!= expectedClass || t
.tag
!= expectedTag || t
.isCompound
!= compoundType
{
674 // Tags don't match. Again, it could be an optional element.
675 ok
:= setDefaultValue(v
, params
)
679 err
= StructuralError
{fmt
.Sprintf("tags don't match (%d vs %+v) %+v %s @%d", expectedTag
, t
, params
, fieldType
.Name(), offset
)}
683 if invalidLength(offset
, t
.length
, len(bytes
)) {
684 err
= SyntaxError
{"data truncated"}
687 innerBytes
:= bytes
[offset
: offset
+t
.length
]
690 // We deal with the structures defined in this package first.
692 case objectIdentifierType
:
693 newSlice
, err1
:= parseObjectIdentifier(innerBytes
)
694 v
.Set(reflect
.MakeSlice(v
.Type(), len(newSlice
), len(newSlice
)))
696 reflect
.Copy(v
, reflect
.ValueOf(newSlice
))
701 bs
, err1
:= parseBitString(innerBytes
)
703 v
.Set(reflect
.ValueOf(bs
))
710 if universalTag
== tagUTCTime
{
711 time
, err1
= parseUTCTime(innerBytes
)
713 time
, err1
= parseGeneralizedTime(innerBytes
)
716 v
.Set(reflect
.ValueOf(time
))
721 parsedInt
, err1
:= parseInt32(innerBytes
)
723 v
.SetInt(int64(parsedInt
))
731 parsedInt
:= parseBigInt(innerBytes
)
732 v
.Set(reflect
.ValueOf(parsedInt
))
735 switch val
:= v
; val
.Kind() {
737 parsedBool
, err1
:= parseBool(innerBytes
)
739 val
.SetBool(parsedBool
)
743 case reflect
.Int
, reflect
.Int32
, reflect
.Int64
:
744 if val
.Type().Size() == 4 {
745 parsedInt
, err1
:= parseInt32(innerBytes
)
747 val
.SetInt(int64(parsedInt
))
751 parsedInt
, err1
:= parseInt64(innerBytes
)
753 val
.SetInt(parsedInt
)
758 // TODO(dfc) Add support for the remaining integer types
760 structType
:= fieldType
762 if structType
.NumField() > 0 &&
763 structType
.Field(0).Type
== rawContentsType
{
764 bytes
:= bytes
[initOffset
:offset
]
765 val
.Field(0).Set(reflect
.ValueOf(RawContent(bytes
)))
769 for i
:= 0; i
< structType
.NumField(); i
++ {
770 field
:= structType
.Field(i
)
771 if i
== 0 && field
.Type
== rawContentsType
{
774 innerOffset
, err
= parseField(val
.Field(i
), innerBytes
, innerOffset
, parseFieldParameters(field
.Tag
.Get("asn1")))
779 // We allow extra bytes at the end of the SEQUENCE because
780 // adding elements to the end has been used in X.509 as the
781 // version numbers have increased.
784 sliceType
:= fieldType
785 if sliceType
.Elem().Kind() == reflect
.Uint8
{
786 val
.Set(reflect
.MakeSlice(sliceType
, len(innerBytes
), len(innerBytes
)))
787 reflect
.Copy(val
, reflect
.ValueOf(innerBytes
))
790 newSlice
, err1
:= parseSequenceOf(innerBytes
, sliceType
, sliceType
.Elem())
798 switch universalTag
{
799 case tagPrintableString
:
800 v
, err
= parsePrintableString(innerBytes
)
802 v
, err
= parseIA5String(innerBytes
)
804 v
, err
= parseT61String(innerBytes
)
806 v
, err
= parseUTF8String(innerBytes
)
807 case tagGeneralString
:
808 // GeneralString is specified in ISO-2022/ECMA-35,
809 // A brief review suggests that it includes structures
810 // that allow the encoding to change midstring and
811 // such. We give up and pass it as an 8-bit string.
812 v
, err
= parseT61String(innerBytes
)
814 err
= SyntaxError
{fmt
.Sprintf("internal error: unknown string type %d", universalTag
)}
821 err
= StructuralError
{"unsupported: " + v
.Type().String()}
825 // setDefaultValue is used to install a default value, from a tag string, into
826 // a Value. It is successful is the field was optional, even if a default value
827 // wasn't provided or it failed to install it into the Value.
828 func setDefaultValue(v reflect
.Value
, params fieldParameters
) (ok
bool) {
829 if !params
.optional
{
833 if params
.defaultValue
== nil {
836 switch val
:= v
; val
.Kind() {
837 case reflect
.Int
, reflect
.Int8
, reflect
.Int16
, reflect
.Int32
, reflect
.Int64
:
838 val
.SetInt(*params
.defaultValue
)
843 // Unmarshal parses the DER-encoded ASN.1 data structure b
844 // and uses the reflect package to fill in an arbitrary value pointed at by val.
845 // Because Unmarshal uses the reflect package, the structs
846 // being written to must use upper case field names.
848 // An ASN.1 INTEGER can be written to an int, int32, int64,
849 // or *big.Int (from the math/big package).
850 // If the encoded value does not fit in the Go type,
851 // Unmarshal returns a parse error.
853 // An ASN.1 BIT STRING can be written to a BitString.
855 // An ASN.1 OCTET STRING can be written to a []byte.
857 // An ASN.1 OBJECT IDENTIFIER can be written to an
860 // An ASN.1 ENUMERATED can be written to an Enumerated.
862 // An ASN.1 UTCTIME or GENERALIZEDTIME can be written to a time.Time.
864 // An ASN.1 PrintableString or IA5String can be written to a string.
866 // Any of the above ASN.1 values can be written to an interface{}.
867 // The value stored in the interface has the corresponding Go type.
868 // For integers, that type is int64.
870 // An ASN.1 SEQUENCE OF x or SET OF x can be written
871 // to a slice if an x can be written to the slice's element type.
873 // An ASN.1 SEQUENCE or SET can be written to a struct
874 // if each of the elements in the sequence can be
875 // written to the corresponding element in the struct.
877 // The following tags on struct fields have special meaning to Unmarshal:
879 // application specifies that a APPLICATION tag is used
880 // default:x sets the default value for optional integer fields
881 // explicit specifies that an additional, explicit tag wraps the implicit one
882 // optional marks the field as ASN.1 OPTIONAL
883 // set causes a SET, rather than a SEQUENCE type to be expected
884 // tag:x specifies the ASN.1 tag number; implies ASN.1 CONTEXT SPECIFIC
886 // If the type of the first field of a structure is RawContent then the raw
887 // ASN1 contents of the struct will be stored in it.
889 // If the type name of a slice element ends with "SET" then it's treated as if
890 // the "set" tag was set on it. This can be used with nested slices where a
891 // struct tag cannot be given.
893 // Other ASN.1 types are not supported; if it encounters them,
894 // Unmarshal returns a parse error.
895 func Unmarshal(b
[]byte, val
interface{}) (rest
[]byte, err error
) {
896 return UnmarshalWithParams(b
, val
, "")
899 // UnmarshalWithParams allows field parameters to be specified for the
900 // top-level element. The form of the params is the same as the field tags.
901 func UnmarshalWithParams(b
[]byte, val
interface{}, params
string) (rest
[]byte, err error
) {
902 v
:= reflect
.ValueOf(val
).Elem()
903 offset
, err
:= parseField(v
, b
, 0, parseFieldParameters(params
))
907 return b
[offset
:], nil