tls.go 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711
  1. // Copyright 2016 Google LLC. All Rights Reserved.
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. // Package tls implements functionality for dealing with TLS-encoded data,
  15. // as defined in RFC 5246. This includes parsing and generation of TLS-encoded
  16. // data, together with utility functions for dealing with the DigitallySigned
  17. // TLS type.
  18. package tls
  19. import (
  20. "bytes"
  21. "encoding/binary"
  22. "fmt"
  23. "reflect"
  24. "strconv"
  25. "strings"
  26. )
  27. // This file holds utility functions for TLS encoding/decoding data
  28. // as per RFC 5246 section 4.
  29. // A structuralError suggests that the TLS data is valid, but the Go type
  30. // which is receiving it doesn't match.
  31. type structuralError struct {
  32. field string
  33. msg string
  34. }
  35. func (e structuralError) Error() string {
  36. var prefix string
  37. if e.field != "" {
  38. prefix = e.field + ": "
  39. }
  40. return "tls: structure error: " + prefix + e.msg
  41. }
  42. // A syntaxError suggests that the TLS data is invalid.
  43. type syntaxError struct {
  44. field string
  45. msg string
  46. }
  47. func (e syntaxError) Error() string {
  48. var prefix string
  49. if e.field != "" {
  50. prefix = e.field + ": "
  51. }
  52. return "tls: syntax error: " + prefix + e.msg
  53. }
  54. // Uint24 is an unsigned 3-byte integer.
  55. type Uint24 uint32
  56. // Enum is an unsigned integer.
  57. type Enum uint64
  58. var (
  59. uint8Type = reflect.TypeOf(uint8(0))
  60. uint16Type = reflect.TypeOf(uint16(0))
  61. uint24Type = reflect.TypeOf(Uint24(0))
  62. uint32Type = reflect.TypeOf(uint32(0))
  63. uint64Type = reflect.TypeOf(uint64(0))
  64. enumType = reflect.TypeOf(Enum(0))
  65. )
  66. // Unmarshal parses the TLS-encoded data in b and uses the reflect package to
  67. // fill in an arbitrary value pointed at by val. Because Unmarshal uses the
  68. // reflect package, the structs being written to must use exported fields
  69. // (upper case names).
  70. //
  71. // The mappings between TLS types and Go types is as follows; some fields
  72. // must have tags (to indicate their encoded size).
  73. //
  74. // TLS Go Required Tags
  75. // opaque byte / uint8
  76. // uint8 byte / uint8
  77. // uint16 uint16
  78. // uint24 tls.Uint24
  79. // uint32 uint32
  80. // uint64 uint64
  81. // enum tls.Enum size:S or maxval:N
  82. // Type<N,M> []Type minlen:N,maxlen:M
  83. // opaque[N] [N]byte / [N]uint8
  84. // uint8[N] [N]byte / [N]uint8
  85. // struct { } struct { }
  86. // select(T) {
  87. // case e1: Type *T selector:Field,val:e1
  88. // }
  89. //
  90. // TLS variants (RFC 5246 s4.6.1) are only supported when the value of the
  91. // associated enumeration type is available earlier in the same enclosing
  92. // struct, and each possible variant is marked with a selector tag (to
  93. // indicate which field selects the variants) and a val tag (to indicate
  94. // what value of the selector picks this particular field).
  95. //
  96. // For example, a TLS structure:
  97. //
  98. // enum { e1(1), e2(2) } EnumType;
  99. // struct {
  100. // EnumType sel;
  101. // select(sel) {
  102. // case e1: uint16
  103. // case e2: uint32
  104. // } data;
  105. // } VariantItem;
  106. //
  107. // would have a corresponding Go type:
  108. //
  109. // type VariantItem struct {
  110. // Sel tls.Enum `tls:"maxval:2"`
  111. // Data16 *uint16 `tls:"selector:Sel,val:1"`
  112. // Data32 *uint32 `tls:"selector:Sel,val:2"`
  113. // }
  114. //
  115. // TLS fixed-length vectors of types other than opaque or uint8 are not supported.
  116. //
  117. // For TLS variable-length vectors that are themselves used in other vectors,
  118. // create a single-field structure to represent the inner type. For example, for:
  119. //
  120. // opaque InnerType<1..65535>;
  121. // struct {
  122. // InnerType inners<1,65535>;
  123. // } Something;
  124. //
  125. // convert to:
  126. //
  127. // type InnerType struct {
  128. // Val []byte `tls:"minlen:1,maxlen:65535"`
  129. // }
  130. // type Something struct {
  131. // Inners []InnerType `tls:"minlen:1,maxlen:65535"`
  132. // }
  133. //
  134. // If the encoded value does not fit in the Go type, Unmarshal returns a parse error.
  135. func Unmarshal(b []byte, val interface{}) ([]byte, error) {
  136. return UnmarshalWithParams(b, val, "")
  137. }
  138. // UnmarshalWithParams allows field parameters to be specified for the
  139. // top-level element. The form of the params is the same as the field tags.
  140. func UnmarshalWithParams(b []byte, val interface{}, params string) ([]byte, error) {
  141. info, err := fieldTagToFieldInfo(params, "")
  142. if err != nil {
  143. return nil, err
  144. }
  145. // The passed in interface{} is a pointer (to allow the value to be written
  146. // to); extract the pointed-to object as a reflect.Value, so parseField
  147. // can do various introspection things.
  148. v := reflect.ValueOf(val).Elem()
  149. offset, err := parseField(v, b, 0, info)
  150. if err != nil {
  151. return nil, err
  152. }
  153. return b[offset:], nil
  154. }
  155. // Return the number of bytes needed to encode values up to (and including) x.
  156. func byteCount(x uint64) uint {
  157. switch {
  158. case x < 0x100:
  159. return 1
  160. case x < 0x10000:
  161. return 2
  162. case x < 0x1000000:
  163. return 3
  164. case x < 0x100000000:
  165. return 4
  166. case x < 0x10000000000:
  167. return 5
  168. case x < 0x1000000000000:
  169. return 6
  170. case x < 0x100000000000000:
  171. return 7
  172. default:
  173. return 8
  174. }
  175. }
  176. type fieldInfo struct {
  177. count uint // Number of bytes
  178. countSet bool
  179. minlen uint64 // Only relevant for slices
  180. maxlen uint64 // Only relevant for slices
  181. selector string // Only relevant for select sub-values
  182. val uint64 // Only relevant for select sub-values
  183. name string // Used for better error messages
  184. }
  185. func (i *fieldInfo) fieldName() string {
  186. if i == nil {
  187. return ""
  188. }
  189. return i.name
  190. }
  191. // Given a tag string, return a fieldInfo describing the field.
  192. func fieldTagToFieldInfo(str string, name string) (*fieldInfo, error) {
  193. var info *fieldInfo
  194. // Iterate over clauses in the tag, ignoring any that don't parse properly.
  195. for _, part := range strings.Split(str, ",") {
  196. switch {
  197. case strings.HasPrefix(part, "maxval:"):
  198. if v, err := strconv.ParseUint(part[7:], 10, 64); err == nil {
  199. info = &fieldInfo{count: byteCount(v), countSet: true}
  200. }
  201. case strings.HasPrefix(part, "size:"):
  202. if sz, err := strconv.ParseUint(part[5:], 10, 32); err == nil {
  203. info = &fieldInfo{count: uint(sz), countSet: true}
  204. }
  205. case strings.HasPrefix(part, "maxlen:"):
  206. v, err := strconv.ParseUint(part[7:], 10, 64)
  207. if err != nil {
  208. continue
  209. }
  210. if info == nil {
  211. info = &fieldInfo{}
  212. }
  213. info.count = byteCount(v)
  214. info.countSet = true
  215. info.maxlen = v
  216. case strings.HasPrefix(part, "minlen:"):
  217. v, err := strconv.ParseUint(part[7:], 10, 64)
  218. if err != nil {
  219. continue
  220. }
  221. if info == nil {
  222. info = &fieldInfo{}
  223. }
  224. info.minlen = v
  225. case strings.HasPrefix(part, "selector:"):
  226. if info == nil {
  227. info = &fieldInfo{}
  228. }
  229. info.selector = part[9:]
  230. case strings.HasPrefix(part, "val:"):
  231. v, err := strconv.ParseUint(part[4:], 10, 64)
  232. if err != nil {
  233. continue
  234. }
  235. if info == nil {
  236. info = &fieldInfo{}
  237. }
  238. info.val = v
  239. }
  240. }
  241. if info != nil {
  242. info.name = name
  243. if info.selector == "" {
  244. if info.count < 1 {
  245. return nil, structuralError{name, "field of unknown size in " + str}
  246. } else if info.count > 8 {
  247. return nil, structuralError{name, "specified size too large in " + str}
  248. } else if info.minlen > info.maxlen {
  249. return nil, structuralError{name, "specified length range inverted in " + str}
  250. } else if info.val > 0 {
  251. return nil, structuralError{name, "specified selector value but not field in " + str}
  252. }
  253. }
  254. } else if name != "" {
  255. info = &fieldInfo{name: name}
  256. }
  257. return info, nil
  258. }
  259. // Check that a value fits into a field described by a fieldInfo structure.
  260. func (i fieldInfo) check(val uint64, fldName string) error {
  261. if val >= (1 << (8 * i.count)) {
  262. return structuralError{fldName, fmt.Sprintf("value %d too large for size", val)}
  263. }
  264. if i.maxlen != 0 {
  265. if val < i.minlen {
  266. return structuralError{fldName, fmt.Sprintf("value %d too small for minimum %d", val, i.minlen)}
  267. }
  268. if val > i.maxlen {
  269. return structuralError{fldName, fmt.Sprintf("value %d too large for maximum %d", val, i.maxlen)}
  270. }
  271. }
  272. return nil
  273. }
  274. // readVarUint reads an big-endian unsigned integer of the given size in
  275. // bytes.
  276. func readVarUint(data []byte, info *fieldInfo) (uint64, error) {
  277. if info == nil || !info.countSet {
  278. return 0, structuralError{info.fieldName(), "no field size information available"}
  279. }
  280. if len(data) < int(info.count) {
  281. return 0, syntaxError{info.fieldName(), "truncated variable-length integer"}
  282. }
  283. var result uint64
  284. for i := uint(0); i < info.count; i++ {
  285. result = (result << 8) | uint64(data[i])
  286. }
  287. if err := info.check(result, info.name); err != nil {
  288. return 0, err
  289. }
  290. return result, nil
  291. }
  292. // parseField is the main parsing function. Given a byte slice and an offset
  293. // (in bytes) into the data, it will try to parse a suitable ASN.1 value out
  294. // and store it in the given Value.
  295. func parseField(v reflect.Value, data []byte, initOffset int, info *fieldInfo) (int, error) {
  296. offset := initOffset
  297. rest := data[offset:]
  298. fieldType := v.Type()
  299. // First look for known fixed types.
  300. switch fieldType {
  301. case uint8Type:
  302. if len(rest) < 1 {
  303. return offset, syntaxError{info.fieldName(), "truncated uint8"}
  304. }
  305. v.SetUint(uint64(rest[0]))
  306. offset++
  307. return offset, nil
  308. case uint16Type:
  309. if len(rest) < 2 {
  310. return offset, syntaxError{info.fieldName(), "truncated uint16"}
  311. }
  312. v.SetUint(uint64(binary.BigEndian.Uint16(rest)))
  313. offset += 2
  314. return offset, nil
  315. case uint24Type:
  316. if len(rest) < 3 {
  317. return offset, syntaxError{info.fieldName(), "truncated uint24"}
  318. }
  319. v.SetUint(uint64(data[0])<<16 | uint64(data[1])<<8 | uint64(data[2]))
  320. offset += 3
  321. return offset, nil
  322. case uint32Type:
  323. if len(rest) < 4 {
  324. return offset, syntaxError{info.fieldName(), "truncated uint32"}
  325. }
  326. v.SetUint(uint64(binary.BigEndian.Uint32(rest)))
  327. offset += 4
  328. return offset, nil
  329. case uint64Type:
  330. if len(rest) < 8 {
  331. return offset, syntaxError{info.fieldName(), "truncated uint64"}
  332. }
  333. v.SetUint(uint64(binary.BigEndian.Uint64(rest)))
  334. offset += 8
  335. return offset, nil
  336. }
  337. // Now deal with user-defined types.
  338. switch v.Kind() {
  339. case enumType.Kind():
  340. // Assume that anything of the same kind as Enum is an Enum, so that
  341. // users can alias types of their own to Enum.
  342. val, err := readVarUint(rest, info)
  343. if err != nil {
  344. return offset, err
  345. }
  346. v.SetUint(val)
  347. offset += int(info.count)
  348. return offset, nil
  349. case reflect.Struct:
  350. structType := fieldType
  351. // TLS includes a select(Enum) {..} construct, where the value of an enum
  352. // indicates which variant field is present (like a C union). We require
  353. // that the enum value be an earlier field in the same structure (the selector),
  354. // and that each of the possible variant destination fields be pointers.
  355. // So the Go mapping looks like:
  356. // type variantType struct {
  357. // Which tls.Enum `tls:"size:1"` // this is the selector
  358. // Val1 *type1 `tls:"selector:Which,val:1"` // this is a destination
  359. // Val2 *type2 `tls:"selector:Which,val:1"` // this is a destination
  360. // }
  361. // To deal with this, we track any enum-like fields and their values...
  362. enums := make(map[string]uint64)
  363. // .. and we track which selector names we've seen (in the destination field tags),
  364. // and whether a destination for that selector has been chosen.
  365. selectorSeen := make(map[string]bool)
  366. for i := 0; i < structType.NumField(); i++ {
  367. // Find information about this field.
  368. tag := structType.Field(i).Tag.Get("tls")
  369. fieldInfo, err := fieldTagToFieldInfo(tag, structType.Field(i).Name)
  370. if err != nil {
  371. return offset, err
  372. }
  373. destination := v.Field(i)
  374. if fieldInfo.selector != "" {
  375. // This is a possible select(Enum) destination, so first check that the referenced
  376. // selector field has already been seen earlier in the struct.
  377. choice, ok := enums[fieldInfo.selector]
  378. if !ok {
  379. return offset, structuralError{fieldInfo.name, "selector not seen: " + fieldInfo.selector}
  380. }
  381. if structType.Field(i).Type.Kind() != reflect.Ptr {
  382. return offset, structuralError{fieldInfo.name, "choice field not a pointer type"}
  383. }
  384. // Is this the first mention of the selector field name? If so, remember it.
  385. seen, ok := selectorSeen[fieldInfo.selector]
  386. if !ok {
  387. selectorSeen[fieldInfo.selector] = false
  388. }
  389. if choice != fieldInfo.val {
  390. // This destination field was not the chosen one, so make it nil (we checked
  391. // it was a pointer above).
  392. v.Field(i).Set(reflect.Zero(structType.Field(i).Type))
  393. continue
  394. }
  395. if seen {
  396. // We already saw a different destination field receive the value for this
  397. // selector value, which indicates a badly annotated structure.
  398. return offset, structuralError{fieldInfo.name, "duplicate selector value for " + fieldInfo.selector}
  399. }
  400. selectorSeen[fieldInfo.selector] = true
  401. // Make an object of the pointed-to type and parse into that.
  402. v.Field(i).Set(reflect.New(structType.Field(i).Type.Elem()))
  403. destination = v.Field(i).Elem()
  404. }
  405. offset, err = parseField(destination, data, offset, fieldInfo)
  406. if err != nil {
  407. return offset, err
  408. }
  409. // Remember any possible tls.Enum values encountered in case they are selectors.
  410. if structType.Field(i).Type.Kind() == enumType.Kind() {
  411. enums[structType.Field(i).Name] = v.Field(i).Uint()
  412. }
  413. }
  414. // Now we have seen all fields in the structure, check that all select(Enum) {..} selector
  415. // fields found a destination to put their data in.
  416. for selector, seen := range selectorSeen {
  417. if !seen {
  418. return offset, syntaxError{info.fieldName(), selector + ": unhandled value for selector"}
  419. }
  420. }
  421. return offset, nil
  422. case reflect.Array:
  423. datalen := v.Len()
  424. if datalen > len(rest) {
  425. return offset, syntaxError{info.fieldName(), "truncated array"}
  426. }
  427. inner := rest[:datalen]
  428. offset += datalen
  429. if fieldType.Elem().Kind() != reflect.Uint8 {
  430. // Only byte/uint8 arrays are supported
  431. return offset, structuralError{info.fieldName(), "unsupported array type: " + v.Type().String()}
  432. }
  433. reflect.Copy(v, reflect.ValueOf(inner))
  434. return offset, nil
  435. case reflect.Slice:
  436. sliceType := fieldType
  437. // Slices represent variable-length vectors, which are prefixed by a length field.
  438. // The fieldInfo indicates the size of that length field.
  439. varlen, err := readVarUint(rest, info)
  440. if err != nil {
  441. return offset, err
  442. }
  443. datalen := int(varlen)
  444. offset += int(info.count)
  445. rest = rest[info.count:]
  446. if datalen > len(rest) {
  447. return offset, syntaxError{info.fieldName(), "truncated slice"}
  448. }
  449. inner := rest[:datalen]
  450. offset += datalen
  451. if fieldType.Elem().Kind() == reflect.Uint8 {
  452. // Fast version for []byte
  453. v.Set(reflect.MakeSlice(sliceType, datalen, datalen))
  454. reflect.Copy(v, reflect.ValueOf(inner))
  455. return offset, nil
  456. }
  457. v.Set(reflect.MakeSlice(sliceType, 0, datalen))
  458. single := reflect.New(sliceType.Elem())
  459. for innerOffset := 0; innerOffset < len(inner); {
  460. var err error
  461. innerOffset, err = parseField(single.Elem(), inner, innerOffset, nil)
  462. if err != nil {
  463. return offset, err
  464. }
  465. v.Set(reflect.Append(v, single.Elem()))
  466. }
  467. return offset, nil
  468. default:
  469. return offset, structuralError{info.fieldName(), fmt.Sprintf("unsupported type: %s of kind %s", fieldType, v.Kind())}
  470. }
  471. }
  472. // Marshal returns the TLS encoding of val.
  473. func Marshal(val interface{}) ([]byte, error) {
  474. return MarshalWithParams(val, "")
  475. }
  476. // MarshalWithParams returns the TLS encoding of val, and allows field
  477. // parameters to be specified for the top-level element. The form
  478. // of the params is the same as the field tags.
  479. func MarshalWithParams(val interface{}, params string) ([]byte, error) {
  480. info, err := fieldTagToFieldInfo(params, "")
  481. if err != nil {
  482. return nil, err
  483. }
  484. var out bytes.Buffer
  485. v := reflect.ValueOf(val)
  486. if err := marshalField(&out, v, info); err != nil {
  487. return nil, err
  488. }
  489. return out.Bytes(), err
  490. }
  491. func marshalField(out *bytes.Buffer, v reflect.Value, info *fieldInfo) error {
  492. var prefix string
  493. if info != nil && len(info.name) > 0 {
  494. prefix = info.name + ": "
  495. }
  496. fieldType := v.Type()
  497. // First look for known fixed types.
  498. switch fieldType {
  499. case uint8Type:
  500. out.WriteByte(byte(v.Uint()))
  501. return nil
  502. case uint16Type:
  503. scratch := make([]byte, 2)
  504. binary.BigEndian.PutUint16(scratch, uint16(v.Uint()))
  505. out.Write(scratch)
  506. return nil
  507. case uint24Type:
  508. i := v.Uint()
  509. if i > 0xffffff {
  510. return structuralError{info.fieldName(), fmt.Sprintf("uint24 overflow %d", i)}
  511. }
  512. scratch := make([]byte, 4)
  513. binary.BigEndian.PutUint32(scratch, uint32(i))
  514. out.Write(scratch[1:])
  515. return nil
  516. case uint32Type:
  517. scratch := make([]byte, 4)
  518. binary.BigEndian.PutUint32(scratch, uint32(v.Uint()))
  519. out.Write(scratch)
  520. return nil
  521. case uint64Type:
  522. scratch := make([]byte, 8)
  523. binary.BigEndian.PutUint64(scratch, uint64(v.Uint()))
  524. out.Write(scratch)
  525. return nil
  526. }
  527. // Now deal with user-defined types.
  528. switch v.Kind() {
  529. case enumType.Kind():
  530. i := v.Uint()
  531. if info == nil {
  532. return structuralError{info.fieldName(), "enum field tag missing"}
  533. }
  534. if err := info.check(i, prefix); err != nil {
  535. return err
  536. }
  537. scratch := make([]byte, 8)
  538. binary.BigEndian.PutUint64(scratch, uint64(i))
  539. out.Write(scratch[(8 - info.count):])
  540. return nil
  541. case reflect.Struct:
  542. structType := fieldType
  543. enums := make(map[string]uint64) // Values of any Enum fields
  544. // The comment parseField() describes the mapping of the TLS select(Enum) {..} construct;
  545. // here we have selector and source (rather than destination) fields.
  546. // Track which selector names we've seen (in the source field tags), and whether a source
  547. // value for that selector has been processed.
  548. selectorSeen := make(map[string]bool)
  549. for i := 0; i < structType.NumField(); i++ {
  550. // Find information about this field.
  551. tag := structType.Field(i).Tag.Get("tls")
  552. fieldInfo, err := fieldTagToFieldInfo(tag, structType.Field(i).Name)
  553. if err != nil {
  554. return err
  555. }
  556. source := v.Field(i)
  557. if fieldInfo.selector != "" {
  558. // This field is a possible source for a select(Enum) {..}. First check
  559. // the selector field name has been seen.
  560. choice, ok := enums[fieldInfo.selector]
  561. if !ok {
  562. return structuralError{fieldInfo.name, "selector not seen: " + fieldInfo.selector}
  563. }
  564. if structType.Field(i).Type.Kind() != reflect.Ptr {
  565. return structuralError{fieldInfo.name, "choice field not a pointer type"}
  566. }
  567. // Is this the first mention of the selector field name? If so, remember it.
  568. seen, ok := selectorSeen[fieldInfo.selector]
  569. if !ok {
  570. selectorSeen[fieldInfo.selector] = false
  571. }
  572. if choice != fieldInfo.val {
  573. // This source was not chosen; police that it should be nil.
  574. if v.Field(i).Pointer() != uintptr(0) {
  575. return structuralError{fieldInfo.name, "unchosen field is non-nil"}
  576. }
  577. continue
  578. }
  579. if seen {
  580. // We already saw a different source field generate the value for this
  581. // selector value, which indicates a badly annotated structure.
  582. return structuralError{fieldInfo.name, "duplicate selector value for " + fieldInfo.selector}
  583. }
  584. selectorSeen[fieldInfo.selector] = true
  585. if v.Field(i).Pointer() == uintptr(0) {
  586. return structuralError{fieldInfo.name, "chosen field is nil"}
  587. }
  588. // Marshal from the pointed-to source object.
  589. source = v.Field(i).Elem()
  590. }
  591. var fieldData bytes.Buffer
  592. if err := marshalField(&fieldData, source, fieldInfo); err != nil {
  593. return err
  594. }
  595. out.Write(fieldData.Bytes())
  596. // Remember any tls.Enum values encountered in case they are selectors.
  597. if structType.Field(i).Type.Kind() == enumType.Kind() {
  598. enums[structType.Field(i).Name] = v.Field(i).Uint()
  599. }
  600. }
  601. // Now we have seen all fields in the structure, check that all select(Enum) {..} selector
  602. // fields found a source field get get their data from.
  603. for selector, seen := range selectorSeen {
  604. if !seen {
  605. return syntaxError{info.fieldName(), selector + ": unhandled value for selector"}
  606. }
  607. }
  608. return nil
  609. case reflect.Array:
  610. datalen := v.Len()
  611. arrayType := fieldType
  612. if arrayType.Elem().Kind() != reflect.Uint8 {
  613. // Only byte/uint8 arrays are supported
  614. return structuralError{info.fieldName(), "unsupported array type"}
  615. }
  616. bytes := make([]byte, datalen)
  617. for i := 0; i < datalen; i++ {
  618. bytes[i] = uint8(v.Index(i).Uint())
  619. }
  620. _, err := out.Write(bytes)
  621. return err
  622. case reflect.Slice:
  623. if info == nil {
  624. return structuralError{info.fieldName(), "slice field tag missing"}
  625. }
  626. sliceType := fieldType
  627. if sliceType.Elem().Kind() == reflect.Uint8 {
  628. // Fast version for []byte: first write the length as info.count bytes.
  629. datalen := v.Len()
  630. scratch := make([]byte, 8)
  631. binary.BigEndian.PutUint64(scratch, uint64(datalen))
  632. out.Write(scratch[(8 - info.count):])
  633. if err := info.check(uint64(datalen), prefix); err != nil {
  634. return err
  635. }
  636. // Then just write the data.
  637. bytes := make([]byte, datalen)
  638. for i := 0; i < datalen; i++ {
  639. bytes[i] = uint8(v.Index(i).Uint())
  640. }
  641. _, err := out.Write(bytes)
  642. return err
  643. }
  644. // General version: use a separate Buffer to write the slice entries into.
  645. var innerBuf bytes.Buffer
  646. for i := 0; i < v.Len(); i++ {
  647. if err := marshalField(&innerBuf, v.Index(i), nil); err != nil {
  648. return err
  649. }
  650. }
  651. // Now insert (and check) the size.
  652. size := uint64(innerBuf.Len())
  653. if err := info.check(size, prefix); err != nil {
  654. return err
  655. }
  656. scratch := make([]byte, 8)
  657. binary.BigEndian.PutUint64(scratch, size)
  658. out.Write(scratch[(8 - info.count):])
  659. // Then copy the data.
  660. _, err := out.Write(innerBuf.Bytes())
  661. return err
  662. default:
  663. return structuralError{info.fieldName(), fmt.Sprintf("unsupported type: %s of kind %s", fieldType, v.Kind())}
  664. }
  665. }