NeoMutt  2018-07-16 +2481-68dcde
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 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 35 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 50 of file pgppacket.c.

51 {
52  if (*used + material >= plen)
53  {
54  size_t nplen = *used + material + CHUNK_SIZE;
55 
56  unsigned char *p = realloc(pbuf, nplen);
57  if (!p)
58  {
59  perror("realloc");
60  return -1;
61  }
62  plen = nplen;
63  pbuf = p;
64  }
65 
66  if (fread(pbuf + *used, 1, material, fp) < material)
67  {
68  perror("fread");
69  return -1;
70  }
71 
72  *used += material;
73  return 0;
74 }
static size_t plen
Length of cached packet.
Definition: pgppacket.c:38
#define CHUNK_SIZE
Amount of data to read at once.
Definition: pgppacket.c:35
static unsigned char * pbuf
Cache PGP data packet.
Definition: pgppacket.c:37
+ 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 83 of file pgppacket.c.

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

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

Variable Documentation

◆ pbuf

unsigned char* pbuf = NULL
static

Cache PGP data packet.

Definition at line 37 of file pgppacket.c.

◆ plen

size_t plen = 0
static

Length of cached packet.

Definition at line 38 of file pgppacket.c.