NeoMutt  2023-03-22
Teaching an old dog new tricks
DOXYGEN
pgppacket.c File Reference

Parse PGP data packets. More...

#include "config.h"
#include <stdbool.h>
#include <stdio.h>
#include <stdlib.h>
#include "mutt/lib.h"
#include "pgppacket.h"
+ Include dependency graph for pgppacket.c:

Go to the source code of this file.

Macros

#define CHUNK_SIZE   1024
 Amount of data to read at once. More...
 

Functions

static int read_material (size_t material, size_t *used, FILE *fp)
 Read PGP data into a buffer. More...
 
unsigned char * pgp_read_packet (FILE *fp, size_t *len)
 Read a PGP packet from a file. More...
 
void pgp_release_packet (void)
 Free the cached PGP packet. More...
 

Variables

static unsigned char * pbuf = NULL
 Cached PGP data packet. More...
 
static size_t plen = 0
 Length of cached packet. More...
 

Detailed Description

Parse PGP data packets.

Authors
  • Thomas Roessler

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program. If not, see http://www.gnu.org/licenses/.

Definition in file pgppacket.c.

Macro Definition Documentation

◆ CHUNK_SIZE

#define CHUNK_SIZE   1024

Amount of data to read at once.

Definition at line 36 of file pgppacket.c.

Function Documentation

◆ read_material()

static int read_material ( size_t  material,
size_t *  used,
FILE *  fp 
)
static

Read PGP data into a buffer.

Parameters
[in]materialNumber of bytes to read
[in,out]usedNumber of bytes already read
[in]fpFile to read from
Return values
0Success
-1Failure (see errno)

This function uses a cache to store the data: pbuf, plen.

Definition at line 51 of file pgppacket.c.

52{
53 if (*used + material >= plen)
54 {
55 size_t nplen = *used + material + CHUNK_SIZE;
56
57 unsigned char *p = realloc(pbuf, nplen);
58 if (!p)
59 {
60 perror("realloc");
61 return -1;
62 }
63 plen = nplen;
64 pbuf = p;
65 }
66
67 if (fread(pbuf + *used, 1, material, fp) < material)
68 {
69 perror("fread");
70 return -1;
71 }
72
73 *used += material;
74 return 0;
75}
static unsigned char * pbuf
Cached PGP data packet.
Definition: pgppacket.c:38
#define CHUNK_SIZE
Amount of data to read at once.
Definition: pgppacket.c:36
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
+ Here is the caller graph for this function:

◆ pgp_read_packet()

unsigned char * pgp_read_packet ( FILE *  fp,
size_t *  len 
)

Read a PGP packet from a file.

Parameters
[in]fpFile to read from
[out]lenNumber of bytes read
Return values
ptrPGP data packet

This function uses a cache to store the data: pbuf, plen.

Definition at line 85 of file pgppacket.c.

86{
87 size_t used = 0;
88 LOFF_T startpos;
89 unsigned char ctb;
90 unsigned char b;
91 size_t material;
92
93 startpos = ftello(fp);
94 if (startpos < 0)
95 return NULL;
96
97 if (plen == 0)
98 {
101 }
102
103 if (fread(&ctb, 1, 1, fp) < 1)
104 {
105 if (!feof(fp))
106 perror("fread");
107 goto bail;
108 }
109
110 if (!(ctb & 0x80))
111 {
112 goto bail;
113 }
114
115 if (ctb & 0x40) /* handle PGP 5.0 packets. */
116 {
117 bool partial = false;
118 pbuf[0] = ctb;
119 used++;
120
121 do
122 {
123 if (fread(&b, 1, 1, fp) < 1)
124 {
125 perror("fread");
126 goto bail;
127 }
128
129 if (b < 192)
130 {
131 material = b;
132 partial = false;
133 }
134 else if (b <= 223)
135 {
136 material = (b - 192) * 256;
137 if (fread(&b, 1, 1, fp) < 1)
138 {
139 perror("fread");
140 goto bail;
141 }
142 material += b + 192;
143 partial = false;
144 }
145 else if (b < 255)
146 {
147 material = 1 << (b & 0x1f);
148 partial = true;
149 }
150 else
151 /* b == 255 */
152 {
153 unsigned char buf[4];
154 if (fread(buf, 4, 1, fp) < 1)
155 {
156 perror("fread");
157 goto bail;
158 }
159 material = (size_t) buf[0] << 24;
160 material |= buf[1] << 16;
161 material |= buf[2] << 8;
162 material |= buf[3];
163 partial = false;
164 }
165
166 if (read_material(material, &used, fp) == -1)
167 goto bail;
168
169 } while (partial);
170 }
171 else
172 /* Old-Style PGP */
173 {
174 int bytes = 0;
175 pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
176 used++;
177
178 switch (ctb & 0x03)
179 {
180 case 0:
181 {
182 if (fread(&b, 1, 1, fp) < 1)
183 {
184 perror("fread");
185 goto bail;
186 }
187
188 material = b;
189 break;
190 }
191
192 case 1:
193 bytes = 2;
194 /* fallthrough */
195
196 case 2:
197 {
198 if (!bytes)
199 bytes = 4;
200
201 material = 0;
202
203 for (int i = 0; i < bytes; i++)
204 {
205 if (fread(&b, 1, 1, fp) < 1)
206 {
207 perror("fread");
208 goto bail;
209 }
210
211 material = (material << 8) + b;
212 }
213 break;
214 }
215
216 default:
217 goto bail;
218 }
219
220 if (read_material(material, &used, fp) == -1)
221 goto bail;
222 }
223
224 if (len)
225 *len = used;
226
227 return pbuf;
228
229bail:
230
231 (void) mutt_file_seek(fp, startpos, SEEK_SET);
232 return NULL;
233}
bool mutt_file_seek(FILE *fp, LOFF_T offset, int whence)
Wrapper for fseeko with error handling.
Definition: file.c:706
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
static int read_material(size_t material, size_t *used, FILE *fp)
Read PGP data into a buffer.
Definition: pgppacket.c:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_release_packet()

void pgp_release_packet ( void  )

Free the cached PGP packet.

Free the data stored in pbuf.

Definition at line 240 of file pgppacket.c.

241{
242 plen = 0;
243 FREE(&pbuf);
244}
#define FREE(x)
Definition: memory.h:43
+ Here is the caller graph for this function:

Variable Documentation

◆ pbuf

unsigned char* pbuf = NULL
static

Cached PGP data packet.

Definition at line 38 of file pgppacket.c.

◆ plen

size_t plen = 0
static

Length of cached packet.

Definition at line 39 of file pgppacket.c.