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 /** \file
51  *
52  * Creates printable text strings from packet contents
53  *
54  */
55 #include "config.h"
56 
57 #ifdef HAVE_SYS_CDEFS_H
58 #include <sys/cdefs.h>
59 #endif
60 
61 #if defined(__NetBSD__)
62 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved.");
63 __RCSID("$NetBSD: packet-show.c,v 1.23 2022/08/26 19:18:38 jhigh Exp $");
64 #endif
65 
66 #include <stdlib.h>
67 #include <string.h>
68 
69 #include "packet-show.h"
70 
71 #include "netpgpsdk.h"
72 #include "netpgpdefs.h"
73 
74 
75 /*
76  * Arrays of value->text maps
77  */
78 
79 static pgp_map_t packet_tag_map[] =
80 {
81 	{PGP_PTAG_CT_RESERVED, "Reserved"},
82 	{PGP_PTAG_CT_PK_SESSION_KEY, "Public-Key Encrypted Session Key"},
83 	{PGP_PTAG_CT_SIGNATURE, "Signature"},
84 	{PGP_PTAG_CT_SK_SESSION_KEY, "Symmetric-Key Encrypted Session Key"},
85 	{PGP_PTAG_CT_1_PASS_SIG, "One-Pass Signature"},
86 	{PGP_PTAG_CT_SECRET_KEY, "Secret Key"},
87 	{PGP_PTAG_CT_PUBLIC_KEY, "Public Key"},
88 	{PGP_PTAG_CT_SECRET_SUBKEY, "Secret Subkey"},
89 	{PGP_PTAG_CT_COMPRESSED, "Compressed Data"},
90 	{PGP_PTAG_CT_SE_DATA, "Symmetrically Encrypted Data"},
91 	{PGP_PTAG_CT_MARKER, "Marker"},
92 	{PGP_PTAG_CT_LITDATA, "Literal Data"},
93 	{PGP_PTAG_CT_TRUST, "Trust"},
94 	{PGP_PTAG_CT_USER_ID, "User ID"},
95 	{PGP_PTAG_CT_PUBLIC_SUBKEY, "Public Subkey"},
96 	{PGP_PTAG_CT_RESERVED2, "reserved2"},
97 	{PGP_PTAG_CT_RESERVED3, "reserved3"},
98 	{PGP_PTAG_CT_USER_ATTR, "User Attribute"},
99 	{PGP_PTAG_CT_SE_IP_DATA,
100 		"Symmetric Encrypted and Integrity Protected Data"},
101 	{PGP_PTAG_CT_MDC, "Modification Detection Code"},
102 	{PGP_PARSER_PTAG, "PGP_PARSER_PTAG"},
103 	{PGP_PTAG_RAW_SS, "PGP_PTAG_RAW_SS"},
104 	{PGP_PTAG_SS_ALL, "PGP_PTAG_SS_ALL"},
105 	{PGP_PARSER_PACKET_END, "PGP_PARSER_PACKET_END"},
106 	{PGP_PTAG_SIG_SUBPKT_BASE, "PGP_PTAG_SIG_SUBPKT_BASE"},
107 	{PGP_PTAG_SS_CREATION_TIME, "SS: Signature Creation Time"},
108 	{PGP_PTAG_SS_EXPIRATION_TIME, "SS: Signature Expiration Time"},
109 	{PGP_PTAG_SS_EXPORT_CERT, "SS: Exportable Certification"},
110 	{PGP_PTAG_SS_TRUST, "SS: Trust Signature"},
111 	{PGP_PTAG_SS_REGEXP, "SS: Regular Expression"},
112 	{PGP_PTAG_SS_REVOCABLE, "SS: Revocable"},
113 	{PGP_PTAG_SS_KEY_EXPIRY, "SS: Key Expiration Time"},
114 	{PGP_PTAG_SS_RESERVED, "SS: Reserved"},
115 	{PGP_PTAG_SS_PREFERRED_SKA, "SS: Preferred Secret Key Algorithm"},
116 	{PGP_PTAG_SS_REVOCATION_KEY, "SS: Revocation Key"},
117 	{PGP_PTAG_SS_ISSUER_KEY_ID, "SS: Issuer Key Id"},
118 	{PGP_PTAG_SS_ISSUER_FINGERPRINT, "SS: Issuer Fingerprint"},
119 	{PGP_PTAG_SS_NOTATION_DATA, "SS: Notation Data"},
120 	{PGP_PTAG_SS_PREFERRED_HASH, "SS: Preferred Hash Algorithm"},
121 	{PGP_PTAG_SS_PREF_COMPRESS, "SS: Preferred Compression Algorithm"},
122 	{PGP_PTAG_SS_KEYSERV_PREFS, "SS: Key Server Preferences"},
123 	{PGP_PTAG_SS_PREF_KEYSERV, "SS: Preferred Key Server"},
124 	{PGP_PTAG_SS_PRIMARY_USER_ID, "SS: Primary User ID"},
125 	{PGP_PTAG_SS_POLICY_URI, "SS: Policy URI"},
126 	{PGP_PTAG_SS_KEY_FLAGS, "SS: Key Flags"},
127 	{PGP_PTAG_SS_SIGNERS_USER_ID, "SS: Signer's User ID"},
128 	{PGP_PTAG_SS_REVOCATION_REASON, "SS: Reason for Revocation"},
129 	{PGP_PTAG_SS_FEATURES, "SS: Features"},
130 	{PGP_PTAG_SS_SIGNATURE_TARGET, "SS: Signature Target"},
131 	{PGP_PTAG_SS_EMBEDDED_SIGNATURE, "SS: Embedded Signature"},
132 
133 	{PGP_PTAG_CT_LITDATA_HEADER, "CT: Literal Data Header"},
134 	{PGP_PTAG_CT_LITDATA_BODY, "CT: Literal Data Body"},
135 	{PGP_PTAG_CT_SIGNATURE_HEADER, "CT: Signature Header"},
136 	{PGP_PTAG_CT_SIGNATURE_FOOTER, "CT: Signature Footer"},
137 	{PGP_PTAG_CT_ARMOUR_HEADER, "CT: Armour Header"},
138 	{PGP_PTAG_CT_ARMOUR_TRAILER, "CT: Armour Trailer"},
139 	{PGP_PTAG_CT_SIGNED_CLEARTEXT_HEADER, "CT: Signed Cleartext Header"},
140 	{PGP_PTAG_CT_SIGNED_CLEARTEXT_BODY, "CT: Signed Cleartext Body"},
141 	{PGP_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, "CT: Signed Cleartext Trailer"},
142 	{PGP_PTAG_CT_UNARMOURED_TEXT, "CT: Unarmoured Text"},
143 	{PGP_PTAG_CT_ENCRYPTED_SECRET_KEY, "CT: Encrypted Secret Key"},
144 	{PGP_PTAG_CT_SE_DATA_HEADER, "CT: Sym Encrypted Data Header"},
145 	{PGP_PTAG_CT_SE_DATA_BODY, "CT: Sym Encrypted Data Body"},
146 	{PGP_PTAG_CT_SE_IP_DATA_HEADER, "CT: Sym Encrypted IP Data Header"},
147 	{PGP_PTAG_CT_SE_IP_DATA_BODY, "CT: Sym Encrypted IP Data Body"},
148 	{PGP_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, "CT: Encrypted PK Session Key"},
149 	{PGP_GET_PASSPHRASE, "CMD: Get Secret Key Passphrase"},
150 	{PGP_GET_SECKEY, "CMD: Get Secret Key"},
151 	{PGP_PARSER_ERROR, "PGP_PARSER_ERROR"},
152 	{PGP_PARSER_ERRCODE, "PGP_PARSER_ERRCODE"},
153 
154 	{0x00, NULL},		/* this is the end-of-array marker */
155 };
156 
157 static pgp_map_t ss_type_map[] =
158 {
159 	{PGP_PTAG_SS_CREATION_TIME, "Signature Creation Time"},
160 	{PGP_PTAG_SS_EXPIRATION_TIME, "Signature Expiration Time"},
161 	{PGP_PTAG_SS_TRUST, "Trust Signature"},
162 	{PGP_PTAG_SS_REGEXP, "Regular Expression"},
163 	{PGP_PTAG_SS_REVOCABLE, "Revocable"},
164 	{PGP_PTAG_SS_KEY_EXPIRY, "Key Expiration Time"},
165 	{PGP_PTAG_SS_PREFERRED_SKA, "Preferred Symmetric Algorithms"},
166 	{PGP_PTAG_SS_REVOCATION_KEY, "Revocation Key"},
167 	{PGP_PTAG_SS_ISSUER_KEY_ID, "Issuer key ID"},
168 	{PGP_PTAG_SS_ISSUER_FINGERPRINT, "Issuer Fingerprint"},
169 	{PGP_PTAG_SS_NOTATION_DATA, "Notation Data"},
170 	{PGP_PTAG_SS_PREFERRED_HASH, "Preferred Hash Algorithms"},
171 	{PGP_PTAG_SS_PREF_COMPRESS, "Preferred Compression Algorithms"},
172 	{PGP_PTAG_SS_KEYSERV_PREFS, "Key Server Preferences"},
173 	{PGP_PTAG_SS_PREF_KEYSERV, "Preferred Key Server"},
174 	{PGP_PTAG_SS_PRIMARY_USER_ID, "Primary User ID"},
175 	{PGP_PTAG_SS_POLICY_URI, "Policy URI"},
176 	{PGP_PTAG_SS_KEY_FLAGS, "Key Flags"},
177 	{PGP_PTAG_SS_REVOCATION_REASON, "Reason for Revocation"},
178 	{PGP_PTAG_SS_FEATURES, "Features"},
179 	{0x00, NULL},		/* this is the end-of-array marker */
180 };
181 
182 
183 static pgp_map_t ss_rr_code_map[] =
184 {
185 	{0x00, "No reason specified"},
186 	{0x01, "Key is superseded"},
187 	{0x02, "Key material has been compromised"},
188 	{0x03, "Key is retired and no longer used"},
189 	{0x20, "User ID information is no longer valid"},
190 	{0x00, NULL},		/* this is the end-of-array marker */
191 };
192 
193 static pgp_map_t sig_type_map[] =
194 {
195 	{PGP_SIG_BINARY, "Signature of a binary document"},
196 	{PGP_SIG_TEXT, "Signature of a canonical text document"},
197 	{PGP_SIG_STANDALONE, "Standalone signature"},
198 	{PGP_CERT_GENERIC, "Generic certification of a User ID and Public Key packet"},
199 	{PGP_CERT_PERSONA, "Personal certification of a User ID and Public Key packet"},
200 	{PGP_CERT_CASUAL, "Casual certification of a User ID and Public Key packet"},
201 	{PGP_CERT_POSITIVE, "Positive certification of a User ID and Public Key packet"},
202 	{PGP_SIG_SUBKEY, "Subkey Binding Signature"},
203 	{PGP_SIG_PRIMARY, "Primary Key Binding Signature"},
204 	{PGP_SIG_DIRECT, "Signature directly on a key"},
205 	{PGP_SIG_REV_KEY, "Key revocation signature"},
206 	{PGP_SIG_REV_SUBKEY, "Subkey revocation signature"},
207 	{PGP_SIG_REV_CERT, "Certification revocation signature"},
208 	{PGP_SIG_TIMESTAMP, "Timestamp signature"},
209 	{PGP_SIG_3RD_PARTY, "Third-Party Confirmation signature"},
210 	{0x00, NULL},		/* this is the end-of-array marker */
211 };
212 
213 static pgp_map_t pubkey_alg_map[] =
214 {
215 	{PGP_PKA_RSA, "RSA (Encrypt or Sign)"},
216 	{PGP_PKA_RSA_ENCRYPT_ONLY, "RSA Encrypt-Only"},
217 	{PGP_PKA_RSA_SIGN_ONLY, "RSA Sign-Only"},
218 	{PGP_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"},
219 	{PGP_PKA_DSA, "DSA"},
220 	{PGP_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve"},
221 	{PGP_PKA_ECDSA, "ECDSA"},
222 	{PGP_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"},
223 	{PGP_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"},
224 	{PGP_PKA_PRIVATE00, "Private/Experimental"},
225 	{PGP_PKA_PRIVATE01, "Private/Experimental"},
226 	{PGP_PKA_PRIVATE02, "Private/Experimental"},
227 	{PGP_PKA_PRIVATE03, "Private/Experimental"},
228 	{PGP_PKA_PRIVATE04, "Private/Experimental"},
229 	{PGP_PKA_PRIVATE05, "Private/Experimental"},
230 	{PGP_PKA_PRIVATE06, "Private/Experimental"},
231 	{PGP_PKA_PRIVATE07, "Private/Experimental"},
232 	{PGP_PKA_PRIVATE08, "Private/Experimental"},
233 	{PGP_PKA_PRIVATE09, "Private/Experimental"},
234 	{PGP_PKA_PRIVATE10, "Private/Experimental"},
235 	{0x00, NULL},		/* this is the end-of-array marker */
236 };
237 
238 static pgp_map_t symm_alg_map[] =
239 {
240 	{PGP_SA_PLAINTEXT, "Plaintext or unencrypted data"},
241 	{PGP_SA_IDEA, "IDEA"},
242 	{PGP_SA_TRIPLEDES, "TripleDES"},
243 	{PGP_SA_CAST5, "CAST5"},
244 	{PGP_SA_BLOWFISH, "Blowfish"},
245 	{PGP_SA_AES_128, "AES (128-bit key)"},
246 	{PGP_SA_AES_192, "AES (192-bit key)"},
247 	{PGP_SA_AES_256, "AES (256-bit key)"},
248 	{PGP_SA_TWOFISH, "Twofish(256-bit key)"},
249 	{PGP_SA_CAMELLIA_128, "Camellia (128-bit key)"},
250 	{PGP_SA_CAMELLIA_192, "Camellia (192-bit key)"},
251 	{PGP_SA_CAMELLIA_256, "Camellia (256-bit key)"},
252 	{0x00, NULL},		/* this is the end-of-array marker */
253 };
254 
255 static pgp_map_t hash_alg_map[] =
256 {
257 	{PGP_HASH_MD5, "MD5"},
258 	{PGP_HASH_SHA1, "SHA1"},
259 	{PGP_HASH_RIPEMD, "RIPEMD160"},
260 	{PGP_HASH_SHA256, "SHA256"},
261 	{PGP_HASH_SHA384, "SHA384"},
262 	{PGP_HASH_SHA512, "SHA512"},
263 	{PGP_HASH_SHA224, "SHA224"},
264 	{0x00, NULL},		/* this is the end-of-array marker */
265 };
266 
267 static pgp_map_t compression_alg_map[] =
268 {
269 	{PGP_C_NONE, "Uncompressed"},
270 	{PGP_C_ZIP, "ZIP(RFC1951)"},
271 	{PGP_C_ZLIB, "ZLIB(RFC1950)"},
272 	{PGP_C_BZIP2, "Bzip2(BZ2)"},
273 	{0x00, NULL},		/* this is the end-of-array marker */
274 };
275 
276 static pgp_bit_map_t ss_notation_map_byte0[] =
277 {
278 	{0x80, "Human-readable"},
279 	{0x00, NULL},
280 };
281 
282 static pgp_bit_map_t *ss_notation_map[] =
283 {
284 	ss_notation_map_byte0,
285 };
286 
287 static pgp_bit_map_t ss_feature_map_byte0[] =
288 {
289 	{0x01, "Modification Detection"},
290 	{0x00, NULL},
291 };
292 
293 static pgp_bit_map_t *ss_feature_map[] =
294 {
295 	ss_feature_map_byte0,
296 };
297 
298 static pgp_bit_map_t ss_key_flags_map[] =
299 {
300 	{0x01, "May be used to certify other keys"},
301 	{0x02, "May be used to sign data"},
302 	{0x04, "May be used to encrypt communications"},
303 	{0x08, "May be used to encrypt storage"},
304 	{0x10, "Private component may have been split by a secret-sharing mechanism"},
305 	{0x80, "Private component may be in possession of more than one person"},
306 	{0x00, NULL},
307 };
308 
309 static pgp_bit_map_t ss_key_server_prefs_map[] =
310 {
311 	{0x80, "Key holder requests that this key only be modified or updated by the key holder or an administrator of the key server"},
312 	{0x00, NULL},
313 };
314 
315 /*
316  * Private functions
317  */
318 
319 static void
list_init(pgp_list_t * list)320 list_init(pgp_list_t *list)
321 {
322 	list->size = 0;
323 	list->used = 0;
324 	list->strings = NULL;
325 }
326 
327 static void
list_free_strings(pgp_list_t * list)328 list_free_strings(pgp_list_t *list)
329 {
330 	unsigned        i;
331 
332 	for (i = 0; i < list->used; i++) {
333 		free(list->strings[i]);
334 		list->strings[i] = NULL;
335 	}
336 }
337 
338 static void
list_free(pgp_list_t * list)339 list_free(pgp_list_t *list)
340 {
341 	if (list->strings)
342 		free(list->strings);
343 	list_init(list);
344 }
345 
346 static unsigned
list_resize(pgp_list_t * list)347 list_resize(pgp_list_t *list)
348 {
349 	/*
350 	 * We only resize in one direction - upwards. Algorithm used : double
351 	 * the current size then add 1
352 	 */
353 	char	**newstrings;
354 	int	  newsize;
355 
356 	newsize = (list->size * 2) + 1;
357 	newstrings = realloc(list->strings, newsize * sizeof(char *));
358 	if (newstrings) {
359 		list->strings = newstrings;
360 		list->size = newsize;
361 		return 1;
362 	}
363 	(void) fprintf(stderr, "list_resize - bad alloc\n");
364 	return 0;
365 }
366 
367 static unsigned
add_str(pgp_list_t * list,const char * str)368 add_str(pgp_list_t *list, const char *str)
369 {
370 	if (list->size == list->used && !list_resize(list)) {
371 		return 0;
372 	}
373 	list->strings[list->used++] = __UNCONST(str);
374 	return 1;
375 }
376 
377 /* find a bitfield in a map - serial search */
378 static const char *
find_bitfield(pgp_bit_map_t * map,uint8_t octet)379 find_bitfield(pgp_bit_map_t *map, uint8_t octet)
380 {
381 	pgp_bit_map_t  *row;
382 
383 	for (row = map; row->string != NULL && row->mask != octet ; row++) {
384 	}
385 	return (row->string) ? row->string : "Unknown";
386 }
387 
388 /* ! generic function to initialise pgp_text_t structure */
389 void
pgp_text_init(pgp_text_t * text)390 pgp_text_init(pgp_text_t *text)
391 {
392 	list_init(&text->known);
393 	list_init(&text->unknown);
394 }
395 
396 /**
397  * \ingroup Core_Print
398  *
399  * pgp_text_free() frees the memory used by an pgp_text_t structure
400  *
401  * \param text Pointer to a previously allocated structure. This structure and its contents will be freed.
402  */
403 void
pgp_text_free(pgp_text_t * text)404 pgp_text_free(pgp_text_t *text)
405 {
406 	/* Strings in "known" array will be constants, so don't free them */
407 	list_free(&text->known);
408 
409 	/*
410 	 * Strings in "unknown" array will be dynamically allocated, so do
411 	 * free them
412 	 */
413 	list_free_strings(&text->unknown);
414 	list_free(&text->unknown);
415 
416 	free(text);
417 }
418 
419 /* XXX: should this (and many others) be unsigned? */
420 /* ! generic function which adds text derived from single octet map to text */
421 static unsigned
add_str_from_octet_map(pgp_text_t * map,char * str,uint8_t octet)422 add_str_from_octet_map(pgp_text_t *map, char *str, uint8_t octet)
423 {
424 	if (str && !add_str(&map->known, str)) {
425 		/*
426 		 * value recognised, but there was a problem adding it to the
427 		 * list
428 		 */
429 		/* XXX - should print out error msg here, Ben? - rachel */
430 		return 0;
431 	} else if (!str) {
432 		/*
433 		 * value not recognised and there was a problem adding it to
434 		 * the unknown list
435 		 */
436 		unsigned        len = 2 + 2 + 1;	/* 2 for "0x", 2 for
437 							 * single octet in hex
438 							 * format, 1 for NUL */
439 		if ((str = calloc(1, len)) == NULL) {
440 			(void) fprintf(stderr, "add_str_from_octet_map: bad alloc\n");
441 			return 0;
442 		}
443 		(void) snprintf(str, len, "0x%x", octet);
444 		if (!add_str(&map->unknown, str)) {
445 			return 0;
446 		}
447 		free(str);
448 	}
449 	return 1;
450 }
451 
452 /* ! generic function which adds text derived from single bit map to text */
453 static unsigned
add_bitmap_entry(pgp_text_t * map,const char * str,uint8_t bit)454 add_bitmap_entry(pgp_text_t *map, const char *str, uint8_t bit)
455 {
456 
457 	if (str && !add_str(&map->known, str)) {
458 		/*
459 		 * value recognised, but there was a problem adding it to the
460 		 * list
461 		 */
462 		/* XXX - should print out error msg here, Ben? - rachel */
463 		return 0;
464 	} else if (!str) {
465 		/*
466 		 * value not recognised and there was a problem adding it to
467 		 * the unknown list
468 		 * 2 chars of the string are the format definition, this will
469 		 * be replaced in the output by 2 chars of hex, so the length
470 		 * will be correct
471 		 */
472 		char		*newstr;
473 		if (asprintf(&newstr, "Unknown bit(0x%x)", bit) == -1) {
474 			(void) fprintf(stderr, "add_bitmap_entry: bad alloc\n");
475 			return 0;
476 		}
477 		if (!add_str(&map->unknown, newstr)) {
478 			return 0;
479 		}
480 		free(newstr);
481 	}
482 	return 1;
483 }
484 
485 /**
486  * Produce a structure containing human-readable textstrings
487  * representing the recognised and unrecognised contents
488  * of this byte array. text_fn() will be called on each octet in turn.
489  * Each octet will generate one string representing the whole byte.
490  *
491  */
492 
493 static pgp_text_t *
text_from_bytemapped_octets(const pgp_data_t * data,const char * (* text_fn)(uint8_t octet))494 text_from_bytemapped_octets(const pgp_data_t *data,
495 			    const char *(*text_fn)(uint8_t octet))
496 {
497 	pgp_text_t	*text;
498 	const char	*str;
499 	unsigned	 i;
500 
501 	/*
502 	 * ! allocate and initialise pgp_text_t structure to store derived
503 	 * strings
504 	 */
505 	if ((text = calloc(1, sizeof(*text))) == NULL) {
506 		return NULL;
507 	}
508 
509 	pgp_text_init(text);
510 
511 	/* ! for each octet in field ... */
512 	for (i = 0; i < data->len; i++) {
513 		/* ! derive string from octet */
514 		str = (*text_fn) (data->contents[i]);
515 
516 		/* ! and add to text */
517 		if (!add_str_from_octet_map(text, netpgp_strdup(str),
518 						data->contents[i])) {
519 			pgp_text_free(text);
520 			return NULL;
521 		}
522 	}
523 	/*
524 	 * ! All values have been added to either the known or the unknown
525 	 * list
526 	 */
527 	return text;
528 }
529 
530 /**
531  * Produce a structure containing human-readable textstrings
532  * representing the recognised and unrecognised contents
533  * of this byte array, derived from each bit of each octet.
534  *
535  */
536 static pgp_text_t *
showall_octets_bits(pgp_data_t * data,pgp_bit_map_t ** map,size_t nmap)537 showall_octets_bits(pgp_data_t *data, pgp_bit_map_t **map, size_t nmap)
538 {
539 	pgp_text_t	*text;
540 	const char	*str;
541 	unsigned         i;
542 	uint8_t		 mask, bit;
543 	int              j = 0;
544 
545 	/*
546 	 * ! allocate and initialise pgp_text_t structure to store derived
547 	 * strings
548 	 */
549 	if ((text = calloc(1, sizeof(pgp_text_t))) == NULL) {
550 		return NULL;
551 	}
552 
553 	pgp_text_init(text);
554 
555 	/* ! for each octet in field ... */
556 	for (i = 0; i < data->len; i++) {
557 		/* ! for each bit in octet ... */
558 		mask = 0x80;
559 		for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
560 			bit = data->contents[i] & mask;
561 			if (bit) {
562 				str = (i >= nmap) ? "Unknown" :
563 					find_bitfield(map[i], bit);
564 				if (!add_bitmap_entry(text, str, bit)) {
565 					pgp_text_free(text);
566 					return NULL;
567 				}
568 			}
569 		}
570 	}
571 	return text;
572 }
573 
574 /*
575  * Public Functions
576  */
577 
578 /**
579  * \ingroup Core_Print
580  * returns description of the Packet Tag
581  * \param packet_tag
582  * \return string or "Unknown"
583 */
584 const char     *
pgp_show_packet_tag(pgp_content_enum packet_tag)585 pgp_show_packet_tag(pgp_content_enum packet_tag)
586 {
587 	const char     *ret;
588 
589 	ret = pgp_str_from_map(packet_tag, packet_tag_map);
590 	if (!ret) {
591 		ret = "Unknown Tag";
592 	}
593 	return ret;
594 }
595 
596 /**
597  * \ingroup Core_Print
598  *
599  * returns description of the Signature Sub-Packet type
600  * \param ss_type Signature Sub-Packet type
601  * \return string or "Unknown"
602  */
603 const char     *
pgp_show_ss_type(pgp_content_enum ss_type)604 pgp_show_ss_type(pgp_content_enum ss_type)
605 {
606 	return pgp_str_from_map(ss_type, ss_type_map);
607 }
608 
609 /**
610  * \ingroup Core_Print
611  *
612  * returns description of the Revocation Reason code
613  * \param ss_rr_code Revocation Reason code
614  * \return string or "Unknown"
615  */
616 const char     *
pgp_show_ss_rr_code(pgp_ss_rr_code_t ss_rr_code)617 pgp_show_ss_rr_code(pgp_ss_rr_code_t ss_rr_code)
618 {
619 	return pgp_str_from_map(ss_rr_code, ss_rr_code_map);
620 }
621 
622 /**
623  * \ingroup Core_Print
624  *
625  * returns description of the given Signature type
626  * \param sig_type Signature type
627  * \return string or "Unknown"
628  */
629 const char     *
pgp_show_sig_type(pgp_sig_type_t sig_type)630 pgp_show_sig_type(pgp_sig_type_t sig_type)
631 {
632 	return pgp_str_from_map(sig_type, sig_type_map);
633 }
634 
635 /**
636  * \ingroup Core_Print
637  *
638  * returns description of the given Public Key Algorithm
639  * \param pka Public Key Algorithm type
640  * \return string or "Unknown"
641  */
642 const char     *
pgp_show_pka(pgp_pubkey_alg_t pka)643 pgp_show_pka(pgp_pubkey_alg_t pka)
644 {
645 	return pgp_str_from_map(pka, pubkey_alg_map);
646 }
647 
648 /**
649  * \ingroup Core_Print
650  * returns description of the Preferred Compression
651  * \param octet Preferred Compression
652  * \return string or "Unknown"
653 */
654 const char     *
pgp_show_ss_zpref(uint8_t octet)655 pgp_show_ss_zpref(uint8_t octet)
656 {
657 	return pgp_str_from_map(octet, compression_alg_map);
658 }
659 
660 /**
661  * \ingroup Core_Print
662  *
663  * returns set of descriptions of the given Preferred Compression Algorithms
664  * \param ss_zpref Array of Preferred Compression Algorithms
665  * \return NULL if cannot allocate memory or other error
666  * \return pointer to structure, if no error
667  */
668 pgp_text_t     *
pgp_showall_ss_zpref(const pgp_data_t * ss_zpref)669 pgp_showall_ss_zpref(const pgp_data_t *ss_zpref)
670 {
671 	return text_from_bytemapped_octets(ss_zpref,
672 					&pgp_show_ss_zpref);
673 }
674 
675 
676 /**
677  * \ingroup Core_Print
678  *
679  * returns description of the Hash Algorithm type
680  * \param hash Hash Algorithm type
681  * \return string or "Unknown"
682  */
683 const char     *
pgp_show_hash_alg(uint8_t hash)684 pgp_show_hash_alg(uint8_t hash)
685 {
686 	return pgp_str_from_map(hash, hash_alg_map);
687 }
688 
689 /**
690  * \ingroup Core_Print
691  *
692  * returns set of descriptions of the given Preferred Hash Algorithms
693  * \param ss_hashpref Array of Preferred Hash Algorithms
694  * \return NULL if cannot allocate memory or other error
695  * \return pointer to structure, if no error
696  */
697 pgp_text_t     *
pgp_showall_ss_hashpref(const pgp_data_t * ss_hashpref)698 pgp_showall_ss_hashpref(const pgp_data_t *ss_hashpref)
699 {
700 	return text_from_bytemapped_octets(ss_hashpref,
701 					   &pgp_show_hash_alg);
702 }
703 
704 const char     *
pgp_show_symm_alg(uint8_t hash)705 pgp_show_symm_alg(uint8_t hash)
706 {
707 	return pgp_str_from_map(hash, symm_alg_map);
708 }
709 
710 /**
711  * \ingroup Core_Print
712  * returns description of the given Preferred Symmetric Key Algorithm
713  * \param octet
714  * \return string or "Unknown"
715 */
716 const char     *
pgp_show_ss_skapref(uint8_t octet)717 pgp_show_ss_skapref(uint8_t octet)
718 {
719 	return pgp_str_from_map(octet, symm_alg_map);
720 }
721 
722 /**
723  * \ingroup Core_Print
724  *
725  * returns set of descriptions of the given Preferred Symmetric Key Algorithms
726  * \param ss_skapref Array of Preferred Symmetric Key Algorithms
727  * \return NULL if cannot allocate memory or other error
728  * \return pointer to structure, if no error
729  */
730 pgp_text_t     *
pgp_showall_ss_skapref(const pgp_data_t * ss_skapref)731 pgp_showall_ss_skapref(const pgp_data_t *ss_skapref)
732 {
733 	return text_from_bytemapped_octets(ss_skapref,
734 					   &pgp_show_ss_skapref);
735 }
736 
737 /**
738  * \ingroup Core_Print
739  * returns description of one SS Feature
740  * \param octet
741  * \return string or "Unknown"
742 */
743 static const char *
show_ss_feature(uint8_t octet,unsigned offset)744 show_ss_feature(uint8_t octet, unsigned offset)
745 {
746 	if (offset >= PGP_ARRAY_SIZE(ss_feature_map)) {
747 		return "Unknown";
748 	}
749 	return find_bitfield(ss_feature_map[offset], octet);
750 }
751 
752 /**
753  * \ingroup Core_Print
754  *
755  * returns set of descriptions of the given SS Features
756  * \param ss_features Signature Sub-Packet Features
757  * \return NULL if cannot allocate memory or other error
758  * \return pointer to structure, if no error
759  */
760 /* XXX: shouldn't this use show_all_octets_bits? */
761 pgp_text_t     *
pgp_showall_ss_features(pgp_data_t ss_features)762 pgp_showall_ss_features(pgp_data_t ss_features)
763 {
764 	pgp_text_t	*text;
765 	const char	*str;
766 	unsigned	 i;
767 	uint8_t		 mask, bit;
768 	int		 j;
769 
770 	if ((text = calloc(1, sizeof(*text))) == NULL) {
771 		return NULL;
772 	}
773 
774 	pgp_text_init(text);
775 
776 	for (i = 0; i < ss_features.len; i++) {
777 		mask = 0x80;
778 		for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) {
779 			bit = ss_features.contents[i] & mask;
780 			if (bit) {
781 				str = show_ss_feature(bit, i);
782 				if (!add_bitmap_entry(text, str, bit)) {
783 					pgp_text_free(text);
784 					return NULL;
785 				}
786 			}
787 		}
788 	}
789 	return text;
790 }
791 
792 /**
793  * \ingroup Core_Print
794  * returns description of SS Key Flag
795  * \param octet
796  * \param map
797  * \return
798 */
799 const char     *
pgp_show_ss_key_flag(uint8_t octet,pgp_bit_map_t * map)800 pgp_show_ss_key_flag(uint8_t octet, pgp_bit_map_t *map)
801 {
802 	return find_bitfield(map, octet);
803 }
804 
805 /**
806  * \ingroup Core_Print
807  *
808  * returns set of descriptions of the given Preferred Key Flags
809  * \param ss_key_flags Array of Key Flags
810  * \return NULL if cannot allocate memory or other error
811  * \return pointer to structure, if no error
812  */
813 pgp_text_t     *
pgp_showall_ss_key_flags(const pgp_data_t * ss_key_flags)814 pgp_showall_ss_key_flags(const pgp_data_t *ss_key_flags)
815 {
816 	pgp_text_t	*text;
817 	const char	*str;
818 	uint8_t		 mask, bit;
819 	int              i;
820 
821 	if ((text = calloc(1, sizeof(*text))) == NULL) {
822 		return NULL;
823 	}
824 
825 	pgp_text_init(text);
826 
827 	/* xxx - TBD: extend to handle multiple octets of bits - rachel */
828 	for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
829 		bit = ss_key_flags->contents[0] & mask;
830 		if (bit) {
831 			str = pgp_show_ss_key_flag(bit, ss_key_flags_map);
832 			if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
833 				pgp_text_free(text);
834 				return NULL;
835 			}
836 		}
837 	}
838 	/*
839 	 * xxx - must add error text if more than one octet. Only one
840 	 * currently specified -- rachel
841 	 */
842 	return text;
843 }
844 
845 /**
846  * \ingroup Core_Print
847  *
848  * returns description of one given Key Server Preference
849  *
850  * \param prefs Byte containing bitfield of preferences
851  * \param map
852  * \return string or "Unknown"
853  */
854 const char     *
pgp_show_keyserv_pref(uint8_t prefs,pgp_bit_map_t * map)855 pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map)
856 {
857 	return find_bitfield(map, prefs);
858 }
859 
860 /**
861  * \ingroup Core_Print
862  * returns set of descriptions of given Key Server Preferences
863  * \param ss_key_server_prefs
864  * \return NULL if cannot allocate memory or other error
865  * \return pointer to structure, if no error
866  *
867 */
868 pgp_text_t     *
pgp_show_keyserv_prefs(const pgp_data_t * prefs)869 pgp_show_keyserv_prefs(const pgp_data_t *prefs)
870 {
871 	pgp_text_t	*text;
872 	const char	*str;
873 	uint8_t		 mask, bit;
874 	int              i = 0;
875 
876 	if ((text = calloc(1, sizeof(*text))) == NULL) {
877 		return NULL;
878 	}
879 
880 	pgp_text_init(text);
881 
882 	/* xxx - TBD: extend to handle multiple octets of bits - rachel */
883 
884 	for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) {
885 		bit = prefs->contents[0] & mask;
886 		if (bit) {
887 			str = pgp_show_keyserv_pref(bit,
888 						ss_key_server_prefs_map);
889 			if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) {
890 				pgp_text_free(text);
891 				return NULL;
892 			}
893 		}
894 	}
895 	/*
896 	 * xxx - must add error text if more than one octet. Only one
897 	 * currently specified -- rachel
898 	 */
899 	return text;
900 }
901 
902 /**
903  * \ingroup Core_Print
904  *
905  * returns set of descriptions of the given SS Notation Data Flags
906  * \param ss_notation Signature Sub-Packet Notation Data
907  * \return NULL if cannot allocate memory or other error
908  * \return pointer to structure, if no error
909  */
910 pgp_text_t     *
pgp_showall_notation(pgp_ss_notation_t ss_notation)911 pgp_showall_notation(pgp_ss_notation_t ss_notation)
912 {
913 	return showall_octets_bits(&ss_notation.flags,
914 				ss_notation_map,
915 				PGP_ARRAY_SIZE(ss_notation_map));
916 }
917