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