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, "%s %s/%s %s %s\n",
191 pk->flags.primary? "pub":"sub",
192 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
193 keystr (keyid), datestr_from_pk (pk), p);
198 /* Print basic information of a secret key including the card serial
199 number information. */
200 #ifdef ENABLE_CARD_SUPPORT
202 print_card_key_info (estream_t fp, kbnode_t keyblock)
208 char pkstrbuf[PUBKEY_STRING_SIZE];
211 for (node = keyblock; node; node = node->next)
213 if (node->pkt->pkttype == PKT_PUBLIC_KEY
214 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
217 PKT_public_key *pk = node->pkt->pkt.public_key;
220 rc = hexkeygrip_from_pk (pk, &hexgrip);
223 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
226 else if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
227 s2k_char = serialno? '>':' ';
229 s2k_char = '#'; /* Key not found. */
231 tty_fprintf (fp, "%s%c %s/%s %n",
232 node->pkt->pkttype == PKT_PUBLIC_KEY ? "sec" : "ssb",
234 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
237 tty_fprintf (fp, _("created: %s"), datestr_from_pk (pk));
238 tty_fprintf (fp, " ");
239 tty_fprintf (fp, _("expires: %s"), expirestr_from_pk (pk));
242 tty_fprintf (fp, "\n%*s%s", indent, "", _("card-no: "));
243 if (strlen (serialno) == 32
244 && !strncmp (serialno, "D27600012401", 12))
246 /* This is an OpenPGP card. Print the relevant part. */
247 /* Example: D2760001240101010001000003470000 */
249 tty_fprintf (fp, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
252 tty_fprintf (fp, "%s", serialno);
254 tty_fprintf (fp, "\n");
260 #endif /*ENABLE_CARD_SUPPORT*/
263 /* Flags = 0x01 hashed 0x02 critical. */
265 status_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
270 /* Don't print these. */
274 snprintf (status, sizeof status,
275 "%d %u %u ", type, flags, (unsigned int) len);
277 write_status_text_and_buffer (STATUS_SIG_SUBPACKET, status, buf, len, 0);
281 /* Print a policy URL. Allowed values for MODE are:
282 * 0 - print to stdout.
283 * 1 - use log_info and emit status messages.
284 * 2 - emit only status messages.
287 show_policy_url (PKT_signature * sig, int indent, int mode)
292 estream_t fp = mode ? log_get_stream () : es_stdout;
295 enum_sig_subpkt (sig->hashed, SIGSUBPKT_POLICY, &len, &seq, &crit)))
302 for (i = 0; i < indent; i++)
306 str = _("Critical signature policy: ");
308 str = _("Signature policy: ");
310 log_info ("%s", str);
312 es_fprintf (fp, "%s", str);
313 print_utf8_buffer (fp, p, len);
314 es_fprintf (fp, "\n");
318 write_status_buffer (STATUS_POLICY_URL, p, len, 0);
325 mode=1 for log_info + status messages
326 mode=2 for status messages only
330 show_keyserver_url (PKT_signature * sig, int indent, int mode)
335 estream_t fp = mode ? log_get_stream () : es_stdout;
338 enum_sig_subpkt (sig->hashed, SIGSUBPKT_PREF_KS, &len, &seq,
346 for (i = 0; i < indent; i++)
347 es_putc (' ', es_stdout);
350 str = _("Critical preferred keyserver: ");
352 str = _("Preferred keyserver: ");
354 log_info ("%s", str);
356 es_fprintf (es_stdout, "%s", str);
357 print_utf8_buffer (fp, p, len);
358 es_fprintf (fp, "\n");
362 status_one_subpacket (SIGSUBPKT_PREF_KS, len,
363 (crit ? 0x02 : 0) | 0x01, p);
369 mode=1 for log_info + status messages
370 mode=2 for status messages only
372 Defined bits in WHICH:
373 1 == standard notations
377 show_notation (PKT_signature * sig, int indent, int mode, int which)
379 estream_t fp = mode ? log_get_stream () : es_stdout;
380 struct notation *nd, *notations;
385 notations = sig_to_notation (sig);
387 /* There may be multiple notations in the same sig. */
388 for (nd = notations; nd; nd = nd->next)
392 int has_at = !!strchr (nd->name, '@');
394 if ((which & 1 && !has_at) || (which & 2 && has_at))
399 for (i = 0; i < indent; i++)
400 es_putc (' ', es_stdout);
402 if (nd->flags.critical)
403 str = _("Critical signature notation: ");
405 str = _("Signature notation: ");
407 log_info ("%s", str);
409 es_fprintf (es_stdout, "%s", str);
410 /* This is all UTF8 */
411 print_utf8_buffer (fp, nd->name, strlen (nd->name));
412 es_fprintf (fp, "=");
413 print_utf8_buffer (fp, nd->value, strlen (nd->value));
414 /* (We need to use log_printf so that the next call to a
415 log function does not insert an extra LF.) */
425 write_status_buffer (STATUS_NOTATION_NAME,
426 nd->name, strlen (nd->name), 0);
427 write_status_buffer (STATUS_NOTATION_DATA,
428 nd->value, strlen (nd->value), 50);
432 free_notation (notations);
437 print_signature_stats (struct keylist_context *s)
440 return; /* Signature checking was not requested. */
442 if (s->inv_sigs == 1)
443 tty_printf (_("1 bad signature\n"));
444 else if (s->inv_sigs)
445 tty_printf (_("%d bad signatures\n"), s->inv_sigs);
447 tty_printf (_("1 signature not checked due to a missing key\n"));
449 tty_printf (_("%d signatures not checked due to missing keys\n"),
452 tty_printf (_("1 signature not checked due to an error\n"));
454 tty_printf (_("%d signatures not checked due to errors\n"), s->oth_err);
458 /* List all keys. If SECRET is true only secret keys are listed. If
459 MARK_SECRET is true secret keys are indicated in a public key
462 list_all (int secret, int mark_secret)
465 KBNODE keyblock = NULL;
468 const char *lastresname, *resname;
469 struct keylist_context listctx;
471 memset (&listctx, 0, sizeof (listctx));
473 listctx.check_sigs = 1;
477 rc = gpg_error (GPG_ERR_GENERAL);
479 rc = keydb_search_first (hd);
482 if (gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
483 log_error ("keydb_search_first failed: %s\n", gpg_strerror (rc));
490 rc = keydb_get_keyblock (hd, &keyblock);
493 if (gpg_err_code (rc) == GPG_ERR_LEGACY_KEY)
494 continue; /* Skip legacy keys. */
495 log_error ("keydb_get_keyblock failed: %s\n", gpg_strerror (rc));
499 if (secret || mark_secret)
500 any_secret = !agent_probe_any_secret_key (NULL, keyblock);
504 if (secret && !any_secret)
505 ; /* Secret key listing requested but this isn't one. */
508 if (!opt.with_colons)
510 resname = keydb_get_resource_name (hd);
511 if (lastresname != resname)
515 es_fprintf (es_stdout, "%s\n", resname);
516 for (i = strlen (resname); i; i--)
517 es_putc ('-', es_stdout);
518 es_putc ('\n', es_stdout);
519 lastresname = resname;
522 merge_keys_and_selfsig (keyblock);
523 list_keyblock (keyblock, secret, any_secret, opt.fingerprint,
526 release_kbnode (keyblock);
529 while (!(rc = keydb_search_next (hd)));
530 es_fflush (es_stdout);
531 if (rc && gpg_err_code (rc) != GPG_ERR_NOT_FOUND)
532 log_error ("keydb_search_next failed: %s\n", gpg_strerror (rc));
533 if (keydb_get_skipped_counter (hd))
534 log_info (_("Warning: %lu key(s) skipped due to their large size\n"),
535 keydb_get_skipped_counter (hd));
537 if (opt.check_sigs && !opt.with_colons)
538 print_signature_stats (&listctx);
541 keylist_context_release (&listctx);
542 release_kbnode (keyblock);
548 list_one (strlist_t names, int secret, int mark_secret)
551 KBNODE keyblock = NULL;
554 const char *keyring_str = _("Keyring");
556 struct keylist_context listctx;
558 memset (&listctx, 0, sizeof (listctx));
559 if (!secret && opt.check_sigs)
560 listctx.check_sigs = 1;
562 /* fixme: using the bynames function has the disadvantage that we
563 * don't know wether one of the names given was not found. OTOH,
564 * this function has the advantage to list the names in the
565 * sequence as defined by the keyDB and does not duplicate
566 * outputs. A solution could be do test whether all given have
567 * been listed (this needs a way to use the keyDB search
568 * functions) or to have the search function return indicators for
569 * found names. Yet another way is to use the keydb search
570 * facilities directly. */
571 rc = getkey_bynames (&ctx, NULL, names, secret, &keyblock);
574 log_error ("error reading key: %s\n", gpg_strerror (rc));
575 get_pubkey_end (ctx);
581 if ((opt.list_options & LIST_SHOW_KEYRING) && !opt.with_colons)
583 resname = keydb_get_resource_name (get_ctx_handle (ctx));
584 es_fprintf (es_stdout, "%s: %s\n", keyring_str, resname);
585 for (i = strlen (resname) + strlen (keyring_str) + 2; i; i--)
586 es_putc ('-', es_stdout);
587 es_putc ('\n', es_stdout);
589 list_keyblock (keyblock, secret, mark_secret, opt.fingerprint, &listctx);
590 release_kbnode (keyblock);
592 while (!getkey_next (ctx, NULL, &keyblock));
595 if (opt.check_sigs && !opt.with_colons)
596 print_signature_stats (&listctx);
598 keylist_context_release (&listctx);
603 locate_one (ctrl_t ctrl, strlist_t names)
607 GETKEY_CTX ctx = NULL;
608 KBNODE keyblock = NULL;
609 struct keylist_context listctx;
611 memset (&listctx, 0, sizeof (listctx));
613 listctx.check_sigs = 1;
615 for (sl = names; sl; sl = sl->next)
617 rc = get_pubkey_byname (ctrl, &ctx, NULL, sl->d, &keyblock, NULL, 1, 0);
620 if (gpg_err_code (rc) != GPG_ERR_NO_PUBKEY)
621 log_error ("error reading key: %s\n", gpg_strerror (rc));
627 list_keyblock (keyblock, 0, 0, opt.fingerprint, &listctx);
628 release_kbnode (keyblock);
630 while (ctx && !get_pubkey_next (ctx, NULL, &keyblock));
631 get_pubkey_end (ctx);
636 if (opt.check_sigs && !opt.with_colons)
637 print_signature_stats (&listctx);
639 keylist_context_release (&listctx);
644 print_key_data (PKT_public_key * pk)
646 int n = pk ? pubkey_get_npkey (pk->pubkey_algo) : 0;
649 for (i = 0; i < n; i++)
651 es_fprintf (es_stdout, "pkd:%d:%u:", i, mpi_get_nbits (pk->pkey[i]));
652 mpi_print (es_stdout, pk->pkey[i], 1);
653 es_putc (':', es_stdout);
654 es_putc ('\n', es_stdout);
659 print_capabilities (PKT_public_key *pk, KBNODE keyblock)
661 unsigned int use = pk->pubkey_usage;
664 if (use & PUBKEY_USAGE_ENC)
665 es_putc ('e', es_stdout);
667 if (use & PUBKEY_USAGE_SIG)
669 es_putc ('s', es_stdout);
670 if (pk->flags.primary)
672 es_putc ('c', es_stdout);
673 /* The PUBKEY_USAGE_CERT flag was introduced later and we
674 used to always print 'c' for a primary key. To avoid any
675 regression here we better track whether we printed 'c'
681 if ((use & PUBKEY_USAGE_CERT) && !c_printed)
682 es_putc ('c', es_stdout);
684 if ((use & PUBKEY_USAGE_AUTH))
685 es_putc ('a', es_stdout);
687 if ((use & PUBKEY_USAGE_UNKNOWN))
688 es_putc ('?', es_stdout);
692 /* Figure out the usable capabilities. */
694 int enc = 0, sign = 0, cert = 0, auth = 0, disabled = 0;
696 for (k = keyblock; k; k = k->next)
698 if (k->pkt->pkttype == PKT_PUBLIC_KEY
699 || k->pkt->pkttype == PKT_PUBLIC_SUBKEY)
701 pk = k->pkt->pkt.public_key;
703 if (pk->flags.primary)
704 disabled = pk_is_disabled (pk);
706 if (pk->flags.valid && !pk->flags.revoked && !pk->has_expired)
708 if (pk->pubkey_usage & PUBKEY_USAGE_ENC)
710 if (pk->pubkey_usage & PUBKEY_USAGE_SIG)
713 if (pk->flags.primary)
716 if (pk->pubkey_usage & PUBKEY_USAGE_CERT)
718 if ((pk->pubkey_usage & PUBKEY_USAGE_AUTH))
724 es_putc ('E', es_stdout);
726 es_putc ('S', es_stdout);
728 es_putc ('C', es_stdout);
730 es_putc ('A', es_stdout);
732 es_putc ('D', es_stdout);
735 es_putc (':', es_stdout);
739 /* FLAGS: 0x01 hashed
742 print_one_subpacket (sigsubpkttype_t type, size_t len, int flags,
747 es_fprintf (es_stdout, "spk:%d:%u:%u:", type, flags, (unsigned int) len);
749 for (i = 0; i < len; i++)
751 /* printable ascii other than : and % */
752 if (buf[i] >= 32 && buf[i] <= 126 && buf[i] != ':' && buf[i] != '%')
753 es_fprintf (es_stdout, "%c", buf[i]);
755 es_fprintf (es_stdout, "%%%02X", buf[i]);
758 es_fprintf (es_stdout, "\n");
763 print_subpackets_colon (PKT_signature * sig)
767 assert (opt.show_subpackets);
769 for (i = opt.show_subpackets; *i; i++)
777 while ((p = enum_sig_subpkt (sig->hashed, *i, &len, &seq, &crit)))
778 print_one_subpacket (*i, len, 0x01 | (crit ? 0x02 : 0), p);
782 while ((p = enum_sig_subpkt (sig->unhashed, *i, &len, &seq, &crit)))
783 print_one_subpacket (*i, len, 0x00 | (crit ? 0x02 : 0), p);
789 dump_attribs (const PKT_user_id *uid, PKT_public_key *pk)
796 for (i = 0; i < uid->numattribs; i++)
798 if (is_status_enabled ())
800 byte array[MAX_FINGERPRINT_LEN], *p;
801 char buf[(MAX_FINGERPRINT_LEN * 2) + 90];
806 fingerprint_from_pk (pk, array, &n);
809 for (j = 0; j < n; j++, p++)
810 sprintf (buf + 2 * j, "%02X", *p);
812 sprintf (buf + strlen (buf), " %lu %u %u %u %lu %lu %u",
813 (ulong) uid->attribs[i].len, uid->attribs[i].type, i + 1,
814 uid->numattribs, (ulong) uid->created,
815 (ulong) uid->expiredate,
816 ((uid->is_primary ? 0x01 : 0) | (uid->
817 is_revoked ? 0x02 : 0) |
818 (uid->is_expired ? 0x04 : 0)));
819 write_status_text (STATUS_ATTRIBUTE, buf);
822 es_fwrite (uid->attribs[i].data, uid->attribs[i].len, 1, attrib_fp);
823 es_fflush (attrib_fp);
828 /* Print IPGP cert records instead of a standard key listing. */
830 list_keyblock_pka (kbnode_t keyblock)
835 char pkstrbuf[PUBKEY_STRING_SIZE];
838 /* Get the keyid from the keyblock. */
839 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
842 log_error ("Oops; key lost!\n");
843 dump_kbnode (keyblock);
847 pk = node->pkt->pkt.public_key;
849 es_fprintf (es_stdout, ";; pub %s/%s %s\n;; ",
850 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
851 keystr_from_pk (pk), datestr_from_pk (pk));
852 print_fingerprint (NULL, pk, 10);
853 hexfpr = hexfingerprint (pk);
855 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
857 if (node->pkt->pkttype == PKT_USER_ID)
859 PKT_user_id *uid = node->pkt->pkt.user_id;
863 if (pk && (uid->is_expired || uid->is_revoked)
864 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
867 es_fputs (";; uid ", es_stdout);
868 print_utf8_buffer (es_stdout, uid->name, uid->len);
869 es_putc ('\n', es_stdout);
870 mbox = mailbox_from_userid (uid->name);
871 if (mbox && (p = strchr (mbox, '@')))
878 es_fprintf (es_stdout, "$ORIGIN _pka.%s.\n", p);
879 gcry_md_hash_buffer (GCRY_MD_SHA1, hashbuf, mbox, strlen (mbox));
880 hash = zb32_encode (hashbuf, 8*20);
883 len = strlen (hexfpr)/2;
884 es_fprintf (es_stdout,
885 "%s TYPE37 \\# %u 0006 0000 00 %02X %s\n",
886 hash, 6 + len, len, hexfpr);
894 es_putc ('\n', es_stdout);
901 list_keyblock_print (KBNODE keyblock, int secret, int fpr,
902 struct keylist_context *listctx)
910 char *hexgrip = NULL;
911 char *serialno = NULL;
912 char pkstrbuf[PUBKEY_STRING_SIZE];
914 /* Get the keyid from the keyblock. */
915 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
918 log_error ("Oops; key lost!\n");
919 dump_kbnode (keyblock);
923 pk = node->pkt->pkt.public_key;
925 if (secret || opt.with_keygrip)
927 rc = hexkeygrip_from_pk (pk, &hexgrip);
929 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
934 if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
935 s2k_char = serialno? '>':' ';
937 s2k_char = '#'; /* Key not found. */
942 check_trustdb_stale ();
945 es_fprintf (es_stdout, "%s%c %s/%s %s",
948 pubkey_string (pk, pkstrbuf, sizeof pkstrbuf),
949 keystr_from_pk (pk), datestr_from_pk (pk));
951 if ((opt.list_options & LIST_SHOW_USAGE))
953 es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk, 0));
955 if (pk->flags.revoked)
957 es_fprintf (es_stdout, " [");
958 es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk));
959 es_fprintf (es_stdout, "]");
961 else if (pk->has_expired)
963 es_fprintf (es_stdout, " [");
964 es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk));
965 es_fprintf (es_stdout, "]");
967 else if (pk->expiredate)
969 es_fprintf (es_stdout, " [");
970 es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk));
971 es_fprintf (es_stdout, "]");
975 /* I need to think about this some more. It's easy enough to
976 include, but it looks sort of confusing in the listing... */
977 if (opt.list_options & LIST_SHOW_VALIDITY)
979 int validity = get_validity (pk, NULL);
980 es_fprintf (es_stdout, " [%s]", trust_value_to_string (validity));
984 if (pk->pubkey_algo >= 100)
985 es_fprintf (es_stdout, " [experimental algorithm %d]", pk->pubkey_algo);
987 es_fprintf (es_stdout, "\n");
990 print_fingerprint (NULL, pk, 0);
992 if (opt.with_keygrip && hexgrip)
993 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
996 print_card_serialno (serialno);
998 if (opt.with_key_data)
1001 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1003 if (node->pkt->pkttype == PKT_USER_ID)
1005 PKT_user_id *uid = node->pkt->pkt.user_id;
1007 if ((uid->is_expired || uid->is_revoked)
1008 && !(opt.list_options & LIST_SHOW_UNUSABLE_UIDS))
1016 if (attrib_fp && uid->attrib_data != NULL)
1017 dump_attribs (uid, pk);
1019 if ((uid->is_revoked || uid->is_expired)
1020 || (opt.list_options & LIST_SHOW_UID_VALIDITY))
1022 const char *validity;
1025 validity = uid_trust_string_fixed (pk, uid);
1027 (keystrlen () + 9) -
1028 atoi (uid_trust_string_fixed (NULL, NULL));
1030 if (indent < 0 || indent > 40)
1033 es_fprintf (es_stdout, "uid%*s%s ", indent, "", validity);
1036 es_fprintf (es_stdout, "uid%*s", (int) keystrlen () + 10, "");
1038 print_utf8_buffer (es_stdout, uid->name, uid->len);
1039 es_putc ('\n', es_stdout);
1041 if ((opt.list_options & LIST_SHOW_PHOTOS) && uid->attribs != NULL)
1042 show_photos (uid->attribs, uid->numattribs, pk, uid);
1044 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1046 PKT_public_key *pk2 = node->pkt->pkt.public_key;
1048 if ((pk2->flags.revoked || pk2->has_expired)
1049 && !(opt.list_options & LIST_SHOW_UNUSABLE_SUBKEYS))
1057 xfree (serialno); serialno = NULL;
1058 xfree (hexgrip); hexgrip = NULL;
1059 if (secret || opt.with_keygrip)
1061 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1063 log_error ("error computing a keygrip: %s\n",
1068 if (!agent_get_keyinfo (NULL, hexgrip, &serialno))
1069 s2k_char = serialno? '>':' ';
1071 s2k_char = '#'; /* Key not found. */
1076 es_fprintf (es_stdout, "%s%c %s/%s %s",
1077 secret? "ssb":"sub",
1079 pubkey_string (pk2, pkstrbuf, sizeof pkstrbuf),
1080 keystr_from_pk (pk2), datestr_from_pk (pk2));
1082 if (pk2->pubkey_algo == PUBKEY_ALGO_ECDSA
1083 || pk2->pubkey_algo == PUBKEY_ALGO_EDDSA
1084 || pk2->pubkey_algo == PUBKEY_ALGO_ECDH)
1086 char *curve = openpgp_oid_to_str (pk2->pkey[0]);
1087 const char *name = openpgp_oid_to_curve (curve);
1088 if (!*name || *name == '?')
1090 es_fprintf (es_stdout, " %s", name);
1094 if ((opt.list_options & LIST_SHOW_USAGE))
1096 es_fprintf (es_stdout, " [%s]", usagestr_from_pk (pk2, 0));
1098 if (pk2->flags.revoked)
1100 es_fprintf (es_stdout, " [");
1101 es_fprintf (es_stdout, _("revoked: %s"), revokestr_from_pk (pk2));
1102 es_fprintf (es_stdout, "]");
1104 else if (pk2->has_expired)
1106 es_fprintf (es_stdout, " [");
1107 es_fprintf (es_stdout, _("expired: %s"), expirestr_from_pk (pk2));
1108 es_fprintf (es_stdout, "]");
1110 else if (pk2->expiredate)
1112 es_fprintf (es_stdout, " [");
1113 es_fprintf (es_stdout, _("expires: %s"), expirestr_from_pk (pk2));
1114 es_fprintf (es_stdout, "]");
1116 es_putc ('\n', es_stdout);
1119 print_fingerprint (NULL, pk2, 0);
1121 print_card_serialno (serialno);
1123 if (opt.with_keygrip && hexgrip)
1124 es_fprintf (es_stdout, " Keygrip = %s\n", hexgrip);
1125 if (opt.with_key_data)
1126 print_key_data (pk2);
1128 else if (opt.list_sigs
1129 && node->pkt->pkttype == PKT_SIGNATURE && !skip_sigs)
1131 PKT_signature *sig = node->pkt->pkt.signature;
1135 if (listctx->check_sigs)
1137 rc = check_key_signature (keyblock, node, NULL);
1138 switch (gpg_err_code (rc))
1143 case GPG_ERR_BAD_SIGNATURE:
1144 listctx->inv_sigs++;
1147 case GPG_ERR_NO_PUBKEY:
1148 case GPG_ERR_UNUSABLE_PUBKEY:
1157 /* TODO: Make sure a cached sig record here still has
1158 the pk that issued it. See also
1159 keyedit.c:print_and_check_one_sig */
1167 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1168 || sig->sig_class == 0x30)
1170 else if ((sig->sig_class & ~3) == 0x10)
1172 else if (sig->sig_class == 0x18)
1174 else if (sig->sig_class == 0x1F)
1178 es_fprintf (es_stdout, "sig "
1179 "[unexpected signature class 0x%02x]\n",
1184 es_fputs (sigstr, es_stdout);
1185 es_fprintf (es_stdout, "%c%c %c%c%c%c%c%c %s %s",
1186 sigrc, (sig->sig_class - 0x10 > 0 &&
1187 sig->sig_class - 0x10 <
1188 4) ? '0' + sig->sig_class - 0x10 : ' ',
1189 sig->flags.exportable ? ' ' : 'L',
1190 sig->flags.revocable ? ' ' : 'R',
1191 sig->flags.policy_url ? 'P' : ' ',
1192 sig->flags.notation ? 'N' : ' ',
1193 sig->flags.expired ? 'X' : ' ',
1194 (sig->trust_depth > 9) ? 'T' : (sig->trust_depth >
1196 sig->trust_depth : ' ', keystr (sig->keyid),
1197 datestr_from_sig (sig));
1198 if (opt.list_options & LIST_SHOW_SIG_EXPIRE)
1199 es_fprintf (es_stdout, " %s", expirestr_from_sig (sig));
1200 es_fprintf (es_stdout, " ");
1202 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1203 else if (sigrc == '?')
1205 else if (!opt.fast_list_mode)
1208 char *p = get_user_id (sig->keyid, &n);
1209 print_utf8_buffer (es_stdout, p, n);
1212 es_putc ('\n', es_stdout);
1214 if (sig->flags.policy_url
1215 && (opt.list_options & LIST_SHOW_POLICY_URLS))
1216 show_policy_url (sig, 3, 0);
1218 if (sig->flags.notation && (opt.list_options & LIST_SHOW_NOTATIONS))
1219 show_notation (sig, 3, 0,
1221 list_options & LIST_SHOW_STD_NOTATIONS) ? 1 : 0)
1224 list_options & LIST_SHOW_USER_NOTATIONS) ? 2 :
1227 if (sig->flags.pref_ks
1228 && (opt.list_options & LIST_SHOW_KEYSERVER_URLS))
1229 show_keyserver_url (sig, 3, 0);
1231 /* fixme: check or list other sigs here */
1234 es_putc ('\n', es_stdout);
1240 print_revokers (estream_t fp, PKT_public_key * pk)
1242 /* print the revoker record */
1243 if (!pk->revkey && pk->numrevkeys)
1249 for (i = 0; i < pk->numrevkeys; i++)
1253 es_fprintf (fp, "rvk:::%d::::::", pk->revkey[i].algid);
1254 p = pk->revkey[i].fpr;
1255 for (j = 0; j < 20; j++, p++)
1256 es_fprintf (fp, "%02X", *p);
1257 es_fprintf (fp, ":%02x%s:\n",
1258 pk->revkey[i].class,
1259 (pk->revkey[i].class & 0x40) ? "s" : "");
1265 /* List a key in colon mode. If SECRET is true this is a secret key
1266 record (i.e. requested via --list-secret-key). If HAS_SECRET a
1267 secret key is available even if SECRET is not set. */
1269 list_keyblock_colon (KBNODE keyblock, int secret, int has_secret, int fpr)
1276 int trustletter = 0;
1280 char *hexgrip = NULL;
1281 char *serialno = NULL;
1284 /* Get the keyid from the keyblock. */
1285 node = find_kbnode (keyblock, PKT_PUBLIC_KEY);
1288 log_error ("Oops; key lost!\n");
1289 dump_kbnode (keyblock);
1293 pk = node->pkt->pkt.public_key;
1294 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1296 rc = hexkeygrip_from_pk (pk, &hexgrip);
1298 log_error ("error computing a keygrip: %s\n", gpg_strerror (rc));
1301 if ((secret||has_secret) && agent_get_keyinfo (NULL, hexgrip, &serialno))
1302 stubkey = 1; /* Key not found. */
1304 keyid_from_pk (pk, keyid);
1305 es_fputs (secret? "sec:":"pub:", es_stdout);
1306 if (!pk->flags.valid)
1307 es_putc ('i', es_stdout);
1308 else if (pk->flags.revoked)
1309 es_putc ('r', es_stdout);
1310 else if (pk->has_expired)
1311 es_putc ('e', es_stdout);
1312 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1316 trustletter = get_validity_info (pk, NULL);
1317 if (trustletter == 'u')
1319 es_putc (trustletter, es_stdout);
1322 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s::",
1325 (ulong) keyid[0], (ulong) keyid[1],
1326 colon_datestr_from_pk (pk), colon_strtime (pk->expiredate));
1328 if (!opt.fast_list_mode && !opt.no_expensive_trust_checks)
1329 es_putc (get_ownertrust_info (pk), es_stdout);
1330 es_putc (':', es_stdout);
1332 es_putc (':', es_stdout);
1333 es_putc (':', es_stdout);
1334 print_capabilities (pk, keyblock);
1335 es_putc (':', es_stdout); /* End of field 13. */
1336 es_putc (':', es_stdout); /* End of field 14. */
1337 if (secret || has_secret)
1340 es_putc ('#', es_stdout);
1342 es_fputs (serialno, es_stdout);
1343 else if (has_secret)
1344 es_putc ('+', es_stdout);
1346 es_putc (':', es_stdout); /* End of field 15. */
1347 es_putc (':', es_stdout); /* End of field 16. */
1348 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1349 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1350 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1352 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1353 const char *name = openpgp_oid_to_curve (curve);
1354 if (!*name || *name == '?')
1356 es_fputs (name, es_stdout);
1359 es_putc (':', es_stdout); /* End of field 17. */
1360 es_putc ('\n', es_stdout);
1362 print_revokers (es_stdout, pk);
1364 print_fingerprint (NULL, pk, 0);
1365 if (opt.with_key_data || opt.with_keygrip)
1368 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1369 if (opt.with_key_data)
1370 print_key_data (pk);
1373 for (kbctx = NULL; (node = walk_kbnode (keyblock, &kbctx, 0));)
1375 if (node->pkt->pkttype == PKT_USER_ID)
1378 PKT_user_id *uid = node->pkt->pkt.user_id;
1380 if (attrib_fp && node->pkt->pkt.user_id->attrib_data != NULL)
1381 dump_attribs (node->pkt->pkt.user_id, pk);
1383 * Fixme: We need a valid flag here too
1385 str = uid->attrib_data ? "uat" : "uid";
1386 if (uid->is_revoked)
1387 es_fprintf (es_stdout, "%s:r::::", str);
1388 else if (uid->is_expired)
1389 es_fprintf (es_stdout, "%s:e::::", str);
1390 else if (opt.no_expensive_trust_checks)
1391 es_fprintf (es_stdout, "%s:::::", str);
1397 uid_validity = get_validity_info (pk, uid);
1400 es_fprintf (es_stdout, "%s:%c::::", str, uid_validity);
1403 es_fprintf (es_stdout, "%s:", colon_strtime (uid->created));
1404 es_fprintf (es_stdout, "%s:", colon_strtime (uid->expiredate));
1406 namehash_from_uid (uid);
1408 for (i = 0; i < 20; i++)
1409 es_fprintf (es_stdout, "%02X", uid->namehash[i]);
1411 es_fprintf (es_stdout, "::");
1413 if (uid->attrib_data)
1414 es_fprintf (es_stdout, "%u %lu", uid->numattribs, uid->attrib_len);
1416 es_write_sanitized (es_stdout, uid->name, uid->len, ":", NULL);
1417 es_putc (':', es_stdout);
1418 es_putc ('\n', es_stdout);
1420 else if (node->pkt->pkttype == PKT_PUBLIC_SUBKEY)
1423 PKT_public_key *pk2;
1425 pk2 = node->pkt->pkt.public_key;
1426 xfree (hexgrip); hexgrip = NULL;
1427 xfree (serialno); serialno = NULL;
1428 if (secret || has_secret || opt.with_keygrip || opt.with_key_data)
1430 rc = hexkeygrip_from_pk (pk2, &hexgrip);
1432 log_error ("error computing a keygrip: %s\n",
1436 if ((secret||has_secret)
1437 && agent_get_keyinfo (NULL, hexgrip, &serialno))
1438 stubkey = 1; /* Key not found. */
1440 keyid_from_pk (pk2, keyid2);
1441 es_fputs (secret? "ssb:":"sub:", es_stdout);
1442 if (!pk2->flags.valid)
1443 es_putc ('i', es_stdout);
1444 else if (pk2->flags.revoked)
1445 es_putc ('r', es_stdout);
1446 else if (pk2->has_expired)
1447 es_putc ('e', es_stdout);
1448 else if (opt.fast_list_mode || opt.no_expensive_trust_checks)
1452 /* TRUSTLETTER should always be defined here. */
1454 es_fprintf (es_stdout, "%c", trustletter);
1456 es_fprintf (es_stdout, ":%u:%d:%08lX%08lX:%s:%s:::::",
1457 nbits_from_pk (pk2),
1459 (ulong) keyid2[0], (ulong) keyid2[1],
1460 colon_datestr_from_pk (pk2), colon_strtime (pk2->expiredate)
1461 /* fixme: add LID and ownertrust here */
1463 print_capabilities (pk2, NULL);
1464 es_putc (':', es_stdout); /* End of field 13. */
1465 es_putc (':', es_stdout); /* End of field 14. */
1466 if (secret || has_secret)
1469 es_putc ('#', es_stdout);
1471 es_fputs (serialno, es_stdout);
1472 else if (has_secret)
1473 es_putc ('+', es_stdout);
1475 es_putc (':', es_stdout); /* End of field 15. */
1476 es_putc (':', es_stdout); /* End of field 16. */
1477 if (pk->pubkey_algo == PUBKEY_ALGO_ECDSA
1478 || pk->pubkey_algo == PUBKEY_ALGO_EDDSA
1479 || pk->pubkey_algo == PUBKEY_ALGO_ECDH)
1481 char *curve = openpgp_oid_to_str (pk->pkey[0]);
1482 const char *name = openpgp_oid_to_curve (curve);
1483 if (!*name || *name == '?')
1485 es_fputs (name, es_stdout);
1488 es_putc (':', es_stdout); /* End of field 17. */
1489 es_putc ('\n', es_stdout);
1491 print_fingerprint (NULL, pk2, 0);
1492 if (opt.with_key_data || opt.with_keygrip)
1495 es_fprintf (es_stdout, "grp:::::::::%s:\n", hexgrip);
1496 if (opt.with_key_data)
1497 print_key_data (pk2);
1500 else if (opt.list_sigs && node->pkt->pkttype == PKT_SIGNATURE)
1502 PKT_signature *sig = node->pkt->pkt.signature;
1503 int sigrc, fprokay = 0;
1506 byte fparray[MAX_FINGERPRINT_LEN];
1508 if (sig->sig_class == 0x20 || sig->sig_class == 0x28
1509 || sig->sig_class == 0x30)
1511 else if ((sig->sig_class & ~3) == 0x10)
1513 else if (sig->sig_class == 0x18)
1515 else if (sig->sig_class == 0x1F)
1519 es_fprintf (es_stdout, "sig::::::::::%02x%c:\n",
1520 sig->sig_class, sig->flags.exportable ? 'x' : 'l');
1526 PKT_public_key *signer_pk = NULL;
1529 if (opt.no_sig_cache)
1530 signer_pk = xmalloc_clear (sizeof (PKT_public_key));
1532 rc = check_key_signature2 (keyblock, node, NULL, signer_pk,
1534 switch (gpg_err_code (rc))
1539 case GPG_ERR_BAD_SIGNATURE:
1542 case GPG_ERR_NO_PUBKEY:
1543 case GPG_ERR_UNUSABLE_PUBKEY:
1551 if (opt.no_sig_cache)
1555 fingerprint_from_pk (signer_pk, fparray, &fplen);
1558 free_public_key (signer_pk);
1566 es_fputs (sigstr, es_stdout);
1567 es_putc (':', es_stdout);
1569 es_putc (sigrc, es_stdout);
1570 es_fprintf (es_stdout, "::%d:%08lX%08lX:%s:%s:", sig->pubkey_algo,
1571 (ulong) sig->keyid[0], (ulong) sig->keyid[1],
1572 colon_datestr_from_sig (sig),
1573 colon_expirestr_from_sig (sig));
1575 if (sig->trust_depth || sig->trust_value)
1576 es_fprintf (es_stdout, "%d %d", sig->trust_depth, sig->trust_value);
1577 es_fprintf (es_stdout, ":");
1579 if (sig->trust_regexp)
1580 es_write_sanitized (es_stdout, sig->trust_regexp,
1581 strlen (sig->trust_regexp), ":", NULL);
1582 es_fprintf (es_stdout, ":");
1585 es_fprintf (es_stdout, "[%s] ", gpg_strerror (rc));
1586 else if (sigrc == '?')
1588 else if (!opt.fast_list_mode)
1591 p = get_user_id (sig->keyid, &n);
1592 es_write_sanitized (es_stdout, p, n, ":", NULL);
1595 es_fprintf (es_stdout, ":%02x%c::", sig->sig_class,
1596 sig->flags.exportable ? 'x' : 'l');
1598 if (opt.no_sig_cache && opt.check_sigs && fprokay)
1600 for (i = 0; i < fplen; i++)
1601 es_fprintf (es_stdout, "%02X", fparray[i]);
1604 es_fprintf (es_stdout, ":::%d:\n", sig->digest_algo);
1606 if (opt.show_subpackets)
1607 print_subpackets_colon (sig);
1609 /* fixme: check or list other sigs here */
1618 * Reorder the keyblock so that the primary user ID (and not attribute
1619 * packet) comes first. Fixme: Replace this by a generic sort
1622 do_reorder_keyblock (KBNODE keyblock, int attr)
1624 KBNODE primary = NULL, primary0 = NULL, primary2 = NULL;
1627 for (node = keyblock; node; primary0 = node, node = node->next)
1629 if (node->pkt->pkttype == PKT_USER_ID &&
1630 ((attr && node->pkt->pkt.user_id->attrib_data) ||
1631 (!attr && !node->pkt->pkt.user_id->attrib_data)) &&
1632 node->pkt->pkt.user_id->is_primary)
1634 primary = primary2 = node;
1635 for (node = node->next; node; primary2 = node, node = node->next)
1637 if (node->pkt->pkttype == PKT_USER_ID
1638 || node->pkt->pkttype == PKT_PUBLIC_SUBKEY
1639 || node->pkt->pkttype == PKT_SECRET_SUBKEY)
1648 return; /* No primary key flag found (should not happen). */
1650 for (last = NULL, node = keyblock; node; last = node, node = node->next)
1652 if (node->pkt->pkttype == PKT_USER_ID)
1656 assert (last); /* The user ID is never the first packet. */
1657 assert (primary0); /* Ditto (this is the node before primary). */
1658 if (node == primary)
1659 return; /* Already the first one. */
1661 last->next = primary;
1662 primary0->next = primary2->next;
1663 primary2->next = node;
1667 reorder_keyblock (KBNODE keyblock)
1669 do_reorder_keyblock (keyblock, 1);
1670 do_reorder_keyblock (keyblock, 0);
1674 list_keyblock (KBNODE keyblock, int secret, int has_secret, int fpr,
1675 struct keylist_context *listctx)
1677 reorder_keyblock (keyblock);
1678 if (opt.print_pka_records)
1679 list_keyblock_pka (keyblock);
1680 else if (opt.with_colons)
1681 list_keyblock_colon (keyblock, secret, has_secret, fpr);
1683 list_keyblock_print (keyblock, secret, fpr, listctx);
1685 es_fflush (es_stdout);
1689 /* Public function used by keygen to list a keyblock. */
1691 list_keyblock_direct (kbnode_t keyblock, int secret, int has_secret, int fpr)
1693 struct keylist_context listctx;
1695 memset (&listctx, 0, sizeof (listctx));
1696 list_keyblock (keyblock, secret, has_secret, fpr, &listctx);
1697 keylist_context_release (&listctx);
1701 /* Print an hex digit in ICAO spelling. */
1703 print_icao_hexdigit (estream_t fp, int c)
1705 static const char *list[16] = {
1706 "Zero", "One", "Two", "Three", "Four", "Five", "Six", "Seven",
1707 "Eight", "Niner", "Alfa", "Bravo", "Charlie", "Delta", "Echo", "Foxtrot"
1710 tty_fprintf (fp, "%s", list[c&15]);
1715 * Function to print the finperprint.
1716 * mode 0: as used in key listings, opt.with_colons is honored
1717 * 1: print using log_info ()
1718 * 2: direct use of tty
1719 * 3: direct use of tty but only primary key.
1720 * 10: Same as 0 but with_colons etc is ignored.
1722 * Modes 1 and 2 will try and print both subkey and primary key
1723 * fingerprints. A MODE with bit 7 set is used internally. If
1724 * OVERRIDE_FP is not NULL that stream will be used in 0 instead
1725 * of es_stdout or instead of the TTY in modes 2 and 3.
1728 print_fingerprint (estream_t override_fp, PKT_public_key *pk, int mode)
1730 byte array[MAX_FINGERPRINT_LEN], *p;
1735 int with_colons = opt.with_colons;
1736 int with_icao = opt.with_icao_spelling;
1745 if (pk->main_keyid[0] == pk->keyid[0]
1746 && pk->main_keyid[1] == pk->keyid[1])
1749 /* Just to be safe */
1750 if ((mode & 0x80) && !primary)
1752 log_error ("primary key is not really primary!\n");
1758 if (!primary && (mode == 1 || mode == 2))
1760 PKT_public_key *primary_pk = xmalloc_clear (sizeof (*primary_pk));
1761 get_pubkey (primary_pk, pk->main_keyid);
1762 print_fingerprint (override_fp, primary_pk, (mode | 0x80));
1763 free_public_key (primary_pk);
1768 fp = log_get_stream ();
1770 text = _("Primary key fingerprint:");
1772 text = _(" Subkey fingerprint:");
1776 fp = override_fp; /* Use tty or given stream. */
1778 /* TRANSLATORS: this should fit into 24 bytes to that the
1779 * fingerprint data is properly aligned with the user ID */
1780 text = _(" Primary key fingerprint:");
1782 text = _(" Subkey fingerprint:");
1786 fp = override_fp; /* Use tty or given stream. */
1787 text = _(" Key fingerprint =");
1791 fp = override_fp? override_fp : es_stdout;
1792 text = _(" Key fingerprint =");
1795 fingerprint_from_pk (pk, array, &n);
1797 if (with_colons && !mode)
1799 es_fprintf (fp, "fpr:::::::::");
1800 for (i = 0; i < n; i++, p++)
1801 es_fprintf (fp, "%02X", *p);
1806 tty_fprintf (fp, "%s", text);
1809 for (i = 0; i < n; i++, i++, p += 2)
1810 tty_fprintf (fp, "%s %02X%02X", i==10? " ":"", *p, p[1]);
1814 for (i = 0; i < n; i++, p++)
1815 tty_fprintf (fp, "%s %02X", (i && !(i % 8))? " ":"", *p);
1818 tty_fprintf (fp, "\n");
1819 if (!with_colons && with_icao)
1822 tty_fprintf (fp, "%*s\"", (int)strlen(text)+1, "");
1823 for (i = 0; i < n; i++, p++)
1828 tty_fprintf (fp, "\n%*s ", (int)strlen(text)+1, "");
1830 tty_fprintf (fp, " ");
1832 tty_fprintf (fp, " ");
1833 print_icao_hexdigit (fp, *p >> 4);
1834 tty_fprintf (fp, " ");
1835 print_icao_hexdigit (fp, *p & 15);
1837 tty_fprintf (fp, "\"\n");
1841 /* Print the serial number of an OpenPGP card if available. */
1843 print_card_serialno (const char *serialno)
1847 if (opt.with_colons)
1848 return; /* Handled elsewhere. */
1850 es_fputs (_(" Card serial no. ="), es_stdout);
1851 es_putc (' ', es_stdout);
1852 if (strlen (serialno) == 32 && !strncmp (serialno, "D27600012401", 12))
1854 /* This is an OpenPGP card. Print the relevant part. */
1855 /* Example: D2760001240101010001000003470000 */
1857 es_fprintf (es_stdout, "%.*s %.*s", 4, serialno+16, 8, serialno+20);
1860 es_fputs (serialno, es_stdout);
1861 es_putc ('\n', es_stdout);
1867 set_attrib_fd (int fd)
1869 static int last_fd = -1;
1871 if (fd != -1 && last_fd == fd)
1874 /* Fixme: Do we need to check for the log stream here? */
1875 if (attrib_fp && attrib_fp != log_get_stream ())
1876 es_fclose (attrib_fp);
1881 #ifdef HAVE_DOSISH_SYSTEM
1882 setmode (fd, O_BINARY);
1885 attrib_fp = es_stdout;
1887 attrib_fp = es_stderr;
1889 attrib_fp = es_fdopen (fd, "wb");
1892 log_fatal ("can't open fd %d for attribute output: %s\n",
1893 fd, strerror (errno));