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