NeoMutt  2025-09-05-43-g177ed6
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
pgpkey.c File Reference

PGP key management routines. More...

#include "config.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.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 "editor/lib.h"
#include "history/lib.h"
#include "send/lib.h"
#include "crypt.h"
#include "globals.h"
#include "gnupgparse.h"
#include "mutt_logging.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.
 
#define PGP_KV_VALID   (1 << 0)
 PGP Key ID is valid.
 
#define PGP_KV_ADDR   (1 << 1)
 PGP Key address is valid.
 
#define PGP_KV_STRING   (1 << 2)
 PGP Key name string is valid.
 
#define PGP_KV_STRONGID   (1 << 3)
 PGP Key is strong.
 
#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.
 

Functions

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

Variables

static struct PgpCacheIdDefaults = NULL
 Cache of GPGME keys.
 

Detailed Description

PGP key management routines.

Authors
  • Thomas Roessler
  • Pietro Cerutti
  • Richard Russon
  • Anna Figueiredo Gomes
  • Alejandro Colomar

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 78 of file pgpkey.c.

◆ PGP_KV_VALID

#define PGP_KV_VALID   (1 << 0)

PGP Key ID is valid.

Definition at line 79 of file pgpkey.c.

◆ PGP_KV_ADDR

#define PGP_KV_ADDR   (1 << 1)

PGP Key address is valid.

Definition at line 80 of file pgpkey.c.

◆ PGP_KV_STRING

#define PGP_KV_STRING   (1 << 2)

PGP Key name string is valid.

Definition at line 81 of file pgpkey.c.

◆ PGP_KV_STRONGID

#define PGP_KV_STRONGID   (1 << 3)

PGP Key is strong.

Definition at line 82 of file pgpkey.c.

◆ PGP_KV_MATCH

#define PGP_KV_MATCH   (PGP_KV_ADDR | PGP_KV_STRING)

Definition at line 85 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 77 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 92 of file pgpkey.c.

93{
94 if (key->flags & KEYFLAG_SUBKEY && key->parent)
95 return key->parent;
96 return key;
97}
#define KEYFLAG_SUBKEY
Key is a subkey.
Definition lib.h:140
KeyFlags flags
Definition pgplib.h:53
struct PgpKeyInfo * parent
Definition pgplib.h:58
+ 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 104 of file pgpkey.c.

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

◆ pgp_keys_are_valid()

bool pgp_keys_are_valid ( struct PgpKeyInfo * keys)

Are all these PGP keys valid?

Parameters
keysSet of keys to examine
Return values
trueAll keys are valid

Definition at line 120 of file pgpkey.c.

121{
122 for (struct PgpKeyInfo *k = keys; k != NULL; k = k->next)
123 {
124 if (!pgp_key_is_valid(k))
125 return false;
126 }
127
128 return true;
129}
bool pgp_key_is_valid(struct PgpKeyInfo *k)
Is a PGP key valid?
Definition pgpkey.c:104
struct PgpKeyInfo * next
Definition pgplib.h:59
+ 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 136 of file pgpkey.c.

137{
138 if ((uid->trust & 3) < 3)
139 return false;
140 /* else */
141 return true;
142}
short trust
Definition pgplib.h:38
+ 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 149 of file pgpkey.c.

150{
151 if (!pgp_key_is_valid(uid->parent))
152 return false;
153 if (uid->flags & KEYFLAG_CANTUSE)
154 return false;
155 /* else */
156 return true;
157}
struct PgpKeyInfo * parent
Parent key.
Definition pgplib.h:40
int flags
Definition pgplib.h:39
+ 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 166 of file pgpkey.c.

168{
170
171 if (pgp_id_is_valid(uid))
172 flags |= PGP_KV_VALID;
173
174 if (pgp_id_is_strong(uid))
175 flags |= PGP_KV_STRONGID;
176
177 if (addr->mailbox && u_addr->mailbox && buf_istr_equal(addr->mailbox, u_addr->mailbox))
178 {
179 flags |= PGP_KV_ADDR;
180 }
181
182 if (addr->personal && u_addr->personal &&
183 buf_istr_equal(addr->personal, u_addr->personal))
184 {
185 flags |= PGP_KV_STRING;
186 }
187
188 return flags;
189}
bool buf_istr_equal(const struct Buffer *a, const struct Buffer *b)
Return if two buffers are equal, case insensitive.
Definition buffer.c:695
bool pgp_id_is_valid(struct PgpUid *uid)
Is a PGP key valid.
Definition pgpkey.c:149
#define PGP_KV_NO_FLAGS
No flags are set.
Definition pgpkey.c:78
#define PGP_KV_STRONGID
PGP Key is strong.
Definition pgpkey.c:82
#define PGP_KV_VALID
PGP Key ID is valid.
Definition pgpkey.c:79
#define PGP_KV_STRING
PGP Key name string is valid.
Definition pgpkey.c:81
#define PGP_KV_ADDR
PGP Key address is valid.
Definition pgpkey.c:80
bool pgp_id_is_strong(struct PgpUid *uid)
Is a PGP key strong?
Definition pgpkey.c:136
uint8_t PgpKeyValidFlags
Flags for valid Pgp Key fields, e.g. PGP_KV_VALID.
Definition pgpkey.c:77
struct Buffer * personal
Real name of address.
Definition address.h:37
struct Buffer * mailbox
Mailbox and host address.
Definition address.h:38
+ 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,
const 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 199 of file pgpkey.c.

201{
202 struct PgpKeyInfo *key = NULL;
203 struct PgpCache *l = NULL;
204 struct Buffer *resp = buf_pool_get();
205
207
208 if (whatfor)
209 {
210 for (l = IdDefaults; l; l = l->next)
211 {
212 if (mutt_istr_equal(whatfor, l->what))
213 {
214 buf_strcpy(resp, l->dflt);
215 break;
216 }
217 }
218 }
219
220 while (true)
221 {
222 buf_reset(resp);
223 if (mw_get_field(tag, resp, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0)
224 {
225 goto done;
226 }
227
228 if (whatfor)
229 {
230 if (l)
231 {
232 mutt_str_replace(&l->dflt, buf_string(resp));
233 }
234 else
235 {
236 l = MUTT_MEM_MALLOC(1, struct PgpCache);
237 l->next = IdDefaults;
238 IdDefaults = l;
239 l->what = mutt_str_dup(whatfor);
240 l->dflt = buf_strdup(resp);
241 }
242 }
243
244 key = pgp_getkeybystr(buf_string(resp), abilities, keyring);
245 if (key)
246 goto done;
247
248 mutt_error(_("No matching keys found for \"%s\""), buf_string(resp));
249 }
250
251done:
252 buf_pool_release(&resp);
253 return key;
254}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition buffer.c:76
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition buffer.c:395
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition buffer.c:571
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
static struct CryptCache * IdDefaults
Cache of GPGME keys.
Definition crypt_gpgme.c:92
int mw_get_field(const char *prompt, struct Buffer *buf, CompletionFlags complete, enum HistoryClass hclass, const struct CompleteOps *comp_api, void *cdata)
Ask the user for a string -.
Definition window.c:273
#define mutt_error(...)
Definition logging2.h:93
@ HC_OTHER
Miscellaneous strings.
Definition lib.h:59
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:48
#define _(a)
Definition message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition string.c:672
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition string.c:255
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition string.c:282
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition mutt.h:56
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
struct PgpKeyInfo * pgp_getkeybystr(const char *cp, KeyFlags abilities, enum PgpRing keyring)
Find a PGP key by string.
Definition pgpkey.c:514
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:82
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:96
String manipulation buffer.
Definition buffer.h:36
List of cached PGP keys.
Definition pgpkey.c:67
char * dflt
Definition pgpkey.c:69
struct PgpCache * next
Linked list.
Definition pgpkey.c:70
char * what
Definition pgpkey.c:68
+ 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 338 of file pgpkey.c.

339{
340 char *scratch = mutt_str_dup(str);
341 if (!scratch)
342 return;
343
344 for (char *t = strtok(scratch, " ,.:\"()<>\n"); t; t = strtok(NULL, " ,.:\"()<>\n"))
345 {
346 if (strlen(t) > 3)
348 }
349
350 FREE(&scratch);
351}
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition list.c:65
#define FREE(x)
Definition memory.h:62
+ 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 358 of file pgpkey.c.

359{
360 for (; p; p = p->next)
361 if (!p->next)
362 return &p->next;
363
364 return NULL;
365}
+ 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 375 of file pgpkey.c.

377{
378 if (!a)
379 return NULL;
380
381 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
382
383 bool multi = false;
384
385 struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
386 struct PgpKeyInfo *the_strong_valid_key = NULL;
387 struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
388 struct PgpKeyInfo *matches = NULL;
389 struct PgpKeyInfo **last = &matches;
390 struct PgpUid *q = NULL;
391
392 if (a->mailbox)
394 if (a->personal)
396
397 if (!oppenc_mode)
398 mutt_message(_("Looking for keys matching \"%s\"..."), buf_string(a->mailbox));
399 keys = pgp_get_candidates(keyring, &hints);
400
401 mutt_list_free(&hints);
402
403 if (!keys)
404 return NULL;
405
406 mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", buf_string(a->personal),
407 buf_string(a->mailbox));
408
409 for (k = keys; k; k = kn)
410 {
411 kn = k->next;
412
413 mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
414
415 if (abilities && !(k->flags & abilities))
416 {
417 mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
418 continue;
419 }
420
421 bool match = false; /* any match */
422
423 for (q = k->address; q; q = q->next)
424 {
425 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
427 struct Address *qa = NULL;
428 TAILQ_FOREACH(qa, &al, entries)
429 {
430 PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
431
432 if (validity & PGP_KV_MATCH) /* something matches */
433 match = true;
434
435 if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
436 {
437 if (validity & PGP_KV_STRONGID)
438 {
439 if (the_strong_valid_key && (the_strong_valid_key != k))
440 multi = true;
441 the_strong_valid_key = k;
442 }
443 else
444 {
445 a_valid_addrmatch_key = k;
446 }
447 }
448 }
449
451 }
452
453 if (match)
454 {
455 *last = pgp_principal_key(k);
456 kn = pgp_remove_key(&keys, *last);
457 last = pgp_get_lastp(k);
458 }
459 }
460
461 pgp_key_free(&keys);
462
463 if (matches)
464 {
465 if (oppenc_mode || !isatty(STDIN_FILENO))
466 {
467 const bool c_crypt_opportunistic_encrypt_strong_keys =
468 cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
469 if (the_strong_valid_key)
470 {
471 pgp_remove_key(&matches, the_strong_valid_key);
472 k = the_strong_valid_key;
473 }
474 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
475 {
476 pgp_remove_key(&matches, a_valid_addrmatch_key);
477 k = a_valid_addrmatch_key;
478 }
479 else
480 {
481 k = NULL;
482 }
483 }
484 else if (the_strong_valid_key && !multi)
485 {
486 /* There was precisely one strong match on a valid ID.
487 * Proceed without asking the user. */
488 pgp_remove_key(&matches, the_strong_valid_key);
489 k = the_strong_valid_key;
490 }
491 else
492 {
493 /* Else: Ask the user. */
494 k = dlg_pgp(matches, a, NULL);
495 if (k)
496 pgp_remove_key(&matches, k);
497 }
498
499 pgp_key_free(&matches);
500
501 return k;
502 }
503
504 return NULL;
505}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition address.c:1460
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition address.c:480
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition helpers.c:47
struct PgpKeyInfo * pgp_get_candidates(enum PgpRing keyring, struct ListHead *hints)
Find PGP keys matching a list of hints.
Definition gnupgparse.c:417
struct PgpKeyInfo * dlg_pgp(struct PgpKeyInfo *keys, struct Address *p, const char *s)
Let the user select a key to use -.
Definition dlg_pgp.c:192
#define mutt_message(...)
Definition logging2.h:92
#define mutt_debug(LEVEL,...)
Definition logging2.h:90
void mutt_list_free(struct ListHead *h)
Free a List AND its strings.
Definition list.c:123
@ LL_DEBUG3
Log at debug level 3.
Definition logging2.h:46
@ LL_DEBUG5
Log at debug level 5.
Definition logging2.h:48
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:338
#define PGP_KV_MATCH
Definition pgpkey.c:85
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:166
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition pgpkey.c:358
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition pgplib.c:201
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition pgplib.c:169
#define TAILQ_FOREACH(var, head, field)
Definition queue.h:782
#define STAILQ_HEAD_INITIALIZER(head)
Definition queue.h:324
#define TAILQ_HEAD_INITIALIZER(head)
Definition queue.h:694
#define NONULL(x)
Definition string2.h:43
An email address.
Definition address.h:36
Container for Accounts, Notifications.
Definition neomutt.h:43
struct ConfigSubset * sub
Inherited config items.
Definition neomutt.h:47
PGP User ID.
Definition pgplib.h:36
char * addr
Definition pgplib.h:37
struct PgpUid * next
Linked list.
Definition pgplib.h:41
+ 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 514 of file pgpkey.c.

515{
516 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
517 struct PgpKeyInfo *keys = NULL;
518 struct PgpKeyInfo *matches = NULL;
519 struct PgpKeyInfo **last = &matches;
520 struct PgpKeyInfo *k = NULL, *kn = NULL;
521 struct PgpUid *a = NULL;
522 size_t l;
523 const char *ps = NULL, *pl = NULL, *pfcopy = NULL, *phint = NULL;
524
525 char *p = strdup(cp); // mutt_str_dup converts "" into NULL, see #1809
526 l = mutt_str_len(p);
527 if ((l > 0) && (p[l - 1] == '!'))
528 p[l - 1] = 0;
529
530 mutt_message(_("Looking for keys matching \"%s\"..."), p);
531
532 pfcopy = crypt_get_fingerprint_or_id(p, &phint, &pl, &ps);
533 pgp_add_string_to_hints(phint, &hints);
534 keys = pgp_get_candidates(keyring, &hints);
535 mutt_list_free(&hints);
536
537 for (k = keys; k; k = kn)
538 {
539 kn = k->next;
540 if (abilities && !(k->flags & abilities))
541 continue;
542
543 /* This shouldn't happen, but keys without any addresses aren't selectable
544 * in dlg_pgp(). */
545 if (!k->address)
546 continue;
547
548 bool match = false;
549
550 mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s:\n", p, pgp_long_keyid(k));
551
552 if ((*p == '\0') || (pfcopy && mutt_istr_equal(pfcopy, k->fingerprint)) ||
553 (pl && mutt_istr_equal(pl, pgp_long_keyid(k))) ||
554 (ps && mutt_istr_equal(ps, pgp_short_keyid(k))))
555 {
556 mutt_debug(LL_DEBUG5, " match #1\n");
557 match = true;
558 }
559 else
560 {
561 for (a = k->address; a; a = a->next)
562 {
563 mutt_debug(LL_DEBUG5, "matching \"%s\" against key %s, \"%s\":\n", p,
564 pgp_long_keyid(k), NONULL(a->addr));
565 if (mutt_istr_find(a->addr, p))
566 {
567 mutt_debug(LL_DEBUG5, " match #2\n");
568 match = true;
569 break;
570 }
571 }
572 }
573
574 if (match)
575 {
576 *last = pgp_principal_key(k);
577 kn = pgp_remove_key(&keys, *last);
578 last = pgp_get_lastp(k);
579 }
580 }
581
582 pgp_key_free(&keys);
583
584 k = NULL;
585 if (matches)
586 {
587 if (isatty(STDIN_FILENO))
588 {
589 k = dlg_pgp(matches, NULL, p);
590 if (k)
591 pgp_remove_key(&matches, k);
592 pgp_key_free(&matches);
593 }
594 else if (pgp_keys_are_valid(matches))
595 {
596 k = matches;
597 }
598 else
599 {
600 mutt_error(_("A key can't be used: expired/disabled/revoked"));
601 }
602 }
603
604 FREE(&pfcopy);
605 FREE(&p);
606 return k;
607}
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:1384
const char * mutt_istr_find(const char *haystack, const char *needle)
Find first occurrence of string (ignoring case)
Definition string.c:523
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:498
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
bool pgp_keys_are_valid(struct PgpKeyInfo *keys)
Are all these PGP keys valid?
Definition pgpkey.c:120
struct PgpUid * address
Definition pgplib.h:52
char * fingerprint
Definition pgplib.h:51
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ IdDefaults

struct PgpCache* IdDefaults = NULL
static

Cache of GPGME keys.

Definition at line 74 of file pgpkey.c.