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 <http://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 ();
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 ();
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_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 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);
912 if (fpr && opt.keyid_format != KF_NONE)
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, int fpr)
1185 int trustletter = 0;
1189 char *hexgrip = NULL;
1190 char *serialno = NULL;
1193 /* Get the keyid from the keyblock. */
1194 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1197 log_error ("Oops; key lost!\n");
1198 dump_kbnode (keyblock);
1202 pk = node->pkt->pkt.public_key;
1203 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1205 rc = hexkeygrip_from_pk (pk, &hexgrip);
1207 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1210 if ((secret || has_secret)
1211 && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1212 stubkey = 1; /* Key not found. */
1214 keyid_from_pk (pk, keyid);
1215 es_fputs (secret? "sec:":"pub:", es_stdout);
1216 if (!pk->flags.valid)
1217 es_putc ('i', es_stdout);
1218 else if (pk->flags.revoked)
1219 es_putc ('r', es_stdout);
1220 else if (pk->has_expired)
1221 es_putc ('e', es_stdout);
1222 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1226 trustletter = get_validity_info (ctrl, pk, NULL);
1227 if (trustletter == 'u')
1229 es_putc (trustletter, es_stdout);
1232 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1235 (ulong) keyid[0], (ulong) keyid[1],
1236 colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1238 if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1239 es_putc (get_ownertrust_info (pk), es_stdout);
1240 es_putc (':', es_stdout);
1242 es_putc (':', es_stdout);
1243 es_putc (':', es_stdout);
1244 print_capabilities (pk, keyblock);
1245 es_putc (':', es_stdout); /* End of field 13. */
1246 es_putc (':', es_stdout); /* End of field 14. */
1247 if (secret || has_secret)
1250 es_putc ('#', es_stdout);
1252 es_fputs (serialno, es_stdout);
1253 else if (has_secret)
1254 es_putc ('+', es_stdout);
1256 es_putc (':', es_stdout); /* End of field 15. */
1257 es_putc (':', es_stdout); /* End of field 16. */
1258 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1259 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1260 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1262 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1263 const char *name = openpgp_oid_to_curve (curve, 0);
1266 es_fputs (name, es_stdout);
1269 es_putc (':', es_stdout); /* End of field 17. */
1270 es_putc (':', es_stdout); /* End of field 18. */
1271 es_putc ('\n', es_stdout);
1273 print_revokers (es_stdout, pk);
1275 print_fingerprint (NULL, pk, 0);
1276 if (opt.with_key_data || opt.with_keygrip)
1279 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1280 if (opt.with_key_data)
1281 print_key_data (pk);
1284 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1286 if (node->pkt->pkttype == PKT_USER_ID)
1289 PKT_user_id *uid = node->pkt->pkt.user_id;
1291 if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1292 dump_attribs (node->pkt->pkt.user_id, pk);
1294 * Fixme: We need a valid flag here too
1296 str = uid->attrib_data ? "uat" : "uid";
1297 if (uid->is_revoked)
1298 es_fprintf (es_stdout, "%s:r::::", str);
1299 else if (uid->is_expired)
1300 es_fprintf (es_stdout, "%s:e::::", str);
1301 else if (opt.no_expensive_trust_checks)
1302 es_fprintf (es_stdout, "%s:::::", str);
1308 uid_validity = get_validity_info (ctrl, pk, uid);
1311 es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1314 es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1315 es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1317 namehash_from_uid (uid);
1319 for (i = 0; i < 20; i++)
1320 es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1322 es_fprintf (es_stdout, "::");
1324 if (uid->attrib_data)
1325 es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1327 es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1328 es_fprintf (es_stdout, "::::::::");
1329 if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)
1332 enum tofu_policy policy;
1333 if (! tofu_get_policy (ctrl, pk, uid, &policy)
1334 && policy != TOFU_POLICY_NONE)
1335 es_fprintf (es_stdout, "%s", tofu_policy_str (policy));
1338 es_putc (':', es_stdout);
1339 es_putc ('\n', es_stdout);
1341 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1344 PKT_public_key *pk2;
1346 pk2 = node->pkt->pkt.public_key;
1347 xfree (hexgrip); hexgrip = NULL;
1348 xfree (serialno); serialno = NULL;
1349 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1351 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1353 log_error ("error computing a keygrip: %s\n",
1357 if ((secret||has_secret)
1358 && agent_get_keyinfo (NULL, hexgrip, &serialno, NULL))
1359 stubkey = 1; /* Key not found. */
1361 keyid_from_pk (pk2, keyid2);
1362 es_fputs (secret? "ssb:":"sub:", es_stdout);
1363 if (!pk2->flags.valid)
1364 es_putc ('i', es_stdout);
1365 else if (pk2->flags.revoked)
1366 es_putc ('r', es_stdout);
1367 else if (pk2->has_expired)
1368 es_putc ('e', es_stdout);
1369 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1373 /* TRUSTLETTER should always be defined here. */
1375 es_fprintf (es_stdout, "%c", trustletter);
1377 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1378 nbits_from_pk (pk2),
1380 (ulong) keyid2[0], (ulong) keyid2[1],
1381 colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1382 /* fixme: add LID and ownertrust here */
1384 print_capabilities (pk2, NULL);
1385 es_putc (':', es_stdout); /* End of field 13. */
1386 es_putc (':', es_stdout); /* End of field 14. */
1387 if (secret || has_secret)
1390 es_putc ('#', es_stdout);
1392 es_fputs (serialno, es_stdout);
1393 else if (has_secret)
1394 es_putc ('+', es_stdout);
1396 es_putc (':', es_stdout); /* End of field 15. */
1397 es_putc (':', es_stdout); /* End of field 16. */
1398 if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1399 || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1400 || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1402 char *curve = openpgp_oid_to_str (pk2->pkey[0]);
1403 const char *name = openpgp_oid_to_curve (curve, 0);
1406 es_fputs (name, es_stdout);
1409 es_putc (':', es_stdout); /* End of field 17. */
1410 es_putc ('\n', es_stdout);
1412 print_fingerprint (NULL, pk2, 0);
1413 if (opt.with_key_data || opt.with_keygrip)
1416 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1417 if (opt.with_key_data)
1418 print_key_data (pk2);
1421 else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1423 PKT_signature *sig = node->pkt->pkt.signature;
1424 int sigrc, fprokay = 0;
1427 byte fparray[MAX_FINGERPRINT_LEN];
1429 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1430 || sig->sig_class == 0x30)
1432 else if ((sig->sig_class & ~3) == 0x10)
1434 else if (sig->sig_class == 0x18)
1436 else if (sig->sig_class == 0x1F)
1440 es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1441 sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1447 PKT_public_key *signer_pk = NULL;
1450 if (opt.no_sig_cache)
1451 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1453 rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1455 switch (gpg_err_code (rc))
1460 case GPG_ERR_BAD_SIGNATURE:
1463 case GPG_ERR_NO_PUBKEY:
1464 case GPG_ERR_UNUSABLE_PUBKEY:
1472 if (opt.no_sig_cache)
1476 fingerprint_from_pk (signer_pk, fparray, &fplen);
1479 free_public_key (signer_pk);
1487 es_fputs (sigstr, es_stdout);
1488 es_putc (':', es_stdout);
1490 es_putc (sigrc, es_stdout);
1491 es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1492 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1493 colon_datestr_from_sig (sig),
1494 colon_expirestr_from_sig (sig));
1496 if (sig->trust_depth || sig->trust_value)
1497 es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1498 es_fprintf (es_stdout, ":");
1500 if (sig->trust_regexp)
1501 es_write_sanitized (es_stdout, sig->trust_regexp,
1502 strlen (sig->trust_regexp), ":", NULL);
1503 es_fprintf (es_stdout, ":");
1506 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1507 else if (sigrc == '?')
1509 else if (!opt.fast_list_mode)
1512 p = get_user_id (sig->keyid, &n);
1513 es_write_sanitized (es_stdout, p, n, ":", NULL);
1516 es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1517 sig->flags.exportable ? 'x' : 'l');
1519 if (opt.no_sig_cache && opt.check_sigs && fprokay)
1521 for (i = 0; i < fplen; i++)
1522 es_fprintf (es_stdout, "%02X", fparray[i]);
1525 es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1527 if (opt.show_subpackets)
1528 print_subpackets_colon (sig);
1530 /* fixme: check or list other sigs here */
1539 * Reorder the keyblock so that the primary user ID (and not attribute
1540 * packet) comes first. Fixme: Replace this by a generic sort
1543 do_reorder_keyblock (KBNODE keyblock, int attr)
1545 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1548 for (node = keyblock; node; primary0 = node, node = node->next)
1550 if (node->pkt->pkttype == PKT_USER_ID &&
1551 ((attr && node->pkt->pkt.user_id->attrib_data) ||
1552 (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1553 node->pkt->pkt.user_id->is_primary)
1555 primary = primary2 = node;
1556 for (node = node->next; node; primary2 = node, node = node->next)
1558 if (node->pkt->pkttype == PKT_USER_ID
1559 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1560 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1569 return; /* No primary key flag found (should not happen). */
1571 for (last = NULL, node = keyblock; node; last = node, node = node->next)
1573 if (node->pkt->pkttype == PKT_USER_ID)
1577 log_assert (last); /* The user ID is never the first packet. */
1578 log_assert (primary0); /* Ditto (this is the node before primary). */
1579 if (node == primary)
1580 return; /* Already the first one. */
1582 last->next = primary;
1583 primary0->next = primary2->next;
1584 primary2->next = node;
1588 reorder_keyblock (KBNODE keyblock)
1590 do_reorder_keyblock (keyblock, 1);
1591 do_reorder_keyblock (keyblock, 0);
1595 list_keyblock (ctrl_t ctrl,
1596 KBNODE keyblock, int secret, int has_secret, int fpr,
1597 struct keylist_context *listctx)
1599 reorder_keyblock (keyblock);
1601 if (opt.with_colons)
1602 list_keyblock_colon (ctrl, keyblock, secret, has_secret, fpr);
1604 list_keyblock_print (ctrl, keyblock, secret, fpr, listctx);
1607 es_fflush (es_stdout);
1611 /* Public function used by keygen to list a keyblock. If NO_VALIDITY
1612 * is set the validity of a key is never shown. */
1614 list_keyblock_direct (ctrl_t ctrl,
1615 kbnode_t keyblock, int secret, int has_secret, int fpr,
1618 struct keylist_context listctx;
1620 memset (&listctx, 0, sizeof (listctx));
1621 listctx.no_validity = !!no_validity;
1622 list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
1623 keylist_context_release (&listctx);
1627 /* Print an hex digit in ICAO spelling. */
1629 print_icao_hexdigit (estream_t fp, int c)
1631 static const char *list[16] = {
1632 "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1633 "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1636 tty_fprintf (fp, "%s", list[c&15]);
1641 * Function to print the finperprint.
1642 * mode 0: as used in key listings, opt.with_colons is honored
1643 * 1: print using log_info ()
1644 * 2: direct use of tty
1645 * 3: direct use of tty but only primary key.
1646 * 4: direct use of tty but only subkey.
1647 * 10: Same as 0 but with_colons etc is ignored.
1648 * 20: Same as 0 but using a compact format.
1650 * Modes 1 and 2 will try and print both subkey and primary key
1651 * fingerprints. A MODE with bit 7 set is used internally. If
1652 * OVERRIDE_FP is not NULL that stream will be used in 0 instead
1653 * of es_stdout or instead of the TTY in modes 2 and 3.
1656 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1658 char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1664 int with_colons = opt.with_colons;
1665 int with_icao = opt.with_icao_spelling;
1674 else if (mode == 20)
1681 if (!opt.fingerprint && !opt.with_fingerprint
1682 && opt.with_subkey_fingerprint && opt.keyid_format == KF_NONE)
1685 if (pk->main_keyid[0] == pk->keyid[0]
1686 && pk->main_keyid[1] == pk->keyid[1])
1689 /* Just to be safe */
1690 if ((mode & 0x80) && !primary)
1692 log_error ("primary key is not really primary!\n");
1698 if (!primary && (mode == 1 || mode == 2))
1700 PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1701 get_pubkey (primary_pk, pk->main_keyid);
1702 print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1703 free_public_key (primary_pk);
1708 fp = log_get_stream ();
1710 text = _("Primary key fingerprint:");
1712 text = _(" Subkey fingerprint:");
1716 fp = override_fp; /* Use tty or given stream. */
1718 /* TRANSLATORS: this should fit into 24 bytes so that the
1719 * fingerprint data is properly aligned with the user ID */
1720 text = _(" Primary key fingerprint:");
1722 text = _(" Subkey fingerprint:");
1726 fp = override_fp; /* Use tty or given stream. */
1727 text = _(" Key fingerprint =");
1731 fp = override_fp; /* Use tty or given stream. */
1732 text = _(" Subkey fingerprint:");
1736 fp = override_fp? override_fp : es_stdout;
1737 if (opt.keyid_format == KF_NONE)
1739 text = " "; /* To indent ICAO spelling. */
1743 text = _(" Key fingerprint =");
1746 hexfingerprint (pk, hexfpr, sizeof hexfpr);
1747 if (with_colons && !mode)
1749 es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
1751 else if (compact && !opt.fingerprint && !opt.with_fingerprint)
1753 tty_fprintf (fp, "%*s%s", 6, "", hexfpr);
1757 char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
1758 format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
1760 tty_fprintf (fp, "%*s%s", 6, "", fmtfpr);
1762 tty_fprintf (fp, "%s %s", text, fmtfpr);
1764 tty_fprintf (fp, "\n");
1765 if (!with_colons && with_icao)
1768 tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1769 for (i = 0, p = hexfpr; *p; i++, p++)
1774 tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
1776 tty_fprintf (fp, " ");
1778 tty_fprintf (fp, " ");
1779 print_icao_hexdigit (fp, xtoi_1 (p));
1781 tty_fprintf (fp, "\"\n");
1785 /* Print the serial number of an OpenPGP card if available. */
1787 print_card_serialno (const char *serialno)
1791 if (opt.with_colons)
1792 return; /* Handled elsewhere. */
1794 es_fputs (_(" Card serial no. ="), es_stdout);
1795 es_putc (' ', es_stdout);
1796 if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1798 /* This is an OpenPGP card. Print the relevant part. */
1799 /* Example: D2760001240101010001000003470000 */
1801 es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1804 es_fputs (serialno, es_stdout);
1805 es_putc ('\n', es_stdout);
1809 /* Print a public or secret (sub)key line. Example:
1811 * pub dsa2048 2007-12-31 [SC] [expires: 2018-12-31]
1812 * 80615870F5BAD690333686D0F2AD85AC1E42B367
1814 * Some global options may result in a different output format. If
1815 * SECRET is set, "sec" or "ssb" is used instead of "pub" or "sub" and
1816 * depending on the value a flag character is shown:
1818 * 1 := ' ' Regular secret key
1819 * 2 := '#' Stub secret key
1820 * 3 := '>' Secret key is on a token.
1823 print_key_line (estream_t fp, PKT_public_key *pk, int secret)
1825 char pkstrbuf[PUBKEY_STRING_SIZE];
1827 tty_fprintf (fp, "%s%c %s",
1828 pk->flags.primary? (secret? "sec":"pub")
1829 /**/ : (secret? "ssb":"sub"),
1830 secret == 2? '#' : secret == 3? '>' : ' ',
1831 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf));
1832 if (opt.keyid_format != KF_NONE)
1833 tty_fprintf (fp, "/%s", keystr_from_pk (pk));
1834 tty_fprintf (fp, " %s", datestr_from_pk (pk));
1836 if ((opt.list_options & LIST_SHOW_USAGE))
1838 tty_fprintf (fp, " [%s]", usagestr_from_pk (pk, 0));
1840 if (pk->flags.revoked)
1842 tty_fprintf (fp, " [");
1843 tty_fprintf (fp, _("revoked: %s"), revokestr_from_pk (pk));
1844 tty_fprintf (fp, "]");
1846 else if (pk->has_expired)
1848 tty_fprintf (fp, " [");
1849 tty_fprintf (fp, _("expired: %s"), expirestr_from_pk (pk));
1850 tty_fprintf (fp, "]");
1852 else if (pk->expiredate)
1854 tty_fprintf (fp, " [");
1855 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
1856 tty_fprintf (fp, "]");
1860 /* I need to think about this some more. It's easy enough to
1861 include, but it looks sort of confusing in the listing... */
1862 if (opt.list_options & LIST_SHOW_VALIDITY)
1864 int validity = get_validity (ctrl, pk, NULL, NULL, 0);
1865 tty_fprintf (fp, " [%s]", trust_value_to_string (validity));
1869 if (pk->pubkey_algo >= 100)
1870 tty_fprintf (fp, " [experimental algorithm %d]", pk->pubkey_algo);
1872 tty_fprintf (fp, "\n");
1874 if (pk->flags.primary && opt.keyid_format == KF_NONE)
1875 print_fingerprint (fp, pk, 20);
1880 set_attrib_fd (int fd)
1882 static int last_fd = -1;
1884 if (fd != -1 && last_fd == fd)
1887 /* Fixme: Do we need to check for the log stream here? */
1888 if (attrib_fp && attrib_fp != log_get_stream ())
1889 es_fclose (attrib_fp);
1894 #ifdef HAVE_DOSISH_SYSTEM
1895 setmode (fd, O_BINARY);
1898 attrib_fp = es_stdout;
1900 attrib_fp = es_stderr;
1902 attrib_fp = es_fdopen (fd, "wb");
1905 log_fatal ("can't open fd %d for attribute output: %s\n",
1906 fd, strerror (errno));