]> git.llucax.com Git - software/mutt-debian.git/blob - pgppacket.c
Imported Upstream version 1.5.18
[software/mutt-debian.git] / pgppacket.c
1 /*
2  * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
3  * 
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License as
6  * published by the Free Software Foundation; either version 2 of
7  * the License, or (at your option) any later version.
8  * 
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  * 
14  * You should have received a copy of the GNU General Public
15  * License along with this program; if not, write to the Free
16  * Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
17  * MA  02110-1301, USA.
18  */
19
20 #if HAVE_CONFIG_H
21 # include "config.h"
22 #endif
23
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <unistd.h>
28 #include <time.h>
29
30
31
32 /* yuck, we were including this one somewhere below. */
33 #include "mutt.h"
34
35 #include "sha1.h"
36 #include "lib.h"
37 #include "pgplib.h"
38 #include "pgppacket.h"
39
40 #define CHUNKSIZE 1024
41
42 static unsigned char *pbuf = NULL;
43 static size_t plen = 0;
44
45 static int read_material (size_t material, size_t * used, FILE * fp)
46 {
47   if (*used + material >= plen)
48   {
49     unsigned char *p;
50     size_t nplen;
51
52     nplen = *used + material + CHUNKSIZE;
53
54     if (!(p = realloc (pbuf, nplen)))   /* __MEM_CHECKED__ */
55     {
56       perror ("realloc");
57       return -1;
58     }
59     plen = nplen;
60     pbuf = p;
61   }
62
63   if (fread (pbuf + *used, 1, material, fp) < material)
64   {
65     perror ("fread");
66     return -1;
67   }
68
69   *used += material;
70   return 0;
71 }
72
73 unsigned char *pgp_read_packet (FILE * fp, size_t * len)
74 {
75   size_t used = 0;
76   LOFF_T startpos;
77   unsigned char ctb;
78   unsigned char b;
79   size_t material;
80
81   startpos = ftello (fp);
82
83   if (!plen)
84   {
85     plen = CHUNKSIZE;
86     pbuf = safe_malloc (plen);
87   }
88
89   if (fread (&ctb, 1, 1, fp) < 1)
90   {
91     if (!feof (fp))
92       perror ("fread");
93     goto bail;
94   }
95
96   if (!(ctb & 0x80))
97   {
98     goto bail;
99   }
100
101   if (ctb & 0x40)               /* handle PGP 5.0 packets. */
102   {
103     int partial = 0;
104     pbuf[0] = ctb;
105     used++;
106
107     do
108     {
109       if (fread (&b, 1, 1, fp) < 1)
110       {
111         perror ("fread");
112         goto bail;
113       }
114
115       if (b < 192)
116       {
117         material = b;
118         partial = 0;
119         /* material -= 1; */
120       }
121       else if (192 <= b && b <= 223)
122       {
123         material = (b - 192) * 256;
124         if (fread (&b, 1, 1, fp) < 1)
125         {
126           perror ("fread");
127           goto bail;
128         }
129         material += b + 192;
130         partial = 0;
131         /* material -= 2; */
132       }
133       else if (b < 255)
134       {
135         material = 1 << (b & 0x1f);
136         partial = 1;
137         /* material -= 1; */
138       }
139       else
140         /* b == 255 */
141       {
142         unsigned char buf[4];
143         if (fread (buf, 4, 1, fp) < 1)
144         {
145           perror ("fread");
146           goto bail;
147         }
148         /*assert( sizeof(material) >= 4 ); */
149         material = buf[0] << 24;
150         material |= buf[1] << 16;
151         material |= buf[2] << 8;
152         material |= buf[3];
153         partial = 0;
154         /* material -= 5; */
155       }
156
157       if (read_material (material, &used, fp) == -1)
158         goto bail;
159
160     }
161     while (partial);
162   }
163   else
164     /* Old-Style PGP */
165   {
166     int bytes = 0;
167     pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
168     used++;
169
170     switch (ctb & 0x03)
171     {
172       case 0:
173       {
174         if (fread (&b, 1, 1, fp) < 1)
175         {
176           perror ("fread");
177           goto bail;
178         }
179
180         material = b;
181         break;
182       }
183
184       case 1:
185       bytes = 2;
186
187       case 2:
188       {
189         int i;
190
191         if (!bytes)
192           bytes = 4;
193
194         material = 0;
195
196         for (i = 0; i < bytes; i++)
197         {
198           if (fread (&b, 1, 1, fp) < 1)
199           {
200             perror ("fread");
201             goto bail;
202           }
203
204           material = (material << 8) + b;
205         }
206         break;
207       }
208
209       default:
210       goto bail;
211     }
212
213     if (read_material (material, &used, fp) == -1)
214       goto bail;
215   }
216
217   if (len)
218     *len = used;
219
220   return pbuf;
221
222 bail:
223
224   fseeko (fp, startpos, SEEK_SET);
225   return NULL;
226 }
227
228 void pgp_release_packet (void)
229 {
230   plen = 0;
231   FREE (&pbuf);
232 }
233