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/>.
28 #ifdef HAVE_DOSISH_SYSTEM
29 #include <fcntl.h> /* for setmode() */
44 #include "call-agent.h"
45 #include "mbox-util.h"
50 static void list_all (ctrl_t, int, int);
51 static void list_one (ctrl_t ctrl,
52 strlist_t names, int secret, int mark_secret);
53 static void locate_one (ctrl_t ctrl, strlist_t names);
54 static void print_card_serialno (const char *serialno);
56 struct keylist_context
58 int check_sigs; /* If set signatures shall be verified. */
59 int good_sigs; /* Counter used if CHECK_SIGS is set. */
60 int inv_sigs; /* Counter used if CHECK_SIGS is set. */
61 int no_key; /* Counter used if CHECK_SIGS is set. */
62 int oth_err; /* Counter used if CHECK_SIGS is set. */
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 ();
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 ();
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))
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 struct notation *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 write_status_buffer (STATUS_NOTATION_DATA,
453 nd->value, strlen (nd->value), 50);
457 free_notation (notations);
462 print_signature_stats (struct keylist_context *s)
465 return; /* Signature checking was not requested. */
468 log_info (ngettext("%d good signature\n",
469 "%d good signatures\n", s->good_sigs), s->good_sigs);
472 log_info (ngettext("%d bad signature\n",
473 "%d bad signatures\n", s->inv_sigs), s->inv_sigs);
476 log_info (ngettext("%d signature not checked due to a missing key\n",
477 "%d signatures not checked due to missing keys\n",
478 s->no_key), s->no_key);
481 log_info (ngettext("%d signature not checked due to an error\n",
482 "%d signatures not checked due to errors\n",
483 s->oth_err), s->oth_err);
487 /* List all keys. If SECRET is true only secret keys are listed. If
488 MARK_SECRET is true secret keys are indicated in a public key
491 list_all (ctrl_t ctrl, int secret, int mark_secret)
494 KBNODE keyblock = NULL;
497 const char *lastresname, *resname;
498 struct keylist_context listctx;
500 memset (&listctx, 0, sizeof (listctx));
502 listctx.check_sigs = 1;
506 rc = gpg_error_from_syserror ();
508 rc = keydb_search_first (hd);
511 if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
512 log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
519 rc = keydb_get_keyblock (hd, &keyblock);
522 if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
523 continue; /* Skip legacy keys. */
524 log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
528 if (secret || mark_secret)
529 any_secret = !agent_probe_any_secret_key (NULL, keyblock);
533 if (secret && !any_secret)
534 ; /* Secret key listing requested but this isn't one. */
537 if (!opt.with_colons)
539 resname = keydb_get_resource_name (hd);
540 if (lastresname != resname)
544 es_fprintf (es_stdout, "%s\n", resname);
545 for (i = strlen (resname); i; i--)
546 es_putc ('-', es_stdout);
547 es_putc ('\n', es_stdout);
548 lastresname = resname;
551 merge_keys_and_selfsig (keyblock);
552 list_keyblock (ctrl, keyblock, secret, any_secret, opt.fingerprint,
555 release_kbnode (keyblock);
558 while (!(rc = keydb_search_next (hd)));
559 es_fflush (es_stdout);
560 if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
561 log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
562 if (keydb_get_skipped_counter (hd))
563 log_info (ngettext("Warning: %lu key skipped due to its large size\n",
564 "Warning: %lu keys skipped due to their large sizes\n",
565 keydb_get_skipped_counter (hd)),
566 keydb_get_skipped_counter (hd));
568 if (opt.check_sigs && !opt.with_colons)
569 print_signature_stats (&listctx);
572 keylist_context_release (&listctx);
573 release_kbnode (keyblock);
579 list_one (ctrl_t ctrl, strlist_t names, int secret, int mark_secret)
582 KBNODE keyblock = NULL;
585 const char *keyring_str = _("Keyring");
587 struct keylist_context listctx;
589 memset (&listctx, 0, sizeof (listctx));
590 if (!secret && opt.check_sigs)
591 listctx.check_sigs = 1;
593 /* fixme: using the bynames function has the disadvantage that we
594 * don't know wether one of the names given was not found. OTOH,
595 * this function has the advantage to list the names in the
596 * sequence as defined by the keyDB and does not duplicate
597 * outputs. A solution could be do test whether all given have
598 * been listed (this needs a way to use the keyDB search
599 * functions) or to have the search function return indicators for
600 * found names. Yet another way is to use the keydb search
601 * facilities directly. */
602 rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
605 log_error ("error reading key: %s\n", gpg_strerror (rc));
612 if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
614 resname = keydb_get_resource_name (get_ctx_handle (ctx));
615 es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
616 for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
617 es_putc ('-', es_stdout);
618 es_putc ('\n', es_stdout);
621 keyblock, secret, mark_secret, opt.fingerprint, &listctx);
622 release_kbnode (keyblock);
624 while (!getkey_next (ctx, NULL, &keyblock));
627 if (opt.check_sigs && !opt.with_colons)
628 print_signature_stats (&listctx);
630 keylist_context_release (&listctx);
635 locate_one (ctrl_t ctrl, strlist_t names)
639 GETKEY_CTX ctx = NULL;
640 KBNODE keyblock = NULL;
641 struct keylist_context listctx;
643 memset (&listctx, 0, sizeof (listctx));
645 listctx.check_sigs = 1;
647 for (sl = names; sl; sl = sl->next)
649 rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
652 if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
653 log_error ("error reading key: %s\n", gpg_strerror (rc));
654 else if (opt.verbose)
655 log_info (_("key \"%s\" not found: %s\n"),
656 sl->d, gpg_strerror (rc));
662 list_keyblock (ctrl, keyblock, 0, 0, opt.fingerprint, &listctx);
663 release_kbnode (keyblock);
665 while (ctx && !getkey_next (ctx, NULL, &keyblock));
671 if (opt.check_sigs && !opt.with_colons)
672 print_signature_stats (&listctx);
674 keylist_context_release (&listctx);
679 print_key_data (PKT_public_key * pk)
681 int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
684 for (i = 0; i < n; i++)
686 es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
687 mpi_print (es_stdout, pk->pkey[i], 1);
688 es_putc (':', es_stdout);
689 es_putc ('\n', es_stdout);
694 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
696 unsigned int use = pk->pubkey_usage;
699 if (use & PUBKEY_USAGE_ENC)
700 es_putc ('e', es_stdout);
702 if (use & PUBKEY_USAGE_SIG)
704 es_putc ('s', es_stdout);
705 if (pk->flags.primary)
707 es_putc ('c', es_stdout);
708 /* The PUBKEY_USAGE_CERT flag was introduced later and we
709 used to always print 'c' for a primary key. To avoid any
710 regression here we better track whether we printed 'c'
716 if ((use & PUBKEY_USAGE_CERT) && !c_printed)
717 es_putc ('c', es_stdout);
719 if ((use & PUBKEY_USAGE_AUTH))
720 es_putc ('a', es_stdout);
722 if ((use & PUBKEY_USAGE_UNKNOWN))
723 es_putc ('?', es_stdout);
727 /* Figure out the usable capabilities. */
729 int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
731 for (k = keyblock; k; k = k->next)
733 if (k->pkt->pkttype == PKT_PUBLIC_KEY
734 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
736 pk = k->pkt->pkt.public_key;
738 if (pk->flags.primary)
739 disabled = pk_is_disabled (pk);
741 if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
743 if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
745 if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
748 if (pk->flags.primary)
751 if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
753 if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
759 es_putc ('E', es_stdout);
761 es_putc ('S', es_stdout);
763 es_putc ('C', es_stdout);
765 es_putc ('A', es_stdout);
767 es_putc ('D', es_stdout);
770 es_putc (':', es_stdout);
774 /* FLAGS: 0x01 hashed
777 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
782 es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
784 for (i = 0; i < len; i++)
786 /* printable ascii other than : and % */
787 if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
788 es_fprintf (es_stdout, "%c", buf[i]);
790 es_fprintf (es_stdout, "%%%02X", buf[i]);
793 es_fprintf (es_stdout, "\n");
798 print_subpackets_colon (PKT_signature * sig)
802 assert (opt.show_subpackets);
804 for (i = opt.show_subpackets; *i; i++)
812 while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
813 print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
817 while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
818 print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
824 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
831 for (i = 0; i < uid->numattribs; i++)
833 if (is_status_enabled ())
835 byte array[MAX_FINGERPRINT_LEN], *p;
836 char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
841 fingerprint_from_pk (pk, array, &n);
844 for (j = 0; j < n; j++, p++)
845 sprintf (buf + 2 * j, "%02X", *p);
847 sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
848 (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
849 uid->numattribs, (ulong) uid->created,
850 (ulong) uid->expiredate,
851 ((uid->is_primary ? 0x01 : 0) | (uid->
852 is_revoked ? 0x02 : 0) |
853 (uid->is_expired ? 0x04 : 0)));
854 write_status_text (STATUS_ATTRIBUTE, buf);
857 es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
858 es_fflush (attrib_fp);
863 /* Print IPGP cert records instead of a standard key listing. */
865 list_keyblock_pka (ctrl_t ctrl, kbnode_t keyblock)
870 char pkstrbuf[PUBKEY_STRING_SIZE];
872 char *hexkeyblock = NULL;
873 unsigned int hexkeyblocklen = 0; /* Init to avoid -Wmaybe-uninitialized. */
876 /* Get the keyid from the keyblock. */
877 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
880 log_error ("Oops; key lost!\n");
881 dump_kbnode (keyblock);
885 pk = node->pkt->pkt.public_key;
887 /* First print an overview of the key with all userids. */
888 es_fprintf (es_stdout, ";; pub %s/%s %s\n;;",
889 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
890 keystr_from_pk (pk), datestr_from_pk (pk));
891 print_fingerprint (NULL, pk, 10);
892 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
894 if (node->pkt->pkttype == PKT_USER_ID)
896 PKT_user_id *uid = node->pkt->pkt.user_id;
898 if (pk && (uid->is_expired || uid->is_revoked)
899 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
902 es_fputs (";; uid ", es_stdout);
903 print_utf8_buffer (es_stdout, uid->name, uid->len);
904 es_putc ('\n', es_stdout);
909 hexfpr = hexfingerprint (pk, NULL, 0);
910 if (opt.print_dane_records)
912 kbnode_t dummy_keyblock;
917 /* We do not have an export function which allows to pass a
918 keyblock, thus we need to search the key again. */
919 err = export_pubkey_buffer (ctrl, hexfpr,
920 EXPORT_DANE_FORMAT, NULL,
921 &dummy_keyblock, &data, &datalen);
922 release_kbnode (dummy_keyblock);
925 hexkeyblocklen = datalen;
926 hexkeyblock = bin2hex (data, datalen, NULL);
928 err = gpg_error_from_syserror ();
930 ascii_strlwr (hexkeyblock);
933 log_error (_("skipped \"%s\": %s\n"), hexfpr, gpg_strerror (err));
937 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
939 if (node->pkt->pkttype == PKT_USER_ID)
941 PKT_user_id *uid = node->pkt->pkt.user_id;
945 if (pk && (uid->is_expired || uid->is_revoked)
946 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
949 mbox = mailbox_from_userid (uid->name);
950 if (mbox && (p = strchr (mbox, '@')))
957 if (opt.print_pka_records)
959 es_fprintf (es_stdout, "$ORIGIN _pka.%s.\n; %s\n; ",
961 print_utf8_buffer (es_stdout, uid->name, uid->len);
962 es_putc ('\n', es_stdout);
963 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf,
964 mbox, strlen (mbox));
965 hash = zb32_encode (hashbuf, 8*20);
968 len = strlen (hexfpr)/2;
969 es_fprintf (es_stdout,
970 "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n",
971 hash, 6 + len, len, hexfpr);
975 if (opt.print_dane_records && hexkeyblock)
977 es_fprintf (es_stdout, "$ORIGIN _openpgpkey.%s.\n; %s\n; ",
979 print_utf8_buffer (es_stdout, uid->name, uid->len);
980 es_putc ('\n', es_stdout);
981 gcry_md_hash_buffer (GCRY_MD_SHA256, hashbuf,
982 mbox, strlen (mbox));
983 hash = bin2hex (hashbuf, 28, NULL);
987 es_fprintf (es_stdout, "%s TYPE61 \\# %u (\n",
988 hash, hexkeyblocklen);
993 es_fprintf (es_stdout, "\t%.64s\n", s);
998 es_fputs ("\t)\n", es_stdout);
1006 es_putc ('\n', es_stdout);
1008 xfree (hexkeyblock);
1014 list_keyblock_print (KBNODE keyblock, int secret, int fpr,
1015 struct keylist_context *listctx)
1023 char *hexgrip = NULL;
1024 char *serialno = NULL;
1025 char pkstrbuf[PUBKEY_STRING_SIZE];
1027 /* Get the keyid from the keyblock. */
1028 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1031 log_error ("Oops; key lost!\n");
1032 dump_kbnode (keyblock);
1036 pk = node->pkt->pkt.public_key;
1038 if (secret || opt.with_keygrip)
1040 rc = hexkeygrip_from_pk (pk, &hexgrip);
1042 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1047 if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
1048 s2k_char = serialno? '>':' ';
1050 s2k_char = '#'; /* Key not found. */
1055 check_trustdb_stale ();
1058 es_fprintf (es_stdout, "%s%c %s/%s %s",
1059 secret? "sec":"pub",
1061 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
1062 keystr_from_pk (pk), datestr_from_pk (pk));
1064 if ((opt.list_options & LIST_SHOW_USAGE))
1066 es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
1068 if (pk->flags.revoked)
1070 es_fprintf (es_stdout, " [");
1071 es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
1072 es_fprintf (es_stdout, "]");
1074 else if (pk->has_expired)
1076 es_fprintf (es_stdout, " [");
1077 es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
1078 es_fprintf (es_stdout, "]");
1080 else if (pk->expiredate)
1082 es_fprintf (es_stdout, " [");
1083 es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
1084 es_fprintf (es_stdout, "]");
1088 /* I need to think about this some more. It's easy enough to
1089 include, but it looks sort of confusing in the listing... */
1090 if (opt.list_options & LIST_SHOW_VALIDITY)
1092 int validity = get_validity (pk, NULL, NULL, 0);
1093 es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
1097 if (pk->pubkey_algo >= 100)
1098 es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
1100 es_fprintf (es_stdout, "\n");
1103 print_fingerprint (NULL, pk, 0);
1105 if (opt.with_keygrip && hexgrip)
1106 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1109 print_card_serialno (serialno);
1111 if (opt.with_key_data)
1112 print_key_data (pk);
1114 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1116 if (node->pkt->pkttype == PKT_USER_ID)
1118 PKT_user_id *uid = node->pkt->pkt.user_id;
1120 if ((uid->is_expired || uid->is_revoked)
1121 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
1129 if (attrib_fp && uid->attrib_data != NULL)
1130 dump_attribs (uid, pk);
1132 if ((uid->is_revoked || uid->is_expired)
1133 || (opt.list_options & LIST_SHOW_UID_VALIDITY))
1135 const char *validity;
1138 validity = uid_trust_string_fixed (pk, uid);
1140 (keystrlen () + (opt.legacy_list_mode? 9:11)) -
1141 atoi (uid_trust_string_fixed (NULL, NULL));
1143 if (indent < 0 || indent > 40)
1146 es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
1149 es_fprintf (es_stdout, "uid%*s",
1150 (int) keystrlen () + (opt.legacy_list_mode? 10:12), "");
1152 print_utf8_buffer (es_stdout, uid->name, uid->len);
1153 es_putc ('\n', es_stdout);
1155 if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
1156 show_photos (uid->attribs, uid->numattribs, pk, uid);
1158 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1160 PKT_public_key *pk2 = node->pkt->pkt.public_key;
1162 if ((pk2->flags.revoked || pk2->has_expired)
1163 && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1171 xfree (serialno); serialno = NULL;
1172 xfree (hexgrip); hexgrip = NULL;
1173 if (secret || opt.with_keygrip)
1175 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1177 log_error ("error computing a keygrip: %s\n",
1182 if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
1183 s2k_char = serialno? '>':' ';
1185 s2k_char = '#'; /* Key not found. */
1190 es_fprintf (es_stdout, "%s%c %s/%s %s",
1191 secret? "ssb":"sub",
1193 pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
1194 keystr_from_pk (pk2), datestr_from_pk (pk2));
1196 if ((opt.list_options & LIST_SHOW_USAGE))
1198 es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
1200 if (pk2->flags.revoked)
1202 es_fprintf (es_stdout, " [");
1203 es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
1204 es_fprintf (es_stdout, "]");
1206 else if (pk2->has_expired)
1208 es_fprintf (es_stdout, " [");
1209 es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
1210 es_fprintf (es_stdout, "]");
1212 else if (pk2->expiredate)
1214 es_fprintf (es_stdout, " [");
1215 es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
1216 es_fprintf (es_stdout, "]");
1218 es_putc ('\n', es_stdout);
1221 print_fingerprint (NULL, pk2, 0);
1223 print_card_serialno (serialno);
1225 if (opt.with_keygrip && hexgrip)
1226 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1227 if (opt.with_key_data)
1228 print_key_data (pk2);
1230 else if (opt.list_sigs
1231 && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1233 PKT_signature *sig = node->pkt->pkt.signature;
1237 if (listctx->check_sigs)
1239 rc = check_key_signature (keyblock, node, NULL);
1240 switch (gpg_err_code (rc))
1243 listctx->good_sigs++;
1246 case GPG_ERR_BAD_SIGNATURE:
1247 listctx->inv_sigs++;
1250 case GPG_ERR_NO_PUBKEY:
1251 case GPG_ERR_UNUSABLE_PUBKEY:
1260 /* TODO: Make sure a cached sig record here still has
1261 the pk that issued it. See also
1262 keyedit.c:print_and_check_one_sig */
1270 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1271 || sig->sig_class == 0x30)
1273 else if ((sig->sig_class & ~3) == 0x10)
1275 else if (sig->sig_class == 0x18)
1277 else if (sig->sig_class == 0x1F)
1281 es_fprintf (es_stdout, "sig "
1282 "[unexpected signature class 0x%02x]\n",
1287 es_fputs (sigstr, es_stdout);
1288 es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1289 sigrc, (sig->sig_class - 0x10 > 0 &&
1290 sig->sig_class - 0x10 <
1291 4) ? '0' + sig->sig_class - 0x10 : ' ',
1292 sig->flags.exportable ? ' ' : 'L',
1293 sig->flags.revocable ? ' ' : 'R',
1294 sig->flags.policy_url ? 'P' : ' ',
1295 sig->flags.notation ? 'N' : ' ',
1296 sig->flags.expired ? 'X' : ' ',
1297 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1299 sig->trust_depth : ' ', keystr (sig->keyid),
1300 datestr_from_sig (sig));
1301 if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1302 es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1303 es_fprintf (es_stdout, " ");
1305 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1306 else if (sigrc == '?')
1308 else if (!opt.fast_list_mode)
1311 char *p = get_user_id (sig->keyid, &n);
1312 print_utf8_buffer (es_stdout, p, n);
1315 es_putc ('\n', es_stdout);
1317 if (sig->flags.policy_url
1318 && (opt.list_options & LIST_SHOW_POLICY_URLS))
1319 show_policy_url (sig, 3, 0);
1321 if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1322 show_notation (sig, 3, 0,
1324 list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1327 list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1330 if (sig->flags.pref_ks
1331 && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1332 show_keyserver_url (sig, 3, 0);
1334 /* fixme: check or list other sigs here */
1337 es_putc ('\n', es_stdout);
1343 print_revokers (estream_t fp, PKT_public_key * pk)
1345 /* print the revoker record */
1346 if (!pk->revkey && pk->numrevkeys)
1352 for (i = 0; i < pk->numrevkeys; i++)
1356 es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1357 p = pk->revkey[i].fpr;
1358 for (j = 0; j < 20; j++, p++)
1359 es_fprintf (fp, "%02X", *p);
1360 es_fprintf (fp, ":%02x%s:\n",
1361 pk->revkey[i].class,
1362 (pk->revkey[i].class & 0x40) ? "s" : "");
1368 /* List a key in colon mode. If SECRET is true this is a secret key
1369 record (i.e. requested via --list-secret-key). If HAS_SECRET a
1370 secret key is available even if SECRET is not set. */
1372 list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
1379 int trustletter = 0;
1383 char *hexgrip = NULL;
1384 char *serialno = NULL;
1387 /* Get the keyid from the keyblock. */
1388 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1391 log_error ("Oops; key lost!\n");
1392 dump_kbnode (keyblock);
1396 pk = node->pkt->pkt.public_key;
1397 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1399 rc = hexkeygrip_from_pk (pk, &hexgrip);
1401 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1404 if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
1405 stubkey = 1; /* Key not found. */
1407 keyid_from_pk (pk, keyid);
1408 es_fputs (secret? "sec:":"pub:", es_stdout);
1409 if (!pk->flags.valid)
1410 es_putc ('i', es_stdout);
1411 else if (pk->flags.revoked)
1412 es_putc ('r', es_stdout);
1413 else if (pk->has_expired)
1414 es_putc ('e', es_stdout);
1415 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1419 trustletter = get_validity_info (pk, NULL);
1420 if (trustletter == 'u')
1422 es_putc (trustletter, es_stdout);
1425 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1428 (ulong) keyid[0], (ulong) keyid[1],
1429 colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1431 if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1432 es_putc (get_ownertrust_info (pk), es_stdout);
1433 es_putc (':', es_stdout);
1435 es_putc (':', es_stdout);
1436 es_putc (':', es_stdout);
1437 print_capabilities (pk, keyblock);
1438 es_putc (':', es_stdout); /* End of field 13. */
1439 es_putc (':', es_stdout); /* End of field 14. */
1440 if (secret || has_secret)
1443 es_putc ('#', es_stdout);
1445 es_fputs (serialno, es_stdout);
1446 else if (has_secret)
1447 es_putc ('+', es_stdout);
1449 es_putc (':', es_stdout); /* End of field 15. */
1450 es_putc (':', es_stdout); /* End of field 16. */
1451 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1452 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1453 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1455 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1456 const char *name = openpgp_oid_to_curve (curve, 0);
1459 es_fputs (name, es_stdout);
1462 es_putc (':', es_stdout); /* End of field 17. */
1463 es_putc (':', es_stdout); /* End of field 18. */
1464 es_putc ('\n', es_stdout);
1466 print_revokers (es_stdout, pk);
1468 print_fingerprint (NULL, pk, 0);
1469 if (opt.with_key_data || opt.with_keygrip)
1472 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1473 if (opt.with_key_data)
1474 print_key_data (pk);
1477 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1479 if (node->pkt->pkttype == PKT_USER_ID)
1482 PKT_user_id *uid = node->pkt->pkt.user_id;
1484 if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1485 dump_attribs (node->pkt->pkt.user_id, pk);
1487 * Fixme: We need a valid flag here too
1489 str = uid->attrib_data ? "uat" : "uid";
1490 if (uid->is_revoked)
1491 es_fprintf (es_stdout, "%s:r::::", str);
1492 else if (uid->is_expired)
1493 es_fprintf (es_stdout, "%s:e::::", str);
1494 else if (opt.no_expensive_trust_checks)
1495 es_fprintf (es_stdout, "%s:::::", str);
1501 uid_validity = get_validity_info (pk, uid);
1504 es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1507 es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1508 es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1510 namehash_from_uid (uid);
1512 for (i = 0; i < 20; i++)
1513 es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1515 es_fprintf (es_stdout, "::");
1517 if (uid->attrib_data)
1518 es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1520 es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1521 es_fprintf (es_stdout, "::::::::");
1522 if (opt.trust_model == TM_TOFU || opt.trust_model == TM_TOFU_PGP)
1525 enum tofu_policy policy;
1526 if (! tofu_get_policy (pk, uid, &policy)
1527 && policy != TOFU_POLICY_NONE)
1528 es_fprintf (es_stdout, "%s", tofu_policy_str (policy));
1531 es_putc (':', es_stdout);
1532 es_putc ('\n', es_stdout);
1534 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1537 PKT_public_key *pk2;
1539 pk2 = node->pkt->pkt.public_key;
1540 xfree (hexgrip); hexgrip = NULL;
1541 xfree (serialno); serialno = NULL;
1542 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1544 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1546 log_error ("error computing a keygrip: %s\n",
1550 if ((secret||has_secret)
1551 && agent_get_keyinfo (NULL, hexgrip, &serialno))
1552 stubkey = 1; /* Key not found. */
1554 keyid_from_pk (pk2, keyid2);
1555 es_fputs (secret? "ssb:":"sub:", es_stdout);
1556 if (!pk2->flags.valid)
1557 es_putc ('i', es_stdout);
1558 else if (pk2->flags.revoked)
1559 es_putc ('r', es_stdout);
1560 else if (pk2->has_expired)
1561 es_putc ('e', es_stdout);
1562 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1566 /* TRUSTLETTER should always be defined here. */
1568 es_fprintf (es_stdout, "%c", trustletter);
1570 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1571 nbits_from_pk (pk2),
1573 (ulong) keyid2[0], (ulong) keyid2[1],
1574 colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1575 /* fixme: add LID and ownertrust here */
1577 print_capabilities (pk2, NULL);
1578 es_putc (':', es_stdout); /* End of field 13. */
1579 es_putc (':', es_stdout); /* End of field 14. */
1580 if (secret || has_secret)
1583 es_putc ('#', es_stdout);
1585 es_fputs (serialno, es_stdout);
1586 else if (has_secret)
1587 es_putc ('+', es_stdout);
1589 es_putc (':', es_stdout); /* End of field 15. */
1590 es_putc (':', es_stdout); /* End of field 16. */
1591 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1592 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1593 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1595 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1596 const char *name = openpgp_oid_to_curve (curve, 0);
1599 es_fputs (name, es_stdout);
1602 es_putc (':', es_stdout); /* End of field 17. */
1603 es_putc ('\n', es_stdout);
1605 print_fingerprint (NULL, pk2, 0);
1606 if (opt.with_key_data || opt.with_keygrip)
1609 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1610 if (opt.with_key_data)
1611 print_key_data (pk2);
1614 else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1616 PKT_signature *sig = node->pkt->pkt.signature;
1617 int sigrc, fprokay = 0;
1620 byte fparray[MAX_FINGERPRINT_LEN];
1622 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1623 || sig->sig_class == 0x30)
1625 else if ((sig->sig_class & ~3) == 0x10)
1627 else if (sig->sig_class == 0x18)
1629 else if (sig->sig_class == 0x1F)
1633 es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1634 sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1640 PKT_public_key *signer_pk = NULL;
1643 if (opt.no_sig_cache)
1644 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1646 rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1648 switch (gpg_err_code (rc))
1653 case GPG_ERR_BAD_SIGNATURE:
1656 case GPG_ERR_NO_PUBKEY:
1657 case GPG_ERR_UNUSABLE_PUBKEY:
1665 if (opt.no_sig_cache)
1669 fingerprint_from_pk (signer_pk, fparray, &fplen);
1672 free_public_key (signer_pk);
1680 es_fputs (sigstr, es_stdout);
1681 es_putc (':', es_stdout);
1683 es_putc (sigrc, es_stdout);
1684 es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1685 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1686 colon_datestr_from_sig (sig),
1687 colon_expirestr_from_sig (sig));
1689 if (sig->trust_depth || sig->trust_value)
1690 es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1691 es_fprintf (es_stdout, ":");
1693 if (sig->trust_regexp)
1694 es_write_sanitized (es_stdout, sig->trust_regexp,
1695 strlen (sig->trust_regexp), ":", NULL);
1696 es_fprintf (es_stdout, ":");
1699 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1700 else if (sigrc == '?')
1702 else if (!opt.fast_list_mode)
1705 p = get_user_id (sig->keyid, &n);
1706 es_write_sanitized (es_stdout, p, n, ":", NULL);
1709 es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1710 sig->flags.exportable ? 'x' : 'l');
1712 if (opt.no_sig_cache && opt.check_sigs && fprokay)
1714 for (i = 0; i < fplen; i++)
1715 es_fprintf (es_stdout, "%02X", fparray[i]);
1718 es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1720 if (opt.show_subpackets)
1721 print_subpackets_colon (sig);
1723 /* fixme: check or list other sigs here */
1732 * Reorder the keyblock so that the primary user ID (and not attribute
1733 * packet) comes first. Fixme: Replace this by a generic sort
1736 do_reorder_keyblock (KBNODE keyblock, int attr)
1738 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1741 for (node = keyblock; node; primary0 = node, node = node->next)
1743 if (node->pkt->pkttype == PKT_USER_ID &&
1744 ((attr && node->pkt->pkt.user_id->attrib_data) ||
1745 (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1746 node->pkt->pkt.user_id->is_primary)
1748 primary = primary2 = node;
1749 for (node = node->next; node; primary2 = node, node = node->next)
1751 if (node->pkt->pkttype == PKT_USER_ID
1752 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1753 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1762 return; /* No primary key flag found (should not happen). */
1764 for (last = NULL, node = keyblock; node; last = node, node = node->next)
1766 if (node->pkt->pkttype == PKT_USER_ID)
1770 assert (last); /* The user ID is never the first packet. */
1771 assert (primary0); /* Ditto (this is the node before primary). */
1772 if (node == primary)
1773 return; /* Already the first one. */
1775 last->next = primary;
1776 primary0->next = primary2->next;
1777 primary2->next = node;
1781 reorder_keyblock (KBNODE keyblock)
1783 do_reorder_keyblock (keyblock, 1);
1784 do_reorder_keyblock (keyblock, 0);
1788 list_keyblock (ctrl_t ctrl,
1789 KBNODE keyblock, int secret, int has_secret, int fpr,
1790 struct keylist_context *listctx)
1792 reorder_keyblock (keyblock);
1793 if (opt.print_pka_records || opt.print_dane_records)
1794 list_keyblock_pka (ctrl, keyblock);
1795 else if (opt.with_colons)
1796 list_keyblock_colon (keyblock, secret, has_secret, fpr);
1798 list_keyblock_print (keyblock, secret, fpr, listctx);
1800 es_fflush (es_stdout);
1804 /* Public function used by keygen to list a keyblock. */
1806 list_keyblock_direct (ctrl_t ctrl,
1807 kbnode_t keyblock, int secret, int has_secret, int fpr)
1809 struct keylist_context listctx;
1811 memset (&listctx, 0, sizeof (listctx));
1812 list_keyblock (ctrl, keyblock, secret, has_secret, fpr, &listctx);
1813 keylist_context_release (&listctx);
1817 /* Print an hex digit in ICAO spelling. */
1819 print_icao_hexdigit (estream_t fp, int c)
1821 static const char *list[16] = {
1822 "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1823 "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1826 tty_fprintf (fp, "%s", list[c&15]);
1831 * Function to print the finperprint.
1832 * mode 0: as used in key listings, opt.with_colons is honored
1833 * 1: print using log_info ()
1834 * 2: direct use of tty
1835 * 3: direct use of tty but only primary key.
1836 * 4: direct use of tty but only subkey.
1837 * 10: Same as 0 but with_colons etc is ignored.
1839 * Modes 1 and 2 will try and print both subkey and primary key
1840 * fingerprints. A MODE with bit 7 set is used internally. If
1841 * OVERRIDE_FP is not NULL that stream will be used in 0 instead
1842 * of es_stdout or instead of the TTY in modes 2 and 3.
1845 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1847 char hexfpr[2*MAX_FINGERPRINT_LEN+1];
1853 int with_colons = opt.with_colons;
1854 int with_icao = opt.with_icao_spelling;
1863 if (pk->main_keyid[0] == pk->keyid[0]
1864 && pk->main_keyid[1] == pk->keyid[1])
1867 /* Just to be safe */
1868 if ((mode & 0x80) && !primary)
1870 log_error ("primary key is not really primary!\n");
1876 if (!primary && (mode == 1 || mode == 2))
1878 PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1879 get_pubkey (primary_pk, pk->main_keyid);
1880 print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1881 free_public_key (primary_pk);
1886 fp = log_get_stream ();
1888 text = _("Primary key fingerprint:");
1890 text = _(" Subkey fingerprint:");
1894 fp = override_fp; /* Use tty or given stream. */
1896 /* TRANSLATORS: this should fit into 24 bytes so that the
1897 * fingerprint data is properly aligned with the user ID */
1898 text = _(" Primary key fingerprint:");
1900 text = _(" Subkey fingerprint:");
1904 fp = override_fp; /* Use tty or given stream. */
1905 text = _(" Key fingerprint =");
1909 fp = override_fp; /* Use tty or given stream. */
1910 text = _(" Subkey fingerprint:");
1914 fp = override_fp? override_fp : es_stdout;
1915 text = _(" Key fingerprint =");
1918 hexfingerprint (pk, hexfpr, sizeof hexfpr);
1919 if (with_colons && !mode)
1921 es_fprintf (fp, "fpr:::::::::%s:", hexfpr);
1925 char fmtfpr[MAX_FORMATTED_FINGERPRINT_LEN + 1];
1926 format_hexfingerprint (hexfpr, fmtfpr, sizeof fmtfpr);
1927 tty_fprintf (fp, "%s %s", text, fmtfpr);
1929 tty_fprintf (fp, "\n");
1930 if (!with_colons && with_icao)
1933 tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1934 for (i = 0, p = hexfpr; *p; i++, p++)
1939 tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
1941 tty_fprintf (fp, " ");
1943 tty_fprintf (fp, " ");
1944 print_icao_hexdigit (fp, xtoi_1 (p));
1946 tty_fprintf (fp, "\"\n");
1950 /* Print the serial number of an OpenPGP card if available. */
1952 print_card_serialno (const char *serialno)
1956 if (opt.with_colons)
1957 return; /* Handled elsewhere. */
1959 es_fputs (_(" Card serial no. ="), es_stdout);
1960 es_putc (' ', es_stdout);
1961 if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1963 /* This is an OpenPGP card. Print the relevant part. */
1964 /* Example: D2760001240101010001000003470000 */
1966 es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1969 es_fputs (serialno, es_stdout);
1970 es_putc ('\n', es_stdout);
1976 set_attrib_fd (int fd)
1978 static int last_fd = -1;
1980 if (fd != -1 && last_fd == fd)
1983 /* Fixme: Do we need to check for the log stream here? */
1984 if (attrib_fp && attrib_fp != log_get_stream ())
1985 es_fclose (attrib_fp);
1990 #ifdef HAVE_DOSISH_SYSTEM
1991 setmode (fd, O_BINARY);
1994 attrib_fp = es_stdout;
1996 attrib_fp = es_stderr;
1998 attrib_fp = es_fdopen (fd, "wb");
2001 log_fatal ("can't open fd %d for attribute output: %s\n",
2002 fd, strerror (errno));