Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 210 lines (177 sloc) 4.444 kb
14c29200 » Antonio Radici
2009-05-24 Imported Upstream version 1.5.18
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 /* This module peeks at a PGP signature and figures out the hash
21 * algorithm.
22 */
23
24 #if HAVE_CONFIG_H
25 # include "config.h"
26 #endif
27
28 #include "mutt.h"
29 #include "pgp.h"
30 #include "pgppacket.h"
31 #include "charset.h"
32
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 #include <ctype.h>
37
38 static struct
39 {
40 short id;
41 const char *name;
42 }
43 HashAlgorithms[] =
44 {
45 { 1, "pgp-md5" },
46 { 2, "pgp-sha1" },
47 { 3, "pgp-ripemd160" },
48 { 5, "pgp-md2" },
49 { 6, "pgp-tiger192" },
50 { 7, "pgp-haval-5-160" },
51 { 8, "pgp-sha256" },
52 { 9, "pgp-sha384" },
53 { 10, "pgp-sha512" },
54 { 11, "pgp-sha224" },
55 { -1, NULL }
56 };
57
58 static const char *pgp_hash_to_micalg (short id)
59 {
60 int i;
61
62 for (i = 0; HashAlgorithms[i].id >= 0; i++)
63 if (HashAlgorithms[i].id == id)
64 return HashAlgorithms[i].name;
65 return "x-unknown";
66 }
67
68 static void pgp_dearmor (FILE *in, FILE *out)
69 {
70 char line[HUGE_STRING];
71 LOFF_T start;
72 LOFF_T end;
73 char *r;
74
75 STATE state;
76
77 memset (&state, 0, sizeof (STATE));
78 state.fpin = in;
79 state.fpout = out;
80
81 /* find the beginning of ASCII armor */
82
83 while ((r = fgets (line, sizeof (line), in)) != NULL)
84 {
85 if (!strncmp (line, "-----BEGIN", 10))
86 break;
87 }
88 if (r == NULL)
89 {
90 dprint (1, (debugfile, "pgp_dearmor: Can't find begin of ASCII armor.\n"));
91 return;
92 }
93
94 /* skip the armor header */
95
96 while ((r = fgets (line, sizeof (line), in)) != NULL)
97 {
98 SKIPWS (r);
99 if (!*r) break;
100 }
101 if (r == NULL)
102 {
103 dprint (1, (debugfile, "pgp_dearmor: Armor header doesn't end.\n"));
104 return;
105 }
106
107 /* actual data starts here */
108 start = ftello (in);
109
110 /* find the checksum */
111
112 while ((r = fgets (line, sizeof (line), in)) != NULL)
113 {
114 if (*line == '=' || !strncmp (line, "-----END", 8))
115 break;
116 }
117 if (r == NULL)
118 {
119 dprint (1, (debugfile, "pgp_dearmor: Can't find end of ASCII armor.\n"));
120 return;
121 }
122
123 if ((end = ftello (in) - strlen (line)) < start)
124 {
125 dprint (1, (debugfile, "pgp_dearmor: end < start???\n"));
126 return;
127 }
128
129 if (fseeko (in, start, SEEK_SET) == -1)
130 {
131 dprint (1, (debugfile, "pgp_dearmor: Can't seekto start.\n"));
132 return;
133 }
134
135 mutt_decode_base64 (&state, end - start, 0, (iconv_t) -1);
136 }
137
138 static short pgp_mic_from_packet (unsigned char *p, size_t len)
139 {
140 /* is signature? */
141 if ((p[0] & 0x3f) != PT_SIG)
142 {
143 dprint (1, (debugfile, "pgp_mic_from_packet: tag = %d, want %d.\n",
144 p[0]&0x3f, PT_SIG));
145 return -1;
146 }
147
148 if (len >= 18 && p[1] == 3)
149 /* version 3 signature */
150 return (short) p[17];
151 else if (len >= 5 && p[1] == 4)
152 /* version 4 signature */
153 return (short) p[4];
154 else
155 {
156 dprint (1, (debugfile, "pgp_mic_from_packet: Bad signature packet.\n"));
157 return -1;
158 }
159 }
160
161 static short pgp_find_hash (const char *fname)
162 {
163 FILE *in = NULL;
164 FILE *out = NULL;
165
166 char tempfile[_POSIX_PATH_MAX];
167
168 unsigned char *p;
169 size_t l;
170
171 short rv = -1;
172
594a6a48 » Antonio Radici
2010-10-03 Imported Upstream version 1.5.21
173 mutt_mktemp (tempfile, sizeof (tempfile));
14c29200 » Antonio Radici
2009-05-24 Imported Upstream version 1.5.18
174 if ((out = safe_fopen (tempfile, "w+")) == NULL)
175 {
176 mutt_perror (tempfile);
177 goto bye;
178 }
179 unlink (tempfile);
180
181 if ((in = fopen (fname, "r")) == NULL)
182 {
183 mutt_perror (fname);
184 goto bye;
185 }
186
187 pgp_dearmor (in, out);
188 rewind (out);
189
190 if ((p = pgp_read_packet (out, &l)) != NULL)
191 {
192 rv = pgp_mic_from_packet (p, l);
193 }
194 else
195 {
196 dprint (1, (debugfile, "pgp_find_hash: No packet.\n"));
197 }
198
199 bye:
200
201 safe_fclose (&in);
202 safe_fclose (&out);
203 pgp_release_packet ();
204 return rv;
205 }
206
207 const char *pgp_micalg (const char *fname)
208 {
209 return pgp_hash_to_micalg (pgp_find_hash (fname));
210 }
211
Something went wrong with that request. Please try again.