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