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() */
43 #include "call-agent.h"
44 #include "mbox-util.h"
49 static void list_all (ctrl_t, int, int);
50 static void list_one (ctrl_t ctrl,
51 strlist_t names, int secret, int mark_secret);
52 static void locate_one (ctrl_t ctrl, strlist_t names);
53 static void print_card_serialno (const char *serialno);
55 struct keylist_context
57 int check_sigs; /* If set signatures shall be verified. */
58 int good_sigs; /* Counter used if CHECK_SIGS is set. */
59 int inv_sigs; /* Counter used if CHECK_SIGS is set. */
60 int no_key; /* Counter used if CHECK_SIGS is set. */
61 int oth_err; /* Counter used if CHECK_SIGS is set. */
62 int no_validity; /* Do not show validity. */
66 static void list_keyblock (ctrl_t ctrl,
67 kbnode_t keyblock, int secret, int has_secret,
68 int fpr, struct keylist_context *listctx);
71 /* The stream used to write attribute packets to. */
72 static estream_t attrib_fp;
75 /* Release resources from a keylist context. */
77 keylist_context_release (struct keylist_context *listctx)
79 (void)listctx; /* Nothing to release. */
83 /* List the keys. If list is NULL, all available keys are listed.
84 With LOCATE_MODE set the locate algorithm is used to find a
87 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
89 #ifndef NO_TRUST_MODELS
92 byte trust_model, marginals, completes, cert_depth, min_cert_level;
93 ulong created, nextcheck;
95 read_trust_options (&trust_model, &created, &nextcheck,
96 &marginals, &completes, &cert_depth, &min_cert_level);
98 es_fprintf (es_stdout, "tru:");
100 if (nextcheck && nextcheck <= make_timestamp ())
101 es_fprintf (es_stdout, "o");
102 if (trust_model != opt.trust_model)
103 es_fprintf (es_stdout, "t");
104 if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC
105 || opt.trust_model == TM_TOFU_PGP)
107 if (marginals != opt.marginals_needed)
108 es_fprintf (es_stdout, "m");
109 if (completes != opt.completes_needed)
110 es_fprintf (es_stdout, "c");
111 if (cert_depth != opt.max_cert_depth)
112 es_fprintf (es_stdout, "d");
113 if (min_cert_level != opt.min_cert_level)
114 es_fprintf (es_stdout, "l");
117 es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
119 /* Only show marginals, completes, and cert_depth in the classic
120 or PGP trust models since they are not meaningful
123 if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
124 es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
125 es_fprintf (es_stdout, "\n");
127 #endif /*!NO_TRUST_MODELS*/
129 /* We need to do the stale check right here because it might need to
130 update the keyring while we already have the keyring open. This
131 is very bad for W32 because of a sharing violation. For real OSes
132 it might lead to false results if we are later listing a keyring
133 which is associated with the inode of a deleted file. */
134 check_trustdb_stale (ctrl);
137 tofu_begin_batch_update (ctrl);
141 locate_one (ctrl, list);
143 list_all (ctrl, 0, opt.with_secret);
145 list_one (ctrl, list, 0, opt.with_secret);
148 tofu_end_batch_update (ctrl);
154 secret_key_list (ctrl_t ctrl, strlist_t list)
158 check_trustdb_stale (ctrl);
161 list_all (ctrl, 1, 0);
162 else /* List by user id */
163 list_one (ctrl, list, 1, 0);
167 format_seckey_info (PKT_public_key *pk)
171 char pkstrbuf[PUBKEY_STRING_SIZE];
174 keyid_from_pk (pk, keyid);
175 p = get_user_id_native (keyid);
177 info = xtryasprintf ("sec %s/%s %s %s",
178 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
179 keystr (keyid), datestr_from_pk (pk), p);
187 print_seckey_info (PKT_public_key *pk)
189 char *p = format_seckey_info (pk);
190 tty_printf ("\n%s\n", p);
194 /* Print information about the public key. With FP passed as NULL,
195 the tty output interface is used, otherwise output is directted to
198 print_pubkey_info (estream_t fp, PKT_public_key *pk)
202 char pkstrbuf[PUBKEY_STRING_SIZE];
204 keyid_from_pk (pk, keyid);
206 /* If the pk was chosen by a particular user ID, that is the one to
209 p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
211 p = get_user_id_native (keyid);
215 tty_fprintf (fp, "%s %s/%s %s %s\n",
216 pk->flags.primary? "pub":"sub",
217 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
218 keystr (keyid), datestr_from_pk (pk), p);
223 /* Print basic information of a secret key including the card serial
224 number information. */
225 #ifdef ENABLE_CARD_SUPPORT
227 print_card_key_info (estream_t fp, kbnode_t keyblock)
233 char pkstrbuf[PUBKEY_STRING_SIZE];
236 for (node = keyblock; node; node = node->next)
238 if (node->pkt->pkttype == PKT_PUBLIC_KEY
239 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
242 PKT_public_key *pk = node->pkt->pkt.public_key;
245 rc = hexkeygrip_from_pk (pk, &hexgrip);
248 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
251 else if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
252 s2k_char = serialno? '>':' ';
254 s2k_char = '#'; /* Key not found. */
256 tty_fprintf (fp, "%s%c %s/%s %n",
257 node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
259 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
262 tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
263 tty_fprintf (fp, " ");
264 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
267 tty_fprintf (fp, "\n%*s%s", indent, "", _("card-no: "));
268 if (strlen (serialno) == 32
269 && !strncmp (serialno, "D27600012401", 12))
271 /* This is an OpenPGP card. Print the relevant part. */
272 /* Example: D2760001240101010001000003470000 */
274 tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
277 tty_fprintf (fp, "%s", serialno);
279 tty_fprintf (fp, "\n");
285 #endif /*ENABLE_CARD_SUPPORT*/
288 /* Flags = 0x01 hashed 0x02 critical. */
290 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
295 /* Don't print these. */
299 snprintf (status, sizeof status,
300 "%d %u %u ", type, flags, (unsigned int) len);
302 write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
306 /* Print a policy URL. Allowed values for MODE are:
307 * 0 - print to stdout.
308 * 1 - use log_info and emit status messages.
309 * 2 - emit only status messages.
312 show_policy_url (PKT_signature * sig, int indent, int mode)
317 estream_t fp = mode ? log_get_stream () : es_stdout;
320 enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
327 for (i = 0; i < indent; i++)
331 str = _("Critical signature policy: ");
333 str = _("Signature policy: ");
335 log_info ("%s", str);
337 es_fprintf (fp, "%s", str);
338 print_utf8_buffer (fp, p, len);
339 es_fprintf (fp, "\n");
343 write_status_buffer (STATUS_POLICY_URL, p, len, 0);
350 mode=1 for log_info + status messages
351 mode=2 for status messages only
355 show_keyserver_url (PKT_signature * sig, int indent, int mode)
360 estream_t fp = mode ? log_get_stream () : es_stdout;
363 enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
371 for (i = 0; i < indent; i++)
372 es_putc (' ', es_stdout);
375 str = _("Critical preferred keyserver: ");
377 str = _("Preferred keyserver: ");
379 log_info ("%s", str);
381 es_fprintf (es_stdout, "%s", str);
382 print_utf8_buffer (fp, p, len);
383 es_fprintf (fp, "\n");
387 status_one_subpacket (SIGSUBPKT_PREF_KS, len,
388 (crit ? 0x02 : 0) | 0x01, p);
394 mode=1 for log_info + status messages
395 mode=2 for status messages only
397 Defined bits in WHICH:
398 1 == standard notations
402 show_notation (PKT_signature * sig, int indent, int mode, int which)
404 estream_t fp = mode ? log_get_stream () : es_stdout;
405 notation_t nd, notations;
410 notations = sig_to_notation (sig);
412 /* There may be multiple notations in the same sig. */
413 for (nd = notations; nd; nd = nd->next)
417 int has_at = !!strchr (nd->name, '@');
419 if ((which & 1 && !has_at) || (which & 2 && has_at))
424 for (i = 0; i < indent; i++)
425 es_putc (' ', es_stdout);
427 if (nd->flags.critical)
428 str = _("Critical signature notation: ");
430 str = _("Signature notation: ");
432 log_info ("%s", str);
434 es_fprintf (es_stdout, "%s", str);
435 /* This is all UTF8 */
436 print_utf8_buffer (fp, nd->name, strlen (nd->name));
437 es_fprintf (fp, "=");
438 print_utf8_buffer (fp, nd->value, strlen (nd->value));
439 /* (We need to use log_printf so that the next call to a
440 log function does not insert an extra LF.) */
450 write_status_buffer (STATUS_NOTATION_NAME,
451 nd->name, strlen (nd->name), 0);
452 if (nd->flags.critical || nd->flags.human)
453 write_status_text (STATUS_NOTATION_FLAGS,
454 nd->flags.critical && nd->flags.human? "1 1" :
455 nd->flags.critical? "1 0" : "0 1");
456 write_status_buffer (STATUS_NOTATION_DATA,
457 nd->value, strlen (nd->value), 50);
461 free_notation (notations);
466 print_signature_stats (struct keylist_context *s)
469 return; /* Signature checking was not requested. */
472 log_info (ngettext("%d good signature\n",
473 "%d good signatures\n", s->good_sigs), s->good_sigs);
476 log_info (ngettext("%d bad signature\n",
477 "%d bad signatures\n", s->inv_sigs), s->inv_sigs);
480 log_info (ngettext("%d signature not checked due to a missing key\n",
481 "%d signatures not checked due to missing keys\n",
482 s->no_key), s->no_key);
485 log_info (ngettext("%d signature not checked due to an error\n",
486 "%d signatures not checked due to errors\n",
487 s->oth_err), s->oth_err);
491 /* List all keys. If SECRET is true only secret keys are listed. If
492 MARK_SECRET is true secret keys are indicated in a public key
495 list_all (ctrl_t ctrl, int secret, int mark_secret)
498 KBNODE keyblock = NULL;
501 const char *lastresname, *resname;
502 struct keylist_context listctx;
504 memset (&listctx, 0, sizeof (listctx));
506 listctx.check_sigs = 1;
510 rc = gpg_error_from_syserror ();
512 rc = keydb_search_first (hd);
515 if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
516 log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
523 rc = keydb_get_keyblock (hd, &keyblock);
526 if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
527 continue; /* Skip legacy keys. */
528 log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
532 if (secret || mark_secret)
533 any_secret = !agent_probe_any_secret_key (NULL, keyblock);
537 if (secret && !any_secret)
538 ; /* Secret key listing requested but this isn't one. */
541 if (!opt.with_colons)
543 resname = keydb_get_resource_name (hd);
544 if (lastresname != resname)
548 es_fprintf (es_stdout, "%s\n", resname);
549 for (i = strlen (resname); i; i--)
550 es_putc ('-', es_stdout);
551 es_putc ('\n', es_stdout);
552 lastresname = resname;
555 merge_keys_and_selfsig (keyblock);
556 list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint,
559 release_kbnode (keyblock);
562 while (!(rc = keydb_search_next (hd)));
563 es_fflush (es_stdout);
564 if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
565 log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
566 if (keydb_get_skipped_counter (hd))
567 log_info (ngettext("Warning: %lu key skipped due to its large size\n",
568 "Warning: %lu keys skipped due to their large sizes\n",
569 keydb_get_skipped_counter (hd)),
570 keydb_get_skipped_counter (hd));
572 if (opt.check_sigs && !opt.with_colons)
573 print_signature_stats (&listctx);
576 keylist_context_release (&listctx);
577 release_kbnode (keyblock);
583 list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
586 KBNODE keyblock = NULL;
589 const char *keyring_str = _("Keyring");
591 struct keylist_context listctx;
593 memset (&listctx, 0, sizeof (listctx));
594 if (!secret && opt.check_sigs)
595 listctx.check_sigs = 1;
597 /* fixme: using the bynames function has the disadvantage that we
598 * don't know wether one of the names given was not found. OTOH,
599 * this function has the advantage to list the names in the
600 * sequence as defined by the keyDB and does not duplicate
601 * outputs. A solution could be do test whether all given have
602 * been listed (this needs a way to use the keyDB search
603 * functions) or to have the search function return indicators for
604 * found names. Yet another way is to use the keydb search
605 * facilities directly. */
606 rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
609 log_error ("error reading key: %s\n", gpg_strerror (rc));
616 if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
618 resname = keydb_get_resource_name (get_ctx_handle (ctx));
619 es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
620 for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
621 es_putc ('-', es_stdout);
622 es_putc ('\n', es_stdout);
625 keyblock, secret, mark_secret, opt.fingerprint, &listctx);
626 release_kbnode (keyblock);
628 while (!getkey_next (ctx, NULL, &keyblock));
631 if (opt.check_sigs && !opt.with_colons)
632 print_signature_stats (&listctx);
634 keylist_context_release (&listctx);
639 locate_one (ctrl_t ctrl, strlist_t names)
643 GETKEY_CTX ctx = NULL;
644 KBNODE keyblock = NULL;
645 struct keylist_context listctx;
647 memset (&listctx, 0, sizeof (listctx));
649 listctx.check_sigs = 1;
651 for (sl = names; sl; sl = sl->next)
653 rc = get_best_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, 1, 0);
656 if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
657 log_error ("error reading key: %s\n", gpg_strerror (rc));
658 else if (opt.verbose)
659 log_info (_("key \"%s\" not found: %s\n"),
660 sl->d, gpg_strerror (rc));
666 list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx);
667 release_kbnode (keyblock);
669 while (ctx && !getkey_next (ctx, NULL, &keyblock));
675 if (opt.check_sigs && !opt.with_colons)
676 print_signature_stats (&listctx);
678 keylist_context_release (&listctx);
683 print_key_data (PKT_public_key * pk)
685 int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
688 for (i = 0; i < n; i++)
690 es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
691 mpi_print (es_stdout, pk->pkey[i], 1);
692 es_putc (':', es_stdout);
693 es_putc ('\n', es_stdout);
698 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
700 unsigned int use = pk->pubkey_usage;
703 if (use & PUBKEY_USAGE_ENC)
704 es_putc ('e', es_stdout);
706 if (use & PUBKEY_USAGE_SIG)
708 es_putc ('s', es_stdout);
709 if (pk->flags.primary)
711 es_putc ('c', es_stdout);
712 /* The PUBKEY_USAGE_CERT flag was introduced later and we
713 used to always print 'c' for a primary key. To avoid any
714 regression here we better track whether we printed 'c'
720 if ((use & PUBKEY_USAGE_CERT) && !c_printed)
721 es_putc ('c', es_stdout);
723 if ((use & PUBKEY_USAGE_AUTH))
724 es_putc ('a', es_stdout);
726 if ((use & PUBKEY_USAGE_UNKNOWN))
727 es_putc ('?', es_stdout);
731 /* Figure out the usable capabilities. */
733 int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
735 for (k = keyblock; k; k = k->next)
737 if (k->pkt->pkttype == PKT_PUBLIC_KEY
738 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
740 pk = k->pkt->pkt.public_key;
742 if (pk->flags.primary)
743 disabled = pk_is_disabled (pk);
745 if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
747 if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
749 if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
752 if (pk->flags.primary)
755 if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
757 if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
763 es_putc ('E', es_stdout);
765 es_putc ('S', es_stdout);
767 es_putc ('C', es_stdout);
769 es_putc ('A', es_stdout);
771 es_putc ('D', es_stdout);
774 es_putc (':', es_stdout);
778 /* FLAGS: 0x01 hashed
781 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
786 es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
788 for (i = 0; i < len; i++)
790 /* printable ascii other than : and % */
791 if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
792 es_fprintf (es_stdout, "%c", buf[i]);
794 es_fprintf (es_stdout, "%%%02X", buf[i]);
797 es_fprintf (es_stdout, "\n");
802 print_subpackets_colon (PKT_signature * sig)
806 log_assert (opt.show_subpackets);
808 for (i = opt.show_subpackets; *i; i++)
816 while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
817 print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
821 while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
822 print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
828 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
835 for (i = 0; i < uid->numattribs; i++)
837 if (is_status_enabled ())
839 byte array[MAX_FINGERPRINT_LEN], *p;
840 char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
845 fingerprint_from_pk (pk, array, &n);
848 for (j = 0; j < n; j++, p++)
849 sprintf (buf + 2 * j, "%02X", *p);
851 sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
852 (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
853 uid->numattribs, (ulong) uid->created,
854 (ulong) uid->expiredate,
855 ((uid->is_primary ? 0x01 : 0) | (uid->
856 is_revoked ? 0x02 : 0) |
857 (uid->is_expired ? 0x04 : 0)));
858 write_status_text (STATUS_ATTRIBUTE, buf);
861 es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
862 es_fflush (attrib_fp);
868 list_keyblock_print (ctrl_t ctrl, kbnode_t keyblock, int secret, int fpr,
869 struct keylist_context *listctx)
876 char *hexgrip = NULL;
877 char *serialno = NULL;
879 /* Get the keyid from the keyblock. */
880 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
883 log_error ("Oops; key lost!\n");
884 dump_kbnode (keyblock);
888 pk = node->pkt->pkt.public_key;
890 if (secret || opt.with_keygrip)
892 rc = hexkeygrip_from_pk (pk, &hexgrip);
894 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
899 /* Encode some info about the secret key in SECRET. */
900 if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
901 secret = serialno? 3 : 1;
903 secret = 2; /* Key not found. */
906 if (!listctx->no_validity)
907 check_trustdb_stale (ctrl);
909 /* Print the "pub" line and in KF_NONE mode the fingerprint. */
910 print_key_line (es_stdout, pk, secret);
913 print_fingerprint (NULL, pk, 0);
915 if (opt.with_keygrip && hexgrip)
916 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
919 print_card_serialno (serialno);
921 if (opt.with_key_data)
924 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
926 if (node->pkt->pkttype == PKT_USER_ID)
928 PKT_user_id *uid = node->pkt->pkt.user_id;
930 int kl = opt.keyid_format == KF_NONE? 10 : keystrlen ();
932 if ((uid->is_expired || uid->is_revoked)
933 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
941 if (attrib_fp && uid->attrib_data != NULL)
942 dump_attribs (uid, pk);
944 if ((uid->is_revoked || uid->is_expired)
945 || ((opt.list_options & LIST_SHOW_UID_VALIDITY)
946 && !listctx->no_validity))
948 const char *validity;
950 validity = uid_trust_string_fixed (ctrl, pk, uid);
951 indent = ((kl + (opt.legacy_list_mode? 9:11))
952 - atoi (uid_trust_string_fixed (ctrl, NULL, NULL)));
953 if (indent < 0 || indent > 40)
956 es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
960 indent = kl + (opt.legacy_list_mode? 10:12);
961 es_fprintf (es_stdout, "uid%*s", indent, "");
964 print_utf8_buffer (es_stdout, uid->name, uid->len);
965 es_putc ('\n', es_stdout);
967 if (opt.with_wkd_hash)
969 char *mbox, *hash, *p;
972 mbox = mailbox_from_userid (uid->name);
973 if (mbox && (p = strchr (mbox, '@')))
976 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf,
977 mbox, strlen (mbox));
978 hash = zb32_encode (hashbuf, 8*20);
981 es_fprintf (es_stdout, " %*s%s@%s\n",
982 indent, "", hash, p);
989 if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
990 show_photos (ctrl, uid->attribs, uid->numattribs, pk, uid);
992 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
994 PKT_public_key *pk2 = node->pkt->pkt.public_key;
996 if ((pk2->flags.revoked || pk2->has_expired)
997 && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1005 xfree (serialno); serialno = NULL;
1006 xfree (hexgrip); hexgrip = NULL;
1007 if (secret || opt.with_keygrip)
1009 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1011 log_error ("error computing a keygrip: %s\n",
1016 if (!agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1017 secret = serialno? 3 : 1;
1019 secret = '2'; /* Key not found. */
1022 /* Print the "sub" line. */
1023 print_key_line (es_stdout, pk2, secret);
1024 if (fpr > 1 || opt.with_subkey_fingerprint)
1026 print_fingerprint (NULL, pk2, 0);
1028 print_card_serialno (serialno);
1030 if (opt.with_keygrip && hexgrip)
1031 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1032 if (opt.with_key_data)
1033 print_key_data (pk2);
1035 else if (opt.list_sigs
1036 && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1038 PKT_signature *sig = node->pkt->pkt.signature;
1042 if (listctx->check_sigs)
1044 rc = check_key_signature (keyblock, node, NULL);
1045 switch (gpg_err_code (rc))
1048 listctx->good_sigs++;
1051 case GPG_ERR_BAD_SIGNATURE:
1052 listctx->inv_sigs++;
1055 case GPG_ERR_NO_PUBKEY:
1056 case GPG_ERR_UNUSABLE_PUBKEY:
1065 /* TODO: Make sure a cached sig record here still has
1066 the pk that issued it. See also
1067 keyedit.c:print_and_check_one_sig */
1075 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1076 || sig->sig_class == 0x30)
1078 else if ((sig->sig_class & ~3) == 0x10)
1080 else if (sig->sig_class == 0x18)
1082 else if (sig->sig_class == 0x1F)
1086 es_fprintf (es_stdout, "sig "
1087 "[unexpected signature class 0x%02x]\n",
1092 es_fputs (sigstr, es_stdout);
1093 es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1094 sigrc, (sig->sig_class - 0x10 > 0 &&
1095 sig->sig_class - 0x10 <
1096 4) ? '0' + sig->sig_class - 0x10 : ' ',
1097 sig->flags.exportable ? ' ' : 'L',
1098 sig->flags.revocable ? ' ' : 'R',
1099 sig->flags.policy_url ? 'P' : ' ',
1100 sig->flags.notation ? 'N' : ' ',
1101 sig->flags.expired ? 'X' : ' ',
1102 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1104 sig->trust_depth : ' ', keystr (sig->keyid),
1105 datestr_from_sig (sig));
1106 if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1107 es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1108 es_fprintf (es_stdout, " ");
1110 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1111 else if (sigrc == '?')
1113 else if (!opt.fast_list_mode)
1116 char *p = get_user_id (sig->keyid, &n);
1117 print_utf8_buffer (es_stdout, p, n);
1120 es_putc ('\n', es_stdout);
1122 if (sig->flags.policy_url
1123 && (opt.list_options & LIST_SHOW_POLICY_URLS))
1124 show_policy_url (sig, 3, 0);
1126 if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1127 show_notation (sig, 3, 0,
1129 list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1132 list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1135 if (sig->flags.pref_ks
1136 && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1137 show_keyserver_url (sig, 3, 0);
1139 /* fixme: check or list other sigs here */
1142 es_putc ('\n', es_stdout);
1148 print_revokers (estream_t fp, PKT_public_key * pk)
1150 /* print the revoker record */
1151 if (!pk->revkey && pk->numrevkeys)
1157 for (i = 0; i < pk->numrevkeys; i++)
1161 es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1162 p = pk->revkey[i].fpr;
1163 for (j = 0; j < 20; j++, p++)
1164 es_fprintf (fp, "%02X", *p);
1165 es_fprintf (fp, ":%02x%s:\n",
1166 pk->revkey[i].class,
1167 (pk->revkey[i].class & 0x40) ? "s" : "");
1173 /* List a key in colon mode. If SECRET is true this is a secret key
1174 record (i.e. requested via --list-secret-key). If HAS_SECRET a
1175 secret key is available even if SECRET is not set. */
1177 list_keyblock_colon (ctrl_t ctrl, kbnode_t keyblock,
1178 int secret, int has_secret)
1185 int trustletter = 0;
1186 int trustletter_print;
1187 int ownertrust_print;
1190 char *hexgrip_buffer = NULL;
1191 const char *hexgrip = NULL;
1192 char *serialno = NULL;
1195 /* Get the keyid from the keyblock. */
1196 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1199 log_error ("Oops; key lost!\n");
1200 dump_kbnode (keyblock);
1204 pk = node->pkt->pkt.public_key;
1205 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1207 rc = hexkeygrip_from_pk (pk, &hexgrip_buffer);
1209 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1210 /* In the error case we print an empty string so that we have a
1211 * "grp" record for each and subkey - even if it is empty. This
1212 * may help to prevent sync problems. */
1213 hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1216 if ((secret || has_secret)
1217 && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1218 stubkey = 1; /* Key not found. */
1220 keyid_from_pk (pk, keyid);
1221 if (!pk->flags.valid)
1222 trustletter_print = 'i';
1223 else if (pk->flags.revoked)
1224 trustletter_print = 'r';
1225 else if (pk->has_expired)
1226 trustletter_print = 'e';
1227 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1228 trustletter_print = 0;
1231 trustletter = get_validity_info (ctrl, keyblock, pk, NULL);
1232 if (trustletter == 'u')
1234 trustletter_print = trustletter;
1237 if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1238 ownertrust_print = get_ownertrust_info (pk);
1240 ownertrust_print = 0;
1242 es_fputs (secret? "sec:":"pub:", es_stdout);
1243 if (trustletter_print)
1244 es_putc (trustletter_print, es_stdout);
1245 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1248 (ulong) keyid[0], (ulong) keyid[1],
1249 colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1251 if (ownertrust_print)
1252 es_putc (ownertrust_print, es_stdout);
1253 es_putc (':', es_stdout);
1255 es_putc (':', es_stdout);
1256 es_putc (':', es_stdout);
1257 print_capabilities (pk, keyblock);
1258 es_putc (':', es_stdout); /* End of field 13. */
1259 es_putc (':', es_stdout); /* End of field 14. */
1260 if (secret || has_secret)
1263 es_putc ('#', es_stdout);
1265 es_fputs (serialno, es_stdout);
1266 else if (has_secret)
1267 es_putc ('+', es_stdout);
1269 es_putc (':', es_stdout); /* End of field 15. */
1270 es_putc (':', es_stdout); /* End of field 16. */
1271 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1272 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1273 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1275 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1276 const char *name = openpgp_oid_to_curve (curve, 0);
1279 es_fputs (name, es_stdout);
1282 es_putc (':', es_stdout); /* End of field 17. */
1283 es_putc (':', es_stdout); /* End of field 18. */
1284 es_putc ('\n', es_stdout);
1286 print_revokers (es_stdout, pk);
1287 print_fingerprint (NULL, pk, 0);
1289 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1290 if (opt.with_key_data)
1291 print_key_data (pk);
1293 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1295 if (node->pkt->pkttype == PKT_USER_ID)
1297 PKT_user_id *uid = node->pkt->pkt.user_id;
1300 if (attrib_fp && uid->attrib_data != NULL)
1301 dump_attribs (uid, pk);
1303 if (uid->is_revoked)
1305 else if (uid->is_expired)
1307 else if (opt.no_expensive_trust_checks)
1312 uid_validity = get_validity_info (ctrl, keyblock, pk, uid);
1314 es_fputs (uid->attrib_data? "uat:":"uid:", es_stdout);
1316 es_putc (uid_validity, es_stdout);
1317 es_fputs ("::::", es_stdout);
1319 es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1320 es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1322 namehash_from_uid (uid);
1324 for (i = 0; i < 20; i++)
1325 es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1327 es_fprintf (es_stdout, "::");
1329 if (uid->attrib_data)
1330 es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1332 es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1333 es_putc (':', es_stdout);
1334 es_putc ('\n', es_stdout);
1336 if (!uid->attrib_data && opt.with_tofu_info
1337 && (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP))
1339 /* Print a "tfs" record. */
1340 tofu_write_tfs_record (ctrl, es_stdout, pk, uid->name);
1344 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1347 PKT_public_key *pk2;
1348 int need_hexgrip = !!hexgrip;
1350 pk2 = node->pkt->pkt.public_key;
1351 xfree (hexgrip_buffer); hexgrip_buffer = NULL; hexgrip = NULL;
1352 xfree (serialno); serialno = NULL;
1354 || secret || has_secret || opt.with_keygrip || opt.with_key_data)
1356 rc = hexkeygrip_from_pk (pk2, &hexgrip_buffer);
1358 log_error ("error computing a keygrip: %s\n",
1360 hexgrip = hexgrip_buffer? hexgrip_buffer : "";
1363 if ((secret||has_secret)
1364 && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1365 stubkey = 1; /* Key not found. */
1367 keyid_from_pk (pk2, keyid2);
1368 es_fputs (secret? "ssb:":"sub:", es_stdout);
1369 if (!pk2->flags.valid)
1370 es_putc ('i', es_stdout);
1371 else if (pk2->flags.revoked)
1372 es_putc ('r', es_stdout);
1373 else if (pk2->has_expired)
1374 es_putc ('e', es_stdout);
1375 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1379 /* TRUSTLETTER should always be defined here. */
1381 es_fprintf (es_stdout, "%c", trustletter);
1383 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1384 nbits_from_pk (pk2),
1386 (ulong) keyid2[0], (ulong) keyid2[1],
1387 colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1388 /* fixme: add LID and ownertrust here */
1390 print_capabilities (pk2, NULL);
1391 es_putc (':', es_stdout); /* End of field 13. */
1392 es_putc (':', es_stdout); /* End of field 14. */
1393 if (secret || has_secret)
1396 es_putc ('#', es_stdout);
1398 es_fputs (serialno, es_stdout);
1399 else if (has_secret)
1400 es_putc ('+', es_stdout);
1402 es_putc (':', es_stdout); /* End of field 15. */
1403 es_putc (':', es_stdout); /* End of field 16. */
1404 if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1405 || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1406 || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1408 char *curve = openpgp_oid_to_str (pk2->pkey[0]);
1409 const char *name = openpgp_oid_to_curve (curve, 0);
1412 es_fputs (name, es_stdout);
1415 es_putc (':', es_stdout); /* End of field 17. */
1416 es_putc ('\n', es_stdout);
1417 print_fingerprint (NULL, pk2, 0);
1419 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1420 if (opt.with_key_data)
1421 print_key_data (pk2);
1423 else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1425 PKT_signature *sig = node->pkt->pkt.signature;
1426 int sigrc, fprokay = 0;
1429 byte fparray[MAX_FINGERPRINT_LEN];
1433 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1434 || sig->sig_class == 0x30)
1436 else if ((sig->sig_class & ~3) == 0x10)
1438 else if (sig->sig_class == 0x18)
1440 else if (sig->sig_class == 0x1F)
1444 es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1445 sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1451 PKT_public_key *signer_pk = NULL;
1454 if (opt.no_sig_cache)
1455 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1457 rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1459 switch (gpg_err_code (rc))
1464 case GPG_ERR_BAD_SIGNATURE:
1467 case GPG_ERR_NO_PUBKEY:
1468 case GPG_ERR_UNUSABLE_PUBKEY:
1476 if (opt.no_sig_cache)
1480 fingerprint_from_pk (signer_pk, fparray, &fplen);
1483 free_public_key (signer_pk);
1492 if (sigrc != '%' && sigrc != '?' && !opt.fast_list_mode)
1493 siguid = get_user_id (sig->keyid, &siguidlen);
1501 es_fputs (sigstr, es_stdout);
1502 es_putc (':', es_stdout);
1504 es_putc (sigrc, es_stdout);
1505 es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1506 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1507 colon_datestr_from_sig (sig),
1508 colon_expirestr_from_sig (sig));
1510 if (sig->trust_depth || sig->trust_value)
1511 es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1512 es_fprintf (es_stdout, ":");
1514 if (sig->trust_regexp)
1515 es_write_sanitized (es_stdout, sig->trust_regexp,
1516 strlen (sig->trust_regexp), ":", NULL);
1517 es_fprintf (es_stdout, ":");
1520 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1522 es_write_sanitized (es_stdout, siguid, siguidlen, ":", NULL);
1524 es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1525 sig->flags.exportable ? 'x' : 'l');
1527 if (opt.no_sig_cache && opt.check_sigs && fprokay)
1529 for (i = 0; i < fplen; i++)
1530 es_fprintf (es_stdout, "%02X", fparray[i]);
1533 es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1535 if (opt.show_subpackets)
1536 print_subpackets_colon (sig);
1538 /* fixme: check or list other sigs here */
1543 xfree (hexgrip_buffer);
1548 * Reorder the keyblock so that the primary user ID (and not attribute
1549 * packet) comes first. Fixme: Replace this by a generic sort
1552 do_reorder_keyblock (KBNODE keyblock, int attr)
1554 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1557 for (node = keyblock; node; primary0 = node, node = node->next)
1559 if (node->pkt->pkttype == PKT_USER_ID &&
1560 ((attr && node->pkt->pkt.user_id->attrib_data) ||
1561 (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1562 node->pkt->pkt.user_id->is_primary)
1564 primary = primary2 = node;
1565 for (node = node->next; node; primary2 = node, node = node->next)
1567 if (node->pkt->pkttype == PKT_USER_ID
1568 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1569 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1578 return; /* No primary key flag found (should not happen). */
1580 for (last = NULL, node = keyblock; node; last = node, node = node->next)
1582 if (node->pkt->pkttype == PKT_USER_ID)
1586 log_assert (last); /* The user ID is never the first packet. */
1587 log_assert (primary0); /* Ditto (this is the node before primary). */
1588 if (node == primary)
1589 return; /* Already the first one. */
1591 last->next = primary;
1592 primary0->next = primary2->next;
1593 primary2->next = node;
1597 reorder_keyblock (KBNODE keyblock)
1599 do_reorder_keyblock (keyblock, 1);
1600 do_reorder_keyblock (keyblock, 0);
1604 list_keyblock (ctrl_t ctrl,
1605 KBNODE keyblock, int secret, int has_secret, int fpr,
1606 struct keylist_context *listctx)
1608 reorder_keyblock (keyblock);
1610 if (opt.with_colons)
1611 list_keyblock_colon (ctrl, keyblock, secret, has_secret);
1613 list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
1616 es_fflush (es_stdout);
1620 /* Public function used by keygen to list a keyblock. If NO_VALIDITY
1621 * is set the validity of a key is never shown. */
1623 list_keyblock_direct (ctrl_t ctrl,
1624 kbnode_t keyblock, int secret, int has_secret, int fpr,
1627 struct keylist_context listctx;
1629 memset (&listctx, 0, sizeof (listctx));
1630 listctx.no_validity = !!no_validity;
1631 list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
1632 keylist_context_release (&listctx);
1636 /* Print an hex digit in ICAO spelling. */
1638 print_icao_hexdigit (estream_t fp, int c)
1640 static const char *list[16] = {
1641 "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1642 "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1645 tty_fprintf (fp, "%s", list[c&15]);
1650 * Function to print the finperprint.
1651 * mode 0: as used in key listings, opt.with_colons is honored
1652 * 1: print using log_info ()
1653 * 2: direct use of tty
1654 * 3: direct use of tty but only primary key.
1655 * 4: direct use of tty but only subkey.
1656 * 10: Same as 0 but with_colons etc is ignored.
1657 * 20: Same as 0 but using a compact format.
1659 * Modes 1 and 2 will try and print both subkey and primary key
1660 * fingerprints. A MODE with bit 7 set is used internally. If
1661 * OVERRIDE_FP is not NULL that stream will be used in 0 instead
1662 * of es_stdout or instead of the TTY in modes 2 and 3.
1665 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1667 char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1673 int with_colons = opt.with_colons;
1674 int with_icao = opt.with_icao_spelling;
1683 else if (mode == 20)
1690 if (!opt.fingerprint && !opt.with_fingerprint
1691 && opt.with_subkey_fingerprint)
1694 if (pk->main_keyid[0] == pk->keyid[0]
1695 && pk->main_keyid[1] == pk->keyid[1])
1698 /* Just to be safe */
1699 if ((mode & 0x80) && !primary)
1701 log_error ("primary key is not really primary!\n");
1707 if (!primary && (mode == 1 || mode == 2))
1709 PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1710 get_pubkey (primary_pk, pk->main_keyid);
1711 print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1712 free_public_key (primary_pk);
1717 fp = log_get_stream ();
1719 text = _("Primary key fingerprint:");
1721 text = _(" Subkey fingerprint:");
1725 fp = override_fp; /* Use tty or given stream. */
1727 /* TRANSLATORS: this should fit into 24 bytes so that the
1728 * fingerprint data is properly aligned with the user ID */
1729 text = _(" Primary key fingerprint:");
1731 text = _(" Subkey fingerprint:");
1735 fp = override_fp; /* Use tty or given stream. */
1736 text = _(" Key fingerprint =");
1740 fp = override_fp; /* Use tty or given stream. */
1741 text = _(" Subkey fingerprint:");
1745 fp = override_fp? override_fp : es_stdout;
1746 if (opt.keyid_format == KF_NONE)
1748 text = " "; /* To indent ICAO spelling. */
1752 text = _(" Key fingerprint =");
1755 hexfingerprint (pk, hexfpr, sizeof hexfpr);
1756 if (with_colons && !mode)
1758 es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
1760 else if (compact && !opt.fingerprint && !opt.with_fingerprint)
1762 tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
1766 char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
1767 format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
1769 tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
1771 tty_fprintf (fp, "%s %s", text, fmtfpr);
1773 tty_fprintf (fp, "\n");
1774 if (!with_colons && with_icao)
1777 tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1778 for (i = 0, p = hexfpr; *p; i++, p++)
1783 tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
1785 tty_fprintf (fp, " ");
1787 tty_fprintf (fp, " ");
1788 print_icao_hexdigit (fp, xtoi_1 (p));
1790 tty_fprintf (fp, "\"\n");
1794 /* Print the serial number of an OpenPGP card if available. */
1796 print_card_serialno (const char *serialno)
1800 if (opt.with_colons)
1801 return; /* Handled elsewhere. */
1803 es_fputs (_(" Card serial no. ="), es_stdout);
1804 es_putc (' ', es_stdout);
1805 if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1807 /* This is an OpenPGP card. Print the relevant part. */
1808 /* Example: D2760001240101010001000003470000 */
1810 es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1813 es_fputs (serialno, es_stdout);
1814 es_putc ('\n', es_stdout);
1818 /* Print a public or secret (sub)key line. Example:
1820 * pub dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
1821 * 80615870F5BAD690333686D0F2AD85AC1E42B367
1823 * Some global options may result in a different output format. If
1824 * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
1825 * depending on the value a flag character is shown:
1827 * 1 := ' ' Regular secret key
1828 * 2 := '#' Stub secret key
1829 * 3 := '>' Secret key is on a token.
1832 print_key_line (estream_t fp, PKT_public_key *pk, int secret)
1834 char pkstrbuf[PUBKEY_STRING_SIZE];
1836 tty_fprintf (fp, "%s%c %s",
1837 pk->flags.primary? (secret? "sec":"pub")
1838 /**/ : (secret? "ssb":"sub"),
1839 secret == 2? '#' : secret == 3? '>' : ' ',
1840 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
1841 if (opt.keyid_format != KF_NONE)
1842 tty_fprintf (fp, "/%s", keystr_from_pk (pk));
1843 tty_fprintf (fp, " %s", datestr_from_pk (pk));
1845 if ((opt.list_options & LIST_SHOW_USAGE))
1847 tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
1849 if (pk->flags.revoked)
1851 tty_fprintf (fp, " [");
1852 tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
1853 tty_fprintf (fp, "]");
1855 else if (pk->has_expired)
1857 tty_fprintf (fp, " [");
1858 tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
1859 tty_fprintf (fp, "]");
1861 else if (pk->expiredate)
1863 tty_fprintf (fp, " [");
1864 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
1865 tty_fprintf (fp, "]");
1869 /* I need to think about this some more. It's easy enough to
1870 include, but it looks sort of confusing in the listing... */
1871 if (opt.list_options & LIST_SHOW_VALIDITY)
1873 int validity = get_validity (ctrl, pk, NULL, NULL, 0);
1874 tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
1878 if (pk->pubkey_algo >= 100)
1879 tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
1881 tty_fprintf (fp, "\n");
1883 /* if the user hasn't explicitly asked for human-readable
1884 fingerprints, show compact fpr of primary key: */
1885 if (pk->flags.primary &&
1886 !opt.fingerprint && !opt.with_fingerprint)
1887 print_fingerprint (fp, pk, 20);
1892 set_attrib_fd (int fd)
1894 static int last_fd = -1;
1896 if (fd != -1 && last_fd == fd)
1899 /* Fixme: Do we need to check for the log stream here? */
1900 if (attrib_fp && attrib_fp != log_get_stream ())
1901 es_fclose (attrib_fp);
1906 #ifdef HAVE_DOSISH_SYSTEM
1907 setmode (fd, O_BINARY);
1910 attrib_fp = es_stdout;
1912 attrib_fp = es_stderr;
1914 attrib_fp = es_fdopen (fd, "wb");
1917 log_fatal ("can't open fd %d for attribute output: %s\n",
1918 fd, strerror (errno));