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