1 /* keylist.c - Print information about OpenPGP keys
2 * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
3 * 2008, 2010, 2012 Free Software Foundation, Inc.
4 * Copyright (C) 2013, 2014 Werner Koch
6 * This file is part of GnuPG.
8 * GnuPG is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 3 of the License, or
11 * (at your option) any later version.
13 * GnuPG is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, see <https://www.gnu.org/licenses/>.
27 #ifdef HAVE_DOSISH_SYSTEM
28 # include <fcntl.h> /* for setmode() */
34 #include "../common/status.h"
37 #include "../common/util.h"
38 #include "../common/ttyio.h"
41 #include "../common/i18n.h"
42 #include "../common/status.h"
43 #include "call-agent.h"
44 #include "../common/mbox-util.h"
45 #include "../common/zb32.h"
47 #include "../common/init.h"
48 #include "../common/recsel.h"
49 #include "../common/compliance.h"
50 #include "../common/pkscreening.h"
53 static void list_all (ctrl_t, int, int);
54 static void list_one (ctrl_t ctrl,
55 strlist_t names, int secret, int mark_secret);
56 static void locate_one (ctrl_t ctrl, strlist_t names, int no_local);
57 static void print_card_serialno (const char *serialno);
59 struct keylist_context
61 int check_sigs; /* If set signatures shall be verified. */
62 int good_sigs; /* Counter used if CHECK_SIGS is set. */
63 int inv_sigs; /* Counter used if CHECK_SIGS is set. */
64 int no_key; /* Counter used if CHECK_SIGS is set. */
65 int oth_err; /* Counter used if CHECK_SIGS is set. */
66 int no_validity; /* Do not show validity. */
69 /* An object and a global instance to store selectors created from
70 * --list-filter select=EXPR.
76 struct list_filter_s list_filter;
79 /* The stream used to write attribute packets to. */
80 static estream_t attrib_fp;
85 static void list_keyblock (ctrl_t ctrl,
86 kbnode_t keyblock, int secret, int has_secret,
87 int fpr, struct keylist_context *listctx);
89 /* Release resources from a keylist context. */
91 keylist_context_release (struct keylist_context *listctx)
93 (void)listctx; /* Nothing to release. */
98 release_list_filter (struct list_filter_s *filt)
100 recsel_release (filt->selkey);
106 cleanup_keylist_globals (void)
108 release_list_filter (&list_filter);
112 /* Parse and set an list filter from string. STRING has the format
113 * "NAME=EXPR" with NAME being the name of the filter. Spaces before
114 * and after NAME are not allowed. If this function is all called
115 * several times all expressions for the same NAME are concatenated.
116 * Supported filter names are:
118 * - select :: If the expression evaluates to true for a certain key
119 * this key will be listed. The expression may use any
120 * variable defined for the export and import filters.
124 parse_and_set_list_filter (const char *string)
128 /* Auto register the cleanup function. */
129 register_mem_cleanup_func (cleanup_keylist_globals);
131 if (!strncmp (string, "select=", 7))
132 err = recsel_parse_expr (&list_filter.selkey, string+7);
134 err = gpg_error (GPG_ERR_INV_NAME);
140 /* List the keys. If list is NULL, all available keys are listed.
141 * With LOCATE_MODE set the locate algorithm is used to find a key; if
142 * in addition NO_LOCAL is set the locate does not look into the local
145 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode, int no_local)
147 #ifndef NO_TRUST_MODELS
150 byte trust_model, marginals, completes, cert_depth, min_cert_level;
151 ulong created, nextcheck;
153 read_trust_options (ctrl, &trust_model, &created, &nextcheck,
154 &marginals, &completes, &cert_depth, &min_cert_level);
156 es_fprintf (es_stdout, "tru:");
158 if (nextcheck && nextcheck <= make_timestamp ())
159 es_fprintf (es_stdout, "o");
160 if (trust_model != opt.trust_model)
161 es_fprintf (es_stdout, "t");
162 if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC
163 || opt.trust_model == TM_TOFU_PGP)
165 if (marginals != opt.marginals_needed)
166 es_fprintf (es_stdout, "m");
167 if (completes != opt.completes_needed)
168 es_fprintf (es_stdout, "c");
169 if (cert_depth != opt.max_cert_depth)
170 es_fprintf (es_stdout, "d");
171 if (min_cert_level != opt.min_cert_level)
172 es_fprintf (es_stdout, "l");
175 es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
177 /* Only show marginals, completes, and cert_depth in the classic
178 or PGP trust models since they are not meaningful
181 if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
182 es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
183 es_fprintf (es_stdout, "\n");
185 #endif /*!NO_TRUST_MODELS*/
187 /* We need to do the stale check right here because it might need to
188 update the keyring while we already have the keyring open. This
189 is very bad for W32 because of a sharing violation. For real OSes
190 it might lead to false results if we are later listing a keyring
191 which is associated with the inode of a deleted file. */
192 check_trustdb_stale (ctrl);
195 tofu_begin_batch_update (ctrl);
199 locate_one (ctrl, list, no_local);
201 list_all (ctrl, 0, opt.with_secret);
203 list_one (ctrl, list, 0, opt.with_secret);
206 tofu_end_batch_update (ctrl);
212 secret_key_list (ctrl_t ctrl, strlist_t list)
216 check_trustdb_stale (ctrl);
219 list_all (ctrl, 1, 0);
220 else /* List by user id */
221 list_one (ctrl, list, 1, 0);
225 /* Helper for print_key_info and print_key_info_log. */
227 format_key_info (ctrl_t ctrl, PKT_public_key *pk, int secret)
231 char pkstrbuf[PUBKEY_STRING_SIZE];
234 keyid_from_pk (pk, keyid);
236 /* If the pk was chosen by a particular user ID, that is the one to
239 p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
241 p = get_user_id_native (ctrl, keyid);
243 result = xtryasprintf ("%s %s/%s %s %s",
244 secret? (pk->flags.primary? "sec":"ssb")
245 /* */ : (pk->flags.primary? "pub":"sub"),
246 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
247 keystr (keyid), datestr_from_pk (pk), p);
253 /* Print basic information about a public or secret key. With FP
254 * passed as NULL, the tty output interface is used, otherwise output
255 * is directed to the given stream. INDENT gives the requested
256 * indentation; if that is a negative value indentation is suppressed
257 * for the first line. SECRET tells that the PK has a secret part.
258 * FIXME: This is similar in use to print_key_line and thus both
259 * functions should eventually be united.
262 print_key_info (ctrl_t ctrl, estream_t fp,
263 int indent, PKT_public_key *pk, int secret)
265 int indentabs = indent >= 0? indent : -indent;
268 /* Note: Negative values for INDENT are not yet needed. */
270 info = format_key_info (ctrl, pk, secret);
272 if (!fp && indent >= 0)
273 tty_printf ("\n"); /* (Backward compatibility to old code) */
274 tty_fprintf (fp, "%*s%s\n", indentabs, "",
275 info? info : "[Ooops - out of core]");
281 /* Same as print_key_info put print using the log functions at
284 print_key_info_log (ctrl_t ctrl, int loglevel,
285 int indent, PKT_public_key *pk, int secret)
287 int indentabs = indent >= 0? indent : -indent;
290 info = format_key_info (ctrl, pk, secret);
292 log_log (loglevel, "%*s%s\n", indentabs, "",
293 info? info : "[Ooops - out of core]");
299 /* Print basic information of a secret key including the card serial
300 number information. */
301 #ifdef ENABLE_CARD_SUPPORT
303 print_card_key_info (estream_t fp, kbnode_t keyblock)
309 char pkstrbuf[PUBKEY_STRING_SIZE];
312 for (node = keyblock; node; node = node->next)
314 if (node->pkt->pkttype == PKT_PUBLIC_KEY
315 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
318 PKT_public_key *pk = node->pkt->pkt.public_key;
321 rc = hexkeygrip_from_pk (pk, &hexgrip);
324 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
327 else if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
328 s2k_char = serialno? '>':' ';
330 s2k_char = '#'; /* Key not found. */
332 tty_fprintf (fp, "%s%c %s/%s %n",
333 node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
335 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
338 tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
339 tty_fprintf (fp, " ");
340 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
343 tty_fprintf (fp, "\n%*s%s", indent, "", _("card-no: "));
344 if (strlen (serialno) == 32
345 && !strncmp (serialno, "D27600012401", 12))
347 /* This is an OpenPGP card. Print the relevant part. */
348 /* Example: D2760001240101010001000003470000 */
350 tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
353 tty_fprintf (fp, "%s", serialno);
355 tty_fprintf (fp, "\n");
361 #endif /*ENABLE_CARD_SUPPORT*/
364 /* Print the preferences line. Allowed values for MODE are:
365 * -1 - print to the TTY
366 * 0 - print to stdout.
370 show_preferences (PKT_user_id *uid, int indent, int mode, int verbose)
372 estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
373 const prefitem_t fake = { 0, 0 };
374 const prefitem_t *prefs;
389 int any, des_seen = 0, sha1_seen = 0, uncomp_seen = 0;
391 tty_fprintf (fp, "%*s %s", indent, "", _("Cipher: "));
392 for (i = any = 0; prefs[i].type; i++)
394 if (prefs[i].type == PREFTYPE_SYM)
397 tty_fprintf (fp, ", ");
399 /* We don't want to display strings for experimental algos */
400 if (!openpgp_cipher_test_algo (prefs[i].value)
401 && prefs[i].value < 100)
402 tty_fprintf (fp, "%s", openpgp_cipher_algo_name (prefs[i].value));
404 tty_fprintf (fp, "[%d]", prefs[i].value);
405 if (prefs[i].value == CIPHER_ALGO_3DES)
412 tty_fprintf (fp, ", ");
413 tty_fprintf (fp, "%s", openpgp_cipher_algo_name (CIPHER_ALGO_3DES));
415 tty_fprintf (fp, "\n%*s %s", indent, "", _("AEAD: "));
416 for (i = any = 0; prefs[i].type; i++)
418 if (prefs[i].type == PREFTYPE_AEAD)
421 tty_fprintf (fp, ", ");
423 /* We don't want to display strings for experimental algos */
424 if (!openpgp_aead_test_algo (prefs[i].value)
425 && prefs[i].value < 100)
426 tty_fprintf (fp, "%s", openpgp_aead_algo_name (prefs[i].value));
428 tty_fprintf (fp, "[%d]", prefs[i].value);
431 tty_fprintf (fp, "\n%*s %s", indent, "", _("Digest: "));
432 for (i = any = 0; prefs[i].type; i++)
434 if (prefs[i].type == PREFTYPE_HASH)
437 tty_fprintf (fp, ", ");
439 /* We don't want to display strings for experimental algos */
440 if (!gcry_md_test_algo (prefs[i].value) && prefs[i].value < 100)
441 tty_fprintf (fp, "%s", gcry_md_algo_name (prefs[i].value));
443 tty_fprintf (fp, "[%d]", prefs[i].value);
444 if (prefs[i].value == DIGEST_ALGO_SHA1)
451 tty_fprintf (fp, ", ");
452 tty_fprintf (fp, "%s", gcry_md_algo_name (DIGEST_ALGO_SHA1));
454 tty_fprintf (fp, "\n%*s %s", indent, "", _("Compression: "));
455 for (i = any = 0; prefs[i].type; i++)
457 if (prefs[i].type == PREFTYPE_ZIP)
459 const char *s = compress_algo_to_string (prefs[i].value);
462 tty_fprintf (fp, ", ");
464 /* We don't want to display strings for experimental algos */
465 if (s && prefs[i].value < 100)
466 tty_fprintf (fp, "%s", s);
468 tty_fprintf (fp, "[%d]", prefs[i].value);
469 if (prefs[i].value == COMPRESS_ALGO_NONE)
476 tty_fprintf (fp, ", ");
479 tty_fprintf (fp, "%s",
480 compress_algo_to_string (COMPRESS_ALGO_ZIP));
481 tty_fprintf (fp, ", ");
483 tty_fprintf (fp, "%s", compress_algo_to_string (COMPRESS_ALGO_NONE));
485 if (uid->flags.mdc || uid->flags.aead || !uid->flags.ks_modify)
487 tty_fprintf (fp, "\n%*s %s", indent, "", _("Features: "));
491 tty_fprintf (fp, "MDC");
497 tty_fprintf (fp, ", ");
498 tty_fprintf (fp, "AEAD");
500 if (!uid->flags.ks_modify)
503 tty_fprintf (fp, ", ");
504 tty_fprintf (fp, _("Keyserver no-modify"));
507 tty_fprintf (fp, "\n");
511 tty_fprintf (fp, "%*s", indent, "");
512 for (i = 0; prefs[i].type; i++)
514 tty_fprintf (fp, " %c%d", prefs[i].type == PREFTYPE_SYM ? 'S' :
515 prefs[i].type == PREFTYPE_AEAD ? 'A' :
516 prefs[i].type == PREFTYPE_HASH ? 'H' :
517 prefs[i].type == PREFTYPE_ZIP ? 'Z' : '?',
521 tty_fprintf (fp, " [mdc]");
523 tty_fprintf (fp, " [aead]");
524 if (!uid->flags.ks_modify)
525 tty_fprintf (fp, " [no-ks-modify]");
526 tty_fprintf (fp, "\n");
531 /* Flags = 0x01 hashed 0x02 critical. */
533 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
538 /* Don't print these. */
542 snprintf (status, sizeof status,
543 "%d %u %u ", type, flags, (unsigned int) len);
545 write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
549 /* Print a policy URL. Allowed values for MODE are:
550 * -1 - print to the TTY
551 * 0 - print to stdout.
552 * 1 - use log_info and emit status messages.
553 * 2 - emit only status messages.
556 show_policy_url (PKT_signature * sig, int indent, int mode)
561 estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
563 while ((p = enum_sig_subpkt (sig, 1, SIGSUBPKT_POLICY, &len, &seq, &crit)))
569 tty_fprintf (fp, "%*s", indent, "");
572 str = _("Critical signature policy: ");
574 str = _("Signature policy: ");
576 log_info ("%s", str);
578 tty_fprintf (fp, "%s", str);
579 tty_print_utf8_string2 (fp, p, len, 0);
580 tty_fprintf (fp, "\n");
584 write_status_buffer (STATUS_POLICY_URL, p, len, 0);
589 /* Print a keyserver URL. Allowed values for MODE are:
590 * -1 - print to the TTY
591 * 0 - print to stdout.
592 * 1 - use log_info and emit status messages.
593 * 2 - emit only status messages.
596 show_keyserver_url (PKT_signature * sig, int indent, int mode)
601 estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
603 while ((p = enum_sig_subpkt (sig, 1, SIGSUBPKT_PREF_KS, &len, &seq, &crit)))
609 tty_fprintf (fp, "%*s", indent, "");
612 str = _("Critical preferred keyserver: ");
614 str = _("Preferred keyserver: ");
616 log_info ("%s", str);
618 tty_fprintf (fp, "%s", str);
619 tty_print_utf8_string2 (fp, p, len, 0);
620 tty_fprintf (fp, "\n");
624 status_one_subpacket (SIGSUBPKT_PREF_KS, len,
625 (crit ? 0x02 : 0) | 0x01, p);
630 /* Print notation data. Allowed values for MODE are:
631 * -1 - print to the TTY
632 * 0 - print to stdout.
633 * 1 - use log_info and emit status messages.
634 * 2 - emit only status messages.
636 * Defined bits in WHICH:
637 * 1 - standard notations
641 show_notation (PKT_signature * sig, int indent, int mode, int which)
643 estream_t fp = mode < 0? NULL : mode ? log_get_stream () : es_stdout;
644 notation_t nd, notations;
649 notations = sig_to_notation (sig);
651 /* There may be multiple notations in the same sig. */
652 for (nd = notations; nd; nd = nd->next)
656 int has_at = !!strchr (nd->name, '@');
658 if ((which & 1 && !has_at) || (which & 2 && has_at))
662 tty_fprintf (fp, "%*s", indent, "");
664 if (nd->flags.critical)
665 str = _("Critical signature notation: ");
667 str = _("Signature notation: ");
669 log_info ("%s", str);
671 tty_fprintf (fp, "%s", str);
672 /* This is all UTF8 */
673 tty_print_utf8_string2 (fp, nd->name, strlen (nd->name), 0);
674 tty_fprintf (fp, "=");
675 tty_print_utf8_string2 (fp, nd->value, strlen (nd->value), 0);
676 /* (We need to use log_printf so that the next call to a
677 log function does not insert an extra LF.) */
681 tty_fprintf (fp, "\n");
687 write_status_buffer (STATUS_NOTATION_NAME,
688 nd->name, strlen (nd->name), 0);
689 if (nd->flags.critical || nd->flags.human)
690 write_status_text (STATUS_NOTATION_FLAGS,
691 nd->flags.critical && nd->flags.human? "1 1" :
692 nd->flags.critical? "1 0" : "0 1");
693 if (!nd->flags.human && nd->bdat && nd->blen)
694 write_status_buffer (STATUS_NOTATION_DATA,
695 nd->bdat, nd->blen, 250);
697 write_status_buffer (STATUS_NOTATION_DATA,
698 nd->value, strlen (nd->value), 50);
702 free_notation (notations);
707 print_signature_stats (struct keylist_context *s)
710 return; /* Signature checking was not requested. */
712 /* Better flush stdout so that the stats are always printed after
714 es_fflush (es_stdout);
717 log_info (ngettext("%d good signature\n",
718 "%d good signatures\n", s->good_sigs), s->good_sigs);
721 log_info (ngettext("%d bad signature\n",
722 "%d bad signatures\n", s->inv_sigs), s->inv_sigs);
725 log_info (ngettext("%d signature not checked due to a missing key\n",
726 "%d signatures not checked due to missing keys\n",
727 s->no_key), s->no_key);
730 log_info (ngettext("%d signature not checked due to an error\n",
731 "%d signatures not checked due to errors\n",
732 s->oth_err), s->oth_err);
736 /* List all keys. If SECRET is true only secret keys are listed. If
737 MARK_SECRET is true secret keys are indicated in a public key
740 list_all (ctrl_t ctrl, int secret, int mark_secret)
743 KBNODE keyblock = NULL;
746 const char *lastresname, *resname;
747 struct keylist_context listctx;
749 memset (&listctx, 0, sizeof (listctx));
751 listctx.check_sigs = 1;
753 hd = keydb_new (ctrl);
755 rc = gpg_error_from_syserror ();
757 rc = keydb_search_first (hd);
760 if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
761 log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
769 glo_ctrl.silence_parse_warnings++;
770 rc = keydb_get_keyblock (hd, &keyblock);
772 glo_ctrl.silence_parse_warnings--;
775 if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
776 continue; /* Skip legacy keys. */
777 log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
781 if (secret || mark_secret)
782 any_secret = !agent_probe_any_secret_key (ctrl, keyblock);
786 if (secret && !any_secret)
787 ; /* Secret key listing requested but this isn't one. */
790 if (!opt.with_colons && !(opt.list_options & LIST_SHOW_ONLY_FPR_MBOX))
792 resname = keydb_get_resource_name (hd);
793 if (lastresname != resname)
797 es_fprintf (es_stdout, "%s\n", resname);
798 for (i = strlen (resname); i; i--)
799 es_putc ('-', es_stdout);
800 es_putc ('\n', es_stdout);
801 lastresname = resname;
804 merge_keys_and_selfsig (ctrl, keyblock);
805 list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint,
808 release_kbnode (keyblock);
811 while (!(rc = keydb_search_next (hd)));
812 es_fflush (es_stdout);
813 if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
814 log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
815 if (keydb_get_skipped_counter (hd))
816 log_info (ngettext("Warning: %lu key skipped due to its large size\n",
817 "Warning: %lu keys skipped due to their large sizes\n",
818 keydb_get_skipped_counter (hd)),
819 keydb_get_skipped_counter (hd));
821 if (opt.check_sigs && !opt.with_colons)
822 print_signature_stats (&listctx);
825 keylist_context_release (&listctx);
826 release_kbnode (keyblock);
832 list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
835 KBNODE keyblock = NULL;
839 const char *keyring_str = _("Keyring");
841 struct keylist_context listctx;
843 memset (&listctx, 0, sizeof (listctx));
844 if (!secret && opt.check_sigs)
845 listctx.check_sigs = 1;
847 /* fixme: using the bynames function has the disadvantage that we
848 * don't know whether one of the names given was not found. OTOH,
849 * this function has the advantage to list the names in the
850 * sequence as defined by the keyDB and does not duplicate
851 * outputs. A solution could be do test whether all given have
852 * been listed (this needs a way to use the keyDB search
853 * functions) or to have the search function return indicators for
854 * found names. Yet another way is to use the keydb search
855 * facilities directly. */
856 rc = getkey_bynames (ctrl, &ctx, NULL, names, secret, &keyblock);
859 log_error ("error reading key: %s\n", gpg_strerror (rc));
860 getkey_end (ctrl, ctx);
861 write_status_error ("keylist.getkey", rc);
867 /* getkey_bynames makes sure that only secret keys are returned
868 * if requested, thus we do not need to test again. With
869 * MARK_SECRET set (ie. option --with-secret) we have to test
870 * for a secret key, though. */
873 else if (mark_secret)
874 any_secret = !agent_probe_any_secret_key (ctrl, keyblock);
878 if (secret && !any_secret)
879 ;/* Secret key listing requested but getkey_bynames failed. */
882 if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
884 resname = keydb_get_resource_name (get_ctx_handle (ctx));
885 es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
886 for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
887 es_putc ('-', es_stdout);
888 es_putc ('\n', es_stdout);
890 list_keyblock (ctrl, keyblock, secret, any_secret,
891 opt.fingerprint, &listctx);
893 release_kbnode (keyblock);
895 while (!getkey_next (ctrl, ctx, NULL, &keyblock));
896 getkey_end (ctrl, ctx);
898 if (opt.check_sigs && !opt.with_colons)
899 print_signature_stats (&listctx);
901 keylist_context_release (&listctx);
906 locate_one (ctrl_t ctrl, strlist_t names, int no_local)
910 GETKEY_CTX ctx = NULL;
911 KBNODE keyblock = NULL;
912 struct keylist_context listctx;
914 memset (&listctx, 0, sizeof (listctx));
916 listctx.check_sigs = 1;
918 for (sl = names; sl; sl = sl->next)
920 rc = get_best_pubkey_byname (ctrl,
921 no_local? GET_PUBKEY_NO_LOCAL
922 /* */: GET_PUBKEY_NORMAL,
923 &ctx, NULL, sl->d, &keyblock, 1);
926 if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
927 log_error ("error reading key: %s\n", gpg_strerror (rc));
928 else if (opt.verbose)
929 log_info (_("key \"%s\" not found: %s\n"),
930 sl->d, gpg_strerror (rc));
936 list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx);
937 release_kbnode (keyblock);
939 while (ctx && !getkey_next (ctrl, ctx, NULL, &keyblock));
940 getkey_end (ctrl, ctx);
945 if (opt.check_sigs && !opt.with_colons)
946 print_signature_stats (&listctx);
948 keylist_context_release (&listctx);
953 print_key_data (PKT_public_key * pk)
955 int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
958 for (i = 0; i < n; i++)
960 es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
961 mpi_print (es_stdout, pk->pkey[i], 1);
962 es_putc (':', es_stdout);
963 es_putc ('\n', es_stdout);
968 /* Various public key screenings. (Right now just ROCA). With
969 * COLON_MODE set the output is formatted for use in the compliance
970 * field of a colon listing.
973 print_pk_screening (PKT_public_key *pk, int colon_mode)
977 if (is_RSA (pk->pubkey_algo) && pubkey_get_npkey (pk->pubkey_algo))
979 err = screen_key_for_roca (pk->pkey[0]);
982 else if (gpg_err_code (err) == GPG_ERR_TRUE)
985 es_fprintf (es_stdout, colon_mode > 1? " %d":"%d", 6001);
987 es_fprintf (es_stdout,
988 " Screening: ROCA vulnerability detected\n");
990 else if (!colon_mode)
991 es_fprintf (es_stdout, " Screening: [ROCA check failed: %s]\n",
999 print_capabilities (ctrl_t ctrl, PKT_public_key *pk, KBNODE keyblock)
1001 unsigned int use = pk->pubkey_usage;
1004 if (use & PUBKEY_USAGE_ENC)
1005 es_putc ('e', es_stdout);
1007 if (use & PUBKEY_USAGE_SIG)
1009 es_putc ('s', es_stdout);
1010 if (pk->flags.primary)
1012 es_putc ('c', es_stdout);
1013 /* The PUBKEY_USAGE_CERT flag was introduced later and we
1014 used to always print 'c' for a primary key. To avoid any
1015 regression here we better track whether we printed 'c'
1021 if ((use & PUBKEY_USAGE_CERT) && !c_printed)
1022 es_putc ('c', es_stdout);
1024 if ((use & PUBKEY_USAGE_AUTH))
1025 es_putc ('a', es_stdout);
1027 if (use & PUBKEY_USAGE_RENC)
1028 es_putc ('r', es_stdout);
1029 if ((use & PUBKEY_USAGE_TIME))
1030 es_putc ('t', es_stdout);
1031 if ((use & PUBKEY_USAGE_GROUP))
1032 es_putc ('g', es_stdout);
1034 if ((use & PUBKEY_USAGE_UNKNOWN))
1035 es_putc ('?', es_stdout);
1039 /* Figure out the usable capabilities. */
1041 int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
1043 for (k = keyblock; k; k = k->next)
1045 if (k->pkt->pkttype == PKT_PUBLIC_KEY
1046 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1048 pk = k->pkt->pkt.public_key;
1050 if (pk->flags.primary)
1051 disabled = pk_is_disabled (pk);
1053 if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
1055 if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
1057 if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
1060 if (pk->flags.primary)
1063 if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
1065 if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
1071 es_putc ('E', es_stdout);
1073 es_putc ('S', es_stdout);
1075 es_putc ('C', es_stdout);
1077 es_putc ('A', es_stdout);
1079 es_putc ('D', es_stdout);
1082 es_putc (':', es_stdout);
1086 /* FLAGS: 0x01 hashed
1089 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
1094 es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
1096 for (i = 0; i < len; i++)
1098 /* printable ascii other than : and % */
1099 if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
1100 es_fprintf (es_stdout, "%c", buf[i]);
1102 es_fprintf (es_stdout, "%%%02X", buf[i]);
1105 es_fprintf (es_stdout, "\n");
1110 print_subpackets_colon (PKT_signature * sig)
1114 log_assert (opt.show_subpackets);
1116 for (i = opt.show_subpackets; *i; i++)
1124 while ((p = enum_sig_subpkt (sig, 1, *i, &len, &seq, &crit)))
1125 print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
1129 while ((p = enum_sig_subpkt (sig, 0, *i, &len, &seq, &crit)))
1130 print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
1136 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
1143 for (i = 0; i < uid->numattribs; i++)
1145 if (is_status_enabled ())
1147 byte array[MAX_FINGERPRINT_LEN], *p;
1148 char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
1153 fingerprint_from_pk (pk, array, &n);
1156 for (j = 0; j < n; j++, p++)
1157 sprintf (buf + 2 * j, "%02X", *p);
1159 sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
1160 (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
1161 uid->numattribs, (ulong) uid->created,
1162 (ulong) uid->expiredate,
1163 ((uid->flags.primary ? 0x01 : 0) | (uid->flags.revoked ? 0x02 : 0) |
1164 (uid->flags.expired ? 0x04 : 0)));
1165 write_status_text (STATUS_ATTRIBUTE, buf);
1168 es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
1169 es_fflush (attrib_fp);
1174 /* Order two signatures. We first order by keyid and then by creation
1177 cmp_signodes (const void *av, const void *bv)
1179 const kbnode_t an = *(const kbnode_t *)av;
1180 const kbnode_t bn = *(const kbnode_t *)bv;
1181 const PKT_signature *a;
1182 const PKT_signature *b;
1185 /* log_assert (an->pkt->pkttype == PKT_SIGNATURE); */
1186 /* log_assert (bn->pkt->pkttype == PKT_SIGNATURE); */
1188 a = an->pkt->pkt.signature;
1189 b = bn->pkt->pkt.signature;
1191 /* Self-signatures are ordered first. */
1192 if ((an->flag & NODFLG_MARK_B) && !(bn->flag & NODFLG_MARK_B))
1194 if (!(an->flag & NODFLG_MARK_B) && (bn->flag & NODFLG_MARK_B))
1197 /* then the keyids. (which are or course the same for self-sigs). */
1198 i = keyid_cmp (a->keyid, b->keyid);
1202 /* Followed by creation time */
1203 if (a->timestamp > b->timestamp)
1205 if (a->timestamp < b->timestamp)
1208 /* followed by the class in a way that a rev comes first. */
1209 if (a->sig_class > b->sig_class)
1211 if (a->sig_class < b->sig_class)
1214 /* To make the sort stable we compare the entire structure as last resort. */
1215 return memcmp (a, b, sizeof *a);
1219 /* Helper for list_keyblock_print. The caller must have set
1220 * NODFLG_MARK_B to indicate self-signatures. */
1222 list_signature_print (ctrl_t ctrl, kbnode_t keyblock, kbnode_t node,
1223 struct keylist_context *listctx)
1225 /* (extra indentation to keep the diff history short) */
1226 PKT_signature *sig = node->pkt->pkt.signature;
1229 char *reason_text = NULL;
1230 char *reason_comment = NULL;
1231 size_t reason_commentlen;
1232 int reason_code = 0;
1234 if (listctx->check_sigs)
1236 rc = check_key_signature (ctrl, keyblock, node, NULL);
1237 switch (gpg_err_code (rc))
1240 listctx->good_sigs++;
1243 case GPG_ERR_BAD_SIGNATURE:
1244 listctx->inv_sigs++;
1247 case GPG_ERR_NO_PUBKEY:
1248 case GPG_ERR_UNUSABLE_PUBKEY:
1251 case GPG_ERR_DIGEST_ALGO:
1252 case GPG_ERR_PUBKEY_ALGO:
1253 if (!(opt.list_options & LIST_SHOW_UNUSABLE_SIGS))
1262 /* TODO: Make sure a cached sig record here still has
1263 the pk that issued it. See also
1264 keyedit.c:print_and_check_one_sig */
1268 if (!(opt.list_options & LIST_SHOW_UNUSABLE_SIGS)
1269 && (gpg_err_code (openpgp_pk_test_algo (sig->pubkey_algo)
1270 == GPG_ERR_PUBKEY_ALGO)
1271 || gpg_err_code (openpgp_md_test_algo (sig->digest_algo)
1272 == GPG_ERR_DIGEST_ALGO)
1273 || (sig->digest_algo == DIGEST_ALGO_SHA1
1274 && !(node->flag & NODFLG_MARK_B) /*no selfsig*/
1275 && !opt.flags.allow_weak_key_signatures)))
1281 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1282 || sig->sig_class == 0x30)
1285 reason_code = get_revocation_reason (sig, &reason_text,
1287 &reason_commentlen);
1289 else if ((sig->sig_class & ~3) == 0x10)
1291 else if (sig->sig_class == 0x18)
1293 else if (sig->sig_class == 0x1F)
1297 es_fprintf (es_stdout, "sig "
1298 "[unexpected signature class 0x%02x]\n",
1303 es_fputs (sigstr, es_stdout);
1304 es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1305 sigrc, (sig->sig_class - 0x10 > 0 &&
1306 sig->sig_class - 0x10 <
1307 4) ? '0' + sig->sig_class - 0x10 : ' ',
1308 sig->flags.exportable ? ' ' : 'L',
1309 sig->flags.revocable ? ' ' : 'R',
1310 sig->flags.policy_url ? 'P' : ' ',
1311 sig->flags.notation ? 'N' : ' ',
1312 sig->flags.expired ? 'X' : ' ',
1313 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1315 sig->trust_depth : ' ', keystr (sig->keyid),
1316 datestr_from_sig (sig));
1317 if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1318 es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1319 es_fprintf (es_stdout, " ");
1321 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1322 else if (sigrc == '?')
1324 else if ((node->flag & NODFLG_MARK_B))
1325 es_fputs (_("[self-signature]"), es_stdout);
1326 else if (!opt.fast_list_mode )
1329 char *p = get_user_id (ctrl, sig->keyid, &n, NULL);
1330 print_utf8_buffer (es_stdout, p, n);
1333 es_putc ('\n', es_stdout);
1335 if (sig->flags.policy_url
1336 && (opt.list_options & LIST_SHOW_POLICY_URLS))
1337 show_policy_url (sig, 3, 0);
1339 if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1340 show_notation (sig, 3, 0,
1342 list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1345 list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1348 if (sig->flags.pref_ks
1349 && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1350 show_keyserver_url (sig, 3, 0);
1352 if (reason_text && (reason_code || reason_comment))
1354 es_fprintf (es_stdout, " %s%s\n",
1355 _("reason for revocation: "), reason_text);
1358 const byte *s, *s_lf;
1362 n = reason_commentlen;
1366 /* We don't want any empty lines, so we skip them. */
1367 for (;n && *s == '\n'; s++, n--)
1371 s_lf = memchr (s, '\n', n);
1372 n_lf = s_lf? s_lf - s : n;
1373 es_fprintf (es_stdout, " %s",
1374 _("revocation comment: "));
1375 es_write_sanitized (es_stdout, s, n_lf, NULL, NULL);
1376 es_putc ('\n', es_stdout);
1377 s += n_lf; n -= n_lf;
1383 xfree (reason_text);
1384 xfree (reason_comment);
1386 /* fixme: check or list other sigs here */
1391 list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
1392 struct keylist_context *listctx)
1399 char *hexgrip = NULL;
1400 char *serialno = NULL;
1402 /* Get the keyid from the keyblock. */
1403 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1406 log_error ("Oops; key lost!\n");
1407 dump_kbnode (keyblock);
1411 pk = node->pkt->pkt.public_key;
1412 mainkid = pk_keyid (pk);
1414 if (secret || opt.with_keygrip)
1416 rc = hexkeygrip_from_pk (pk, &hexgrip);
1418 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1423 /* Encode some info about the secret key in SECRET. */
1424 if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1425 secret = serialno? 3 : 1;
1427 secret = 2; /* Key not found. */
1430 if (!listctx->no_validity)
1431 check_trustdb_stale (ctrl);
1433 /* Print the "pub" line and in KF_NONE mode the fingerprint. */
1434 print_key_line (ctrl, es_stdout, pk, secret);
1437 print_fingerprint (ctrl, NULL, pk, 0);
1439 if (opt.with_keygrip && hexgrip)
1440 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1443 print_card_serialno (serialno);
1445 if (opt.with_key_data)
1446 print_key_data (pk);
1448 if (opt.with_key_screening)
1449 print_pk_screening (pk, 0);
1451 if (opt.with_key_origin
1452 && (pk->keyorg || pk->keyupdate || pk->updateurl))
1454 char updatestr[MK_DATESTR_SIZE];
1456 es_fprintf (es_stdout, " origin=%s last=%s %s",
1457 key_origin_string (pk->keyorg),
1458 mk_datestr (updatestr, sizeof updatestr, pk->keyupdate),
1459 pk->updateurl? "url=":"");
1461 print_utf8_string (es_stdout, pk->updateurl);
1462 es_putc ('\n', es_stdout);
1465 for (node = keyblock; node; node = node->next)
1467 if (is_deleted_kbnode (node))
1470 if (node->pkt->pkttype == PKT_USER_ID)
1472 PKT_user_id *uid = node->pkt->pkt.user_id;
1474 int kl = opt.keyid_format == KF_NONE? 10 : keystrlen ();
1476 if ((uid->flags.expired || uid->flags.revoked)
1477 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
1485 if (attrib_fp && uid->attrib_data != NULL)
1486 dump_attribs (uid, pk);
1488 if ((uid->flags.revoked || uid->flags.expired)
1489 || ((opt.list_options & LIST_SHOW_UID_VALIDITY)
1490 && !listctx->no_validity))
1492 const char *validity;
1494 validity = uid_trust_string_fixed (ctrl, pk, uid);
1495 indent = ((kl + (opt.legacy_list_mode? 9:11))
1496 - atoi (uid_trust_string_fixed (ctrl, NULL, NULL)));
1497 if (indent < 0 || indent > 40)
1500 es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
1504 indent = kl + (opt.legacy_list_mode? 10:12);
1505 es_fprintf (es_stdout, "uid%*s", indent, "");
1508 print_utf8_buffer (es_stdout, uid->name, uid->len);
1509 es_putc ('\n', es_stdout);
1511 if ((opt.list_options & LIST_SHOW_PREF_VERBOSE))
1512 show_preferences (uid, indent+2, 0, 1);
1513 else if ((opt.list_options & LIST_SHOW_PREF))
1514 show_preferences (uid, indent+2, 0, 0);
1516 if (opt.with_wkd_hash)
1518 char *mbox, *hash, *p;
1521 mbox = mailbox_from_userid (uid->name, 0);
1522 if (mbox && (p = strchr (mbox, '@')))
1525 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf,
1526 mbox, strlen (mbox));
1527 hash = zb32_encode (hashbuf, 8*20);
1530 es_fprintf (es_stdout, " %*s%s@%s\n",
1531 indent, "", hash, p);
1538 if (opt.with_key_origin
1539 && (uid->keyorg || uid->keyupdate || uid->updateurl))
1541 char updatestr[MK_DATESTR_SIZE];
1543 es_fprintf (es_stdout, " %*sorigin=%s last=%s %s",
1545 key_origin_string (uid->keyorg),
1546 mk_datestr (updatestr, sizeof updatestr,
1548 uid->updateurl? "url=":"");
1550 print_utf8_string (es_stdout, uid->updateurl);
1551 es_putc ('\n', es_stdout);
1554 if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
1555 show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
1557 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1559 PKT_public_key *pk2 = node->pkt->pkt.public_key;
1561 if ((pk2->flags.revoked || pk2->has_expired)
1562 && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1570 xfree (serialno); serialno = NULL;
1571 xfree (hexgrip); hexgrip = NULL;
1572 if (secret || opt.with_keygrip)
1574 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1576 log_error ("error computing a keygrip: %s\n",
1581 if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1582 secret = serialno? 3 : 1;
1584 secret = 2; /* Key not found. */
1587 /* Print the "sub" line. */
1588 print_key_line (ctrl, es_stdout, pk2, secret);
1589 if (fpr > 1 || opt.with_subkey_fingerprint)
1591 print_fingerprint (ctrl, NULL, pk2, 0);
1593 print_card_serialno (serialno);
1595 if (opt.with_keygrip && hexgrip)
1596 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1597 if (opt.with_key_data)
1598 print_key_data (pk2);
1599 if (opt.with_key_screening)
1600 print_pk_screening (pk2, 0);
1602 else if (opt.list_sigs
1603 && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1606 unsigned int sigcount = 0;
1610 for (n=node; n && n->pkt->pkttype == PKT_SIGNATURE; n = n->next)
1612 sigarray = xcalloc (sigcount, sizeof *sigarray);
1615 for (n=node; n && n->pkt->pkttype == PKT_SIGNATURE; n = n->next)
1617 if (keyid_eq (mainkid, n->pkt->pkt.signature->keyid))
1618 n->flag |= NODFLG_MARK_B; /* Is a self-sig. */
1620 n->flag &= ~NODFLG_MARK_B;
1622 sigarray[sigcount++] = node = n;
1624 /* Note that NODE is now at the last signature. */
1626 if ((opt.list_options & LIST_SORT_SIGS))
1627 qsort (sigarray, sigcount, sizeof *sigarray, cmp_signodes);
1629 for (idx=0; idx < sigcount; idx++)
1630 list_signature_print (ctrl, keyblock, sigarray[idx], listctx);
1634 es_putc ('\n', es_stdout);
1640 /* Do a simple key listing printing only the fingerprint and the mail
1641 * address of valid keys. */
1643 list_keyblock_simple (ctrl_t ctrl, kbnode_t keyblock)
1648 char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1653 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1656 log_error ("Oops; key lost!\n");
1657 dump_kbnode (keyblock);
1660 hexfingerprint (node->pkt->pkt.public_key, hexfpr, sizeof hexfpr);
1662 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1664 if (node->pkt->pkttype == PKT_USER_ID)
1666 PKT_user_id *uid = node->pkt->pkt.user_id;
1668 if (uid->attrib_data)
1671 if (uid->flags.expired || uid->flags.revoked)
1674 mbox = mailbox_from_userid (uid->name, 0);
1677 ec = gpg_err_code_from_syserror ();
1678 if (ec != GPG_ERR_EINVAL)
1679 log_error ("error getting mailbox from user-id: %s\n",
1683 es_fprintf (es_stdout, "%s %s\n", hexfpr, mbox);
1691 print_revokers (estream_t fp, PKT_public_key * pk)
1693 /* print the revoker record */
1694 if (!pk->revkey && pk->numrevkeys)
1700 for (i = 0; i < pk->numrevkeys; i++)
1704 es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1705 p = pk->revkey[i].fpr;
1706 for (j = 0; j < pk->revkey[i].fprlen; j++, p++)
1707 es_fprintf (fp, "%02X", *p);
1708 es_fprintf (fp, ":%02x%s:\n",
1709 pk->revkey[i].class,
1710 (pk->revkey[i].class & 0x40) ? "s" : "");
1716 /* Print the compliance flags to field 18. PK is the public key.
1717 * KEYLENGTH is the length of the key in bits and CURVENAME is either
1718 * NULL or the name of the curve. The latter two args are here
1719 * merely because the caller has already computed them. */
1721 print_compliance_flags (PKT_public_key *pk,
1722 unsigned int keylength, const char *curvename)
1727 keylength = nbits_from_pk (pk);
1729 if (pk->version == 5)
1731 es_fputs (gnupg_status_compliance_flag (CO_GNUPG), es_stdout);
1734 if (gnupg_pk_is_compliant (CO_DE_VS, pk->pubkey_algo, 0, pk->pkey,
1735 keylength, curvename))
1737 es_fprintf (es_stdout, any ? " %s" : "%s",
1738 gnupg_status_compliance_flag (CO_DE_VS));
1742 if (opt.with_key_screening)
1743 print_pk_screening (pk, 1+any);
1747 /* List a key in colon mode. If SECRET is true this is a secret key
1748 record (i.e. requested via --list-secret-key). If HAS_SECRET a
1749 secret key is available even if SECRET is not set. */
1751 list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
1752 int secret, int has_secret)
1759 int trustletter = 0;
1760 int trustletter_print;
1761 int ownertrust_print;
1764 char *hexgrip_buffer = NULL;
1765 const char *hexgrip = NULL;
1766 char *serialno = NULL;
1768 unsigned int keylength;
1770 const char *curvename = NULL;
1772 /* Get the keyid from the keyblock. */
1773 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1776 log_error ("Oops; key lost!\n");
1777 dump_kbnode (keyblock);
1781 pk = node->pkt->pkt.public_key;
1782 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1784 rc = hexkeygrip_from_pk (pk, &hexgrip_buffer);
1786 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1787 /* In the error case we print an empty string so that we have a
1788 * "grp" record for each primary and subkey - even if it is
1789 * empty. This may help to prevent sync problems. */
1790 hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1793 if ((secret || has_secret)
1794 && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1795 stubkey = 1; /* Key not found. */
1797 keyid_from_pk (pk, keyid);
1798 if (!pk->flags.valid)
1799 trustletter_print = 'i';
1800 else if (pk->flags.revoked)
1801 trustletter_print = 'r';
1802 else if (pk->has_expired)
1803 trustletter_print = 'e';
1804 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1805 trustletter_print = 0;
1808 trustletter = get_validity_info (ctrl, keyblock, pk, NULL);
1809 if (trustletter == 'u')
1811 trustletter_print = trustletter;
1814 if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1815 ownertrust_print = get_ownertrust_info (ctrl, pk, 0);
1817 ownertrust_print = 0;
1819 keylength = nbits_from_pk (pk);
1821 es_fputs (secret? "sec:":"pub:", es_stdout);
1822 if (trustletter_print)
1823 es_putc (trustletter_print, es_stdout);
1824 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1827 (ulong) keyid[0], (ulong) keyid[1],
1828 colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1830 if (ownertrust_print)
1831 es_putc (ownertrust_print, es_stdout);
1832 es_putc (':', es_stdout);
1834 es_putc (':', es_stdout);
1835 es_putc (':', es_stdout);
1836 print_capabilities (ctrl, pk, keyblock);
1837 es_putc (':', es_stdout); /* End of field 13. */
1838 es_putc (':', es_stdout); /* End of field 14. */
1839 if (secret || has_secret)
1842 es_putc ('#', es_stdout);
1844 es_fputs (serialno, es_stdout);
1845 else if (has_secret)
1846 es_putc ('+', es_stdout);
1848 es_putc (':', es_stdout); /* End of field 15. */
1849 es_putc (':', es_stdout); /* End of field 16. */
1850 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1851 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1852 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1854 curve = openpgp_oid_to_str (pk->pkey[0]);
1855 curvename = openpgp_oid_to_curve (curve, 0);
1858 es_fputs (curvename, es_stdout);
1860 es_putc (':', es_stdout); /* End of field 17. */
1861 print_compliance_flags (pk, keylength, curvename);
1862 es_putc (':', es_stdout); /* End of field 18 (compliance). */
1864 es_fputs (colon_strtime (pk->keyupdate), es_stdout);
1865 es_putc (':', es_stdout); /* End of field 19 (last_update). */
1866 es_fprintf (es_stdout, "%d%s", pk->keyorg, pk->updateurl? " ":"");
1868 es_write_sanitized (es_stdout, pk->updateurl, strlen (pk->updateurl),
1870 es_putc (':', es_stdout); /* End of field 20 (origin). */
1871 es_putc ('\n', es_stdout);
1873 print_revokers (es_stdout, pk);
1874 print_fingerprint (ctrl, NULL, pk, 0);
1876 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1877 if (opt.with_key_data)
1878 print_key_data (pk);
1880 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1882 if (node->pkt->pkttype == PKT_USER_ID)
1884 PKT_user_id *uid = node->pkt->pkt.user_id;
1887 if (attrib_fp && uid->attrib_data != NULL)
1888 dump_attribs (uid, pk);
1890 if (uid->flags.revoked)
1892 else if (uid->flags.expired)
1894 else if (opt.no_expensive_trust_checks)
1899 uid_validity = get_validity_info (ctrl, keyblock, pk, uid);
1901 es_fputs (uid->attrib_data? "uat:":"uid:", es_stdout);
1903 es_putc (uid_validity, es_stdout);
1904 es_fputs ("::::", es_stdout);
1906 es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1907 es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1909 namehash_from_uid (uid);
1911 for (i = 0; i < 20; i++)
1912 es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1914 es_fprintf (es_stdout, "::");
1916 if (uid->attrib_data)
1917 es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1919 es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1920 es_fputs (":::::::::", es_stdout);
1922 es_fputs (colon_strtime (uid->keyupdate), es_stdout);
1923 es_putc (':', es_stdout); /* End of field 19 (last_update). */
1924 es_fprintf (es_stdout, "%d%s", uid->keyorg, uid->updateurl? " ":"");
1926 es_write_sanitized (es_stdout,
1927 uid->updateurl, strlen (uid->updateurl),
1929 es_putc (':', es_stdout); /* End of field 20 (origin). */
1930 es_putc ('\n', es_stdout);
1932 if (!uid->attrib_data && opt.with_tofu_info
1933 && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP))
1935 /* Print a "tfs" record. */
1936 tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name);
1940 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1943 PKT_public_key *pk2;
1944 int need_hexgrip = !!hexgrip;
1946 pk2 = node->pkt->pkt.public_key;
1947 xfree (hexgrip_buffer); hexgrip_buffer = NULL; hexgrip = NULL;
1948 xfree (serialno); serialno = NULL;
1950 || secret || has_secret || opt.with_keygrip || opt.with_key_data)
1952 rc = hexkeygrip_from_pk (pk2, &hexgrip_buffer);
1954 log_error ("error computing a keygrip: %s\n",
1956 hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1959 if ((secret||has_secret)
1960 && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1961 stubkey = 1; /* Key not found. */
1963 keyid_from_pk (pk2, keyid2);
1964 es_fputs (secret? "ssb:":"sub:", es_stdout);
1965 if (!pk2->flags.valid)
1966 es_putc ('i', es_stdout);
1967 else if (pk2->flags.revoked)
1968 es_putc ('r', es_stdout);
1969 else if (pk2->has_expired)
1970 es_putc ('e', es_stdout);
1971 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1975 /* TRUSTLETTER should always be defined here. */
1977 es_fprintf (es_stdout, "%c", trustletter);
1979 keylength = nbits_from_pk (pk2);
1980 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1983 (ulong) keyid2[0], (ulong) keyid2[1],
1984 colon_datestr_from_pk (pk2),
1985 colon_strtime (pk2->expiredate));
1986 print_capabilities (ctrl, pk2, NULL);
1987 es_putc (':', es_stdout); /* End of field 13. */
1988 es_putc (':', es_stdout); /* End of field 14. */
1989 if (secret || has_secret)
1992 es_putc ('#', es_stdout);
1994 es_fputs (serialno, es_stdout);
1995 else if (has_secret)
1996 es_putc ('+', es_stdout);
1998 es_putc (':', es_stdout); /* End of field 15. */
1999 es_putc (':', es_stdout); /* End of field 16. */
2000 if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
2001 || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
2002 || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
2005 curve = openpgp_oid_to_str (pk2->pkey[0]);
2006 curvename = openpgp_oid_to_curve (curve, 0);
2009 es_fputs (curvename, es_stdout);
2011 es_putc (':', es_stdout); /* End of field 17. */
2012 print_compliance_flags (pk2, keylength, curvename);
2013 es_putc (':', es_stdout); /* End of field 18. */
2014 es_putc ('\n', es_stdout);
2015 print_fingerprint (ctrl, NULL, pk2, 0);
2017 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
2018 if (opt.with_key_data)
2019 print_key_data (pk2);
2021 else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
2023 PKT_signature *sig = node->pkt->pkt.signature;
2024 int sigrc, fprokay = 0;
2027 byte fparray[MAX_FINGERPRINT_LEN];
2030 char *issuer_fpr = NULL;
2031 char *reason_text = NULL;
2032 char *reason_comment = NULL;
2033 size_t reason_commentlen;
2034 int reason_code = 0; /* Init to silence compiler warning. */
2036 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
2037 || sig->sig_class == 0x30)
2040 reason_code = get_revocation_reason (sig, &reason_text,
2042 &reason_commentlen);
2044 else if ((sig->sig_class & ~3) == 0x10)
2046 else if (sig->sig_class == 0x18)
2048 else if (sig->sig_class == 0x1F)
2052 es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
2053 sig->sig_class, sig->flags.exportable ? 'x' : 'l');
2059 PKT_public_key *signer_pk = NULL;
2061 es_fflush (es_stdout);
2062 if (opt.no_sig_cache)
2063 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
2065 rc = check_key_signature2 (ctrl, keyblock, node, NULL, signer_pk,
2067 switch (gpg_err_code (rc))
2072 case GPG_ERR_BAD_SIGNATURE:
2075 case GPG_ERR_NO_PUBKEY:
2076 case GPG_ERR_UNUSABLE_PUBKEY:
2084 if (opt.no_sig_cache)
2088 fingerprint_from_pk (signer_pk, fparray, &fplen);
2091 free_public_key (signer_pk);
2097 sigrc = ' '; /* Note the fix-up below in --list-sigs mode. */
2100 if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
2103 siguid = get_user_id (ctrl, sig->keyid, &siguidlen, &nouid);
2104 if (!opt.check_sigs && nouid)
2105 sigrc = '?'; /* No key in local keyring. */
2114 es_fputs (sigstr, es_stdout);
2115 es_putc (':', es_stdout);
2117 es_putc (sigrc, es_stdout);
2118 es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
2119 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
2120 colon_datestr_from_sig (sig),
2121 colon_expirestr_from_sig (sig));
2123 if (sig->trust_depth || sig->trust_value)
2124 es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
2125 es_fprintf (es_stdout, ":");
2127 if (sig->trust_regexp)
2128 es_write_sanitized (es_stdout, sig->trust_regexp,
2129 strlen (sig->trust_regexp), ":", NULL);
2130 es_fprintf (es_stdout, ":");
2133 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
2135 es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
2137 es_fprintf (es_stdout, ":%02x%c", sig->sig_class,
2138 sig->flags.exportable ? 'x' : 'l');
2140 es_fprintf (es_stdout, ",%02x", reason_code);
2141 es_fputs ("::", es_stdout);
2143 if (opt.no_sig_cache && opt.check_sigs && fprokay)
2145 for (i = 0; i < fplen; i++)
2146 es_fprintf (es_stdout, "%02X", fparray[i]);
2148 else if ((issuer_fpr = issuer_fpr_string (sig)))
2149 es_fputs (issuer_fpr, es_stdout);
2151 es_fprintf (es_stdout, ":::%d:", sig->digest_algo);
2155 es_fputs ("::::", es_stdout);
2156 es_write_sanitized (es_stdout, reason_comment, reason_commentlen,
2158 es_putc (':', es_stdout);
2160 es_putc ('\n', es_stdout);
2162 if (opt.show_subpackets)
2163 print_subpackets_colon (sig);
2165 /* fixme: check or list other sigs here */
2166 xfree (reason_text);
2167 xfree (reason_comment);
2174 xfree (hexgrip_buffer);
2179 * Reorder the keyblock so that the primary user ID (and not attribute
2180 * packet) comes first. Fixme: Replace this by a generic sort
2183 do_reorder_keyblock (KBNODE keyblock, int attr)
2185 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
2188 for (node = keyblock; node; primary0 = node, node = node->next)
2190 if (node->pkt->pkttype == PKT_USER_ID &&
2191 ((attr && node->pkt->pkt.user_id->attrib_data) ||
2192 (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
2193 node->pkt->pkt.user_id->flags.primary)
2195 primary = primary2 = node;
2196 for (node = node->next; node; primary2 = node, node = node->next)
2198 if (node->pkt->pkttype == PKT_USER_ID
2199 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
2200 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
2209 return; /* No primary key flag found (should not happen). */
2211 for (last = NULL, node = keyblock; node; last = node, node = node->next)
2213 if (node->pkt->pkttype == PKT_USER_ID)
2217 log_assert (last); /* The user ID is never the first packet. */
2218 log_assert (primary0); /* Ditto (this is the node before primary). */
2219 if (node == primary)
2220 return; /* Already the first one. */
2222 last->next = primary;
2223 primary0->next = primary2->next;
2224 primary2->next = node;
2228 reorder_keyblock (KBNODE keyblock)
2230 do_reorder_keyblock (keyblock, 1);
2231 do_reorder_keyblock (keyblock, 0);
2236 list_keyblock (ctrl_t ctrl,
2237 KBNODE keyblock, int secret, int has_secret, int fpr,
2238 struct keylist_context *listctx)
2240 reorder_keyblock (keyblock);
2242 if (list_filter.selkey)
2245 struct impex_filter_parm_s parm;
2248 for (parm.node = keyblock; parm.node; parm.node = parm.node->next)
2250 if (recsel_select (list_filter.selkey, impex_filter_getval, &parm))
2257 return; /* Skip this one. */
2260 if (opt.with_colons)
2261 list_keyblock_colon (ctrl, keyblock, secret, has_secret);
2262 else if ((opt.list_options & LIST_SHOW_ONLY_FPR_MBOX))
2264 if (!listctx->no_validity)
2265 check_trustdb_stale (ctrl);
2266 list_keyblock_simple (ctrl, keyblock);
2269 list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
2272 es_fflush (es_stdout);
2276 /* Public function used by keygen to list a keyblock. If NO_VALIDITY
2277 * is set the validity of a key is never shown. */
2279 list_keyblock_direct (ctrl_t ctrl,
2280 kbnode_t keyblock, int secret, int has_secret, int fpr,
2283 struct keylist_context listctx;
2285 memset (&listctx, 0, sizeof (listctx));
2286 listctx.no_validity = !!no_validity;
2287 list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
2288 keylist_context_release (&listctx);
2292 /* Print an hex digit in ICAO spelling. */
2294 print_icao_hexdigit (estream_t fp, int c)
2296 static const char *list[16] = {
2297 "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
2298 "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
2301 tty_fprintf (fp, "%s", list[c&15]);
2306 * Function to print the finperprint.
2307 * mode 0: as used in key listings, opt.with_colons is honored
2308 * 1: print using log_info ()
2309 * 2: direct use of tty
2310 * 3: direct use of tty but only primary key.
2311 * 4: direct use of tty but only subkey.
2312 * 10: Same as 0 but with_colons etc is ignored.
2313 * 20: Same as 0 but using a compact format.
2315 * Modes 1 and 2 will try and print both subkey and primary key
2316 * fingerprints. A MODE with bit 7 set is used internally. If
2317 * OVERRIDE_FP is not NULL that stream will be used in 0 instead
2318 * of es_stdout or instead of the TTY in modes 2 and 3.
2321 print_fingerprint (ctrl_t ctrl, estream_t override_fp,
2322 PKT_public_key *pk, int mode)
2324 char hexfpr[2*MAX_FINGERPRINT_LEN+1];
2330 int with_colons = opt.with_colons;
2331 int with_icao = opt.with_icao_spelling;
2340 else if (mode == 20)
2347 if (!opt.fingerprint && !opt.with_fingerprint
2348 && opt.with_subkey_fingerprint)
2351 if (pk->main_keyid[0] == pk->keyid[0]
2352 && pk->main_keyid[1] == pk->keyid[1])
2355 /* Just to be safe */
2356 if ((mode & 0x80) && !primary)
2358 log_error ("primary key is not really primary!\n");
2364 if (!primary && (mode == 1 || mode == 2))
2366 PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
2367 get_pubkey (ctrl, primary_pk, pk->main_keyid);
2368 print_fingerprint (ctrl, override_fp, primary_pk, (mode | 0x80));
2369 free_public_key (primary_pk);
2374 fp = log_get_stream ();
2376 text = _("Primary key fingerprint:");
2378 text = _(" Subkey fingerprint:");
2382 fp = override_fp; /* Use tty or given stream. */
2384 /* TRANSLATORS: this should fit into 24 bytes so that the
2385 * fingerprint data is properly aligned with the user ID */
2386 text = _(" Primary key fingerprint:");
2388 text = _(" Subkey fingerprint:");
2392 fp = override_fp; /* Use tty or given stream. */
2393 text = _(" Key fingerprint =");
2397 fp = override_fp; /* Use tty or given stream. */
2398 text = _(" Subkey fingerprint:");
2402 fp = override_fp? override_fp : es_stdout;
2403 if (opt.keyid_format == KF_NONE)
2405 text = " "; /* To indent ICAO spelling. */
2409 text = _(" Key fingerprint =");
2412 hexfingerprint (pk, hexfpr, sizeof hexfpr);
2413 if (with_colons && !mode)
2415 es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
2417 else if (compact && !opt.fingerprint && !opt.with_fingerprint)
2419 tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
2423 char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
2424 format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
2426 tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
2428 tty_fprintf (fp, "%s %s", text, fmtfpr);
2430 tty_fprintf (fp, "\n");
2431 if (!with_colons && with_icao)
2434 tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
2435 for (i = 0, p = hexfpr; *p; i++, p++)
2440 tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
2442 tty_fprintf (fp, " ");
2444 tty_fprintf (fp, " ");
2445 print_icao_hexdigit (fp, xtoi_1 (p));
2447 tty_fprintf (fp, "\"\n");
2451 /* Print the serial number of an OpenPGP card if available. */
2453 print_card_serialno (const char *serialno)
2457 if (opt.with_colons)
2458 return; /* Handled elsewhere. */
2460 es_fputs (_(" Card serial no. ="), es_stdout);
2461 es_putc (' ', es_stdout);
2462 if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
2464 /* This is an OpenPGP card. Print the relevant part. */
2465 /* Example: D2760001240101010001000003470000 */
2467 es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
2470 es_fputs (serialno, es_stdout);
2471 es_putc ('\n', es_stdout);
2475 /* Print a public or secret (sub)key line. Example:
2477 * pub dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
2478 * 80615870F5BAD690333686D0F2AD85AC1E42B367
2480 * pub rsa2048 2017-12-31 [SC] [expires: 2028-12-31]
2481 * 80615870F5BAD690333686D0F2AD85AC1E42B3671122334455
2483 * Some global options may result in a different output format. If
2484 * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
2485 * depending on the value a flag character is shown:
2487 * 1 := ' ' Regular secret key
2488 * 2 := '#' Stub secret key
2489 * 3 := '>' Secret key is on a token.
2492 print_key_line (ctrl_t ctrl, estream_t fp, PKT_public_key *pk, int secret)
2494 char pkstrbuf[PUBKEY_STRING_SIZE];
2496 tty_fprintf (fp, "%s%c %s",
2497 pk->flags.primary? (secret? "sec":"pub")
2498 /**/ : (secret? "ssb":"sub"),
2499 secret == 2? '#' : secret == 3? '>' : ' ',
2500 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
2501 if (opt.keyid_format != KF_NONE)
2502 tty_fprintf (fp, "/%s", keystr_from_pk (pk));
2503 tty_fprintf (fp, " %s", datestr_from_pk (pk));
2505 if (pk->flags.primary
2506 && !(openpgp_pk_algo_usage (pk->pubkey_algo)
2507 & (PUBKEY_USAGE_CERT| PUBKEY_USAGE_SIG|PUBKEY_USAGE_AUTH)))
2509 /* A primary key which is really not capable to sign. */
2510 tty_fprintf (fp, " [INVALID_ALGO]");
2512 else if ((opt.list_options & LIST_SHOW_USAGE))
2514 tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
2517 if (pk->flags.revoked)
2519 tty_fprintf (fp, " [");
2520 tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
2521 tty_fprintf (fp, "]");
2523 else if (pk->has_expired)
2525 tty_fprintf (fp, " [");
2526 tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
2527 tty_fprintf (fp, "]");
2529 else if (pk->expiredate)
2531 tty_fprintf (fp, " [");
2532 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
2533 tty_fprintf (fp, "]");
2537 /* I need to think about this some more. It's easy enough to
2538 include, but it looks sort of confusing in the listing... */
2539 if (opt.list_options & LIST_SHOW_VALIDITY)
2541 int validity = get_validity (ctrl, pk, NULL, NULL, 0);
2542 tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
2546 if (pk->pubkey_algo >= 100)
2547 tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
2549 tty_fprintf (fp, "\n");
2551 /* if the user hasn't explicitly asked for human-readable
2552 fingerprints, show compact fpr of primary key: */
2553 if (pk->flags.primary &&
2554 !opt.fingerprint && !opt.with_fingerprint)
2555 print_fingerprint (ctrl, fp, pk, 20);
2560 set_attrib_fd (int fd)
2562 static int last_fd = -1;
2564 if (fd != -1 && last_fd == fd)
2567 /* Fixme: Do we need to check for the log stream here? */
2568 if (attrib_fp && attrib_fp != log_get_stream ())
2569 es_fclose (attrib_fp);
2574 if (! gnupg_fd_valid (fd))
2575 log_fatal ("attribute-fd is invalid: %s\n", strerror (errno));
2577 #ifdef HAVE_DOSISH_SYSTEM
2578 setmode (fd, O_BINARY);
2581 attrib_fp = es_stdout;
2583 attrib_fp = es_stderr;
2585 attrib_fp = es_fdopen (fd, "wb");
2588 log_fatal ("can't open fd %d for attribute output: %s\n",
2589 fd, strerror (errno));