You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

162 lines
4.0 KiB

  1. // Copyright 2012 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.
  4. package packet
  5. import (
  6. "bytes"
  7. "io"
  8. "io/ioutil"
  9. "golang.org/x/crypto/openpgp/errors"
  10. )
  11. // OpaquePacket represents an OpenPGP packet as raw, unparsed data. This is
  12. // useful for splitting and storing the original packet contents separately,
  13. // handling unsupported packet types or accessing parts of the packet not yet
  14. // implemented by this package.
  15. type OpaquePacket struct {
  16. // Packet type
  17. Tag uint8
  18. // Reason why the packet was parsed opaquely
  19. Reason error
  20. // Binary contents of the packet data
  21. Contents []byte
  22. }
  23. func (op *OpaquePacket) parse(r io.Reader) (err error) {
  24. op.Contents, err = ioutil.ReadAll(r)
  25. return
  26. }
  27. // Serialize marshals the packet to a writer in its original form, including
  28. // the packet header.
  29. func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
  30. err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
  31. if err == nil {
  32. _, err = w.Write(op.Contents)
  33. }
  34. return
  35. }
  36. // Parse attempts to parse the opaque contents into a structure supported by
  37. // this package. If the packet is not known then the result will be another
  38. // OpaquePacket.
  39. func (op *OpaquePacket) Parse() (p Packet, err error) {
  40. hdr := bytes.NewBuffer(nil)
  41. err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
  42. if err != nil {
  43. op.Reason = err
  44. return op, err
  45. }
  46. p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
  47. if err != nil {
  48. op.Reason = err
  49. p = op
  50. }
  51. return
  52. }
  53. // OpaqueReader reads OpaquePackets from an io.Reader.
  54. type OpaqueReader struct {
  55. r io.Reader
  56. }
  57. func NewOpaqueReader(r io.Reader) *OpaqueReader {
  58. return &OpaqueReader{r: r}
  59. }
  60. // Read the next OpaquePacket.
  61. func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
  62. tag, _, contents, err := readHeader(or.r)
  63. if err != nil {
  64. return
  65. }
  66. op = &OpaquePacket{Tag: uint8(tag), Reason: err}
  67. err = op.parse(contents)
  68. if err != nil {
  69. consumeAll(contents)
  70. }
  71. return
  72. }
  73. // OpaqueSubpacket represents an unparsed OpenPGP subpacket,
  74. // as found in signature and user attribute packets.
  75. type OpaqueSubpacket struct {
  76. SubType uint8
  77. Contents []byte
  78. }
  79. // OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
  80. // their byte representation.
  81. func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
  82. var (
  83. subHeaderLen int
  84. subPacket *OpaqueSubpacket
  85. )
  86. for len(contents) > 0 {
  87. subHeaderLen, subPacket, err = nextSubpacket(contents)
  88. if err != nil {
  89. break
  90. }
  91. result = append(result, subPacket)
  92. contents = contents[subHeaderLen+len(subPacket.Contents):]
  93. }
  94. return
  95. }
  96. func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
  97. // RFC 4880, section 5.2.3.1
  98. var subLen uint32
  99. if len(contents) < 1 {
  100. goto Truncated
  101. }
  102. subPacket = &OpaqueSubpacket{}
  103. switch {
  104. case contents[0] < 192:
  105. subHeaderLen = 2 // 1 length byte, 1 subtype byte
  106. if len(contents) < subHeaderLen {
  107. goto Truncated
  108. }
  109. subLen = uint32(contents[0])
  110. contents = contents[1:]
  111. case contents[0] < 255:
  112. subHeaderLen = 3 // 2 length bytes, 1 subtype
  113. if len(contents) < subHeaderLen {
  114. goto Truncated
  115. }
  116. subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
  117. contents = contents[2:]
  118. default:
  119. subHeaderLen = 6 // 5 length bytes, 1 subtype
  120. if len(contents) < subHeaderLen {
  121. goto Truncated
  122. }
  123. subLen = uint32(contents[1])<<24 |
  124. uint32(contents[2])<<16 |
  125. uint32(contents[3])<<8 |
  126. uint32(contents[4])
  127. contents = contents[5:]
  128. }
  129. if subLen > uint32(len(contents)) || subLen == 0 {
  130. goto Truncated
  131. }
  132. subPacket.SubType = contents[0]
  133. subPacket.Contents = contents[1:subLen]
  134. return
  135. Truncated:
  136. err = errors.StructuralError("subpacket truncated")
  137. return
  138. }
  139. func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
  140. buf := make([]byte, 6)
  141. n := serializeSubpacketLength(buf, len(osp.Contents)+1)
  142. buf[n] = osp.SubType
  143. if _, err = w.Write(buf[:n+1]); err != nil {
  144. return
  145. }
  146. _, err = w.Write(osp.Contents)
  147. return
  148. }