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.17 2010/08/15 16:36:24 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 __ops_map_t packet_tag_map[] = 80 { 81 {OPS_PTAG_CT_RESERVED, "Reserved"}, 82 {OPS_PTAG_CT_PK_SESSION_KEY, "Public-Key Encrypted Session Key"}, 83 {OPS_PTAG_CT_SIGNATURE, "Signature"}, 84 {OPS_PTAG_CT_SK_SESSION_KEY, "Symmetric-Key Encrypted Session Key"}, 85 {OPS_PTAG_CT_1_PASS_SIG, "One-Pass Signature"}, 86 {OPS_PTAG_CT_SECRET_KEY, "Secret Key"}, 87 {OPS_PTAG_CT_PUBLIC_KEY, "Public Key"}, 88 {OPS_PTAG_CT_SECRET_SUBKEY, "Secret Subkey"}, 89 {OPS_PTAG_CT_COMPRESSED, "Compressed Data"}, 90 {OPS_PTAG_CT_SE_DATA, "Symmetrically Encrypted Data"}, 91 {OPS_PTAG_CT_MARKER, "Marker"}, 92 {OPS_PTAG_CT_LITDATA, "Literal Data"}, 93 {OPS_PTAG_CT_TRUST, "Trust"}, 94 {OPS_PTAG_CT_USER_ID, "User ID"}, 95 {OPS_PTAG_CT_PUBLIC_SUBKEY, "Public Subkey"}, 96 {OPS_PTAG_CT_RESERVED2, "reserved2"}, 97 {OPS_PTAG_CT_RESERVED3, "reserved3"}, 98 {OPS_PTAG_CT_USER_ATTR, "User Attribute"}, 99 {OPS_PTAG_CT_SE_IP_DATA, 100 "Symmetric Encrypted and Integrity Protected Data"}, 101 {OPS_PTAG_CT_MDC, "Modification Detection Code"}, 102 {OPS_PARSER_PTAG, "OPS_PARSER_PTAG"}, 103 {OPS_PTAG_RAW_SS, "OPS_PTAG_RAW_SS"}, 104 {OPS_PTAG_SS_ALL, "OPS_PTAG_SS_ALL"}, 105 {OPS_PARSER_PACKET_END, "OPS_PARSER_PACKET_END"}, 106 {OPS_PTAG_SIG_SUBPKT_BASE, "OPS_PTAG_SIG_SUBPKT_BASE"}, 107 {OPS_PTAG_SS_CREATION_TIME, "SS: Signature Creation Time"}, 108 {OPS_PTAG_SS_EXPIRATION_TIME, "SS: Signature Expiration Time"}, 109 {OPS_PTAG_SS_EXPORT_CERT, "SS: Exportable Certification"}, 110 {OPS_PTAG_SS_TRUST, "SS: Trust Signature"}, 111 {OPS_PTAG_SS_REGEXP, "SS: Regular Expression"}, 112 {OPS_PTAG_SS_REVOCABLE, "SS: Revocable"}, 113 {OPS_PTAG_SS_KEY_EXPIRY, "SS: Key Expiration Time"}, 114 {OPS_PTAG_SS_RESERVED, "SS: Reserved"}, 115 {OPS_PTAG_SS_PREFERRED_SKA, "SS: Preferred Secret Key Algorithm"}, 116 {OPS_PTAG_SS_REVOCATION_KEY, "SS: Revocation Key"}, 117 {OPS_PTAG_SS_ISSUER_KEY_ID, "SS: Issuer Key Id"}, 118 {OPS_PTAG_SS_NOTATION_DATA, "SS: Notation Data"}, 119 {OPS_PTAG_SS_PREFERRED_HASH, "SS: Preferred Hash Algorithm"}, 120 {OPS_PTAG_SS_PREF_COMPRESS, "SS: Preferred Compression Algorithm"}, 121 {OPS_PTAG_SS_KEYSERV_PREFS, "SS: Key Server Preferences"}, 122 {OPS_PTAG_SS_PREF_KEYSERV, "SS: Preferred Key Server"}, 123 {OPS_PTAG_SS_PRIMARY_USER_ID, "SS: Primary User ID"}, 124 {OPS_PTAG_SS_POLICY_URI, "SS: Policy URI"}, 125 {OPS_PTAG_SS_KEY_FLAGS, "SS: Key Flags"}, 126 {OPS_PTAG_SS_SIGNERS_USER_ID, "SS: Signer's User ID"}, 127 {OPS_PTAG_SS_REVOCATION_REASON, "SS: Reason for Revocation"}, 128 {OPS_PTAG_SS_FEATURES, "SS: Features"}, 129 {OPS_PTAG_SS_SIGNATURE_TARGET, "SS: Signature Target"}, 130 {OPS_PTAG_SS_EMBEDDED_SIGNATURE, "SS: Embedded Signature"}, 131 132 {OPS_PTAG_CT_LITDATA_HEADER, "CT: Literal Data Header"}, 133 {OPS_PTAG_CT_LITDATA_BODY, "CT: Literal Data Body"}, 134 {OPS_PTAG_CT_SIGNATURE_HEADER, "CT: Signature Header"}, 135 {OPS_PTAG_CT_SIGNATURE_FOOTER, "CT: Signature Footer"}, 136 {OPS_PTAG_CT_ARMOUR_HEADER, "CT: Armour Header"}, 137 {OPS_PTAG_CT_ARMOUR_TRAILER, "CT: Armour Trailer"}, 138 {OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER, "CT: Signed Cleartext Header"}, 139 {OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY, "CT: Signed Cleartext Body"}, 140 {OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, "CT: Signed Cleartext Trailer"}, 141 {OPS_PTAG_CT_UNARMOURED_TEXT, "CT: Unarmoured Text"}, 142 {OPS_PTAG_CT_ENCRYPTED_SECRET_KEY, "CT: Encrypted Secret Key"}, 143 {OPS_PTAG_CT_SE_DATA_HEADER, "CT: Sym Encrypted Data Header"}, 144 {OPS_PTAG_CT_SE_DATA_BODY, "CT: Sym Encrypted Data Body"}, 145 {OPS_PTAG_CT_SE_IP_DATA_HEADER, "CT: Sym Encrypted IP Data Header"}, 146 {OPS_PTAG_CT_SE_IP_DATA_BODY, "CT: Sym Encrypted IP Data Body"}, 147 {OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, "CT: Encrypted PK Session Key"}, 148 {OPS_GET_PASSPHRASE, "CMD: Get Secret Key Passphrase"}, 149 {OPS_GET_SECKEY, "CMD: Get Secret Key"}, 150 {OPS_PARSER_ERROR, "OPS_PARSER_ERROR"}, 151 {OPS_PARSER_ERRCODE, "OPS_PARSER_ERRCODE"}, 152 153 {0x00, NULL}, /* this is the end-of-array marker */ 154 }; 155 156 static __ops_map_t ss_type_map[] = 157 { 158 {OPS_PTAG_SS_CREATION_TIME, "Signature Creation Time"}, 159 {OPS_PTAG_SS_EXPIRATION_TIME, "Signature Expiration Time"}, 160 {OPS_PTAG_SS_TRUST, "Trust Signature"}, 161 {OPS_PTAG_SS_REGEXP, "Regular Expression"}, 162 {OPS_PTAG_SS_REVOCABLE, "Revocable"}, 163 {OPS_PTAG_SS_KEY_EXPIRY, "Key Expiration Time"}, 164 {OPS_PTAG_SS_PREFERRED_SKA, "Preferred Symmetric Algorithms"}, 165 {OPS_PTAG_SS_REVOCATION_KEY, "Revocation Key"}, 166 {OPS_PTAG_SS_ISSUER_KEY_ID, "Issuer key ID"}, 167 {OPS_PTAG_SS_NOTATION_DATA, "Notation Data"}, 168 {OPS_PTAG_SS_PREFERRED_HASH, "Preferred Hash Algorithms"}, 169 {OPS_PTAG_SS_PREF_COMPRESS, "Preferred Compression Algorithms"}, 170 {OPS_PTAG_SS_KEYSERV_PREFS, "Key Server Preferences"}, 171 {OPS_PTAG_SS_PREF_KEYSERV, "Preferred Key Server"}, 172 {OPS_PTAG_SS_PRIMARY_USER_ID, "Primary User ID"}, 173 {OPS_PTAG_SS_POLICY_URI, "Policy URI"}, 174 {OPS_PTAG_SS_KEY_FLAGS, "Key Flags"}, 175 {OPS_PTAG_SS_REVOCATION_REASON, "Reason for Revocation"}, 176 {OPS_PTAG_SS_FEATURES, "Features"}, 177 {0x00, NULL}, /* this is the end-of-array marker */ 178 }; 179 180 181 static __ops_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 __ops_map_t sig_type_map[] = 192 { 193 {OPS_SIG_BINARY, "Signature of a binary document"}, 194 {OPS_SIG_TEXT, "Signature of a canonical text document"}, 195 {OPS_SIG_STANDALONE, "Standalone signature"}, 196 {OPS_CERT_GENERIC, "Generic certification of a User ID and Public Key packet"}, 197 {OPS_CERT_PERSONA, "Personal certification of a User ID and Public Key packet"}, 198 {OPS_CERT_CASUAL, "Casual certification of a User ID and Public Key packet"}, 199 {OPS_CERT_POSITIVE, "Positive certification of a User ID and Public Key packet"}, 200 {OPS_SIG_SUBKEY, "Subkey Binding Signature"}, 201 {OPS_SIG_PRIMARY, "Primary Key Binding Signature"}, 202 {OPS_SIG_DIRECT, "Signature directly on a key"}, 203 {OPS_SIG_REV_KEY, "Key revocation signature"}, 204 {OPS_SIG_REV_SUBKEY, "Subkey revocation signature"}, 205 {OPS_SIG_REV_CERT, "Certification revocation signature"}, 206 {OPS_SIG_TIMESTAMP, "Timestamp signature"}, 207 {OPS_SIG_3RD_PARTY, "Third-Party Confirmation signature"}, 208 {0x00, NULL}, /* this is the end-of-array marker */ 209 }; 210 211 static __ops_map_t pubkey_alg_map[] = 212 { 213 {OPS_PKA_RSA, "RSA (Encrypt or Sign)"}, 214 {OPS_PKA_RSA_ENCRYPT_ONLY, "RSA Encrypt-Only"}, 215 {OPS_PKA_RSA_SIGN_ONLY, "RSA Sign-Only"}, 216 {OPS_PKA_ELGAMAL, "Elgamal (Encrypt-Only)"}, 217 {OPS_PKA_DSA, "DSA"}, 218 {OPS_PKA_RESERVED_ELLIPTIC_CURVE, "Reserved for Elliptic Curve"}, 219 {OPS_PKA_RESERVED_ECDSA, "Reserved for ECDSA"}, 220 {OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN, "Reserved (formerly Elgamal Encrypt or Sign"}, 221 {OPS_PKA_RESERVED_DH, "Reserved for Diffie-Hellman (X9.42)"}, 222 {OPS_PKA_PRIVATE00, "Private/Experimental"}, 223 {OPS_PKA_PRIVATE01, "Private/Experimental"}, 224 {OPS_PKA_PRIVATE02, "Private/Experimental"}, 225 {OPS_PKA_PRIVATE03, "Private/Experimental"}, 226 {OPS_PKA_PRIVATE04, "Private/Experimental"}, 227 {OPS_PKA_PRIVATE05, "Private/Experimental"}, 228 {OPS_PKA_PRIVATE06, "Private/Experimental"}, 229 {OPS_PKA_PRIVATE07, "Private/Experimental"}, 230 {OPS_PKA_PRIVATE08, "Private/Experimental"}, 231 {OPS_PKA_PRIVATE09, "Private/Experimental"}, 232 {OPS_PKA_PRIVATE10, "Private/Experimental"}, 233 {0x00, NULL}, /* this is the end-of-array marker */ 234 }; 235 236 static __ops_map_t symm_alg_map[] = 237 { 238 {OPS_SA_PLAINTEXT, "Plaintext or unencrypted data"}, 239 {OPS_SA_IDEA, "IDEA"}, 240 {OPS_SA_TRIPLEDES, "TripleDES"}, 241 {OPS_SA_CAST5, "CAST5"}, 242 {OPS_SA_BLOWFISH, "Blowfish"}, 243 {OPS_SA_AES_128, "AES (128-bit key)"}, 244 {OPS_SA_AES_192, "AES (192-bit key)"}, 245 {OPS_SA_AES_256, "AES (256-bit key)"}, 246 {OPS_SA_TWOFISH, "Twofish(256-bit key)"}, 247 {0x00, NULL}, /* this is the end-of-array marker */ 248 }; 249 250 static __ops_map_t hash_alg_map[] = 251 { 252 {OPS_HASH_MD5, "MD5"}, 253 {OPS_HASH_SHA1, "SHA1"}, 254 {OPS_HASH_RIPEMD, "RIPEMD160"}, 255 {OPS_HASH_SHA256, "SHA256"}, 256 {OPS_HASH_SHA384, "SHA384"}, 257 {OPS_HASH_SHA512, "SHA512"}, 258 {OPS_HASH_SHA224, "SHA224"}, 259 {0x00, NULL}, /* this is the end-of-array marker */ 260 }; 261 262 static __ops_map_t compression_alg_map[] = 263 { 264 {OPS_C_NONE, "Uncompressed"}, 265 {OPS_C_ZIP, "ZIP(RFC1951)"}, 266 {OPS_C_ZLIB, "ZLIB(RFC1950)"}, 267 {OPS_C_BZIP2, "Bzip2(BZ2)"}, 268 {0x00, NULL}, /* this is the end-of-array marker */ 269 }; 270 271 static __ops_bit_map_t ss_notation_map_byte0[] = 272 { 273 {0x80, "Human-readable"}, 274 {0x00, NULL}, 275 }; 276 277 static __ops_bit_map_t *ss_notation_map[] = 278 { 279 ss_notation_map_byte0, 280 }; 281 282 static __ops_bit_map_t ss_feature_map_byte0[] = 283 { 284 {0x01, "Modification Detection"}, 285 {0x00, NULL}, 286 }; 287 288 static __ops_bit_map_t *ss_feature_map[] = 289 { 290 ss_feature_map_byte0, 291 }; 292 293 static __ops_bit_map_t ss_key_flags_map[] = 294 { 295 {0x01, "May be used to certify other keys"}, 296 {0x02, "May be used to sign data"}, 297 {0x04, "May be used to encrypt communications"}, 298 {0x08, "May be used to encrypt storage"}, 299 {0x10, "Private component may have been split by a secret-sharing mechanism"}, 300 {0x80, "Private component may be in possession of more than one person"}, 301 {0x00, NULL}, 302 }; 303 304 static __ops_bit_map_t ss_key_server_prefs_map[] = 305 { 306 {0x80, "Key holder requests that this key only be modified or updated by the key holder or an administrator of the key server"}, 307 {0x00, NULL}, 308 }; 309 310 /* 311 * Private functions 312 */ 313 314 static void 315 list_init(__ops_list_t *list) 316 { 317 list->size = 0; 318 list->used = 0; 319 list->strings = NULL; 320 } 321 322 static void 323 list_free_strings(__ops_list_t *list) 324 { 325 unsigned i; 326 327 for (i = 0; i < list->used; i++) { 328 free(list->strings[i]); 329 list->strings[i] = NULL; 330 } 331 } 332 333 static void 334 list_free(__ops_list_t *list) 335 { 336 if (list->strings) 337 free(list->strings); 338 list_init(list); 339 } 340 341 static unsigned 342 list_resize(__ops_list_t *list) 343 { 344 /* 345 * We only resize in one direction - upwards. Algorithm used : double 346 * the current size then add 1 347 */ 348 char **newstrings; 349 int newsize; 350 351 newsize = (list->size * 2) + 1; 352 newstrings = realloc(list->strings, newsize * sizeof(char *)); 353 if (newstrings) { 354 list->strings = newstrings; 355 list->size = newsize; 356 return 1; 357 } 358 (void) fprintf(stderr, "list_resize - bad alloc\n"); 359 return 0; 360 } 361 362 static unsigned 363 add_str(__ops_list_t *list, const char *str) 364 { 365 if (list->size == list->used && !list_resize(list)) { 366 return 0; 367 } 368 list->strings[list->used++] = __UNCONST(str); 369 return 1; 370 } 371 372 /* find a bitfield in a map - serial search */ 373 static const char * 374 find_bitfield(__ops_bit_map_t *map, uint8_t octet) 375 { 376 __ops_bit_map_t *row; 377 378 for (row = map; row->string != NULL && row->mask != octet ; row++) { 379 } 380 return (row->string) ? row->string : "Unknown"; 381 } 382 383 /* ! generic function to initialise __ops_text_t structure */ 384 void 385 __ops_text_init(__ops_text_t *text) 386 { 387 list_init(&text->known); 388 list_init(&text->unknown); 389 } 390 391 /** 392 * \ingroup Core_Print 393 * 394 * __ops_text_free() frees the memory used by an __ops_text_t structure 395 * 396 * \param text Pointer to a previously allocated structure. This structure and its contents will be freed. 397 */ 398 void 399 __ops_text_free(__ops_text_t *text) 400 { 401 /* Strings in "known" array will be constants, so don't free them */ 402 list_free(&text->known); 403 404 /* 405 * Strings in "unknown" array will be dynamically allocated, so do 406 * free them 407 */ 408 list_free_strings(&text->unknown); 409 list_free(&text->unknown); 410 411 free(text); 412 } 413 414 /* XXX: should this (and many others) be unsigned? */ 415 /* ! generic function which adds text derived from single octet map to text */ 416 static unsigned 417 add_str_from_octet_map(__ops_text_t *map, char *str, uint8_t octet) 418 { 419 if (str && !add_str(&map->known, str)) { 420 /* 421 * value recognised, but there was a problem adding it to the 422 * list 423 */ 424 /* XXX - should print out error msg here, Ben? - rachel */ 425 return 0; 426 } else if (!str) { 427 /* 428 * value not recognised and there was a problem adding it to 429 * the unknown list 430 */ 431 unsigned len = 2 + 2 + 1; /* 2 for "0x", 2 for 432 * single octet in hex 433 * format, 1 for NUL */ 434 if ((str = calloc(1, len)) == NULL) { 435 (void) fprintf(stderr, "add_str_from_octet_map: bad alloc\n"); 436 return 0; 437 } 438 (void) snprintf(str, len, "0x%x", octet); 439 if (!add_str(&map->unknown, str)) { 440 return 0; 441 } 442 free(str); 443 } 444 return 1; 445 } 446 447 /* ! generic function which adds text derived from single bit map to text */ 448 static unsigned 449 add_bitmap_entry(__ops_text_t *map, const char *str, uint8_t bit) 450 { 451 const char *fmt_unknown = "Unknown bit(0x%x)"; 452 453 if (str && !add_str(&map->known, str)) { 454 /* 455 * value recognised, but there was a problem adding it to the 456 * list 457 */ 458 /* XXX - should print out error msg here, Ben? - rachel */ 459 return 0; 460 } else if (!str) { 461 /* 462 * value not recognised and there was a problem adding it to 463 * the unknown list 464 * 2 chars of the string are the format definition, this will 465 * be replaced in the output by 2 chars of hex, so the length 466 * will be correct 467 */ 468 unsigned len = (unsigned)(strlen(fmt_unknown) + 1); 469 char *newstr; 470 471 if ((newstr = calloc(1, len)) == NULL) { 472 (void) fprintf(stderr, "add_bitmap_entry: bad alloc\n"); 473 return 0; 474 } 475 (void) snprintf(newstr, len, fmt_unknown, bit); 476 if (!add_str(&map->unknown, newstr)) { 477 return 0; 478 } 479 free(newstr); 480 } 481 return 1; 482 } 483 484 /** 485 * Produce a structure containing human-readable textstrings 486 * representing the recognised and unrecognised contents 487 * of this byte array. text_fn() will be called on each octet in turn. 488 * Each octet will generate one string representing the whole byte. 489 * 490 */ 491 492 static __ops_text_t * 493 text_from_bytemapped_octets(const __ops_data_t *data, 494 const char *(*text_fn)(uint8_t octet)) 495 { 496 __ops_text_t *text; 497 const char *str; 498 unsigned i; 499 500 /* 501 * ! allocate and initialise __ops_text_t structure to store derived 502 * strings 503 */ 504 if ((text = calloc(1, sizeof(*text))) == NULL) { 505 return NULL; 506 } 507 508 __ops_text_init(text); 509 510 /* ! for each octet in field ... */ 511 for (i = 0; i < data->len; i++) { 512 /* ! derive string from octet */ 513 str = (*text_fn) (data->contents[i]); 514 515 /* ! and add to text */ 516 if (!add_str_from_octet_map(text, netpgp_strdup(str), 517 data->contents[i])) { 518 __ops_text_free(text); 519 return NULL; 520 } 521 } 522 /* 523 * ! All values have been added to either the known or the unknown 524 * list 525 */ 526 return text; 527 } 528 529 /** 530 * Produce a structure containing human-readable textstrings 531 * representing the recognised and unrecognised contents 532 * of this byte array, derived from each bit of each octet. 533 * 534 */ 535 static __ops_text_t * 536 showall_octets_bits(__ops_data_t *data, __ops_bit_map_t **map, size_t nmap) 537 { 538 __ops_text_t *text; 539 const char *str; 540 unsigned i; 541 uint8_t mask, bit; 542 int j = 0; 543 544 /* 545 * ! allocate and initialise __ops_text_t structure to store derived 546 * strings 547 */ 548 if ((text = calloc(1, sizeof(__ops_text_t))) == NULL) { 549 return NULL; 550 } 551 552 __ops_text_init(text); 553 554 /* ! for each octet in field ... */ 555 for (i = 0; i < data->len; i++) { 556 /* ! for each bit in octet ... */ 557 mask = 0x80; 558 for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) { 559 bit = data->contents[i] & mask; 560 if (bit) { 561 str = (i >= nmap) ? "Unknown" : 562 find_bitfield(map[i], bit); 563 if (!add_bitmap_entry(text, str, bit)) { 564 __ops_text_free(text); 565 return NULL; 566 } 567 } 568 } 569 } 570 return text; 571 } 572 573 /* 574 * Public Functions 575 */ 576 577 /** 578 * \ingroup Core_Print 579 * returns description of the Packet Tag 580 * \param packet_tag 581 * \return string or "Unknown" 582 */ 583 const char * 584 __ops_show_packet_tag(__ops_content_enum packet_tag) 585 { 586 const char *ret; 587 588 ret = __ops_str_from_map(packet_tag, packet_tag_map); 589 if (!ret) { 590 ret = "Unknown Tag"; 591 } 592 return ret; 593 } 594 595 /** 596 * \ingroup Core_Print 597 * 598 * returns description of the Signature Sub-Packet type 599 * \param ss_type Signature Sub-Packet type 600 * \return string or "Unknown" 601 */ 602 const char * 603 __ops_show_ss_type(__ops_content_enum ss_type) 604 { 605 return __ops_str_from_map(ss_type, ss_type_map); 606 } 607 608 /** 609 * \ingroup Core_Print 610 * 611 * returns description of the Revocation Reason code 612 * \param ss_rr_code Revocation Reason code 613 * \return string or "Unknown" 614 */ 615 const char * 616 __ops_show_ss_rr_code(__ops_ss_rr_code_t ss_rr_code) 617 { 618 return __ops_str_from_map(ss_rr_code, ss_rr_code_map); 619 } 620 621 /** 622 * \ingroup Core_Print 623 * 624 * returns description of the given Signature type 625 * \param sig_type Signature type 626 * \return string or "Unknown" 627 */ 628 const char * 629 __ops_show_sig_type(__ops_sig_type_t sig_type) 630 { 631 return __ops_str_from_map(sig_type, sig_type_map); 632 } 633 634 /** 635 * \ingroup Core_Print 636 * 637 * returns description of the given Public Key Algorithm 638 * \param pka Public Key Algorithm type 639 * \return string or "Unknown" 640 */ 641 const char * 642 __ops_show_pka(__ops_pubkey_alg_t pka) 643 { 644 return __ops_str_from_map(pka, pubkey_alg_map); 645 } 646 647 /** 648 * \ingroup Core_Print 649 * returns description of the Preferred Compression 650 * \param octet Preferred Compression 651 * \return string or "Unknown" 652 */ 653 const char * 654 __ops_show_ss_zpref(uint8_t octet) 655 { 656 return __ops_str_from_map(octet, compression_alg_map); 657 } 658 659 /** 660 * \ingroup Core_Print 661 * 662 * returns set of descriptions of the given Preferred Compression Algorithms 663 * \param ss_zpref Array of Preferred Compression Algorithms 664 * \return NULL if cannot allocate memory or other error 665 * \return pointer to structure, if no error 666 */ 667 __ops_text_t * 668 __ops_showall_ss_zpref(const __ops_data_t *ss_zpref) 669 { 670 return text_from_bytemapped_octets(ss_zpref, 671 &__ops_show_ss_zpref); 672 } 673 674 675 /** 676 * \ingroup Core_Print 677 * 678 * returns description of the Hash Algorithm type 679 * \param hash Hash Algorithm type 680 * \return string or "Unknown" 681 */ 682 const char * 683 __ops_show_hash_alg(uint8_t hash) 684 { 685 return __ops_str_from_map(hash, hash_alg_map); 686 } 687 688 /** 689 * \ingroup Core_Print 690 * 691 * returns set of descriptions of the given Preferred Hash Algorithms 692 * \param ss_hashpref Array of Preferred Hash Algorithms 693 * \return NULL if cannot allocate memory or other error 694 * \return pointer to structure, if no error 695 */ 696 __ops_text_t * 697 __ops_showall_ss_hashpref(const __ops_data_t *ss_hashpref) 698 { 699 return text_from_bytemapped_octets(ss_hashpref, 700 &__ops_show_hash_alg); 701 } 702 703 const char * 704 __ops_show_symm_alg(uint8_t hash) 705 { 706 return __ops_str_from_map(hash, symm_alg_map); 707 } 708 709 /** 710 * \ingroup Core_Print 711 * returns description of the given Preferred Symmetric Key Algorithm 712 * \param octet 713 * \return string or "Unknown" 714 */ 715 const char * 716 __ops_show_ss_skapref(uint8_t octet) 717 { 718 return __ops_str_from_map(octet, symm_alg_map); 719 } 720 721 /** 722 * \ingroup Core_Print 723 * 724 * returns set of descriptions of the given Preferred Symmetric Key Algorithms 725 * \param ss_skapref Array of Preferred Symmetric Key Algorithms 726 * \return NULL if cannot allocate memory or other error 727 * \return pointer to structure, if no error 728 */ 729 __ops_text_t * 730 __ops_showall_ss_skapref(const __ops_data_t *ss_skapref) 731 { 732 return text_from_bytemapped_octets(ss_skapref, 733 &__ops_show_ss_skapref); 734 } 735 736 /** 737 * \ingroup Core_Print 738 * returns description of one SS Feature 739 * \param octet 740 * \return string or "Unknown" 741 */ 742 static const char * 743 __ops_show_ss_feature(uint8_t octet, unsigned offset) 744 { 745 if (offset >= OPS_ARRAY_SIZE(ss_feature_map)) { 746 return "Unknown"; 747 } 748 return find_bitfield(ss_feature_map[offset], octet); 749 } 750 751 /** 752 * \ingroup Core_Print 753 * 754 * returns set of descriptions of the given SS Features 755 * \param ss_features Signature Sub-Packet Features 756 * \return NULL if cannot allocate memory or other error 757 * \return pointer to structure, if no error 758 */ 759 /* XXX: shouldn't this use show_all_octets_bits? */ 760 __ops_text_t * 761 __ops_showall_ss_features(__ops_data_t ss_features) 762 { 763 __ops_text_t *text; 764 const char *str; 765 unsigned i; 766 uint8_t mask, bit; 767 int j; 768 769 if ((text = calloc(1, sizeof(*text))) == NULL) { 770 return NULL; 771 } 772 773 __ops_text_init(text); 774 775 for (i = 0; i < ss_features.len; i++) { 776 mask = 0x80; 777 for (j = 0; j < 8; j++, mask = (unsigned)mask >> 1) { 778 bit = ss_features.contents[i] & mask; 779 if (bit) { 780 str = __ops_show_ss_feature(bit, i); 781 if (!add_bitmap_entry(text, str, bit)) { 782 __ops_text_free(text); 783 return NULL; 784 } 785 } 786 } 787 } 788 return text; 789 } 790 791 /** 792 * \ingroup Core_Print 793 * returns description of SS Key Flag 794 * \param octet 795 * \param map 796 * \return 797 */ 798 const char * 799 __ops_show_ss_key_flag(uint8_t octet, __ops_bit_map_t *map) 800 { 801 return find_bitfield(map, octet); 802 } 803 804 /** 805 * \ingroup Core_Print 806 * 807 * returns set of descriptions of the given Preferred Key Flags 808 * \param ss_key_flags Array of Key Flags 809 * \return NULL if cannot allocate memory or other error 810 * \return pointer to structure, if no error 811 */ 812 __ops_text_t * 813 __ops_showall_ss_key_flags(const __ops_data_t *ss_key_flags) 814 { 815 __ops_text_t *text; 816 const char *str; 817 uint8_t mask, bit; 818 int i; 819 820 if ((text = calloc(1, sizeof(*text))) == NULL) { 821 return NULL; 822 } 823 824 __ops_text_init(text); 825 826 /* xxx - TBD: extend to handle multiple octets of bits - rachel */ 827 for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) { 828 bit = ss_key_flags->contents[0] & mask; 829 if (bit) { 830 str = __ops_show_ss_key_flag(bit, ss_key_flags_map); 831 if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) { 832 __ops_text_free(text); 833 return NULL; 834 } 835 } 836 } 837 /* 838 * xxx - must add error text if more than one octet. Only one 839 * currently specified -- rachel 840 */ 841 return text; 842 } 843 844 /** 845 * \ingroup Core_Print 846 * 847 * returns description of one given Key Server Preference 848 * 849 * \param prefs Byte containing bitfield of preferences 850 * \param map 851 * \return string or "Unknown" 852 */ 853 const char * 854 __ops_show_keyserv_pref(uint8_t prefs, __ops_bit_map_t *map) 855 { 856 return find_bitfield(map, prefs); 857 } 858 859 /** 860 * \ingroup Core_Print 861 * returns set of descriptions of given Key Server Preferences 862 * \param ss_key_server_prefs 863 * \return NULL if cannot allocate memory or other error 864 * \return pointer to structure, if no error 865 * 866 */ 867 __ops_text_t * 868 __ops_show_keyserv_prefs(const __ops_data_t *prefs) 869 { 870 __ops_text_t *text; 871 const char *str; 872 uint8_t mask, bit; 873 int i = 0; 874 875 if ((text = calloc(1, sizeof(*text))) == NULL) { 876 return NULL; 877 } 878 879 __ops_text_init(text); 880 881 /* xxx - TBD: extend to handle multiple octets of bits - rachel */ 882 883 for (i = 0, mask = 0x80; i < 8; i++, mask = (unsigned)mask >> 1) { 884 bit = prefs->contents[0] & mask; 885 if (bit) { 886 str = __ops_show_keyserv_pref(bit, 887 ss_key_server_prefs_map); 888 if (!add_bitmap_entry(text, netpgp_strdup(str), bit)) { 889 __ops_text_free(text); 890 return NULL; 891 } 892 } 893 } 894 /* 895 * xxx - must add error text if more than one octet. Only one 896 * currently specified -- rachel 897 */ 898 return text; 899 } 900 901 /** 902 * \ingroup Core_Print 903 * 904 * returns set of descriptions of the given SS Notation Data Flags 905 * \param ss_notation Signature Sub-Packet Notation Data 906 * \return NULL if cannot allocate memory or other error 907 * \return pointer to structure, if no error 908 */ 909 __ops_text_t * 910 __ops_showall_notation(__ops_ss_notation_t ss_notation) 911 { 912 return showall_octets_bits(&ss_notation.flags, 913 ss_notation_map, 914 OPS_ARRAY_SIZE(ss_notation_map)); 915 } 916