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.20 2010/11/15 08:50:32 agc 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 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 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 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 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 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 * 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 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 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 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 452 add_bitmap_entry(pgp_text_t *map, const char *str, uint8_t bit) 453 { 454 const char *fmt_unknown = "Unknown bit(0x%x)"; 455 456 if (str && !add_str(&map->known, str)) { 457 /* 458 * value recognised, but there was a problem adding it to the 459 * list 460 */ 461 /* XXX - should print out error msg here, Ben? - rachel */ 462 return 0; 463 } else if (!str) { 464 /* 465 * value not recognised and there was a problem adding it to 466 * the unknown list 467 * 2 chars of the string are the format definition, this will 468 * be replaced in the output by 2 chars of hex, so the length 469 * will be correct 470 */ 471 unsigned len = (unsigned)(strlen(fmt_unknown) + 1); 472 char *newstr; 473 474 if ((newstr = calloc(1, len)) == NULL) { 475 (void) fprintf(stderr, "add_bitmap_entry: bad alloc\n"); 476 return 0; 477 } 478 (void) snprintf(newstr, len, fmt_unknown, bit); 479 if (!add_str(&map->unknown, newstr)) { 480 return 0; 481 } 482 free(newstr); 483 } 484 return 1; 485 } 486 487 /** 488 * Produce a structure containing human-readable textstrings 489 * representing the recognised and unrecognised contents 490 * of this byte array. text_fn() will be called on each octet in turn. 491 * Each octet will generate one string representing the whole byte. 492 * 493 */ 494 495 static pgp_text_t * 496 text_from_bytemapped_octets(const pgp_data_t *data, 497 const char *(*text_fn)(uint8_t octet)) 498 { 499 pgp_text_t *text; 500 const char *str; 501 unsigned i; 502 503 /* 504 * ! allocate and initialise pgp_text_t structure to store derived 505 * strings 506 */ 507 if ((text = calloc(1, sizeof(*text))) == NULL) { 508 return NULL; 509 } 510 511 pgp_text_init(text); 512 513 /* ! for each octet in field ... */ 514 for (i = 0; i < data->len; i++) { 515 /* ! derive string from octet */ 516 str = (*text_fn) (data->contents[i]); 517 518 /* ! and add to text */ 519 if (!add_str_from_octet_map(text, netpgp_strdup(str), 520 data->contents[i])) { 521 pgp_text_free(text); 522 return NULL; 523 } 524 } 525 /* 526 * ! All values have been added to either the known or the unknown 527 * list 528 */ 529 return text; 530 } 531 532 /** 533 * Produce a structure containing human-readable textstrings 534 * representing the recognised and unrecognised contents 535 * of this byte array, derived from each bit of each octet. 536 * 537 */ 538 static pgp_text_t * 539 showall_octets_bits(pgp_data_t *data, pgp_bit_map_t **map, size_t nmap) 540 { 541 pgp_text_t *text; 542 const char *str; 543 unsigned i; 544 uint8_t mask, bit; 545 int j = 0; 546 547 /* 548 * ! allocate and initialise pgp_text_t structure to store derived 549 * strings 550 */ 551 if ((text = calloc(1, sizeof(pgp_text_t))) == NULL) { 552 return NULL; 553 } 554 555 pgp_text_init(text); 556 557 /* ! for each octet in field ... */ 558 for (i = 0; i < data->len; i++) { 559 /* ! for each bit in octet ... */ 560 mask = 0x80; 561 for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) { 562 bit = data->contents[i] & mask; 563 if (bit) { 564 str = (i >= nmap) ? "Unknown" : 565 find_bitfield(map[i], bit); 566 if (!add_bitmap_entry(text, str, bit)) { 567 pgp_text_free(text); 568 return NULL; 569 } 570 } 571 } 572 } 573 return text; 574 } 575 576 /* 577 * Public Functions 578 */ 579 580 /** 581 * \ingroup Core_Print 582 * returns description of the Packet Tag 583 * \param packet_tag 584 * \return string or "Unknown" 585 */ 586 const char * 587 pgp_show_packet_tag(pgp_content_enum packet_tag) 588 { 589 const char *ret; 590 591 ret = pgp_str_from_map(packet_tag, packet_tag_map); 592 if (!ret) { 593 ret = "Unknown Tag"; 594 } 595 return ret; 596 } 597 598 /** 599 * \ingroup Core_Print 600 * 601 * returns description of the Signature Sub-Packet type 602 * \param ss_type Signature Sub-Packet type 603 * \return string or "Unknown" 604 */ 605 const char * 606 pgp_show_ss_type(pgp_content_enum ss_type) 607 { 608 return pgp_str_from_map(ss_type, ss_type_map); 609 } 610 611 /** 612 * \ingroup Core_Print 613 * 614 * returns description of the Revocation Reason code 615 * \param ss_rr_code Revocation Reason code 616 * \return string or "Unknown" 617 */ 618 const char * 619 pgp_show_ss_rr_code(pgp_ss_rr_code_t ss_rr_code) 620 { 621 return pgp_str_from_map(ss_rr_code, ss_rr_code_map); 622 } 623 624 /** 625 * \ingroup Core_Print 626 * 627 * returns description of the given Signature type 628 * \param sig_type Signature type 629 * \return string or "Unknown" 630 */ 631 const char * 632 pgp_show_sig_type(pgp_sig_type_t sig_type) 633 { 634 return pgp_str_from_map(sig_type, sig_type_map); 635 } 636 637 /** 638 * \ingroup Core_Print 639 * 640 * returns description of the given Public Key Algorithm 641 * \param pka Public Key Algorithm type 642 * \return string or "Unknown" 643 */ 644 const char * 645 pgp_show_pka(pgp_pubkey_alg_t pka) 646 { 647 return pgp_str_from_map(pka, pubkey_alg_map); 648 } 649 650 /** 651 * \ingroup Core_Print 652 * returns description of the Preferred Compression 653 * \param octet Preferred Compression 654 * \return string or "Unknown" 655 */ 656 const char * 657 pgp_show_ss_zpref(uint8_t octet) 658 { 659 return pgp_str_from_map(octet, compression_alg_map); 660 } 661 662 /** 663 * \ingroup Core_Print 664 * 665 * returns set of descriptions of the given Preferred Compression Algorithms 666 * \param ss_zpref Array of Preferred Compression Algorithms 667 * \return NULL if cannot allocate memory or other error 668 * \return pointer to structure, if no error 669 */ 670 pgp_text_t * 671 pgp_showall_ss_zpref(const pgp_data_t *ss_zpref) 672 { 673 return text_from_bytemapped_octets(ss_zpref, 674 &pgp_show_ss_zpref); 675 } 676 677 678 /** 679 * \ingroup Core_Print 680 * 681 * returns description of the Hash Algorithm type 682 * \param hash Hash Algorithm type 683 * \return string or "Unknown" 684 */ 685 const char * 686 pgp_show_hash_alg(uint8_t hash) 687 { 688 return pgp_str_from_map(hash, hash_alg_map); 689 } 690 691 /** 692 * \ingroup Core_Print 693 * 694 * returns set of descriptions of the given Preferred Hash Algorithms 695 * \param ss_hashpref Array of Preferred Hash Algorithms 696 * \return NULL if cannot allocate memory or other error 697 * \return pointer to structure, if no error 698 */ 699 pgp_text_t * 700 pgp_showall_ss_hashpref(const pgp_data_t *ss_hashpref) 701 { 702 return text_from_bytemapped_octets(ss_hashpref, 703 &pgp_show_hash_alg); 704 } 705 706 const char * 707 pgp_show_symm_alg(uint8_t hash) 708 { 709 return pgp_str_from_map(hash, symm_alg_map); 710 } 711 712 /** 713 * \ingroup Core_Print 714 * returns description of the given Preferred Symmetric Key Algorithm 715 * \param octet 716 * \return string or "Unknown" 717 */ 718 const char * 719 pgp_show_ss_skapref(uint8_t octet) 720 { 721 return pgp_str_from_map(octet, symm_alg_map); 722 } 723 724 /** 725 * \ingroup Core_Print 726 * 727 * returns set of descriptions of the given Preferred Symmetric Key Algorithms 728 * \param ss_skapref Array of Preferred Symmetric Key Algorithms 729 * \return NULL if cannot allocate memory or other error 730 * \return pointer to structure, if no error 731 */ 732 pgp_text_t * 733 pgp_showall_ss_skapref(const pgp_data_t *ss_skapref) 734 { 735 return text_from_bytemapped_octets(ss_skapref, 736 &pgp_show_ss_skapref); 737 } 738 739 /** 740 * \ingroup Core_Print 741 * returns description of one SS Feature 742 * \param octet 743 * \return string or "Unknown" 744 */ 745 static const char * 746 show_ss_feature(uint8_t octet, unsigned offset) 747 { 748 if (offset >= PGP_ARRAY_SIZE(ss_feature_map)) { 749 return "Unknown"; 750 } 751 return find_bitfield(ss_feature_map[offset], octet); 752 } 753 754 /** 755 * \ingroup Core_Print 756 * 757 * returns set of descriptions of the given SS Features 758 * \param ss_features Signature Sub-Packet Features 759 * \return NULL if cannot allocate memory or other error 760 * \return pointer to structure, if no error 761 */ 762 /* XXX: shouldn't this use show_all_octets_bits? */ 763 pgp_text_t * 764 pgp_showall_ss_features(pgp_data_t ss_features) 765 { 766 pgp_text_t *text; 767 const char *str; 768 unsigned i; 769 uint8_t mask, bit; 770 int j; 771 772 if ((text = calloc(1, sizeof(*text))) == NULL) { 773 return NULL; 774 } 775 776 pgp_text_init(text); 777 778 for (i = 0; i < ss_features.len; i++) { 779 mask = 0x80; 780 for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) { 781 bit = ss_features.contents[i] & mask; 782 if (bit) { 783 str = show_ss_feature(bit, i); 784 if (!add_bitmap_entry(text, str, bit)) { 785 pgp_text_free(text); 786 return NULL; 787 } 788 } 789 } 790 } 791 return text; 792 } 793 794 /** 795 * \ingroup Core_Print 796 * returns description of SS Key Flag 797 * \param octet 798 * \param map 799 * \return 800 */ 801 const char * 802 pgp_show_ss_key_flag(uint8_t octet, pgp_bit_map_t *map) 803 { 804 return find_bitfield(map, octet); 805 } 806 807 /** 808 * \ingroup Core_Print 809 * 810 * returns set of descriptions of the given Preferred Key Flags 811 * \param ss_key_flags Array of Key Flags 812 * \return NULL if cannot allocate memory or other error 813 * \return pointer to structure, if no error 814 */ 815 pgp_text_t * 816 pgp_showall_ss_key_flags(const pgp_data_t *ss_key_flags) 817 { 818 pgp_text_t *text; 819 const char *str; 820 uint8_t mask, bit; 821 int i; 822 823 if ((text = calloc(1, sizeof(*text))) == NULL) { 824 return NULL; 825 } 826 827 pgp_text_init(text); 828 829 /* xxx - TBD: extend to handle multiple octets of bits - rachel */ 830 for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) { 831 bit = ss_key_flags->contents[0] & mask; 832 if (bit) { 833 str = pgp_show_ss_key_flag(bit, ss_key_flags_map); 834 if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) { 835 pgp_text_free(text); 836 return NULL; 837 } 838 } 839 } 840 /* 841 * xxx - must add error text if more than one octet. Only one 842 * currently specified -- rachel 843 */ 844 return text; 845 } 846 847 /** 848 * \ingroup Core_Print 849 * 850 * returns description of one given Key Server Preference 851 * 852 * \param prefs Byte containing bitfield of preferences 853 * \param map 854 * \return string or "Unknown" 855 */ 856 const char * 857 pgp_show_keyserv_pref(uint8_t prefs, pgp_bit_map_t *map) 858 { 859 return find_bitfield(map, prefs); 860 } 861 862 /** 863 * \ingroup Core_Print 864 * returns set of descriptions of given Key Server Preferences 865 * \param ss_key_server_prefs 866 * \return NULL if cannot allocate memory or other error 867 * \return pointer to structure, if no error 868 * 869 */ 870 pgp_text_t * 871 pgp_show_keyserv_prefs(const pgp_data_t *prefs) 872 { 873 pgp_text_t *text; 874 const char *str; 875 uint8_t mask, bit; 876 int i = 0; 877 878 if ((text = calloc(1, sizeof(*text))) == NULL) { 879 return NULL; 880 } 881 882 pgp_text_init(text); 883 884 /* xxx - TBD: extend to handle multiple octets of bits - rachel */ 885 886 for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) { 887 bit = prefs->contents[0] & mask; 888 if (bit) { 889 str = pgp_show_keyserv_pref(bit, 890 ss_key_server_prefs_map); 891 if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) { 892 pgp_text_free(text); 893 return NULL; 894 } 895 } 896 } 897 /* 898 * xxx - must add error text if more than one octet. Only one 899 * currently specified -- rachel 900 */ 901 return text; 902 } 903 904 /** 905 * \ingroup Core_Print 906 * 907 * returns set of descriptions of the given SS Notation Data Flags 908 * \param ss_notation Signature Sub-Packet Notation Data 909 * \return NULL if cannot allocate memory or other error 910 * \return pointer to structure, if no error 911 */ 912 pgp_text_t * 913 pgp_showall_notation(pgp_ss_notation_t ss_notation) 914 { 915 return showall_octets_bits(&ss_notation.flags, 916 ss_notation_map, 917 PGP_ARRAY_SIZE(ss_notation_map)); 918 } 919