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