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"
48 static void list_all (int, int);
49 static void list_one (strlist_t names, int secret, int mark_secret);
50 static void locate_one (ctrl_t ctrl, strlist_t names);
51 static void print_card_serialno (const char *serialno);
53 struct keylist_context
55 int check_sigs; /* If set signatures shall be verified. */
56 int inv_sigs; /* Counter used if CHECK_SIGS is set. */
57 int no_key; /* Counter used if CHECK_SIGS is set. */
58 int oth_err; /* Counter used if CHECK_SIGS is set. */
62 static void list_keyblock (kbnode_t keyblock, int secret, int has_secret,
63 int fpr, struct keylist_context *listctx);
66 /* The stream used to write attribute packets to. */
67 static estream_t attrib_fp;
70 /* Release resources from a keylist context. */
72 keylist_context_release (struct keylist_context *listctx)
74 (void)listctx; /* Nothing to release. */
78 /* List the keys. If list is NULL, all available keys are listed.
79 With LOCATE_MODE set the locate algorithm is used to find a
82 public_key_list (ctrl_t ctrl, strlist_t list, int locate_mode)
84 #ifndef NO_TRUST_MODELS
87 byte trust_model, marginals, completes, cert_depth, min_cert_level;
88 ulong created, nextcheck;
90 read_trust_options (&trust_model, &created, &nextcheck,
91 &marginals, &completes, &cert_depth, &min_cert_level);
93 es_fprintf (es_stdout, "tru:");
95 if (nextcheck && nextcheck <= make_timestamp ())
96 es_fprintf (es_stdout, "o");
97 if (trust_model != opt.trust_model)
98 es_fprintf (es_stdout, "t");
99 if (opt.trust_model == TM_PGP || opt.trust_model == TM_CLASSIC)
101 if (marginals != opt.marginals_needed)
102 es_fprintf (es_stdout, "m");
103 if (completes != opt.completes_needed)
104 es_fprintf (es_stdout, "c");
105 if (cert_depth != opt.max_cert_depth)
106 es_fprintf (es_stdout, "d");
107 if (min_cert_level != opt.min_cert_level)
108 es_fprintf (es_stdout, "l");
111 es_fprintf (es_stdout, ":%d:%lu:%lu", trust_model, created, nextcheck);
113 /* Only show marginals, completes, and cert_depth in the classic
114 or PGP trust models since they are not meaningful
117 if (trust_model == TM_PGP || trust_model == TM_CLASSIC)
118 es_fprintf (es_stdout, ":%d:%d:%d", marginals, completes, cert_depth);
119 es_fprintf (es_stdout, "\n");
121 #endif /*!NO_TRUST_MODELS*/
123 /* We need to do the stale check right here because it might need to
124 update the keyring while we already have the keyring open. This
125 is very bad for W32 because of a sharing violation. For real OSes
126 it might lead to false results if we are later listing a keyring
127 which is associated with the inode of a deleted file. */
128 check_trustdb_stale ();
131 locate_one (ctrl, list);
133 list_all (0, opt.with_secret);
135 list_one (list, 0, opt.with_secret);
140 secret_key_list (ctrl_t ctrl, strlist_t list)
144 check_trustdb_stale ();
148 else /* List by user id */
149 list_one (list, 1, 0);
153 print_seckey_info (PKT_public_key *pk)
157 char pkstrbuf[PUBKEY_STRING_SIZE];
159 keyid_from_pk (pk, keyid);
160 p = get_user_id_native (keyid);
162 tty_printf ("\nsec %s/%s %s %s\n",
163 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
164 keystr (keyid), datestr_from_pk (pk), p);
169 /* Print information about the public key. With FP passed as NULL,
170 the tty output interface is used, otherwise output is directted to
173 print_pubkey_info (estream_t fp, PKT_public_key * pk)
177 char pkstrbuf[PUBKEY_STRING_SIZE];
179 keyid_from_pk (pk, keyid);
181 /* If the pk was chosen by a particular user ID, that is the one to
184 p = utf8_to_native (pk->user_id->name, pk->user_id->len, 0);
186 p = get_user_id_native (keyid);
190 tty_fprintf (fp, "pub %s/%s %s %s\n",
191 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
192 keystr (keyid), datestr_from_pk (pk), p);
197 /* Print basic information of a secret key including the card serial
198 number information. */
199 #ifdef ENABLE_CARD_SUPPORT
201 print_card_key_info (estream_t fp, kbnode_t keyblock)
207 char pkstrbuf[PUBKEY_STRING_SIZE];
209 for (node = keyblock; node; node = node->next)
211 if (node->pkt->pkttype == PKT_PUBLIC_KEY
212 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
215 PKT_public_key *pk = node->pkt->pkt.public_key;
218 rc = hexkeygrip_from_pk (pk, &hexgrip);
221 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
224 else if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
225 s2k_char = serialno? '>':' ';
227 s2k_char = '#'; /* Key not found. */
229 tty_fprintf (fp, "%s%c %s/%s ",
230 node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
232 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
233 keystr_from_pk (pk));
234 tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
235 tty_fprintf (fp, " ");
236 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
239 tty_fprintf (fp, "\n ");
240 tty_fprintf (fp, _("card-no: "));
241 if (strlen (serialno) == 32
242 && !strncmp (serialno, "D27600012401", 12))
244 /* This is an OpenPGP card. Print the relevant part. */
245 /* Example: D2760001240101010001000003470000 */
247 tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
250 tty_fprintf (fp, "%s", serialno);
252 tty_fprintf (fp, "\n");
258 #endif /*ENABLE_CARD_SUPPORT*/
261 /* Flags = 0x01 hashed 0x02 critical. */
263 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
268 /* Don't print these. */
272 snprintf (status, sizeof status,
273 "%d %u %u ", type, flags, (unsigned int) len);
275 write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
279 /* Print a policy URL. Allowed values for MODE are:
280 * 0 - print to stdout.
281 * 1 - use log_info and emit status messages.
282 * 2 - emit only status messages.
285 show_policy_url (PKT_signature * sig, int indent, int mode)
290 estream_t fp = mode ? log_get_stream () : es_stdout;
293 enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
300 for (i = 0; i < indent; i++)
304 str = _("Critical signature policy: ");
306 str = _("Signature policy: ");
308 log_info ("%s", str);
310 es_fprintf (fp, "%s", str);
311 print_utf8_buffer (fp, p, len);
312 es_fprintf (fp, "\n");
316 write_status_buffer (STATUS_POLICY_URL, p, len, 0);
323 mode=1 for log_info + status messages
324 mode=2 for status messages only
328 show_keyserver_url (PKT_signature * sig, int indent, int mode)
333 estream_t fp = mode ? log_get_stream () : es_stdout;
336 enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
344 for (i = 0; i < indent; i++)
345 es_putc (' ', es_stdout);
348 str = _("Critical preferred keyserver: ");
350 str = _("Preferred keyserver: ");
352 log_info ("%s", str);
354 es_fprintf (es_stdout, "%s", str);
355 print_utf8_buffer (fp, p, len);
356 es_fprintf (fp, "\n");
360 status_one_subpacket (SIGSUBPKT_PREF_KS, len,
361 (crit ? 0x02 : 0) | 0x01, p);
367 mode=1 for log_info + status messages
368 mode=2 for status messages only
370 Defined bits in WHICH:
371 1 == standard notations
375 show_notation (PKT_signature * sig, int indent, int mode, int which)
377 estream_t fp = mode ? log_get_stream () : es_stdout;
378 struct notation *nd, *notations;
383 notations = sig_to_notation (sig);
385 /* There may be multiple notations in the same sig. */
386 for (nd = notations; nd; nd = nd->next)
390 int has_at = !!strchr (nd->name, '@');
392 if ((which & 1 && !has_at) || (which & 2 && has_at))
397 for (i = 0; i < indent; i++)
398 es_putc (' ', es_stdout);
400 if (nd->flags.critical)
401 str = _("Critical signature notation: ");
403 str = _("Signature notation: ");
405 log_info ("%s", str);
407 es_fprintf (es_stdout, "%s", str);
408 /* This is all UTF8 */
409 print_utf8_buffer (fp, nd->name, strlen (nd->name));
410 es_fprintf (fp, "=");
411 print_utf8_buffer (fp, nd->value, strlen (nd->value));
412 /* (We need to use log_printf so that the next call to a
413 log function does not insert an extra LF.) */
423 write_status_buffer (STATUS_NOTATION_NAME,
424 nd->name, strlen (nd->name), 0);
425 write_status_buffer (STATUS_NOTATION_DATA,
426 nd->value, strlen (nd->value), 50);
430 free_notation (notations);
435 print_signature_stats (struct keylist_context *s)
438 return; /* Signature checking was not requested. */
440 if (s->inv_sigs == 1)
441 tty_printf (_("1 bad signature\n"));
442 else if (s->inv_sigs)
443 tty_printf (_("%d bad signatures\n"), s->inv_sigs);
445 tty_printf (_("1 signature not checked due to a missing key\n"));
447 tty_printf (_("%d signatures not checked due to missing keys\n"),
450 tty_printf (_("1 signature not checked due to an error\n"));
452 tty_printf (_("%d signatures not checked due to errors\n"), s->oth_err);
456 /* List all keys. If SECRET is true only secret keys are listed. If
457 MARK_SECRET is true secret keys are indicated in a public key
460 list_all (int secret, int mark_secret)
463 KBNODE keyblock = NULL;
466 const char *lastresname, *resname;
467 struct keylist_context listctx;
469 memset (&listctx, 0, sizeof (listctx));
471 listctx.check_sigs = 1;
475 rc = gpg_error (GPG_ERR_GENERAL);
477 rc = keydb_search_first (hd);
480 if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
481 log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
488 rc = keydb_get_keyblock (hd, &keyblock);
491 if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
492 continue; /* Skip legacy keys. */
493 log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
497 if (secret || mark_secret)
498 any_secret = !agent_probe_any_secret_key (NULL, keyblock);
502 if (secret && !any_secret)
503 ; /* Secret key listing requested but this isn't one. */
506 if (!opt.with_colons)
508 resname = keydb_get_resource_name (hd);
509 if (lastresname != resname)
513 es_fprintf (es_stdout, "%s\n", resname);
514 for (i = strlen (resname); i; i--)
515 es_putc ('-', es_stdout);
516 es_putc ('\n', es_stdout);
517 lastresname = resname;
520 merge_keys_and_selfsig (keyblock);
521 list_keyblock (keyblock, secret, any_secret, opt.fingerprint,
524 release_kbnode (keyblock);
527 while (!(rc = keydb_search_next (hd)));
528 es_fflush (es_stdout);
529 if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
530 log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
531 if (keydb_get_skipped_counter (hd))
532 log_info (_("Warning: %lu key(s) skipped due to their large size\n"),
533 keydb_get_skipped_counter (hd));
535 if (opt.check_sigs && !opt.with_colons)
536 print_signature_stats (&listctx);
539 keylist_context_release (&listctx);
540 release_kbnode (keyblock);
546 list_one (strlist_t names, int secret, int mark_secret)
549 KBNODE keyblock = NULL;
552 const char *keyring_str = _("Keyring");
554 struct keylist_context listctx;
556 memset (&listctx, 0, sizeof (listctx));
557 if (!secret && opt.check_sigs)
558 listctx.check_sigs = 1;
560 /* fixme: using the bynames function has the disadvantage that we
561 * don't know wether one of the names given was not found. OTOH,
562 * this function has the advantage to list the names in the
563 * sequence as defined by the keyDB and does not duplicate
564 * outputs. A solution could be do test whether all given have
565 * been listed (this needs a way to use the keyDB search
566 * functions) or to have the search function return indicators for
567 * found names. Yet another way is to use the keydb search
568 * facilities directly. */
569 rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
572 log_error ("error reading key: %s\n", gpg_strerror (rc));
573 get_pubkey_end (ctx);
579 if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
581 resname = keydb_get_resource_name (get_ctx_handle (ctx));
582 es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
583 for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
584 es_putc ('-', es_stdout);
585 es_putc ('\n', es_stdout);
587 list_keyblock (keyblock, secret, mark_secret, opt.fingerprint, &listctx);
588 release_kbnode (keyblock);
590 while (!getkey_next (ctx, NULL, &keyblock));
593 if (opt.check_sigs && !opt.with_colons)
594 print_signature_stats (&listctx);
596 keylist_context_release (&listctx);
601 locate_one (ctrl_t ctrl, strlist_t names)
605 GETKEY_CTX ctx = NULL;
606 KBNODE keyblock = NULL;
607 struct keylist_context listctx;
609 memset (&listctx, 0, sizeof (listctx));
611 listctx.check_sigs = 1;
613 for (sl = names; sl; sl = sl->next)
615 rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
618 if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
619 log_error ("error reading key: %s\n", gpg_strerror (rc));
625 list_keyblock (keyblock, 0, 0, opt.fingerprint, &listctx);
626 release_kbnode (keyblock);
628 while (ctx && !get_pubkey_next (ctx, NULL, &keyblock));
629 get_pubkey_end (ctx);
634 if (opt.check_sigs && !opt.with_colons)
635 print_signature_stats (&listctx);
637 keylist_context_release (&listctx);
642 print_key_data (PKT_public_key * pk)
644 int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
647 for (i = 0; i < n; i++)
649 es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
650 mpi_print (es_stdout, pk->pkey[i], 1);
651 es_putc (':', es_stdout);
652 es_putc ('\n', es_stdout);
657 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
659 unsigned int use = pk->pubkey_usage;
662 if (use & PUBKEY_USAGE_ENC)
663 es_putc ('e', es_stdout);
665 if (use & PUBKEY_USAGE_SIG)
667 es_putc ('s', es_stdout);
668 if (pk->flags.primary)
670 es_putc ('c', es_stdout);
671 /* The PUBKEY_USAGE_CERT flag was introduced later and we
672 used to always print 'c' for a primary key. To avoid any
673 regression here we better track whether we printed 'c'
679 if ((use & PUBKEY_USAGE_CERT) && !c_printed)
680 es_putc ('c', es_stdout);
682 if ((use & PUBKEY_USAGE_AUTH))
683 es_putc ('a', es_stdout);
685 if ((use & PUBKEY_USAGE_UNKNOWN))
686 es_putc ('?', es_stdout);
690 /* Figure out the usable capabilities. */
692 int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
694 for (k = keyblock; k; k = k->next)
696 if (k->pkt->pkttype == PKT_PUBLIC_KEY
697 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
699 pk = k->pkt->pkt.public_key;
701 if (pk->flags.primary)
702 disabled = pk_is_disabled (pk);
704 if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
706 if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
708 if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
711 if (pk->flags.primary)
714 if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
716 if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
722 es_putc ('E', es_stdout);
724 es_putc ('S', es_stdout);
726 es_putc ('C', es_stdout);
728 es_putc ('A', es_stdout);
730 es_putc ('D', es_stdout);
733 es_putc (':', es_stdout);
737 /* FLAGS: 0x01 hashed
740 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
745 es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
747 for (i = 0; i < len; i++)
749 /* printable ascii other than : and % */
750 if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
751 es_fprintf (es_stdout, "%c", buf[i]);
753 es_fprintf (es_stdout, "%%%02X", buf[i]);
756 es_fprintf (es_stdout, "\n");
761 print_subpackets_colon (PKT_signature * sig)
765 assert (opt.show_subpackets);
767 for (i = opt.show_subpackets; *i; i++)
775 while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
776 print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
780 while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
781 print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
787 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
794 for (i = 0; i < uid->numattribs; i++)
796 if (is_status_enabled ())
798 byte array[MAX_FINGERPRINT_LEN], *p;
799 char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
804 fingerprint_from_pk (pk, array, &n);
807 for (j = 0; j < n; j++, p++)
808 sprintf (buf + 2 * j, "%02X", *p);
810 sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
811 (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
812 uid->numattribs, (ulong) uid->created,
813 (ulong) uid->expiredate,
814 ((uid->is_primary ? 0x01 : 0) | (uid->
815 is_revoked ? 0x02 : 0) |
816 (uid->is_expired ? 0x04 : 0)));
817 write_status_text (STATUS_ATTRIBUTE, buf);
820 es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
821 es_fflush (attrib_fp);
826 /* Print IPGP cert records instead of a standard key listing. */
828 list_keyblock_pka (kbnode_t keyblock)
833 char pkstrbuf[PUBKEY_STRING_SIZE];
836 /* Get the keyid from the keyblock. */
837 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
840 log_error ("Oops; key lost!\n");
841 dump_kbnode (keyblock);
845 pk = node->pkt->pkt.public_key;
847 es_fprintf (es_stdout, ";; pub %s/%s %s\n;; ",
848 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
849 keystr_from_pk (pk), datestr_from_pk (pk));
850 print_fingerprint (NULL, pk, 10);
851 hexfpr = hexfingerprint (pk);
853 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
855 if (node->pkt->pkttype == PKT_USER_ID)
857 PKT_user_id *uid = node->pkt->pkt.user_id;
861 if (pk && (uid->is_expired || uid->is_revoked)
862 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
865 es_fputs (";; uid ", es_stdout);
866 print_utf8_buffer (es_stdout, uid->name, uid->len);
867 es_putc ('\n', es_stdout);
868 mbox = mailbox_from_userid (uid->name);
869 if (mbox && (p = strchr (mbox, '@')))
876 es_fprintf (es_stdout, "$ORIGIN _pka.%s.\n", p);
877 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
878 hash = zb32_encode (hashbuf, 8*20);
881 len = strlen (hexfpr)/2;
882 es_fprintf (es_stdout,
883 "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n",
884 hash, 6 + len, len, hexfpr);
892 es_putc ('\n', es_stdout);
899 list_keyblock_print (KBNODE keyblock, int secret, int fpr,
900 struct keylist_context *listctx)
908 char *hexgrip = NULL;
909 char *serialno = NULL;
910 char pkstrbuf[PUBKEY_STRING_SIZE];
912 /* Get the keyid from the keyblock. */
913 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
916 log_error ("Oops; key lost!\n");
917 dump_kbnode (keyblock);
921 pk = node->pkt->pkt.public_key;
923 if (secret || opt.with_keygrip)
925 rc = hexkeygrip_from_pk (pk, &hexgrip);
927 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
932 if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
933 s2k_char = serialno? '>':' ';
935 s2k_char = '#'; /* Key not found. */
940 check_trustdb_stale ();
943 es_fprintf (es_stdout, "%s%c %s/%s %s",
946 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
947 keystr_from_pk (pk), datestr_from_pk (pk));
949 if ((opt.list_options & LIST_SHOW_USAGE))
951 es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
953 if (pk->flags.revoked)
955 es_fprintf (es_stdout, " [");
956 es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
957 es_fprintf (es_stdout, "]");
959 else if (pk->has_expired)
961 es_fprintf (es_stdout, " [");
962 es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
963 es_fprintf (es_stdout, "]");
965 else if (pk->expiredate)
967 es_fprintf (es_stdout, " [");
968 es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
969 es_fprintf (es_stdout, "]");
973 /* I need to think about this some more. It's easy enough to
974 include, but it looks sort of confusing in the listing... */
975 if (opt.list_options & LIST_SHOW_VALIDITY)
977 int validity = get_validity (pk, NULL);
978 es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
982 if (pk->pubkey_algo >= 100)
983 es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
985 es_fprintf (es_stdout, "\n");
988 print_fingerprint (NULL, pk, 0);
990 if (opt.with_keygrip && hexgrip)
991 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
994 print_card_serialno (serialno);
996 if (opt.with_key_data)
999 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1001 if (node->pkt->pkttype == PKT_USER_ID)
1003 PKT_user_id *uid = node->pkt->pkt.user_id;
1005 if ((uid->is_expired || uid->is_revoked)
1006 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
1014 if (attrib_fp && uid->attrib_data != NULL)
1015 dump_attribs (uid, pk);
1017 if ((uid->is_revoked || uid->is_expired)
1018 || (opt.list_options & LIST_SHOW_UID_VALIDITY))
1020 const char *validity;
1023 validity = uid_trust_string_fixed (pk, uid);
1025 (keystrlen () + 9) -
1026 atoi (uid_trust_string_fixed (NULL, NULL));
1028 if (indent < 0 || indent > 40)
1031 es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
1034 es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
1036 print_utf8_buffer (es_stdout, uid->name, uid->len);
1037 es_putc ('\n', es_stdout);
1039 if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
1040 show_photos (uid->attribs, uid->numattribs, pk, uid);
1042 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1044 PKT_public_key *pk2 = node->pkt->pkt.public_key;
1046 if ((pk2->flags.revoked || pk2->has_expired)
1047 && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1055 xfree (serialno); serialno = NULL;
1056 xfree (hexgrip); hexgrip = NULL;
1057 if (secret || opt.with_keygrip)
1059 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1061 log_error ("error computing a keygrip: %s\n",
1066 if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
1067 s2k_char = serialno? '>':' ';
1069 s2k_char = '#'; /* Key not found. */
1074 es_fprintf (es_stdout, "%s%c %s/%s %s",
1075 secret? "ssb":"sub",
1077 pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
1078 keystr_from_pk (pk2), datestr_from_pk (pk2));
1080 if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1081 || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1082 || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1084 char *curve = openpgp_oid_to_str (pk2->pkey[0]);
1085 const char *name = openpgp_oid_to_curve (curve);
1086 if (!*name || *name == '?')
1088 es_fprintf (es_stdout, " %s", name);
1092 if ((opt.list_options & LIST_SHOW_USAGE))
1094 es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
1096 if (pk2->flags.revoked)
1098 es_fprintf (es_stdout, " [");
1099 es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
1100 es_fprintf (es_stdout, "]");
1102 else if (pk2->has_expired)
1104 es_fprintf (es_stdout, " [");
1105 es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
1106 es_fprintf (es_stdout, "]");
1108 else if (pk2->expiredate)
1110 es_fprintf (es_stdout, " [");
1111 es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
1112 es_fprintf (es_stdout, "]");
1114 es_putc ('\n', es_stdout);
1117 print_fingerprint (NULL, pk2, 0);
1119 print_card_serialno (serialno);
1121 if (opt.with_keygrip && hexgrip)
1122 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1123 if (opt.with_key_data)
1124 print_key_data (pk2);
1126 else if (opt.list_sigs
1127 && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1129 PKT_signature *sig = node->pkt->pkt.signature;
1133 if (listctx->check_sigs)
1135 rc = check_key_signature (keyblock, node, NULL);
1136 switch (gpg_err_code (rc))
1141 case GPG_ERR_BAD_SIGNATURE:
1142 listctx->inv_sigs++;
1145 case GPG_ERR_NO_PUBKEY:
1146 case GPG_ERR_UNUSABLE_PUBKEY:
1155 /* TODO: Make sure a cached sig record here still has
1156 the pk that issued it. See also
1157 keyedit.c:print_and_check_one_sig */
1165 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1166 || sig->sig_class == 0x30)
1168 else if ((sig->sig_class & ~3) == 0x10)
1170 else if (sig->sig_class == 0x18)
1172 else if (sig->sig_class == 0x1F)
1176 es_fprintf (es_stdout, "sig "
1177 "[unexpected signature class 0x%02x]\n",
1182 es_fputs (sigstr, es_stdout);
1183 es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1184 sigrc, (sig->sig_class - 0x10 > 0 &&
1185 sig->sig_class - 0x10 <
1186 4) ? '0' + sig->sig_class - 0x10 : ' ',
1187 sig->flags.exportable ? ' ' : 'L',
1188 sig->flags.revocable ? ' ' : 'R',
1189 sig->flags.policy_url ? 'P' : ' ',
1190 sig->flags.notation ? 'N' : ' ',
1191 sig->flags.expired ? 'X' : ' ',
1192 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1194 sig->trust_depth : ' ', keystr (sig->keyid),
1195 datestr_from_sig (sig));
1196 if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1197 es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1198 es_fprintf (es_stdout, " ");
1200 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1201 else if (sigrc == '?')
1203 else if (!opt.fast_list_mode)
1206 char *p = get_user_id (sig->keyid, &n);
1207 print_utf8_buffer (es_stdout, p, n);
1210 es_putc ('\n', es_stdout);
1212 if (sig->flags.policy_url
1213 && (opt.list_options & LIST_SHOW_POLICY_URLS))
1214 show_policy_url (sig, 3, 0);
1216 if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1217 show_notation (sig, 3, 0,
1219 list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1222 list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1225 if (sig->flags.pref_ks
1226 && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1227 show_keyserver_url (sig, 3, 0);
1229 /* fixme: check or list other sigs here */
1232 es_putc ('\n', es_stdout);
1238 print_revokers (estream_t fp, PKT_public_key * pk)
1240 /* print the revoker record */
1241 if (!pk->revkey && pk->numrevkeys)
1247 for (i = 0; i < pk->numrevkeys; i++)
1251 es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1252 p = pk->revkey[i].fpr;
1253 for (j = 0; j < 20; j++, p++)
1254 es_fprintf (fp, "%02X", *p);
1255 es_fprintf (fp, ":%02x%s:\n",
1256 pk->revkey[i].class,
1257 (pk->revkey[i].class & 0x40) ? "s" : "");
1263 /* List a key in colon mode. If SECRET is true this is a secret key
1264 record (i.e. requested via --list-secret-key). If HAS_SECRET a
1265 secret key is available even if SECRET is not set. */
1267 list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
1274 int trustletter = 0;
1278 char *hexgrip = NULL;
1279 char *serialno = NULL;
1282 /* Get the keyid from the keyblock. */
1283 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1286 log_error ("Oops; key lost!\n");
1287 dump_kbnode (keyblock);
1291 pk = node->pkt->pkt.public_key;
1292 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1294 rc = hexkeygrip_from_pk (pk, &hexgrip);
1296 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1299 if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
1300 stubkey = 1; /* Key not found. */
1302 keyid_from_pk (pk, keyid);
1303 es_fputs (secret? "sec:":"pub:", es_stdout);
1304 if (!pk->flags.valid)
1305 es_putc ('i', es_stdout);
1306 else if (pk->flags.revoked)
1307 es_putc ('r', es_stdout);
1308 else if (pk->has_expired)
1309 es_putc ('e', es_stdout);
1310 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1314 trustletter = get_validity_info (pk, NULL);
1315 if (trustletter == 'u')
1317 es_putc (trustletter, es_stdout);
1320 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1323 (ulong) keyid[0], (ulong) keyid[1],
1324 colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1326 if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1327 es_putc (get_ownertrust_info (pk), es_stdout);
1328 es_putc (':', es_stdout);
1330 es_putc (':', es_stdout);
1331 es_putc (':', es_stdout);
1332 print_capabilities (pk, keyblock);
1333 es_putc (':', es_stdout); /* End of field 13. */
1334 es_putc (':', es_stdout); /* End of field 14. */
1335 if (secret || has_secret)
1338 es_putc ('#', es_stdout);
1340 es_fputs (serialno, es_stdout);
1341 else if (has_secret)
1342 es_putc ('+', es_stdout);
1344 es_putc (':', es_stdout); /* End of field 15. */
1345 es_putc (':', es_stdout); /* End of field 16. */
1346 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1347 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1348 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1350 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1351 const char *name = openpgp_oid_to_curve (curve);
1352 if (!*name || *name == '?')
1354 es_fputs (name, es_stdout);
1357 es_putc (':', es_stdout); /* End of field 17. */
1358 es_putc ('\n', es_stdout);
1360 print_revokers (es_stdout, pk);
1362 print_fingerprint (NULL, pk, 0);
1363 if (opt.with_key_data || opt.with_keygrip)
1366 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1367 if (opt.with_key_data)
1368 print_key_data (pk);
1371 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1373 if (node->pkt->pkttype == PKT_USER_ID)
1376 PKT_user_id *uid = node->pkt->pkt.user_id;
1378 if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1379 dump_attribs (node->pkt->pkt.user_id, pk);
1381 * Fixme: We need a valid flag here too
1383 str = uid->attrib_data ? "uat" : "uid";
1384 if (uid->is_revoked)
1385 es_fprintf (es_stdout, "%s:r::::", str);
1386 else if (uid->is_expired)
1387 es_fprintf (es_stdout, "%s:e::::", str);
1388 else if (opt.no_expensive_trust_checks)
1389 es_fprintf (es_stdout, "%s:::::", str);
1395 uid_validity = get_validity_info (pk, uid);
1398 es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1401 es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1402 es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1404 namehash_from_uid (uid);
1406 for (i = 0; i < 20; i++)
1407 es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1409 es_fprintf (es_stdout, "::");
1411 if (uid->attrib_data)
1412 es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1414 es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1415 es_putc (':', es_stdout);
1416 es_putc ('\n', es_stdout);
1418 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1421 PKT_public_key *pk2;
1423 pk2 = node->pkt->pkt.public_key;
1424 xfree (hexgrip); hexgrip = NULL;
1425 xfree (serialno); serialno = NULL;
1426 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1428 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1430 log_error ("error computing a keygrip: %s\n",
1434 if ((secret||has_secret)
1435 && agent_get_keyinfo (NULL, hexgrip, &serialno))
1436 stubkey = 1; /* Key not found. */
1438 keyid_from_pk (pk2, keyid2);
1439 es_fputs (secret? "ssb:":"sub:", es_stdout);
1440 if (!pk2->flags.valid)
1441 es_putc ('i', es_stdout);
1442 else if (pk2->flags.revoked)
1443 es_putc ('r', es_stdout);
1444 else if (pk2->has_expired)
1445 es_putc ('e', es_stdout);
1446 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1450 /* TRUSTLETTER should always be defined here. */
1452 es_fprintf (es_stdout, "%c", trustletter);
1454 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1455 nbits_from_pk (pk2),
1457 (ulong) keyid2[0], (ulong) keyid2[1],
1458 colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1459 /* fixme: add LID and ownertrust here */
1461 print_capabilities (pk2, NULL);
1462 es_putc (':', es_stdout); /* End of field 13. */
1463 es_putc (':', es_stdout); /* End of field 14. */
1464 if (secret || has_secret)
1467 es_putc ('#', es_stdout);
1469 es_fputs (serialno, es_stdout);
1470 else if (has_secret)
1471 es_putc ('+', es_stdout);
1473 es_putc (':', es_stdout); /* End of field 15. */
1474 es_putc (':', es_stdout); /* End of field 16. */
1475 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1476 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1477 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1479 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1480 const char *name = openpgp_oid_to_curve (curve);
1481 if (!*name || *name == '?')
1483 es_fputs (name, es_stdout);
1486 es_putc (':', es_stdout); /* End of field 17. */
1487 es_putc ('\n', es_stdout);
1489 print_fingerprint (NULL, pk2, 0);
1490 if (opt.with_key_data || opt.with_keygrip)
1493 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1494 if (opt.with_key_data)
1495 print_key_data (pk2);
1498 else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1500 PKT_signature *sig = node->pkt->pkt.signature;
1501 int sigrc, fprokay = 0;
1504 byte fparray[MAX_FINGERPRINT_LEN];
1506 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1507 || sig->sig_class == 0x30)
1509 else if ((sig->sig_class & ~3) == 0x10)
1511 else if (sig->sig_class == 0x18)
1513 else if (sig->sig_class == 0x1F)
1517 es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1518 sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1524 PKT_public_key *signer_pk = NULL;
1527 if (opt.no_sig_cache)
1528 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1530 rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1532 switch (gpg_err_code (rc))
1537 case GPG_ERR_BAD_SIGNATURE:
1540 case GPG_ERR_NO_PUBKEY:
1541 case GPG_ERR_UNUSABLE_PUBKEY:
1549 if (opt.no_sig_cache)
1553 fingerprint_from_pk (signer_pk, fparray, &fplen);
1556 free_public_key (signer_pk);
1564 es_fputs (sigstr, es_stdout);
1565 es_putc (':', es_stdout);
1567 es_putc (sigrc, es_stdout);
1568 es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1569 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1570 colon_datestr_from_sig (sig),
1571 colon_expirestr_from_sig (sig));
1573 if (sig->trust_depth || sig->trust_value)
1574 es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1575 es_fprintf (es_stdout, ":");
1577 if (sig->trust_regexp)
1578 es_write_sanitized (es_stdout, sig->trust_regexp,
1579 strlen (sig->trust_regexp), ":", NULL);
1580 es_fprintf (es_stdout, ":");
1583 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1584 else if (sigrc == '?')
1586 else if (!opt.fast_list_mode)
1589 p = get_user_id (sig->keyid, &n);
1590 es_write_sanitized (es_stdout, p, n, ":", NULL);
1593 es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1594 sig->flags.exportable ? 'x' : 'l');
1596 if (opt.no_sig_cache && opt.check_sigs && fprokay)
1598 for (i = 0; i < fplen; i++)
1599 es_fprintf (es_stdout, "%02X", fparray[i]);
1602 es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1604 if (opt.show_subpackets)
1605 print_subpackets_colon (sig);
1607 /* fixme: check or list other sigs here */
1616 * Reorder the keyblock so that the primary user ID (and not attribute
1617 * packet) comes first. Fixme: Replace this by a generic sort
1620 do_reorder_keyblock (KBNODE keyblock, int attr)
1622 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1625 for (node = keyblock; node; primary0 = node, node = node->next)
1627 if (node->pkt->pkttype == PKT_USER_ID &&
1628 ((attr && node->pkt->pkt.user_id->attrib_data) ||
1629 (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1630 node->pkt->pkt.user_id->is_primary)
1632 primary = primary2 = node;
1633 for (node = node->next; node; primary2 = node, node = node->next)
1635 if (node->pkt->pkttype == PKT_USER_ID
1636 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1637 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1646 return; /* No primary key flag found (should not happen). */
1648 for (last = NULL, node = keyblock; node; last = node, node = node->next)
1650 if (node->pkt->pkttype == PKT_USER_ID)
1654 assert (last); /* The user ID is never the first packet. */
1655 assert (primary0); /* Ditto (this is the node before primary). */
1656 if (node == primary)
1657 return; /* Already the first one. */
1659 last->next = primary;
1660 primary0->next = primary2->next;
1661 primary2->next = node;
1665 reorder_keyblock (KBNODE keyblock)
1667 do_reorder_keyblock (keyblock, 1);
1668 do_reorder_keyblock (keyblock, 0);
1672 list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
1673 struct keylist_context *listctx)
1675 reorder_keyblock (keyblock);
1676 if (opt.print_pka_records)
1677 list_keyblock_pka (keyblock);
1678 else if (opt.with_colons)
1679 list_keyblock_colon (keyblock, secret, has_secret, fpr);
1681 list_keyblock_print (keyblock, secret, fpr, listctx);
1683 es_fflush (es_stdout);
1687 /* Public function used by keygen to list a keyblock. */
1689 list_keyblock_direct (kbnode_t keyblock, int secret, int has_secret, int fpr)
1691 struct keylist_context listctx;
1693 memset (&listctx, 0, sizeof (listctx));
1694 list_keyblock (keyblock, secret, has_secret, fpr, &listctx);
1695 keylist_context_release (&listctx);
1699 /* Print an hex digit in ICAO spelling. */
1701 print_icao_hexdigit (estream_t fp, int c)
1703 static const char *list[16] = {
1704 "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1705 "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1708 tty_fprintf (fp, "%s", list[c&15]);
1713 * Function to print the finperprint.
1714 * mode 0: as used in key listings, opt.with_colons is honored
1715 * 1: print using log_info ()
1716 * 2: direct use of tty
1717 * 3: direct use of tty but only primary key.
1718 * 10: Same as 0 but with_colons etc is ignored.
1720 * Modes 1 and 2 will try and print both subkey and primary key
1721 * fingerprints. A MODE with bit 7 set is used internally. If
1722 * OVERRIDE_FP is not NULL that stream will be used in 0 instead
1723 * of es_stdout or instead of the TTY in modes 2 and 3.
1726 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1728 byte array[MAX_FINGERPRINT_LEN], *p;
1733 int with_colons = opt.with_colons;
1734 int with_icao = opt.with_icao_spelling;
1743 if (pk->main_keyid[0] == pk->keyid[0]
1744 && pk->main_keyid[1] == pk->keyid[1])
1747 /* Just to be safe */
1748 if ((mode & 0x80) && !primary)
1750 log_error ("primary key is not really primary!\n");
1756 if (!primary && (mode == 1 || mode == 2))
1758 PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1759 get_pubkey (primary_pk, pk->main_keyid);
1760 print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1761 free_public_key (primary_pk);
1766 fp = log_get_stream ();
1768 text = _("Primary key fingerprint:");
1770 text = _(" Subkey fingerprint:");
1774 fp = override_fp; /* Use tty or given stream. */
1776 /* TRANSLATORS: this should fit into 24 bytes to that the
1777 * fingerprint data is properly aligned with the user ID */
1778 text = _(" Primary key fingerprint:");
1780 text = _(" Subkey fingerprint:");
1784 fp = override_fp; /* Use tty or given stream. */
1785 text = _(" Key fingerprint =");
1789 fp = override_fp? override_fp : es_stdout;
1790 text = _(" Key fingerprint =");
1793 fingerprint_from_pk (pk, array, &n);
1795 if (with_colons && !mode)
1797 es_fprintf (fp, "fpr:::::::::");
1798 for (i = 0; i < n; i++, p++)
1799 es_fprintf (fp, "%02X", *p);
1804 tty_fprintf (fp, "%s", text);
1807 for (i = 0; i < n; i++, i++, p += 2)
1808 tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
1812 for (i = 0; i < n; i++, p++)
1813 tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
1816 tty_fprintf (fp, "\n");
1817 if (!with_colons && with_icao)
1820 tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1821 for (i = 0; i < n; i++, p++)
1826 tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
1828 tty_fprintf (fp, " ");
1830 tty_fprintf (fp, " ");
1831 print_icao_hexdigit (fp, *p >> 4);
1832 tty_fprintf (fp, " ");
1833 print_icao_hexdigit (fp, *p & 15);
1835 tty_fprintf (fp, "\"\n");
1839 /* Print the serial number of an OpenPGP card if available. */
1841 print_card_serialno (const char *serialno)
1845 if (opt.with_colons)
1846 return; /* Handled elsewhere. */
1848 es_fputs (_(" Card serial no. ="), es_stdout);
1849 es_putc (' ', es_stdout);
1850 if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1852 /* This is an OpenPGP card. Print the relevant part. */
1853 /* Example: D2760001240101010001000003470000 */
1855 es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1858 es_fputs (serialno, es_stdout);
1859 es_putc ('\n', es_stdout);
1865 set_attrib_fd (int fd)
1867 static int last_fd = -1;
1869 if (fd != -1 && last_fd == fd)
1872 /* Fixme: Do we need to check for the log stream here? */
1873 if (attrib_fp && attrib_fp != log_get_stream ())
1874 es_fclose (attrib_fp);
1879 #ifdef HAVE_DOSISH_SYSTEM
1880 setmode (fd, O_BINARY);
1883 attrib_fp = es_stdout;
1885 attrib_fp = es_stderr;
1887 attrib_fp = es_fdopen (fd, "wb");
1890 log_fatal ("can't open fd %d for attribute output: %s\n",
1891 fd, strerror (errno));