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