packet-print.c revision 1.12
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/* 51 * ! \file \brief Standard API print functions 52 */ 53#include "config.h" 54 55#ifdef HAVE_SYS_CDEFS_H 56#include <sys/cdefs.h> 57#endif 58 59#if defined(__NetBSD__) 60__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 61__RCSID("$NetBSD: packet-print.c,v 1.12 2009/05/21 00:33:31 agc Exp $"); 62#endif 63 64#include <string.h> 65#include <stdio.h> 66 67#ifdef HAVE_UNISTD_H 68#include <unistd.h> 69#endif 70 71#include "crypto.h" 72#include "keyring.h" 73#include "packet-show.h" 74#include "signature.h" 75#include "readerwriter.h" 76#include "netpgpdefs.h" 77#include "packet.h" 78 79static int indent = 0; 80 81/* static functions */ 82 83/* printhex is now print_hex for consistency */ 84static void 85print_hex(const unsigned char *src, size_t length) 86{ 87 while (length-- > 0) { 88 printf("%02X", *src++); 89 } 90} 91 92static void 93print_indent(void) 94{ 95 int i = 0; 96 97 for (i = 0; i < indent; i++) { 98 printf(" "); 99 } 100} 101 102static void 103print_name(const char *name) 104{ 105 print_indent(); 106 if (name) { 107 printf("%s: ", name); 108 } 109} 110 111static void 112print_hexdump(const char *name, const unsigned char *data, unsigned int len) 113{ 114 print_name(name); 115 116 printf("len=%d, data=0x", len); 117 print_hex(data, len); 118 printf("\n"); 119} 120 121static void 122print_hexdump_data(const char *name, const unsigned char *data, unsigned len) 123{ 124 print_name(name); 125 126 printf("0x"); 127 print_hex(data, len); 128 printf("\n"); 129} 130 131static void 132print_unsigned_int(const char *name, unsigned int val) 133{ 134 print_name(name); 135 printf("%d\n", val); 136} 137 138static void 139showtime(const char *name, time_t t) 140{ 141 printf("%s=%" PRItime "d (%.24s)", name, (long long) t, ctime(&t)); 142} 143 144static void 145print_time(const char *name, time_t t) 146{ 147 print_indent(); 148 printf("%s: ", name); 149 showtime("time", t); 150 printf("\n"); 151} 152 153static void 154print_time_short(FILE *fp, time_t t) 155{ 156 struct tm *tm; 157 158 tm = gmtime(&t); 159 (void) fprintf(fp, "%04d-%02d-%02d", 160 tm->tm_year + 1900, 161 tm->tm_mon + 1, 162 tm->tm_mday); 163} 164 165static void 166print_string_and_value(const char *name, const char *str, unsigned char value) 167{ 168 print_name(name); 169 printf("%s (0x%x)\n", str, value); 170} 171 172static void 173print_tagname(const char *str) 174{ 175 print_indent(); 176 printf("%s packet\n", str); 177} 178 179static void 180print_data(const char *name, const __ops_data_t * data) 181{ 182 print_hexdump(name, data->contents, data->len); 183} 184 185static void 186print_bn(const char *name, const BIGNUM * bn) 187{ 188 print_indent(); 189 printf("%s=", name); 190 if (bn) { 191 BN_print_fp(stdout, bn); 192 putchar('\n'); 193 } else { 194 puts("(unset)"); 195 } 196} 197 198 199static void 200print_packet_hex(const __ops_subpacket_t *pkt) 201{ 202 unsigned char *cur; 203 unsigned rem; 204 unsigned blksz = 4; 205 int i; 206 207 printf("\nhexdump of packet contents follows:\n"); 208 for (i = 1, cur = pkt->raw; 209 cur < (pkt->raw + pkt->length); 210 cur += blksz, i++) { 211 rem = pkt->raw + pkt->length - cur; 212 hexdump(stdout, cur, (rem <= blksz) ? rem : blksz, ""); 213 printf(" "); 214 if (i % 8 == 0) { 215 printf("\n"); 216 } 217 218 } 219 printf("\n"); 220} 221 222static void 223print_escaped(const unsigned char *data, size_t length) 224{ 225 while (length-- > 0) { 226 if ((*data >= 0x20 && *data < 0x7f && *data != '%') || 227 *data == '\n') { 228 putchar(*data); 229 } else { 230 printf("%%%02x", *data); 231 } 232 ++data; 233 } 234} 235 236static void 237print_string(const char *name, const char *str) 238{ 239 print_name(name); 240 print_escaped((const unsigned char *) str, strlen(str)); 241 putchar('\n'); 242} 243 244static void 245print_utf8_string(const char *name, const unsigned char *str) 246{ 247 /* \todo Do this better for non-English character sets */ 248 print_string(name, (const char *) str); 249} 250 251static void 252print_duration(const char *name, time_t t) 253{ 254 int mins, hours, days, years; 255 256 print_indent(); 257 printf("%s: ", name); 258 printf("duration %" PRItime "d seconds", (long long) t); 259 260 mins = (int)(t / 60); 261 hours = mins / 60; 262 days = hours / 24; 263 years = days / 365; 264 265 printf(" (approx. "); 266 if (years) { 267 printf("%d %s", years, years == 1 ? "year" : "years"); 268 } else if (days) { 269 printf("%d %s", days, days == 1 ? "day" : "days"); 270 } else if (hours) { 271 printf("%d %s", hours, hours == 1 ? "hour" : "hours"); 272 } 273 printf(")\n"); 274} 275 276static void 277print_boolean(const char *name, unsigned char boolval) 278{ 279 print_name(name); 280 printf("%s\n", (boolval) ? "Yes" : "No"); 281} 282 283static void 284print_text_breakdown(__ops_text_t * text) 285{ 286 const char *prefix = ".. "; 287 unsigned i; 288 289 /* these were recognised */ 290 for (i = 0; i < text->known.used; i++) { 291 print_indent(); 292 printf("%s", prefix); 293 printf("%s\n", text->known.strings[i]); 294 } 295 /* 296 * these were not recognised. the strings will contain the hex value 297 * of the unrecognised value in string format - see 298 * process_octet_str() 299 */ 300 if (text->unknown.used) { 301 printf("\n"); 302 print_indent(); 303 printf("Not Recognised: "); 304 } 305 for (i = 0; i < text->unknown.used; i++) { 306 print_indent(); 307 printf("%s", prefix); 308 printf("%s\n", text->unknown.strings[i]); 309 } 310} 311 312static void 313print_headers(const __ops_headers_t *h) 314{ 315 unsigned i; 316 317 for (i = 0; i < h->headerc; ++i) { 318 printf("%s=%s\n", h->headers[i].key, h->headers[i].value); 319 } 320} 321 322static void 323print_block(const char *name, const unsigned char *str, size_t length) 324{ 325 int o = length; 326 327 print_indent(); 328 printf(">>>>> %s >>>>>\n", name); 329 330 print_indent(); 331 for (; length > 0; --length) { 332 if (*str >= 0x20 && *str < 0x7f && *str != '%') { 333 putchar(*str); 334 } else if (*str == '\n') { 335 putchar(*str); 336 print_indent(); 337 } else { 338 printf("%%%02x", *str); 339 } 340 ++str; 341 } 342 if (o && str[-1] != '\n') { 343 putchar('\n'); 344 print_indent(); 345 fputs("[no newline]", stdout); 346 } else { 347 print_indent(); 348 } 349 printf("<<<<< %s <<<<<\n", name); 350} 351 352/* return the number of bits in the public key */ 353static int 354numkeybits(const __ops_pubkey_t *pubkey) 355{ 356 switch(pubkey->alg) { 357 case OPS_PKA_RSA: 358 case OPS_PKA_RSA_ENCRYPT_ONLY: 359 case OPS_PKA_RSA_SIGN_ONLY: 360 return BN_num_bytes(pubkey->key.rsa.n) * 8; 361 case OPS_PKA_DSA: 362 switch(BN_num_bytes(pubkey->key.dsa.q)) { 363 case 20: 364 return 1024; 365 case 28: 366 return 2048; 367 case 32: 368 return 3072; 369 default: 370 return 0; 371 } 372 case OPS_PKA_ELGAMAL: 373 return BN_num_bytes(pubkey->key.elgamal.y) * 8; 374 default: 375 return -1; 376 } 377} 378 379/** 380 \ingroup Core_Print 381 382 Prints a public key in succinct detail 383 384 \param key Ptr to public key 385*/ 386void 387__ops_print_pubkeydata(FILE *fp, const __ops_keydata_t * key) 388{ 389 unsigned int i; 390 391 (void) fprintf(fp, "pub %d/%s ", 392 numkeybits(&key->key.pubkey), 393 __ops_show_pka(key->key.pubkey.alg)); 394 hexdump(fp, key->key_id, OPS_KEY_ID_SIZE, ""); 395 (void) fprintf(fp, " "); 396 print_time_short(fp, key->key.pubkey.birthtime); 397 (void) fprintf(fp, "\nKey fingerprint: "); 398 hexdump(fp, key->fingerprint.fingerprint, 20, " "); 399 (void) fprintf(fp, "\n"); 400 for (i = 0; i < key->nuids; i++) { 401 (void) fprintf(fp, "uid %s\n", 402 key->uids[i].userid); 403 } 404} 405 406/** 407\ingroup Core_Print 408\param pubkey 409*/ 410void 411__ops_print_pubkey(const __ops_pubkey_t * pubkey) 412{ 413 printf("------- PUBLIC KEY ------\n"); 414 print_unsigned_int("Version", (unsigned)pubkey->version); 415 print_time("Creation Time", pubkey->birthtime); 416 if (pubkey->version == OPS_V3) 417 print_unsigned_int("Days Valid", pubkey->days_valid); 418 419 print_string_and_value("Algorithm", __ops_show_pka(pubkey->alg), 420 pubkey->alg); 421 422 switch (pubkey->alg) { 423 case OPS_PKA_DSA: 424 print_bn("p", pubkey->key.dsa.p); 425 print_bn("q", pubkey->key.dsa.q); 426 print_bn("g", pubkey->key.dsa.g); 427 print_bn("y", pubkey->key.dsa.y); 428 break; 429 430 case OPS_PKA_RSA: 431 case OPS_PKA_RSA_ENCRYPT_ONLY: 432 case OPS_PKA_RSA_SIGN_ONLY: 433 print_bn("n", pubkey->key.rsa.n); 434 print_bn("e", pubkey->key.rsa.e); 435 break; 436 437 case OPS_PKA_ELGAMAL: 438 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 439 print_bn("p", pubkey->key.elgamal.p); 440 print_bn("g", pubkey->key.elgamal.g); 441 print_bn("y", pubkey->key.elgamal.y); 442 break; 443 444 default: 445 (void) fprintf(stderr, 446 "__ops_print_pubkey: Unusual algorithm\n"); 447 } 448 449 printf("------- end of PUBLIC KEY ------\n"); 450} 451 452/** 453 \ingroup Core_Print 454 455 Prints a secret key 456 457 \param key Ptr to public key 458*/ 459 460void 461__ops_print_seckeydata(const __ops_keydata_t * key) 462{ 463 printf("sec "); 464 __ops_show_pka(key->key.pubkey.alg); 465 printf(" "); 466 467 hexdump(stdout, key->key_id, OPS_KEY_ID_SIZE, ""); 468 printf(" "); 469 470 print_time_short(stdout, key->key.pubkey.birthtime); 471 printf(" "); 472 473 if (key->nuids == 1) { 474 /* print on same line as other info */ 475 printf("%s\n", key->uids[0].userid); 476 } else { 477 /* print all uids on separate line */ 478 unsigned int i; 479 printf("\n"); 480 for (i = 0; i < key->nuids; i++) { 481 printf("uid %s\n", key->uids[i].userid); 482 } 483 } 484} 485 486/** 487\ingroup Core_Print 488\param type 489\param seckey 490*/ 491static void 492__ops_print_seckey_verbose(const __ops_content_tag_t type, 493 const __ops_seckey_t *seckey) 494{ 495 printf("------- SECRET KEY or ENCRYPTED SECRET KEY ------\n"); 496 print_tagname((type == OPS_PTAG_CT_SECRET_KEY) ? 497 "SECRET_KEY" : 498 "ENCRYPTED_SECRET_KEY"); 499 /* __ops_print_pubkey(key); */ 500 printf("S2K Usage: %d\n", seckey->s2k_usage); 501 if (seckey->s2k_usage != OPS_S2KU_NONE) { 502 printf("S2K Specifier: %d\n", seckey->s2k_specifier); 503 printf("Symmetric algorithm: %d (%s)\n", seckey->alg, 504 __ops_show_symm_alg(seckey->alg)); 505 printf("Hash algorithm: %d (%s)\n", seckey->hash_alg, 506 __ops_show_hash_alg(seckey->hash_alg)); 507 if (seckey->s2k_specifier != OPS_S2KS_SIMPLE) { 508 print_hexdump("Salt", seckey->salt, 509 sizeof(seckey->salt)); 510 } 511 if (seckey->s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED) { 512 printf("Octet count: %d\n", seckey->octetc); 513 } 514 print_hexdump("IV", seckey->iv, __ops_block_size(seckey->alg)); 515 } 516 /* no more set if encrypted */ 517 if (type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) { 518 return; 519 } 520 switch (seckey->pubkey.alg) { 521 case OPS_PKA_RSA: 522 print_bn("d", seckey->key.rsa.d); 523 print_bn("p", seckey->key.rsa.p); 524 print_bn("q", seckey->key.rsa.q); 525 print_bn("u", seckey->key.rsa.u); 526 break; 527 528 case OPS_PKA_DSA: 529 print_bn("x", seckey->key.dsa.x); 530 break; 531 532 default: 533 (void) fprintf(stderr, 534 "__ops_print_seckey_verbose: unusual algorithm\n"); 535 } 536 if (seckey->s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) { 537 print_hexdump("Checkhash", seckey->checkhash, 538 OPS_CHECKHASH_SIZE); 539 } else { 540 printf("Checksum: %04x\n", seckey->checksum); 541 } 542 printf("------- end of SECRET KEY or ENCRYPTED SECRET KEY ------\n"); 543} 544 545 546/** 547\ingroup Core_Print 548\param tag 549\param key 550*/ 551static void 552__ops_print_pk_sesskey(__ops_content_tag_t tag, 553 const __ops_pk_sesskey_t * key) 554{ 555 print_tagname((tag == OPS_PTAG_CT_PK_SESSION_KEY) ? 556 "PUBLIC KEY SESSION KEY" : 557 "ENCRYPTED PUBLIC KEY SESSION KEY"); 558 printf("Version: %d\n", key->version); 559 print_hexdump("Key ID", key->key_id, sizeof(key->key_id)); 560 printf("Algorithm: %d (%s)\n", key->alg, 561 __ops_show_pka(key->alg)); 562 switch (key->alg) { 563 case OPS_PKA_RSA: 564 print_bn("encrypted_m", key->parameters.rsa.encrypted_m); 565 break; 566 567 case OPS_PKA_ELGAMAL: 568 print_bn("g_to_k", key->parameters.elgamal.g_to_k); 569 print_bn("encrypted_m", key->parameters.elgamal.encrypted_m); 570 break; 571 572 default: 573 (void) fprintf(stderr, 574 "__ops_print_pk_sesskey: unusual algorithm\n"); 575 } 576 if (tag == OPS_PTAG_CT_PK_SESSION_KEY) { 577 printf("Symmetric algorithm: %d (%s)\n", key->symm_alg, 578 __ops_show_symm_alg(key->symm_alg)); 579 print_hexdump("Key", key->key, __ops_key_size(key->symm_alg)); 580 printf("Checksum: %04x\n", key->checksum); 581 } 582} 583 584static void 585start_subpacket(int type) 586{ 587 indent++; 588 print_indent(); 589 printf("-- %s (type 0x%02x)\n", 590 __ops_show_ss_type(type), 591 type - OPS_PTAG_SIG_SUBPKT_BASE); 592} 593 594static void 595end_subpacket(void) 596{ 597 indent--; 598} 599 600/** 601\ingroup Core_Print 602\param contents 603*/ 604int 605__ops_print_packet(const __ops_packet_t * pkt) 606{ 607 const __ops_parser_content_union_t *content = &pkt->u; 608 __ops_text_t *text; 609 static unsigned unarmoured; 610 const char *str; 611 612 if (unarmoured && pkt->tag != OPS_PTAG_CT_UNARMOURED_TEXT) { 613 unarmoured = 0; 614 puts("UNARMOURED TEXT ends"); 615 } 616 if (pkt->tag == OPS_PARSER_PTAG) { 617 printf("=> OPS_PARSER_PTAG: %s\n", 618 __ops_show_packet_tag(content->ptag.type)); 619 } else { 620 printf("=> %s\n", __ops_show_packet_tag(pkt->tag)); 621 } 622 623 switch (pkt->tag) { 624 case OPS_PARSER_ERROR: 625 printf("parse error: %s\n", content->error.error); 626 break; 627 628 case OPS_PARSER_ERRCODE: 629 printf("parse error: %s\n", 630 __ops_errcode(content->errcode.errcode)); 631 break; 632 633 case OPS_PARSER_PACKET_END: 634 print_packet_hex(&content->packet); 635 break; 636 637 case OPS_PARSER_PTAG: 638 if (content->ptag.type == OPS_PTAG_CT_PUBLIC_KEY) { 639 indent = 0; 640 printf("\n*** NEXT KEY ***\n"); 641 } 642 printf("\n"); 643 print_indent(); 644 printf("==== ptag new_format=%d type=%d length_type=%d" 645 " length=0x%x (%d) position=0x%x (%d)\n", 646 content->ptag.new_format, 647 content->ptag.type, content->ptag.length_type, 648 content->ptag.length, content->ptag.length, 649 content->ptag.position, content->ptag.position); 650 print_tagname(__ops_show_packet_tag(content->ptag.type)); 651 break; 652 653 case OPS_PTAG_CT_SE_DATA_HEADER: 654 print_tagname("SYMMETRIC ENCRYPTED DATA"); 655 break; 656 657 case OPS_PTAG_CT_SE_IP_DATA_HEADER: 658 print_tagname( 659 "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER"); 660 printf("Version: %d\n", content->se_ip_data_header.version); 661 break; 662 663 case OPS_PTAG_CT_SE_IP_DATA_BODY: 664 print_tagname( 665 "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY"); 666 printf(" data body length=%d\n", 667 content->se_data_body.length); 668 printf(" data="); 669 hexdump(stdout, content->se_data_body.data, 670 content->se_data_body.length, ""); 671 printf("\n"); 672 break; 673 674 case OPS_PTAG_CT_PUBLIC_KEY: 675 case OPS_PTAG_CT_PUBLIC_SUBKEY: 676 print_tagname((pkt->tag == OPS_PTAG_CT_PUBLIC_KEY) ? 677 "PUBLIC KEY" : 678 "PUBLIC SUBKEY"); 679 __ops_print_pubkey(&content->pubkey); 680 break; 681 682 case OPS_PTAG_CT_TRUST: 683 print_tagname("TRUST"); 684 print_data("Trust", &content->trust.data); 685 break; 686 687 case OPS_PTAG_CT_USER_ID: 688 /* XXX: how do we print UTF-8? */ 689 print_tagname("USER ID"); 690 print_utf8_string("userid", content->userid.userid); 691 break; 692 693 case OPS_PTAG_CT_SIGNATURE: 694 print_tagname("SIGNATURE"); 695 print_indent(); 696 print_unsigned_int("Signature Version", 697 (unsigned)content->sig.info.version); 698 if (content->sig.info.birthtime_set) { 699 print_time("Signature Creation Time", 700 content->sig.info.birthtime); 701 } 702 703 print_string_and_value("Signature Type", 704 __ops_show_sig_type(content->sig.info.type), 705 content->sig.info.type); 706 707 if (content->sig.info.signer_id_set) { 708 print_hexdump_data("Signer ID", 709 content->sig.info.signer_id, 710 sizeof(content->sig.info.signer_id)); 711 } 712 713 print_string_and_value("Public Key Algorithm", 714 __ops_show_pka(content->sig.info.key_alg), 715 content->sig.info.key_alg); 716 print_string_and_value("Hash Algorithm", 717 __ops_show_hash_alg(content->sig.info.hash_alg), 718 content->sig.info.hash_alg); 719 720 print_unsigned_int("Hashed data len", 721 content->sig.info.v4_hashed_data_length); 722 723 print_indent(); 724 print_hexdump_data("hash2", &content->sig.hash2[0], 2); 725 726 switch (content->sig.info.key_alg) { 727 case OPS_PKA_RSA: 728 case OPS_PKA_RSA_SIGN_ONLY: 729 print_bn("sig", content->sig.info.sig.rsa.sig); 730 break; 731 732 case OPS_PKA_DSA: 733 print_bn("r", content->sig.info.sig.dsa.r); 734 print_bn("s", content->sig.info.sig.dsa.s); 735 break; 736 737 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 738 print_bn("r", content->sig.info.sig.elgamal.r); 739 print_bn("s", content->sig.info.sig.elgamal.s); 740 break; 741 742 default: 743 (void) fprintf(stderr, 744 "__ops_print_packet: Unusual algorithm\n"); 745 return 0; 746 } 747 748 if (content->sig.hash) 749 printf("data hash is set\n"); 750 751 break; 752 753 case OPS_PTAG_CT_COMPRESSED: 754 print_tagname("COMPRESSED"); 755 print_unsigned_int("Compressed Data Type", 756 (unsigned)content->compressed.type); 757 break; 758 759 case OPS_PTAG_CT_1_PASS_SIG: 760 print_tagname("ONE PASS SIGNATURE"); 761 762 print_unsigned_int("Version", 763 (unsigned)content->one_pass_sig.version); 764 print_string_and_value("Signature Type", 765 __ops_show_sig_type(content->one_pass_sig.sig_type), 766 content->one_pass_sig.sig_type); 767 print_string_and_value("Hash Algorithm", 768 __ops_show_hash_alg(content->one_pass_sig.hash_alg), 769 content->one_pass_sig.hash_alg); 770 print_string_and_value("Public Key Algorithm", 771 __ops_show_pka(content->one_pass_sig.key_alg), 772 content->one_pass_sig.key_alg); 773 print_hexdump_data("Signer ID", 774 content->one_pass_sig.keyid, 775 sizeof(content->one_pass_sig.keyid)); 776 777 print_unsigned_int("Nested", 778 content->one_pass_sig.nested); 779 break; 780 781 case OPS_PTAG_CT_USER_ATTR: 782 print_tagname("USER ATTRIBUTE"); 783 print_hexdump("User Attribute", 784 content->userattr.data.contents, 785 content->userattr.data.len); 786 break; 787 788 case OPS_PTAG_RAW_SS: 789 if (pkt->critical) { 790 (void) fprintf(stderr, "contents are critical\n"); 791 return 0; 792 } 793 start_subpacket(pkt->tag); 794 print_unsigned_int("Raw Signature Subpacket: tag", 795 (unsigned)(content->ss_raw.tag - 796 OPS_PTAG_SIG_SUBPKT_BASE)); 797 print_hexdump("Raw Data", 798 content->ss_raw.raw, 799 content->ss_raw.length); 800 break; 801 802 case OPS_PTAG_SS_CREATION_TIME: 803 start_subpacket(pkt->tag); 804 print_time("Signature Creation Time", content->ss_time.time); 805 end_subpacket(); 806 break; 807 808 case OPS_PTAG_SS_EXPIRATION_TIME: 809 start_subpacket(pkt->tag); 810 print_duration("Signature Expiration Time", 811 content->ss_time.time); 812 end_subpacket(); 813 break; 814 815 case OPS_PTAG_SS_KEY_EXPIRY: 816 start_subpacket(pkt->tag); 817 print_duration("Key Expiration Time", content->ss_time.time); 818 end_subpacket(); 819 break; 820 821 case OPS_PTAG_SS_TRUST: 822 start_subpacket(pkt->tag); 823 print_string("Trust Signature", ""); 824 print_unsigned_int("Level", 825 (unsigned)content->ss_trust.level); 826 print_unsigned_int("Amount", 827 (unsigned)content->ss_trust.amount); 828 end_subpacket(); 829 break; 830 831 case OPS_PTAG_SS_REVOCABLE: 832 start_subpacket(pkt->tag); 833 print_boolean("Revocable", content->ss_revocable.revocable); 834 end_subpacket(); 835 break; 836 837 case OPS_PTAG_SS_REVOCATION_KEY: 838 start_subpacket(pkt->tag); 839 /* not yet tested */ 840 printf(" revocation key: class=0x%x", 841 content->ss_revocation_key.class); 842 if (content->ss_revocation_key.class & 0x40) 843 printf(" (sensitive)"); 844 printf(", algid=0x%x", 845 content->ss_revocation_key.algid); 846 printf(", fingerprint="); 847 hexdump(stdout, content->ss_revocation_key.fingerprint, 20, ""); 848 printf("\n"); 849 end_subpacket(); 850 break; 851 852 case OPS_PTAG_SS_ISSUER_KEY_ID: 853 start_subpacket(pkt->tag); 854 print_hexdump("Issuer Key Id", 855 &content->ss_issuer_key_id.key_id[0], 856 sizeof(content->ss_issuer_key_id.key_id)); 857 end_subpacket(); 858 break; 859 860 case OPS_PTAG_SS_PREFERRED_SKA: 861 start_subpacket(pkt->tag); 862 print_data("Preferred Symmetric Algorithms", 863 &content->ss_skapref.data); 864 865 text = __ops_showall_ss_skapref(content->ss_skapref); 866 print_text_breakdown(text); 867 __ops_text_free(text); 868 869 end_subpacket(); 870 break; 871 872 case OPS_PTAG_SS_PRIMARY_USER_ID: 873 start_subpacket(pkt->tag); 874 print_boolean("Primary User ID", 875 content->ss_primary_userid.primary_userid); 876 end_subpacket(); 877 break; 878 879 case OPS_PTAG_SS_PREFERRED_HASH: 880 start_subpacket(pkt->tag); 881 print_data("Preferred Hash Algorithms", 882 &content->ss_hashpref.data); 883 884 text = __ops_showall_ss_hashpref(content->ss_hashpref); 885 print_text_breakdown(text); 886 __ops_text_free(text); 887 end_subpacket(); 888 break; 889 890 case OPS_PTAG_SS_PREF_COMPRESS: 891 start_subpacket(pkt->tag); 892 print_data("Preferred Compression Algorithms", 893 &content->ss_zpref.data); 894 895 text = __ops_showall_ss_zpref(content->ss_zpref); 896 print_text_breakdown(text); 897 __ops_text_free(text); 898 end_subpacket(); 899 break; 900 901 case OPS_PTAG_SS_KEY_FLAGS: 902 start_subpacket(pkt->tag); 903 print_data("Key Flags", &content->ss_key_flags.data); 904 905 text = __ops_showall_ss_key_flags(content->ss_key_flags); 906 print_text_breakdown(text); 907 __ops_text_free(text); 908 909 end_subpacket(); 910 break; 911 912 case OPS_PTAG_SS_KEYSERV_PREFS: 913 start_subpacket(pkt->tag); 914 print_data("Key Server Preferences", 915 &content->ss_key_server_prefs.data); 916 917 text = __ops_show_keyserv_prefs(content->ss_key_server_prefs); 918 print_text_breakdown(text); 919 __ops_text_free(text); 920 921 end_subpacket(); 922 break; 923 924 case OPS_PTAG_SS_FEATURES: 925 start_subpacket(pkt->tag); 926 print_data("Features", 927 &content->ss_features.data); 928 929 text = __ops_showall_ss_features(content->ss_features); 930 print_text_breakdown(text); 931 __ops_text_free(text); 932 933 end_subpacket(); 934 break; 935 936 case OPS_PTAG_SS_NOTATION_DATA: 937 start_subpacket(pkt->tag); 938 print_indent(); 939 printf("Notation Data:\n"); 940 941 indent++; 942 print_data("Flags", &content->ss_notation.flags); 943 text = __ops_showall_notation(content->ss_notation); 944 print_text_breakdown(text); 945 __ops_text_free(text); 946 947 /* xxx - TODO: print out UTF - rachel */ 948 949 print_data("Name", &content->ss_notation.name); 950 951 print_data("Value", &content->ss_notation.value); 952 953 indent--; 954 end_subpacket(); 955 break; 956 957 case OPS_PTAG_SS_REGEXP: 958 start_subpacket(pkt->tag); 959 print_hexdump("Regular Expression", 960 (unsigned char *) content->ss_regexp.regexp, 961 strlen(content->ss_regexp.regexp)); 962 print_string(NULL, content->ss_regexp.regexp); 963 end_subpacket(); 964 break; 965 966 case OPS_PTAG_SS_POLICY_URI: 967 start_subpacket(pkt->tag); 968 print_string("Policy URL", content->ss_policy.url); 969 end_subpacket(); 970 break; 971 972 case OPS_PTAG_SS_SIGNERS_USER_ID: 973 start_subpacket(pkt->tag); 974 print_utf8_string("Signer's User ID", 975 content->ss_signer.userid); 976 end_subpacket(); 977 break; 978 979 case OPS_PTAG_SS_PREF_KEYSERV: 980 start_subpacket(pkt->tag); 981 print_string("Preferred Key Server", content->ss_keyserv.name); 982 end_subpacket(); 983 break; 984 985 case OPS_PTAG_SS_EMBEDDED_SIGNATURE: 986 start_subpacket(pkt->tag); 987 end_subpacket();/* \todo print out contents? */ 988 break; 989 990 case OPS_PTAG_SS_USERDEFINED00: 991 case OPS_PTAG_SS_USERDEFINED01: 992 case OPS_PTAG_SS_USERDEFINED02: 993 case OPS_PTAG_SS_USERDEFINED03: 994 case OPS_PTAG_SS_USERDEFINED04: 995 case OPS_PTAG_SS_USERDEFINED05: 996 case OPS_PTAG_SS_USERDEFINED06: 997 case OPS_PTAG_SS_USERDEFINED07: 998 case OPS_PTAG_SS_USERDEFINED08: 999 case OPS_PTAG_SS_USERDEFINED09: 1000 case OPS_PTAG_SS_USERDEFINED10: 1001 start_subpacket(pkt->tag); 1002 print_hexdump("Internal or user-defined", 1003 content->ss_userdef.data.contents, 1004 content->ss_userdef.data.len); 1005 end_subpacket(); 1006 break; 1007 1008 case OPS_PTAG_SS_RESERVED: 1009 start_subpacket(pkt->tag); 1010 print_hexdump("Reserved", 1011 content->ss_userdef.data.contents, 1012 content->ss_userdef.data.len); 1013 end_subpacket(); 1014 break; 1015 1016 case OPS_PTAG_SS_REVOCATION_REASON: 1017 start_subpacket(pkt->tag); 1018 print_hexdump("Revocation Reason", 1019 &content->ss_revocation.code, 1020 1); 1021 str = __ops_show_ss_rr_code(content->ss_revocation.code); 1022 print_string(NULL, str); 1023 /* xxx - todo : output text as UTF-8 string */ 1024 end_subpacket(); 1025 break; 1026 1027 case OPS_PTAG_CT_LITERAL_DATA_HEADER: 1028 print_tagname("LITERAL DATA HEADER"); 1029 printf(" literal data header format=%c filename='%s'\n", 1030 content->litdata_header.format, 1031 content->litdata_header.filename); 1032 showtime(" modification time", 1033 content->litdata_header.mtime); 1034 printf("\n"); 1035 break; 1036 1037 case OPS_PTAG_CT_LITERAL_DATA_BODY: 1038 print_tagname("LITERAL DATA BODY"); 1039 printf(" literal data body length=%d\n", 1040 content->litdata_body.length); 1041 printf(" data="); 1042 print_escaped(content->litdata_body.data, 1043 content->litdata_body.length); 1044 printf("\n"); 1045 break; 1046 1047 case OPS_PTAG_CT_SIGNATURE_HEADER: 1048 print_tagname("SIGNATURE"); 1049 print_indent(); 1050 print_unsigned_int("Signature Version", 1051 (unsigned)content->sig.info.version); 1052 if (content->sig.info.birthtime_set) 1053 print_time("Signature Creation Time", 1054 content->sig.info.birthtime); 1055 1056 print_string_and_value("Signature Type", 1057 __ops_show_sig_type(content->sig.info.type), 1058 content->sig.info.type); 1059 1060 if (content->sig.info.signer_id_set) 1061 print_hexdump_data("Signer ID", 1062 content->sig.info.signer_id, 1063 sizeof(content->sig.info.signer_id)); 1064 1065 print_string_and_value("Public Key Algorithm", 1066 __ops_show_pka(content->sig.info.key_alg), 1067 content->sig.info.key_alg); 1068 print_string_and_value("Hash Algorithm", 1069 __ops_show_hash_alg(content->sig.info.hash_alg), 1070 content->sig.info.hash_alg); 1071 1072 break; 1073 1074 case OPS_PTAG_CT_SIGNATURE_FOOTER: 1075 print_indent(); 1076 print_hexdump_data("hash2", &content->sig.hash2[0], 2); 1077 1078 switch (content->sig.info.key_alg) { 1079 case OPS_PKA_RSA: 1080 print_bn("sig", content->sig.info.sig.rsa.sig); 1081 break; 1082 1083 case OPS_PKA_DSA: 1084 print_bn("r", content->sig.info.sig.dsa.r); 1085 print_bn("s", content->sig.info.sig.dsa.s); 1086 break; 1087 1088 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 1089 print_bn("r", content->sig.info.sig.elgamal.r); 1090 print_bn("s", content->sig.info.sig.elgamal.s); 1091 break; 1092 1093 case OPS_PKA_PRIVATE00: 1094 case OPS_PKA_PRIVATE01: 1095 case OPS_PKA_PRIVATE02: 1096 case OPS_PKA_PRIVATE03: 1097 case OPS_PKA_PRIVATE04: 1098 case OPS_PKA_PRIVATE05: 1099 case OPS_PKA_PRIVATE06: 1100 case OPS_PKA_PRIVATE07: 1101 case OPS_PKA_PRIVATE08: 1102 case OPS_PKA_PRIVATE09: 1103 case OPS_PKA_PRIVATE10: 1104 print_data("Private/Experimental", 1105 &content->sig.info.sig.unknown.data); 1106 break; 1107 1108 default: 1109 (void) fprintf(stderr, 1110 "__ops_print_packet: Unusual key algorithm\n"); 1111 return 0; 1112 } 1113 break; 1114 1115 case OPS_PARSER_CMD_GET_SK_PASSPHRASE: 1116 print_tagname("OPS_PARSER_CMD_GET_SK_PASSPHRASE"); 1117 break; 1118 1119 case OPS_PTAG_CT_SECRET_KEY: 1120 print_tagname("OPS_PTAG_CT_SECRET_KEY"); 1121 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1122 break; 1123 1124 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 1125 print_tagname("OPS_PTAG_CT_ENCRYPTED_SECRET_KEY"); 1126 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1127 break; 1128 1129 case OPS_PTAG_CT_ARMOUR_HEADER: 1130 print_tagname("ARMOUR HEADER"); 1131 print_string("type", content->armour_header.type); 1132 break; 1133 1134 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 1135 print_tagname("SIGNED CLEARTEXT HEADER"); 1136 print_headers(&content->cleartext_head.headers); 1137 break; 1138 1139 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: 1140 print_tagname("SIGNED CLEARTEXT BODY"); 1141 print_block("signed cleartext", content->cleartext_body.data, 1142 content->cleartext_body.length); 1143 break; 1144 1145 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 1146 print_tagname("SIGNED CLEARTEXT TRAILER"); 1147 printf("hash algorithm: %d\n", 1148 content->cleartext_trailer.hash->alg); 1149 printf("\n"); 1150 break; 1151 1152 case OPS_PTAG_CT_UNARMOURED_TEXT: 1153 if (!unarmoured) { 1154 print_tagname("UNARMOURED TEXT"); 1155 unarmoured = 1; 1156 } 1157 putchar('['); 1158 print_escaped(content->unarmoured_text.data, 1159 content->unarmoured_text.length); 1160 putchar(']'); 1161 break; 1162 1163 case OPS_PTAG_CT_ARMOUR_TRAILER: 1164 print_tagname("ARMOUR TRAILER"); 1165 print_string("type", content->armour_header.type); 1166 break; 1167 1168 case OPS_PTAG_CT_PK_SESSION_KEY: 1169 case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: 1170 __ops_print_pk_sesskey(pkt->tag, &content->pk_sesskey); 1171 break; 1172 1173 case OPS_PARSER_CMD_GET_SECRET_KEY: 1174 __ops_print_pk_sesskey(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, 1175 content->get_seckey.pk_sesskey); 1176 break; 1177 1178 default: 1179 print_tagname("UNKNOWN PACKET TYPE"); 1180 fprintf(stderr, "__ops_print_packet: unknown tag=%d (0x%x)\n", 1181 pkt->tag, pkt->tag); 1182 exit(EXIT_FAILURE); 1183 } 1184 return 1; 1185} 1186 1187static __ops_parse_cb_return_t 1188cb_list_packets(const __ops_packet_t * pkt, __ops_callback_data_t * cbinfo) 1189{ 1190 __OPS_USED(cbinfo); 1191 1192 __ops_print_packet(pkt); 1193 return OPS_RELEASE_MEMORY; 1194} 1195 1196/** 1197\ingroup Core_Print 1198\param filename 1199\param armour 1200\param keyring 1201\param cb_get_passphrase 1202*/ 1203void 1204__ops_list_packets(char *filename, 1205 unsigned armour, 1206 __ops_keyring_t *keyring, 1207 __ops_cbfunc_t *cb_get_passphrase) 1208{ 1209 __ops_parseinfo_t *pinfo = NULL; 1210 const unsigned accumulate = 1; 1211 int fd = 0; 1212 1213 fd = __ops_setup_file_read(&pinfo, filename, NULL, cb_list_packets, 1214 accumulate); 1215 __ops_parse_options(pinfo, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 1216 pinfo->cryptinfo.keyring = keyring; 1217 pinfo->cryptinfo.getpassphrase = cb_get_passphrase; 1218 if (armour) { 1219 __ops_reader_push_dearmour(pinfo); 1220 } 1221 __ops_parse(pinfo, 1); 1222 __ops_teardown_file_read(pinfo, fd); 1223} 1224