NeoMutt  2024-03-23-142-g2b2e76
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 <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 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. */
92 fputs(tstr, fp);
93 FREE(&tstr);
94}
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:90
#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:830
#define MUTT_ICONV_NO_FLAGS
No flags are set.
Definition: charset.h:72
+ 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:709
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 size_t 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);
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; 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);
204 array->value = (char *) p;
205 for (s1 = str; n; 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 (isxdigit(s[0]) && 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);
247 array->value = (char *) p;
248 for (s = str; n; s++, n--)
249 {
250 if (*s == '\\')
251 {
252 s++;
253 if (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}
+ 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) * sizeof(*array));
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) * sizeof(*array));
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 (!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}
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{
388 int idx;
389 const char *s = NULL, *s2 = NULL;
390 time_t tt = 0;
391 char shortbuf[128] = { 0 };
392 unsigned long aval = 0;
393 const char *delim = NULL;
394 gpgme_user_id_t uid = NULL;
395 static int max_header_width = 0;
396
397 if (max_header_width == 0)
398 {
399 for (int i = 0; i < KIP_MAX; i++)
400 {
402 const int width = mutt_strwidth(_(KeyInfoPrompts[i]));
403 if (max_header_width < width)
404 max_header_width = width;
405 KeyInfoPadding[i] -= width;
406 }
407 for (int i = 0; i < KIP_MAX; i++)
408 KeyInfoPadding[i] += max_header_width;
409 }
410
411 bool is_pgp = (key->protocol == GPGME_PROTOCOL_OpenPGP);
412
413 for (idx = 0, uid = key->uids; uid; idx++, uid = uid->next)
414 {
415 if (uid->revoked)
416 continue;
417
418 s = uid->uid;
419 /* L10N: DOTFILL */
420
421 if (idx == 0)
422 fprintf(fp, "%*s", KeyInfoPadding[KIP_NAME], _(KeyInfoPrompts[KIP_NAME]));
423 else
424 fprintf(fp, "%*s", KeyInfoPadding[KIP_AKA], _(KeyInfoPrompts[KIP_AKA]));
425 if (uid->invalid)
426 {
427 /* L10N: comes after the Name or aka if the key is invalid */
428 fputs(_("[Invalid]"), fp);
429 putc(' ', fp);
430 }
431 if (is_pgp)
432 print_utf8(fp, s, strlen(s));
433 else
435 putc('\n', fp);
436 }
437
438 if (key->subkeys && (key->subkeys->timestamp > 0))
439 {
440 tt = key->subkeys->timestamp;
441
442 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
443 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_FROM],
444 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
445 }
446
447 if (key->subkeys && (key->subkeys->expires > 0))
448 {
449 tt = key->subkeys->expires;
450
451 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
452 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_TO],
453 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
454 }
455
456 if (key->subkeys)
457 s = gpgme_pubkey_algo_name(key->subkeys->pubkey_algo);
458 else
459 s = "?";
460
461 s2 = is_pgp ? "PGP" : "X.509";
462
463 if (key->subkeys)
464 aval = key->subkeys->length;
465
467 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
468 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), s2, aval, s);
469
471 delim = "";
472
474 {
475 /* L10N: value in Key Usage: field */
476 fprintf(fp, "%s%s", delim, _("encryption"));
477 delim = _(", ");
478 }
480 {
481 /* L10N: value in Key Usage: field */
482 fprintf(fp, "%s%s", delim, _("signing"));
483 delim = _(", ");
484 }
486 {
487 /* L10N: value in Key Usage: field */
488 fprintf(fp, "%s%s", delim, _("certification"));
489 }
490 putc('\n', fp);
491
492 if (key->subkeys)
493 {
494 s = key->subkeys->fpr;
496 if (is_pgp && (strlen(s) == 40))
497 {
498 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0') &&
499 (s[3] != '\0') && (s[4] != '\0');
500 s += 4, i++)
501 {
502 putc(*s, fp);
503 putc(s[1], fp);
504 putc(s[2], fp);
505 putc(s[3], fp);
506 putc(' ', fp);
507 if (i == 4)
508 putc(' ', fp);
509 }
510 }
511 else
512 {
513 for (int i = 0; (s[0] != '\0') && (s[1] != '\0') && (s[2] != '\0'); s += 2, i++)
514 {
515 putc(*s, fp);
516 putc(s[1], fp);
517 putc(is_pgp ? ' ' : ':', fp);
518 if (is_pgp && (i == 7))
519 putc(' ', fp);
520 }
521 }
522 fprintf(fp, "%s\n", s);
523 }
524
525 if (key->issuer_serial)
526 {
527 s = key->issuer_serial;
528 fprintf(fp, "%*s0x%s\n", KeyInfoPadding[KIP_SERIAL_NO],
530 }
531
532 if (key->issuer_name)
533 {
534 s = key->issuer_name;
537 putc('\n', fp);
538 }
539
540 /* For PGP we list all subkeys. */
541 if (is_pgp)
542 {
543 gpgme_subkey_t subkey = NULL;
544
545 for (idx = 1, subkey = key->subkeys; subkey; idx++, subkey = subkey->next)
546 {
547 s = subkey->keyid;
548
549 putc('\n', fp);
550 if (strlen(s) == 16)
551 s += 8; /* display only the short keyID */
552 fprintf(fp, "%*s0x%s", KeyInfoPadding[KIP_SUBKEY], _(KeyInfoPrompts[KIP_SUBKEY]), s);
553 if (subkey->revoked)
554 {
555 putc(' ', fp);
556 /* L10N: describes a subkey */
557 fputs(_("[Revoked]"), fp);
558 }
559 if (subkey->invalid)
560 {
561 putc(' ', fp);
562 /* L10N: describes a subkey */
563 fputs(_("[Invalid]"), fp);
564 }
565 if (subkey->expired)
566 {
567 putc(' ', fp);
568 /* L10N: describes a subkey */
569 fputs(_("[Expired]"), fp);
570 }
571 if (subkey->disabled)
572 {
573 putc(' ', fp);
574 /* L10N: describes a subkey */
575 fputs(_("[Disabled]"), fp);
576 }
577 putc('\n', fp);
578
579 if (subkey->timestamp > 0)
580 {
581 tt = subkey->timestamp;
582
583 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
584 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_FROM],
585 _(KeyInfoPrompts[KIP_VALID_FROM]), shortbuf);
586 }
587
588 if (subkey->expires > 0)
589 {
590 tt = subkey->expires;
591
592 mutt_date_localtime_format(shortbuf, sizeof(shortbuf), nl_langinfo(D_T_FMT), tt);
593 fprintf(fp, "%*s%s\n", KeyInfoPadding[KIP_VALID_TO],
594 _(KeyInfoPrompts[KIP_VALID_TO]), shortbuf);
595 }
596
597 s = gpgme_pubkey_algo_name(subkey->pubkey_algo);
598
599 aval = subkey->length;
600
602 /* L10N: This is printed after "Key Type: " and looks like this: PGP, 2048 bit RSA */
603 fprintf(fp, ngettext("%s, %lu bit %s\n", "%s, %lu bit %s\n", aval), "PGP", aval, s);
604
606 delim = "";
607
608 if (subkey->can_encrypt)
609 {
610 fprintf(fp, "%s%s", delim, _("encryption"));
611 delim = _(", ");
612 }
613 if (subkey->can_sign)
614 {
615 fprintf(fp, "%s%s", delim, _("signing"));
616 delim = _(", ");
617 }
618 if (subkey->can_certify)
619 {
620 fprintf(fp, "%s%s", delim, _("certification"));
621 }
622 putc('\n', fp);
623 }
624 }
625}
unsigned int key_check_cap(gpgme_key_t key, enum KeyCap cap)
Check the capabilities of a key.
Definition: crypt_gpgme.c:2902
@ 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:950
size_t mutt_str_len(const char *a)
Calculate the length of a string, safely.
Definition: string.c:545
+ 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 631 of file gpgme_functions.c.

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

708{
709 if (k->flags & KEYFLAG_CANTUSE)
710 return false;
711 return true;
712}
#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 719 of file gpgme_functions.c.

720{
721 for (struct CryptKeyInfo *k = keys; k != NULL; k = k->next)
722 {
723 if (!crypt_key_is_valid(k))
724 return false;
725 }
726
727 return true;
728}
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 54 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 57 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 831 of file gpgme_functions.c.