NeoMutt
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
pgpkey.h File Reference

PGP key management routines. More...

#include <stdbool.h>
#include "lib.h"
+ Include dependency graph for pgpkey.h:
+ This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Enumerations

enum  PgpRing { PGP_PUBRING , PGP_SECRING }
 PGP ring type. More...
 

Functions

struct Bodypgp_class_make_key_attachment (void)
 Implements CryptModuleSpecs::pgp_make_key_attachment() -.
 
struct PgpKeyInfopgp_ask_for_key (char *tag, const char *whatfor, KeyFlags abilities, enum PgpRing keyring)
 Ask the user for a PGP key.
 
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 *p, KeyFlags abilities, enum PgpRing keyring)
 Find a PGP key by string.
 
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_id_is_valid (struct PgpUid *uid)
 Is a PGP key valid.
 
bool pgp_id_is_strong (struct PgpUid *uid)
 Is a PGP key strong?
 

Detailed Description

PGP key management routines.

Authors
  • Richard Russon
  • 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.h.

Enumeration Type Documentation

◆ PgpRing

enum PgpRing

PGP ring type.

Enumerator
PGP_PUBRING 

Public keys.

PGP_SECRING 

Secret keys.

Definition at line 37 of file pgpkey.h.

38{
41};
@ PGP_SECRING
Secret keys.
Definition: pgpkey.h:40
@ PGP_PUBRING
Public keys.
Definition: pgpkey.h:39

Function Documentation

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

182{
183 struct PgpKeyInfo *key = NULL;
184 struct PgpCache *l = NULL;
185 struct Buffer *resp = buf_pool_get();
186
188
189 if (whatfor)
190 {
191 for (l = IdDefaults; l; l = l->next)
192 {
193 if (mutt_istr_equal(whatfor, l->what))
194 {
195 buf_strcpy(resp, l->dflt);
196 break;
197 }
198 }
199 }
200
201 while (true)
202 {
203 buf_reset(resp);
204 if (mw_get_field(tag, resp, MUTT_COMP_NO_FLAGS, HC_OTHER, NULL, NULL) != 0)
205 {
206 goto done;
207 }
208
209 if (whatfor)
210 {
211 if (l)
212 {
213 mutt_str_replace(&l->dflt, buf_string(resp));
214 }
215 else
216 {
217 l = mutt_mem_malloc(sizeof(struct PgpCache));
218 l->next = IdDefaults;
219 IdDefaults = l;
220 l->what = mutt_str_dup(whatfor);
221 l->dflt = buf_strdup(resp);
222 }
223 }
224
225 key = pgp_getkeybystr(buf_string(resp), abilities, keyring);
226 if (key)
227 goto done;
228
229 mutt_error(_("No matching keys found for \"%s\""), buf_string(resp));
230 }
231
232done:
233 buf_pool_release(&resp);
234 return key;
235}
void buf_reset(struct Buffer *buf)
Reset an existing Buffer.
Definition: buffer.c:88
size_t buf_strcpy(struct Buffer *buf, const char *s)
Copy a string into a Buffer.
Definition: buffer.c:407
char * buf_strdup(const struct Buffer *buf)
Copy a Buffer's string.
Definition: buffer.c:542
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:93
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:275
#define mutt_error(...)
Definition: logging2.h:92
@ HC_OTHER
Miscellaneous strings.
Definition: lib.h:54
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define _(a)
Definition: message.h:28
bool mutt_istr_equal(const char *a, const char *b)
Compare two strings, ignoring case.
Definition: string.c:810
char * mutt_str_dup(const char *str)
Copy a string, safely.
Definition: string.c:251
char * mutt_str_replace(char **p, const char *s)
Replace one string with another.
Definition: string.c:327
#define MUTT_COMP_NO_FLAGS
No flags are set.
Definition: mutt.h:55
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:73
static struct PgpCache * IdDefaults
Cache of GPGME keys.
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:496
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition: pool.c:81
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition: pool.c:94
String manipulation buffer.
Definition: buffer.h:34
List of cached PGP keys.
Definition: pgpkey.c:64
char * dflt
Definition: pgpkey.c:66
struct PgpCache * next
Linked list.
Definition: pgpkey.c:67
char * what
Definition: pgpkey.c:65
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_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 357 of file pgpkey.c.

359{
360 if (!a)
361 return NULL;
362
363 struct ListHead hints = STAILQ_HEAD_INITIALIZER(hints);
364
365 bool multi = false;
366
367 struct PgpKeyInfo *keys = NULL, *k = NULL, *kn = NULL;
368 struct PgpKeyInfo *the_strong_valid_key = NULL;
369 struct PgpKeyInfo *a_valid_addrmatch_key = NULL;
370 struct PgpKeyInfo *matches = NULL;
371 struct PgpKeyInfo **last = &matches;
372 struct PgpUid *q = NULL;
373
374 if (a->mailbox)
376 if (a->personal)
378
379 if (!oppenc_mode)
380 mutt_message(_("Looking for keys matching \"%s\"..."), buf_string(a->mailbox));
381 keys = pgp_get_candidates(keyring, &hints);
382
383 mutt_list_free(&hints);
384
385 if (!keys)
386 return NULL;
387
388 mutt_debug(LL_DEBUG5, "looking for %s <%s>\n", buf_string(a->personal),
389 buf_string(a->mailbox));
390
391 for (k = keys; k; k = kn)
392 {
393 kn = k->next;
394
395 mutt_debug(LL_DEBUG5, " looking at key: %s\n", pgp_keyid(k));
396
397 if (abilities && !(k->flags & abilities))
398 {
399 mutt_debug(LL_DEBUG3, " insufficient abilities: Has %x, want %x\n", k->flags, abilities);
400 continue;
401 }
402
403 bool match = false; /* any match */
404
405 for (q = k->address; q; q = q->next)
406 {
407 struct AddressList al = TAILQ_HEAD_INITIALIZER(al);
409 struct Address *qa = NULL;
410 TAILQ_FOREACH(qa, &al, entries)
411 {
412 PgpKeyValidFlags validity = pgp_id_matches_addr(a, qa, q);
413
414 if (validity & PGP_KV_MATCH) /* something matches */
415 match = true;
416
417 if ((validity & PGP_KV_VALID) && (validity & PGP_KV_ADDR))
418 {
419 if (validity & PGP_KV_STRONGID)
420 {
421 if (the_strong_valid_key && (the_strong_valid_key != k))
422 multi = true;
423 the_strong_valid_key = k;
424 }
425 else
426 {
427 a_valid_addrmatch_key = k;
428 }
429 }
430 }
431
433 }
434
435 if (match)
436 {
437 *last = pgp_principal_key(k);
438 kn = pgp_remove_key(&keys, *last);
439 last = pgp_get_lastp(k);
440 }
441 }
442
443 pgp_key_free(&keys);
444
445 if (matches)
446 {
447 if (oppenc_mode)
448 {
449 const bool c_crypt_opportunistic_encrypt_strong_keys =
450 cs_subset_bool(NeoMutt->sub, "crypt_opportunistic_encrypt_strong_keys");
451 if (the_strong_valid_key)
452 {
453 pgp_remove_key(&matches, the_strong_valid_key);
454 k = the_strong_valid_key;
455 }
456 else if (a_valid_addrmatch_key && !c_crypt_opportunistic_encrypt_strong_keys)
457 {
458 pgp_remove_key(&matches, a_valid_addrmatch_key);
459 k = a_valid_addrmatch_key;
460 }
461 else
462 {
463 k = NULL;
464 }
465 }
466 else if (the_strong_valid_key && !multi)
467 {
468 /* There was precisely one strong match on a valid ID.
469 * Proceed without asking the user. */
470 pgp_remove_key(&matches, the_strong_valid_key);
471 k = the_strong_valid_key;
472 }
473 else
474 {
475 /* Else: Ask the user. */
476 k = dlg_pgp(matches, a, NULL);
477 if (k)
478 pgp_remove_key(&matches, k);
479 }
480
481 pgp_key_free(&matches);
482
483 return k;
484 }
485
486 return NULL;
487}
void mutt_addrlist_clear(struct AddressList *al)
Unlink and free all Address in an AddressList.
Definition: address.c:1461
int mutt_addrlist_parse(struct AddressList *al, const char *s)
Parse a list of email addresses.
Definition: address.c:478
bool cs_subset_bool(const struct ConfigSubset *sub, const char *name)
Get a boolean config item by name.
Definition: helpers.c:48
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:540
#define mutt_message(...)
Definition: logging2.h:91
#define mutt_debug(LEVEL,...)
Definition: logging2.h:89
struct ListNode * mutt_list_insert_tail(struct ListHead *h, char *s)
Append a string to the end of a List.
Definition: list.c:64
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: logging2.h:45
@ LL_DEBUG5
Log at debug level 5.
Definition: logging2.h:47
char * pgp_keyid(struct PgpKeyInfo *k)
Get the ID of the main (parent) key.
Definition: pgp.c:205
#define PGP_KV_STRONGID
PGP Key is strong.
Definition: pgpkey.c:79
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:320
#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
#define PGP_KV_VALID
PGP Key ID is valid.
Definition: pgpkey.c:76
#define PGP_KV_ADDR
PGP Key address is valid.
Definition: pgpkey.c:77
static struct PgpKeyInfo ** pgp_get_lastp(struct PgpKeyInfo *p)
Get the last PGP key in a list.
Definition: pgpkey.c:340
uint8_t PgpKeyValidFlags
Flags for valid Pgp Key fields, e.g. PGP_KV_VALID.
Definition: pgpkey.c:74
struct PgpKeyInfo * pgp_principal_key(struct PgpKeyInfo *key)
Get the main (parent) PGP key.
Definition: pgpkey.c:89
void pgp_key_free(struct PgpKeyInfo **kpp)
Free a PGP key info.
Definition: pgplib.c:200
struct PgpKeyInfo * pgp_remove_key(struct PgpKeyInfo **klist, struct PgpKeyInfo *key)
Remove a PGP key from a list.
Definition: pgplib.c:168
#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
struct Buffer * personal
Real name of address.
Definition: address.h:37
struct Buffer * mailbox
Mailbox and host address.
Definition: address.h:38
Container for Accounts, Notifications.
Definition: neomutt.h:41
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:45
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 496 of file pgpkey.c.

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

◆ 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:135
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:140
+ Here is the call graph for this function:
+ 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_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: