NeoMutt  2025-12-11-911-gd8d604
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
gpgme_functions.c File Reference

Gpgme functions. More...

#include "config.h"
#include <gpg-error.h>
#include <gpgme.h>
#include <langinfo.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 "gpgme_functions.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 "module_data.h"
#include "mutt_logging.h"
#include <libintl.h>
+ Include dependency graph for gpgme_functions.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_exit (struct GpgmeData *gd, const struct KeyEvent *event)
 Exit this menu - 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 gpgme_functions.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 83 of file gpgme_functions.c.

84{
85 char *tstr = MUTT_MEM_MALLOC(len + 1, char);
86 memcpy(tstr, buf, len);
87 tstr[len] = 0;
88
89 /* fromcode "utf-8" is sure, so we don't want
90 * charset-hook corrections: flags must be 0. */
92 fputs(tstr, fp);
93 FREE(&tstr);
94}
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 106 of file gpgme_functions.c.

107{
108 bool any = false;
109
110 for (; dn->key; dn++)
111 {
112 if (mutt_str_equal(dn->key, key))
113 {
114 if (any)
115 fputs(" + ", fp);
116 print_utf8(fp, dn->value, strlen(dn->value));
117 any = true;
118 }
119 }
120 return any;
121}
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 128 of file gpgme_functions.c.

129{
130 static const char *const stdpart[] = {
131 "CN", "OU", "O", "STREET", "L", "ST", "C", NULL,
132 };
133 bool any = false;
134 bool any2 = false;
135
136 for (int i = 0; stdpart[i]; i++)
137 {
138 if (any)
139 fputs(", ", fp);
140 any = print_dn_part(fp, dn, stdpart[i]);
141 }
142 /* now print the rest without any specific ordering */
143 for (; dn->key; dn++)
144 {
145 int i;
146 for (i = 0; stdpart[i]; i++)
147 {
148 if (mutt_str_equal(dn->key, stdpart[i]))
149 break;
150 }
151 if (!stdpart[i])
152 {
153 if (any)
154 fputs(", ", fp);
155 if (!any2)
156 fputs("(", fp);
157 any = print_dn_part(fp, dn, dn->key);
158 any2 = true;
159 }
160 }
161 if (any2)
162 fputs(")", fp);
163}
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 173 of file gpgme_functions.c.

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

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

344{
345 const char *s = NULL;
346
347 if (*userid == '<')
348 {
349 s = strchr(userid + 1, '>');
350 if (s)
351 print_utf8(fp, userid + 1, s - userid - 1);
352 }
353 else if (*userid == '(')
354 {
355 fputs(_("[Can't display this user ID (unknown encoding)]"), fp);
356 }
357 else if (!mutt_isalnum(userid[0]))
358 {
359 fputs(_("[Can't display this user ID (invalid encoding)]"), fp);
360 }
361 else
362 {
363 struct DnArray *dn = parse_dn(userid);
364 if (dn)
365 {
366 print_dn_parts(fp, dn);
367 for (int i = 0; dn[i].key; i++)
368 {
369 FREE(&dn[i].key);
370 FREE(&dn[i].value);
371 }
372 FREE(&dn);
373 }
374 else
375 {
376 fputs(_("[Can't display this user ID (invalid DN)]"), fp);
377 }
378 }
379}
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 386 of file gpgme_functions.c.

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

640{
641 const char *s = NULL;
642 gpgme_ctx_t listctx = NULL;
643 gpgme_error_t err = GPG_ERR_NO_ERROR;
644 gpgme_key_t k = NULL;
645 int maxdepth = 100;
646
647 struct Buffer *tempfile = buf_pool_get();
648 buf_mktemp(tempfile);
649 FILE *fp = mutt_file_fopen(buf_string(tempfile), "w");
650 if (!fp)
651 {
652 mutt_perror(_("Can't create temporary file"));
653 goto cleanup;
654 }
655 mutt_message(_("Collecting data..."));
656
657 print_key_info(key->kobj, fp);
658
659 listctx = create_gpgme_context(key->flags & KEYFLAG_ISX509);
660
661 k = key->kobj;
662 gpgme_key_ref(k);
663 while ((s = k->chain_id) && k->subkeys && !mutt_str_equal(s, k->subkeys->fpr))
664 {
665 putc('\n', fp);
666 err = gpgme_op_keylist_start(listctx, s, 0);
667 gpgme_key_unref(k);
668 k = NULL;
669 if (err == GPG_ERR_NO_ERROR)
670 err = gpgme_op_keylist_next(listctx, &k);
671 if (err != GPG_ERR_NO_ERROR)
672 {
673 fprintf(fp, _("Error finding issuer key: %s\n"), gpgme_strerror(err));
674 goto leave;
675 }
676 gpgme_op_keylist_end(listctx);
677
678 print_key_info(k, fp);
679 if (!--maxdepth)
680 {
681 putc('\n', fp);
682 fputs(_("Error: certification chain too long - stopping here\n"), fp);
683 break;
684 }
685 }
686
687leave:
688 gpgme_key_unref(k);
689 gpgme_release(listctx);
690 mutt_file_fclose(&fp);
692 char title[1024] = { 0 };
693 snprintf(title, sizeof(title), _("Key ID: 0x%s"), crypt_keyid(key));
694
695 struct PagerData pdata = { 0 };
696 struct PagerView pview = { &pdata };
697
698 pdata.fname = buf_string(tempfile);
699
700 pview.banner = title;
701 pview.flags = MUTT_PAGER_NONE;
702 pview.mode = PAGER_MODE_OTHER;
703
704 mutt_do_pager(&pview, NULL);
705
706cleanup:
707 buf_pool_release(&tempfile);
708}
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 int create_gpgme_context(gpgme_ctx_t *ctx)
Create a GPGME context.
Definition gpgme.c:51
static void print_key_info(gpgme_key_t key, FILE *fp)
Verbose information about a key or certificate to a file.
#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:49
gpgme_key_t kobj
GPGME key object.
Definition crypt_gpgme.h:46
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 715 of file gpgme_functions.c.

716{
717 if (k->flags & KEYFLAG_CANTUSE)
718 return false;
719 return true;
720}
#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 727 of file gpgme_functions.c.

728{
729 for (struct CryptKeyInfo *k = keys; k != NULL; k = k->next)
730 {
731 if (!crypt_key_is_valid(k))
732 return false;
733 }
734
735 return true;
736}
static bool crypt_key_is_valid(struct CryptKeyInfo *k)
Is the key valid.
A stored PGP key.
Definition crypt_gpgme.h:44
struct CryptKeyInfo * next
Linked list.
Definition crypt_gpgme.h:45
+ 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 57 of file gpgme_functions.c.

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

◆ GpgmeFunctions

const struct GpgmeFunction GpgmeFunctions[]
static
Initial value:
= {
{ OP_EXIT, op_exit },
{ OP_GENERIC_SELECT_ENTRY, op_generic_select_entry },
{ OP_VERIFY_KEY, op_verify_key },
{ OP_VIEW_ID, op_view_id },
{ 0, NULL },
}
static int op_exit(struct AliasFunctionData *fdata, const struct KeyEvent *event)
exit this menu - Implements alias_function_t -
Definition functions.c:312
static int op_generic_select_entry(struct AliasFunctionData *fdata, const struct KeyEvent *event)
select the current entry - Implements alias_function_t -
Definition functions.c:392
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 850 of file gpgme_functions.c.

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