NeoMutt  2021-10-29-43-g6b8931
Teaching an old dog new tricks
DOXYGEN
pgpkey.c File Reference

PGP key management routines. More...

#include "config.h"
#include <locale.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <unistd.h>
#include "private.h"
#include "mutt/lib.h"
#include "address/lib.h"
#include "config/lib.h"
#include "email/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "mutt.h"
#include "pgpkey.h"
#include "lib.h"
#include "send/lib.h"
#include "crypt.h"
#include "gnupgparse.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "options.h"
#include "pgpinvoke.h"
#include "pgp.h"
#include "pgplib.h"
+ Include dependency graph for pgpkey.c:

Go to the source code of this file.

Data Structures

struct  PgpCache
 List of cached PGP keys. More...
 

Macros

#define PGP_KV_NO_FLAGS   0
 No flags are set. More...
 
#define PGP_KV_VALID   (1 << 0)
 PGP Key ID is valid. More...
 
#define PGP_KV_ADDR   (1 << 1)
 PGP Key address is valid. More...
 
#define PGP_KV_STRING   (1 << 2)
 PGP Key name string is valid. More...
 
#define PGP_KV_STRONGID   (1 << 3)
 PGP Key is strong. More...
 
#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)
 

Typedefs

typedef uint8_t PgpKeyValidFlags
 Flags for valid Pgp Key fields, e.g. PGP_KV_VALID. More...
 

Functions

struct PgpKeyInfopgp_principal_key (struct PgpKeyInfo *key)
 Get the main (parent) PGP key. More...
 
bool pgp_key_is_valid (struct PgpKeyInfo *k)
 Is a PGP key valid? More...
 
bool pgp_id_is_strong (struct PgpUid *uid)
 Is a PGP key strong? More...
 
bool pgp_id_is_valid (struct PgpUid *uid)
 Is a PGP key valid. More...
 
static PgpKeyValidFlags pgp_id_matches_addr (struct Address *addr, struct Address *u_addr, struct PgpUid *uid)
 Does the key ID match the address. More...
 
struct PgpKeyInfopgp_ask_for_key (char *tag, char *whatfor, KeyFlags abilities, enum PgpRing keyring)
 Ask the user for a PGP key. More...
 
struct Bodypgp_class_make_key_attachment (void)
 Implements CryptModuleSpecs::pgp_make_key_attachment() -. More...
 
static void pgp_add_string_to_hints (const char *str, struct ListHead *hints)
 Split a string and add the parts to a List. More...
 
static struct PgpKeyInfo ** pgp_get_lastp (struct PgpKeyInfo *p)
 Get the last PGP key in a list. More...
 
struct PgpKeyInfopgp_getkeybyaddr (struct Address *a, KeyFlags abilities, enum PgpRing keyring, bool oppenc_mode)
 Find a PGP key by address. More...
 
struct PgpKeyInfopgp_getkeybystr (const char *cp, KeyFlags abilities, enum PgpRing keyring)
 Find a PGP key by string. More...
 

Variables

static struct PgpCacheid_defaults = NULL
 

Detailed Description

PGP key management routines.

Authors
  • Michael R. Elkins
  • Thomas Roessler
  • Pietro Cerutti

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 pgpkey.c.

Macro Definition Documentation

◆ PGP_KV_NO_FLAGS

#define PGP_KV_NO_FLAGS   0

No flags are set.

Definition at line 75 of file pgpkey.c.

◆ PGP_KV_VALID

#define PGP_KV_VALID   (1 << 0)

PGP Key ID is valid.

Definition at line 76 of file pgpkey.c.

◆ PGP_KV_ADDR

#define PGP_KV_ADDR   (1 << 1)

PGP Key address is valid.

Definition at line 77 of file pgpkey.c.

◆ PGP_KV_STRING

#define PGP_KV_STRING   (1 << 2)

PGP Key name string is valid.

Definition at line 78 of file pgpkey.c.

◆ PGP_KV_STRONGID

#define PGP_KV_STRONGID   (1 << 3)

PGP Key is strong.

Definition at line 79 of file pgpkey.c.

◆ PGP_KV_MATCH

#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)

Definition at line 82 of file pgpkey.c.

Typedef Documentation

◆ PgpKeyValidFlags

typedef uint8_t PgpKeyValidFlags

Flags for valid Pgp Key fields, e.g. PGP_KV_VALID.

Definition at line 74 of file pgpkey.c.

Function Documentation

◆ pgp_principal_key()

struct PgpKeyInfo* pgp_principal_key ( struct PgpKeyInfo key)

Get the main (parent) PGP key.

Parameters
keyKey to start with
Return values
ptrPGP Key

Definition at line 89 of file pgpkey.c.

90 {
91  if (key->flags & KEYFLAG_SUBKEY && key->parent)
92  return key->parent;
93  return key;
94 }
#define KEYFLAG_SUBKEY
Key is a subkey.
Definition: lib.h:131
KeyFlags flags
Definition: pgplib.h:51
struct PgpKeyInfo * parent
Definition: pgplib.h:56
+ Here is the caller graph for this function:

◆ pgp_key_is_valid()

bool pgp_key_is_valid ( struct PgpKeyInfo k)

Is a PGP key valid?

Parameters
kKey to examine
Return values
trueKey is valid

Definition at line 101 of file pgpkey.c.

102 {
103  struct PgpKeyInfo *pk = pgp_principal_key(k);
104  if (k->flags & KEYFLAG_CANTUSE)
105  return false;
106  if (pk->flags & KEYFLAG_CANTUSE)
107  return false;
108 
109  return true;
110 }
#define KEYFLAG_CANTUSE
Definition: lib.h:136
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition: pgpkey.c:89
Information about a PGP key.
Definition: pgplib.h:47
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_id_is_strong()

bool pgp_id_is_strong ( struct PgpUid uid)

Is a PGP key strong?

Parameters
uidUID of a PGP key
Return values
trueKey is strong

Definition at line 117 of file pgpkey.c.

118 {
119  if ((uid->trust & 3) < 3)
120  return false;
121  /* else */
122  return true;
123 }
short trust
Definition: pgplib.h:37
+ Here is the caller graph for this function:

◆ pgp_id_is_valid()

bool pgp_id_is_valid ( struct PgpUid uid)

Is a PGP key valid.

Parameters
uidUID of a PGP key
Return values
trueKey is valid

Definition at line 130 of file pgpkey.c.

131 {
132  if (!pgp_key_is_valid(uid->parent))
133  return false;
134  if (uid->flags & KEYFLAG_CANTUSE)
135  return false;
136  /* else */
137  return true;
138 }
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition: pgpkey.c:101
struct PgpKeyInfo * parent
Parent key.
Definition: pgplib.h:39
int flags
Definition: pgplib.h:38
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_id_matches_addr()

static PgpKeyValidFlags pgp_id_matches_addr ( struct Address addr,
struct Address u_addr,
struct PgpUid uid 
)
static

Does the key ID match the address.

Parameters
addrFirst email address
u_addrSecond email address
uidUID of PGP key
Return values
numFlags, e.g. PGP_KV_VALID

Definition at line 147 of file pgpkey.c.

149 {
151 
152  if (pgp_id_is_valid(uid))
153  flags |= PGP_KV_VALID;
154 
155  if (pgp_id_is_strong(uid))
156  flags |= PGP_KV_STRONGID;
157 
158  if (addr->mailbox && u_addr->mailbox && mutt_istr_equal(addr->mailbox, u_addr->mailbox))
159  {
160  flags |= PGP_KV_ADDR;
161  }
162 
163  if (addr->personal && u_addr->personal &&
164  mutt_istr_equal(addr->personal, u_addr->personal))
165  {
166  flags |= PGP_KV_STRING;
167  }
168 
169  return flags;
170 }
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:727
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition: pgpkey.c:130
#define PGP_KV_NO_FLAGS
No flags are set.
Definition: pgpkey.c:75
#define PGP_KV_STRONGID
PGP Key is strong.
Definition: pgpkey.c:79
#define PGP_KV_VALID
PGP Key ID is valid.
Definition: pgpkey.c:76
#define PGP_KV_STRING
PGP Key name string is valid.
Definition: pgpkey.c:78
#define PGP_KV_ADDR
PGP Key address is valid.
Definition: pgpkey.c:77
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition: pgpkey.c:117
uint8_t PgpKeyValidFlags
Flags for valid Pgp Key fields, e.g. PGP_KV_VALID.
Definition: pgpkey.c:74
char * mailbox
Mailbox and host address.
Definition: address.h:38
char * personal
Real name of address.
Definition: address.h:37
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_ask_for_key()

struct PgpKeyInfo* pgp_ask_for_key ( char *  tag,
char *  whatfor,
KeyFlags  abilities,
enum PgpRing  keyring 
)

Ask the user for a PGP key.

Parameters
tagPrompt for the user
whatforUse for key, e.g. "signing"
abilitiesAbilities to match, see KeyFlags
keyringPGP keyring to use
Return values
ptrSelected PGP key

Definition at line 180 of file pgpkey.c.

182 {
183  struct PgpKeyInfo *key = NULL;
184  char resp[128];
185  struct PgpCache *l = NULL;
186 
188 
189  resp[0] = '\0';
190  if (whatfor)
191  {
192  for (l = id_defaults; l; l = l->next)
193  {
194  if (mutt_istr_equal(whatfor, l->what))
195  {
196  mutt_str_copy(resp, l->dflt, sizeof(resp));
197  break;
198  }
199  }
200  }
201 
202  while (true)
203  {
204  resp[0] = '\0';
205  if (mutt_get_field(tag, resp, sizeof(resp), MUTT_COMP_NO_FLAGS, false, NULL, NULL) != 0)
206  {
207  return NULL;
208  }
209 
210  if (whatfor)
211  {
212  if (l)
213  mutt_str_replace(&l->dflt, resp);
214  else
215  {
216  l = mutt_mem_malloc(sizeof(struct PgpCache));
217  l->next = id_defaults;
218  id_defaults = l;
219  l->what = mutt_str_dup(whatfor);
220  l->dflt = mutt_str_dup(resp);
221  }
222  }
223 
224  key = pgp_getkeybystr(resp, abilities, keyring);
225  if (key)
226  return key;
227 
228  mutt_error(_("No matching keys found for \"%s\""), resp);
229  }
230  /* not reached */
231 }
int mutt_get_field(const char *field, char *buf, size_t buflen, CompletionFlags complete, bool multiple, char ***files, int *numfiles)
Ask the user for a string.
Definition: curs_lib.c:335
#define mutt_error(...)
Definition: logging.h:87
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define _(a)
Definition: message.h:28
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:181
size_t mutt_str_copy(char *dest, const char *src, size_t dsize)
Copy a string into a buffer (guaranteeing NUL-termination)
Definition: string.c:560
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:257
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:52
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:113
static struct PgpCache * id_defaults
Definition: pgpkey.c:71
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition: pgpkey.c:490
List of cached PGP keys.
Definition: pgpkey.c:65
char * dflt
Definition: pgpkey.c:67
struct PgpCache * next
Linked list.
Definition: pgpkey.c:68
char * what
Definition: pgpkey.c:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_add_string_to_hints()

static void pgp_add_string_to_hints ( const char *  str,
struct ListHead *  hints 
)
static

Split a string and add the parts to a List.

Parameters
[in]strString to parse
[out]hintsList of string parts

The string str is split by whitespace and punctuation and the parts added to hints.

Definition at line 316 of file pgpkey.c.

317 {
318  char *scratch = mutt_str_dup(str);
319  if (!scratch)
320  return;
321 
322  for (char *t = strtok(scratch, " ,.:\"()<>\n"); t;
323  t = strtok(NULL, " ,.:\"()<>\n"))
324  {
325  if (strlen(t) > 3)
327  }
328 
329  FREE(&scratch);
330 }
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
#define FREE(x)
Definition: memory.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_get_lastp()

static struct PgpKeyInfo** pgp_get_lastp ( struct PgpKeyInfo p)
static

Get the last PGP key in a list.

Parameters
pList of PGP keys
Return values
ptrLast PGP key in list

Definition at line 337 of file pgpkey.c.

338 {
339  for (; p; p = p->next)
340  if (!p->next)
341  return &p->next;
342 
343  return NULL;
344 }
struct PgpKeyInfo * next
Definition: pgplib.h:57
+ Here is the caller graph for this function:

◆ pgp_getkeybyaddr()

struct PgpKeyInfo* pgp_getkeybyaddr ( struct Address a,
KeyFlags  abilities,
enum PgpRing  keyring,
bool  oppenc_mode 
)

Find a PGP key by address.

Parameters
aEmail address to match
abilitiesAbilities to match, see KeyFlags
keyringPGP keyring to use
oppenc_modeIf true, use opportunistic encryption
Return values
ptrMatching PGP key

Definition at line 354 of file pgpkey.c.

356 {
357  if (!a)
358  return NULL;
359 
360  struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
361 
362  bool multi = false;
363 
364  struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
365  struct PgpKeyInfo *the_strong_valid_key = NULL;
366  struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
367  struct PgpKeyInfo *matches = NULL;
368  struct PgpKeyInfo **last = &matches;
369  struct PgpUid *q = NULL;
370 
371  if (a->mailbox)
373  if (a->personal)
374  pgp_add_string_to_hints(a->personal, &hints);
375 
376  if (!oppenc_mode)
377  mutt_message(_("Looking for keys matching \"%s\"..."), a->mailbox);
378  keys = pgp_get_candidates(keyring, &hints);
379 
380  mutt_list_free(&hints);
381 
382  if (!keys)
383  return NULL;
384 
385  mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", NONULL(a->personal), NONULL(a->mailbox));
386 
387  for (k = keys; k; k = kn)
388  {
389  kn = k->next;
390 
391  mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
392 
393  if (abilities && !(k->flags & abilities))
394  {
395  mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
396  continue;
397  }
398 
399  bool match = false; /* any match */
400 
401  for (q = k->address; q; q = q->next)
402  {
403  struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
404  mutt_addrlist_parse(&al, NONULL(q->addr));
405  struct Address *qa = NULL;
406  TAILQ_FOREACH(qa, &al, entries)
407  {
408  PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
409 
410  if (validity & PGP_KV_MATCH) /* something matches */
411  match = true;
412 
413  if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
414  {
415  if (validity & PGP_KV_STRONGID)
416  {
417  if (the_strong_valid_key && (the_strong_valid_key != k))
418  multi = true;
419  the_strong_valid_key = k;
420  }
421  else
422  {
423  a_valid_addrmatch_key = k;
424  }
425  }
426  }
427 
428  mutt_addrlist_clear(&al);
429  }
430 
431  if (match)
432  {
433  *last = pgp_principal_key(k);
434  kn = pgp_remove_key(&keys, *last);
435  last = pgp_get_lastp(k);
436  }
437  }
438 
439  pgp_key_free(&keys);
440 
441  if (matches)
442  {
443  if (oppenc_mode)
444  {
445  const bool c_crypt_opportunistic_encrypt_strong_keys = cs_subset_bool(
446  NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
447  if (the_strong_valid_key)
448  {
449  pgp_remove_key(&matches, the_strong_valid_key);
450  k = the_strong_valid_key;
451  }
452  else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
453  {
454  pgp_remove_key(&matches, a_valid_addrmatch_key);
455  k = a_valid_addrmatch_key;
456  }
457  else
458  k = NULL;
459  }
460  else if (the_strong_valid_key && !multi)
461  {
462  /* There was precisely one strong match on a valid ID.
463  * Proceed without asking the user. */
464  pgp_remove_key(&matches, the_strong_valid_key);
465  k = the_strong_valid_key;
466  }
467  else
468  {
469  /* Else: Ask the user. */
470  k = dlg_select_pgp_key(matches, a, NULL);
471  if (k)
472  pgp_remove_key(&matches, k);
473  }
474 
475  pgp_key_free(&matches);
476 
477  return k;
478  }
479 
480  return NULL;
481 }
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1470
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:458
struct PgpKeyInfo * dlg_select_pgp_key(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use.
Definition: dlgpgp.c:584
struct PgpKeyInfo * pgp_get_candidates(enum PgpRing keyring, struct ListHead *hints)
Find PGP keys matching a list of hints.
Definition: gnupgparse.c:414
#define mutt_message(...)
Definition: logging.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition: list.c:122
@ LL_DEBUG3
Log at debug level 3.
Definition: logging.h:42
@ LL_DEBUG5
Log at debug level 5.
Definition: logging.h:44
char * pgp_keyid(struct PgpKeyInfo *k)
Get the ID of the main (parent) key.
Definition: pgp.c:196
static void pgp_add_string_to_hints(const char *str, struct ListHead *hints)
Split a string and add the parts to a List.
Definition: pgpkey.c:316
#define PGP_KV_MATCH
Definition: pgpkey.c:82
static PgpKeyValidFlags pgp_id_matches_addr(struct Address *addr, struct Address *u_addr, struct PgpUid *uid)
Does the key ID match the address.
Definition: pgpkey.c:147
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition: pgpkey.c:337
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition: pgplib.c:167
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:199
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:725
#define STAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:324
#define TAILQ_HEAD_INITIALIZER(head)
Definition: queue.h:637
#define NONULL(x)
Definition: string2.h:37
An email address.
Definition: address.h:36
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
PGP User ID.
Definition: pgplib.h:35
char * addr
Definition: pgplib.h:36
struct PgpUid * next
Linked list.
Definition: pgplib.h:40
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ pgp_getkeybystr()

struct PgpKeyInfo* pgp_getkeybystr ( const char *  cp,
KeyFlags  abilities,
enum PgpRing  keyring 
)

Find a PGP key by string.

Parameters
cpString to match, can be empty but cannot be NULL
abilitiesAbilities to match, see KeyFlags
keyringPGP keyring to use
Return values
ptrMatching PGP key

Definition at line 490 of file pgpkey.c.

491 {
492  struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
493  struct PgpKeyInfo *keys = NULL;
494  struct PgpKeyInfo *matches = NULL;
495  struct PgpKeyInfo **last = &matches;
496  struct PgpKeyInfo *k = NULL, *kn = NULL;
497  struct PgpUid *a = NULL;
498  size_t l;
499  const char *ps = NULL, *pl = NULL, *pfcopy = NULL, *phint = NULL;
500 
501  char *p = strdup(cp); // mutt_str_dup converts "" into NULL, see #1809
502  l = mutt_str_len(p);
503  if ((l > 0) && (p[l - 1] == '!'))
504  p[l - 1] = 0;
505 
506  mutt_message(_("Looking for keys matching \"%s\"..."), p);
507 
508  pfcopy = crypt_get_fingerprint_or_id(p, &phint, &pl, &ps);
509  pgp_add_string_to_hints(phint, &hints);
510  keys = pgp_get_candidates(keyring, &hints);
511  mutt_list_free(&hints);
512 
513  for (k = keys; k; k = kn)
514  {
515  kn = k->next;
516  if (abilities && !(k->flags & abilities))
517  continue;
518 
519  /* This shouldn't happen, but keys without any addresses aren't selectable
520  * in dlg_select_pgp_key(). */
521  if (!k->address)
522  continue;
523 
524  bool match = false;
525 
526  mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s:\n", p, pgp_long_keyid(k));
527 
528  if ((*p == '\0') || (pfcopy && mutt_istr_equal(pfcopy, k->fingerprint)) ||
529  (pl && mutt_istr_equal(pl, pgp_long_keyid(k))) ||
530  (ps && mutt_istr_equal(ps, pgp_short_keyid(k))))
531  {
532  mutt_debug(LL_DEBUG5, " match #1\n");
533  match = true;
534  }
535  else
536  {
537  for (a = k->address; a; a = a->next)
538  {
539  mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s, \"%s\":\n", p,
540  pgp_long_keyid(k), NONULL(a->addr));
541  if (mutt_istr_find(a->addr, p))
542  {
543  mutt_debug(LL_DEBUG5, " match #2\n");
544  match = true;
545  break;
546  }
547  }
548  }
549 
550  if (match)
551  {
552  *last = pgp_principal_key(k);
553  kn = pgp_remove_key(&keys, *last);
554  last = pgp_get_lastp(k);
555  }
556  }
557 
558  pgp_key_free(&keys);
559 
560  if (matches)
561  {
562  k = dlg_select_pgp_key(matches, NULL, p);
563  if (k)
564  pgp_remove_key(&matches, k);
565  pgp_key_free(&matches);
566  }
567  else
568  {
569  k = NULL;
570  }
571 
572  FREE(&pfcopy);
573  FREE(&p);
574  return k;
575 }
const char * crypt_get_fingerprint_or_id(const char *p, const char **pphint, const char **ppl, const char **pps)
Get the fingerprint or long key ID.
Definition: crypt.c:1296
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition: string.c:500
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:475
char * pgp_long_keyid(struct PgpKeyInfo *k)
Get a key's long id.
Definition: pgp.c:157
char * pgp_short_keyid(struct PgpKeyInfo *k)
Get a key's short id.
Definition: pgp.c:169
struct PgpUid * address
Definition: pgplib.h:50
char * fingerprint
Definition: pgplib.h:49
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ id_defaults

struct PgpCache* id_defaults = NULL
static

Definition at line 71 of file pgpkey.c.