opaque.go 4.1 KB

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