-/*
- * Copyright notice from original mutt:
- * Copyright (C) 2001 Thomas Roessler <roessler@does-not-exist.org>
- *
- * This file is part of mutt-ng, see http://www.muttng.org/.
- * It's licensed under the GNU General Public License,
- * please see the file GPL in the top level source directory.
- */
-
-/* This module peeks at a PGP signature and figures out the hash
- * algorithm.
- */
-
-#include <lib-lib/lib-lib.h>
-
-#include <lib-mime/mime.h>
-#include <lib-ui/curses.h>
-
-#include "handler.h"
-#include "pgp.h"
-#include "pgppacket.h"
-#include "charset.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"}, {
- 8, "pgp-sha256"}, {
- 9, "pgp-sha384"}, {
- 10, "pgp-sha512"}, {
- -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];
- off_t start;
- off_t end;
- char *r;
-
- STATE state;
-
- p_clear(&state, 1);
- state.fpin = in;
- state.fpout = out;
-
- /* find the beginning of ASCII armor */
-
- while ((r = fgets (line, sizeof (line), in)) != NULL) {
- if (!m_strncmp (line, "-----BEGIN", 10))
- break;
- }
- if (r == NULL) {
- return;
- }
-
- /* skip the armor header */
-
- while ((r = fgets (line, sizeof (line), in)) != NULL) {
- r = vskipspaces(r);
- if (!*r)
- break;
- }
- if (r == NULL) {
- return;
- }
-
- /* actual data starts here */
- start = ftello (in);
-
- /* find the checksum */
-
- while ((r = fgets (line, sizeof (line), in)) != NULL) {
- if (*line == '=' || !m_strncmp (line, "-----END", 8))
- break;
- }
- if (r == NULL) {
- return;
- }
-
- if ((end = ftello (in) - m_strlen(line)) < start) {
- return;
- }
-
- if (fseeko (in, start, SEEK_SET) == -1) {
- return;
- }
-
- mutt_decode_base64 (&state, end - start, 0, MUTT_ICONV_ERROR);
-}
-
-static short pgp_mic_from_packet (unsigned char *p, size_t len)
-{
- /* is signature? */
- if ((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 {
- 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;
-
- out = m_tempfile (tempfile, sizeof(tempfile), NONULL(MCore.tmpdir), NULL);
- if (!out) {
- mutt_perror (_("Can't create temporary file"));
- goto bye;
- }
- unlink (tempfile);
-
- if ((in = fopen (fname, "r")) == NULL) {
- mutt_perror (_("Can't create temporary file"));
- goto bye;
- }
-
- pgp_dearmor (in, out);
- rewind (out);
-
- if ((p = pgp_read_packet (out, &l)) != NULL) {
- rv = pgp_mic_from_packet (p, l);
- }
-
-bye:
-
- m_fclose(&in);
- m_fclose(&out);
- pgp_release_packet ();
- return rv;
-}
-
-const char *pgp_micalg (const char *fname)
-{
- return pgp_hash_to_micalg (pgp_find_hash (fname));
-}