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