packet-print.c revision 1.30
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.30 2010/03/16 04:14:29 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 uint8_t *data, unsigned 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 uint8_t *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 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, uint8_t 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 rem; 181 unsigned blksz = 4; 182 uint8_t *cur; 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 uint8_t *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 uint8_t *) str, strlen(str)); 219 putchar('\n'); 220} 221 222static void 223print_utf8_string(int indent, const char *name, const uint8_t *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, uint8_t 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 uint8_t *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 uint8_t *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/* print the sub key binding signature info */ 386static int 387psubkeybinding(char *buf, size_t size, __ops_subsig_t *subsig, const __ops_pubkey_t *pubkey, char *expired) 388{ 389 char keyid[512]; 390 char t[32]; 391 392 return snprintf(buf, size, "sub %d/%s %s %s %s\n", 393 numkeybits(pubkey), 394 __ops_show_pka(subsig->sig.info.key_alg), 395 strhexdump(keyid, subsig->sig.info.signer_id, OPS_KEY_ID_SIZE, ""), 396 ptimestr(t, sizeof(t), subsig->sig.info.birthtime), 397 expired); 398} 399 400static int 401isrevoked(const __ops_key_t *key, unsigned uid) 402{ 403 unsigned r; 404 405 for (r = 0 ; r < key->revokec ; r++) { 406 if (key->revokes[r].uid == uid) { 407 return r; 408 } 409 } 410 return -1; 411} 412 413#ifndef KB 414#define KB(x) ((x) * 1024) 415#endif 416 417/* print into a string (malloc'ed) the pubkeydata */ 418int 419__ops_sprint_keydata(__ops_io_t *io, const __ops_keyring_t *keyring, 420 const __ops_key_t *key, char **buf, const char *header, 421 const __ops_pubkey_t *pubkey, const int psigs) 422{ 423 const __ops_key_t *trustkey; 424 unsigned from; 425 unsigned i; 426 unsigned j; 427 time_t now; 428 char uidbuf[KB(128)]; 429 char keyid[OPS_KEY_ID_SIZE * 3]; 430 char fp[(OPS_FINGERPRINT_SIZE * 3) + 1]; 431 char expired[128]; 432 char t[32]; 433 int cc; 434 int n; 435 int r; 436 437 if (key->revoked) { 438 return -1; 439 } 440 now = time(NULL); 441 if (pubkey->duration > 0) { 442 cc = snprintf(expired, sizeof(expired), 443 (pubkey->birthtime + pubkey->duration < now) ? 444 "[EXPIRED " : "[EXPIRES "); 445 ptimestr(&expired[cc], sizeof(expired) - cc, 446 pubkey->birthtime + pubkey->duration); 447 cc += 10; 448 cc += snprintf(&expired[cc], sizeof(expired) - cc, "]"); 449 } else { 450 expired[0] = 0x0; 451 } 452 for (i = 0, n = 0; i < key->uidc; i++) { 453 if ((r = isrevoked(key, i)) >= 0 && 454 key->revokes[r].code == OPS_REVOCATION_COMPROMISED) { 455 continue; 456 } 457 n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, "uid%s%s%s\n", 458 (psigs) ? " " : " ", 459 key->uids[i].userid, 460 (isrevoked(key, i) >= 0) ? " [REVOKED]" : ""); 461 for (j = 0 ; j < key->subsigc ; j++) { 462 if (psigs) { 463 if (key->subsigs[j].uid != i) { 464 continue; 465 } 466 } else { 467 if (!(key->subsigs[j].sig.info.version == 4 && 468 key->subsigs[j].sig.info.type == OPS_SIG_SUBKEY && 469 i == key->uidc - 1)) { 470 continue; 471 } 472 } 473 from = 0; 474 trustkey = __ops_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from); 475 if (key->subsigs[j].sig.info.version == 4 && 476 key->subsigs[j].sig.info.type == OPS_SIG_SUBKEY) { 477 psubkeybinding(&uidbuf[n], sizeof(uidbuf) - n, &key->subsigs[j], pubkey, expired); 478 } else { 479 n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, 480 "sig %s %s %s\n", 481 strhexdump(keyid, key->subsigs[j].sig.info.signer_id, OPS_KEY_ID_SIZE, ""), 482 ptimestr(t, sizeof(t), key->subsigs[j].sig.info.birthtime), 483 (trustkey) ? (char *)trustkey->uids[trustkey->uid0].userid : "[unknown]"); 484 } 485 } 486 } 487 return __ops_asprintf(buf, "%s %d/%s %s %s %s\nKey fingerprint: %s\n%s", 488 header, 489 numkeybits(pubkey), 490 __ops_show_pka(pubkey->alg), 491 strhexdump(keyid, key->key_id, OPS_KEY_ID_SIZE, ""), 492 ptimestr(t, sizeof(t), pubkey->birthtime), 493 expired, 494 strhexdump(fp, key->fingerprint.fingerprint, OPS_FINGERPRINT_SIZE, " "), 495 uidbuf); 496} 497 498int 499__ops_hkp_sprint_keydata(__ops_io_t *io, const __ops_keyring_t *keyring, 500 const __ops_key_t *key, char **buf, 501 const __ops_pubkey_t *pubkey, const int psigs) 502{ 503 const __ops_key_t *trustkey; 504 unsigned from; 505 unsigned i; 506 unsigned j; 507 char keyid[OPS_KEY_ID_SIZE * 3]; 508 char uidbuf[KB(128)]; 509 char fp[(OPS_FINGERPRINT_SIZE * 3) + 1]; 510 int n; 511 512 if (key->revoked) { 513 return -1; 514 } 515 for (i = 0, n = 0; i < key->uidc; i++) { 516 n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, 517 "uid:%lld:%lld:%s\n", 518 (long long)pubkey->birthtime, 519 (long long)pubkey->duration, 520 key->uids[i].userid); 521 for (j = 0 ; j < key->subsigc ; j++) { 522 if (psigs) { 523 if (key->subsigs[j].uid != i) { 524 continue; 525 } 526 } else { 527 if (!(key->subsigs[j].sig.info.version == 4 && 528 key->subsigs[j].sig.info.type == OPS_SIG_SUBKEY && 529 i == key->uidc - 1)) { 530 continue; 531 } 532 } 533 from = 0; 534 trustkey = __ops_getkeybyid(io, keyring, key->subsigs[j].sig.info.signer_id, &from); 535 if (key->subsigs[j].sig.info.version == 4 && 536 key->subsigs[j].sig.info.type == OPS_SIG_SUBKEY) { 537 n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, "sub:%d:%d:%s:%lld:%lld\n", 538 numkeybits(pubkey), 539 key->subsigs[j].sig.info.key_alg, 540 strhexdump(keyid, key->subsigs[j].sig.info.signer_id, OPS_KEY_ID_SIZE, ""), 541 (long long)(key->subsigs[j].sig.info.birthtime), 542 (long long)pubkey->duration); 543 } else { 544 n += snprintf(&uidbuf[n], sizeof(uidbuf) - n, 545 "sig:%s:%lld:%s\n", 546 strhexdump(keyid, key->subsigs[j].sig.info.signer_id, OPS_KEY_ID_SIZE, ""), 547 (long long)key->subsigs[j].sig.info.birthtime, 548 (trustkey) ? (char *)trustkey->uids[trustkey->uid0].userid : ""); 549 } 550 } 551 } 552 return __ops_asprintf(buf, "pub:%s:%d:%d:%lld:%lld\n%s", 553 strhexdump(fp, key->fingerprint.fingerprint, OPS_FINGERPRINT_SIZE, ""), 554 pubkey->alg, 555 numkeybits(pubkey), 556 (long long)pubkey->birthtime, 557 (long long)pubkey->duration, 558 uidbuf); 559} 560 561/* print the key data for a pub or sec key */ 562void 563__ops_print_keydata(__ops_io_t *io, const __ops_keyring_t *keyring, 564 const __ops_key_t *key, const char *header, 565 const __ops_pubkey_t *pubkey, const int psigs) 566{ 567 char *cp; 568 569 if (__ops_sprint_keydata(io, keyring, key, &cp, header, pubkey, psigs) >= 0) { 570 (void) fprintf(io->res, "%s", cp); 571 free(cp); 572 } 573} 574 575/** 576\ingroup Core_Print 577\param pubkey 578*/ 579void 580__ops_print_pubkey(const __ops_pubkey_t *pubkey) 581{ 582 printf("------- PUBLIC KEY ------\n"); 583 print_uint(0, "Version", (unsigned)pubkey->version); 584 print_time(0, "Creation Time", pubkey->birthtime); 585 if (pubkey->version == OPS_V3) { 586 print_uint(0, "Days Valid", pubkey->days_valid); 587 } 588 print_string_and_value(0, "Algorithm", __ops_show_pka(pubkey->alg), 589 pubkey->alg); 590 switch (pubkey->alg) { 591 case OPS_PKA_DSA: 592 print_bn(0, "p", pubkey->key.dsa.p); 593 print_bn(0, "q", pubkey->key.dsa.q); 594 print_bn(0, "g", pubkey->key.dsa.g); 595 print_bn(0, "y", pubkey->key.dsa.y); 596 break; 597 598 case OPS_PKA_RSA: 599 case OPS_PKA_RSA_ENCRYPT_ONLY: 600 case OPS_PKA_RSA_SIGN_ONLY: 601 print_bn(0, "n", pubkey->key.rsa.n); 602 print_bn(0, "e", pubkey->key.rsa.e); 603 break; 604 605 case OPS_PKA_ELGAMAL: 606 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 607 print_bn(0, "p", pubkey->key.elgamal.p); 608 print_bn(0, "g", pubkey->key.elgamal.g); 609 print_bn(0, "y", pubkey->key.elgamal.y); 610 break; 611 612 default: 613 (void) fprintf(stderr, 614 "__ops_print_pubkey: Unusual algorithm\n"); 615 } 616 617 printf("------- end of PUBLIC KEY ------\n"); 618} 619 620int 621__ops_sprint_pubkey(const __ops_key_t *key, char *out, size_t outsize) 622{ 623 char fp[(OPS_FINGERPRINT_SIZE * 3) + 1]; 624 int cc; 625 626 cc = snprintf(out, outsize, "key:%s:%d:%lld:%lld:%d:\n", 627 strhexdump(fp, key->fingerprint.fingerprint, OPS_FINGERPRINT_SIZE, ""), 628 key->key.pubkey.version, 629 (long long)key->key.pubkey.birthtime, 630 (long long)key->key.pubkey.days_valid, 631 key->key.pubkey.alg); 632 switch (key->key.pubkey.alg) { 633 case OPS_PKA_DSA: 634 cc += snprintf(&out[cc], outsize - cc, 635 "pubkey:p=%s:q=%s:g=%s:y=%s\n", 636 BN_bn2hex(key->key.pubkey.key.dsa.p), 637 BN_bn2hex(key->key.pubkey.key.dsa.q), 638 BN_bn2hex(key->key.pubkey.key.dsa.g), 639 BN_bn2hex(key->key.pubkey.key.dsa.y)); 640 break; 641 case OPS_PKA_RSA: 642 case OPS_PKA_RSA_ENCRYPT_ONLY: 643 case OPS_PKA_RSA_SIGN_ONLY: 644 cc += snprintf(&out[cc], outsize - cc, 645 "pubkey:n=%s:e=%s\n", 646 BN_bn2hex(key->key.pubkey.key.rsa.n), 647 BN_bn2hex(key->key.pubkey.key.rsa.e)); 648 break; 649 case OPS_PKA_ELGAMAL: 650 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 651 cc += snprintf(&out[cc], outsize - cc, 652 "pubkey:p=%s:g=%s:y=%s\n", 653 BN_bn2hex(key->key.pubkey.key.elgamal.p), 654 BN_bn2hex(key->key.pubkey.key.elgamal.g), 655 BN_bn2hex(key->key.pubkey.key.elgamal.y)); 656 break; 657 default: 658 (void) fprintf(stderr, 659 "__ops_print_pubkey: Unusual algorithm\n"); 660 } 661 return cc; 662} 663 664/** 665\ingroup Core_Print 666\param type 667\param seckey 668*/ 669static void 670__ops_print_seckey_verbose(const __ops_content_tag_t type, 671 const __ops_seckey_t *seckey) 672{ 673 printf("------- SECRET KEY or ENCRYPTED SECRET KEY ------\n"); 674 print_tagname(0, (type == OPS_PTAG_CT_SECRET_KEY) ? 675 "SECRET_KEY" : 676 "ENCRYPTED_SECRET_KEY"); 677 /* __ops_print_pubkey(key); */ 678 printf("S2K Usage: %d\n", seckey->s2k_usage); 679 if (seckey->s2k_usage != OPS_S2KU_NONE) { 680 printf("S2K Specifier: %d\n", seckey->s2k_specifier); 681 printf("Symmetric algorithm: %d (%s)\n", seckey->alg, 682 __ops_show_symm_alg(seckey->alg)); 683 printf("Hash algorithm: %d (%s)\n", seckey->hash_alg, 684 __ops_show_hash_alg((uint8_t)seckey->hash_alg)); 685 if (seckey->s2k_specifier != OPS_S2KS_SIMPLE) { 686 print_hexdump(0, "Salt", seckey->salt, 687 sizeof(seckey->salt)); 688 } 689 if (seckey->s2k_specifier == OPS_S2KS_ITERATED_AND_SALTED) { 690 printf("Octet count: %u\n", seckey->octetc); 691 } 692 print_hexdump(0, "IV", seckey->iv, __ops_block_size(seckey->alg)); 693 } 694 /* no more set if encrypted */ 695 if (type == OPS_PTAG_CT_ENCRYPTED_SECRET_KEY) { 696 return; 697 } 698 switch (seckey->pubkey.alg) { 699 case OPS_PKA_RSA: 700 print_bn(0, "d", seckey->key.rsa.d); 701 print_bn(0, "p", seckey->key.rsa.p); 702 print_bn(0, "q", seckey->key.rsa.q); 703 print_bn(0, "u", seckey->key.rsa.u); 704 break; 705 706 case OPS_PKA_DSA: 707 print_bn(0, "x", seckey->key.dsa.x); 708 break; 709 710 default: 711 (void) fprintf(stderr, 712 "__ops_print_seckey_verbose: unusual algorithm\n"); 713 } 714 if (seckey->s2k_usage == OPS_S2KU_ENCRYPTED_AND_HASHED) { 715 print_hexdump(0, "Checkhash", seckey->checkhash, 716 OPS_CHECKHASH_SIZE); 717 } else { 718 printf("Checksum: %04x\n", seckey->checksum); 719 } 720 printf("------- end of SECRET KEY or ENCRYPTED SECRET KEY ------\n"); 721} 722 723 724/** 725\ingroup Core_Print 726\param tag 727\param key 728*/ 729static void 730__ops_print_pk_sesskey(__ops_content_tag_t tag, 731 const __ops_pk_sesskey_t * key) 732{ 733 print_tagname(0, (tag == OPS_PTAG_CT_PK_SESSION_KEY) ? 734 "PUBLIC KEY SESSION KEY" : 735 "ENCRYPTED PUBLIC KEY SESSION KEY"); 736 printf("Version: %d\n", key->version); 737 print_hexdump(0, "Key ID", key->key_id, sizeof(key->key_id)); 738 printf("Algorithm: %d (%s)\n", key->alg, 739 __ops_show_pka(key->alg)); 740 switch (key->alg) { 741 case OPS_PKA_RSA: 742 print_bn(0, "encrypted_m", key->params.rsa.encrypted_m); 743 break; 744 745 case OPS_PKA_ELGAMAL: 746 print_bn(0, "g_to_k", key->params.elgamal.g_to_k); 747 print_bn(0, "encrypted_m", key->params.elgamal.encrypted_m); 748 break; 749 750 default: 751 (void) fprintf(stderr, 752 "__ops_print_pk_sesskey: unusual algorithm\n"); 753 } 754 if (tag == OPS_PTAG_CT_PK_SESSION_KEY) { 755 printf("Symmetric algorithm: %d (%s)\n", key->symm_alg, 756 __ops_show_symm_alg(key->symm_alg)); 757 print_hexdump(0, "Key", key->key, __ops_key_size(key->symm_alg)); 758 printf("Checksum: %04x\n", key->checksum); 759 } 760} 761 762static void 763start_subpacket(int *indent, int type) 764{ 765 *indent += 1; 766 print_indent(*indent); 767 printf("-- %s (type 0x%02x)\n", 768 __ops_show_ss_type((__ops_ss_type_t)type), 769 type - OPS_PTAG_SIG_SUBPKT_BASE); 770} 771 772static void 773end_subpacket(int *indent) 774{ 775 *indent -= 1; 776} 777 778/** 779\ingroup Core_Print 780\param contents 781*/ 782int 783__ops_print_packet(__ops_printstate_t *print, const __ops_packet_t *pkt) 784{ 785 const __ops_contents_t *content = &pkt->u; 786 __ops_text_t *text; 787 const char *str; 788 789 if (print->unarmoured && pkt->tag != OPS_PTAG_CT_UNARMOURED_TEXT) { 790 print->unarmoured = 0; 791 puts("UNARMOURED TEXT ends"); 792 } 793 if (pkt->tag == OPS_PARSER_PTAG) { 794 printf("=> OPS_PARSER_PTAG: %s\n", 795 __ops_show_packet_tag((__ops_packet_tag_t)content->ptag.type)); 796 } else { 797 printf("=> %s\n", __ops_show_packet_tag(pkt->tag)); 798 } 799 800 switch (pkt->tag) { 801 case OPS_PARSER_ERROR: 802 printf("parse error: %s\n", content->error.error); 803 break; 804 805 case OPS_PARSER_ERRCODE: 806 printf("parse error: %s\n", 807 __ops_errcode(content->errcode.errcode)); 808 break; 809 810 case OPS_PARSER_PACKET_END: 811 print_packet_hex(&content->packet); 812 break; 813 814 case OPS_PARSER_PTAG: 815 if (content->ptag.type == OPS_PTAG_CT_PUBLIC_KEY) { 816 print->indent = 0; 817 printf("\n*** NEXT KEY ***\n"); 818 } 819 printf("\n"); 820 print_indent(print->indent); 821 printf("==== ptag new_format=%u type=%u length_type=%d" 822 " length=0x%x (%u) position=0x%x (%u)\n", 823 content->ptag.new_format, 824 content->ptag.type, content->ptag.length_type, 825 content->ptag.length, content->ptag.length, 826 content->ptag.position, content->ptag.position); 827 print_tagname(print->indent, __ops_show_packet_tag((__ops_packet_tag_t)content->ptag.type)); 828 break; 829 830 case OPS_PTAG_CT_SE_DATA_HEADER: 831 print_tagname(print->indent, "SYMMETRIC ENCRYPTED DATA"); 832 break; 833 834 case OPS_PTAG_CT_SE_IP_DATA_HEADER: 835 print_tagname(print->indent, 836 "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER"); 837 printf("Version: %d\n", content->se_ip_data_header.version); 838 break; 839 840 case OPS_PTAG_CT_SE_IP_DATA_BODY: 841 print_tagname(print->indent, 842 "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY"); 843 printf(" data body length=%u\n", 844 content->se_data_body.length); 845 printf(" data="); 846 hexdump(stdout, content->se_data_body.data, 847 content->se_data_body.length, ""); 848 printf("\n"); 849 break; 850 851 case OPS_PTAG_CT_PUBLIC_KEY: 852 case OPS_PTAG_CT_PUBLIC_SUBKEY: 853 print_tagname(print->indent, (pkt->tag == OPS_PTAG_CT_PUBLIC_KEY) ? 854 "PUBLIC KEY" : 855 "PUBLIC SUBKEY"); 856 __ops_print_pubkey(&content->pubkey); 857 break; 858 859 case OPS_PTAG_CT_TRUST: 860 print_tagname(print->indent, "TRUST"); 861 print_data(print->indent, "Trust", &content->trust.data); 862 break; 863 864 case OPS_PTAG_CT_USER_ID: 865 print_tagname(print->indent, "USER ID"); 866 print_utf8_string(print->indent, "userid", content->userid.userid); 867 break; 868 869 case OPS_PTAG_CT_SIGNATURE: 870 print_tagname(print->indent, "SIGNATURE"); 871 print_indent(print->indent); 872 print_uint(print->indent, "Signature Version", 873 (unsigned)content->sig.info.version); 874 if (content->sig.info.birthtime_set) { 875 print_time(print->indent, "Signature Creation Time", 876 content->sig.info.birthtime); 877 } 878 if (content->sig.info.duration_set) { 879 print_uint(print->indent, "Signature Duration", 880 (unsigned)content->sig.info.duration); 881 } 882 883 print_string_and_value(print->indent, "Signature Type", 884 __ops_show_sig_type(content->sig.info.type), 885 content->sig.info.type); 886 887 if (content->sig.info.signer_id_set) { 888 hexdump_data(print->indent, "Signer ID", 889 content->sig.info.signer_id, 890 sizeof(content->sig.info.signer_id)); 891 } 892 893 print_string_and_value(print->indent, "Public Key Algorithm", 894 __ops_show_pka(content->sig.info.key_alg), 895 content->sig.info.key_alg); 896 print_string_and_value(print->indent, "Hash Algorithm", 897 __ops_show_hash_alg((uint8_t) 898 content->sig.info.hash_alg), 899 (uint8_t)content->sig.info.hash_alg); 900 print_uint(print->indent, "Hashed data len", 901 content->sig.info.v4_hashlen); 902 print_indent(print->indent); 903 hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2); 904 switch (content->sig.info.key_alg) { 905 case OPS_PKA_RSA: 906 case OPS_PKA_RSA_SIGN_ONLY: 907 print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig); 908 break; 909 910 case OPS_PKA_DSA: 911 print_bn(print->indent, "r", content->sig.info.sig.dsa.r); 912 print_bn(print->indent, "s", content->sig.info.sig.dsa.s); 913 break; 914 915 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 916 print_bn(print->indent, "r", content->sig.info.sig.elgamal.r); 917 print_bn(print->indent, "s", content->sig.info.sig.elgamal.s); 918 break; 919 920 default: 921 (void) fprintf(stderr, 922 "__ops_print_packet: Unusual algorithm\n"); 923 return 0; 924 } 925 926 if (content->sig.hash) 927 printf("data hash is set\n"); 928 929 break; 930 931 case OPS_PTAG_CT_COMPRESSED: 932 print_tagname(print->indent, "COMPRESSED"); 933 print_uint(print->indent, "Compressed Data Type", 934 (unsigned)content->compressed.type); 935 break; 936 937 case OPS_PTAG_CT_1_PASS_SIG: 938 print_tagname(print->indent, "ONE PASS SIGNATURE"); 939 940 print_uint(print->indent, "Version", (unsigned)content->one_pass_sig.version); 941 print_string_and_value(print->indent, "Signature Type", 942 __ops_show_sig_type(content->one_pass_sig.sig_type), 943 content->one_pass_sig.sig_type); 944 print_string_and_value(print->indent, "Hash Algorithm", 945 __ops_show_hash_alg((uint8_t)content->one_pass_sig.hash_alg), 946 (uint8_t)content->one_pass_sig.hash_alg); 947 print_string_and_value(print->indent, "Public Key Algorithm", 948 __ops_show_pka(content->one_pass_sig.key_alg), 949 content->one_pass_sig.key_alg); 950 hexdump_data(print->indent, "Signer ID", 951 content->one_pass_sig.keyid, 952 sizeof(content->one_pass_sig.keyid)); 953 print_uint(print->indent, "Nested", content->one_pass_sig.nested); 954 break; 955 956 case OPS_PTAG_CT_USER_ATTR: 957 print_tagname(print->indent, "USER ATTRIBUTE"); 958 print_hexdump(print->indent, "User Attribute", 959 content->userattr.data.contents, 960 content->userattr.data.len); 961 break; 962 963 case OPS_PTAG_RAW_SS: 964 if (pkt->critical) { 965 (void) fprintf(stderr, "contents are critical\n"); 966 return 0; 967 } 968 start_subpacket(&print->indent, pkt->tag); 969 print_uint(print->indent, "Raw Signature Subpacket: tag", 970 (unsigned)(content->ss_raw.tag - 971 (unsigned)OPS_PTAG_SIG_SUBPKT_BASE)); 972 print_hexdump(print->indent, "Raw Data", 973 content->ss_raw.raw, 974 content->ss_raw.length); 975 break; 976 977 case OPS_PTAG_SS_CREATION_TIME: 978 start_subpacket(&print->indent, pkt->tag); 979 print_time(print->indent, "Signature Creation Time", content->ss_time.time); 980 end_subpacket(&print->indent); 981 break; 982 983 case OPS_PTAG_SS_EXPIRATION_TIME: 984 start_subpacket(&print->indent, pkt->tag); 985 print_duration(print->indent, "Signature Expiration Time", 986 content->ss_time.time); 987 end_subpacket(&print->indent); 988 break; 989 990 case OPS_PTAG_SS_KEY_EXPIRY: 991 start_subpacket(&print->indent, pkt->tag); 992 print_duration(print->indent, "Key Expiration Time", content->ss_time.time); 993 end_subpacket(&print->indent); 994 break; 995 996 case OPS_PTAG_SS_TRUST: 997 start_subpacket(&print->indent, pkt->tag); 998 print_string(print->indent, "Trust Signature", ""); 999 print_uint(print->indent, "Level", (unsigned)content->ss_trust.level); 1000 print_uint(print->indent, "Amount", (unsigned)content->ss_trust.amount); 1001 end_subpacket(&print->indent); 1002 break; 1003 1004 case OPS_PTAG_SS_REVOCABLE: 1005 start_subpacket(&print->indent, pkt->tag); 1006 print_boolean(print->indent, "Revocable", content->ss_revocable.revocable); 1007 end_subpacket(&print->indent); 1008 break; 1009 1010 case OPS_PTAG_SS_REVOCATION_KEY: 1011 start_subpacket(&print->indent, pkt->tag); 1012 /* not yet tested */ 1013 printf(" revocation key: class=0x%x", 1014 content->ss_revocation_key.class); 1015 if (content->ss_revocation_key.class & 0x40) { 1016 printf(" (sensitive)"); 1017 } 1018 printf(", algid=0x%x", content->ss_revocation_key.algid); 1019 printf(", fingerprint="); 1020 hexdump(stdout, content->ss_revocation_key.fingerprint, 1021 OPS_FINGERPRINT_SIZE, ""); 1022 printf("\n"); 1023 end_subpacket(&print->indent); 1024 break; 1025 1026 case OPS_PTAG_SS_ISSUER_KEY_ID: 1027 start_subpacket(&print->indent, pkt->tag); 1028 print_hexdump(print->indent, "Issuer Key Id", 1029 &content->ss_issuer.key_id[0], 1030 sizeof(content->ss_issuer.key_id)); 1031 end_subpacket(&print->indent); 1032 break; 1033 1034 case OPS_PTAG_SS_PREFERRED_SKA: 1035 start_subpacket(&print->indent, pkt->tag); 1036 print_data(print->indent, "Preferred Symmetric Algorithms", 1037 &content->ss_skapref.data); 1038 1039 text = __ops_showall_ss_skapref(content->ss_skapref); 1040 print_text_breakdown(print->indent, text); 1041 __ops_text_free(text); 1042 1043 end_subpacket(&print->indent); 1044 break; 1045 1046 case OPS_PTAG_SS_PRIMARY_USER_ID: 1047 start_subpacket(&print->indent, pkt->tag); 1048 print_boolean(print->indent, "Primary User ID", 1049 content->ss_primary_userid.primary_userid); 1050 end_subpacket(&print->indent); 1051 break; 1052 1053 case OPS_PTAG_SS_PREFERRED_HASH: 1054 start_subpacket(&print->indent, pkt->tag); 1055 print_data(print->indent, "Preferred Hash Algorithms", 1056 &content->ss_hashpref.data); 1057 1058 text = __ops_showall_ss_hashpref(content->ss_hashpref); 1059 print_text_breakdown(print->indent, text); 1060 __ops_text_free(text); 1061 end_subpacket(&print->indent); 1062 break; 1063 1064 case OPS_PTAG_SS_PREF_COMPRESS: 1065 start_subpacket(&print->indent, pkt->tag); 1066 print_data(print->indent, "Preferred Compression Algorithms", 1067 &content->ss_zpref.data); 1068 1069 text = __ops_showall_ss_zpref(content->ss_zpref); 1070 print_text_breakdown(print->indent, text); 1071 __ops_text_free(text); 1072 end_subpacket(&print->indent); 1073 break; 1074 1075 case OPS_PTAG_SS_KEY_FLAGS: 1076 start_subpacket(&print->indent, pkt->tag); 1077 print_data(print->indent, "Key Flags", &content->ss_key_flags.data); 1078 1079 text = __ops_showall_ss_key_flags(content->ss_key_flags); 1080 print_text_breakdown(print->indent, text); 1081 __ops_text_free(text); 1082 1083 end_subpacket(&print->indent); 1084 break; 1085 1086 case OPS_PTAG_SS_KEYSERV_PREFS: 1087 start_subpacket(&print->indent, pkt->tag); 1088 print_data(print->indent, "Key Server Preferences", 1089 &content->ss_key_server_prefs.data); 1090 1091 text = __ops_show_keyserv_prefs(content->ss_key_server_prefs); 1092 print_text_breakdown(print->indent, text); 1093 __ops_text_free(text); 1094 1095 end_subpacket(&print->indent); 1096 break; 1097 1098 case OPS_PTAG_SS_FEATURES: 1099 start_subpacket(&print->indent, pkt->tag); 1100 print_data(print->indent, "Features", 1101 &content->ss_features.data); 1102 1103 text = __ops_showall_ss_features(content->ss_features); 1104 print_text_breakdown(print->indent, text); 1105 __ops_text_free(text); 1106 1107 end_subpacket(&print->indent); 1108 break; 1109 1110 case OPS_PTAG_SS_NOTATION_DATA: 1111 start_subpacket(&print->indent, pkt->tag); 1112 print_indent(print->indent); 1113 printf("Notation Data:\n"); 1114 1115 print->indent++; 1116 print_data(print->indent, "Flags", &content->ss_notation.flags); 1117 text = __ops_showall_notation(content->ss_notation); 1118 print_text_breakdown(print->indent, text); 1119 __ops_text_free(text); 1120 1121 print_data(print->indent, "Name", &content->ss_notation.name); 1122 1123 print_data(print->indent, "Value", &content->ss_notation.value); 1124 1125 print->indent--; 1126 end_subpacket(&print->indent); 1127 break; 1128 1129 case OPS_PTAG_SS_REGEXP: 1130 start_subpacket(&print->indent, pkt->tag); 1131 print_hexdump(print->indent, "Regular Expression", 1132 (uint8_t *) content->ss_regexp.regexp, 1133 strlen(content->ss_regexp.regexp)); 1134 print_string(print->indent, NULL, content->ss_regexp.regexp); 1135 end_subpacket(&print->indent); 1136 break; 1137 1138 case OPS_PTAG_SS_POLICY_URI: 1139 start_subpacket(&print->indent, pkt->tag); 1140 print_string(print->indent, "Policy URL", content->ss_policy.url); 1141 end_subpacket(&print->indent); 1142 break; 1143 1144 case OPS_PTAG_SS_SIGNERS_USER_ID: 1145 start_subpacket(&print->indent, pkt->tag); 1146 print_utf8_string(print->indent, "Signer's User ID", 1147 content->ss_signer.userid); 1148 end_subpacket(&print->indent); 1149 break; 1150 1151 case OPS_PTAG_SS_PREF_KEYSERV: 1152 start_subpacket(&print->indent, pkt->tag); 1153 print_string(print->indent, "Preferred Key Server", content->ss_keyserv.name); 1154 end_subpacket(&print->indent); 1155 break; 1156 1157 case OPS_PTAG_SS_EMBEDDED_SIGNATURE: 1158 start_subpacket(&print->indent, pkt->tag); 1159 end_subpacket(&print->indent);/* \todo print out contents? */ 1160 break; 1161 1162 case OPS_PTAG_SS_USERDEFINED00: 1163 case OPS_PTAG_SS_USERDEFINED01: 1164 case OPS_PTAG_SS_USERDEFINED02: 1165 case OPS_PTAG_SS_USERDEFINED03: 1166 case OPS_PTAG_SS_USERDEFINED04: 1167 case OPS_PTAG_SS_USERDEFINED05: 1168 case OPS_PTAG_SS_USERDEFINED06: 1169 case OPS_PTAG_SS_USERDEFINED07: 1170 case OPS_PTAG_SS_USERDEFINED08: 1171 case OPS_PTAG_SS_USERDEFINED09: 1172 case OPS_PTAG_SS_USERDEFINED10: 1173 start_subpacket(&print->indent, pkt->tag); 1174 print_hexdump(print->indent, "Internal or user-defined", 1175 content->ss_userdef.data.contents, 1176 content->ss_userdef.data.len); 1177 end_subpacket(&print->indent); 1178 break; 1179 1180 case OPS_PTAG_SS_RESERVED: 1181 start_subpacket(&print->indent, pkt->tag); 1182 print_hexdump(print->indent, "Reserved", 1183 content->ss_userdef.data.contents, 1184 content->ss_userdef.data.len); 1185 end_subpacket(&print->indent); 1186 break; 1187 1188 case OPS_PTAG_SS_REVOCATION_REASON: 1189 start_subpacket(&print->indent, pkt->tag); 1190 print_hexdump(print->indent, "Revocation Reason", 1191 &content->ss_revocation.code, 1192 1); 1193 str = __ops_show_ss_rr_code(content->ss_revocation.code); 1194 print_string(print->indent, NULL, str); 1195 end_subpacket(&print->indent); 1196 break; 1197 1198 case OPS_PTAG_CT_LITDATA_HEADER: 1199 print_tagname(print->indent, "LITERAL DATA HEADER"); 1200 printf(" literal data header format=%c filename='%s'\n", 1201 content->litdata_header.format, 1202 content->litdata_header.filename); 1203 showtime(" modification time", 1204 content->litdata_header.mtime); 1205 printf("\n"); 1206 break; 1207 1208 case OPS_PTAG_CT_LITDATA_BODY: 1209 print_tagname(print->indent, "LITERAL DATA BODY"); 1210 printf(" literal data body length=%u\n", 1211 content->litdata_body.length); 1212 printf(" data="); 1213 print_escaped(content->litdata_body.data, 1214 content->litdata_body.length); 1215 printf("\n"); 1216 break; 1217 1218 case OPS_PTAG_CT_SIGNATURE_HEADER: 1219 print_tagname(print->indent, "SIGNATURE"); 1220 print_indent(print->indent); 1221 print_uint(print->indent, "Signature Version", 1222 (unsigned)content->sig.info.version); 1223 if (content->sig.info.birthtime_set) { 1224 print_time(print->indent, "Signature Creation Time", 1225 content->sig.info.birthtime); 1226 } 1227 if (content->sig.info.duration_set) { 1228 print_uint(print->indent, "Signature Duration", 1229 (unsigned)content->sig.info.duration); 1230 } 1231 print_string_and_value(print->indent, "Signature Type", 1232 __ops_show_sig_type(content->sig.info.type), 1233 content->sig.info.type); 1234 if (content->sig.info.signer_id_set) { 1235 hexdump_data(print->indent, "Signer ID", 1236 content->sig.info.signer_id, 1237 sizeof(content->sig.info.signer_id)); 1238 } 1239 print_string_and_value(print->indent, "Public Key Algorithm", 1240 __ops_show_pka(content->sig.info.key_alg), 1241 content->sig.info.key_alg); 1242 print_string_and_value(print->indent, "Hash Algorithm", 1243 __ops_show_hash_alg((uint8_t)content->sig.info.hash_alg), 1244 (uint8_t)content->sig.info.hash_alg); 1245 print_uint(print->indent, "Hashed data len", 1246 content->sig.info.v4_hashlen); 1247 1248 break; 1249 1250 case OPS_PTAG_CT_SIGNATURE_FOOTER: 1251 print_indent(print->indent); 1252 hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2); 1253 1254 switch (content->sig.info.key_alg) { 1255 case OPS_PKA_RSA: 1256 print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig); 1257 break; 1258 1259 case OPS_PKA_DSA: 1260 print_bn(print->indent, "r", content->sig.info.sig.dsa.r); 1261 print_bn(print->indent, "s", content->sig.info.sig.dsa.s); 1262 break; 1263 1264 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 1265 print_bn(print->indent, "r", content->sig.info.sig.elgamal.r); 1266 print_bn(print->indent, "s", content->sig.info.sig.elgamal.s); 1267 break; 1268 1269 case OPS_PKA_PRIVATE00: 1270 case OPS_PKA_PRIVATE01: 1271 case OPS_PKA_PRIVATE02: 1272 case OPS_PKA_PRIVATE03: 1273 case OPS_PKA_PRIVATE04: 1274 case OPS_PKA_PRIVATE05: 1275 case OPS_PKA_PRIVATE06: 1276 case OPS_PKA_PRIVATE07: 1277 case OPS_PKA_PRIVATE08: 1278 case OPS_PKA_PRIVATE09: 1279 case OPS_PKA_PRIVATE10: 1280 print_data(print->indent, "Private/Experimental", 1281 &content->sig.info.sig.unknown.data); 1282 break; 1283 1284 default: 1285 (void) fprintf(stderr, 1286 "__ops_print_packet: Unusual key algorithm\n"); 1287 return 0; 1288 } 1289 break; 1290 1291 case OPS_GET_PASSPHRASE: 1292 print_tagname(print->indent, "OPS_GET_PASSPHRASE"); 1293 break; 1294 1295 case OPS_PTAG_CT_SECRET_KEY: 1296 print_tagname(print->indent, "OPS_PTAG_CT_SECRET_KEY"); 1297 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1298 break; 1299 1300 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 1301 print_tagname(print->indent, "OPS_PTAG_CT_ENCRYPTED_SECRET_KEY"); 1302 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1303 break; 1304 1305 case OPS_PTAG_CT_ARMOUR_HEADER: 1306 print_tagname(print->indent, "ARMOUR HEADER"); 1307 print_string(print->indent, "type", content->armour_header.type); 1308 break; 1309 1310 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 1311 print_tagname(print->indent, "SIGNED CLEARTEXT HEADER"); 1312 print_headers(&content->cleartext_head.headers); 1313 break; 1314 1315 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: 1316 print_tagname(print->indent, "SIGNED CLEARTEXT BODY"); 1317 print_block(print->indent, "signed cleartext", content->cleartext_body.data, 1318 content->cleartext_body.length); 1319 break; 1320 1321 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 1322 print_tagname(print->indent, "SIGNED CLEARTEXT TRAILER"); 1323 printf("hash algorithm: %d\n", 1324 content->cleartext_trailer.hash->alg); 1325 printf("\n"); 1326 break; 1327 1328 case OPS_PTAG_CT_UNARMOURED_TEXT: 1329 if (!print->unarmoured) { 1330 print_tagname(print->indent, "UNARMOURED TEXT"); 1331 print->unarmoured = 1; 1332 } 1333 putchar('['); 1334 print_escaped(content->unarmoured_text.data, 1335 content->unarmoured_text.length); 1336 putchar(']'); 1337 break; 1338 1339 case OPS_PTAG_CT_ARMOUR_TRAILER: 1340 print_tagname(print->indent, "ARMOUR TRAILER"); 1341 print_string(print->indent, "type", content->armour_header.type); 1342 break; 1343 1344 case OPS_PTAG_CT_PK_SESSION_KEY: 1345 case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: 1346 __ops_print_pk_sesskey(pkt->tag, &content->pk_sesskey); 1347 break; 1348 1349 case OPS_GET_SECKEY: 1350 __ops_print_pk_sesskey(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, 1351 content->get_seckey.pk_sesskey); 1352 break; 1353 1354 default: 1355 print_tagname(print->indent, "UNKNOWN PACKET TYPE"); 1356 fprintf(stderr, "__ops_print_packet: unknown tag=%d (0x%x)\n", 1357 pkt->tag, pkt->tag); 1358 exit(EXIT_FAILURE); 1359 } 1360 return 1; 1361} 1362 1363static __ops_cb_ret_t 1364cb_list_packets(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 1365{ 1366 __ops_print_packet(&cbinfo->printstate, pkt); 1367 return OPS_RELEASE_MEMORY; 1368} 1369 1370/** 1371\ingroup Core_Print 1372\param filename 1373\param armour 1374\param keyring 1375\param cb_get_passphrase 1376*/ 1377int 1378__ops_list_packets(__ops_io_t *io, 1379 char *filename, 1380 unsigned armour, 1381 __ops_keyring_t *secring, 1382 __ops_keyring_t *pubring, 1383 void *passfp, 1384 __ops_cbfunc_t *cb_get_passphrase) 1385{ 1386 __ops_stream_t *stream = NULL; 1387 const unsigned accumulate = 1; 1388 const int printerrors = 1; 1389 int fd; 1390 1391 fd = __ops_setup_file_read(io, &stream, filename, NULL, cb_list_packets, 1392 accumulate); 1393 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 1394 stream->cryptinfo.secring = secring; 1395 stream->cryptinfo.pubring = pubring; 1396 stream->cbinfo.passfp = passfp; 1397 stream->cryptinfo.getpassphrase = cb_get_passphrase; 1398 if (armour) { 1399 __ops_reader_push_dearmour(stream); 1400 } 1401 __ops_parse(stream, printerrors); 1402 __ops_teardown_file_read(stream, fd); 1403 return 1; 1404} 1405