summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorThomas Roessler <roessler@does-not-exist.org>2001-02-12 17:21:37 +0000
committerThomas Roessler <roessler@does-not-exist.org>2001-02-12 17:21:37 +0000
commitfe573eb97b07fa240232dfa0aa174017667ecdd8 (patch)
treefa81f4bba8eae775efff04d1aa46ea6437e6656d
parent3afe7d22837c0cca6df26fa5335aa0695eba13fc (diff)
Auto-detect the micalg used with PGP/MIME signatures.
-rw-r--r--Makefile.am13
-rw-r--r--compose.c33
-rw-r--r--configure.in2
-rw-r--r--gnupgparse.c6
-rw-r--r--init.h14
-rw-r--r--mutt.h1
-rw-r--r--pgp.c2
-rw-r--r--pgp.h2
-rw-r--r--pgplib.c38
-rw-r--r--pgplib.h1
-rw-r--r--pgpmicalg.c204
-rw-r--r--pgppacket.c226
-rw-r--r--pgppacket.h52
-rw-r--r--pgppubring.c242
-rw-r--r--postpone.c19
-rw-r--r--protos.h1
-rw-r--r--send.c10
-rw-r--r--sendlib.c2
18 files changed, 511 insertions, 357 deletions
diff --git a/Makefile.am b/Makefile.am
index 40414490..74e4db93 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -65,16 +65,17 @@ INCLUDES=-I$(top_srcdir) -I. $(IMAP_INCLUDES) \
-Iintl -I$(includedir)
non_us_sources = pgp.c pgpinvoke.c pgpkey.c pgplib.c sha1.c \
- gnupgparse.c sha1.h \
+ pgpmicalg.c gnupgparse.c sha1.h \
doc/language.txt doc/language50.txt OPS.PGP doc/PGP-Notes.txt \
OPS.MIX remailer.c remailer.h pgpewrap \
contrib/pgp2.rc contrib/pgp5.rc contrib/gpg.rc \
- mutt_ssl.c mutt_ssl.h README.SSL mutt_ssl_nss.c
+ mutt_ssl.c mutt_ssl.h README.SSL mutt_ssl_nss.c \
+ pgppacket.c pgppacket.h
EXTRA_mutt_SOURCES = account.c md5c.c mutt_sasl.c mutt_socket.c mutt_ssl.c \
pop.c pop_auth.c pop_lib.c pgp.c pgpinvoke.c pgpkey.c pgplib.c \
- sha1.c gnupgparse.c resize.c dotlock.c remailer.c browser.h mbyte.h \
- remailer.h url.h mutt_ssl_nss.c
+ sha1.c pgpmicalg.c gnupgparse.c resize.c dotlock.c remailer.c browser.h mbyte.h \
+ remailer.h url.h mutt_ssl_nss.c pgppacket.c
EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \
attach.h buffy.h charset.h copy.h dotlock.h functions.h gen_defs \
@@ -86,13 +87,13 @@ EXTRA_DIST = COPYRIGHT GPL OPS OPS.PGP TODO configure acconfig.h account.h \
_regex.h OPS.MIX README.SECURITY remailer.c remailer.h browser.h \
mbyte.h lib.h extlib.c pgpewrap pgplib.h Muttrc.head Muttrc \
makedoc.c stamp-doc-rc README.SSL README.UPGRADE checktypes.c \
- muttbug
+ muttbug pgppacket.h
mutt_dotlock_SOURCES = mutt_dotlock.c
mutt_dotlock_LDADD = @LIBOBJS@
mutt_dotlock_DEPENDENCIES = @LIBOBJS@
-pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c
+pgpring_SOURCES = pgppubring.c pgplib.c lib.c extlib.c sha1.c pgppacket.c
pgpring_LDADD = @LIBOBJS@ $(INTLLIBS)
pgpring_DEPENDENCIES = @LIBOBJS@ $(INTLDEPS)
diff --git a/compose.c b/compose.c
index 141389ec..59ce80fe 100644
--- a/compose.c
+++ b/compose.c
@@ -121,21 +121,16 @@ static void redraw_pgp_lines (int pgp)
move (HDR_PGPSIGINFO, 0);
clrtoeol ();
if (pgp & PGPSIGN)
- {
printw ("%s%s", _(" sign as: "), PgpSignAs ? PgpSignAs : _("<default>"));
- mvprintw (HDR_PGPSIGINFO, 40, "%s%s", _("MIC algorithm: "),
- NONULL(PgpSignMicalg));
- }
}
static int pgp_send_menu (int bits, int *redraw)
{
pgp_key_t *p;
char input_signas[SHORT_STRING];
- char input_micalg[SHORT_STRING];
- switch (mutt_multi_choice (_("(e)ncrypt, (s)ign, sign (a)s, (b)oth, select (m)ic algorithm, or (f)orget it? "),
- _("esabmf")))
+ switch (mutt_multi_choice (_("(e)ncrypt, (s)ign, sign (a)s, (b)oth, or (f)orget it? "),
+ _("esabf")))
{
case 1: /* (e)ncrypt */
bits |= PGPENCRYPT;
@@ -153,7 +148,6 @@ static int pgp_send_menu (int bits, int *redraw)
{
snprintf (input_signas, sizeof (input_signas), "0x%s", pgp_keyid (p));
mutt_str_replace (&PgpSignAs, input_signas);
- mutt_str_replace (&PgpSignMicalg, pgp_pkalg_to_mic (p->algorithm));
pgp_free_key (&p);
bits |= PGPSIGN;
@@ -172,28 +166,7 @@ static int pgp_send_menu (int bits, int *redraw)
bits = PGPENCRYPT | PGPSIGN;
break;
- case 5: /* select (m)ic algorithm */
- if (!(bits & PGPSIGN))
- mutt_error _("This doesn't make sense if you don't want to sign the message.");
- else
- {
- /* Copy the existing MIC algorithm into place */
- strfcpy(input_micalg, NONULL (PgpSignMicalg), sizeof (input_micalg));
-
- if (mutt_get_field (_("MIC algorithm: "), input_micalg, sizeof (input_micalg), 0) == 0)
- {
- if (mutt_strcasecmp (input_micalg, "pgp-md5") && mutt_strcasecmp (input_micalg, "pgp-sha1")
- && mutt_strcasecmp (input_micalg, "pgp-rmd160"))
- {
- mutt_error _("Unknown MIC algorithm, valid ones are: pgp-md5, pgp-sha1, pgp-rmd160");
- }
- else
- mutt_str_replace (&PgpSignMicalg, input_micalg);
- }
- }
- break;
-
- case 6: /* (f)orget it */
+ case 5: /* (f)orget it */
bits = 0;
break;
}
diff --git a/configure.in b/configure.in
index bf539ed7..82e01d1c 100644
--- a/configure.in
+++ b/configure.in
@@ -75,7 +75,7 @@ else
AC_DEFINE(HAVE_PGP)
PGPAUX_TARGET=pgpring
AM_CONDITIONAL(NEEDS_PGPEWRAP, true)
- MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pgp.o pgpinvoke.o pgpkey.o pgplib.o gnupgparse.o"
+ MUTT_LIB_OBJECTS="$MUTT_LIB_OBJECTS pgp.o pgpinvoke.o pgpkey.o pgplib.o gnupgparse.o pgpmicalg.o pgppacket.o"
OPS="$OPS \$(srcdir)/OPS.PGP"
fi
diff --git a/gnupgparse.c b/gnupgparse.c
index c7feca89..88b1716e 100644
--- a/gnupgparse.c
+++ b/gnupgparse.c
@@ -252,6 +252,10 @@ static pgp_key_t *parse_pub_line (char *buf, int *is_subkey, pgp_key_t *k)
{
if (!pend || !*p)
break; /* empty field or no trailing colon */
+
+ /* ignore user IDs on subkeys */
+ if (!is_uid && (*is_subkey && option (OPTPGPIGNORESUB)))
+ break;
dprint (2, (debugfile, "user ID: %s\n", p));
@@ -318,7 +322,7 @@ pgp_key_t *pgp_get_candidates (pgp_ring_t keyring, LIST * hints)
if (is_sub)
{
pgp_uid_t **l;
-
+
k->flags |= KEYFLAG_SUBKEY;
k->parent = mainkey;
for (l = &k->address; *l; l = &(*l)->next)
diff --git a/init.h b/init.h
index 598fd4f2..3289b403 100644
--- a/init.h
+++ b/init.h
@@ -1176,20 +1176,6 @@ struct option_t MuttVars[] = {
** which of your private keys to use. It is recommended that you use the
** keyid form to specify your key (e.g., ``0x00112233'').
*/
- { "pgp_sign_micalg", DT_STR, R_NONE, UL &PgpSignMicalg, UL "pgp-md5" },
- /*
- ** .pp
- ** This variable contains the default message integrity check algorithm.
- ** Valid values are ``pgp-md5'', ``pgp-sha1'', and ``pgp-rmd160''. If you
- ** select a signing key using the sign as option on the compose menu,
- ** mutt will automagically figure out the correct value to insert here,
- ** but it does not know about the user's default key.
- ** .pp
- ** So if you are using an RSA key for signing, set this variable to
- ** ``pgp-md5'', if you use a PGP 5 DSS key for signing, say ``pgp-sha1''
- ** here. The value of this variable will show up in the micalg parameter
- ** of MIME headers when creating RFC 2015 signatures.
- */
{ "pgp_strict_enc", DT_BOOL, R_NONE, OPTPGPSTRICTENC, 1 },
/*
** .pp
diff --git a/mutt.h b/mutt.h
index 6b6be113..cde5ecd9 100644
--- a/mutt.h
+++ b/mutt.h
@@ -48,6 +48,7 @@
#include "rfc822.h"
#include "hash.h"
+#include "charset.h"
#ifdef SUBVERSION
# define MUTT_VERSION (VERSION SUBVERSION)
diff --git a/pgp.c b/pgp.c
index f45f1a66..0ec12ed9 100644
--- a/pgp.c
+++ b/pgp.c
@@ -1152,7 +1152,7 @@ static BODY *pgp_sign_message (BODY *a)
mutt_generate_boundary (&t->parameter);
mutt_set_parameter ("protocol", "application/pgp-signature", &t->parameter);
- mutt_set_parameter ("micalg", PgpSignMicalg, &t->parameter);
+ mutt_set_parameter ("micalg", pgp_micalg (sigfile), &t->parameter);
t->parts = a;
a = t;
diff --git a/pgp.h b/pgp.h
index 32f26105..05c1a9a8 100644
--- a/pgp.h
+++ b/pgp.h
@@ -24,7 +24,6 @@
WHERE REGEXP PgpGoodSign;
WHERE char *PgpSignAs;
-WHERE char *PgpSignMicalg;
WHERE short PgpTimeout;
WHERE char *PgpEntryFormat;
@@ -49,6 +48,7 @@ WHERE char *PgpGetkeysCommand;
BODY *pgp_decrypt_part (BODY *, STATE *, FILE *);
BODY *pgp_make_key_attachment (char *);
+const char *pgp_micalg (const char *fname);
char *_pgp_keyid (pgp_key_t *);
char *pgp_keyid (pgp_key_t *);
diff --git a/pgplib.c b/pgplib.c
index f22a3db3..dc1fca0f 100644
--- a/pgplib.c
+++ b/pgplib.c
@@ -52,44 +52,6 @@ const char *pgp_pkalgbytype (unsigned char type)
}
-static struct
-{
- char *pkalg;
- char *micalg;
-}
-pktomic[] =
-{
- {
- "RSA", "pgp-md5"
- }
- ,
- {
- "ElG", "pgp-rmd160"
- }
- ,
- {
- "DSA", "pgp-sha1"
- }
- ,
- {
- NULL, "x-unknown"
- }
-};
-
-
-const char *pgp_pkalg_to_mic (const char *alg)
-{
- int i;
-
- for (i = 0; pktomic[i].pkalg; i++)
- {
- if (!mutt_strcasecmp (pktomic[i].pkalg, alg))
- break;
- }
-
- return pktomic[i].micalg;
-}
-
/* unused */
diff --git a/pgplib.h b/pgplib.h
index 574aa779..55ce4050 100644
--- a/pgplib.h
+++ b/pgplib.h
@@ -81,7 +81,6 @@ typedef enum pgp_ring pgp_ring_t;
/* prototypes */
-const char *pgp_pkalg_to_mic (const char *);
const char *pgp_pkalgbytype (unsigned char);
pgp_key_t *pgp_remove_key (pgp_key_t **, pgp_key_t *);
diff --git a/pgpmicalg.c b/pgpmicalg.c
new file mode 100644
index 00000000..6ba7779c
--- /dev/null
+++ b/pgpmicalg.c
@@ -0,0 +1,204 @@
+/*
+ * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111, USA.
+ */
+
+/* This module peeks at a PGP signature and figures out the hash
+ * algorithm.
+ */
+
+#include "mutt.h"
+#include "pgp.h"
+#include "pgppacket.h"
+#include "mime.h"
+#include "charset.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+
+static struct
+{
+ short id;
+ const char *name;
+}
+HashAlgorithms[] =
+{
+ { 1, "pgp-md5" },
+ { 2, "pgp-sha1" },
+ { 3, "pgp-ripemd160" },
+ { 5, "pgp-md2" },
+ { 6, "pgp-tiger192" },
+ { 7, "pgp-haval-5-160" },
+ { -1, NULL }
+};
+
+static const char *pgp_hash_to_micalg (short id)
+{
+ int i;
+
+ for (i = 0; HashAlgorithms[i].id >= 0; i++)
+ if (HashAlgorithms[i].id == id)
+ return HashAlgorithms[i].name;
+ return "x-unknown";
+}
+
+static void pgp_dearmor (FILE *in, FILE *out)
+{
+ char line[HUGE_STRING];
+ long start;
+ long end;
+ char *r;
+
+ STATE state;
+
+ memset (&state, 0, sizeof (STATE));
+ state.fpin = in;
+ state.fpout = out;
+
+ /* find the beginning of ASCII armor */
+
+ while ((r = fgets (line, sizeof (line), in)) != NULL)
+ {
+ if (!strncmp (line, "-----BEGIN", 10))
+ break;
+ }
+ if (r == NULL)
+ {
+ dprint (1, (debugfile, "pgp_dearmor: Can't find begin of ASCII armor.\n"));
+ return;
+ }
+
+ /* skip the armor header */
+
+ while ((r = fgets (line, sizeof (line), in)) != NULL)
+ {
+ SKIPWS (r);
+ if (!*r) break;
+ }
+ if (r == NULL)
+ {
+ dprint (1, (debugfile, "pgp_dearmor: Armor header doesn't end.\n"));
+ return;
+ }
+
+ /* actual data starts here */
+ start = ftell (in);
+
+ /* find the checksum */
+
+ while ((r = fgets (line, sizeof (line), in)) != NULL)
+ {
+ if (*line == '=' || !strncmp (line, "-----END", 8))
+ break;
+ }
+ if (r == NULL)
+ {
+ dprint (1, (debugfile, "pgp_dearmor: Can't find end of ASCII armor.\n"));
+ return;
+ }
+
+ if ((end = ftell (in) - strlen (line)) < start)
+ {
+ dprint (1, (debugfile, "pgp_dearmor: end < start???\n"));
+ return;
+ }
+
+ if (fseek (in, start, SEEK_SET) == -1)
+ {
+ dprint (1, (debugfile, "pgp_dearmor: Can't seekto start.\n"));
+ return;
+ }
+
+ mutt_decode_base64 (&state, end - start, 0, (iconv_t) -1);
+}
+
+static short pgp_mic_from_packet (unsigned char *p, size_t len)
+{
+ /* is signature? */
+ if ((p[0] & 0x3f) != PT_SIG)
+ {
+ dprint (1, (debugfile, "pgp_mic_from_packet: tag = %d, want %d.\n",
+ p[0]&0x3f, PT_SIG));
+ return -1;
+ }
+
+ if (len >= 18 && p[1] == 3)
+ /* version 3 signature */
+ return (short) p[17];
+ else if (len >= 5 && p[1] == 4)
+ /* version 4 signature */
+ return (short) p[4];
+ else
+ {
+ dprint (1, (debugfile, "pgp_mic_from_packet: Bad signature packet.\n"));
+ return -1;
+ }
+}
+
+static short pgp_find_hash (const char *fname)
+{
+ FILE *in = NULL;
+ FILE *out = NULL;
+
+ char tempfile[_POSIX_PATH_MAX];
+
+ unsigned char *p;
+ size_t l;
+
+ short rv = -1;
+
+ mutt_mktemp (tempfile);
+ if ((out = safe_fopen (tempfile, "w+")) == NULL)
+ {
+ mutt_perror (tempfile);
+ goto bye;
+ }
+ unlink (tempfile);
+
+ if ((in = fopen (fname, "r")) == NULL)
+ {
+ mutt_perror (fname);
+ goto bye;
+ }
+
+ pgp_dearmor (in, out);
+ rewind (out);
+
+ if ((p = pgp_read_packet (out, &l)) != NULL)
+ {
+ rv = pgp_mic_from_packet (p, l);
+ }
+ else
+ {
+ dprint (1, (debugfile, "pgp_find_hash: No packet.\n"));
+ }
+
+ bye:
+
+ safe_fclose (&in);
+ safe_fclose (&out);
+ pgp_release_packet ();
+ return rv;
+}
+
+const char *pgp_micalg (const char *fname)
+{
+ return pgp_hash_to_micalg (pgp_find_hash (fname));
+}
+
diff --git a/pgppacket.c b/pgppacket.c
new file mode 100644
index 00000000..519e70b3
--- /dev/null
+++ b/pgppacket.c
@@ -0,0 +1,226 @@
+/*
+ * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111, USA.
+ */
+
+#include "config.h"
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+
+#include "sha1.h"
+#include "lib.h"
+#include "pgplib.h"
+#include "pgppacket.h"
+
+#define CHUNKSIZE 1024
+
+static unsigned char *pbuf = NULL;
+static size_t plen = 0;
+
+static int read_material (size_t material, size_t * used, FILE * fp)
+{
+ if (*used + material >= plen)
+ {
+ unsigned char *p;
+ size_t nplen;
+
+ nplen = *used + material + CHUNKSIZE;
+
+ if (!(p = realloc (pbuf, nplen))) /* __MEM_CHECKED__ */
+ {
+ perror ("realloc");
+ return -1;
+ }
+ plen = nplen;
+ pbuf = p;
+ }
+
+ if (fread (pbuf + *used, 1, material, fp) < material)
+ {
+ perror ("fread");
+ return -1;
+ }
+
+ *used += material;
+ return 0;
+}
+
+unsigned char *pgp_read_packet (FILE * fp, size_t * len)
+{
+ size_t used = 0;
+ long startpos;
+ unsigned char ctb;
+ unsigned char b;
+ size_t material;
+
+ startpos = ftell (fp);
+
+ if (!plen)
+ {
+ plen = CHUNKSIZE;
+ pbuf = safe_malloc (plen);
+ }
+
+ if (fread (&ctb, 1, 1, fp) < 1)
+ {
+ if (!feof (fp))
+ perror ("fread");
+ goto bail;
+ }
+
+ if (!(ctb & 0x80))
+ {
+ goto bail;
+ }
+
+ if (ctb & 0x40) /* handle PGP 5.0 packets. */
+ {
+ int partial = 0;
+ pbuf[0] = ctb;
+ used++;
+
+ do
+ {
+ if (fread (&b, 1, 1, fp) < 1)
+ {
+ perror ("fread");
+ goto bail;
+ }
+
+ if (b < 192)
+ {
+ material = b;
+ partial = 0;
+ material -= 1;
+ }
+ else if (192 <= b && b <= 223)
+ {
+ material = (b - 192) * 256;
+ if (fread (&b, 1, 1, fp) < 1)
+ {
+ perror ("fread");
+ goto bail;
+ }
+ material += b + 192;
+ partial = 0;
+ material -= 2;
+ }
+ else if (b < 255)
+ {
+ material = 1 << (b & 0x1f);
+ partial = 1;
+ material -= 1;
+ }
+ else
+ /* b == 255 */
+ {
+ unsigned char buf[4];
+ if (fread (buf, 4, 1, fp) < 1)
+ {
+ perror ("fread");
+ goto bail;
+ }
+ /*assert( sizeof(material) >= 4 ); */
+ material = buf[0] << 24;
+ material |= buf[1] << 16;
+ material |= buf[2] << 8;
+ material |= buf[3];
+ partial = 0;
+ material -= 5;
+ }
+
+ if (read_material (material, &used, fp) == -1)
+ goto bail;
+
+ }
+ while (partial);
+ }
+ else
+ /* Old-Style PGP */
+ {
+ int bytes = 0;
+ pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
+ used++;
+
+ switch (ctb & 0x03)
+ {
+ case 0:
+ {
+ if (fread (&b, 1, 1, fp) < 1)
+ {
+ perror ("fread");
+ goto bail;
+ }
+
+ material = b;
+ break;
+ }
+
+ case 1:
+ bytes = 2;
+
+ case 2:
+ {
+ int i;
+
+ if (!bytes)
+ bytes = 4;
+
+ material = 0;
+
+ for (i = 0; i < bytes; i++)
+ {
+ if (fread (&b, 1, 1, fp) < 1)
+ {
+ perror ("fread");
+ goto bail;
+ }
+
+ material = (material << 8) + b;
+ }
+ break;
+ }
+
+ default:
+ goto bail;
+ }
+
+ if (read_material (material, &used, fp) == -1)
+ goto bail;
+ }
+
+ if (len)
+ *len = used;
+
+ return pbuf;
+
+bail:
+
+ fseek (fp, startpos, SEEK_SET);
+ return NULL;
+}
+
+void pgp_release_packet (void)
+{
+ plen = 0;
+ free (pbuf);
+ pbuf = NULL;
+}
+
diff --git a/pgppacket.h b/pgppacket.h
new file mode 100644
index 00000000..4b7fd647
--- /dev/null
+++ b/pgppacket.h
@@ -0,0 +1,52 @@
+/*
+ * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 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, write to the Free
+ * Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
+ * MA 02111, USA.
+ */
+
+/*
+ * Definitions for a rudimentary PGP packet parser which is shared
+ * by mutt proper and the PGP public key ring lister.
+ */
+
+#ifndef _PGPPACKET_H
+# define _PGPPACKET_H
+
+enum packet_tags
+{
+ PT_RES0 = 0, /* reserved */
+ PT_ESK, /* Encrypted Session Key */
+ PT_SIG, /* Signature Packet */
+ PT_CESK, /* Conventionally Encrypted Session Key Packet */
+ PT_OPS, /* One-Pass Signature Packet */
+ PT_SECKEY, /* Secret Key Packet */
+ PT_PUBKEY, /* Public Key Packet */
+ PT_SUBSECKEY, /* Secret Subkey Packet */
+ PT_COMPRESSED, /* Compressed Data Packet */
+ PT_SKE, /* Symmetrically Encrypted Data Packet */
+ PT_MARKER, /* Marker Packet */
+ PT_LITERAL, /* Literal Data Packet */
+ PT_TRUST, /* Trust Packet */
+ PT_NAME, /* Name Packet */
+ PT_SUBKEY, /* Subkey Packet */
+ PT_RES15, /* Reserved */
+ PT_COMMENT /* Comment Packet */
+};
+
+unsigned char *pgp_read_packet (FILE * fp, size_t * len);
+void pgp_release_packet (void);
+
+#endif
diff --git a/pgppubring.c b/pgppubring.c
index aa05822a..0181264f 100644
--- a/pgppubring.c
+++ b/pgppubring.c
@@ -52,6 +52,8 @@ extern int optind;
#include "sha1.h"
#include "lib.h"
#include "pgplib.h"
+#include "pgppacket.h"
+
#ifdef HAVE_FGETPOS
#define FGETPOS(fp,pos) fgetpos((fp),&(pos))
@@ -61,10 +63,7 @@ extern int optind;
#define FSETPOS(fp,pos) fseek((fp),(pos),SEEK_SET)
#endif
-#define CHUNKSIZE 1024
-static unsigned char *pbuf = NULL;
-static size_t plen = 0;
static void pgpring_find_candidates (char *ringfile, const char *hints[], int nhints);
static void pgpring_dump_keyblock (pgp_key_t *p);
@@ -141,243 +140,6 @@ int main (int argc, char * const argv[])
/* The actual key ring parser */
-enum packet_tags
-{
- PT_RES0 = 0, /* reserved */
- PT_ESK, /* Encrypted Session Key */
- PT_SIG, /* Signature Packet */
- PT_CESK, /* Conventionally Encrypted Session Key Packet */
- PT_OPS, /* One-Pass Signature Packet */
- PT_SECKEY, /* Secret Key Packet */
- PT_PUBKEY, /* Public Key Packet */
- PT_SUBSECKEY, /* Secret Subkey Packet */
- PT_COMPRESSED, /* Compressed Data Packet */
- PT_SKE, /* Symmetrically Encrypted Data Packet */
- PT_MARKER, /* Marker Packet */
- PT_LITERAL, /* Literal Data Packet */
- PT_TRUST, /* Trust Packet */
- PT_NAME, /* Name Packet */
- PT_SUBKEY, /* Subkey Packet */
- PT_RES15, /* Reserved */
- PT_COMMENT /* Comment Packet */
-};
-
-/*
- * These aren't displayed at all currently, but they may come quite
- * handy for debugging strings.
- *
- * No need to translate them.
- *
- */
-
-#if 0
-
-const char *pgp_packet_name[] =
-{
- "reserved",
- "Encrypted Session Key",
- "Signature Packet",
- "Conventionally Encrypted Session Key Packet",
- "One-Pass Signature Packet",
- "Secret Key Packet",
- "Public Key Packet",
- "Secret Subkey Packet",
- "Compressed Data Packet",
- "Symmetrically Encrypted Data Packet",
- "Marker Packet",
- "Literal Data Packet",
- "Trust Packet",
- "Name Packet",
- "Subkey Packet",
- "Reserved",
- "Comment Packet"
-};
-
-#endif
-
-static int read_material (size_t material, size_t * used, FILE * fp)
-{
- if (*used + material >= plen)
- {
- unsigned char *p;
- size_t nplen;
-
- nplen = *used + material + CHUNKSIZE;
-
- if (!(p = realloc (pbuf, nplen))) /* __MEM_CHECKED__ */
- {
- perror ("realloc");
- return -1;
- }
- plen = nplen;
- pbuf = p;
- }
-
- if (fread (pbuf + *used, 1, material, fp) < material)
- {
- perror ("fread");
- return -1;
- }
-
- *used += material;
- return 0;
-}
-
-static unsigned char *pgp_read_packet (FILE * fp, size_t * len)
-{
- size_t used = 0;
- long startpos;
- unsigned char ctb;
- unsigned char b;
- size_t material;
-
- startpos = ftell (fp);
-
- if (!plen)
- {
- plen = CHUNKSIZE;
- pbuf = safe_malloc (plen);
- }
-
- if (fread (&ctb, 1, 1, fp) < 1)
- {
- if (!feof (fp))
- perror ("fread");
- goto bail;
- }
-
- if (!(ctb & 0x80))
- {
- goto bail;
- }
-
- if (ctb & 0x40) /* handle PGP 5.0 packets. */
- {
- int partial = 0;
- pbuf[0] = ctb;
- used++;
-
- do
- {
- if (fread (&b, 1, 1, fp) < 1)
- {
- perror ("fread");
- goto bail;
- }
-
- if (b < 192)
- {
- material = b;
- partial = 0;
- material -= 1;
- }
- else if (192 <= b && b <= 223)
- {
- material = (b - 192) * 256;
- if (fread (&b, 1, 1, fp) < 1)
- {
- perror ("fread");
- goto bail;
- }
- material += b + 192;
- partial = 0;
- material -= 2;
- }
- else if (b < 255)
- {
- material = 1 << (b & 0x1f);
- partial = 1;
- material -= 1;
- }
- else
- /* b == 255 */
- {
- unsigned char buf[4];
- if (fread (buf, 4, 1, fp) < 1)
- {
- perror ("fread");
- goto bail;
- }
- /*assert( sizeof(material) >= 4 ); */
- material = buf[0] << 24;
- material |= buf[1] << 16;
- material |= buf[2] << 8;
- material |= buf[3];
- partial = 0;
- material -= 5;
- }
-
- if (read_material (material, &used, fp) == -1)
- goto bail;
-
- }
- while (partial);
- }
- else
- /* Old-Style PGP */
- {
- int bytes = 0;
- pbuf[0] = 0x80 | ((ctb >> 2) & 0x0f);
- used++;
-
- switch (ctb & 0x03)
- {
- case 0:
- {
- if (fread (&b, 1, 1, fp) < 1)
- {
- perror ("fread");
- goto bail;
- }
-
- material = b;
- break;
- }
-
- case 1:
- bytes = 2;
-
- case 2:
- {
- int i;
-
- if (!bytes)
- bytes = 4;
-
- material = 0;
-
- for (i = 0; i < bytes; i++)
- {
- if (fread (&b, 1, 1, fp) < 1)
- {
- perror ("fread");
- goto bail;
- }
-
- material = (material << 8) + b;
- }
- break;
- }
-
- default:
- goto bail;
- }
-
- if (read_material (material, &used, fp) == -1)
- goto bail;
- }
-
- if (len)
- *len = used;
-
- return pbuf;
-
-bail:
-
- fseek (fp, startpos, SEEK_SET);
- return NULL;
-}
-
static pgp_key_t *pgp_parse_pgp2_key (unsigned char *buff, size_t l)
{
pgp_key_t *p;
diff --git a/postpone.c b/postpone.c
index 330f7471..030c83d4 100644
--- a/postpone.c
+++ b/postpone.c
@@ -387,7 +387,6 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
{
int pgp = 0;
char pgp_sign_as[LONG_STRING] = "\0", *q;
- char pgp_sign_micalg[LONG_STRING] = "\0";
SKIPWS (p);
for (; *p; p++)
@@ -422,16 +421,17 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
*q = '\0';
break;
+ /* This used to be the micalg parameter.
+ *
+ * It's no longer needed, so we just skip the parameter in order
+ * to be able to recall old messages.
+ */
case 'm':
case 'M':
- q = pgp_sign_micalg;
-
if(*(p+1) == '<')
- {
- for(p += 2; *p && *p != '>' && q < pgp_sign_micalg + sizeof(pgp_sign_micalg) - 1;
- *q++ = *p++)
+ {
+ for (p += 2; *p && *p != '>'; p++)
;
-
if(*p != '>')
{
mutt_error _("Illegal PGP header");
@@ -439,7 +439,6 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
}
}
- *q = '\0';
break;
default:
@@ -452,10 +451,6 @@ int mutt_parse_pgp_hdr (char *p, int set_signas)
if (set_signas || *pgp_sign_as)
mutt_str_replace (&PgpSignAs, pgp_sign_as);
- /* the micalg field must not be empty */
- if (set_signas && *pgp_sign_micalg)
- mutt_str_replace (&PgpSignMicalg, pgp_sign_micalg);
-
return pgp;
}
#endif /* HAVE_PGP */
diff --git a/protos.h b/protos.h
index dc6bab9a..c29e8119 100644
--- a/