packet-print.c revision 1.31
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.31 2010/05/25 01:05:11 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], 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] : "[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]); 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] : ""); 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_enum 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_enum 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_content_enum)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_content_enum)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); 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_content_enum)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); 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); 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); 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); 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.contents, 960 content->userattr.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); 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); 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); 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); 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, sizeof(content->ss_issuer)); 1030 end_subpacket(&print->indent); 1031 break; 1032 1033 case OPS_PTAG_SS_PREFERRED_SKA: 1034 start_subpacket(&print->indent, pkt->tag); 1035 print_data(print->indent, "Preferred Symmetric Algorithms", 1036 &content->ss_skapref); 1037 text = __ops_showall_ss_skapref(&content->ss_skapref); 1038 print_text_breakdown(print->indent, text); 1039 __ops_text_free(text); 1040 1041 end_subpacket(&print->indent); 1042 break; 1043 1044 case OPS_PTAG_SS_PRIMARY_USER_ID: 1045 start_subpacket(&print->indent, pkt->tag); 1046 print_boolean(print->indent, "Primary User ID", 1047 content->ss_primary_userid); 1048 end_subpacket(&print->indent); 1049 break; 1050 1051 case OPS_PTAG_SS_PREFERRED_HASH: 1052 start_subpacket(&print->indent, pkt->tag); 1053 print_data(print->indent, "Preferred Hash Algorithms", 1054 &content->ss_hashpref); 1055 text = __ops_showall_ss_hashpref(&content->ss_hashpref); 1056 print_text_breakdown(print->indent, text); 1057 __ops_text_free(text); 1058 end_subpacket(&print->indent); 1059 break; 1060 1061 case OPS_PTAG_SS_PREF_COMPRESS: 1062 start_subpacket(&print->indent, pkt->tag); 1063 print_data(print->indent, "Preferred Compression Algorithms", 1064 &content->ss_zpref); 1065 text = __ops_showall_ss_zpref(&content->ss_zpref); 1066 print_text_breakdown(print->indent, text); 1067 __ops_text_free(text); 1068 end_subpacket(&print->indent); 1069 break; 1070 1071 case OPS_PTAG_SS_KEY_FLAGS: 1072 start_subpacket(&print->indent, pkt->tag); 1073 print_data(print->indent, "Key Flags", &content->ss_key_flags); 1074 1075 text = __ops_showall_ss_key_flags(&content->ss_key_flags); 1076 print_text_breakdown(print->indent, text); 1077 __ops_text_free(text); 1078 1079 end_subpacket(&print->indent); 1080 break; 1081 1082 case OPS_PTAG_SS_KEYSERV_PREFS: 1083 start_subpacket(&print->indent, pkt->tag); 1084 print_data(print->indent, "Key Server Preferences", 1085 &content->ss_key_server_prefs); 1086 text = __ops_show_keyserv_prefs(&content->ss_key_server_prefs); 1087 print_text_breakdown(print->indent, text); 1088 __ops_text_free(text); 1089 1090 end_subpacket(&print->indent); 1091 break; 1092 1093 case OPS_PTAG_SS_FEATURES: 1094 start_subpacket(&print->indent, pkt->tag); 1095 print_data(print->indent, "Features", &content->ss_features); 1096 text = __ops_showall_ss_features(content->ss_features); 1097 print_text_breakdown(print->indent, text); 1098 __ops_text_free(text); 1099 1100 end_subpacket(&print->indent); 1101 break; 1102 1103 case OPS_PTAG_SS_NOTATION_DATA: 1104 start_subpacket(&print->indent, pkt->tag); 1105 print_indent(print->indent); 1106 printf("Notation Data:\n"); 1107 1108 print->indent++; 1109 print_data(print->indent, "Flags", &content->ss_notation.flags); 1110 text = __ops_showall_notation(content->ss_notation); 1111 print_text_breakdown(print->indent, text); 1112 __ops_text_free(text); 1113 1114 print_data(print->indent, "Name", &content->ss_notation.name); 1115 1116 print_data(print->indent, "Value", &content->ss_notation.value); 1117 1118 print->indent--; 1119 end_subpacket(&print->indent); 1120 break; 1121 1122 case OPS_PTAG_SS_REGEXP: 1123 start_subpacket(&print->indent, pkt->tag); 1124 print_hexdump(print->indent, "Regular Expression", 1125 (uint8_t *) content->ss_regexp, 1126 strlen(content->ss_regexp)); 1127 print_string(print->indent, NULL, content->ss_regexp); 1128 end_subpacket(&print->indent); 1129 break; 1130 1131 case OPS_PTAG_SS_POLICY_URI: 1132 start_subpacket(&print->indent, pkt->tag); 1133 print_string(print->indent, "Policy URL", content->ss_policy); 1134 end_subpacket(&print->indent); 1135 break; 1136 1137 case OPS_PTAG_SS_SIGNERS_USER_ID: 1138 start_subpacket(&print->indent, pkt->tag); 1139 print_utf8_string(print->indent, "Signer's User ID", content->ss_signer); 1140 end_subpacket(&print->indent); 1141 break; 1142 1143 case OPS_PTAG_SS_PREF_KEYSERV: 1144 start_subpacket(&print->indent, pkt->tag); 1145 print_string(print->indent, "Preferred Key Server", content->ss_keyserv); 1146 end_subpacket(&print->indent); 1147 break; 1148 1149 case OPS_PTAG_SS_EMBEDDED_SIGNATURE: 1150 start_subpacket(&print->indent, pkt->tag); 1151 end_subpacket(&print->indent);/* \todo print out contents? */ 1152 break; 1153 1154 case OPS_PTAG_SS_USERDEFINED00: 1155 case OPS_PTAG_SS_USERDEFINED01: 1156 case OPS_PTAG_SS_USERDEFINED02: 1157 case OPS_PTAG_SS_USERDEFINED03: 1158 case OPS_PTAG_SS_USERDEFINED04: 1159 case OPS_PTAG_SS_USERDEFINED05: 1160 case OPS_PTAG_SS_USERDEFINED06: 1161 case OPS_PTAG_SS_USERDEFINED07: 1162 case OPS_PTAG_SS_USERDEFINED08: 1163 case OPS_PTAG_SS_USERDEFINED09: 1164 case OPS_PTAG_SS_USERDEFINED10: 1165 start_subpacket(&print->indent, pkt->tag); 1166 print_hexdump(print->indent, "Internal or user-defined", 1167 content->ss_userdef.contents, 1168 content->ss_userdef.len); 1169 end_subpacket(&print->indent); 1170 break; 1171 1172 case OPS_PTAG_SS_RESERVED: 1173 start_subpacket(&print->indent, pkt->tag); 1174 print_hexdump(print->indent, "Reserved", 1175 content->ss_userdef.contents, 1176 content->ss_userdef.len); 1177 end_subpacket(&print->indent); 1178 break; 1179 1180 case OPS_PTAG_SS_REVOCATION_REASON: 1181 start_subpacket(&print->indent, pkt->tag); 1182 print_hexdump(print->indent, "Revocation Reason", 1183 &content->ss_revocation.code, 1184 1); 1185 str = __ops_show_ss_rr_code(content->ss_revocation.code); 1186 print_string(print->indent, NULL, str); 1187 end_subpacket(&print->indent); 1188 break; 1189 1190 case OPS_PTAG_CT_LITDATA_HEADER: 1191 print_tagname(print->indent, "LITERAL DATA HEADER"); 1192 printf(" literal data header format=%c filename='%s'\n", 1193 content->litdata_header.format, 1194 content->litdata_header.filename); 1195 showtime(" modification time", 1196 content->litdata_header.mtime); 1197 printf("\n"); 1198 break; 1199 1200 case OPS_PTAG_CT_LITDATA_BODY: 1201 print_tagname(print->indent, "LITERAL DATA BODY"); 1202 printf(" literal data body length=%u\n", 1203 content->litdata_body.length); 1204 printf(" data="); 1205 print_escaped(content->litdata_body.data, 1206 content->litdata_body.length); 1207 printf("\n"); 1208 break; 1209 1210 case OPS_PTAG_CT_SIGNATURE_HEADER: 1211 print_tagname(print->indent, "SIGNATURE"); 1212 print_indent(print->indent); 1213 print_uint(print->indent, "Signature Version", 1214 (unsigned)content->sig.info.version); 1215 if (content->sig.info.birthtime_set) { 1216 print_time(print->indent, "Signature Creation Time", 1217 content->sig.info.birthtime); 1218 } 1219 if (content->sig.info.duration_set) { 1220 print_uint(print->indent, "Signature Duration", 1221 (unsigned)content->sig.info.duration); 1222 } 1223 print_string_and_value(print->indent, "Signature Type", 1224 __ops_show_sig_type(content->sig.info.type), 1225 content->sig.info.type); 1226 if (content->sig.info.signer_id_set) { 1227 hexdump_data(print->indent, "Signer ID", 1228 content->sig.info.signer_id, 1229 sizeof(content->sig.info.signer_id)); 1230 } 1231 print_string_and_value(print->indent, "Public Key Algorithm", 1232 __ops_show_pka(content->sig.info.key_alg), 1233 content->sig.info.key_alg); 1234 print_string_and_value(print->indent, "Hash Algorithm", 1235 __ops_show_hash_alg((uint8_t)content->sig.info.hash_alg), 1236 (uint8_t)content->sig.info.hash_alg); 1237 print_uint(print->indent, "Hashed data len", 1238 content->sig.info.v4_hashlen); 1239 1240 break; 1241 1242 case OPS_PTAG_CT_SIGNATURE_FOOTER: 1243 print_indent(print->indent); 1244 hexdump_data(print->indent, "hash2", &content->sig.hash2[0], 2); 1245 1246 switch (content->sig.info.key_alg) { 1247 case OPS_PKA_RSA: 1248 print_bn(print->indent, "sig", content->sig.info.sig.rsa.sig); 1249 break; 1250 1251 case OPS_PKA_DSA: 1252 print_bn(print->indent, "r", content->sig.info.sig.dsa.r); 1253 print_bn(print->indent, "s", content->sig.info.sig.dsa.s); 1254 break; 1255 1256 case OPS_PKA_ELGAMAL_ENCRYPT_OR_SIGN: 1257 print_bn(print->indent, "r", content->sig.info.sig.elgamal.r); 1258 print_bn(print->indent, "s", content->sig.info.sig.elgamal.s); 1259 break; 1260 1261 case OPS_PKA_PRIVATE00: 1262 case OPS_PKA_PRIVATE01: 1263 case OPS_PKA_PRIVATE02: 1264 case OPS_PKA_PRIVATE03: 1265 case OPS_PKA_PRIVATE04: 1266 case OPS_PKA_PRIVATE05: 1267 case OPS_PKA_PRIVATE06: 1268 case OPS_PKA_PRIVATE07: 1269 case OPS_PKA_PRIVATE08: 1270 case OPS_PKA_PRIVATE09: 1271 case OPS_PKA_PRIVATE10: 1272 print_data(print->indent, "Private/Experimental", 1273 &content->sig.info.sig.unknown); 1274 break; 1275 1276 default: 1277 (void) fprintf(stderr, 1278 "__ops_print_packet: Unusual key algorithm\n"); 1279 return 0; 1280 } 1281 break; 1282 1283 case OPS_GET_PASSPHRASE: 1284 print_tagname(print->indent, "OPS_GET_PASSPHRASE"); 1285 break; 1286 1287 case OPS_PTAG_CT_SECRET_KEY: 1288 print_tagname(print->indent, "OPS_PTAG_CT_SECRET_KEY"); 1289 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1290 break; 1291 1292 case OPS_PTAG_CT_ENCRYPTED_SECRET_KEY: 1293 print_tagname(print->indent, "OPS_PTAG_CT_ENCRYPTED_SECRET_KEY"); 1294 __ops_print_seckey_verbose(pkt->tag, &content->seckey); 1295 break; 1296 1297 case OPS_PTAG_CT_ARMOUR_HEADER: 1298 print_tagname(print->indent, "ARMOUR HEADER"); 1299 print_string(print->indent, "type", content->armour_header.type); 1300 break; 1301 1302 case OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER: 1303 print_tagname(print->indent, "SIGNED CLEARTEXT HEADER"); 1304 print_headers(&content->cleartext_head); 1305 break; 1306 1307 case OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY: 1308 print_tagname(print->indent, "SIGNED CLEARTEXT BODY"); 1309 print_block(print->indent, "signed cleartext", content->cleartext_body.data, 1310 content->cleartext_body.length); 1311 break; 1312 1313 case OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER: 1314 print_tagname(print->indent, "SIGNED CLEARTEXT TRAILER"); 1315 printf("hash algorithm: %d\n", 1316 content->cleartext_trailer->alg); 1317 printf("\n"); 1318 break; 1319 1320 case OPS_PTAG_CT_UNARMOURED_TEXT: 1321 if (!print->unarmoured) { 1322 print_tagname(print->indent, "UNARMOURED TEXT"); 1323 print->unarmoured = 1; 1324 } 1325 putchar('['); 1326 print_escaped(content->unarmoured_text.data, 1327 content->unarmoured_text.length); 1328 putchar(']'); 1329 break; 1330 1331 case OPS_PTAG_CT_ARMOUR_TRAILER: 1332 print_tagname(print->indent, "ARMOUR TRAILER"); 1333 print_string(print->indent, "type", content->armour_header.type); 1334 break; 1335 1336 case OPS_PTAG_CT_PK_SESSION_KEY: 1337 case OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY: 1338 __ops_print_pk_sesskey(pkt->tag, &content->pk_sesskey); 1339 break; 1340 1341 case OPS_GET_SECKEY: 1342 __ops_print_pk_sesskey(OPS_PTAG_CT_ENCRYPTED_PK_SESSION_KEY, 1343 content->get_seckey.pk_sesskey); 1344 break; 1345 1346 default: 1347 print_tagname(print->indent, "UNKNOWN PACKET TYPE"); 1348 fprintf(stderr, "__ops_print_packet: unknown tag=%d (0x%x)\n", 1349 pkt->tag, pkt->tag); 1350 exit(EXIT_FAILURE); 1351 } 1352 return 1; 1353} 1354 1355static __ops_cb_ret_t 1356cb_list_packets(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 1357{ 1358 __ops_print_packet(&cbinfo->printstate, pkt); 1359 return OPS_RELEASE_MEMORY; 1360} 1361 1362/** 1363\ingroup Core_Print 1364\param filename 1365\param armour 1366\param keyring 1367\param cb_get_passphrase 1368*/ 1369int 1370__ops_list_packets(__ops_io_t *io, 1371 char *filename, 1372 unsigned armour, 1373 __ops_keyring_t *secring, 1374 __ops_keyring_t *pubring, 1375 void *passfp, 1376 __ops_cbfunc_t *cb_get_passphrase) 1377{ 1378 __ops_stream_t *stream = NULL; 1379 const unsigned accumulate = 1; 1380 const int printerrors = 1; 1381 int fd; 1382 1383 fd = __ops_setup_file_read(io, &stream, filename, NULL, cb_list_packets, 1384 accumulate); 1385 __ops_parse_options(stream, OPS_PTAG_SS_ALL, OPS_PARSE_PARSED); 1386 stream->cryptinfo.secring = secring; 1387 stream->cryptinfo.pubring = pubring; 1388 stream->cbinfo.passfp = passfp; 1389 stream->cryptinfo.getpassphrase = cb_get_passphrase; 1390 if (armour) { 1391 __ops_reader_push_dearmour(stream); 1392 } 1393 __ops_parse(stream, printerrors); 1394 __ops_teardown_file_read(stream, fd); 1395 return 1; 1396} 1397