packet-print.c revision 1.1
1/*
2 * Copyright (c) 2005-2008 Nominet UK (www.nic.uk)
3 * All rights reserved.
4 * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted
5 * their moral rights under the UK Copyright Design and Patents Act 1988 to
6 * be recorded as the authors of this copyright work.
7 *
8 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
9 * use this file except in compliance with the License.
10 *
11 * You may obtain a copy of the License at
12 *     http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the License is distributed on an "AS IS" BASIS,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 *
18 * See the License for the specific language governing permissions and
19 * limitations under the License.
20 */
21
22/*
23 * ! \file \brief Standard API print functions
24 */
25#include "config.h"
26
27#ifdef HAVE_ASSERT_H
28#include <assert.h>
29#endif
30
31#include <string.h>
32
33#include "crypto.h"
34#include "keyring.h"
35#include "packet-show.h"
36#include "signature.h"
37
38#include "readerwriter.h"
39#include "netpgpdefs.h"
40#include "keyring_local.h"
41#include "parse_local.h"
42
43static int      indent = 0;
44
45static void print_bn(const char *, const BIGNUM *);
46static void print_hex(const unsigned char *, size_t);
47static void print_hexdump(const char *, const unsigned char *, unsigned int);
48static void print_hexdump_data(const char *, const unsigned char *, unsigned int);
49static void     print_indent(void);
50static void     print_name(const char *);
51static void print_string_and_value(const char *, const char *, unsigned char);
52static void     print_tagname(const char *);
53static void print_time(const char *, time_t);
54static void     print_time_short(time_t);
55static void print_unsigned_int(const char *, unsigned int);
56static void     showtime(const char *, time_t);
57static void     showtime_short(time_t);
58
59/**
60   \ingroup Core_Print
61
62   Prints a public key in succinct detail
63
64   \param key Ptr to public key
65*/
66
67void
68__ops_print_public_keydata(const __ops_keydata_t * key)
69{
70	unsigned int    i;
71
72	printf("pub %s ", __ops_show_pka(key->key.pkey.algorithm));
73	hexdump(key->key_id, OPS_KEY_ID_SIZE, "");
74	printf(" ");
75	print_time_short(key->key.pkey.creation_time);
76	printf("\nKey fingerprint: ");
77	hexdump(key->fingerprint.fingerprint, 20, " ");
78	printf("\n");
79
80	for (i = 0; i < key->nuids; i++) {
81		printf("uid                              %s\n",
82			key->uids[i].user_id);
83	}
84}
85
86/**
87\ingroup Core_Print
88\param pkey
89*/
90void
91__ops_print_public_key(const __ops_public_key_t * pkey)
92{
93	printf("------- PUBLIC KEY ------\n");
94	print_unsigned_int("Version", pkey->version);
95	print_time("Creation Time", pkey->creation_time);
96	if (pkey->version == OPS_V3)
97		print_unsigned_int("Days Valid", pkey->days_valid);
98
99	print_string_and_value("Algorithm", __ops_show_pka(pkey->algorithm),
100			       pkey->algorithm);
101
102	switch (pkey->algorithm) {
103	case OPS_PKA_DSA:
104		print_bn("p", pkey->key.dsa.p);
105		print_bn("q", pkey->key.dsa.q);
106		print_bn("g", pkey->key.dsa.g);
107		print_bn("y", pkey->key.dsa.y);
108		break;
109
110	case OPS_PKA_RSA:
111	case OPS_PKA_RSA_ENCRYPT_ONLY:
112	case OPS_PKA_RSA_SIGN_ONLY:
113		print_bn("n", pkey->key.rsa.n);
114		print_bn("e", pkey->key.rsa.e);
115		break;
116
117	case OPS_PKA_ELGAMAL:
118	case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
119		print_bn("p", pkey->key.elgamal.p);
120		print_bn("g", pkey->key.elgamal.g);
121		print_bn("y", pkey->key.elgamal.y);
122		break;
123
124	default:
125		assert( /* CONSTCOND */ 0);
126	}
127
128	printf("------- end of PUBLIC KEY ------\n");
129}
130
131/**
132   \ingroup Core_Print
133
134   Prints a secret key
135
136   \param key Ptr to public key
137*/
138
139void
140__ops_print_secret_keydata(const __ops_keydata_t * key)
141{
142	printf("sec ");
143	__ops_show_pka(key->key.pkey.algorithm);
144	printf(" ");
145
146	hexdump(key->key_id, OPS_KEY_ID_SIZE, "");
147	printf(" ");
148
149	print_time_short(key->key.pkey.creation_time);
150	printf(" ");
151
152	if (key->nuids == 1) {
153		/* print on same line as other info */
154		printf("%s\n", key->uids[0].user_id);
155	} else {
156		/* print all uids on separate line  */
157		unsigned int    i;
158		printf("\n");
159		for (i = 0; i < key->nuids; i++) {
160			printf("uid                              %s\n", key->uids[i].user_id);
161		}
162	}
163}
164
165/*
166void
167__ops_print_secret_key_verbose(const __ops_secret_key_t* skey)
168    {
169    if(key->type == OPS_PTAG_CT_SECRET_KEY)
170	print_tagname("SECRET_KEY");
171    else
172	print_tagname("ENCRYPTED_SECRET_KEY");
173    __ops_print_secret_key(key->type,skey);
174	}
175*/
176
177/**
178\ingroup Core_Print
179\param type
180\param skey
181*/
182static void
183__ops_print_secret_key_verbose(const __ops_content_tag_t type, const __ops_secret_key_t * skey)
184{
185	printf("------- SECRET KEY or ENCRYPTED SECRET KEY ------\n");
186	if (type == OPS_PTAG_CT_SECRET_KEY)
187		print_tagname("SECRET_KEY");
188	else
189		print_tagname("ENCRYPTED_SECRET_KEY");
190	/* __ops_print_public_key(key); */
191	printf("S2K Usage: %d\n", skey->s2k_usage);
192	if (skey->s2k_usage != OPS_S2KU_NONE) {
193		printf("S2K Specifier: %d\n", skey->s2k_specifier);
194		printf("Symmetric algorithm: %d (%s)\n", skey->algorithm,
195		       __ops_show_symmetric_algorithm(skey->algorithm));
196		printf("Hash algorithm: %d (%s)\n", skey->hash_algorithm,
197		       __ops_show_hash_algorithm(skey->hash_algorithm));
198		if (skey->s2k_specifier != OPS_S2KS_SIMPLE)
199			print_hexdump("Salt", skey->salt, sizeof(skey->salt));
200		if (skey->s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED)
201			printf("Octet count: %d\n", skey->octet_count);
202		print_hexdump("IV", skey->iv, __ops_block_size(skey->algorithm));
203	}
204	/* no more set if encrypted */
205	if (type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY)
206		return;
207
208	switch (skey->public_key.algorithm) {
209	case OPS_PKA_RSA:
210		print_bn("d", skey->key.rsa.d);
211		print_bn("p", skey->key.rsa.p);
212		print_bn("q", skey->key.rsa.q);
213		print_bn("u", skey->key.rsa.u);
214		break;
215
216	case OPS_PKA_DSA:
217		print_bn("x", skey->key.dsa.x);
218		break;
219
220	default:
221		assert( /* CONSTCOND */ 0);
222	}
223
224	if (skey->s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED)
225		print_hexdump("Checkhash", skey->checkhash, OPS_CHECKHASH_SIZE);
226	else
227		printf("Checksum: %04x\n", skey->checksum);
228
229	printf("------- end of SECRET KEY or ENCRYPTED SECRET KEY ------\n");
230}
231
232
233/* static functions */
234
235static void
236print_unsigned_int(const char *name, unsigned int val)
237{
238	print_name(name);
239	printf("%d\n", val);
240}
241
242static void
243print_time(const char *name, time_t t)
244{
245	print_indent();
246	printf("%s: ", name);
247	showtime("time", t);
248	printf("\n");
249}
250
251static void
252print_time_short(time_t t)
253{
254	showtime_short(t);
255}
256
257static void
258print_string_and_value(const char *name, const char *str,
259		       unsigned char value)
260{
261	print_name(name);
262
263	printf("%s", str);
264	printf(" (0x%x)", value);
265	printf("\n");
266}
267
268void
269print_bn(const char *name, const BIGNUM * bn)
270{
271	print_indent();
272	printf("%s=", name);
273	if (bn) {
274		BN_print_fp(stdout, bn);
275		putchar('\n');
276	} else
277		puts("(unset)");
278}
279
280static void
281print_tagname(const char *str)
282{
283	print_indent();
284	printf("%s packet\n", str);
285}
286
287static void
288print_hexdump(const char *name,
289	      const unsigned char *data,
290	      unsigned int len)
291{
292	print_name(name);
293
294	printf("len=%d, data=0x", len);
295	print_hex(data, len);
296	printf("\n");
297}
298
299static void
300print_hexdump_data(const char *name,
301		   const unsigned char *data,
302		   unsigned int len)
303{
304	print_name(name);
305
306	printf("0x");
307	print_hex(data, len);
308	printf("\n");
309}
310
311static void
312print_data(const char *name, const __ops_data_t * data)
313{
314	print_hexdump(name, data->contents, data->len);
315}
316
317
318static void
319print_name(const char *name)
320{
321	print_indent();
322	if (name)
323		printf("%s: ", name);
324}
325
326static void
327print_indent(void)
328{
329	int             i = 0;
330
331	for (i = 0; i < indent; i++)
332		printf("  ");
333}
334
335/* printhex is now print_hex for consistency */
336static void
337print_hex(const unsigned char *src, size_t length)
338{
339	while (length--)
340		printf("%02X", *src++);
341}
342
343static void
344showtime(const char *name, time_t t)
345{
346	printf("%s=%" PRItime "d (%.24s)", name, (long long) t, ctime(&t));
347}
348static void
349showtime_short(time_t t)
350{
351	struct tm      *tm;
352	/*
353        const int maxbuf=512;
354        char buf[maxbuf+1];
355        buf[maxbuf]='\0';
356        // this needs to be tm struct
357        strftime(buf,maxbuf,"%F",&t);
358        printf(buf);
359        */
360	tm = gmtime(&t);
361	printf("%04d-%02d-%02d", tm->tm_year + 1900, tm->tm_mon + 1, tm->tm_mday);
362}
363
364
365static void
366print_packet_hex(const __ops_packet_t * packet)
367{
368	unsigned char  *cur;
369	int             i;
370	int             rem;
371	int             blksz = 4;
372
373	printf("\nhexdump of packet contents follows:\n");
374
375
376	for (i = 1, cur = packet->raw; cur < (packet->raw + packet->length); cur += blksz, i++) {
377		rem = packet->raw + packet->length - cur;
378		hexdump(cur, rem <= blksz ? rem : blksz, "");
379		printf(" ");
380		if (!(i % 8))
381			printf("\n");
382
383	}
384
385	printf("\n");
386}
387
388static void
389print_escaped(const unsigned char *data, size_t length)
390{
391	while (length-- > 0) {
392		if ((*data >= 0x20 && *data < 0x7f && *data != '%') || *data == '\n')
393			putchar(*data);
394		else
395			printf("%%%02x", *data);
396		++data;
397	}
398}
399
400static void
401print_string(const char *name, const char *str)
402{
403	print_name(name);
404	print_escaped((const unsigned char *) str, strlen(str));
405	putchar('\n');
406}
407
408static void
409print_utf8_string(const char *name, const unsigned char *str)
410{
411	/* \todo Do this better for non-English character sets */
412	print_string(name, (const char *) str);
413}
414
415static void
416print_duration(const char *name, time_t t)
417{
418	int             mins, hours, days, years;
419
420	print_indent();
421	printf("%s: ", name);
422	printf("duration %" PRItime "d seconds", (long long) t);
423
424	mins = t / 60;
425	hours = mins / 60;
426	days = hours / 24;
427	years = days / 365;
428
429	printf(" (approx. ");
430	if (years)
431		printf("%d %s", years, years == 1 ? "year" : "years");
432	else if (days)
433		printf("%d %s", days, days == 1 ? "day" : "days");
434	else if (hours)
435		printf("%d %s", hours, hours == 1 ? "hour" : "hours");
436
437	printf(")");
438	printf("\n");
439}
440
441static void
442print_boolean(const char *name, unsigned char boolval)
443{
444	print_name(name);
445	printf("%s\n", (boolval) ? "Yes" : "No");
446}
447
448static void
449print_text_breakdown(__ops_text_t * text)
450{
451	unsigned        i;
452	const char     *prefix = ".. ";
453
454	/* these were recognised */
455
456	for (i = 0; i < text->known.used; i++) {
457		print_indent();
458		printf(prefix);
459		printf("%s\n", text->known.strings[i]);
460	}
461
462	/*
463	 * these were not recognised. the strings will contain the hex value
464	 * of the unrecognised value in string format - see
465	 * process_octet_str()
466	 */
467
468	if (text->unknown.used) {
469		printf("\n");
470		print_indent();
471		printf("Not Recognised: ");
472	}
473	for (i = 0; i < text->unknown.used; i++) {
474		print_indent();
475		printf(prefix);
476		printf("%s\n", text->unknown.strings[i]);
477	}
478
479}
480
481static void
482print_headers(const __ops_headers_t * headers)
483{
484	unsigned        n;
485
486	for (n = 0; n < headers->nheaders; ++n)
487		printf("%s=%s\n", headers->headers[n].key, headers->headers[n].value);
488}
489
490static void
491print_block(const char *name, const unsigned char *str,
492	    size_t length)
493{
494	int             o = length;
495
496	print_indent();
497	printf(">>>>> %s >>>>>\n", name);
498
499	print_indent();
500	for (; length > 0; --length) {
501		if (*str >= 0x20 && *str < 0x7f && *str != '%')
502			putchar(*str);
503		else if (*str == '\n') {
504			putchar(*str);
505			print_indent();
506		} else
507			printf("%%%02x", *str);
508		++str;
509	}
510	if (o && str[-1] != '\n') {
511		putchar('\n');
512		print_indent();
513		fputs("[no newline]", stdout);
514	} else
515		print_indent();
516	printf("<<<<< %s <<<<<\n", name);
517}
518
519/**
520\ingroup Core_Print
521\param tag
522\param key
523*/
524static void
525__ops_print_pk_session_key(__ops_content_tag_t tag,
526			 const __ops_pk_session_key_t * key)
527{
528	if (tag == OPS_PTAG_CT_PK_SESSION_KEY)
529		print_tagname("PUBLIC KEY SESSION KEY");
530	else
531		print_tagname("ENCRYPTED PUBLIC KEY SESSION KEY");
532
533	printf("Version: %d\n", key->version);
534	print_hexdump("Key ID", key->key_id, sizeof(key->key_id));
535	printf("Algorithm: %d (%s)\n", key->algorithm,
536	       __ops_show_pka(key->algorithm));
537	switch (key->algorithm) {
538	case OPS_PKA_RSA:
539		print_bn("encrypted_m", key->parameters.rsa.encrypted_m);
540		break;
541
542	case OPS_PKA_ELGAMAL:
543		print_bn("g_to_k", key->parameters.elgamal.g_to_k);
544		print_bn("encrypted_m", key->parameters.elgamal.encrypted_m);
545		break;
546
547	default:
548		assert( /* CONSTCOND */ 0);
549	}
550
551	if (tag != OPS_PTAG_CT_PK_SESSION_KEY)
552		return;
553
554	printf("Symmetric algorithm: %d (%s)\n", key->symmetric_algorithm,
555	       __ops_show_symmetric_algorithm(key->symmetric_algorithm));
556	print_hexdump("Key", key->key, __ops_key_size(key->symmetric_algorithm));
557	printf("Checksum: %04x\n", key->checksum);
558}
559
560static void
561start_subpacket(unsigned type)
562{
563	indent++;
564	print_indent();
565	printf("-- %s (type 0x%02x)\n",
566	       __ops_show_ss_type(type),
567	       type - OPS_PTAG_SIGNATURE_SUBPACKET_BASE);
568}
569
570static void
571end_subpacket(void)
572{
573	indent--;
574}
575
576/**
577\ingroup Core_Print
578\param contents
579*/
580int
581__ops_print_packet(const __ops_parser_content_t * contents)
582{
583	const __ops_parser_content_union_t *content = &contents->u;
584	__ops_text_t     *text;
585	const char     *str;
586	static bool unarmoured;
587
588	if (unarmoured && contents->tag != OPS_PTAG_CT_UNARMOURED_TEXT) {
589		unarmoured = false;
590		puts("UNARMOURED TEXT ends");
591	}
592	if (contents->tag == OPS_PARSER_PTAG) {
593		printf("=> OPS_PARSER_PTAG: %s\n", __ops_show_packet_tag(content->ptag.content_tag));
594	} else {
595		printf("=> %s\n", __ops_show_packet_tag(contents->tag));
596	}
597
598	switch (contents->tag) {
599	case OPS_PARSER_ERROR:
600		printf("parse error: %s\n", content->error.error);
601		break;
602
603	case OPS_PARSER_ERRCODE:
604		printf("parse error: %s\n",
605		       __ops_errcode(content->errcode.errcode));
606		break;
607
608	case OPS_PARSER_PACKET_END:
609		print_packet_hex(&content->packet);
610		break;
611
612	case OPS_PARSER_PTAG:
613		if (content->ptag.content_tag == OPS_PTAG_CT_PUBLIC_KEY) {
614			indent = 0;
615			printf("\n*** NEXT KEY ***\n");
616		}
617		printf("\n");
618		print_indent();
619		printf("==== ptag new_format=%d content_tag=%d length_type=%d"
620		       " length=0x%x (%d) position=0x%x (%d)\n", content->ptag.new_format,
621		       content->ptag.content_tag, content->ptag.length_type,
622		       content->ptag.length, content->ptag.length,
623		       content->ptag.position, content->ptag.position);
624		print_tagname(__ops_show_packet_tag(content->ptag.content_tag));
625		break;
626
627	case OPS_PTAG_CT_SE_DATA_HEADER:
628		print_tagname("SYMMETRIC ENCRYPTED DATA");
629		break;
630
631	case OPS_PTAG_CT_SE_IP_DATA_HEADER:
632		print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER");
633		printf("Version: %d\n", content->se_ip_data_header.version);
634		break;
635
636	case OPS_PTAG_CT_SE_IP_DATA_BODY:
637		print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY");
638		printf("  data body length=%d\n",
639		       content->se_data_body.length);
640		printf("    data=");
641		hexdump(content->se_data_body.data,
642			content->se_data_body.length, "");
643		printf("\n");
644		break;
645
646	case OPS_PTAG_CT_PUBLIC_KEY:
647	case OPS_PTAG_CT_PUBLIC_SUBKEY:
648		if (contents->tag == OPS_PTAG_CT_PUBLIC_KEY)
649			print_tagname("PUBLIC KEY");
650		else
651			print_tagname("PUBLIC SUBKEY");
652		__ops_print_public_key(&content->public_key);
653		break;
654
655	case OPS_PTAG_CT_TRUST:
656		print_tagname("TRUST");
657		print_data("Trust", &content->trust.data);
658		break;
659
660	case OPS_PTAG_CT_USER_ID:
661		/* XXX: how do we print UTF-8? */
662		print_tagname("USER ID");
663		print_utf8_string("user_id", content->user_id.user_id);
664		break;
665
666	case OPS_PTAG_CT_SIGNATURE:
667		print_tagname("SIGNATURE");
668		print_indent();
669		print_unsigned_int("Signature Version",
670				   content->signature.info.version);
671		if (content->signature.info.creation_time_set)
672			print_time("Signature Creation Time",
673				   content->signature.info.creation_time);
674
675		print_string_and_value("Signature Type",
676			    __ops_show_sig_type(content->signature.info.type),
677				       content->signature.info.type);
678
679		if (content->signature.info.signer_id_set)
680			print_hexdump_data("Signer ID",
681					   content->signature.info.signer_id,
682				  sizeof(content->signature.info.signer_id));
683
684		print_string_and_value("Public Key Algorithm",
685			__ops_show_pka(content->signature.info.key_algorithm),
686				     content->signature.info.key_algorithm);
687		print_string_and_value("Hash Algorithm",
688				       __ops_show_hash_algorithm(content->signature.info.hash_algorithm),
689				    content->signature.info.hash_algorithm);
690
691		print_unsigned_int("Hashed data len", content->signature.info.v4_hashed_data_length);
692
693		print_indent();
694		print_hexdump_data("hash2", &content->signature.hash2[0], 2);
695
696		switch (content->signature.info.key_algorithm) {
697		case OPS_PKA_RSA:
698		case OPS_PKA_RSA_SIGN_ONLY:
699			print_bn("sig", content->signature.info.signature.rsa.sig);
700			break;
701
702		case OPS_PKA_DSA:
703			print_bn("r", content->signature.info.signature.dsa.r);
704			print_bn("s", content->signature.info.signature.dsa.s);
705			break;
706
707		case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
708			print_bn("r", content->signature.info.signature.elgamal.r);
709			print_bn("s", content->signature.info.signature.elgamal.s);
710			break;
711
712		default:
713			assert( /* CONSTCOND */ 0);
714		}
715
716		if (content->signature.hash)
717			printf("data hash is set\n");
718
719		break;
720
721	case OPS_PTAG_CT_COMPRESSED:
722		print_tagname("COMPRESSED");
723		print_unsigned_int("Compressed Data Type", content->compressed.type);
724		break;
725
726	case OPS_PTAG_CT_ONE_PASS_SIGNATURE:
727		print_tagname("ONE PASS SIGNATURE");
728
729		print_unsigned_int("Version", content->one_pass_signature.version);
730		print_string_and_value("Signature Type",
731		    __ops_show_sig_type(content->one_pass_signature.sig_type),
732				       content->one_pass_signature.sig_type);
733		print_string_and_value("Hash Algorithm",
734				       __ops_show_hash_algorithm(content->one_pass_signature.hash_algorithm),
735				content->one_pass_signature.hash_algorithm);
736		print_string_and_value("Public Key Algorithm",
737		    __ops_show_pka(content->one_pass_signature.key_algorithm),
738				 content->one_pass_signature.key_algorithm);
739		print_hexdump_data("Signer ID",
740				   content->one_pass_signature.keyid,
741				   sizeof(content->one_pass_signature.keyid));
742
743		print_unsigned_int("Nested",
744				   content->one_pass_signature.nested);
745		break;
746
747	case OPS_PTAG_CT_USER_ATTRIBUTE:
748		print_tagname("USER ATTRIBUTE");
749		print_hexdump("User Attribute",
750			      content->user_attribute.data.contents,
751			      content->user_attribute.data.len);
752		break;
753
754	case OPS_PTAG_RAW_SS:
755		assert(!contents->critical);
756		start_subpacket(contents->tag);
757		print_unsigned_int("Raw Signature Subpacket: tag",
758		   content->ss_raw.tag - OPS_PTAG_SIGNATURE_SUBPACKET_BASE);
759		print_hexdump("Raw Data",
760			      content->ss_raw.raw,
761			      content->ss_raw.length);
762		break;
763
764	case OPS_PTAG_SS_CREATION_TIME:
765		start_subpacket(contents->tag);
766		print_time("Signature Creation Time", content->ss_time.time);
767		end_subpacket();
768		break;
769
770	case OPS_PTAG_SS_EXPIRATION_TIME:
771		start_subpacket(contents->tag);
772		print_duration("Signature Expiration Time", content->ss_time.time);
773		end_subpacket();
774		break;
775
776	case OPS_PTAG_SS_KEY_EXPIRATION_TIME:
777		start_subpacket(contents->tag);
778		print_duration("Key Expiration Time", content->ss_time.time);
779		end_subpacket();
780		break;
781
782	case OPS_PTAG_SS_TRUST:
783		start_subpacket(contents->tag);
784		print_string("Trust Signature", "");
785		print_unsigned_int("Level",
786				   content->ss_trust.level);
787		print_unsigned_int("Amount",
788				   content->ss_trust.amount);
789		end_subpacket();
790		break;
791
792	case OPS_PTAG_SS_REVOCABLE:
793		start_subpacket(contents->tag);
794		print_boolean("Revocable", content->ss_revocable.revocable);
795		end_subpacket();
796		break;
797
798	case OPS_PTAG_SS_REVOCATION_KEY:
799		start_subpacket(contents->tag);
800		/* not yet tested */
801		printf("  revocation key: class=0x%x",
802		       content->ss_revocation_key.class);
803		if (content->ss_revocation_key.class & 0x40)
804			printf(" (sensitive)");
805		printf(", algid=0x%x",
806		       content->ss_revocation_key.algid);
807		printf(", fingerprint=");
808		hexdump(content->ss_revocation_key.fingerprint, 20, "");
809		printf("\n");
810		end_subpacket();
811		break;
812
813	case OPS_PTAG_SS_ISSUER_KEY_ID:
814		start_subpacket(contents->tag);
815		print_hexdump("Issuer Key Id",
816			      &content->ss_issuer_key_id.key_id[0],
817			      sizeof(content->ss_issuer_key_id.key_id));
818		end_subpacket();
819		break;
820
821	case OPS_PTAG_SS_PREFERRED_SKA:
822		start_subpacket(contents->tag);
823		print_data("Preferred Symmetric Algorithms",
824			   &content->ss_preferred_ska.data);
825
826		text = __ops_showall_ss_preferred_ska(content->ss_preferred_ska);
827		print_text_breakdown(text);
828		__ops_text_free(text);
829
830		end_subpacket();
831		break;
832
833	case OPS_PTAG_SS_PRIMARY_USER_ID:
834		start_subpacket(contents->tag);
835		print_boolean("Primary User ID",
836			      content->ss_primary_user_id.primary_user_id);
837		end_subpacket();
838		break;
839
840	case OPS_PTAG_SS_PREFERRED_HASH:
841		start_subpacket(contents->tag);
842		print_data("Preferred Hash Algorithms",
843			   &content->ss_preferred_hash.data);
844
845		text = __ops_showall_ss_preferred_hash(content->ss_preferred_hash);
846		print_text_breakdown(text);
847		__ops_text_free(text);
848		end_subpacket();
849		break;
850
851	case OPS_PTAG_SS_PREFERRED_COMPRESSION:
852		start_subpacket(contents->tag);
853		print_data("Preferred Compression Algorithms",
854			   &content->ss_preferred_compression.data);
855
856		text = __ops_showall_ss_preferred_compression(content->ss_preferred_compression);
857		print_text_breakdown(text);
858		__ops_text_free(text);
859		end_subpacket();
860		break;
861
862	case OPS_PTAG_SS_KEY_FLAGS:
863		start_subpacket(contents->tag);
864		print_data("Key Flags", &content->ss_key_flags.data);
865
866		text = __ops_showall_ss_key_flags(content->ss_key_flags);
867		print_text_breakdown(text);
868		__ops_text_free(text);
869
870		end_subpacket();
871		break;
872
873	case OPS_PTAG_SS_KEY_SERVER_PREFS:
874		start_subpacket(contents->tag);
875		print_data("Key Server Preferences",
876			   &content->ss_key_server_prefs.data);
877
878		text = __ops_showall_ss_key_server_prefs(content->ss_key_server_prefs);
879		print_text_breakdown(text);
880		__ops_text_free(text);
881
882		end_subpacket();
883		break;
884
885	case OPS_PTAG_SS_FEATURES:
886		start_subpacket(contents->tag);
887		print_data("Features",
888			   &content->ss_features.data);
889
890		text = __ops_showall_ss_features(content->ss_features);
891		print_text_breakdown(text);
892		__ops_text_free(text);
893
894		end_subpacket();
895		break;
896
897	case OPS_PTAG_SS_NOTATION_DATA:
898		start_subpacket(contents->tag);
899		print_indent();
900		printf("Notation Data:\n");
901
902		indent++;
903		print_data("Flags",
904			   &content->ss_notation_data.flags);
905		text = __ops_showall_ss_notation_data_flags(content->ss_notation_data);
906		print_text_breakdown(text);
907		__ops_text_free(text);
908
909		/* xxx - TODO: print out UTF - rachel */
910
911		print_data("Name",
912			   &content->ss_notation_data.name);
913
914		print_data("Value",
915			   &content->ss_notation_data.value);
916
917		indent--;
918		end_subpacket();
919		break;
920
921	case OPS_PTAG_SS_REGEXP:
922		start_subpacket(contents->tag);
923		print_hexdump("Regular Expression",
924			      (unsigned char *) content->ss_regexp.text,
925			      strlen(content->ss_regexp.text));
926		print_string(NULL,
927			     content->ss_regexp.text);
928		end_subpacket();
929		break;
930
931	case OPS_PTAG_SS_POLICY_URI:
932		start_subpacket(contents->tag);
933		print_string("Policy URL",
934			     content->ss_policy_url.text);
935		end_subpacket();
936		break;
937
938	case OPS_PTAG_SS_SIGNERS_USER_ID:
939		start_subpacket(contents->tag);
940		print_utf8_string("Signer's User ID", content->ss_signers_user_id.user_id);
941		end_subpacket();
942		break;
943
944	case OPS_PTAG_SS_PREFERRED_KEY_SERVER:
945		start_subpacket(contents->tag);
946		print_string("Preferred Key Server",
947			     content->ss_preferred_key_server.text);
948		end_subpacket();
949		break;
950
951	case OPS_PTAG_SS_EMBEDDED_SIGNATURE:
952		start_subpacket(contents->tag);
953		end_subpacket();/* \todo print out contents? */
954		break;
955
956	case OPS_PTAG_SS_USERDEFINED00:
957	case OPS_PTAG_SS_USERDEFINED01:
958	case OPS_PTAG_SS_USERDEFINED02:
959	case OPS_PTAG_SS_USERDEFINED03:
960	case OPS_PTAG_SS_USERDEFINED04:
961	case OPS_PTAG_SS_USERDEFINED05:
962	case OPS_PTAG_SS_USERDEFINED06:
963	case OPS_PTAG_SS_USERDEFINED07:
964	case OPS_PTAG_SS_USERDEFINED08:
965	case OPS_PTAG_SS_USERDEFINED09:
966	case OPS_PTAG_SS_USERDEFINED10:
967		start_subpacket(contents->tag);
968		print_hexdump("Internal or user-defined",
969			      content->ss_userdefined.data.contents,
970			      content->ss_userdefined.data.len);
971		end_subpacket();
972		break;
973
974	case OPS_PTAG_SS_RESERVED:
975		start_subpacket(contents->tag);
976		print_hexdump("Reserved",
977			      content->ss_userdefined.data.contents,
978			      content->ss_userdefined.data.len);
979		end_subpacket();
980		break;
981
982	case OPS_PTAG_SS_REVOCATION_REASON:
983		start_subpacket(contents->tag);
984		print_hexdump("Revocation Reason",
985			      &content->ss_revocation_reason.code,
986			      1);
987		str = __ops_show_ss_rr_code(content->ss_revocation_reason.code);
988		print_string(NULL, str);
989		/* xxx - todo : output text as UTF-8 string */
990		end_subpacket();
991		break;
992
993	case OPS_PTAG_CT_LITERAL_DATA_HEADER:
994		print_tagname("LITERAL DATA HEADER");
995		printf("  literal data header format=%c filename='%s'\n",
996		       content->literal_data_header.format,
997		       content->literal_data_header.filename);
998		showtime("    modification time",
999			 content->literal_data_header.modification_time);
1000		printf("\n");
1001		break;
1002
1003	case OPS_PTAG_CT_LITERAL_DATA_BODY:
1004		print_tagname("LITERAL DATA BODY");
1005		printf("  literal data body length=%d\n",
1006		       content->literal_data_body.length);
1007		printf("    data=");
1008		print_escaped(content->literal_data_body.data,
1009			      content->literal_data_body.length);
1010		printf("\n");
1011		break;
1012
1013	case OPS_PTAG_CT_SIGNATURE_HEADER:
1014		print_tagname("SIGNATURE");
1015		print_indent();
1016		print_unsigned_int("Signature Version",
1017				   content->signature.info.version);
1018		if (content->signature.info.creation_time_set)
1019			print_time("Signature Creation Time", content->signature.info.creation_time);
1020
1021		print_string_and_value("Signature Type",
1022			    __ops_show_sig_type(content->signature.info.type),
1023				       content->signature.info.type);
1024
1025		if (content->signature.info.signer_id_set)
1026			print_hexdump_data("Signer ID",
1027					   content->signature.info.signer_id,
1028				  sizeof(content->signature.info.signer_id));
1029
1030		print_string_and_value("Public Key Algorithm",
1031			__ops_show_pka(content->signature.info.key_algorithm),
1032				     content->signature.info.key_algorithm);
1033		print_string_and_value("Hash Algorithm",
1034				       __ops_show_hash_algorithm(content->signature.info.hash_algorithm),
1035				    content->signature.info.hash_algorithm);
1036
1037		break;
1038
1039	case OPS_PTAG_CT_SIGNATURE_FOOTER:
1040		print_indent();
1041		print_hexdump_data("hash2", &content->signature.hash2[0], 2);
1042
1043		switch (content->signature.info.key_algorithm) {
1044		case OPS_PKA_RSA:
1045			print_bn("sig", content->signature.info.signature.rsa.sig);
1046			break;
1047
1048		case OPS_PKA_DSA:
1049			print_bn("r", content->signature.info.signature.dsa.r);
1050			print_bn("s", content->signature.info.signature.dsa.s);
1051			break;
1052
1053		case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1054			print_bn("r", content->signature.info.signature.elgamal.r);
1055			print_bn("s", content->signature.info.signature.elgamal.s);
1056			break;
1057
1058		case OPS_PKA_PRIVATE00:
1059		case OPS_PKA_PRIVATE01:
1060		case OPS_PKA_PRIVATE02:
1061		case OPS_PKA_PRIVATE03:
1062		case OPS_PKA_PRIVATE04:
1063		case OPS_PKA_PRIVATE05:
1064		case OPS_PKA_PRIVATE06:
1065		case OPS_PKA_PRIVATE07:
1066		case OPS_PKA_PRIVATE08:
1067		case OPS_PKA_PRIVATE09:
1068		case OPS_PKA_PRIVATE10:
1069			print_data("Private/Experimental",
1070			   &content->signature.info.signature.unknown.data);
1071			break;
1072
1073		default:
1074			assert( /* CONSTCOND */ 0);
1075		}
1076		break;
1077
1078	case OPS_PARSER_CMD_GET_SK_PASSPHRASE:
1079		print_tagname("OPS_PARSER_CMD_GET_SK_PASSPHRASE");
1080		break;
1081
1082	case OPS_PTAG_CT_SECRET_KEY:
1083		print_tagname("OPS_PTAG_CT_SECRET_KEY");
1084		__ops_print_secret_key_verbose(contents->tag, &content->secret_key);
1085		break;
1086
1087	case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY:
1088		print_tagname("OPS_PTAG_CT_ENCRYPTED_SECRET_KEY");
1089		__ops_print_secret_key_verbose(contents->tag, &content->secret_key);
1090		break;
1091
1092	case OPS_PTAG_CT_ARMOUR_HEADER:
1093		print_tagname("ARMOUR HEADER");
1094		print_string("type", content->armour_header.type);
1095		break;
1096
1097	case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1098		print_tagname("SIGNED CLEARTEXT HEADER");
1099		print_headers(&content->signed_cleartext_header.headers);
1100		break;
1101
1102	case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
1103		print_tagname("SIGNED CLEARTEXT BODY");
1104		print_block("signed cleartext", content->signed_cleartext_body.data,
1105			    content->signed_cleartext_body.length);
1106		break;
1107
1108	case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
1109		print_tagname("SIGNED CLEARTEXT TRAILER");
1110		printf("hash algorithm: %d\n",
1111		       content->signed_cleartext_trailer.hash->algorithm);
1112		printf("\n");
1113		break;
1114
1115	case OPS_PTAG_CT_UNARMOURED_TEXT:
1116		if (!unarmoured) {
1117			print_tagname("UNARMOURED TEXT");
1118			unarmoured = true;
1119		}
1120		putchar('[');
1121		print_escaped(content->unarmoured_text.data,
1122			      content->unarmoured_text.length);
1123		putchar(']');
1124		break;
1125
1126	case OPS_PTAG_CT_ARMOUR_TRAILER:
1127		print_tagname("ARMOUR TRAILER");
1128		print_string("type", content->armour_header.type);
1129		break;
1130
1131	case OPS_PTAG_CT_PK_SESSION_KEY:
1132	case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1133		__ops_print_pk_session_key(contents->tag, &content->pk_session_key);
1134		break;
1135
1136	case OPS_PARSER_CMD_GET_SECRET_KEY:
1137		__ops_print_pk_session_key(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,
1138				    content->get_secret_key.pk_session_key);
1139		break;
1140
1141	default:
1142		print_tagname("UNKNOWN PACKET TYPE");
1143		fprintf(stderr, "__ops_print_packet: unknown tag=%d (0x%x)\n", contents->tag,
1144			contents->tag);
1145		exit(1);
1146	}
1147	return 1;
1148}
1149
1150static __ops_parse_cb_return_t
1151cb_list_packets(const __ops_parser_content_t * contents, __ops_parse_cb_info_t * cbinfo)
1152{
1153	OPS_USED(cbinfo);
1154
1155	__ops_print_packet(contents);
1156#ifdef XXX
1157	if (unarmoured && contents->tag != OPS_PTAG_CT_UNARMOURED_TEXT) {
1158		unarmoured = false;
1159		puts("UNARMOURED TEXT ends");
1160	}
1161	switch (contents->tag) {
1162	case OPS_PARSER_ERROR:
1163		printf("parse error: %s\n", content->error.error);
1164		break;
1165
1166	case OPS_PARSER_ERRCODE:
1167		printf("parse error: %s\n",
1168		       __ops_errcode(content->errcode.errcode));
1169		break;
1170
1171	case OPS_PARSER_PACKET_END:
1172		print_packet_hex(&content->packet);
1173		break;
1174
1175	case OPS_PARSER_PTAG:
1176		if (content->ptag.content_tag == OPS_PTAG_CT_PUBLIC_KEY) {
1177			indent = 0;
1178			printf("\n*** NEXT KEY ***\n");
1179		}
1180		printf("\n");
1181		print_indent();
1182		printf("==== ptag new_format=%d content_tag=%d length_type=%d"
1183		       " length=0x%x (%d) position=0x%x (%d)\n", content->ptag.new_format,
1184		       content->ptag.content_tag, content->ptag.length_type,
1185		       content->ptag.length, content->ptag.length,
1186		       content->ptag.position, content->ptag.position);
1187		print_tagname(__ops_show_packet_tag(content->ptag.content_tag));
1188		break;
1189
1190	case OPS_PTAG_CT_SE_DATA_HEADER:
1191		print_tagname("SYMMETRIC ENCRYPTED DATA");
1192		break;
1193
1194	case OPS_PTAG_CT_SE_IP_DATA_HEADER:
1195		print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER");
1196		printf("Version: %d\n", content->se_ip_data_header.version);
1197		break;
1198
1199	case OPS_PTAG_CT_SE_IP_DATA_BODY:
1200		print_tagname("SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY");
1201		printf("  data body length=%d\n",
1202		       content->se_data_body.length);
1203		printf("    data=");
1204		hexdump(content->se_data_body.data,
1205			content->se_data_body.length, "");
1206		printf("\n");
1207		break;
1208
1209	case OPS_PTAG_CT_PUBLIC_KEY:
1210	case OPS_PTAG_CT_PUBLIC_SUBKEY:
1211		if (contents->tag == OPS_PTAG_CT_PUBLIC_KEY)
1212			print_tagname("PUBLIC KEY");
1213		else
1214			print_tagname("PUBLIC SUBKEY");
1215
1216		__ops_print_public_key(&content->public_key);
1217		break;
1218
1219	case OPS_PTAG_CT_TRUST:
1220		print_tagname("TRUST");
1221		print_data("Trust", &content->trust.data);
1222		break;
1223
1224	case OPS_PTAG_CT_USER_ID:
1225		/* XXX: how do we print UTF-8? */
1226		print_tagname("USER ID");
1227		print_utf8_string("user_id", content->user_id.user_id);
1228		break;
1229
1230	case OPS_PTAG_CT_SIGNATURE:
1231		print_tagname("SIGNATURE");
1232		print_indent();
1233		print_unsigned_int("Signature Version",
1234				   content->signature.info.version);
1235		if (content->signature.info.creation_time_set)
1236			print_time("Signature Creation Time",
1237				   content->signature.info.creation_time);
1238
1239		print_string_and_value("Signature Type",
1240			    __ops_show_sig_type(content->signature.info.type),
1241				       content->signature.info.type);
1242
1243		if (content->signature.info.signer_id_set)
1244			print_hexdump_data("Signer ID",
1245					   content->signature.info.signer_id,
1246				  sizeof(content->signature.info.signer_id));
1247
1248		print_string_and_value("Public Key Algorithm",
1249			__ops_show_pka(content->signature.info.key_algorithm),
1250				     content->signature.info.key_algorithm);
1251		print_string_and_value("Hash Algorithm",
1252				       __ops_show_hash_algorithm(content->signature.info.hash_algorithm),
1253				    content->signature.info.hash_algorithm);
1254		print_unsigned_int("Hashed data len", content->signature.info.v4_hashed_data_length);
1255
1256		print_indent();
1257		print_hexdump_data("hash2", &content->signature.hash2[0], 2);
1258
1259		switch (content->signature.info.key_algorithm) {
1260		case OPS_PKA_RSA:
1261		case OPS_PKA_RSA_SIGN_ONLY:
1262			print_bn("sig", content->signature.info.signature.rsa.sig);
1263			break;
1264
1265		case OPS_PKA_DSA:
1266			print_bn("r", content->signature.info.signature.dsa.r);
1267			print_bn("s", content->signature.info.signature.dsa.s);
1268			break;
1269
1270		case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1271			print_bn("r", content->signature.info.signature.elgamal.r);
1272			print_bn("s", content->signature.info.signature.elgamal.s);
1273			break;
1274
1275		default:
1276			assert(0);
1277		}
1278
1279		if (content->signature.hash)
1280			printf("data hash is set\n");
1281
1282		break;
1283
1284	case OPS_PTAG_CT_COMPRESSED:
1285		print_tagname("COMPRESSED");
1286		print_unsigned_int("Compressed Data Type", content->compressed.type);
1287		break;
1288
1289	case OPS_PTAG_CT_ONE_PASS_SIGNATURE:
1290		print_tagname("ONE PASS SIGNATURE");
1291
1292		print_unsigned_int("Version", content->one_pass_signature.version);
1293		print_string_and_value("Signature Type",
1294		    __ops_show_sig_type(content->one_pass_signature.sig_type),
1295				       content->one_pass_signature.sig_type);
1296		print_string_and_value("Hash Algorithm",
1297				       __ops_show_hash_algorithm(content->one_pass_signature.hash_algorithm),
1298				content->one_pass_signature.hash_algorithm);
1299		print_string_and_value("Public Key Algorithm",
1300		    __ops_show_pka(content->one_pass_signature.key_algorithm),
1301				 content->one_pass_signature.key_algorithm);
1302		print_hexdump_data("Signer ID",
1303				   content->one_pass_signature.keyid,
1304				   sizeof(content->one_pass_signature.keyid));
1305
1306		print_unsigned_int("Nested",
1307				   content->one_pass_signature.nested);
1308		break;
1309
1310	case OPS_PTAG_CT_USER_ATTRIBUTE:
1311		print_tagname("USER ATTRIBUTE");
1312		print_hexdump("User Attribute",
1313			      content->user_attribute.data.contents,
1314			      content->user_attribute.data.len);
1315		break;
1316
1317	case OPS_PTAG_RAW_SS:
1318		assert(!contents->critical);
1319		start_subpacket(contents->tag);
1320		print_unsigned_int("Raw Signature Subpacket: tag",
1321		   content->ss_raw.tag - OPS_PTAG_SIGNATURE_SUBPACKET_BASE);
1322		print_hexdump("Raw Data",
1323			      content->ss_raw.raw,
1324			      content->ss_raw.length);
1325		break;
1326
1327	case OPS_PTAG_SS_CREATION_TIME:
1328		start_subpacket(contents->tag);
1329		print_time("Signature Creation Time", content->ss_time.time);
1330		end_subpacket();
1331		break;
1332
1333	case OPS_PTAG_SS_EXPIRATION_TIME:
1334		start_subpacket(contents->tag);
1335		print_duration("Signature Expiration Time", content->ss_time.time);
1336		end_subpacket();
1337		break;
1338
1339	case OPS_PTAG_SS_KEY_EXPIRATION_TIME:
1340		start_subpacket(contents->tag);
1341		print_duration("Key Expiration Time", content->ss_time.time);
1342		end_subpacket();
1343		break;
1344
1345	case OPS_PTAG_SS_TRUST:
1346		start_subpacket(contents->tag);
1347		print_string("Trust Signature", "");
1348		print_unsigned_int("Level",
1349				   content->ss_trust.level);
1350		print_unsigned_int("Amount",
1351				   content->ss_trust.amount);
1352		end_subpacket();
1353		break;
1354
1355	case OPS_PTAG_SS_REVOCABLE:
1356		start_subpacket(contents->tag);
1357		print_boolean("Revocable", content->ss_revocable.revocable);
1358		end_subpacket();
1359		break;
1360
1361	case OPS_PTAG_SS_REVOCATION_KEY:
1362		start_subpacket(contents->tag);
1363		/* not yet tested */
1364		printf("  revocation key: class=0x%x",
1365		       content->ss_revocation_key.class);
1366		if (content->ss_revocation_key.class & 0x40)
1367			printf(" (sensitive)");
1368		printf(", algid=0x%x",
1369		       content->ss_revocation_key.algid);
1370		printf(", fingerprint=");
1371		hexdump(content->ss_revocation_key.fingerprint, 20, "");
1372		printf("\n");
1373		end_subpacket();
1374		break;
1375
1376	case OPS_PTAG_SS_ISSUER_KEY_ID:
1377		start_subpacket(contents->tag);
1378		print_hexdump("Issuer Key Id",
1379			      &content->ss_issuer_key_id.key_id[0],
1380			      sizeof(content->ss_issuer_key_id.key_id));
1381		end_subpacket();
1382		break;
1383
1384	case OPS_PTAG_SS_PREFERRED_SKA:
1385		start_subpacket(contents->tag);
1386		print_data("Preferred Symmetric Algorithms",
1387			   &content->ss_preferred_ska.data);
1388
1389		text = __ops_showall_ss_preferred_ska(content->ss_preferred_ska);
1390		print_text_breakdown(text);
1391		__ops_text_free(text);
1392
1393		end_subpacket();
1394		break;
1395
1396	case OPS_PTAG_SS_PRIMARY_USER_ID:
1397		start_subpacket(contents->tag);
1398		print_boolean("Primary User ID",
1399			      content->ss_primary_user_id.primary_user_id);
1400		end_subpacket();
1401		break;
1402
1403	case OPS_PTAG_SS_PREFERRED_HASH:
1404		start_subpacket(contents->tag);
1405		print_data("Preferred Hash Algorithms",
1406			   &content->ss_preferred_hash.data);
1407
1408		text = __ops_showall_ss_preferred_hash(content->ss_preferred_hash);
1409		print_text_breakdown(text);
1410		__ops_text_free(text);
1411		end_subpacket();
1412		break;
1413
1414	case OPS_PTAG_SS_PREFERRED_COMPRESSION:
1415		start_subpacket(contents->tag);
1416		print_data("Preferred Compression Algorithms",
1417			   &content->ss_preferred_compression.data);
1418
1419		text = __ops_showall_ss_preferred_compression(content->ss_preferred_compression);
1420		print_text_breakdown(text);
1421		__ops_text_free(text);
1422		end_subpacket();
1423		break;
1424
1425	case OPS_PTAG_SS_KEY_FLAGS:
1426		start_subpacket(contents->tag);
1427		print_data("Key Flags", &content->ss_key_flags.data);
1428
1429		text = __ops_showall_ss_key_flags(content->ss_key_flags);
1430		print_text_breakdown(text);
1431		__ops_text_free(text);
1432
1433		end_subpacket();
1434		break;
1435
1436	case OPS_PTAG_SS_KEY_SERVER_PREFS:
1437		start_subpacket(contents->tag);
1438		print_data("Key Server Preferences",
1439			   &content->ss_key_server_prefs.data);
1440
1441		text = __ops_showall_ss_key_server_prefs(content->ss_key_server_prefs);
1442		print_text_breakdown(text);
1443		__ops_text_free(text);
1444
1445		end_subpacket();
1446		break;
1447
1448	case OPS_PTAG_SS_FEATURES:
1449		start_subpacket(contents->tag);
1450		print_data("Features",
1451			   &content->ss_features.data);
1452
1453		text = __ops_showall_ss_features(content->ss_features);
1454		print_text_breakdown(text);
1455		__ops_text_free(text);
1456
1457		end_subpacket();
1458		break;
1459
1460	case OPS_PTAG_SS_NOTATION_DATA:
1461		start_subpacket(contents->tag);
1462		print_indent();
1463		printf("Notation Data:\n");
1464
1465		indent++;
1466		print_data("Flags",
1467			   &content->ss_notation_data.flags);
1468		text = __ops_showall_ss_notation_data_flags(content->ss_notation_data);
1469		print_text_breakdown(text);
1470		__ops_text_free(text);
1471
1472		/* xxx - TODO: print out UTF - rachel */
1473
1474		print_data("Name",
1475			   &content->ss_notation_data.name);
1476
1477		print_data("Value",
1478			   &content->ss_notation_data.value);
1479
1480		indent--;
1481		end_subpacket();
1482		break;
1483
1484	case OPS_PTAG_SS_REGEXP:
1485		start_subpacket(contents->tag);
1486		print_hexdump("Regular Expression",
1487			      (unsigned char *) content->ss_regexp.text,
1488			      strlen(content->ss_regexp.text));
1489		print_string(NULL,
1490			     content->ss_regexp.text);
1491		end_subpacket();
1492		break;
1493
1494	case OPS_PTAG_SS_POLICY_URL:
1495		start_subpacket(contents->tag);
1496		print_string("Policy URL",
1497			     content->ss_policy_url.text);
1498		end_subpacket();
1499		break;
1500
1501	case OPS_PTAG_SS_SIGNERS_USER_ID:
1502		start_subpacket(contents->tag);
1503		print_utf8_string("Signer's User ID", content->ss_signers_user_id.user_id);
1504		end_subpacket();
1505		break;
1506
1507	case OPS_PTAG_SS_PREFERRED_KEY_SERVER:
1508		start_subpacket(contents->tag);
1509		print_string("Preferred Key Server",
1510			     content->ss_preferred_key_server.text);
1511		end_subpacket();
1512		break;
1513
1514	case OPS_PTAG_SS_USERDEFINED00:
1515	case OPS_PTAG_SS_USERDEFINED01:
1516	case OPS_PTAG_SS_USERDEFINED02:
1517	case OPS_PTAG_SS_USERDEFINED03:
1518	case OPS_PTAG_SS_USERDEFINED04:
1519	case OPS_PTAG_SS_USERDEFINED05:
1520	case OPS_PTAG_SS_USERDEFINED06:
1521	case OPS_PTAG_SS_USERDEFINED07:
1522	case OPS_PTAG_SS_USERDEFINED08:
1523	case OPS_PTAG_SS_USERDEFINED09:
1524	case OPS_PTAG_SS_USERDEFINED10:
1525		start_subpacket(contents->tag);
1526		print_hexdump("Internal or user-defined",
1527			      content->ss_userdefined.data.contents,
1528			      content->ss_userdefined.data.len);
1529		end_subpacket();
1530		break;
1531
1532	case OPS_PTAG_SS_RESERVED:
1533		start_subpacket(contents->tag);
1534		print_hexdump("Reserved",
1535			      content->ss_userdefined.data.contents,
1536			      content->ss_userdefined.data.len);
1537		end_subpacket();
1538		break;
1539
1540	case OPS_PTAG_SS_REVOCATION_REASON:
1541		start_subpacket(contents->tag);
1542		print_hexdump("Revocation Reason",
1543			      &content->ss_revocation_reason.code,
1544			      1);
1545		str = __ops_show_ss_rr_code(content->ss_revocation_reason.code);
1546		print_string(NULL, str);
1547		/* xxx - todo : output text as UTF-8 string */
1548		end_subpacket();
1549		break;
1550
1551	case OPS_PTAG_CT_LITERAL_DATA_HEADER:
1552		print_tagname("LITERAL DATA HEADER");
1553		printf("  literal data header format=%c filename='%s'\n",
1554		       content->literal_data_header.format,
1555		       content->literal_data_header.filename);
1556		print_time("    modification time",
1557			   content->literal_data_header.modification_time);
1558		printf("\n");
1559		break;
1560
1561	case OPS_PTAG_CT_LITERAL_DATA_BODY:
1562		print_tagname("LITERAL DATA BODY");
1563		printf("  literal data body length=%d\n",
1564		       content->literal_data_body.length);
1565		printf("    data=");
1566		print_escaped(content->literal_data_body.data,
1567			      content->literal_data_body.length);
1568		printf("\n");
1569		break;
1570
1571	case OPS_PTAG_CT_SIGNATURE_HEADER:
1572		print_tagname("SIGNATURE");
1573		print_indent();
1574		print_unsigned_int("Signature Version",
1575				   content->signature.info.version);
1576		if (content->signature.info.creation_time_set)
1577			print_time("Signature Creation Time", content->signature.info.creation_time);
1578
1579		print_string_and_value("Signature Type",
1580			    __ops_show_sig_type(content->signature.info.type),
1581				       content->signature.info.type);
1582
1583		if (content->signature.info.signer_id_set)
1584			print_hexdump_data("Signer ID",
1585					   content->signature.info.signer_id,
1586				  sizeof(content->signature.info.signer_id));
1587
1588		print_string_and_value("Public Key Algorithm",
1589			__ops_show_pka(content->signature.info.key_algorithm),
1590				     content->signature.info.key_algorithm);
1591		print_string_and_value("Hash Algorithm",
1592				       __ops_show_hash_algorithm(content->signature.info.hash_algorithm),
1593				    content->signature.info.hash_algorithm);
1594
1595		break;
1596
1597	case OPS_PTAG_CT_SIGNATURE_FOOTER:
1598		print_indent();
1599		print_hexdump_data("hash2", &content->signature.hash2[0], 2);
1600
1601		switch (content->signature.info.key_algorithm) {
1602		case OPS_PKA_RSA:
1603			print_bn("sig", content->signature.info.signature.rsa.sig);
1604			break;
1605
1606		case OPS_PKA_DSA:
1607			print_bn("r", content->signature.info.signature.dsa.r);
1608			print_bn("s", content->signature.info.signature.dsa.s);
1609			break;
1610
1611		case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN:
1612			print_bn("r", content->signature.info.signature.elgamal.r);
1613			print_bn("s", content->signature.info.signature.elgamal.s);
1614			break;
1615
1616		case OPS_PKA_PRIVATE00:
1617		case OPS_PKA_PRIVATE01:
1618		case OPS_PKA_PRIVATE02:
1619		case OPS_PKA_PRIVATE03:
1620		case OPS_PKA_PRIVATE04:
1621		case OPS_PKA_PRIVATE05:
1622		case OPS_PKA_PRIVATE06:
1623		case OPS_PKA_PRIVATE07:
1624		case OPS_PKA_PRIVATE08:
1625		case OPS_PKA_PRIVATE09:
1626		case OPS_PKA_PRIVATE10:
1627			print_data("Private/Experimental",
1628			   &content->signature.info.signature.unknown.data);
1629			break;
1630
1631		default:
1632			assert(0);
1633		}
1634		break;
1635
1636	case OPS_PARSER_CMD_GET_SK_PASSPHRASE:
1637		if (cbinfo->cryptinfo.cb_get_passphrase) {
1638			return cbinfo->cryptinfo.cb_get_passphrase(contents, cbinfo);
1639		}
1640		break;
1641
1642	case OPS_PTAG_CT_SECRET_KEY:
1643	case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY:
1644		__ops_print_secret_key_verbose(contents->tag, &content->secret_key);
1645		break;
1646
1647	case OPS_PTAG_CT_ARMOUR_HEADER:
1648		print_tagname("ARMOUR HEADER");
1649		print_string("type", content->armour_header.type);
1650		break;
1651
1652	case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER:
1653		print_tagname("SIGNED CLEARTEXT HEADER");
1654		print_headers(&content->signed_cleartext_header.headers);
1655		break;
1656
1657	case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY:
1658		print_tagname("SIGNED CLEARTEXT BODY");
1659		print_block("signed cleartext", content->signed_cleartext_body.data,
1660			    content->signed_cleartext_body.length);
1661		break;
1662
1663	case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER:
1664		print_tagname("SIGNED CLEARTEXT TRAILER");
1665		printf("hash algorithm: %d\n",
1666		       content->signed_cleartext_trailer.hash->algorithm);
1667		printf("\n");
1668		break;
1669
1670	case OPS_PTAG_CT_UNARMOURED_TEXT:
1671		if (!unarmoured) {
1672			print_tagname("UNARMOURED TEXT");
1673			unarmoured = true;
1674		}
1675		putchar('[');
1676		print_escaped(content->unarmoured_text.data,
1677			      content->unarmoured_text.length);
1678		putchar(']');
1679		break;
1680
1681	case OPS_PTAG_CT_ARMOUR_TRAILER:
1682		print_tagname("ARMOUR TRAILER");
1683		print_string("type", content->armour_header.type);
1684		break;
1685
1686	case OPS_PTAG_CT_PK_SESSION_KEY:
1687	case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY:
1688		__ops_print_pk_session_key(contents->tag, &content->pk_session_key);
1689		break;
1690
1691	case OPS_PARSER_CMD_GET_SECRET_KEY:
1692		__ops_print_pk_session_key(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY,
1693				    content->get_secret_key.pk_session_key);
1694		return get_secret_key_cb(contents, cbinfo);
1695
1696	default:
1697		print_tagname("UNKNOWN PACKET TYPE");
1698		fprintf(stderr, "packet-dump: unknown tag=%d (0x%x)\n", contents->tag,
1699			contents->tag);
1700		exit(1);
1701	}
1702#endif				/* XXX */
1703	return OPS_RELEASE_MEMORY;
1704}
1705
1706/**
1707\ingroup Core_Print
1708\param filename
1709\param armour
1710\param keyring
1711\param cb_get_passphrase
1712*/
1713void
1714__ops_list_packets(char *filename, bool armour, __ops_keyring_t * keyring, __ops_parse_cb_t * cb_get_passphrase)
1715{
1716	int             fd = 0;
1717	__ops_parse_info_t *pinfo = NULL;
1718	const bool accumulate = true;
1719
1720	fd = __ops_setup_file_read(&pinfo, filename, NULL, cb_list_packets, accumulate);
1721	__ops_parse_options(pinfo, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED);
1722	pinfo->cryptinfo.keyring = keyring;
1723	pinfo->cryptinfo.cb_get_passphrase = cb_get_passphrase;
1724
1725	if (armour)
1726		__ops_reader_push_dearmour(pinfo);
1727
1728	__ops_parse_and_print_errors(pinfo);
1729
1730	__ops_teardown_file_read(pinfo, fd);
1731}
1732