NeoMutt  2022-04-29-145-g9b6a0e
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  {
99  plen = CHUNK_SIZE;
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 
229 bail:
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:690
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.