xref: /netbsd-src/crypto/external/bsd/netpgp/dist/src/lib/packet-print.c (revision 0294a66b694d2a57b43f64b66c7a4aee89316c4e)
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 
84 static void
print_indent(int indent)85 print_indent(int indent)
86 {
87 	int             i;
88 
89 	for (i = 0; i < indent; i++) {
90 		printf("  ");
91 	}
92 }
93 
94 static void
print_name(int indent,const char * name)95 print_name(int indent, const char *name)
96 {
97 	print_indent(indent);
98 	if (name) {
99 		printf("%s: ", name);
100 	}
101 }
102 
103 static void
print_hexdump(int indent,const char * name,const uint8_t * data,unsigned len)104 print_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 
110 static void
hexdump_data(int indent,const char * name,const uint8_t * data,unsigned len)111 hexdump_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 
117 static void
print_uint(int indent,const char * name,unsigned val)118 print_uint(int indent, const char *name, unsigned val)
119 {
120 	print_name(indent, name);
121 	printf("%u\n", val);
122 }
123 
124 static void
showtime(const char * name,time_t t)125 showtime(const char *name, time_t t)
126 {
127 	printf("%s=%" PRItime "d (%.24s)", name, (long long) t, ctime(&t));
128 }
129 
130 static void
print_time(int indent,const char * name,time_t t)131 print_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 
139 static void
print_string_and_value(int indent,const char * name,const char * str,uint8_t value)140 print_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 
146 static void
print_tagname(int indent,const char * str)147 print_tagname(int indent, const char *str)
148 {
149 	print_indent(indent);
150 	printf("%s packet\n", str);
151 }
152 
153 static void
print_data(int indent,const char * name,const pgp_data_t * data)154 print_data(int indent, const char *name, const pgp_data_t *data)
155 {
156 	print_hexdump(indent, name, data->contents, (unsigned)data->len);
157 }
158 
159 static void
print_bn(int indent,const char * name,const BIGNUM * bn)160 print_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 
172 static void
print_packet_hex(const pgp_subpacket_t * pkt)173 print_packet_hex(const pgp_subpacket_t *pkt)
174 {
175 	hexdump(stdout, "packet contents:", pkt->raw, pkt->length);
176 }
177 
178 static void
print_escaped(const uint8_t * data,size_t length)179 print_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 
192 static void
print_string(int indent,const char * name,const char * str)193 print_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 
200 static void
print_utf8_string(int indent,const char * name,const uint8_t * str)201 print_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 
207 static void
print_duration(int indent,const char * name,time_t t)208 print_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 
232 static void
print_boolean(int indent,const char * name,uint8_t boolval)233 print_boolean(int indent, const char *name, uint8_t boolval)
234 {
235 	print_name(indent, name);
236 	printf("%s\n", (boolval) ? "Yes" : "No");
237 }
238 
239 static void
print_text_breakdown(int indent,pgp_text_t * text)240 print_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 
268 static void
print_headers(const pgp_headers_t * h)269 print_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 
278 static void
print_block(int indent,const char * name,const uint8_t * str,size_t length)279 print_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 */
309 static int
numkeybits(const pgp_pubkey_t * pubkey)310 numkeybits(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 */
338 static char *
strhexdump(char * dest,const uint8_t * src,size_t length,const char * sep)339 strhexdump(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 */
352 static char *
ptimestr(char * dest,size_t size,time_t t)353 ptimestr(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 */
366 static int
psubkeybinding(char * buf,size_t size,const pgp_key_t * key,const char * expired)367 psubkeybinding(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 
380 static int
isrevoked(const pgp_key_t * key,unsigned uid)381 isrevoked(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 */
398 int
pgp_sprint_keydata(pgp_io_t * io,const pgp_keyring_t * keyring,const pgp_key_t * key,char ** buf,const char * header,const pgp_pubkey_t * pubkey,const int psigs)399 pgp_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 */
479 int
pgp_sprint_mj(pgp_io_t * io,const pgp_keyring_t * keyring,const pgp_key_t * key,mj_t * keyjson,const char * header,const pgp_pubkey_t * pubkey,const int psigs)480 pgp_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 
565 int
pgp_hkp_sprint_keydata(pgp_io_t * io,const pgp_keyring_t * keyring,const pgp_key_t * key,char ** buf,const pgp_pubkey_t * pubkey,const int psigs)566 pgp_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 */
629 void
pgp_print_keydata(pgp_io_t * io,const pgp_keyring_t * keyring,const pgp_key_t * key,const char * header,const pgp_pubkey_t * pubkey,const int psigs)630 pgp_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 */
646 void
pgp_print_pubkey(const pgp_pubkey_t * pubkey)647 pgp_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 
689 int
pgp_sprint_pubkey(const pgp_key_t * key,char * out,size_t outsize)690 pgp_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 */
739 static void
print_seckey_verbose(const pgp_content_enum type,const pgp_seckey_t * seckey)740 print_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 */
799 static void
print_pk_sesskey(pgp_content_enum tag,const pgp_pk_sesskey_t * key)800 print_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 
832 static void
start_subpacket(int * indent,int type)833 start_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 
842 static void
end_subpacket(int * indent)843 end_subpacket(int *indent)
844 {
845 	*indent -= 1;
846 }
847 
848 /**
849 \ingroup Core_Print
850 \param contents
851 */
852 int
pgp_print_packet(pgp_printstate_t * print,const pgp_packet_t * pkt)853 pgp_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 
1432 static pgp_cb_ret_t
cb_list_packets(const pgp_packet_t * pkt,pgp_cbdata_t * cbinfo)1433 cb_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 */
1446 int
pgp_list_packets(pgp_io_t * io,char * filename,unsigned armour,pgp_keyring_t * secring,pgp_keyring_t * pubring,void * passfp,pgp_cbfunc_t * cb_get_passphrase)1447 pgp_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