opaque.go 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  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. return op, err
  44. }
  45. return Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
  46. }
  47. // OpaqueReader reads OpaquePackets from an io.Reader.
  48. type OpaqueReader struct {
  49. r io.Reader
  50. }
  51. func NewOpaqueReader(r io.Reader) *OpaqueReader {
  52. return &OpaqueReader{r: r}
  53. }
  54. // Read the next OpaquePacket.
  55. func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
  56. tag, _, contents, err := readHeader(or.r)
  57. if err != nil {
  58. return
  59. }
  60. op = &OpaquePacket{Tag: uint8(tag), Reason: err}
  61. err = op.parse(contents)
  62. if err != nil {
  63. consumeAll(contents)
  64. }
  65. return
  66. }
  67. // OpaqueSubpacket represents an unparsed OpenPGP subpacket,
  68. // as found in signature and user attribute packets.
  69. type OpaqueSubpacket struct {
  70. Length uint32
  71. SubType uint8
  72. Contents []byte
  73. }
  74. // OpaqueSubpackets extracts opaque, unparsed OpenPGP subpackets from
  75. // their byte representation.
  76. func OpaqueSubpackets(contents []byte) ([]*OpaqueSubpacket, error) {
  77. var result []*OpaqueSubpacket
  78. var err error
  79. var (
  80. subHeaderLen uint32
  81. subPacket *OpaqueSubpacket
  82. )
  83. for len(contents) > 0 {
  84. subHeaderLen, subPacket, err = nextSubpacket(contents)
  85. if err != nil {
  86. break
  87. }
  88. result = append(result, subPacket)
  89. contents = contents[subHeaderLen+subPacket.Length:]
  90. }
  91. return result, err
  92. }
  93. func nextSubpacket(contents []byte) (subHeaderLen uint32, subPacket *OpaqueSubpacket, err error) {
  94. // RFC 4880, section 5.2.3.1
  95. if len(contents) < 1 {
  96. goto Truncated
  97. }
  98. subPacket = &OpaqueSubpacket{}
  99. switch {
  100. case contents[0] < 192:
  101. subHeaderLen = 1
  102. subPacket.Length = uint32(contents[0])
  103. contents = contents[1:]
  104. case contents[0] < 255:
  105. subHeaderLen = 2
  106. if len(contents) < 2 {
  107. goto Truncated
  108. }
  109. subPacket.Length = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
  110. contents = contents[2:]
  111. default:
  112. subHeaderLen = 5
  113. if len(contents) < 5 {
  114. goto Truncated
  115. }
  116. subPacket.Length = uint32(contents[1])<<24 |
  117. uint32(contents[2])<<16 |
  118. uint32(contents[3])<<8 |
  119. uint32(contents[4])
  120. contents = contents[5:]
  121. }
  122. if subPacket.Length > uint32(len(contents)) {
  123. goto Truncated
  124. }
  125. subPacket.SubType = contents[0]
  126. subPacket.Contents = contents[1:subPacket.Length]
  127. return
  128. Truncated:
  129. err = errors.StructuralError("subpacket truncated")
  130. return
  131. }