opaque.go 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  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. "io"
  9. "io/ioutil"
  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. Length uint32
  77. SubType uint8
  78. Contents []byte
  79. }
  80. // OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
  81. // their byte representation.
  82. func OpaqueSubpackets(contents []byte) ([]*OpaqueSubpacket, error) {
  83. var result []*OpaqueSubpacket
  84. var err error
  85. var (
  86. subHeaderLen uint32
  87. subPacket *OpaqueSubpacket
  88. )
  89. for len(contents) > 0 {
  90. subHeaderLen, subPacket, err = nextSubpacket(contents)
  91. if err != nil {
  92. break
  93. }
  94. result = append(result, subPacket)
  95. contents = contents[subHeaderLen+subPacket.Length:]
  96. }
  97. return result, err
  98. }
  99. func nextSubpacket(contents []byte) (subHeaderLen uint32, subPacket *OpaqueSubpacket, err error) {
  100. // RFC 4880, section 5.2.3.1
  101. if len(contents) < 1 {
  102. goto Truncated
  103. }
  104. subPacket = &OpaqueSubpacket{}
  105. switch {
  106. case contents[0] < 192:
  107. subHeaderLen = 1
  108. subPacket.Length = uint32(contents[0])
  109. contents = contents[1:]
  110. case contents[0] < 255:
  111. subHeaderLen = 2
  112. if len(contents) < 2 {
  113. goto Truncated
  114. }
  115. subPacket.Length = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
  116. contents = contents[2:]
  117. default:
  118. subHeaderLen = 5
  119. if len(contents) < 5 {
  120. goto Truncated
  121. }
  122. subPacket.Length = uint32(contents[1])<<24 |
  123. uint32(contents[2])<<16 |
  124. uint32(contents[3])<<8 |
  125. uint32(contents[4])
  126. contents = contents[5:]
  127. }
  128. if subPacket.Length > uint32(len(contents)) {
  129. goto Truncated
  130. }
  131. subPacket.SubType = contents[0]
  132. subPacket.Contents = contents[1:subPacket.Length]
  133. return
  134. Truncated:
  135. err = errors.StructuralError("subpacket truncated")
  136. return
  137. }