NeoMutt  2022-04-29-249-gaae397
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 "mutt.h"
#include "pgpkey.h"
#include "lib.h"
#include "enter/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:134
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:139
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:819
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 struct PgpCache *l = NULL;
185 struct Buffer *resp = mutt_buffer_pool_get();
186
188
189 if (whatfor)
190 {
191 for (l = id_defaults; l; l = l->next)
192 {
193 if (mutt_istr_equal(whatfor, l->what))
194 {
195 mutt_buffer_strcpy(resp, l->dflt);
196 break;
197 }
198 }
199 }
200
201 while (true)
202 {
203 mutt_buffer_reset(resp);
204 if (mutt_buffer_get_field(tag, resp, MUTT_COMP_NO_FLAGS, false, NULL, NULL, NULL) != 0)
205 {
206 goto done;
207 }
208
209 if (whatfor)
210 {
211 if (l)
213 else
214 {
215 l = mutt_mem_malloc(sizeof(struct PgpCache));
216 l->next = id_defaults;
217 id_defaults = l;
218 l->what = mutt_str_dup(whatfor);
219 l->dflt = mutt_buffer_strdup(resp);
220 }
221 }
222
223 key = pgp_getkeybystr(mutt_buffer_string(resp), abilities, keyring);
224 if (key)
225 goto done;
226
227 mutt_error(_("No matching keys found for \"%s\""), mutt_buffer_string(resp));
228 }
229
230done:
232 return key;
233}
size_t mutt_buffer_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:327
void mutt_buffer_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:85
char * mutt_buffer_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:447
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
int mutt_buffer_get_field(const char *field, struct Buffer *buf, CompletionFlags complete, bool multiple, struct Mailbox *m, char ***files, int *numfiles)
Ask the user for a string.
Definition: window.c:180
#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:250
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:326
#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:74
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:491
void mutt_buffer_pool_release(struct Buffer **pbuf)
Free a Buffer from the pool.
Definition: pool.c:112
struct Buffer * mutt_buffer_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:101
String manipulation buffer.
Definition: buffer.h:34
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 318 of file pgpkey.c.

319{
320 char *scratch = mutt_str_dup(str);
321 if (!scratch)
322 return;
323
324 for (char *t = strtok(scratch, " ,.:\"()<>\n"); t; t = strtok(NULL, " ,.:\"()<>\n"))
325 {
326 if (strlen(t) > 3)
328 }
329
330 FREE(&scratch);
331}
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:43
+ 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 338 of file pgpkey.c.

339{
340 for (; p; p = p->next)
341 if (!p->next)
342 return &p->next;
343
344 return NULL;
345}
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 355 of file pgpkey.c.

357{
358 if (!a)
359 return NULL;
360
361 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
362
363 bool multi = false;
364
365 struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
366 struct PgpKeyInfo *the_strong_valid_key = NULL;
367 struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
368 struct PgpKeyInfo *matches = NULL;
369 struct PgpKeyInfo **last = &matches;
370 struct PgpUid *q = NULL;
371
372 if (a->mailbox)
374 if (a->personal)
376
377 if (!oppenc_mode)
378 mutt_message(_("Looking for keys matching \"%s\"..."), a->mailbox);
379 keys = pgp_get_candidates(keyring, &hints);
380
381 mutt_list_free(&hints);
382
383 if (!keys)
384 return NULL;
385
386 mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", NONULL(a->personal), NONULL(a->mailbox));
387
388 for (k = keys; k; k = kn)
389 {
390 kn = k->next;
391
392 mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
393
394 if (abilities && !(k->flags & abilities))
395 {
396 mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
397 continue;
398 }
399
400 bool match = false; /* any match */
401
402 for (q = k->address; q; q = q->next)
403 {
404 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
406 struct Address *qa = NULL;
407 TAILQ_FOREACH(qa, &al, entries)
408 {
409 PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
410
411 if (validity & PGP_KV_MATCH) /* something matches */
412 match = true;
413
414 if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
415 {
416 if (validity & PGP_KV_STRONGID)
417 {
418 if (the_strong_valid_key && (the_strong_valid_key != k))
419 multi = true;
420 the_strong_valid_key = k;
421 }
422 else
423 {
424 a_valid_addrmatch_key = k;
425 }
426 }
427 }
428
430 }
431
432 if (match)
433 {
434 *last = pgp_principal_key(k);
435 kn = pgp_remove_key(&keys, *last);
436 last = pgp_get_lastp(k);
437 }
438 }
439
440 pgp_key_free(&keys);
441
442 if (matches)
443 {
444 if (oppenc_mode)
445 {
446 const bool c_crypt_opportunistic_encrypt_strong_keys =
447 cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
448 if (the_strong_valid_key)
449 {
450 pgp_remove_key(&matches, the_strong_valid_key);
451 k = the_strong_valid_key;
452 }
453 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
454 {
455 pgp_remove_key(&matches, a_valid_addrmatch_key);
456 k = a_valid_addrmatch_key;
457 }
458 else
459 k = NULL;
460 }
461 else if (the_strong_valid_key && !multi)
462 {
463 /* There was precisely one strong match on a valid ID.
464 * Proceed without asking the user. */
465 pgp_remove_key(&matches, the_strong_valid_key);
466 k = the_strong_valid_key;
467 }
468 else
469 {
470 /* Else: Ask the user. */
471 k = dlg_select_pgp_key(matches, a, NULL);
472 if (k)
473 pgp_remove_key(&matches, k);
474 }
475
476 pgp_key_free(&matches);
477
478 return k;
479 }
480
481 return NULL;
482}
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
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:73
struct PgpKeyInfo * dlg_select_pgp_key(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use.
Definition: dlg_pgp.c:586
struct PgpKeyInfo * pgp_get_candidates(enum PgpRing keyring, struct ListHead *hints)
Find PGP keys matching a list of hints.
Definition: gnupgparse.c:415
#define mutt_message(...)
Definition: logging.h:86
#define mutt_debug(LEVEL,...)
Definition: logging.h:84
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:204
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:318
#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:338
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:199
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition: pgplib.c:167
#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 491 of file pgpkey.c.

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