...
1
2
3
4
5 package packet
6
7 import (
8 "bytes"
9 "io"
10 "io/ioutil"
11
12 "github.com/ProtonMail/go-crypto/openpgp/errors"
13 )
14
15
16
17
18
19 type OpaquePacket struct {
20
21 Tag uint8
22
23 Reason error
24
25 Contents []byte
26 }
27
28 func (op *OpaquePacket) parse(r io.Reader) (err error) {
29 op.Contents, err = ioutil.ReadAll(r)
30 return
31 }
32
33
34
35 func (op *OpaquePacket) Serialize(w io.Writer) (err error) {
36 err = serializeHeader(w, packetType(op.Tag), len(op.Contents))
37 if err == nil {
38 _, err = w.Write(op.Contents)
39 }
40 return
41 }
42
43
44
45
46 func (op *OpaquePacket) Parse() (p Packet, err error) {
47 hdr := bytes.NewBuffer(nil)
48 err = serializeHeader(hdr, packetType(op.Tag), len(op.Contents))
49 if err != nil {
50 op.Reason = err
51 return op, err
52 }
53 p, err = Read(io.MultiReader(hdr, bytes.NewBuffer(op.Contents)))
54 if err != nil {
55 op.Reason = err
56 p = op
57 }
58 return
59 }
60
61
62 type OpaqueReader struct {
63 r io.Reader
64 }
65
66 func NewOpaqueReader(r io.Reader) *OpaqueReader {
67 return &OpaqueReader{r: r}
68 }
69
70
71 func (or *OpaqueReader) Next() (op *OpaquePacket, err error) {
72 tag, _, contents, err := readHeader(or.r)
73 if err != nil {
74 return
75 }
76 op = &OpaquePacket{Tag: uint8(tag), Reason: err}
77 err = op.parse(contents)
78 if err != nil {
79 consumeAll(contents)
80 }
81 return
82 }
83
84
85
86 type OpaqueSubpacket struct {
87 SubType uint8
88 EncodedLength []byte
89 Contents []byte
90 }
91
92
93
94 func OpaqueSubpackets(contents []byte) (result []*OpaqueSubpacket, err error) {
95 var (
96 subHeaderLen int
97 subPacket *OpaqueSubpacket
98 )
99 for len(contents) > 0 {
100 subHeaderLen, subPacket, err = nextSubpacket(contents)
101 if err != nil {
102 break
103 }
104 result = append(result, subPacket)
105 contents = contents[subHeaderLen+len(subPacket.Contents):]
106 }
107 return
108 }
109
110 func nextSubpacket(contents []byte) (subHeaderLen int, subPacket *OpaqueSubpacket, err error) {
111
112 var subLen uint32
113 var encodedLength []byte
114 if len(contents) < 1 {
115 goto Truncated
116 }
117 subPacket = &OpaqueSubpacket{}
118 switch {
119 case contents[0] < 192:
120 subHeaderLen = 2
121 if len(contents) < subHeaderLen {
122 goto Truncated
123 }
124 encodedLength = contents[0:1]
125 subLen = uint32(contents[0])
126 contents = contents[1:]
127 case contents[0] < 255:
128 subHeaderLen = 3
129 if len(contents) < subHeaderLen {
130 goto Truncated
131 }
132 encodedLength = contents[0:2]
133 subLen = uint32(contents[0]-192)<<8 + uint32(contents[1]) + 192
134 contents = contents[2:]
135 default:
136 subHeaderLen = 6
137 if len(contents) < subHeaderLen {
138 goto Truncated
139 }
140 encodedLength = contents[0:5]
141 subLen = uint32(contents[1])<<24 |
142 uint32(contents[2])<<16 |
143 uint32(contents[3])<<8 |
144 uint32(contents[4])
145 contents = contents[5:]
146
147 }
148 if subLen > uint32(len(contents)) || subLen == 0 {
149 goto Truncated
150 }
151 subPacket.SubType = contents[0]
152 subPacket.EncodedLength = encodedLength
153 subPacket.Contents = contents[1:subLen]
154 return
155 Truncated:
156 err = errors.StructuralError("subpacket truncated")
157 return
158 }
159
160 func (osp *OpaqueSubpacket) Serialize(w io.Writer) (err error) {
161 buf := make([]byte, 6)
162 copy(buf, osp.EncodedLength)
163 n := len(osp.EncodedLength)
164
165 buf[n] = osp.SubType
166 if _, err = w.Write(buf[:n+1]); err != nil {
167 return
168 }
169 _, err = w.Write(osp.Contents)
170 return
171 }
172
View as plain text