NeoMutt  2022-04-29-247-gc6aae8
Teaching an old dog new tricks
DOXYGEN
gpgme_functions.c File Reference

Gpgme functions. More...

#include "config.h"
#include <ctype.h>
#include <gpgme.h>
#include <langinfo.h>
#include <limits.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 "menu/lib.h"
#include "pager/lib.h"
#include "question/lib.h"
#include "crypt_gpgme.h"
#include "mutt_logging.h"
#include "muttlib.h"
#include "opcodes.h"
#include "options.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. More...
 
static bool print_dn_part (FILE *fp, struct DnArray *dn, const char *key)
 Print the X.500 Distinguished Name. More...
 
static void print_dn_parts (FILE *fp, struct DnArray *dn)
 Print all parts of a DN in a standard sequence. More...
 
static const char * parse_dn_part (struct DnArray *array, const char *str)
 Parse an RDN. More...
 
static struct DnArrayparse_dn (const char *str)
 Parse a DN and return an array-ized one. More...
 
static void parse_and_print_user_id (FILE *fp, const char *userid)
 Print a nice representation of the userid. More...
 
static void print_key_info (gpgme_key_t key, FILE *fp)
 Verbose information about a key or certificate to a file. More...
 
static void verify_key (struct CryptKeyInfo *key)
 Show detailed information about the selected key. More...
 
static bool crypt_key_is_valid (struct CryptKeyInfo *k)
 Is the key valid. More...
 
static int op_exit (struct GpgmeData *gd, int op)
 Exit this menu - Implements gpgme_function_t -. More...
 
static int op_generic_select_entry (struct GpgmeData *gd, int op)
 Select the current entry - Implements gpgme_function_t -. More...
 
static int op_verify_key (struct GpgmeData *gd, int op)
 Verify a PGP public key - Implements gpgme_function_t -. More...
 
static int op_view_id (struct GpgmeData *gd, int op)
 View the key's user id - Implements gpgme_function_t -. More...
 
int gpgme_function_dispatcher (struct MuttWindow *win, int op)
 Perform a Gpgme function - Implements function_dispatcher_t -. More...
 

Variables

int KeyInfoPadding [KIP_MAX] = { 0 }
 
static const char *const KeyInfoPrompts []
 
struct GpgmeFunction GpgmeFunctions []
 All the NeoMutt functions that the Gpgme supports. More...
 

Detailed Description

Gpgme functions.

Authors
  • Richard Russon

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);
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. */
91 const char *const c_charset = cs_subset_string(NeoMutt->sub, "charset");
92 mutt_ch_convert_string(&tstr, "utf-8", c_charset, MUTT_ICONV_NO_FLAGS);
93 fputs(tstr, fp);
94 FREE(&tstr);
95}
const char * cs_subset_string(const struct ConfigSubset *sub, const char *name)
Get a string config item by name.
Definition: helpers.c:317
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:90
#define FREE(x)
Definition: memory.h:43
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:752
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:71
Container for Accounts, Notifications.
Definition: neomutt.h:37
struct ConfigSubset * sub
Inherited config items.
Definition: neomutt.h:39
+ 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 gpgme_functions.c.

108{
109 bool any = false;
110
111 for (; dn->key; dn++)
112 {
113 if (strcmp(dn->key, key) == 0)
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.
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 gpgme_functions.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 (strcmp(dn->key, stdpart[i]) == 0)
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 gpgme_functions.c.

175{
176 const char *s = NULL, *s1 = NULL;
177 size_t 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);
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; 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);
205 array->value = (char *) p;
206 for (s1 = str; n; 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 (isxdigit(s[0]) && isxdigit(s[1]))
223 {
224 s++;
225 n++;
226 }
227 else
228 return NULL; /* invalid escape sequence */
229 }
230 else if (*s == '\"')
231 return NULL; /* invalid encoding */
232 else if ((*s == ',') || (*s == '=') || (*s == '+') || (*s == '<') ||
233 (*s == '>') || (*s == '#') || (*s == ';'))
234 {
235 break;
236 }
237 else
238 n++;
239 }
240
241 p = mutt_mem_malloc(n + 1);
242 array->value = (char *) p;
243 for (s = str; n; s++, n--)
244 {
245 if (*s == '\\')
246 {
247 s++;
248 if (isxdigit(*s))
249 {
250 sscanf(s, "%2hhx", (unsigned char *) p++);
251 s++;
252 }
253 else
254 *p++ = *s;
255 }
256 else
257 *p++ = *s;
258 }
259 *p = '\0';
260 }
261 return s;
262}
+ 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 272 of file gpgme_functions.c.

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

335{
336 const char *s = NULL;
337
338 if (*userid == '<')
339 {
340 s = strchr(userid + 1, '>');
341 if (s)
342 print_utf8(fp, userid + 1, s - userid - 1);
343 }
344 else if (*userid == '(')
345 fputs(_("[Can't display this user ID (unknown encoding)]"), fp);
346 else if (!isalnum(userid[0]))
347 fputs(_("[Can't display this user ID (invalid encoding)]"), fp);
348 else
349 {
350 struct DnArray *dn = parse_dn(userid);
351 if (!dn)
352 fputs(_("[Can't display this user ID (invalid DN)]"), fp);
353 else
354 {
355 print_dn_parts(fp, dn);
356 for (int i = 0; dn[i].key; i++)
357 {
358 FREE(&dn[i].key);
359 FREE(&dn[i].value);
360 }
361 FREE(&dn);
362 }
363 }
364}
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 371 of file gpgme_functions.c.

372{
373 int idx;
374 const char *s = NULL, *s2 = NULL;
375 time_t tt = 0;
376 char shortbuf[128] = { 0 };
377 unsigned long aval = 0;
378 const char *delim = NULL;
379 gpgme_user_id_t uid = NULL;
380 static int max_header_width = 0;
381
382 if (max_header_width == 0)
383 {
384 for (int i = 0; i < KIP_MAX; i++)
385 {
387 const int width = mutt_strwidth(_(KeyInfoPrompts[i]));
388 if (max_header_width < width)
389 max_header_width = width;
390 KeyInfoPadding[i] -= width;
391 }
392 for (int i = 0; i < KIP_MAX; i++)
393 KeyInfoPadding[i] += max_header_width;
394 }
395
396 bool is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP);
397
398 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
399 {
400 if (uid->revoked)
401 continue;
402
403 s = uid->uid;
404 /* L10N: DOTFILL */
405
406 if (idx == 0)
407 fprintf(fp, "%*s", KeyInfoPadding[KIP_NAME], _(KeyInfoPrompts[KIP_NAME]));
408 else
409 fprintf(fp, "%*s", KeyInfoPadding[KIP_AKA], _(KeyInfoPrompts[KIP_AKA]));
410 if (uid->invalid)
411 {
412 /* L10N: comes after the Name or aka if the key is invalid */
413 fputs(_("[Invalid]"), fp);
414 putc(' ', fp);
415 }
416 if (is_pgp)
417 print_utf8(fp, s, strlen(s));
418 else
420 putc('\n', fp);
421 }
422
423 if (key->subkeys && (key->subkeys->timestamp > 0))
424 {
425 tt = key->subkeys->timestamp;
426
427 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
428 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_FROM],
429 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
430 }
431
432 if (key->subkeys && (key->subkeys->expires > 0))
433 {
434 tt = key->subkeys->expires;
435
436 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
437 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_TO],
438 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
439 }
440
441 if (key->subkeys)
442 s = gpgme_pubkey_algo_name(key->subkeys->pubkey_algo);
443 else
444 s = "?";
445
446 s2 = is_pgp ? "PGP" : "X.509";
447
448 if (key->subkeys)
449 aval = key->subkeys->length;
450
452 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
453 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), s2, aval, s);
454
456 delim = "";
457
459 {
460 /* L10N: value in Key Usage: field */
461 fprintf(fp, "%s%s", delim, _("encryption"));
462 delim = _(", ");
463 }
465 {
466 /* L10N: value in Key Usage: field */
467 fprintf(fp, "%s%s", delim, _("signing"));
468 delim = _(", ");
469 }
471 {
472 /* L10N: value in Key Usage: field */
473 fprintf(fp, "%s%s", delim, _("certification"));
474 }
475 putc('\n', fp);
476
477 if (key->subkeys)
478 {
479 s = key->subkeys->fpr;
481 if (is_pgp && (strlen(s) == 40))
482 {
483 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0') &&
484 (s[3] != '\0') && (s[4] != '\0');
485 s += 4, i++)
486 {
487 putc(*s, fp);
488 putc(s[1], fp);
489 putc(s[2], fp);
490 putc(s[3], fp);
491 putc(' ', fp);
492 if (i == 4)
493 putc(' ', fp);
494 }
495 }
496 else
497 {
498 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0'); s += 2, i++)
499 {
500 putc(*s, fp);
501 putc(s[1], fp);
502 putc(is_pgp ? ' ' : ':', fp);
503 if (is_pgp && (i == 7))
504 putc(' ', fp);
505 }
506 }
507 fprintf(fp, "%s\n", s);
508 }
509
510 if (key->issuer_serial)
511 {
512 s = key->issuer_serial;
513 fprintf(fp, "%*s0x%s\n", KeyInfoPadding[KIP_SERIAL_NO],
515 }
516
517 if (key->issuer_name)
518 {
519 s = key->issuer_name;
522 putc('\n', fp);
523 }
524
525 /* For PGP we list all subkeys. */
526 if (is_pgp)
527 {
528 gpgme_subkey_t subkey = NULL;
529
530 for (idx = 1, subkey = key->subkeys; subkey; idx++, subkey = subkey->next)
531 {
532 s = subkey->keyid;
533
534 putc('\n', fp);
535 if (strlen(s) == 16)
536 s += 8; /* display only the short keyID */
537 fprintf(fp, "%*s0x%s", KeyInfoPadding[KIP_SUBKEY], _(KeyInfoPrompts[KIP_SUBKEY]), s);
538 if (subkey->revoked)
539 {
540 putc(' ', fp);
541 /* L10N: describes a subkey */
542 fputs(_("[Revoked]"), fp);
543 }
544 if (subkey->invalid)
545 {
546 putc(' ', fp);
547 /* L10N: describes a subkey */
548 fputs(_("[Invalid]"), fp);
549 }
550 if (subkey->expired)
551 {
552 putc(' ', fp);
553 /* L10N: describes a subkey */
554 fputs(_("[Expired]"), fp);
555 }
556 if (subkey->disabled)
557 {
558 putc(' ', fp);
559 /* L10N: describes a subkey */
560 fputs(_("[Disabled]"), fp);
561 }
562 putc('\n', fp);
563
564 if (subkey->timestamp > 0)
565 {
566 tt = subkey->timestamp;
567
568 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
569 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_FROM],
570 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
571 }
572
573 if (subkey->expires > 0)
574 {
575 tt = subkey->expires;
576
577 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
578 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_TO],
579 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
580 }
581
582 s = gpgme_pubkey_algo_name(subkey->pubkey_algo);
583
584 aval = subkey->length;
585
587 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
588 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), "PGP", aval, s);
589
591 delim = "";
592
593 if (subkey->can_encrypt)
594 {
595 fprintf(fp, "%s%s", delim, _("encryption"));
596 delim = _(", ");
597 }
598 if (subkey->can_sign)
599 {
600 fprintf(fp, "%s%s", delim, _("signing"));
601 delim = _(", ");
602 }
603 if (subkey->can_certify)
604 {
605 fprintf(fp, "%s%s", delim, _("certification"));
606 }
607 putc('\n', fp);
608 }
609 }
610}
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
Definition: crypt_gpgme.c:2837
@ KIP_FINGERPRINT
PGP Key field: Fingerprint.
Definition: crypt_gpgme.h:64
@ KIP_SERIAL_NO
PGP Key field: Serial number.
Definition: crypt_gpgme.h:65
@ KIP_SUBKEY
PGP Key field: Subkey.
Definition: crypt_gpgme.h:67
@ KIP_AKA
PGP Key field: aka (Also Known As)
Definition: crypt_gpgme.h:59
@ KIP_VALID_FROM
PGP Key field: Valid From date.
Definition: crypt_gpgme.h:60
@ KIP_MAX
Definition: crypt_gpgme.h:68
@ KIP_KEY_TYPE
PGP Key field: Key Type.
Definition: crypt_gpgme.h:62
@ KIP_NAME
PGP Key field: Name.
Definition: crypt_gpgme.h:58
@ KIP_ISSUED_BY
PGP Key field: Issued By.
Definition: crypt_gpgme.h:66
@ KIP_KEY_USAGE
PGP Key field: Key Usage.
Definition: crypt_gpgme.h:63
@ KIP_VALID_TO
PGP Key field: Valid To date.
Definition: crypt_gpgme.h:61
@ KEY_CAP_CAN_CERTIFY
Key can be used to certify.
Definition: crypt_gpgme.h:78
@ KEY_CAP_CAN_ENCRYPT
Key can be used for encryption.
Definition: crypt_gpgme.h:76
@ KEY_CAP_CAN_SIGN
Key can be used for signing.
Definition: crypt_gpgme.h:77
size_t mutt_strwidth(const char *s)
Measure a string's width in screen cells.
Definition: curs_lib.c:907
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:692
static const char *const KeyInfoPrompts[]
int KeyInfoPadding[KIP_MAX]
static void parse_and_print_user_id(FILE *fp, const char *userid)
Print a nice representation of the userid.
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:567
+ 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 616 of file gpgme_functions.c.

617{
618 const char *s = NULL;
619 gpgme_ctx_t listctx = NULL;
620 gpgme_error_t err;
621 gpgme_key_t k = NULL;
622 int maxdepth = 100;
623
624 struct Buffer tempfile = mutt_buffer_make(PATH_MAX);
625 mutt_buffer_mktemp(&tempfile);
626 FILE *fp = mutt_file_fopen(mutt_buffer_string(&tempfile), "w");
627 if (!fp)
628 {
629 mutt_perror(_("Can't create temporary file"));
630 goto cleanup;
631 }
632 mutt_message(_("Collecting data..."));
633
634 print_key_info(key->kobj, fp);
635
636 listctx = create_gpgme_context(key->flags & KEYFLAG_ISX509);
637
638 k = key->kobj;
639 gpgme_key_ref(k);
640 while ((s = k->chain_id) && k->subkeys && (strcmp(s, k->subkeys->fpr) != 0))
641 {
642 putc('\n', fp);
643 err = gpgme_op_keylist_start(listctx, s, 0);
644 gpgme_key_unref(k);
645 k = NULL;
646 if (err == 0)
647 err = gpgme_op_keylist_next(listctx, &k);
648 if (err != 0)
649 {
650 fprintf(fp, _("Error finding issuer key: %s\n"), gpgme_strerror(err));
651 goto leave;
652 }
653 gpgme_op_keylist_end(listctx);
654
655 print_key_info(k, fp);
656 if (!--maxdepth)
657 {
658 putc('\n', fp);
659 fputs(_("Error: certification chain too long - stopping here\n"), fp);
660 break;
661 }
662 }
663
664leave:
665 gpgme_key_unref(k);
666 gpgme_release(listctx);
667 mutt_file_fclose(&fp);
669 char title[1024] = { 0 };
670 snprintf(title, sizeof(title), _("Key ID: 0x%s"), crypt_keyid(key));
671
672 struct PagerData pdata = { 0 };
673 struct PagerView pview = { &pdata };
674
675 pdata.fname = mutt_buffer_string(&tempfile);
676
677 pview.banner = title;
679 pview.mode = PAGER_MODE_OTHER;
680
681 mutt_do_pager(&pview, NULL);
682
683cleanup:
684 mutt_buffer_dealloc(&tempfile);
685}
struct Buffer mutt_buffer_make(size_t size)
Make a new buffer on the stack.
Definition: buffer.c:67
void mutt_buffer_dealloc(struct Buffer *buf)
Release the memory allocated by a buffer.
Definition: buffer.c:309
static const char * mutt_buffer_string(const struct Buffer *buf)
Convert a buffer to a const char * "string".
Definition: buffer.h:77
const char * crypt_keyid(struct CryptKeyInfo *k)
Find the ID for the key.
Definition: crypt_gpgme.c:138
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:123
FILE * mutt_file_fopen(const char *path, const char *mode)
Call fopen() safely.
Definition: file.c:618
int mutt_file_fclose(FILE **fp)
Close a FILE handle (and NULL the pointer)
Definition: file.c:152
static int create_gpgme_context(gpgme_ctx_t *ctx)
Create a GPGME context.
Definition: gpgme.c:48
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: logging.h:86
#define mutt_perror(...)
Definition: logging.h:88
#define PATH_MAX
Definition: mutt.h:40
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c:74
#define mutt_buffer_mktemp(buf)
Definition: muttlib.h:74
#define KEYFLAG_ISX509
Key is an X.509 key.
Definition: lib.h:129
#define MUTT_PAGER_NO_FLAGS
No flags are set.
Definition: lib.h:58
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:139
String manipulation buffer.
Definition: buffer.h:34
KeyFlags flags
global and per uid flags (for convenience)
Definition: crypt_gpgme.h:49
gpgme_key_t kobj
Definition: crypt_gpgme.h:46
Data to be displayed by PagerView.
Definition: lib.h:158
const char * fname
Name of the file to read.
Definition: lib.h:162
Paged view into some data.
Definition: lib.h:169
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:170
enum PagerMode mode
Pager mode.
Definition: lib.h:171
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:172
const char * banner
Title to display in status bar.
Definition: lib.h:173
+ 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 692 of file gpgme_functions.c.

693{
694 if (k->flags & KEYFLAG_CANTUSE)
695 return false;
696 return true;
697}
#define KEYFLAG_CANTUSE
Definition: lib.h:139
+ Here is the caller graph for this function:

Variable Documentation

◆ KeyInfoPadding

int KeyInfoPadding[KIP_MAX] = { 0 }

Definition at line 55 of file gpgme_functions.c.

◆ 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

Definition at line 57 of file gpgme_functions.c.

◆ GpgmeFunctions

struct GpgmeFunction GpgmeFunctions[]
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 GpgmeData *gd, int op)
Exit this menu - Implements gpgme_function_t -.
static int op_generic_select_entry(struct GpgmeData *gd, int op)
Select the current entry - Implements gpgme_function_t -.
static int op_view_id(struct GpgmeData *gd, int op)
View the key's user id - Implements gpgme_function_t -.
static int op_verify_key(struct GpgmeData *gd, int op)
Verify a PGP public key - Implements gpgme_function_t -.

All the NeoMutt functions that the Gpgme supports.

Definition at line 800 of file gpgme_functions.c.