packet-print.c revision 1.25
1287759Sgnn/*- 2287759Sgnn * Copyright (c) 2009 The NetBSD Foundation, Inc. 3287759Sgnn * All rights reserved. 4287759Sgnn * 5287759Sgnn * This code is derived from software contributed to The NetBSD Foundation 6287759Sgnn * by Alistair Crooks (agc@NetBSD.org) 7287759Sgnn * 8287759Sgnn * Redistribution and use in source and binary forms, with or without 9287759Sgnn * modification, are permitted provided that the following conditions 10287759Sgnn * are met: 11287759Sgnn * 1. Redistributions of source code must retain the above copyright 12287759Sgnn * notice, this list of conditions and the following disclaimer. 13287759Sgnn * 2. Redistributions in binary form must reproduce the above copyright 14287759Sgnn * notice, this list of conditions and the following disclaimer in the 15287759Sgnn * documentation and/or other materials provided with the distribution. 16287759Sgnn * 17287759Sgnn * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 18287759Sgnn * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 19287759Sgnn * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 20287759Sgnn * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 21287759Sgnn * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 22287759Sgnn * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 23287759Sgnn * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 24287759Sgnn * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 25287759Sgnn * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26287759Sgnn * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 27287759Sgnn * POSSIBILITY OF SUCH DAMAGE. 28287759Sgnn */ 29287759Sgnn/* 30287759Sgnn * Copyright (c) 2005-2008 Nominet UK (www.nic.uk) 31287759Sgnn * All rights reserved. 32287759Sgnn * Contributors: Ben Laurie, Rachel Willmer. The Contributors have asserted 33287759Sgnn * their moral rights under the UK Copyright Design and Patents Act 1988 to 34287759Sgnn * be recorded as the authors of this copyright work. 35287759Sgnn * 36287759Sgnn * Licensed under the Apache License, Version 2.0 (the "License"); you may not 37287759Sgnn * use this file except in compliance with the License. 38287759Sgnn * 39287759Sgnn * You may obtain a copy of the License at 40287759Sgnn * http://www.apache.org/licenses/LICENSE-2.0 41287759Sgnn * 42287759Sgnn * Unless required by applicable law or agreed to in writing, software 43287759Sgnn * distributed under the License is distributed on an "AS IS" BASIS, 44287759Sgnn * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 45287759Sgnn * 46287759Sgnn * See the License for the specific language governing permissions and 47287759Sgnn * limitations under the License. 48287759Sgnn */ 49287759Sgnn 50287759Sgnn/* 51287759Sgnn * ! \file \brief Standard API print functions 52287759Sgnn */ 53287759Sgnn#include "config.h" 54287759Sgnn 55287759Sgnn#ifdef HAVE_SYS_CDEFS_H 56287759Sgnn#include <sys/cdefs.h> 57287759Sgnn#endif 58287759Sgnn 59287759Sgnn#if defined(__NetBSD__) 60287759Sgnn__COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 61287759Sgnn__RCSID("$NetBSD: packet-print.c,v 1.25 2010/02/08 17:19:12 agc Exp $"); 62287759Sgnn#endif 63287759Sgnn 64287759Sgnn#include <string.h> 65287759Sgnn#include <stdio.h> 66287759Sgnn 67287759Sgnn#ifdef HAVE_UNISTD_H 68287759Sgnn#include <unistd.h> 69287759Sgnn#endif 70287759Sgnn 71287759Sgnn#include "crypto.h" 72287759Sgnn#include "keyring.h" 73287759Sgnn#include "packet-show.h" 74287759Sgnn#include "signature.h" 75287759Sgnn#include "readerwriter.h" 76287759Sgnn#include "netpgpdefs.h" 77287759Sgnn#include "netpgpsdk.h" 78287759Sgnn#include "packet.h" 79287759Sgnn#include "netpgpdigest.h" 80287759Sgnn 81287759Sgnn/* static functions */ 82287759Sgnn 83287759Sgnnstatic void 84287759Sgnnprint_indent(int indent) 85287759Sgnn{ 86296335Sgnn int i; 87296335Sgnn 88287759Sgnn for (i = 0; i < indent; i++) { 89287759Sgnn printf(" "); 90287759Sgnn } 91287759Sgnn} 92287759Sgnn 93287759Sgnnstatic void 94287759Sgnnprint_name(int indent, const char *name) 95287759Sgnn{ 96287759Sgnn print_indent(indent); 97287759Sgnn if (name) { 98287759Sgnn printf("%s: ", name); 99287759Sgnn } 100287759Sgnn} 101287759Sgnn 102287759Sgnnstatic void 103287759Sgnnprint_hexdump(int indent, const char *name, const unsigned char *data, unsigned int len) 104287759Sgnn{ 105287759Sgnn print_name(indent, name); 106287759Sgnn 107287759Sgnn printf("len=%u, data=0x", len); 108287759Sgnn hexdump(stdout, data, len, ""); 109287759Sgnn printf("\n"); 110287759Sgnn} 111287759Sgnn 112287759Sgnnstatic void 113287759Sgnnhexdump_data(int indent, const char *name, const unsigned char *data, unsigned len) 114287759Sgnn{ 115287759Sgnn print_name(indent, name); 116287759Sgnn 117287759Sgnn printf("0x"); 118287759Sgnn hexdump(stdout, data, len, ""); 119287759Sgnn printf("\n"); 120287759Sgnn} 121287759Sgnn 122287759Sgnnstatic void 123287759Sgnnprint_uint(int indent, const char *name, unsigned int val) 124296335Sgnn{ 125296335Sgnn print_name(indent, name); 126287759Sgnn printf("%u\n", val); 127287759Sgnn} 128287759Sgnn 129287759Sgnnstatic void 130287759Sgnnshowtime(const char *name, time_t t) 131287759Sgnn{ 132287759Sgnn printf("%s=%" PRItime "d (%.24s)", name, (long long) t, ctime(&t)); 133287759Sgnn} 134287759Sgnn 135287759Sgnnstatic void 136287759Sgnnprint_time(int indent, const char *name, time_t t) 137287759Sgnn{ 138287759Sgnn print_indent(indent); 139287759Sgnn printf("%s: ", name); 140287759Sgnn showtime("time", t); 141287759Sgnn printf("\n"); 142287759Sgnn} 143287759Sgnn 144287759Sgnnstatic void 145287759Sgnnprint_string_and_value(int indent, const char *name, const char *str, unsigned char value) 146287759Sgnn{ 147287759Sgnn print_name(indent, name); 148287759Sgnn printf("%s (0x%x)\n", str, value); 149287759Sgnn} 150287759Sgnn 151287759Sgnnstatic void 152287759Sgnnprint_tagname(int indent, const char *str) 153287759Sgnn{ 154287759Sgnn print_indent(indent); 155287759Sgnn printf("%s packet\n", str); 156287759Sgnn} 157287759Sgnn 158287759Sgnnstatic void 159287759Sgnnprint_data(int indent, const char *name, const __ops_data_t *data) 160287759Sgnn{ 161287759Sgnn print_hexdump(indent, name, data->contents, data->len); 162287759Sgnn} 163287759Sgnn 164287759Sgnnstatic void 165287759Sgnnprint_bn(int indent, const char *name, const BIGNUM *bn) 166287759Sgnn{ 167287759Sgnn 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(__ops_printstate_t *print, const __ops_packet_t *pkt) 662{ 663 const __ops_contents_t *content = &pkt->u; 664 __ops_text_t *text; 665 const char *str; 666 667 if (print->unarmoured && pkt->tag != OPS_PTAG_CT_UNARMOURED_TEXT) { 668 print->unarmoured = 0; 669 puts("UNARMOURED TEXT ends"); 670 } 671 if (pkt->tag == OPS_PARSER_PTAG) { 672 printf("=> OPS_PARSER_PTAG: %s\n", 673 __ops_show_packet_tag((__ops_packet_tag_t)content->ptag.type)); 674 } else { 675 printf("=> %s\n", __ops_show_packet_tag(pkt->tag)); 676 } 677 678 switch (pkt->tag) { 679 case OPS_PARSER_ERROR: 680 printf("parse error: %s\n", content->error.error); 681 break; 682 683 case OPS_PARSER_ERRCODE: 684 printf("parse error: %s\n", 685 __ops_errcode(content->errcode.errcode)); 686 break; 687 688 case OPS_PARSER_PACKET_END: 689 print_packet_hex(&content->packet); 690 break; 691 692 case OPS_PARSER_PTAG: 693 if (content->ptag.type == OPS_PTAG_CT_PUBLIC_KEY) { 694 print->indent = 0; 695 printf("\n*** NEXT KEY ***\n"); 696 } 697 printf("\n"); 698 print_indent(print->indent); 699 printf("==== ptag new_format=%u type=%u length_type=%d" 700 " length=0x%x (%u) position=0x%x (%u)\n", 701 content->ptag.new_format, 702 content->ptag.type, content->ptag.length_type, 703 content->ptag.length, content->ptag.length, 704 content->ptag.position, content->ptag.position); 705 print_tagname(print->indent, __ops_show_packet_tag((__ops_packet_tag_t)content->ptag.type)); 706 break; 707 708 case OPS_PTAG_CT_SE_DATA_HEADER: 709 print_tagname(print->indent, "SYMMETRIC ENCRYPTED DATA"); 710 break; 711 712 case OPS_PTAG_CT_SE_IP_DATA_HEADER: 713 print_tagname(print->indent, 714 "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA HEADER"); 715 printf("Version: %d\n", content->se_ip_data_header.version); 716 break; 717 718 case OPS_PTAG_CT_SE_IP_DATA_BODY: 719 print_tagname(print->indent, 720 "SYMMETRIC ENCRYPTED INTEGRITY PROTECTED DATA BODY"); 721 printf(" data body length=%u\n", 722 content->se_data_body.length); 723 printf(" data="); 724 hexdump(stdout, content->se_data_body.data, 725 content->se_data_body.length, ""); 726 printf("\n"); 727 break; 728 729 case OPS_PTAG_CT_PUBLIC_KEY: 730 case OPS_PTAG_CT_PUBLIC_SUBKEY: 731 print_tagname(print->indent, (pkt->tag == OPS_PTAG_CT_PUBLIC_KEY) ? 732 "PUBLIC KEY" : 733 "PUBLIC SUBKEY"); 734 __ops_print_pubkey(&content->pubkey); 735 break; 736 737 case OPS_PTAG_CT_TRUST: 738 print_tagname(print->indent, "TRUST"); 739 print_data(print->indent, "Trust", &content->trust.data); 740 break; 741 742 case OPS_PTAG_CT_USER_ID: 743 print_tagname(print->indent, "USER ID"); 744 print_utf8_string(print->indent, "userid", content->userid.userid); 745 break; 746 747 case OPS_PTAG_CT_SIGNATURE: 748 print_tagname(print->indent, "SIGNATURE"); 749 print_indent(print->indent); 750 print_uint(print->indent, "Signature Version", 751 (unsigned)content->sig.info.version); 752 if (content->sig.info.birthtime_set) { 753 print_time(print->indent, "Signature Creation Time", 754 content->sig.info.birthtime); 755 } 756 if (content->sig.info.duration_set) { 757 print_uint(print->indent, "Signature Duration", 758 (unsigned)content->sig.info.duration); 759 } 760 761 print_string_and_value(print->indent, "Signature Type", 762 __ops_show_sig_type(content->sig.info.type), 763 content->sig.info.type); 764 765 if (content->sig.info.signer_id_set) { 766 hexdump_data(print->indent, "Signer ID", 767 content->sig.info.signer_id, 768 sizeof(content->sig.info.signer_id)); 769 } 770 771 print_string_and_value(print->indent, "Public Key Algorithm", 772 __ops_show_pka(content->sig.info.key_alg), 773 content->sig.info.key_alg); 774 print_string_and_value(print->indent, "Hash Algorithm", 775 __ops_show_hash_alg((unsigned char) 776 content->sig.info.hash_alg), 777 (unsigned char)content->sig.info.hash_alg); 778 print_uint(print->indent, "Hashed data len", 779 content->sig.info.v4_hashlen); 780 print_indent(print->indent); 781 hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2); 782 switch (content->sig.info.key_alg) { 783 case OPS_PKA_RSA: 784 case OPS_PKA_RSA_SIGN_ONLY: 785 print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig); 786 break; 787 788 case OPS_PKA_DSA: 789 print_bn(print->indent, "r", content->sig.info.sig.dsa.r); 790 print_bn(print->indent, "s", content->sig.info.sig.dsa.s); 791 break; 792 793 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 794 print_bn(print->indent, "r", content->sig.info.sig.elgamal.r); 795 print_bn(print->indent, "s", content->sig.info.sig.elgamal.s); 796 break; 797 798 default: 799 (void) fprintf(stderr, 800 "__ops_print_packet: Unusual algorithm\n"); 801 return 0; 802 } 803 804 if (content->sig.hash) 805 printf("data hash is set\n"); 806 807 break; 808 809 case OPS_PTAG_CT_COMPRESSED: 810 print_tagname(print->indent, "COMPRESSED"); 811 print_uint(print->indent, "Compressed Data Type", 812 (unsigned)content->compressed.type); 813 break; 814 815 case OPS_PTAG_CT_1_PASS_SIG: 816 print_tagname(print->indent, "ONE PASS SIGNATURE"); 817 818 print_uint(print->indent, "Version", (unsigned)content->one_pass_sig.version); 819 print_string_and_value(print->indent, "Signature Type", 820 __ops_show_sig_type(content->one_pass_sig.sig_type), 821 content->one_pass_sig.sig_type); 822 print_string_and_value(print->indent, "Hash Algorithm", 823 __ops_show_hash_alg((unsigned char)content->one_pass_sig.hash_alg), 824 (unsigned char)content->one_pass_sig.hash_alg); 825 print_string_and_value(print->indent, "Public Key Algorithm", 826 __ops_show_pka(content->one_pass_sig.key_alg), 827 content->one_pass_sig.key_alg); 828 hexdump_data(print->indent, "Signer ID", 829 content->one_pass_sig.keyid, 830 sizeof(content->one_pass_sig.keyid)); 831 print_uint(print->indent, "Nested", content->one_pass_sig.nested); 832 break; 833 834 case OPS_PTAG_CT_USER_ATTR: 835 print_tagname(print->indent, "USER ATTRIBUTE"); 836 print_hexdump(print->indent, "User Attribute", 837 content->userattr.data.contents, 838 content->userattr.data.len); 839 break; 840 841 case OPS_PTAG_RAW_SS: 842 if (pkt->critical) { 843 (void) fprintf(stderr, "contents are critical\n"); 844 return 0; 845 } 846 start_subpacket(&print->indent, pkt->tag); 847 print_uint(print->indent, "Raw Signature Subpacket: tag", 848 (unsigned)(content->ss_raw.tag - 849 (unsigned)OPS_PTAG_SIG_SUBPKT_BASE)); 850 print_hexdump(print->indent, "Raw Data", 851 content->ss_raw.raw, 852 content->ss_raw.length); 853 break; 854 855 case OPS_PTAG_SS_CREATION_TIME: 856 start_subpacket(&print->indent, pkt->tag); 857 print_time(print->indent, "Signature Creation Time", content->ss_time.time); 858 end_subpacket(&print->indent); 859 break; 860 861 case OPS_PTAG_SS_EXPIRATION_TIME: 862 start_subpacket(&print->indent, pkt->tag); 863 print_duration(print->indent, "Signature Expiration Time", 864 content->ss_time.time); 865 end_subpacket(&print->indent); 866 break; 867 868 case OPS_PTAG_SS_KEY_EXPIRY: 869 start_subpacket(&print->indent, pkt->tag); 870 print_duration(print->indent, "Key Expiration Time", content->ss_time.time); 871 end_subpacket(&print->indent); 872 break; 873 874 case OPS_PTAG_SS_TRUST: 875 start_subpacket(&print->indent, pkt->tag); 876 print_string(print->indent, "Trust Signature", ""); 877 print_uint(print->indent, "Level", (unsigned)content->ss_trust.level); 878 print_uint(print->indent, "Amount", (unsigned)content->ss_trust.amount); 879 end_subpacket(&print->indent); 880 break; 881 882 case OPS_PTAG_SS_REVOCABLE: 883 start_subpacket(&print->indent, pkt->tag); 884 print_boolean(print->indent, "Revocable", content->ss_revocable.revocable); 885 end_subpacket(&print->indent); 886 break; 887 888 case OPS_PTAG_SS_REVOCATION_KEY: 889 start_subpacket(&print->indent, pkt->tag); 890 /* not yet tested */ 891 printf(" revocation key: class=0x%x", 892 content->ss_revocation_key.class); 893 if (content->ss_revocation_key.class & 0x40) { 894 printf(" (sensitive)"); 895 } 896 printf(", algid=0x%x", content->ss_revocation_key.algid); 897 printf(", fingerprint="); 898 hexdump(stdout, content->ss_revocation_key.fingerprint, 899 OPS_FINGERPRINT_SIZE, ""); 900 printf("\n"); 901 end_subpacket(&print->indent); 902 break; 903 904 case OPS_PTAG_SS_ISSUER_KEY_ID: 905 start_subpacket(&print->indent, pkt->tag); 906 print_hexdump(print->indent, "Issuer Key Id", 907 &content->ss_issuer.key_id[0], 908 sizeof(content->ss_issuer.key_id)); 909 end_subpacket(&print->indent); 910 break; 911 912 case OPS_PTAG_SS_PREFERRED_SKA: 913 start_subpacket(&print->indent, pkt->tag); 914 print_data(print->indent, "Preferred Symmetric Algorithms", 915 &content->ss_skapref.data); 916 917 text = __ops_showall_ss_skapref(content->ss_skapref); 918 print_text_breakdown(print->indent, text); 919 __ops_text_free(text); 920 921 end_subpacket(&print->indent); 922 break; 923 924 case OPS_PTAG_SS_PRIMARY_USER_ID: 925 start_subpacket(&print->indent, pkt->tag); 926 print_boolean(print->indent, "Primary User ID", 927 content->ss_primary_userid.primary_userid); 928 end_subpacket(&print->indent); 929 break; 930 931 case OPS_PTAG_SS_PREFERRED_HASH: 932 start_subpacket(&print->indent, pkt->tag); 933 print_data(print->indent, "Preferred Hash Algorithms", 934 &content->ss_hashpref.data); 935 936 text = __ops_showall_ss_hashpref(content->ss_hashpref); 937 print_text_breakdown(print->indent, text); 938 __ops_text_free(text); 939 end_subpacket(&print->indent); 940 break; 941 942 case OPS_PTAG_SS_PREF_COMPRESS: 943 start_subpacket(&print->indent, pkt->tag); 944 print_data(print->indent, "Preferred Compression Algorithms", 945 &content->ss_zpref.data); 946 947 text = __ops_showall_ss_zpref(content->ss_zpref); 948 print_text_breakdown(print->indent, text); 949 __ops_text_free(text); 950 end_subpacket(&print->indent); 951 break; 952 953 case OPS_PTAG_SS_KEY_FLAGS: 954 start_subpacket(&print->indent, pkt->tag); 955 print_data(print->indent, "Key Flags", &content->ss_key_flags.data); 956 957 text = __ops_showall_ss_key_flags(content->ss_key_flags); 958 print_text_breakdown(print->indent, text); 959 __ops_text_free(text); 960 961 end_subpacket(&print->indent); 962 break; 963 964 case OPS_PTAG_SS_KEYSERV_PREFS: 965 start_subpacket(&print->indent, pkt->tag); 966 print_data(print->indent, "Key Server Preferences", 967 &content->ss_key_server_prefs.data); 968 969 text = __ops_show_keyserv_prefs(content->ss_key_server_prefs); 970 print_text_breakdown(print->indent, text); 971 __ops_text_free(text); 972 973 end_subpacket(&print->indent); 974 break; 975 976 case OPS_PTAG_SS_FEATURES: 977 start_subpacket(&print->indent, pkt->tag); 978 print_data(print->indent, "Features", 979 &content->ss_features.data); 980 981 text = __ops_showall_ss_features(content->ss_features); 982 print_text_breakdown(print->indent, text); 983 __ops_text_free(text); 984 985 end_subpacket(&print->indent); 986 break; 987 988 case OPS_PTAG_SS_NOTATION_DATA: 989 start_subpacket(&print->indent, pkt->tag); 990 print_indent(print->indent); 991 printf("Notation Data:\n"); 992 993 print->indent++; 994 print_data(print->indent, "Flags", &content->ss_notation.flags); 995 text = __ops_showall_notation(content->ss_notation); 996 print_text_breakdown(print->indent, text); 997 __ops_text_free(text); 998 999 print_data(print->indent, "Name", &content->ss_notation.name); 1000 1001 print_data(print->indent, "Value", &content->ss_notation.value); 1002 1003 print->indent--; 1004 end_subpacket(&print->indent); 1005 break; 1006 1007 case OPS_PTAG_SS_REGEXP: 1008 start_subpacket(&print->indent, pkt->tag); 1009 print_hexdump(print->indent, "Regular Expression", 1010 (unsigned char *) content->ss_regexp.regexp, 1011 strlen(content->ss_regexp.regexp)); 1012 print_string(print->indent, NULL, content->ss_regexp.regexp); 1013 end_subpacket(&print->indent); 1014 break; 1015 1016 case OPS_PTAG_SS_POLICY_URI: 1017 start_subpacket(&print->indent, pkt->tag); 1018 print_string(print->indent, "Policy URL", content->ss_policy.url); 1019 end_subpacket(&print->indent); 1020 break; 1021 1022 case OPS_PTAG_SS_SIGNERS_USER_ID: 1023 start_subpacket(&print->indent, pkt->tag); 1024 print_utf8_string(print->indent, "Signer's User ID", 1025 content->ss_signer.userid); 1026 end_subpacket(&print->indent); 1027 break; 1028 1029 case OPS_PTAG_SS_PREF_KEYSERV: 1030 start_subpacket(&print->indent, pkt->tag); 1031 print_string(print->indent, "Preferred Key Server", content->ss_keyserv.name); 1032 end_subpacket(&print->indent); 1033 break; 1034 1035 case OPS_PTAG_SS_EMBEDDED_SIGNATURE: 1036 start_subpacket(&print->indent, pkt->tag); 1037 end_subpacket(&print->indent);/* \todo print out contents? */ 1038 break; 1039 1040 case OPS_PTAG_SS_USERDEFINED00: 1041 case OPS_PTAG_SS_USERDEFINED01: 1042 case OPS_PTAG_SS_USERDEFINED02: 1043 case OPS_PTAG_SS_USERDEFINED03: 1044 case OPS_PTAG_SS_USERDEFINED04: 1045 case OPS_PTAG_SS_USERDEFINED05: 1046 case OPS_PTAG_SS_USERDEFINED06: 1047 case OPS_PTAG_SS_USERDEFINED07: 1048 case OPS_PTAG_SS_USERDEFINED08: 1049 case OPS_PTAG_SS_USERDEFINED09: 1050 case OPS_PTAG_SS_USERDEFINED10: 1051 start_subpacket(&print->indent, pkt->tag); 1052 print_hexdump(print->indent, "Internal or user-defined", 1053 content->ss_userdef.data.contents, 1054 content->ss_userdef.data.len); 1055 end_subpacket(&print->indent); 1056 break; 1057 1058 case OPS_PTAG_SS_RESERVED: 1059 start_subpacket(&print->indent, pkt->tag); 1060 print_hexdump(print->indent, "Reserved", 1061 content->ss_userdef.data.contents, 1062 content->ss_userdef.data.len); 1063 end_subpacket(&print->indent); 1064 break; 1065 1066 case OPS_PTAG_SS_REVOCATION_REASON: 1067 start_subpacket(&print->indent, pkt->tag); 1068 print_hexdump(print->indent, "Revocation Reason", 1069 &content->ss_revocation.code, 1070 1); 1071 str = __ops_show_ss_rr_code(content->ss_revocation.code); 1072 print_string(print->indent, NULL, str); 1073 end_subpacket(&print->indent); 1074 break; 1075 1076 case OPS_PTAG_CT_LITDATA_HEADER: 1077 print_tagname(print->indent, "LITERAL DATA HEADER"); 1078 printf(" literal data header format=%c filename='%s'\n", 1079 content->litdata_header.format, 1080 content->litdata_header.filename); 1081 showtime(" modification time", 1082 content->litdata_header.mtime); 1083 printf("\n"); 1084 break; 1085 1086 case OPS_PTAG_CT_LITDATA_BODY: 1087 print_tagname(print->indent, "LITERAL DATA BODY"); 1088 printf(" literal data body length=%u\n", 1089 content->litdata_body.length); 1090 printf(" data="); 1091 print_escaped(content->litdata_body.data, 1092 content->litdata_body.length); 1093 printf("\n"); 1094 break; 1095 1096 case OPS_PTAG_CT_SIGNATURE_HEADER: 1097 print_tagname(print->indent, "SIGNATURE"); 1098 print_indent(print->indent); 1099 print_uint(print->indent, "Signature Version", 1100 (unsigned)content->sig.info.version); 1101 if (content->sig.info.birthtime_set) { 1102 print_time(print->indent, "Signature Creation Time", 1103 content->sig.info.birthtime); 1104 } 1105 if (content->sig.info.duration_set) { 1106 print_uint(print->indent, "Signature Duration", 1107 (unsigned)content->sig.info.duration); 1108 } 1109 print_string_and_value(print->indent, "Signature Type", 1110 __ops_show_sig_type(content->sig.info.type), 1111 content->sig.info.type); 1112 if (content->sig.info.signer_id_set) { 1113 hexdump_data(print->indent, "Signer ID", 1114 content->sig.info.signer_id, 1115 sizeof(content->sig.info.signer_id)); 1116 } 1117 print_string_and_value(print->indent, "Public Key Algorithm", 1118 __ops_show_pka(content->sig.info.key_alg), 1119 content->sig.info.key_alg); 1120 print_string_and_value(print->indent, "Hash Algorithm", 1121 __ops_show_hash_alg((unsigned char)content->sig.info.hash_alg), 1122 (unsigned char)content->sig.info.hash_alg); 1123 print_uint(print->indent, "Hashed data len", 1124 content->sig.info.v4_hashlen); 1125 1126 break; 1127 1128 case OPS_PTAG_CT_SIGNATURE_FOOTER: 1129 print_indent(print->indent); 1130 hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2); 1131 1132 switch (content->sig.info.key_alg) { 1133 case OPS_PKA_RSA: 1134 print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig); 1135 break; 1136 1137 case OPS_PKA_DSA: 1138 print_bn(print->indent, "r", content->sig.info.sig.dsa.r); 1139 print_bn(print->indent, "s", content->sig.info.sig.dsa.s); 1140 break; 1141 1142 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 1143 print_bn(print->indent, "r", content->sig.info.sig.elgamal.r); 1144 print_bn(print->indent, "s", content->sig.info.sig.elgamal.s); 1145 break; 1146 1147 case OPS_PKA_PRIVATE00: 1148 case OPS_PKA_PRIVATE01: 1149 case OPS_PKA_PRIVATE02: 1150 case OPS_PKA_PRIVATE03: 1151 case OPS_PKA_PRIVATE04: 1152 case OPS_PKA_PRIVATE05: 1153 case OPS_PKA_PRIVATE06: 1154 case OPS_PKA_PRIVATE07: 1155 case OPS_PKA_PRIVATE08: 1156 case OPS_PKA_PRIVATE09: 1157 case OPS_PKA_PRIVATE10: 1158 print_data(print->indent, "Private/Experimental", 1159 &content->sig.info.sig.unknown.data); 1160 break; 1161 1162 default: 1163 (void) fprintf(stderr, 1164 "__ops_print_packet: Unusual key algorithm\n"); 1165 return 0; 1166 } 1167 break; 1168 1169 case OPS_GET_PASSPHRASE: 1170 print_tagname(print->indent, "OPS_GET_PASSPHRASE"); 1171 break; 1172 1173 case OPS_PTAG_CT_SECRET_KEY: 1174 print_tagname(print->indent, "OPS_PTAG_CT_SECRET_KEY"); 1175 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1176 break; 1177 1178 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 1179 print_tagname(print->indent, "OPS_PTAG_CT_ENCRYPTED_SECRET_KEY"); 1180 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1181 break; 1182 1183 case OPS_PTAG_CT_ARMOUR_HEADER: 1184 print_tagname(print->indent, "ARMOUR HEADER"); 1185 print_string(print->indent, "type", content->armour_header.type); 1186 break; 1187 1188 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 1189 print_tagname(print->indent, "SIGNED CLEARTEXT HEADER"); 1190 print_headers(&content->cleartext_head.headers); 1191 break; 1192 1193 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: 1194 print_tagname(print->indent, "SIGNED CLEARTEXT BODY"); 1195 print_block(print->indent, "signed cleartext", content->cleartext_body.data, 1196 content->cleartext_body.length); 1197 break; 1198 1199 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 1200 print_tagname(print->indent, "SIGNED CLEARTEXT TRAILER"); 1201 printf("hash algorithm: %d\n", 1202 content->cleartext_trailer.hash->alg); 1203 printf("\n"); 1204 break; 1205 1206 case OPS_PTAG_CT_UNARMOURED_TEXT: 1207 if (!print->unarmoured) { 1208 print_tagname(print->indent, "UNARMOURED TEXT"); 1209 print->unarmoured = 1; 1210 } 1211 putchar('['); 1212 print_escaped(content->unarmoured_text.data, 1213 content->unarmoured_text.length); 1214 putchar(']'); 1215 break; 1216 1217 case OPS_PTAG_CT_ARMOUR_TRAILER: 1218 print_tagname(print->indent, "ARMOUR TRAILER"); 1219 print_string(print->indent, "type", content->armour_header.type); 1220 break; 1221 1222 case OPS_PTAG_CT_PK_SESSION_KEY: 1223 case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: 1224 __ops_print_pk_sesskey(pkt->tag, &content->pk_sesskey); 1225 break; 1226 1227 case OPS_GET_SECKEY: 1228 __ops_print_pk_sesskey(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, 1229 content->get_seckey.pk_sesskey); 1230 break; 1231 1232 default: 1233 print_tagname(print->indent, "UNKNOWN PACKET TYPE"); 1234 fprintf(stderr, "__ops_print_packet: unknown tag=%d (0x%x)\n", 1235 pkt->tag, pkt->tag); 1236 exit(EXIT_FAILURE); 1237 } 1238 return 1; 1239} 1240 1241static __ops_cb_ret_t 1242cb_list_packets(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 1243{ 1244 __ops_print_packet(&cbinfo->printstate, pkt); 1245 return OPS_RELEASE_MEMORY; 1246} 1247 1248/** 1249\ingroup Core_Print 1250\param filename 1251\param armour 1252\param keyring 1253\param cb_get_passphrase 1254*/ 1255int 1256__ops_list_packets(__ops_io_t *io, 1257 char *filename, 1258 unsigned armour, 1259 __ops_keyring_t *keyring, 1260 void *passfp, 1261 __ops_cbfunc_t *cb_get_passphrase) 1262{ 1263 __ops_stream_t *stream = NULL; 1264 const unsigned accumulate = 1; 1265 const int printerrors = 1; 1266 int fd; 1267 1268 fd = __ops_setup_file_read(io, &stream, filename, NULL, cb_list_packets, 1269 accumulate); 1270 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 1271 stream->cryptinfo.keyring = keyring; 1272 stream->cbinfo.passfp = passfp; 1273 stream->cryptinfo.getpassphrase = cb_get_passphrase; 1274 if (armour) { 1275 __ops_reader_push_dearmour(stream); 1276 } 1277 __ops_parse(stream, printerrors); 1278 __ops_teardown_file_read(stream, fd); 1279 return 1; 1280} 1281