remove reallocs, free and fix makedoc compilation
[apps/madmutt.git] / lib-crypt / pgppacket.c
1 /*
2  * Copyright notice from original mutt:
3  * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
4  *
5  * This file is part of mutt-ng, see http://www.muttng.org/.
6  * It's licensed under the GNU General Public License,
7  * please see the file GPL in the top level source directory.
8  */
9
10 #include <lib-lib/lib-lib.h>
11 #include <lib-hash/hash.h>
12
13 #include "lib.h"
14 #include "pgplib.h"
15 #include "pgppacket.h"
16
17 #define CHUNKSIZE 1024
18
19 static unsigned char *pbuf = NULL;
20 static size_t plen = 0;
21
22 static int read_material (size_t material, size_t * used, FILE * fp)
23 {
24   if (*used + material >= plen) {
25     p_realloc(&pbuf, plen = *used + material + CHUNKSIZE);
26   }
27
28   if (fread (pbuf + *used, 1, material, fp) < material) {
29     perror ("fread");
30     return -1;
31   }
32
33   *used += material;
34   return 0;
35 }
36
37 unsigned char *pgp_read_packet (FILE * fp, size_t * len)
38 {
39   size_t used = 0;
40   off_t startpos;
41   unsigned char ctb;
42   unsigned char b;
43   size_t material;
44
45   startpos = ftello (fp);
46
47   if (!plen) {
48     pbuf = p_new(unsigned char, plen = CHUNKSIZE);
49   }
50
51   if (fread (&ctb, 1, 1, fp) < 1) {
52     if (!feof (fp))
53       perror ("fread");
54     goto bail;
55   }
56
57   if (!(ctb & 0x80)) {
58     goto bail;
59   }
60
61   if (ctb & 0x40) {             /* handle PGP 5.0 packets. */
62     int partial = 0;
63
64     pbuf[0] = ctb;
65     used++;
66
67     do {
68       if (fread (&b, 1, 1, fp) < 1) {
69         perror ("fread");
70         goto bail;
71       }
72
73       if (b < 192) {
74         material = b;
75         partial = 0;
76         /* material -= 1; */
77       }
78       else if (192 <= b && b <= 223) {
79         material = (b - 192) * 256;
80         if (fread (&b, 1, 1, fp) < 1) {
81           perror ("fread");
82           goto bail;
83         }
84         material += b + 192;
85         partial = 0;
86         /* material -= 2; */
87       }
88       else if (b < 255) {
89         material = 1 << (b & 0x1f);
90         partial = 1;
91         /* material -= 1; */
92       }
93       else
94         /* b == 255 */
95       {
96         unsigned char buf[4];
97
98         if (fread (buf, 4, 1, fp) < 1) {
99           perror ("fread");
100           goto bail;
101         }
102         /*assert( sizeof(material) >= 4 ); */
103         material = buf[0] << 24;
104         material |= buf[1] << 16;
105         material |= buf[2] << 8;
106         material |= buf[3];
107         partial = 0;
108         /* material -= 5; */
109       }
110
111       if (read_material (material, &used, fp) == -1)
112         goto bail;
113
114     }
115     while (partial);
116   }
117   else
118     /* Old-Style PGP */
119   {
120     int bytes = 0;
121
122     pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
123     used++;
124
125     switch (ctb & 0x03) {
126     case 0:
127       {
128         if (fread (&b, 1, 1, fp) < 1) {
129           perror ("fread");
130           goto bail;
131         }
132
133         material = b;
134         break;
135       }
136
137     case 1:
138       bytes = 2;
139
140     case 2:
141       {
142         int i;
143
144         if (!bytes)
145           bytes = 4;
146
147         material = 0;
148
149         for (i = 0; i < bytes; i++) {
150           if (fread (&b, 1, 1, fp) < 1) {
151             perror ("fread");
152             goto bail;
153           }
154
155           material = (material << 8) + b;
156         }
157         break;
158       }
159
160     default:
161       goto bail;
162     }
163
164     if (read_material (material, &used, fp) == -1)
165       goto bail;
166   }
167
168   if (len)
169     *len = used;
170
171   return pbuf;
172
173 bail:
174
175   fseeko (fp, startpos, SEEK_SET);
176   return NULL;
177 }
178
179 void pgp_release_packet (void)
180 {
181   plen = 0;
182   p_delete(&pbuf);
183 }