NeoMutt  2019-12-07
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/mutt.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
 Cache 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 size_t plen
Length of cached packet.
Definition: pgppacket.c:39
#define CHUNK_SIZE
Amount of data to read at once.
Definition: pgppacket.c:36
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
+ 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

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

Definition at line 84 of file pgppacket.c.

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

240 {
241  plen = 0;
242  FREE(&pbuf);
243 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:39
#define FREE(x)
Definition: memory.h:40
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:38
+ Here is the caller graph for this function:

Variable Documentation

◆ pbuf

unsigned char* pbuf = NULL
static

Cache 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.