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
79static 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
157static 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
183static 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
193static 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
213static 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
238static 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
255static 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
267static 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
276static pgp_bit_map_t ss_notation_map_byte0[] =
277{
278	{0x80, "Human-readable"},
279	{0x00, NULL},
280};
281
282static pgp_bit_map_t *ss_notation_map[] =
283{
284	ss_notation_map_byte0,
285};
286
287static pgp_bit_map_t ss_feature_map_byte0[] =
288{
289	{0x01, "Modification Detection"},
290	{0x00, NULL},
291};
292
293static pgp_bit_map_t *ss_feature_map[] =
294{
295	ss_feature_map_byte0,
296};
297
298static 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
309static 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
319static void
320list_init(pgp_list_t *list)
321{
322	list->size = 0;
323	list->used = 0;
324	list->strings = NULL;
325}
326
327static void
328list_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
338static void
339list_free(pgp_list_t *list)
340{
341	if (list->strings)
342		free(list->strings);
343	list_init(list);
344}
345
346static unsigned
347list_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
367static unsigned
368add_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 */
378static const char *
379find_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 */
389void
390pgp_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 */
403void
404pgp_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 */
421static unsigned
422add_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 */
453static unsigned
454add_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
493static pgp_text_t *
494text_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 */
536static pgp_text_t *
537showall_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*/
584const char     *
585pgp_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 */
603const char     *
604pgp_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 */
616const char     *
617pgp_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 */
629const char     *
630pgp_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 */
642const char     *
643pgp_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*/
654const char     *
655pgp_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 */
668pgp_text_t     *
669pgp_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 */
683const char     *
684pgp_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 */
697pgp_text_t     *
698pgp_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
704const char     *
705pgp_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*/
716const char     *
717pgp_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 */
730pgp_text_t     *
731pgp_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*/
743static const char *
744show_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? */
761pgp_text_t     *
762pgp_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*/
799const char     *
800pgp_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 */
813pgp_text_t     *
814pgp_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 */
854const char     *
855pgp_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*/
868pgp_text_t     *
869pgp_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 */
910pgp_text_t     *
911pgp_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