packet-print.c revision 1.44
1/*-
2 * Copyright (c) 2009 The NetBSD Foundation, Inc.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to The NetBSD Foundation
6 * by Alistair Crooks (agc@NetBSD.org)
7 *
8 * Redistribution and use in source and binary forms, with or without
9 * modification, are permitted provided that the following conditions
10 * are met:
11 * 1. Redistributions of source code must retain the above copyright
12 *    notice, this list of conditions and the following disclaimer.
13 * 2. Redistributions in binary form must reproduce the above copyright
14 *    notice, this list of conditions and the following disclaimer in the
15 *    documentation and/or other materials provided with the distribution.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
18 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
19 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
20 * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
21 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
22 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
23 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
25 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
27 * POSSIBILITY OF SUCH DAMAGE.
28 */
29/*
30 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
31 * All rights reserved.
32 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
33 * their moral rights under the UK Copyright Design and Patents Act 1988 to
34 * be recorded as the authors of this copyright work.
35 *
36 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
37 * use this file except in compliance with the License.
38 *
39 * You may obtain a copy of the License at
40 *     http://www.apache.org/licenses/LICENSE-2.0
41 *
42 * Unless required by applicable law or agreed to in writing, software
43 * distributed under the License is distributed on an "AS IS" BASIS,
44 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
45 *
46 * See the License for the specific language governing permissions and
47 * limitations under the License.
48 */
49
50/*
51 * ! \file \brief Standard API print functions
52 */
53#include "config.h"
54
55#ifdef HAVE_SYS_CDEFS_H
56#include <sys/cdefs.h>
57#endif
58
59#if defined(__NetBSD__)
60__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
61__RCSID("$NetBSD: packet-print.c,v 1.44 2022/08/26 19:18:38 jhigh Exp $");
62#endif
63
64#include <string.h>
65#include <stdio.h>
66
67#ifdef HAVE_UNISTD_H
68#include <unistd.h>
69#endif
70
71#include "crypto.h"
72#include "keyring.h"
73#include "packet-show.h"
74#include "signature.h"
75#include "readerwriter.h"
76#include "netpgpdefs.h"
77#include "netpgpsdk.h"
78#include "packet.h"
79#include "netpgpdigest.h"
80#include "mj.h"
81
82/* static functions */
83
84static void
85print_indent(int indent)
86{
87	int             i;
88
89	for (i = 0; i < indent; i++) {
90		printf("  ");
91	}
92}
93
94static void
95print_name(int indent, const char *name)
96{
97	print_indent(indent);
98	if (name) {
99		printf("%s: ", name);
100	}
101}
102
103static void
104print_hexdump(int indent, const char *name, const uint8_t *data, unsigned len)
105{
106	print_name(indent, name);
107	hexdump(stdout, NULL, data, len);
108}
109
110static void
111hexdump_data(int indent, const char *name, const uint8_t *data, unsigned len)
112{
113	print_name(indent, name);
114	hexdump(stdout, NULL, data, len);
115}
116
117static void
118print_uint(int indent, const char *name, unsigned val)
119{
120	print_name(indent, name);
121	printf("%u\n", val);
122}
123
124static void
125showtime(const char *name, time_t t)
126{
127	printf("%s=%" PRItime "d (%.24s)", name, (long long) t, ctime(&t));
128}
129
130static void
131print_time(int indent, const char *name, time_t t)
132{
133	print_indent(indent);
134	printf("%s: ", name);
135	showtime("time", t);
136	printf("\n");
137}
138
139static void
140print_string_and_value(int indent, const char *name, const char *str, uint8_t value)
141{
142	print_name(indent, name);
143	printf("%s (0x%x)\n", str, value);
144}
145
146static void
147print_tagname(int indent, const char *str)
148{
149	print_indent(indent);
150	printf("%s packet\n", str);
151}
152
153static void
154print_data(int indent, const char *name, const pgp_data_t *data)
155{
156	print_hexdump(indent, name, data->contents, (unsigned)data->len);
157}
158
159static void
160print_bn(int indent, const char *name, const BIGNUM *bn)
161{
162	print_indent(indent);
163	printf("%s=", name);
164	if (bn) {
165		BN_print_fp(stdout, bn);
166		putchar('\n');
167	} else {
168		puts("(unset)");
169	}
170}
171
172static void
173print_packet_hex(const pgp_subpacket_t *pkt)
174{
175	hexdump(stdout, "packet contents:", pkt->raw, pkt->length);
176}
177
178static void
179print_escaped(const uint8_t *data, size_t length)
180{
181	while (length-- > 0) {
182		if ((*data >= 0x20 && *data < 0x7f && *data != '%') ||
183		    *data == '\n') {
184			putchar(*data);
185		} else {
186			printf("%%%02x", *data);
187		}
188		++data;
189	}
190}
191
192static void
193print_string(int indent, const char *name, const char *str)
194{
195	print_name(indent, name);
196	print_escaped((const uint8_t *) str, strlen(str));
197	putchar('\n');
198}
199
200static void
201print_utf8_string(int indent, const char *name, const uint8_t *str)
202{
203	/* \todo Do this better for non-English character sets */
204	print_string(indent, name, (const char *) str);
205}
206
207static void
208print_duration(int indent, const char *name, time_t t)
209{
210	int             mins, hours, days, years;
211
212	print_indent(indent);
213	printf("%s: ", name);
214	printf("duration %" PRItime "d seconds", (long long) t);
215
216	mins = (int)(t / 60);
217	hours = mins / 60;
218	days = hours / 24;
219	years = days / 365;
220
221	printf(" (approx. ");
222	if (years) {
223		printf("%d %s", years, years == 1 ? "year" : "years");
224	} else if (days) {
225		printf("%d %s", days, days == 1 ? "day" : "days");
226	} else if (hours) {
227		printf("%d %s", hours, hours == 1 ? "hour" : "hours");
228	}
229	printf(")\n");
230}
231
232static void
233print_boolean(int indent, const char *name, uint8_t boolval)
234{
235	print_name(indent, name);
236	printf("%s\n", (boolval) ? "Yes" : "No");
237}
238
239static void
240print_text_breakdown(int indent, pgp_text_t *text)
241{
242	const char     *prefix = ".. ";
243	unsigned        i;
244
245	/* these were recognised */
246	for (i = 0; i < text->known.used; i++) {
247		print_indent(indent);
248		printf("%s", prefix);
249		printf("%s\n", text->known.strings[i]);
250	}
251	/*
252	 * these were not recognised. the strings will contain the hex value
253	 * of the unrecognised value in string format - see
254	 * process_octet_str()
255	 */
256	if (text->unknown.used) {
257		printf("\n");
258		print_indent(indent);
259		printf("Not Recognised: ");
260	}
261	for (i = 0; i < text->unknown.used; i++) {
262		print_indent(indent);
263		printf("%s", prefix);
264		printf("%s\n", text->unknown.strings[i]);
265	}
266}
267
268static void
269print_headers(const pgp_headers_t *h)
270{
271	unsigned        i;
272
273	for (i = 0; i < h->headerc; ++i) {
274		printf("%s=%s\n", h->headers[i].key, h->headers[i].value);
275	}
276}
277
278static void
279print_block(int indent, const char *name, const uint8_t *str, size_t length)
280{
281	int             o = (int)length;
282
283	print_indent(indent);
284	printf(">>>>> %s >>>>>\n", name);
285
286	print_indent(indent);
287	for (; length > 0; --length) {
288		if (*str >= 0x20 && *str < 0x7f && *str != '%') {
289			putchar(*str);
290		} else if (*str == '\n') {
291			putchar(*str);
292			print_indent(indent);
293		} else {
294			printf("%%%02x", *str);
295		}
296		++str;
297	}
298	if (o && str[-1] != '\n') {
299		putchar('\n');
300		print_indent(indent);
301		fputs("[no newline]", stdout);
302	} else {
303		print_indent(indent);
304	}
305	printf("<<<<< %s <<<<<\n", name);
306}
307
308/* return the number of bits in the public key */
309static int
310numkeybits(const pgp_pubkey_t *pubkey)
311{
312	switch(pubkey->alg) {
313	case PGP_PKA_RSA:
314	case PGP_PKA_RSA_ENCRYPT_ONLY:
315	case PGP_PKA_RSA_SIGN_ONLY:
316		return BN_num_bytes(pubkey->key.rsa.n) * 8;
317	case PGP_PKA_DSA:
318		switch(BN_num_bytes(pubkey->key.dsa.q)) {
319		case 20:
320			return 1024;
321		case 28:
322			return 2048;
323		case 32:
324			return 3072;
325		default:
326			return 0;
327		}
328	case PGP_PKA_ECDSA:
329		return ecdsa_numbits(&pubkey->key.ecdsa);
330	case PGP_PKA_ELGAMAL:
331		return BN_num_bytes(pubkey->key.elgamal.y) * 8;
332	default:
333		return -1;
334	}
335}
336
337/* return the hexdump as a string */
338static char *
339strhexdump(char *dest, const uint8_t *src, size_t length, const char *sep)
340{
341	unsigned i;
342	int	n;
343
344	for (n = 0, i = 0 ; i < length ; i += 2) {
345		n += snprintf(&dest[n], 3, "%02x", *src++);
346		n += snprintf(&dest[n], 10, "%02x%s", *src++, sep);
347	}
348	return dest;
349}
350
351/* return the time as a string */
352static char *
353ptimestr(char *dest, size_t size, time_t t)
354{
355	struct tm      *tm;
356
357	tm = gmtime(&t);
358	(void) snprintf(dest, size, "%04d-%02d-%02d",
359		tm->tm_year + 1900,
360		tm->tm_mon + 1,
361		tm->tm_mday);
362	return dest;
363}
364
365/* print the sub key binding signature info */
366static int
367psubkeybinding(char *buf, size_t size, const pgp_key_t *key, const char *expired)
368{
369	char	keyid[512];
370	char	t[32];
371
372	return snprintf(buf, size, "encryption %d/%s %s %s %s\n",
373		numkeybits(&key->enckey),
374		pgp_show_pka(key->enckey.alg),
375		strhexdump(keyid, key->encid, PGP_KEY_ID_SIZE, ""),
376		ptimestr(t, sizeof(t), key->enckey.birthtime),
377		expired);
378}
379
380static int
381isrevoked(const pgp_key_t *key, unsigned uid)
382{
383	unsigned	r;
384
385	for (r = 0 ; r < key->revokec ; r++) {
386		if (key->revokes[r].uid == uid) {
387			return r;
388		}
389	}
390	return -1;
391}
392
393#ifndef KB
394#define KB(x)	((x) * 1024)
395#endif
396
397/* print into a string (malloc'ed) the pubkeydata */
398int
399pgp_sprint_keydata(pgp_io_t *io, const pgp_keyring_t *keyring,
400		const pgp_key_t *key, char **buf, const char *header,
401		const pgp_pubkey_t *pubkey, const int psigs)
402{
403	const pgp_key_t	*trustkey;
404	unsigned	 	 from;
405	unsigned		 i;
406	unsigned		 j;
407	time_t			 now;
408	char			 uidbuf[KB(128)];
409	char			 keyid[PGP_KEY_ID_SIZE * 3];
410	char			 fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
411	char			 expired[128];
412	char			 t[32];
413	int			 cc;
414	int			 n;
415	int			 r;
416
417	if (key == NULL || key->revoked) {
418		return -1;
419	}
420	now = time(NULL);
421	if (pubkey->duration > 0) {
422		cc = snprintf(expired, sizeof(expired),
423			(pubkey->birthtime + pubkey->duration < now) ?
424			"[EXPIRED " : "[EXPIRES ");
425		ptimestr(&expired[cc], sizeof(expired) - cc,
426			pubkey->birthtime + pubkey->duration);
427		cc += 10;
428		cc += snprintf(&expired[cc], sizeof(expired) - cc, "]");
429	} else {
430		expired[0] = 0x0;
431	}
432	for (i = 0, n = 0; i < key->uidc; i++) {
433		if ((r = isrevoked(key, i)) >= 0 &&
434		    key->revokes[r].code == PGP_REVOCATION_COMPROMISED) {
435			continue;
436		}
437		n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, "uid%s%s%s\n",
438				(psigs) ? "    " : "              ",
439				key->uids[i],
440				(isrevoked(key, i) >= 0) ? " [REVOKED]" : "");
441		for (j = 0 ; j < key->subsigc ; j++) {
442			if (psigs) {
443				if (key->subsigs[j].uid != i) {
444					continue;
445				}
446			} else {
447				if (!(key->subsigs[j].sig.info.version == 4 &&
448					key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY &&
449					i == key->uidc - 1)) {
450						continue;
451				}
452			}
453			from = 0;
454			trustkey = pgp_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from, NULL);
455			if (key->subsigs[j].sig.info.version == 4 &&
456					key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY) {
457				psubkeybinding(&uidbuf[n], sizeof(uidbuf) - n, key, expired);
458			} else {
459				n += snprintf(&uidbuf[n], sizeof(uidbuf) - n,
460					"sig        %s  %s  %s\n",
461					strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""),
462					ptimestr(t, sizeof(t), key->subsigs[j].sig.info.birthtime),
463					(trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "[unknown]");
464			}
465		}
466	}
467	return pgp_asprintf(buf, "%s %d/%s %s %s %s\nKey fingerprint: %s\n%s",
468		header,
469		numkeybits(pubkey),
470		pgp_show_pka(pubkey->alg),
471		strhexdump(keyid, key->sigid, PGP_KEY_ID_SIZE, ""),
472		ptimestr(t, sizeof(t), pubkey->birthtime),
473		expired,
474		strhexdump(fp, key->sigfingerprint.fingerprint, key->sigfingerprint.length, " "),
475		uidbuf);
476}
477
478/* return the key info as a JSON encoded string */
479int
480pgp_sprint_mj(pgp_io_t *io, const pgp_keyring_t *keyring,
481		const pgp_key_t *key, mj_t *keyjson, const char *header,
482		const pgp_pubkey_t *pubkey, const int psigs)
483{
484	const pgp_key_t	*trustkey;
485	unsigned	 	 from;
486	unsigned		 i;
487	unsigned		 j;
488	mj_t			 sub_obj;
489	char			 keyid[PGP_KEY_ID_SIZE * 3];
490	char			 fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
491	int			 r;
492
493	if (key == NULL || key->revoked) {
494		return -1;
495	}
496	(void) memset(keyjson, 0x0, sizeof(*keyjson));
497	mj_create(keyjson, "object");
498	mj_append_field(keyjson, "header", "string", header, -1);
499	mj_append_field(keyjson, "key bits", "integer", (int64_t) numkeybits(pubkey));
500	mj_append_field(keyjson, "pka", "string", pgp_show_pka(pubkey->alg), -1);
501	mj_append_field(keyjson, "key id", "string", strhexdump(keyid, key->sigid, PGP_KEY_ID_SIZE, ""), -1);
502	mj_append_field(keyjson, "fingerprint", "string",
503		strhexdump(fp, key->sigfingerprint.fingerprint, key->sigfingerprint.length, " "), -1);
504	mj_append_field(keyjson, "birthtime", "integer", pubkey->birthtime);
505	mj_append_field(keyjson, "duration", "integer", pubkey->duration);
506	for (i = 0; i < key->uidc; i++) {
507		if ((r = isrevoked(key, i)) >= 0 &&
508		    key->revokes[r].code == PGP_REVOCATION_COMPROMISED) {
509			continue;
510		}
511		(void) memset(&sub_obj, 0x0, sizeof(sub_obj));
512		mj_create(&sub_obj, "array");
513		mj_append(&sub_obj, "string", key->uids[i], -1);
514		mj_append(&sub_obj, "string", (r >= 0) ? "[REVOKED]" : "", -1);
515		mj_append_field(keyjson, "uid", "array", &sub_obj);
516		mj_delete(&sub_obj);
517		for (j = 0 ; j < key->subsigc ; j++) {
518			if (psigs) {
519				if (key->subsigs[j].uid != i) {
520					continue;
521				}
522			} else {
523				if (!(key->subsigs[j].sig.info.version == 4 &&
524					key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY &&
525					i == key->uidc - 1)) {
526						continue;
527				}
528			}
529			(void) memset(&sub_obj, 0x0, sizeof(sub_obj));
530			mj_create(&sub_obj, "array");
531			if (key->subsigs[j].sig.info.version == 4 &&
532					key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY) {
533				mj_append(&sub_obj, "integer", (int64_t)numkeybits(&key->enckey));
534				mj_append(&sub_obj, "string",
535					(const char *)pgp_show_pka(key->enckey.alg), -1);
536				mj_append(&sub_obj, "string",
537					strhexdump(keyid, key->encid, PGP_KEY_ID_SIZE, ""), -1);
538				mj_append(&sub_obj, "integer", (int64_t)key->enckey.birthtime);
539				mj_append_field(keyjson, "encryption", "array", &sub_obj);
540				mj_delete(&sub_obj);
541			} else {
542				mj_append(&sub_obj, "string",
543					strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""), -1);
544				mj_append(&sub_obj, "integer",
545					(int64_t)(key->subsigs[j].sig.info.birthtime));
546				from = 0;
547				trustkey = pgp_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from, NULL);
548				mj_append(&sub_obj, "string",
549					(trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "[unknown]", -1);
550				mj_append_field(keyjson, "sig", "array", &sub_obj);
551				mj_delete(&sub_obj);
552			}
553		}
554	}
555	if (pgp_get_debug_level(__FILE__)) {
556		char	*buf;
557
558		mj_asprint(&buf, keyjson, 1);
559		(void) fprintf(stderr, "pgp_sprint_mj: '%s'\n", buf);
560		free(buf);
561	}
562	return 1;
563}
564
565int
566pgp_hkp_sprint_keydata(pgp_io_t *io, const pgp_keyring_t *keyring,
567		const pgp_key_t *key, char **buf,
568		const pgp_pubkey_t *pubkey, const int psigs)
569{
570	const pgp_key_t	*trustkey;
571	unsigned	 	 from;
572	unsigned	 	 i;
573	unsigned	 	 j;
574	char			 keyid[PGP_KEY_ID_SIZE * 3];
575	char		 	 uidbuf[KB(128)];
576	char		 	 fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
577	int		 	 n;
578
579	if (key->revoked) {
580		return -1;
581	}
582	for (i = 0, n = 0; i < key->uidc; i++) {
583		n += snprintf(&uidbuf[n], sizeof(uidbuf) - n,
584			"uid:%lld:%lld:%s\n",
585			(long long)pubkey->birthtime,
586			(long long)pubkey->duration,
587			key->uids[i]);
588		for (j = 0 ; j < key->subsigc ; j++) {
589			if (psigs) {
590				if (key->subsigs[j].uid != i) {
591					continue;
592				}
593			} else {
594				if (!(key->subsigs[j].sig.info.version == 4 &&
595					key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY &&
596					i == key->uidc - 1)) {
597						continue;
598				}
599			}
600			from = 0;
601			trustkey = pgp_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from, NULL);
602			if (key->subsigs[j].sig.info.version == 4 &&
603					key->subsigs[j].sig.info.type == PGP_SIG_SUBKEY) {
604				n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, "sub:%d:%d:%s:%lld:%lld\n",
605					numkeybits(pubkey),
606					key->subsigs[j].sig.info.key_alg,
607					strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""),
608					(long long)(key->subsigs[j].sig.info.birthtime),
609					(long long)pubkey->duration);
610			} else {
611				n += snprintf(&uidbuf[n], sizeof(uidbuf) - n,
612					"sig:%s:%lld:%s\n",
613					strhexdump(keyid, key->subsigs[j].sig.info.signer_id, PGP_KEY_ID_SIZE, ""),
614					(long long)key->subsigs[j].sig.info.birthtime,
615					(trustkey) ? (char *)trustkey->uids[trustkey->uid0] : "");
616			}
617		}
618	}
619	return pgp_asprintf(buf, "pub:%s:%d:%d:%lld:%lld\n%s",
620		strhexdump(fp, key->sigfingerprint.fingerprint, PGP_FINGERPRINT_SIZE, ""),
621		pubkey->alg,
622		numkeybits(pubkey),
623		(long long)pubkey->birthtime,
624		(long long)pubkey->duration,
625		uidbuf);
626}
627
628/* print the key data for a pub or sec key */
629void
630pgp_print_keydata(pgp_io_t *io, const pgp_keyring_t *keyring,
631		const pgp_key_t *key, const char *header,
632		const pgp_pubkey_t *pubkey, const int psigs)
633{
634	char	*cp;
635
636	if (pgp_sprint_keydata(io, keyring, key, &cp, header, pubkey, psigs) >= 0) {
637		(void) fprintf(io->res, "%s", cp);
638		free(cp);
639	}
640}
641
642/**
643\ingroup Core_Print
644\param pubkey
645*/
646void
647pgp_print_pubkey(const pgp_pubkey_t *pubkey)
648{
649	printf("------- PUBLIC KEY ------\n");
650	print_uint(0, "Version", (unsigned)pubkey->version);
651	print_time(0, "Creation Time", pubkey->birthtime);
652	if (pubkey->version == PGP_V3) {
653		print_uint(0, "Days Valid", pubkey->days_valid);
654	}
655	print_string_and_value(0, "Algorithm", pgp_show_pka(pubkey->alg),
656			       pubkey->alg);
657	switch (pubkey->alg) {
658	case PGP_PKA_DSA:
659		print_bn(0, "p", pubkey->key.dsa.p);
660		print_bn(0, "q", pubkey->key.dsa.q);
661		print_bn(0, "g", pubkey->key.dsa.g);
662		print_bn(0, "y", pubkey->key.dsa.y);
663		break;
664	case PGP_PKA_ECDSA:
665		print_bn(0, "p", pubkey->key.ecdsa.p);
666		break;
667	case PGP_PKA_RSA:
668	case PGP_PKA_RSA_ENCRYPT_ONLY:
669	case PGP_PKA_RSA_SIGN_ONLY:
670		print_bn(0, "n", pubkey->key.rsa.n);
671		print_bn(0, "e", pubkey->key.rsa.e);
672		break;
673
674	case PGP_PKA_ELGAMAL:
675	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
676		print_bn(0, "p", pubkey->key.elgamal.p);
677		print_bn(0, "g", pubkey->key.elgamal.g);
678		print_bn(0, "y", pubkey->key.elgamal.y);
679		break;
680
681	default:
682		(void) fprintf(stderr,
683			"pgp_print_pubkey: Unusual algorithm\n");
684	}
685
686	printf("------- end of PUBLIC KEY ------\n");
687}
688
689int
690pgp_sprint_pubkey(const pgp_key_t *key, char *out, size_t outsize)
691{
692	char	fp[(PGP_FINGERPRINT_SIZE * 3) + 1];
693	int	cc;
694
695	cc = snprintf(out, outsize, "key=%s\nname=%s\ncreation=%lld\nexpiry=%lld\nversion=%d\nalg=%d\n",
696		strhexdump(fp, key->sigfingerprint.fingerprint, PGP_FINGERPRINT_SIZE, ""),
697		key->uids[key->uid0],
698		(long long)key->key.pubkey.birthtime,
699		(long long)key->key.pubkey.days_valid,
700		key->key.pubkey.version,
701		key->key.pubkey.alg);
702	switch (key->key.pubkey.alg) {
703	case PGP_PKA_DSA:
704		cc += snprintf(&out[cc], outsize - cc,
705			"p=%s\nq=%s\ng=%s\ny=%s\n",
706			BN_bn2hex(key->key.pubkey.key.dsa.p),
707			BN_bn2hex(key->key.pubkey.key.dsa.q),
708			BN_bn2hex(key->key.pubkey.key.dsa.g),
709			BN_bn2hex(key->key.pubkey.key.dsa.y));
710		break;
711	case PGP_PKA_RSA:
712	case PGP_PKA_RSA_ENCRYPT_ONLY:
713	case PGP_PKA_RSA_SIGN_ONLY:
714		cc += snprintf(&out[cc], outsize - cc,
715			"n=%s\ne=%s\n",
716			BN_bn2hex(key->key.pubkey.key.rsa.n),
717			BN_bn2hex(key->key.pubkey.key.rsa.e));
718		break;
719	case PGP_PKA_ELGAMAL:
720	case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
721		cc += snprintf(&out[cc], outsize - cc,
722			"p=%s\ng=%s\ny=%s\n",
723			BN_bn2hex(key->key.pubkey.key.elgamal.p),
724			BN_bn2hex(key->key.pubkey.key.elgamal.g),
725			BN_bn2hex(key->key.pubkey.key.elgamal.y));
726		break;
727	default:
728		(void) fprintf(stderr,
729			"pgp_print_pubkey: Unusual algorithm\n");
730	}
731	return cc;
732}
733
734/**
735\ingroup Core_Print
736\param type
737\param seckey
738*/
739static void
740print_seckey_verbose(const pgp_content_enum type,
741				const pgp_seckey_t *seckey)
742{
743	printf("------- SECRET KEY or ENCRYPTED SECRET KEY ------\n");
744	print_tagname(0, (type == PGP_PTAG_CT_SECRET_KEY) ?
745			"SECRET_KEY" :
746			"ENCRYPTED_SECRET_KEY");
747	/* pgp_print_pubkey(key); */
748	printf("S2K Usage: %d\n", seckey->s2k_usage);
749	if (seckey->s2k_usage != PGP_S2KU_NONE) {
750		printf("S2K Specifier: %d\n", seckey->s2k_specifier);
751		printf("Symmetric algorithm: %d (%s)\n", seckey->alg,
752		       pgp_show_symm_alg(seckey->alg));
753		printf("Hash algorithm: %d (%s)\n", seckey->hash_alg,
754		       pgp_show_hash_alg((uint8_t)seckey->hash_alg));
755		if (seckey->s2k_specifier != PGP_S2KS_SIMPLE) {
756			print_hexdump(0, "Salt", seckey->salt,
757					(unsigned)sizeof(seckey->salt));
758		}
759		if (seckey->s2k_specifier == PGP_S2KS_ITERATED_AND_SALTED) {
760			printf("Octet count: %u\n", seckey->octetc);
761		}
762		print_hexdump(0, "IV", seckey->iv, pgp_block_size(seckey->alg));
763	}
764	/* no more set if encrypted */
765	if (type == PGP_PTAG_CT_ENCRYPTED_SECRET_KEY) {
766		return;
767	}
768	switch (seckey->pubkey.alg) {
769	case PGP_PKA_RSA:
770		print_bn(0, "d", seckey->key.rsa.d);
771		print_bn(0, "p", seckey->key.rsa.p);
772		print_bn(0, "q", seckey->key.rsa.q);
773		print_bn(0, "u", seckey->key.rsa.u);
774		break;
775
776	case PGP_PKA_DSA:
777		print_bn(0, "x", seckey->key.dsa.x);
778		break;
779
780	default:
781		(void) fprintf(stderr,
782			"print_seckey_verbose: unusual algorithm\n");
783	}
784	if (seckey->s2k_usage == PGP_S2KU_ENCRYPTED_AND_HASHED) {
785		print_hexdump(0, "Checkhash", seckey->checkhash,
786				PGP_CHECKHASH_SIZE);
787	} else {
788		printf("Checksum: %04x\n", seckey->checksum);
789	}
790	printf("------- end of SECRET KEY or ENCRYPTED SECRET KEY ------\n");
791}
792
793
794/**
795\ingroup Core_Print
796\param tag
797\param key
798*/
799static void
800print_pk_sesskey(pgp_content_enum tag,
801			 const pgp_pk_sesskey_t * key)
802{
803	print_tagname(0, (tag == PGP_PTAG_CT_PK_SESSION_KEY) ?
804		"PUBLIC KEY SESSION KEY" :
805		"ENCRYPTED PUBLIC KEY SESSION KEY");
806	printf("Version: %d\n", key->version);
807	print_hexdump(0, "Key ID", key->key_id, (unsigned)sizeof(key->key_id));
808	printf("Algorithm: %d (%s)\n", key->alg,
809	       pgp_show_pka(key->alg));
810	switch (key->alg) {
811	case PGP_PKA_RSA:
812		print_bn(0, "encrypted_m", key->params.rsa.encrypted_m);
813		break;
814
815	case PGP_PKA_ELGAMAL:
816		print_bn(0, "g_to_k", key->params.elgamal.g_to_k);
817		print_bn(0, "encrypted_m", key->params.elgamal.encrypted_m);
818		break;
819
820	default:
821		(void) fprintf(stderr,
822			"print_pk_sesskey: unusual algorithm\n");
823	}
824	if (tag == PGP_PTAG_CT_PK_SESSION_KEY) {
825		printf("Symmetric algorithm: %d (%s)\n", key->symm_alg,
826		       pgp_show_symm_alg(key->symm_alg));
827		print_hexdump(0, "Key", key->key, pgp_key_size(key->symm_alg));
828		printf("Checksum: %04x\n", key->checksum);
829	}
830}
831
832static void
833start_subpacket(int *indent, int type)
834{
835	*indent += 1;
836	print_indent(*indent);
837	printf("-- %s (type 0x%02x)\n",
838	       pgp_show_ss_type((pgp_content_enum)type),
839	       type - PGP_PTAG_SIG_SUBPKT_BASE);
840}
841
842static void
843end_subpacket(int *indent)
844{
845	*indent -= 1;
846}
847
848/**
849\ingroup Core_Print
850\param contents
851*/
852int
853pgp_print_packet(pgp_printstate_t *print, const pgp_packet_t *pkt)
854{
855	const pgp_contents_t	*content = &pkt->u;
856	pgp_text_t		*text;
857	const char		*str;
858
859	if (print->unarmoured && pkt->tag != PGP_PTAG_CT_UNARMOURED_TEXT) {
860		print->unarmoured = 0;
861		puts("UNARMOURED TEXT ends");
862	}
863	if (pkt->tag == PGP_PARSER_PTAG) {
864		printf("=> PGP_PARSER_PTAG: %s\n",
865			pgp_show_packet_tag((pgp_content_enum)content->ptag.type));
866	} else {
867		printf("=> %s\n", pgp_show_packet_tag(pkt->tag));
868	}
869
870	switch (pkt->tag) {
871	case PGP_PARSER_ERROR:
872		printf("parse error: %s\n", content->error);
873		break;
874
875	case PGP_PARSER_ERRCODE:
876		printf("parse error: %s\n",
877		       pgp_errcode(content->errcode.errcode));
878		break;
879
880	case PGP_PARSER_PACKET_END:
881		print_packet_hex(&content->packet);
882		break;
883
884	case PGP_PARSER_PTAG:
885		if (content->ptag.type == PGP_PTAG_CT_PUBLIC_KEY) {
886			print->indent = 0;
887			printf("\n*** NEXT KEY ***\n");
888		}
889		printf("\n");
890		print_indent(print->indent);
891		printf("==== ptag new_format=%u type=%u length_type=%d"
892		       " length=0x%x (%u) position=0x%x (%u)\n",
893		       content->ptag.new_format,
894		       content->ptag.type, content->ptag.length_type,
895		       content->ptag.length, content->ptag.length,
896		       content->ptag.position, content->ptag.position);
897		print_tagname(print->indent, pgp_show_packet_tag((pgp_content_enum)content->ptag.type));
898		break;
899
900	case PGP_PTAG_CT_SE_DATA_HEADER:
901		print_tagname(print->indent, "SYMMETRIC ENCRYPTED DATA");
902		break;
903
904	case PGP_PTAG_CT_SE_IP_DATA_HEADER:
905		print_tagname(print->indent,
906			"SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER");
907		printf("Version: %d\n", content->se_ip_data_header);
908		break;
909
910	case PGP_PTAG_CT_SE_IP_DATA_BODY:
911		print_tagname(print->indent,
912			"SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY");
913		hexdump(stdout, "data", content->se_data_body.data,
914			content->se_data_body.length);
915		break;
916
917	case PGP_PTAG_CT_PUBLIC_KEY:
918	case PGP_PTAG_CT_PUBLIC_SUBKEY:
919		print_tagname(print->indent, (pkt->tag == PGP_PTAG_CT_PUBLIC_KEY) ?
920			"PUBLIC KEY" :
921			"PUBLIC SUBKEY");
922		pgp_print_pubkey(&content->pubkey);
923		break;
924
925	case PGP_PTAG_CT_TRUST:
926		print_tagname(print->indent, "TRUST");
927		print_data(print->indent, "Trust", &content->trust);
928		break;
929
930	case PGP_PTAG_CT_USER_ID:
931		print_tagname(print->indent, "USER ID");
932		print_utf8_string(print->indent, "userid", content->userid);
933		break;
934
935	case PGP_PTAG_CT_SIGNATURE:
936		print_tagname(print->indent, "SIGNATURE");
937		print_indent(print->indent);
938		print_uint(print->indent, "Signature Version",
939				   (unsigned)content->sig.info.version);
940		if (content->sig.info.birthtime_set) {
941			print_time(print->indent, "Signature Creation Time",
942				   content->sig.info.birthtime);
943		}
944		if (content->sig.info.duration_set) {
945			print_uint(print->indent, "Signature Duration",
946				   (unsigned)content->sig.info.duration);
947		}
948
949		print_string_and_value(print->indent, "Signature Type",
950			    pgp_show_sig_type(content->sig.info.type),
951				       content->sig.info.type);
952
953		if (content->sig.info.signer_id_set) {
954			hexdump_data(print->indent, "Signer ID",
955					   content->sig.info.signer_id,
956				  (unsigned)sizeof(content->sig.info.signer_id));
957		}
958
959		print_string_and_value(print->indent, "Public Key Algorithm",
960			pgp_show_pka(content->sig.info.key_alg),
961				     content->sig.info.key_alg);
962		print_string_and_value(print->indent, "Hash Algorithm",
963			pgp_show_hash_alg((uint8_t)
964				content->sig.info.hash_alg),
965			(uint8_t)content->sig.info.hash_alg);
966		print_uint(print->indent, "Hashed data len",
967			(unsigned)content->sig.info.v4_hashlen);
968		print_indent(print->indent);
969		hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2);
970		switch (content->sig.info.key_alg) {
971		case PGP_PKA_RSA:
972		case PGP_PKA_RSA_SIGN_ONLY:
973			print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig);
974			break;
975
976		case PGP_PKA_DSA:
977			print_bn(print->indent, "r", content->sig.info.sig.dsa.r);
978			print_bn(print->indent, "s", content->sig.info.sig.dsa.s);
979			break;
980
981		case PGP_PKA_ECDSA:
982			print_bn(print->indent, "r", content->sig.info.sig.ecdsa.r);
983			print_bn(print->indent, "s", content->sig.info.sig.ecdsa.s);
984			break;
985
986		case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
987			print_bn(print->indent, "r", content->sig.info.sig.elgamal.r);
988			print_bn(print->indent, "s", content->sig.info.sig.elgamal.s);
989			break;
990
991		default:
992			(void) fprintf(stderr,
993				"pgp_print_packet: Unusual algorithm\n");
994			return 0;
995		}
996
997		if (content->sig.hash)
998			printf("data hash is set\n");
999
1000		break;
1001
1002	case PGP_PTAG_CT_COMPRESSED:
1003		print_tagname(print->indent, "COMPRESSED");
1004		print_uint(print->indent, "Compressed Data Type",
1005			(unsigned)content->compressed);
1006		break;
1007
1008	case PGP_PTAG_CT_1_PASS_SIG:
1009		print_tagname(print->indent, "ONE PASS SIGNATURE");
1010
1011		print_uint(print->indent, "Version", (unsigned)content->one_pass_sig.version);
1012		print_string_and_value(print->indent, "Signature Type",
1013		    pgp_show_sig_type(content->one_pass_sig.sig_type),
1014				       content->one_pass_sig.sig_type);
1015		print_string_and_value(print->indent, "Hash Algorithm",
1016			pgp_show_hash_alg((uint8_t)content->one_pass_sig.hash_alg),
1017			(uint8_t)content->one_pass_sig.hash_alg);
1018		print_string_and_value(print->indent, "Public Key Algorithm",
1019			pgp_show_pka(content->one_pass_sig.key_alg),
1020			content->one_pass_sig.key_alg);
1021		hexdump_data(print->indent, "Signer ID",
1022				   content->one_pass_sig.keyid,
1023				   (unsigned)sizeof(content->one_pass_sig.keyid));
1024		print_uint(print->indent, "Nested", content->one_pass_sig.nested);
1025		break;
1026
1027	case PGP_PTAG_CT_USER_ATTR:
1028		print_tagname(print->indent, "USER ATTRIBUTE");
1029		print_hexdump(print->indent, "User Attribute",
1030			      content->userattr.contents,
1031			      (unsigned)content->userattr.len);
1032		break;
1033
1034	case PGP_PTAG_RAW_SS:
1035		if (pkt->critical) {
1036			(void) fprintf(stderr, "contents are critical\n");
1037			return 0;
1038		}
1039		start_subpacket(&print->indent, pkt->tag);
1040		print_uint(print->indent, "Raw Signature Subpacket: tag",
1041			(unsigned)(content->ss_raw.tag -
1042		   	(unsigned)PGP_PTAG_SIG_SUBPKT_BASE));
1043		print_hexdump(print->indent, "Raw Data",
1044			      content->ss_raw.raw,
1045			      (unsigned)content->ss_raw.length);
1046		break;
1047
1048	case PGP_PTAG_SS_CREATION_TIME:
1049		start_subpacket(&print->indent, pkt->tag);
1050		print_time(print->indent, "Signature Creation Time", content->ss_time);
1051		end_subpacket(&print->indent);
1052		break;
1053
1054	case PGP_PTAG_SS_EXPIRATION_TIME:
1055		start_subpacket(&print->indent, pkt->tag);
1056		print_duration(print->indent, "Signature Expiration Time",
1057			content->ss_time);
1058		end_subpacket(&print->indent);
1059		break;
1060
1061	case PGP_PTAG_SS_KEY_EXPIRY:
1062		start_subpacket(&print->indent, pkt->tag);
1063		print_duration(print->indent, "Key Expiration Time", content->ss_time);
1064		end_subpacket(&print->indent);
1065		break;
1066
1067	case PGP_PTAG_SS_TRUST:
1068		start_subpacket(&print->indent, pkt->tag);
1069		print_string(print->indent, "Trust Signature", "");
1070		print_uint(print->indent, "Level", (unsigned)content->ss_trust.level);
1071		print_uint(print->indent, "Amount", (unsigned)content->ss_trust.amount);
1072		end_subpacket(&print->indent);
1073		break;
1074
1075	case PGP_PTAG_SS_REVOCABLE:
1076		start_subpacket(&print->indent, pkt->tag);
1077		print_boolean(print->indent, "Revocable", content->ss_revocable);
1078		end_subpacket(&print->indent);
1079		break;
1080
1081	case PGP_PTAG_SS_REVOCATION_KEY:
1082		start_subpacket(&print->indent, pkt->tag);
1083		/* not yet tested */
1084		printf("  revocation key: class=0x%x",
1085		       content->ss_revocation_key.class);
1086		if (content->ss_revocation_key.class & 0x40) {
1087			printf(" (sensitive)");
1088		}
1089		printf(", algid=0x%x", content->ss_revocation_key.algid);
1090		hexdump(stdout, "fingerprint", content->ss_revocation_key.fingerprint,
1091				PGP_FINGERPRINT_SIZE);
1092		end_subpacket(&print->indent);
1093		break;
1094
1095	case PGP_PTAG_SS_ISSUER_KEY_ID:
1096		start_subpacket(&print->indent, pkt->tag);
1097		print_hexdump(print->indent, "Issuer Key Id",
1098			      content->ss_issuer, (unsigned)sizeof(content->ss_issuer));
1099		end_subpacket(&print->indent);
1100		break;
1101
1102	case PGP_PTAG_SS_ISSUER_FINGERPRINT:
1103		start_subpacket(&print->indent, pkt->tag);
1104		print_hexdump(print->indent, "Issuer Fingerprint",
1105			      content->ss_issuer_fingerprint.fingerprint,
1106			      content->ss_issuer_fingerprint.len);
1107		end_subpacket(&print->indent);
1108		break;
1109
1110	case PGP_PTAG_SS_PREFERRED_SKA:
1111		start_subpacket(&print->indent, pkt->tag);
1112		print_data(print->indent, "Preferred Symmetric Algorithms",
1113			   &content->ss_skapref);
1114		text = pgp_showall_ss_skapref(&content->ss_skapref);
1115		print_text_breakdown(print->indent, text);
1116		pgp_text_free(text);
1117
1118		end_subpacket(&print->indent);
1119		break;
1120
1121	case PGP_PTAG_SS_PRIMARY_USER_ID:
1122		start_subpacket(&print->indent, pkt->tag);
1123		print_boolean(print->indent, "Primary User ID",
1124			      content->ss_primary_userid);
1125		end_subpacket(&print->indent);
1126		break;
1127
1128	case PGP_PTAG_SS_PREFERRED_HASH:
1129		start_subpacket(&print->indent, pkt->tag);
1130		print_data(print->indent, "Preferred Hash Algorithms",
1131			   &content->ss_hashpref);
1132		text = pgp_showall_ss_hashpref(&content->ss_hashpref);
1133		print_text_breakdown(print->indent, text);
1134		pgp_text_free(text);
1135		end_subpacket(&print->indent);
1136		break;
1137
1138	case PGP_PTAG_SS_PREF_COMPRESS:
1139		start_subpacket(&print->indent, pkt->tag);
1140		print_data(print->indent, "Preferred Compression Algorithms",
1141			   &content->ss_zpref);
1142		text = pgp_showall_ss_zpref(&content->ss_zpref);
1143		print_text_breakdown(print->indent, text);
1144		pgp_text_free(text);
1145		end_subpacket(&print->indent);
1146		break;
1147
1148	case PGP_PTAG_SS_KEY_FLAGS:
1149		start_subpacket(&print->indent, pkt->tag);
1150		print_data(print->indent, "Key Flags", &content->ss_key_flags);
1151
1152		text = pgp_showall_ss_key_flags(&content->ss_key_flags);
1153		print_text_breakdown(print->indent, text);
1154		pgp_text_free(text);
1155
1156		end_subpacket(&print->indent);
1157		break;
1158
1159	case PGP_PTAG_SS_KEYSERV_PREFS:
1160		start_subpacket(&print->indent, pkt->tag);
1161		print_data(print->indent, "Key Server Preferences",
1162			   &content->ss_key_server_prefs);
1163		text = pgp_show_keyserv_prefs(&content->ss_key_server_prefs);
1164		print_text_breakdown(print->indent, text);
1165		pgp_text_free(text);
1166
1167		end_subpacket(&print->indent);
1168		break;
1169
1170	case PGP_PTAG_SS_FEATURES:
1171		start_subpacket(&print->indent, pkt->tag);
1172		print_data(print->indent, "Features", &content->ss_features);
1173		text = pgp_showall_ss_features(content->ss_features);
1174		print_text_breakdown(print->indent, text);
1175		pgp_text_free(text);
1176
1177		end_subpacket(&print->indent);
1178		break;
1179
1180	case PGP_PTAG_SS_NOTATION_DATA:
1181		start_subpacket(&print->indent, pkt->tag);
1182		print_indent(print->indent);
1183		printf("Notation Data:\n");
1184
1185		print->indent++;
1186		print_data(print->indent, "Flags", &content->ss_notation.flags);
1187		text = pgp_showall_notation(content->ss_notation);
1188		print_text_breakdown(print->indent, text);
1189		pgp_text_free(text);
1190
1191		print_data(print->indent, "Name", &content->ss_notation.name);
1192
1193		print_data(print->indent, "Value", &content->ss_notation.value);
1194
1195		print->indent--;
1196		end_subpacket(&print->indent);
1197		break;
1198
1199	case PGP_PTAG_SS_REGEXP:
1200		start_subpacket(&print->indent, pkt->tag);
1201		print_hexdump(print->indent, "Regular Expression",
1202			      (uint8_t *) content->ss_regexp,
1203			      (unsigned)strlen(content->ss_regexp));
1204		print_string(print->indent, NULL, content->ss_regexp);
1205		end_subpacket(&print->indent);
1206		break;
1207
1208	case PGP_PTAG_SS_POLICY_URI:
1209		start_subpacket(&print->indent, pkt->tag);
1210		print_string(print->indent, "Policy URL", content->ss_policy);
1211		end_subpacket(&print->indent);
1212		break;
1213
1214	case PGP_PTAG_SS_SIGNERS_USER_ID:
1215		start_subpacket(&print->indent, pkt->tag);
1216		print_utf8_string(print->indent, "Signer's User ID", content->ss_signer);
1217		end_subpacket(&print->indent);
1218		break;
1219
1220	case PGP_PTAG_SS_PREF_KEYSERV:
1221		start_subpacket(&print->indent, pkt->tag);
1222		print_string(print->indent, "Preferred Key Server", content->ss_keyserv);
1223		end_subpacket(&print->indent);
1224		break;
1225
1226	case PGP_PTAG_SS_EMBEDDED_SIGNATURE:
1227		start_subpacket(&print->indent, pkt->tag);
1228		end_subpacket(&print->indent);/* \todo print out contents? */
1229		break;
1230
1231	case PGP_PTAG_SS_USERDEFINED00:
1232	case PGP_PTAG_SS_USERDEFINED01:
1233	case PGP_PTAG_SS_USERDEFINED02:
1234	case PGP_PTAG_SS_USERDEFINED03:
1235	case PGP_PTAG_SS_USERDEFINED04:
1236	case PGP_PTAG_SS_USERDEFINED05:
1237	case PGP_PTAG_SS_USERDEFINED06:
1238	case PGP_PTAG_SS_USERDEFINED07:
1239	case PGP_PTAG_SS_USERDEFINED08:
1240	case PGP_PTAG_SS_USERDEFINED09:
1241	case PGP_PTAG_SS_USERDEFINED10:
1242		start_subpacket(&print->indent, pkt->tag);
1243		print_hexdump(print->indent, "Internal or user-defined",
1244			      content->ss_userdef.contents,
1245			      (unsigned)content->ss_userdef.len);
1246		end_subpacket(&print->indent);
1247		break;
1248
1249	case PGP_PTAG_SS_RESERVED:
1250		start_subpacket(&print->indent, pkt->tag);
1251		print_hexdump(print->indent, "Reserved",
1252			      content->ss_userdef.contents,
1253			      (unsigned)content->ss_userdef.len);
1254		end_subpacket(&print->indent);
1255		break;
1256
1257	case PGP_PTAG_SS_REVOCATION_REASON:
1258		start_subpacket(&print->indent, pkt->tag);
1259		print_hexdump(print->indent, "Revocation Reason",
1260			      &content->ss_revocation.code,
1261			      1);
1262		str = pgp_show_ss_rr_code(content->ss_revocation.code);
1263		print_string(print->indent, NULL, str);
1264		end_subpacket(&print->indent);
1265		break;
1266
1267	case PGP_PTAG_CT_LITDATA_HEADER:
1268		print_tagname(print->indent, "LITERAL DATA HEADER");
1269		printf("  literal data header format=%c filename='%s'\n",
1270		       content->litdata_header.format,
1271		       content->litdata_header.filename);
1272		showtime("    modification time",
1273			 content->litdata_header.mtime);
1274		printf("\n");
1275		break;
1276
1277	case PGP_PTAG_CT_LITDATA_BODY:
1278		print_tagname(print->indent, "LITERAL DATA BODY");
1279		printf("  literal data body length=%u\n",
1280		       content->litdata_body.length);
1281		printf("    data=");
1282		print_escaped(content->litdata_body.data,
1283			      content->litdata_body.length);
1284		printf("\n");
1285		break;
1286
1287	case PGP_PTAG_CT_SIGNATURE_HEADER:
1288		print_tagname(print->indent, "SIGNATURE");
1289		print_indent(print->indent);
1290		print_uint(print->indent, "Signature Version",
1291				   (unsigned)content->sig.info.version);
1292		if (content->sig.info.birthtime_set) {
1293			print_time(print->indent, "Signature Creation Time",
1294				content->sig.info.birthtime);
1295		}
1296		if (content->sig.info.duration_set) {
1297			print_uint(print->indent, "Signature Duration",
1298				   (unsigned)content->sig.info.duration);
1299		}
1300		print_string_and_value(print->indent, "Signature Type",
1301			    pgp_show_sig_type(content->sig.info.type),
1302				       content->sig.info.type);
1303		if (content->sig.info.signer_id_set) {
1304			hexdump_data(print->indent, "Signer ID",
1305				content->sig.info.signer_id,
1306				(unsigned)sizeof(content->sig.info.signer_id));
1307		}
1308		print_string_and_value(print->indent, "Public Key Algorithm",
1309			pgp_show_pka(content->sig.info.key_alg),
1310				     content->sig.info.key_alg);
1311		print_string_and_value(print->indent, "Hash Algorithm",
1312			pgp_show_hash_alg((uint8_t)content->sig.info.hash_alg),
1313			(uint8_t)content->sig.info.hash_alg);
1314		print_uint(print->indent, "Hashed data len",
1315			(unsigned)content->sig.info.v4_hashlen);
1316
1317		break;
1318
1319	case PGP_PTAG_CT_SIGNATURE_FOOTER:
1320		print_indent(print->indent);
1321		hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2);
1322
1323		switch (content->sig.info.key_alg) {
1324		case PGP_PKA_RSA:
1325			print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig);
1326			break;
1327
1328		case PGP_PKA_DSA:
1329			print_bn(print->indent, "r", content->sig.info.sig.dsa.r);
1330			print_bn(print->indent, "s", content->sig.info.sig.dsa.s);
1331			break;
1332
1333		case PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1334			print_bn(print->indent, "r", content->sig.info.sig.elgamal.r);
1335			print_bn(print->indent, "s", content->sig.info.sig.elgamal.s);
1336			break;
1337
1338		case PGP_PKA_PRIVATE00:
1339		case PGP_PKA_PRIVATE01:
1340		case PGP_PKA_PRIVATE02:
1341		case PGP_PKA_PRIVATE03:
1342		case PGP_PKA_PRIVATE04:
1343		case PGP_PKA_PRIVATE05:
1344		case PGP_PKA_PRIVATE06:
1345		case PGP_PKA_PRIVATE07:
1346		case PGP_PKA_PRIVATE08:
1347		case PGP_PKA_PRIVATE09:
1348		case PGP_PKA_PRIVATE10:
1349			print_data(print->indent, "Private/Experimental",
1350			   &content->sig.info.sig.unknown);
1351			break;
1352
1353		default:
1354			(void) fprintf(stderr,
1355				"pgp_print_packet: Unusual key algorithm\n");
1356			return 0;
1357		}
1358		break;
1359
1360	case PGP_GET_PASSPHRASE:
1361		print_tagname(print->indent, "PGP_GET_PASSPHRASE");
1362		break;
1363
1364	case PGP_PTAG_CT_SECRET_KEY:
1365		print_tagname(print->indent, "PGP_PTAG_CT_SECRET_KEY");
1366		print_seckey_verbose(pkt->tag, &content->seckey);
1367		break;
1368
1369	case PGP_PTAG_CT_ENCRYPTED_SECRET_KEY:
1370		print_tagname(print->indent, "PGP_PTAG_CT_ENCRYPTED_SECRET_KEY");
1371		print_seckey_verbose(pkt->tag, &content->seckey);
1372		break;
1373
1374	case PGP_PTAG_CT_ARMOUR_HEADER:
1375		print_tagname(print->indent, "ARMOUR HEADER");
1376		print_string(print->indent, "type", content->armour_header.type);
1377		break;
1378
1379	case PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1380		print_tagname(print->indent, "SIGNED CLEARTEXT HEADER");
1381		print_headers(&content->cleartext_head);
1382		break;
1383
1384	case PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY:
1385		print_tagname(print->indent, "SIGNED CLEARTEXT BODY");
1386		print_block(print->indent, "signed cleartext", content->cleartext_body.data,
1387			    content->cleartext_body.length);
1388		break;
1389
1390	case PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
1391		print_tagname(print->indent, "SIGNED CLEARTEXT TRAILER");
1392		printf("hash algorithm: %d\n",
1393		       content->cleartext_trailer->alg);
1394		printf("\n");
1395		break;
1396
1397	case PGP_PTAG_CT_UNARMOURED_TEXT:
1398		if (!print->unarmoured) {
1399			print_tagname(print->indent, "UNARMOURED TEXT");
1400			print->unarmoured = 1;
1401		}
1402		putchar('[');
1403		print_escaped(content->unarmoured_text.data,
1404			      content->unarmoured_text.length);
1405		putchar(']');
1406		break;
1407
1408	case PGP_PTAG_CT_ARMOUR_TRAILER:
1409		print_tagname(print->indent, "ARMOUR TRAILER");
1410		print_string(print->indent, "type", content->armour_header.type);
1411		break;
1412
1413	case PGP_PTAG_CT_PK_SESSION_KEY:
1414	case PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1415		print_pk_sesskey(pkt->tag, &content->pk_sesskey);
1416		break;
1417
1418	case PGP_GET_SECKEY:
1419		print_pk_sesskey(PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,
1420				    content->get_seckey.pk_sesskey);
1421		break;
1422
1423	default:
1424		print_tagname(print->indent, "UNKNOWN PACKET TYPE");
1425		fprintf(stderr, "pgp_print_packet: unknown tag=%d (0x%x)\n",
1426			pkt->tag, pkt->tag);
1427		return 0;
1428	}
1429	return 1;
1430}
1431
1432static pgp_cb_ret_t
1433cb_list_packets(const pgp_packet_t *pkt, pgp_cbdata_t *cbinfo)
1434{
1435	pgp_print_packet(&cbinfo->printstate, pkt);
1436	return PGP_RELEASE_MEMORY;
1437}
1438
1439/**
1440\ingroup Core_Print
1441\param filename
1442\param armour
1443\param keyring
1444\param cb_get_passphrase
1445*/
1446int
1447pgp_list_packets(pgp_io_t *io,
1448			char *filename,
1449			unsigned armour,
1450			pgp_keyring_t *secring,
1451			pgp_keyring_t *pubring,
1452			void *passfp,
1453			pgp_cbfunc_t *cb_get_passphrase)
1454{
1455	pgp_stream_t	*stream = NULL;
1456	const unsigned	 accumulate = 1;
1457	const int	 printerrors = 1;
1458	int		 fd;
1459
1460	fd = pgp_setup_file_read(io, &stream, filename, NULL, cb_list_packets,
1461				accumulate);
1462	pgp_parse_options(stream, PGP_PTAG_SS_ALL, PGP_PARSE_PARSED);
1463	stream->cryptinfo.secring = secring;
1464	stream->cryptinfo.pubring = pubring;
1465	stream->cbinfo.passfp = passfp;
1466	stream->cryptinfo.getpassphrase = cb_get_passphrase;
1467	if (armour) {
1468		pgp_reader_push_dearmour(stream);
1469	}
1470	pgp_parse(stream, printerrors);
1471	pgp_teardown_file_read(stream, fd);
1472	return 1;
1473}
1474