NeoMutt  2019-12-07-60-g0cfa53
Teaching an old dog new tricks
DOXYGEN
pgpmicalg.c File Reference

Identify the hash algorithm from a PGP signature. More...

#include "config.h"
#include <iconv.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include "mutt/mutt.h"
#include "pgpmicalg.h"
#include "handler.h"
#include "pgppacket.h"
#include "state.h"
+ Include dependency graph for pgpmicalg.c:

Go to the source code of this file.

Functions

static const char * pgp_hash_to_micalg (short id)
 Lookup a hash name, given its id. More...
 
static void pgp_dearmor (FILE *fp_in, FILE *fp_out)
 Unwrap an armoured PGP block. More...
 
static short pgp_mic_from_packet (unsigned char *p, size_t len)
 Get the hash algorithm from a PGP packet. More...
 
static short pgp_find_hash (const char *fname)
 Find the hash algorithm of a file. More...
 
const char * pgp_micalg (const char *fname)
 Find the hash algorithm of a file. More...
 

Variables

struct {
   short   id
 
   const char *   name
 
HashAlgorithms []
 PGP Hashing algorithms. More...
 

Detailed Description

Identify the hash algorithm from a PGP signature.

Authors
  • Thomas Roessler

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, see http://www.gnu.org/licenses/.

Definition in file pgpmicalg.c.

Function Documentation

◆ pgp_hash_to_micalg()

static const char* pgp_hash_to_micalg ( short  id)
static

Lookup a hash name, given its id.

Parameters
idID
Return values
ptrName of hash algorithm

Definition at line 59 of file pgpmicalg.c.

60 {
61  for (int i = 0; HashAlgorithms[i].id >= 0; i++)
62  if (HashAlgorithms[i].id == id)
63  return HashAlgorithms[i].name;
64  return "x-unknown";
65 }
static const struct @1 HashAlgorithms[]
PGP Hashing algorithms.
+ Here is the caller graph for this function:

◆ pgp_dearmor()

static void pgp_dearmor ( FILE *  fp_in,
FILE *  fp_out 
)
static

Unwrap an armoured PGP block.

Parameters
fp_inFile to read from
fp_outFile to write to

Definition at line 72 of file pgpmicalg.c.

73 {
74  char line[8192];
75  char *r = NULL;
76 
77  struct State state = { 0 };
78  state.fp_in = fp_in;
79  state.fp_out = fp_out;
80 
81  /* find the beginning of ASCII armor */
82 
83  while ((r = fgets(line, sizeof(line), fp_in)))
84  {
85  if (strncmp(line, "-----BEGIN", 10) == 0)
86  break;
87  }
88  if (!r)
89  {
90  mutt_debug(LL_DEBUG1, "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), fp_in)))
97  {
98  SKIPWS(r);
99  if (!*r)
100  break;
101  }
102  if (!r)
103  {
104  mutt_debug(LL_DEBUG1, "Armor header doesn't end\n");
105  return;
106  }
107 
108  /* actual data starts here */
109  LOFF_T start = ftello(fp_in);
110  if (start < 0)
111  return;
112 
113  /* find the checksum */
114 
115  while ((r = fgets(line, sizeof(line), fp_in)))
116  {
117  if ((*line == '=') || (strncmp(line, "-----END", 8) == 0))
118  break;
119  }
120  if (!r)
121  {
122  mutt_debug(LL_DEBUG1, "Can't find end of ASCII armor\n");
123  return;
124  }
125 
126  LOFF_T end = ftello(fp_in) - strlen(line);
127  if (end < start)
128  {
129  mutt_debug(LL_DEBUG1, "end < start???\n");
130  return;
131  }
132 
133  if (fseeko(fp_in, start, SEEK_SET) == -1)
134  {
135  mutt_debug(LL_DEBUG1, "Can't seekto start\n");
136  return;
137  }
138 
139  mutt_decode_base64(&state, end - start, false, (iconv_t) -1);
140 }
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
void mutt_decode_base64(struct State *s, size_t len, bool istext, iconv_t cd)
Decode base64-encoded text.
Definition: handler.c:1487
#define SKIPWS(ch)
Definition: string2.h:47
const char * line
Definition: common.c:36
Log at debug level 1.
Definition: logging.h:40
Keep track when processing files.
Definition: state.h:44
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_mic_from_packet()

static short pgp_mic_from_packet ( unsigned char *  p,
size_t  len 
)
static

Get the hash algorithm from a PGP packet.

Parameters
pPGP packet
lenLength of packet
Return values
numHash algorithm id

Definition at line 148 of file pgpmicalg.c.

149 {
150  /* is signature? */
151  if ((p[0] & 0x3f) != PT_SIG)
152  {
153  mutt_debug(LL_DEBUG1, "tag = %d, want %d\n", p[0] & 0x3f, PT_SIG);
154  return -1;
155  }
156 
157  if ((len >= 18) && (p[1] == 3))
158  {
159  /* version 3 signature */
160  return (short) p[17];
161  }
162  else if ((len >= 5) && (p[1] == 4))
163  {
164  /* version 4 signature */
165  return (short) p[4];
166  }
167  else
168  {
169  mutt_debug(LL_DEBUG1, "Bad signature packet\n");
170  return -1;
171  }
172 }
Signature Packet.
Definition: pgppacket.h:39
Log at debug level 1.
Definition: logging.h:40
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
+ Here is the caller graph for this function:

◆ pgp_find_hash()

static short pgp_find_hash ( const char *  fname)
static

Find the hash algorithm of a file.

Parameters
fnameFile to read
Return values
numHash algorithm id

Definition at line 179 of file pgpmicalg.c.

180 {
181  size_t l;
182  short rc = -1;
183 
184  FILE *fp_out = mutt_file_mkstemp();
185  if (!fp_out)
186  {
187  mutt_perror(_("Can't create temporary file"));
188  goto bye;
189  }
190 
191  FILE *fp_in = fopen(fname, "r");
192  if (!fp_in)
193  {
194  mutt_perror(fname);
195  goto bye;
196  }
197 
198  pgp_dearmor(fp_in, fp_out);
199  rewind(fp_out);
200 
201  unsigned char *p = pgp_read_packet(fp_out, &l);
202  if (p)
203  {
204  rc = pgp_mic_from_packet(p, l);
205  }
206  else
207  {
208  mutt_debug(LL_DEBUG1, "No packet\n");
209  }
210 
211 bye:
212 
213  mutt_file_fclose(&fp_in);
214  mutt_file_fclose(&fp_out);
216  return rc;
217 }
#define mutt_perror(...)
Definition: logging.h:85
void pgp_release_packet(void)
Free the cached PGP packet.
Definition: pgppacket.c:239
#define _(a)
Definition: message.h:28
FILE * fp_out
File to write to.
Definition: state.h:47
FILE * fp_in
File to read from.
Definition: state.h:46
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
#define mutt_file_mkstemp()
Definition: file.h:105
Log at debug level 1.
Definition: logging.h:40
static void pgp_dearmor(FILE *fp_in, FILE *fp_out)
Unwrap an armoured PGP block.
Definition: pgpmicalg.c:72
#define mutt_debug(LEVEL,...)
Definition: logging.h:81
unsigned char * pgp_read_packet(FILE *fp, size_t *len)
Read a PGP packet from a file.
Definition: pgppacket.c:84
static short pgp_mic_from_packet(unsigned char *p, size_t len)
Get the hash algorithm from a PGP packet.
Definition: pgpmicalg.c:148
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_micalg()

const char* pgp_micalg ( const char *  fname)

Find the hash algorithm of a file.

Parameters
fnameFile to read
Return values
ptrName of hash algorithm

Definition at line 224 of file pgpmicalg.c.

225 {
226  return pgp_hash_to_micalg(pgp_find_hash(fname));
227 }
static const char * pgp_hash_to_micalg(short id)
Lookup a hash name, given its id.
Definition: pgpmicalg.c:59
static short pgp_find_hash(const char *fname)
Find the hash algorithm of a file.
Definition: pgpmicalg.c:179
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ id

short id

Definition at line 45 of file pgpmicalg.c.

◆ name

const char* name

Definition at line 46 of file pgpmicalg.c.

◆ HashAlgorithms

const { ... } HashAlgorithms[]
Initial value:
= {
{ 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" },
{ 11, "pgp-sha224" }, { -1, NULL },
}

PGP Hashing algorithms.