NeoMutt  2025-12-11-949-g4870ee
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
functions_gpgme.c File Reference

Gpgme functions. More...

#include "config.h"
#include <gpg-error.h>
#include <gpgme.h>
#include <langinfo.h>
#include <stdbool.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include "mutt/lib.h"
#include "config/lib.h"
#include "core/lib.h"
#include "gui/lib.h"
#include "lib.h"
#include "key/lib.h"
#include "menu/lib.h"
#include "pager/lib.h"
#include "question/lib.h"
#include "crypt_gpgme.h"
#include "globals.h"
#include "gpgme_functions.h"
#include "module_data.h"
#include "mutt_logging.h"
#include <libintl.h>
+ Include dependency graph for functions_gpgme.c:

Go to the source code of this file.

Data Structures

struct  DnArray
 An X500 Distinguished Name. More...
 

Functions

static void print_utf8 (FILE *fp, const char *buf, size_t len)
 Write a UTF-8 string to a file.
 
static bool print_dn_part (FILE *fp, struct DnArray *dn, const char *key)
 Print the X.500 Distinguished Name.
 
static void print_dn_parts (FILE *fp, struct DnArray *dn)
 Print all parts of a DN in a standard sequence.
 
static const char * parse_dn_part (struct DnArray *array, const char *str)
 Parse an RDN.
 
static struct DnArrayparse_dn (const char *str)
 Parse a DN and return an array-ized one.
 
static void parse_and_print_user_id (FILE *fp, const char *userid)
 Print a nice representation of the userid.
 
static void print_key_info (gpgme_key_t key, FILE *fp)
 Verbose information about a key or certificate to a file.
 
static void verify_key (struct CryptKeyInfo *key)
 Show detailed information about the selected key.
 
static bool crypt_key_is_valid (struct CryptKeyInfo *k)
 Is the key valid.
 
bool crypt_keys_are_valid (struct CryptKeyInfo *keys)
 Are all these keys valid?
 
static int op_quit (struct GpgmeData *gd, const struct KeyEvent *event)
 Save changes and exit this dialog - Implements gpgme_function_t -.
 
static int op_generic_select_entry (struct GpgmeData *gd, const struct KeyEvent *event)
 Select the current entry - Implements gpgme_function_t -.
 
static int op_verify_key (struct GpgmeData *gd, const struct KeyEvent *event)
 Verify a PGP public key - Implements gpgme_function_t -.
 
static int op_view_id (struct GpgmeData *gd, const struct KeyEvent *event)
 View the key's user id - Implements gpgme_function_t -.
 
int gpgme_function_dispatcher (struct MuttWindow *win, const struct KeyEvent *event)
 Perform a Gpgme function - Implements function_dispatcher_t -.
 

Variables

static const char *const KeyInfoPrompts []
 Names of header fields used in the pgp key display, e.g. Name:, Fingerprint:
 
static const struct GpgmeFunction GpgmeFunctions []
 All the NeoMutt functions that the Gpgme supports.
 

Detailed Description

Gpgme functions.

Authors
  • Richard Russon
  • Alejandro Colomar
  • Thomas Klausner

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

Function Documentation

◆ print_utf8()

static void print_utf8 ( FILE * fp,
const char * buf,
size_t len )
static

Write a UTF-8 string to a file.

Parameters
fpFile to write to
bufBuffer to read from
lenLength to read

Convert the character set.

Definition at line 84 of file functions_gpgme.c.

85{
86 char *tstr = MUTT_MEM_MALLOC(len + 1, char);
87 memcpy(tstr, buf, len);
88 tstr[len] = 0;
89
90 /* fromcode "utf-8" is sure, so we don't want
91 * charset-hook corrections: flags must be 0. */
93 fputs(tstr, fp);
94 FREE(&tstr);
95}
const char * cc_charset(void)
Get the cached value of $charset.
#define FREE(x)
Free memory and set the pointer to NULL.
Definition memory.h:68
#define MUTT_MEM_MALLOC(n, type)
Definition memory.h:53
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition charset.c:817
#define MUTT_ICONV_NONE
No flags are set.
Definition charset.h:66
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_dn_part()

static bool print_dn_part ( FILE * fp,
struct DnArray * dn,
const char * key )
static

Print the X.500 Distinguished Name.

Parameters
fpFile to write to
dnDistinguished Name
keyKey string
Return values
trueAny DN keys match the given key string
falseOtherwise

Print the X.500 Distinguished Name part KEY from the array of parts DN to FP.

Definition at line 107 of file functions_gpgme.c.

108{
109 bool any = false;
110
111 for (; dn->key; dn++)
112 {
113 if (mutt_str_equal(dn->key, key))
114 {
115 if (any)
116 fputs(" + ", fp);
117 print_utf8(fp, dn->value, strlen(dn->value));
118 any = true;
119 }
120 }
121 return any;
122}
static void print_utf8(FILE *fp, const char *buf, size_t len)
Write a UTF-8 string to a file.
bool mutt_str_equal(const char *a, const char *b)
Compare two strings.
Definition string.c:665
char * key
Key.
char * value
Value.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_dn_parts()

static void print_dn_parts ( FILE * fp,
struct DnArray * dn )
static

Print all parts of a DN in a standard sequence.

Parameters
fpFile to write to
dnArray of Distinguished Names

Definition at line 129 of file functions_gpgme.c.

130{
131 static const char *const stdpart[] = {
132 "CN", "OU", "O", "STREET", "L", "ST", "C", NULL,
133 };
134 bool any = false;
135 bool any2 = false;
136
137 for (int i = 0; stdpart[i]; i++)
138 {
139 if (any)
140 fputs(", ", fp);
141 any = print_dn_part(fp, dn, stdpart[i]);
142 }
143 /* now print the rest without any specific ordering */
144 for (; dn->key; dn++)
145 {
146 int i;
147 for (i = 0; stdpart[i]; i++)
148 {
149 if (mutt_str_equal(dn->key, stdpart[i]))
150 break;
151 }
152 if (!stdpart[i])
153 {
154 if (any)
155 fputs(", ", fp);
156 if (!any2)
157 fputs("(", fp);
158 any = print_dn_part(fp, dn, dn->key);
159 any2 = true;
160 }
161 }
162 if (any2)
163 fputs(")", fp);
164}
static bool print_dn_part(FILE *fp, struct DnArray *dn, const char *key)
Print the X.500 Distinguished Name.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_dn_part()

static const char * parse_dn_part ( struct DnArray * array,
const char * str )
static

Parse an RDN.

Parameters
arrayArray for results
strString to parse
Return values
ptrFirst character after Distinguished Name

This is a helper to parse_dn()

Definition at line 174 of file functions_gpgme.c.

175{
176 const char *s = NULL, *s1 = NULL;
177 int n;
178 char *p = NULL;
179
180 /* parse attribute type */
181 for (s = str + 1; (s[0] != '\0') && (s[0] != '='); s++)
182 ; // do nothing
183
184 if (s[0] == '\0')
185 return NULL; /* error */
186 n = s - str;
187 if (n == 0)
188 return NULL; /* empty key */
189 array->key = MUTT_MEM_MALLOC(n + 1, char);
190 p = array->key;
191 memcpy(p, str, n); /* fixme: trim trailing spaces */
192 p[n] = 0;
193 str = s + 1;
194
195 if (*str == '#')
196 { /* hexstring */
197 str++;
198 for (s = str; mutt_isxdigit(*s); s++)
199 s++;
200 n = s - str;
201 if ((n == 0) || (n & 1))
202 return NULL; /* empty or odd number of digits */
203 n /= 2;
204 p = MUTT_MEM_MALLOC(n + 1, char);
205 array->value = (char *) p;
206 for (s1 = str; n > 0; s1 += 2, n--)
207 sscanf(s1, "%2hhx", (unsigned char *) p++);
208 *p = '\0';
209 }
210 else
211 { /* regular v3 quoted string */
212 for (n = 0, s = str; *s; s++)
213 {
214 if (*s == '\\')
215 { /* pair */
216 s++;
217 if ((*s == ',') || (*s == '=') || (*s == '+') || (*s == '<') || (*s == '>') ||
218 (*s == '#') || (*s == ';') || (*s == '\\') || (*s == '\"') || (*s == ' '))
219 {
220 n++;
221 }
222 else if (mutt_isxdigit(s[0]) && mutt_isxdigit(s[1]))
223 {
224 s++;
225 n++;
226 }
227 else
228 {
229 return NULL; /* invalid escape sequence */
230 }
231 }
232 else if (*s == '\"')
233 {
234 return NULL; /* invalid encoding */
235 }
236 else if ((*s == ',') || (*s == '=') || (*s == '+') || (*s == '<') ||
237 (*s == '>') || (*s == '#') || (*s == ';'))
238 {
239 break;
240 }
241 else
242 {
243 n++;
244 }
245 }
246
247 p = MUTT_MEM_MALLOC(n + 1, char);
248 array->value = (char *) p;
249 for (s = str; n > 0; s++, n--)
250 {
251 if (*s == '\\')
252 {
253 s++;
254 if (mutt_isxdigit(*s))
255 {
256 sscanf(s, "%2hhx", (unsigned char *) p++);
257 s++;
258 }
259 else
260 {
261 *p++ = *s;
262 }
263 }
264 else
265 {
266 *p++ = *s;
267 }
268 }
269 *p = '\0';
270 }
271 return s;
272}
bool mutt_isxdigit(int arg)
Wrapper for isxdigit(3)
Definition ctype.c:111
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_dn()

static struct DnArray * parse_dn ( const char * str)
static

Parse a DN and return an array-ized one.

Parameters
strString to parse
Return values
ptrArray of Distinguished Names

This is not a validating parser and it does not support any old-stylish syntax; GPGME is expected to return only rfc2253 compatible strings.

Definition at line 282 of file functions_gpgme.c.

283{
284 struct DnArray *array = NULL;
285 size_t arrayidx, arraysize;
286
287 arraysize = 7; /* C,ST,L,O,OU,CN,email */
288 array = MUTT_MEM_MALLOC(arraysize + 1, struct DnArray);
289 arrayidx = 0;
290 while (*str)
291 {
292 while (str[0] == ' ')
293 str++;
294 if (str[0] == '\0')
295 break; /* ready */
296 if (arrayidx >= arraysize)
297 {
298 /* neomutt lacks a real mutt_mem_realloc - so we need to copy */
299 arraysize += 5;
300 struct DnArray *a2 = MUTT_MEM_MALLOC(arraysize + 1, struct DnArray);
301 for (int i = 0; i < arrayidx; i++)
302 {
303 a2[i].key = array[i].key;
304 a2[i].value = array[i].value;
305 }
306 FREE(&array);
307 array = a2;
308 }
309 array[arrayidx].key = NULL;
310 array[arrayidx].value = NULL;
311 str = parse_dn_part(array + arrayidx, str);
312 arrayidx++;
313 if (!str)
314 goto failure;
315 while (str[0] == ' ')
316 str++;
317 if ((str[0] != '\0') && (str[0] != ',') && (str[0] != ';') && (str[0] != '+'))
318 goto failure; /* invalid delimiter */
319 if (str[0] != '\0')
320 str++;
321 }
322 array[arrayidx].key = NULL;
323 array[arrayidx].value = NULL;
324 return array;
325
326failure:
327 for (int i = 0; i < arrayidx; i++)
328 {
329 FREE(&array[i].key);
330 FREE(&array[i].value);
331 }
332 FREE(&array);
333 return NULL;
334}
static const char * parse_dn_part(struct DnArray *array, const char *str)
Parse an RDN.
An X500 Distinguished Name.
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ parse_and_print_user_id()

static void parse_and_print_user_id ( FILE * fp,
const char * userid )
static

Print a nice representation of the userid.

Parameters
fpFile to write to
useridString returned by GPGME key functions (utf-8 encoded)

Make sure it is displayed in a proper way, which does mean to reorder some parts for S/MIME's DNs.

Definition at line 344 of file functions_gpgme.c.

345{
346 const char *s = NULL;
347
348 if (*userid == '<')
349 {
350 s = strchr(userid + 1, '>');
351 if (s)
352 print_utf8(fp, userid + 1, s - userid - 1);
353 }
354 else if (*userid == '(')
355 {
356 fputs(_("[Can't display this user ID (unknown encoding)]"), fp);
357 }
358 else if (!mutt_isalnum(userid[0]))
359 {
360 fputs(_("[Can't display this user ID (invalid encoding)]"), fp);
361 }
362 else
363 {
364 struct DnArray *dn = parse_dn(userid);
365 if (dn)
366 {
367 print_dn_parts(fp, dn);
368 for (int i = 0; dn[i].key; i++)
369 {
370 FREE(&dn[i].key);
371 FREE(&dn[i].value);
372 }
373 FREE(&dn);
374 }
375 else
376 {
377 fputs(_("[Can't display this user ID (invalid DN)]"), fp);
378 }
379 }
380}
bool mutt_isalnum(int arg)
Wrapper for isalnum(3)
Definition ctype.c:40
static struct DnArray * parse_dn(const char *str)
Parse a DN and return an array-ized one.
static void print_dn_parts(FILE *fp, struct DnArray *dn)
Print all parts of a DN in a standard sequence.
#define _(a)
Definition message.h:28
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ print_key_info()

static void print_key_info ( gpgme_key_t key,
FILE * fp )
static

Verbose information about a key or certificate to a file.

Parameters
keyKey to use
fpFile to write to

Definition at line 387 of file functions_gpgme.c.

388{
390 int idx;
391 const char *s = NULL, *s2 = NULL;
392 time_t tt = 0;
393 char shortbuf[128] = { 0 };
394 unsigned long aval = 0;
395 const char *delim = NULL;
396 gpgme_user_id_t uid = NULL;
397 static int max_header_width = 0;
398
399 if (max_header_width == 0)
400 {
401 for (int i = 0; i < KIP_MAX; i++)
402 {
403 mod_data->key_info_padding[i] = mutt_str_len(_(KeyInfoPrompts[i]));
404 const int width = mutt_strwidth(_(KeyInfoPrompts[i]));
405 if (max_header_width < width)
406 max_header_width = width;
407 mod_data->key_info_padding[i] -= width;
408 }
409 for (int i = 0; i < KIP_MAX; i++)
410 mod_data->key_info_padding[i] += max_header_width;
411 }
412
413 bool is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP);
414
415 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
416 {
417 if (uid->revoked)
418 continue;
419
420 s = uid->uid;
421 /* L10N: DOTFILL */
422
423 if (idx == 0)
424 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_NAME], _(KeyInfoPrompts[KIP_NAME]));
425 else
426 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_AKA], _(KeyInfoPrompts[KIP_AKA]));
427 if (uid->invalid)
428 {
429 /* L10N: comes after the Name or aka if the key is invalid */
430 fputs(_("[Invalid]"), fp);
431 putc(' ', fp);
432 }
433 if (is_pgp)
434 print_utf8(fp, s, strlen(s));
435 else
437 putc('\n', fp);
438 }
439
440 if (key->subkeys && (key->subkeys->timestamp > 0))
441 {
442 tt = key->subkeys->timestamp;
443
444 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
445 fprintf(fp, "%*s%s\n", mod_data->key_info_padding[KIP_VALID_FROM],
446 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
447 }
448
449 if (key->subkeys && (key->subkeys->expires > 0))
450 {
451 tt = key->subkeys->expires;
452
453 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
454 fprintf(fp, "%*s%s\n", mod_data->key_info_padding[KIP_VALID_TO],
455 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
456 }
457
458 if (key->subkeys)
459 s = gpgme_pubkey_algo_name(key->subkeys->pubkey_algo);
460 else
461 s = "?";
462
463 s2 = is_pgp ? "PGP" : "X.509";
464
465 if (key->subkeys)
466 aval = key->subkeys->length;
467
468 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_KEY_TYPE],
470 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
471 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), s2, aval, s);
472
473 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_KEY_USAGE],
475 delim = "";
476
478 {
479 /* L10N: value in Key Usage: field */
480 fprintf(fp, "%s%s", delim, _("encryption"));
481 delim = _(", ");
482 }
484 {
485 /* L10N: value in Key Usage: field */
486 fprintf(fp, "%s%s", delim, _("signing"));
487 delim = _(", ");
488 }
490 {
491 /* L10N: value in Key Usage: field */
492 fprintf(fp, "%s%s", delim, _("certification"));
493 }
494 putc('\n', fp);
495
496 if (key->subkeys)
497 {
498 s = key->subkeys->fpr;
499 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_FINGERPRINT],
501 if (is_pgp && (strlen(s) == 40))
502 {
503 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0') &&
504 (s[3] != '\0') && (s[4] != '\0');
505 s += 4, i++)
506 {
507 putc(*s, fp);
508 putc(s[1], fp);
509 putc(s[2], fp);
510 putc(s[3], fp);
511 putc(' ', fp);
512 if (i == 4)
513 putc(' ', fp);
514 }
515 }
516 else
517 {
518 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0'); s += 2, i++)
519 {
520 putc(*s, fp);
521 putc(s[1], fp);
522 putc(is_pgp ? ' ' : ':', fp);
523 if (is_pgp && (i == 7))
524 putc(' ', fp);
525 }
526 }
527 fprintf(fp, "%s\n", s);
528 }
529
530 if (key->issuer_serial)
531 {
532 s = key->issuer_serial;
533 fprintf(fp, "%*s0x%s\n", mod_data->key_info_padding[KIP_SERIAL_NO],
535 }
536
537 if (key->issuer_name)
538 {
539 s = key->issuer_name;
540 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_ISSUED_BY],
543 putc('\n', fp);
544 }
545
546 /* For PGP we list all subkeys. */
547 if (is_pgp)
548 {
549 gpgme_subkey_t subkey = NULL;
550
551 for (idx = 1, subkey = key->subkeys; subkey; idx++, subkey = subkey->next)
552 {
553 s = subkey->keyid;
554
555 putc('\n', fp);
556 if (strlen(s) == 16)
557 s += 8; /* display only the short keyID */
558 fprintf(fp, "%*s0x%s", mod_data->key_info_padding[KIP_SUBKEY],
560 if (subkey->revoked)
561 {
562 putc(' ', fp);
563 /* L10N: describes a subkey */
564 fputs(_("[Revoked]"), fp);
565 }
566 if (subkey->invalid)
567 {
568 putc(' ', fp);
569 /* L10N: describes a subkey */
570 fputs(_("[Invalid]"), fp);
571 }
572 if (subkey->expired)
573 {
574 putc(' ', fp);
575 /* L10N: describes a subkey */
576 fputs(_("[Expired]"), fp);
577 }
578 if (subkey->disabled)
579 {
580 putc(' ', fp);
581 /* L10N: describes a subkey */
582 fputs(_("[Disabled]"), fp);
583 }
584 putc('\n', fp);
585
586 if (subkey->timestamp > 0)
587 {
588 tt = subkey->timestamp;
589
590 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
591 fprintf(fp, "%*s%s\n", mod_data->key_info_padding[KIP_VALID_FROM],
592 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
593 }
594
595 if (subkey->expires > 0)
596 {
597 tt = subkey->expires;
598
599 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
600 fprintf(fp, "%*s%s\n", mod_data->key_info_padding[KIP_VALID_TO],
601 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
602 }
603
604 s = gpgme_pubkey_algo_name(subkey->pubkey_algo);
605
606 aval = subkey->length;
607
608 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_KEY_TYPE],
610 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
611 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), "PGP", aval, s);
612
613 fprintf(fp, "%*s", mod_data->key_info_padding[KIP_KEY_USAGE],
615 delim = "";
616
617 if (subkey->can_encrypt)
618 {
619 fprintf(fp, "%s%s", delim, _("encryption"));
620 delim = _(", ");
621 }
622 if (subkey->can_sign)
623 {
624 fprintf(fp, "%s%s", delim, _("signing"));
625 delim = _(", ");
626 }
627 if (subkey->can_certify)
628 {
629 fprintf(fp, "%s%s", delim, _("certification"));
630 }
631 putc('\n', fp);
632 }
633 }
634}
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
@ KIP_FINGERPRINT
PGP Key field: Fingerprint.
Definition crypt_gpgme.h:66
@ KIP_SERIAL_NO
PGP Key field: Serial number.
Definition crypt_gpgme.h:67
@ KIP_SUBKEY
PGP Key field: Subkey.
Definition crypt_gpgme.h:69
@ KIP_AKA
PGP Key field: aka (Also Known As)
Definition crypt_gpgme.h:61
@ KIP_VALID_FROM
PGP Key field: Valid From date.
Definition crypt_gpgme.h:62
@ KIP_MAX
Definition crypt_gpgme.h:70
@ KIP_KEY_TYPE
PGP Key field: Key Type.
Definition crypt_gpgme.h:64
@ KIP_NAME
PGP Key field: Name.
Definition crypt_gpgme.h:60
@ KIP_ISSUED_BY
PGP Key field: Issued By.
Definition crypt_gpgme.h:68
@ KIP_KEY_USAGE
PGP Key field: Key Usage.
Definition crypt_gpgme.h:65
@ KIP_VALID_TO
PGP Key field: Valid To date.
Definition crypt_gpgme.h:63
@ KEY_CAP_CAN_CERTIFY
Key can be used to certify.
Definition crypt_gpgme.h:80
@ KEY_CAP_CAN_ENCRYPT
Key can be used for encryption.
Definition crypt_gpgme.h:78
@ KEY_CAP_CAN_SIGN
Key can be used for signing.
Definition crypt_gpgme.h:79
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition curs_lib.c:445
static const char *const KeyInfoPrompts[]
Names of header fields used in the pgp key display, e.g. Name:, Fingerprint:
static void parse_and_print_user_id(FILE *fp, const char *userid)
Print a nice representation of the userid.
@ MODULE_ID_NCRYPT
ModuleNcrypt, Ncrypt
Definition module_api.h:82
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition date.c:952
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition string.c:503
void * neomutt_get_module_data(struct NeoMutt *n, enum ModuleId id)
Get the private data for a Module.
Definition neomutt.c:666
Ncrypt private Module data.
Definition module_data.h:39
int key_info_padding[KIP_MAX]
Padding for key info prompts.
Definition module_data.h:46
Container for Accounts, Notifications.
Definition neomutt.h:41
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ verify_key()

static void verify_key ( struct CryptKeyInfo * key)
static

Show detailed information about the selected key.

Parameters
keyKey to show

Definition at line 640 of file functions_gpgme.c.

641{
642 const char *s = NULL;
643 gpgme_ctx_t listctx = NULL;
644 gpgme_error_t err = GPG_ERR_NO_ERROR;
645 gpgme_key_t k = NULL;
646 int maxdepth = 100;
647
648 struct Buffer *tempfile = buf_pool_get();
649 buf_mktemp(tempfile);
650 FILE *fp = mutt_file_fopen(buf_string(tempfile), "w");
651 if (!fp)
652 {
653 mutt_perror(_("Can't create temporary file"));
654 goto cleanup;
655 }
656 mutt_message(_("Collecting data..."));
657
658 print_key_info(key->kobj, fp);
659
660 listctx = create_gpgme_context(key->flags & KEYFLAG_ISX509);
661
662 k = key->kobj;
663 gpgme_key_ref(k);
664 while ((s = k->chain_id) && k->subkeys && !mutt_str_equal(s, k->subkeys->fpr))
665 {
666 putc('\n', fp);
667 err = gpgme_op_keylist_start(listctx, s, 0);
668 gpgme_key_unref(k);
669 k = NULL;
670 if (err == GPG_ERR_NO_ERROR)
671 err = gpgme_op_keylist_next(listctx, &k);
672 if (err != GPG_ERR_NO_ERROR)
673 {
674 fprintf(fp, _("Error finding issuer key: %s\n"), gpgme_strerror(err));
675 goto leave;
676 }
677 gpgme_op_keylist_end(listctx);
678
679 print_key_info(k, fp);
680 if (!--maxdepth)
681 {
682 putc('\n', fp);
683 fputs(_("Error: certification chain too long - stopping here\n"), fp);
684 break;
685 }
686 }
687
688leave:
689 gpgme_key_unref(k);
690 gpgme_release(listctx);
691 mutt_file_fclose(&fp);
693 char title[1024] = { 0 };
694 snprintf(title, sizeof(title), _("Key ID: 0x%s"), crypt_keyid(key));
695
696 struct PagerData pdata = { 0 };
697 struct PagerView pview = { &pdata };
698
699 pdata.fname = buf_string(tempfile);
700
701 pview.banner = title;
702 pview.flags = MUTT_PAGER_NONE;
703 pview.mode = PAGER_MODE_OTHER;
704
705 mutt_do_pager(&pview, NULL);
706
707cleanup:
708 buf_pool_release(&tempfile);
709}
static const char * buf_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition buffer.h:96
const char * crypt_keyid(struct CryptKeyInfo *k)
Find the ID for the key.
int mutt_do_pager(struct PagerView *pview, struct Email *e)
Display some page-able text to the user (help or attachment)
Definition do_pager.c:122
#define mutt_file_fclose(FP)
Definition file.h:144
#define mutt_file_fopen(PATH, MODE)
Definition file.h:143
static void print_key_info(gpgme_key_t key, FILE *fp)
Verbose information about a key or certificate to a file.
static int create_gpgme_context(gpgme_ctx_t *ctx)
Create a GPGME context.
Definition gpgme.c:51
#define mutt_message(...)
Definition logging2.h:93
#define mutt_perror(...)
Definition logging2.h:95
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
@ KEYFLAG_ISX509
Key is an X.509 key.
Definition lib.h:149
#define MUTT_PAGER_NONE
No flags are set.
Definition lib.h:63
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition lib.h:143
struct Buffer * buf_pool_get(void)
Get a Buffer from the pool.
Definition pool.c:91
void buf_pool_release(struct Buffer **ptr)
Return a Buffer to the pool.
Definition pool.c:111
String manipulation buffer.
Definition buffer.h:36
KeyFlags flags
global and per uid flags (for convenience)
Definition crypt_gpgme.h:50
gpgme_key_t kobj
GPGME key object.
Definition crypt_gpgme.h:47
Data to be displayed by PagerView.
Definition lib.h:162
const char * fname
Name of the file to read.
Definition lib.h:166
Paged view into some data.
Definition lib.h:173
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition lib.h:174
enum PagerMode mode
Pager mode.
Definition lib.h:175
PagerFlags flags
Additional settings to tweak pager's function.
Definition lib.h:176
const char * banner
Title to display in status bar.
Definition lib.h:177
#define buf_mktemp(buf)
Definition tmp.h:33
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ crypt_key_is_valid()

static bool crypt_key_is_valid ( struct CryptKeyInfo * k)
static

Is the key valid.

Parameters
kKey to test
Return values
trueKey is valid

Definition at line 716 of file functions_gpgme.c.

717{
718 if (k->flags & KEYFLAG_CANTUSE)
719 return false;
720 return true;
721}
#define KEYFLAG_CANTUSE
Definition lib.h:161
+ Here is the caller graph for this function:

◆ crypt_keys_are_valid()

bool crypt_keys_are_valid ( struct CryptKeyInfo * keys)

Are all these keys valid?

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

Definition at line 728 of file functions_gpgme.c.

729{
730 for (struct CryptKeyInfo *k = keys; k != NULL; k = k->next)
731 {
732 if (!crypt_key_is_valid(k))
733 return false;
734 }
735
736 return true;
737}
static bool crypt_key_is_valid(struct CryptKeyInfo *k)
Is the key valid.
A stored PGP key.
Definition crypt_gpgme.h:45
struct CryptKeyInfo * next
Linked list.
Definition crypt_gpgme.h:46
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Variable Documentation

◆ KeyInfoPrompts

const char* const KeyInfoPrompts[]
static
Initial value:
= {
N_("Name: "), N_("aka: "), N_("Valid From: "), N_("Valid To: "),
N_("Key Type: "), N_("Key Usage: "), N_("Fingerprint: "), N_("Serial-No: "),
N_("Issued By: "), N_("Subkey: ")
}
#define N_(a)
Definition message.h:32

Names of header fields used in the pgp key display, e.g. Name:, Fingerprint:

Definition at line 58 of file functions_gpgme.c.

58 {
59 /* L10N: The following are the headers for the "verify key" output from the
60 GPGME key selection menu (bound to "c" in the key selection menu).
61 They will be automatically aligned. */
62 N_("Name: "), N_("aka: "), N_("Valid From: "), N_("Valid To: "),
63 N_("Key Type: "), N_("Key Usage: "), N_("Fingerprint: "), N_("Serial-No: "),
64 N_("Issued By: "), N_("Subkey: ")
65};

◆ GpgmeFunctions

const struct GpgmeFunction GpgmeFunctions[]
static
Initial value:
= {
{ OP_EXIT, op_quit },
{ OP_GENERIC_SELECT_ENTRY, op_generic_select_entry },
{ OP_QUIT, op_quit },
{ OP_VERIFY_KEY, op_verify_key },
{ OP_VIEW_ID, op_view_id },
{ 0, NULL },
}
static int op_quit(struct AliasFunctionData *fdata, const struct KeyEvent *event)
Save changes and exit this dialog - Implements alias_function_t -.
Definition functions.c:308
static int op_generic_select_entry(struct AliasFunctionData *fdata, const struct KeyEvent *event)
select the current entry - Implements alias_function_t -
Definition functions.c:388
static int op_verify_key(struct GpgmeData *gd, const struct KeyEvent *event)
Verify a PGP public key - Implements gpgme_function_t -.
static int op_view_id(struct GpgmeData *gd, const struct KeyEvent *event)
View the key's user id - Implements gpgme_function_t -.

All the NeoMutt functions that the Gpgme supports.

Definition at line 851 of file functions_gpgme.c.

851 {
852 // clang-format off
853 { OP_EXIT, op_quit },
854 { OP_GENERIC_SELECT_ENTRY, op_generic_select_entry },
855 { OP_QUIT, op_quit },
856 { OP_VERIFY_KEY, op_verify_key },
857 { OP_VIEW_ID, op_view_id },
858 { 0, NULL },
859 // clang-format on
860};