NeoMutt  2024-10-02-37-gfa9146
Teaching an old dog new tricks
DOXYGEN
Loading...
Searching...
No Matches
gpgme_functions.c File Reference

Gpgme functions. More...

#include "config.h"
#include <ctype.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 "menu/lib.h"
#include "pager/lib.h"
#include "question/lib.h"
#include "crypt_gpgme.h"
#include "globals.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, 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_verify_key (struct GpgmeData *gd, int op)
 Verify a PGP public key - Implements gpgme_function_t -.
 
static int op_view_id (struct GpgmeData *gd, int op)
 View the key's user id - Implements gpgme_function_t -.
 
int gpgme_function_dispatcher (struct MuttWindow *win, int op)
 Perform a Gpgme function - Implements function_dispatcher_t -.
 

Variables

int KeyInfoPadding [KIP_MAX] = { 0 }
 Number of padding spaces needed after each of the strings in KeyInfoPrompts after translation.
 
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

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 84 of file gpgme_functions.c.

85{
86 char *tstr = mutt_mem_malloc(len + 1);
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.
Definition: config_cache.c:116
void * mutt_mem_malloc(size_t size)
Allocate memory on the heap.
Definition: memory.c:91
#define FREE(x)
Definition: memory.h:45
int mutt_ch_convert_string(char **ps, const char *from, const char *to, uint8_t flags)
Convert a string between encodings.
Definition: charset.c:831
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:73
+ 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 (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:660
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 (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 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 {
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);
248 array->value = (char *) p;
249 for (s = str; n; s++, n--)
250 {
251 if (*s == '\\')
252 {
253 s++;
254 if (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}
+ 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 gpgme_functions.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) * sizeof(*array));
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) * sizeof(*array));
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 gpgme_functions.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 (!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}
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 gpgme_functions.c.

388{
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 {
403 const int width = mutt_strwidth(_(KeyInfoPrompts[i]));
404 if (max_header_width < width)
405 max_header_width = width;
406 KeyInfoPadding[i] -= width;
407 }
408 for (int i = 0; i < KIP_MAX; i++)
409 KeyInfoPadding[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", KeyInfoPadding[KIP_NAME], _(KeyInfoPrompts[KIP_NAME]));
424 else
425 fprintf(fp, "%*s", KeyInfoPadding[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", KeyInfoPadding[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", KeyInfoPadding[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
468 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
469 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), s2, aval, s);
470
472 delim = "";
473
475 {
476 /* L10N: value in Key Usage: field */
477 fprintf(fp, "%s%s", delim, _("encryption"));
478 delim = _(", ");
479 }
481 {
482 /* L10N: value in Key Usage: field */
483 fprintf(fp, "%s%s", delim, _("signing"));
484 delim = _(", ");
485 }
487 {
488 /* L10N: value in Key Usage: field */
489 fprintf(fp, "%s%s", delim, _("certification"));
490 }
491 putc('\n', fp);
492
493 if (key->subkeys)
494 {
495 s = key->subkeys->fpr;
497 if (is_pgp && (strlen(s) == 40))
498 {
499 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0') &&
500 (s[3] != '\0') && (s[4] != '\0');
501 s += 4, i++)
502 {
503 putc(*s, fp);
504 putc(s[1], fp);
505 putc(s[2], fp);
506 putc(s[3], fp);
507 putc(' ', fp);
508 if (i == 4)
509 putc(' ', fp);
510 }
511 }
512 else
513 {
514 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0'); s += 2, i++)
515 {
516 putc(*s, fp);
517 putc(s[1], fp);
518 putc(is_pgp ? ' ' : ':', fp);
519 if (is_pgp && (i == 7))
520 putc(' ', fp);
521 }
522 }
523 fprintf(fp, "%s\n", s);
524 }
525
526 if (key->issuer_serial)
527 {
528 s = key->issuer_serial;
529 fprintf(fp, "%*s0x%s\n", KeyInfoPadding[KIP_SERIAL_NO],
531 }
532
533 if (key->issuer_name)
534 {
535 s = key->issuer_name;
538 putc('\n', fp);
539 }
540
541 /* For PGP we list all subkeys. */
542 if (is_pgp)
543 {
544 gpgme_subkey_t subkey = NULL;
545
546 for (idx = 1, subkey = key->subkeys; subkey; idx++, subkey = subkey->next)
547 {
548 s = subkey->keyid;
549
550 putc('\n', fp);
551 if (strlen(s) == 16)
552 s += 8; /* display only the short keyID */
553 fprintf(fp, "%*s0x%s", KeyInfoPadding[KIP_SUBKEY], _(KeyInfoPrompts[KIP_SUBKEY]), s);
554 if (subkey->revoked)
555 {
556 putc(' ', fp);
557 /* L10N: describes a subkey */
558 fputs(_("[Revoked]"), fp);
559 }
560 if (subkey->invalid)
561 {
562 putc(' ', fp);
563 /* L10N: describes a subkey */
564 fputs(_("[Invalid]"), fp);
565 }
566 if (subkey->expired)
567 {
568 putc(' ', fp);
569 /* L10N: describes a subkey */
570 fputs(_("[Expired]"), fp);
571 }
572 if (subkey->disabled)
573 {
574 putc(' ', fp);
575 /* L10N: describes a subkey */
576 fputs(_("[Disabled]"), fp);
577 }
578 putc('\n', fp);
579
580 if (subkey->timestamp > 0)
581 {
582 tt = subkey->timestamp;
583
584 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
585 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_FROM],
586 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
587 }
588
589 if (subkey->expires > 0)
590 {
591 tt = subkey->expires;
592
593 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
594 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_TO],
595 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
596 }
597
598 s = gpgme_pubkey_algo_name(subkey->pubkey_algo);
599
600 aval = subkey->length;
601
603 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
604 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), "PGP", aval, s);
605
607 delim = "";
608
609 if (subkey->can_encrypt)
610 {
611 fprintf(fp, "%s%s", delim, _("encryption"));
612 delim = _(", ");
613 }
614 if (subkey->can_sign)
615 {
616 fprintf(fp, "%s%s", delim, _("signing"));
617 delim = _(", ");
618 }
619 if (subkey->can_certify)
620 {
621 fprintf(fp, "%s%s", delim, _("certification"));
622 }
623 putc('\n', fp);
624 }
625 }
626}
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
Definition: crypt_gpgme.c:2948
@ 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:443
static const char *const KeyInfoPrompts[]
Names of header fields used in the pgp key display, e.g. Name:, Fingerprint:
int KeyInfoPadding[KIP_MAX]
Number of padding spaces needed after each of the strings in KeyInfoPrompts after translation.
static void parse_and_print_user_id(FILE *fp, const char *userid)
Print a nice representation of the userid.
size_t mutt_date_localtime_format(char *buf, size_t buflen, const char *format, time_t t)
Format localtime.
Definition: date.c:951
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:496
+ 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 632 of file gpgme_functions.c.

633{
634 const char *s = NULL;
635 gpgme_ctx_t listctx = NULL;
636 gpgme_error_t err = GPG_ERR_NO_ERROR;
637 gpgme_key_t k = NULL;
638 int maxdepth = 100;
639
640 struct Buffer *tempfile = buf_pool_get();
641 buf_mktemp(tempfile);
642 FILE *fp = mutt_file_fopen(buf_string(tempfile), "w");
643 if (!fp)
644 {
645 mutt_perror(_("Can't create temporary file"));
646 goto cleanup;
647 }
648 mutt_message(_("Collecting data..."));
649
650 print_key_info(key->kobj, fp);
651
652 listctx = create_gpgme_context(key->flags & KEYFLAG_ISX509);
653
654 k = key->kobj;
655 gpgme_key_ref(k);
656 while ((s = k->chain_id) && k->subkeys && !mutt_str_equal(s, k->subkeys->fpr))
657 {
658 putc('\n', fp);
659 err = gpgme_op_keylist_start(listctx, s, 0);
660 gpgme_key_unref(k);
661 k = NULL;
662 if (err == GPG_ERR_NO_ERROR)
663 err = gpgme_op_keylist_next(listctx, &k);
664 if (err != GPG_ERR_NO_ERROR)
665 {
666 fprintf(fp, _("Error finding issuer key: %s\n"), gpgme_strerror(err));
667 goto leave;
668 }
669 gpgme_op_keylist_end(listctx);
670
671 print_key_info(k, fp);
672 if (!--maxdepth)
673 {
674 putc('\n', fp);
675 fputs(_("Error: certification chain too long - stopping here\n"), fp);
676 break;
677 }
678 }
679
680leave:
681 gpgme_key_unref(k);
682 gpgme_release(listctx);
683 mutt_file_fclose(&fp);
685 char title[1024] = { 0 };
686 snprintf(title, sizeof(title), _("Key ID: 0x%s"), crypt_keyid(key));
687
688 struct PagerData pdata = { 0 };
689 struct PagerView pview = { &pdata };
690
691 pdata.fname = buf_string(tempfile);
692
693 pview.banner = title;
695 pview.mode = PAGER_MODE_OTHER;
696
697 mutt_do_pager(&pview, NULL);
698
699cleanup:
700 buf_pool_release(&tempfile);
701}
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.
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:122
#define mutt_file_fclose(FP)
Definition: file.h:138
#define mutt_file_fopen(PATH, MODE)
Definition: file.h:137
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:91
#define mutt_perror(...)
Definition: logging2.h:93
void mutt_clear_error(void)
Clear the message line (bottom line of screen)
Definition: mutt_logging.c: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:60
@ PAGER_MODE_OTHER
Pager is invoked via 3rd path. Non-email content is likely to be shown.
Definition: lib.h:142
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:36
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:161
const char * fname
Name of the file to read.
Definition: lib.h:165
Paged view into some data.
Definition: lib.h:172
struct PagerData * pdata
Data that pager displays. NOTNULL.
Definition: lib.h:173
enum PagerMode mode
Pager mode.
Definition: lib.h:174
PagerFlags flags
Additional settings to tweak pager's function.
Definition: lib.h:175
const char * banner
Title to display in status bar.
Definition: lib.h:176
#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 708 of file gpgme_functions.c.

709{
710 if (k->flags & KEYFLAG_CANTUSE)
711 return false;
712 return true;
713}
#define KEYFLAG_CANTUSE
Definition: lib.h:139
+ 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 720 of file gpgme_functions.c.

721{
722 for (struct CryptKeyInfo *k = keys; k != NULL; k = k->next)
723 {
724 if (!crypt_key_is_valid(k))
725 return false;
726 }
727
728 return true;
729}
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

◆ KeyInfoPadding

int KeyInfoPadding[KIP_MAX] = { 0 }

Number of padding spaces needed after each of the strings in KeyInfoPrompts after translation.

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

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

Definition at line 58 of file gpgme_functions.c.

◆ 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 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 832 of file gpgme_functions.c.