2 * Copyright notice from original mutt:
3 * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
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.
10 /* This module peeks at a PGP signature and figures out the hash
20 #include "pgppacket.h"
32 } HashAlgorithms[] = {
36 3, "pgp-ripemd160"}, {
39 7, "pgp-haval-5-160"}, {
46 static const char *pgp_hash_to_micalg (short id)
50 for (i = 0; HashAlgorithms[i].id >= 0; i++)
51 if (HashAlgorithms[i].id == id)
52 return HashAlgorithms[i].name;
56 static void pgp_dearmor (FILE * in, FILE * out)
58 char line[HUGE_STRING];
65 memset (&state, 0, sizeof (STATE));
69 /* find the beginning of ASCII armor */
71 while ((r = fgets (line, sizeof (line), in)) != NULL) {
72 if (!strncmp (line, "-----BEGIN", 10))
77 (debugfile, "pgp_dearmor: Can't find begin of ASCII armor.\n"));
81 /* skip the armor header */
83 while ((r = fgets (line, sizeof (line), in)) != NULL) {
89 dprint (1, (debugfile, "pgp_dearmor: Armor header doesn't end.\n"));
93 /* actual data starts here */
96 /* find the checksum */
98 while ((r = fgets (line, sizeof (line), in)) != NULL) {
99 if (*line == '=' || !strncmp (line, "-----END", 8))
103 dprint (1, (debugfile, "pgp_dearmor: Can't find end of ASCII armor.\n"));
107 if ((end = ftell (in) - mutt_strlen (line)) < start) {
108 dprint (1, (debugfile, "pgp_dearmor: end < start???\n"));
112 if (fseek (in, start, SEEK_SET) == -1) {
113 dprint (1, (debugfile, "pgp_dearmor: Can't seekto start.\n"));
117 mutt_decode_base64 (&state, end - start, 0, (iconv_t) - 1);
120 static short pgp_mic_from_packet (unsigned char *p, size_t len)
123 if ((p[0] & 0x3f) != PT_SIG) {
124 dprint (1, (debugfile, "pgp_mic_from_packet: tag = %d, want %d.\n",
125 p[0] & 0x3f, PT_SIG));
129 if (len >= 18 && p[1] == 3)
130 /* version 3 signature */
131 return (short) p[17];
132 else if (len >= 5 && p[1] == 4)
133 /* version 4 signature */
136 dprint (1, (debugfile, "pgp_mic_from_packet: Bad signature packet.\n"));
141 static short pgp_find_hash (const char *fname)
146 char tempfile[_POSIX_PATH_MAX];
153 mutt_mktemp (tempfile);
154 if ((out = safe_fopen (tempfile, "w+")) == NULL) {
155 mutt_perror (tempfile);
160 if ((in = fopen (fname, "r")) == NULL) {
165 pgp_dearmor (in, out);
168 if ((p = pgp_read_packet (out, &l)) != NULL) {
169 rv = pgp_mic_from_packet (p, l);
172 dprint (1, (debugfile, "pgp_find_hash: No packet.\n"));
179 pgp_release_packet ();
183 const char *pgp_micalg (const char *fname)
185 return pgp_hash_to_micalg (pgp_find_hash (fname));