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 #include "config.h" 50 51 #ifdef HAVE_SYS_CDEFS_H 52 #include <sys/cdefs.h> 53 #endif 54 55 #if defined(__NetBSD__) 56 __COPYRIGHT("@(#) Copyright (c) 2009 The NetBSD Foundation, Inc. All rights reserved."); 57 __RCSID("$NetBSD: reader.c,v 1.42 2010/08/15 16:36:24 agc Exp $"); 58 #endif 59 60 #include <sys/types.h> 61 #include <sys/stat.h> 62 63 #ifdef HAVE_SYS_MMAN_H 64 #include <sys/mman.h> 65 #endif 66 67 #ifdef HAVE_SYS_PARAM_H 68 #include <sys/param.h> 69 #endif 70 71 #ifdef HAVE_FCNTL_H 72 #include <fcntl.h> 73 #endif 74 75 #ifdef HAVE_UNISTD_H 76 #include <unistd.h> 77 #endif 78 79 #ifdef HAVE_DIRECT_H 80 #include <direct.h> 81 #endif 82 83 #ifdef HAVE_INTTYPES_H 84 #include <inttypes.h> 85 #endif 86 87 #ifdef HAVE_OPENSSL_IDEA_H 88 #include <openssl/cast.h> 89 #endif 90 91 #ifdef HAVE_OPENSSL_IDEA_H 92 #include <openssl/idea.h> 93 #endif 94 95 #ifdef HAVE_OPENSSL_AES_H 96 #include <openssl/aes.h> 97 #endif 98 99 #ifdef HAVE_OPENSSL_DES_H 100 #include <openssl/des.h> 101 #endif 102 103 #include <string.h> 104 #include <stdlib.h> 105 #include <stdio.h> 106 107 #ifdef HAVE_TERMIOS_H 108 #include <termios.h> 109 #endif 110 111 #ifdef HAVE_ERRNO_H 112 #include <errno.h> 113 #endif 114 115 #ifdef HAVE_UNISTD_H 116 #include <unistd.h> 117 #endif 118 119 #ifdef HAVE_LIMITS_H 120 #include <limits.h> 121 #endif 122 123 #include "errors.h" 124 #include "crypto.h" 125 #include "create.h" 126 #include "signature.h" 127 #include "packet.h" 128 #include "packet-parse.h" 129 #include "packet-show.h" 130 #include "packet.h" 131 #include "keyring.h" 132 #include "readerwriter.h" 133 #include "netpgpsdk.h" 134 #include "netpgpdefs.h" 135 #include "netpgpdigest.h" 136 137 138 /* get a pass phrase from the user */ 139 int 140 __ops_getpassphrase(void *in, char *phrase, size_t size) 141 { 142 char *p; 143 144 if (in == NULL) { 145 while ((p = getpass("netpgp passphrase: ")) == NULL) { 146 } 147 (void) snprintf(phrase, size, "%s", p); 148 } else { 149 if (fgets(phrase, (int)size, in) == NULL) { 150 return 0; 151 } 152 phrase[strlen(phrase) - 1] = 0x0; 153 } 154 return 1; 155 } 156 157 /** 158 * \ingroup Internal_Readers_Generic 159 * \brief Starts reader stack 160 * \param stream Parse settings 161 * \param reader Reader to use 162 * \param destroyer Destroyer to use 163 * \param vp Reader-specific arg 164 */ 165 void 166 __ops_reader_set(__ops_stream_t *stream, 167 __ops_reader_func_t *reader, 168 __ops_reader_destroyer_t *destroyer, 169 void *vp) 170 { 171 stream->readinfo.reader = reader; 172 stream->readinfo.destroyer = destroyer; 173 stream->readinfo.arg = vp; 174 } 175 176 /** 177 * \ingroup Internal_Readers_Generic 178 * \brief Adds to reader stack 179 * \param stream Parse settings 180 * \param reader Reader to use 181 * \param destroyer Reader's destroyer 182 * \param vp Reader-specific arg 183 */ 184 void 185 __ops_reader_push(__ops_stream_t *stream, 186 __ops_reader_func_t *reader, 187 __ops_reader_destroyer_t *destroyer, 188 void *vp) 189 { 190 __ops_reader_t *readinfo; 191 192 if ((readinfo = calloc(1, sizeof(*readinfo))) == NULL) { 193 (void) fprintf(stderr, "__ops_reader_push: bad alloc\n"); 194 } else { 195 *readinfo = stream->readinfo; 196 (void) memset(&stream->readinfo, 0x0, sizeof(stream->readinfo)); 197 stream->readinfo.next = readinfo; 198 stream->readinfo.parent = stream; 199 200 /* should copy accumulate flags from other reader? RW */ 201 stream->readinfo.accumulate = readinfo->accumulate; 202 203 __ops_reader_set(stream, reader, destroyer, vp); 204 } 205 } 206 207 /** 208 * \ingroup Internal_Readers_Generic 209 * \brief Removes from reader stack 210 * \param stream Parse settings 211 */ 212 void 213 __ops_reader_pop(__ops_stream_t *stream) 214 { 215 __ops_reader_t *next = stream->readinfo.next; 216 217 stream->readinfo = *next; 218 free(next); 219 } 220 221 /** 222 * \ingroup Internal_Readers_Generic 223 * \brief Gets arg from reader 224 * \param readinfo Reader info 225 * \return Pointer to reader info's arg 226 */ 227 void * 228 __ops_reader_get_arg(__ops_reader_t *readinfo) 229 { 230 return readinfo->arg; 231 } 232 233 /**************************************************************************/ 234 235 #define CRC24_POLY 0x1864cfbL 236 237 enum { 238 NONE = 0, 239 BEGIN_PGP_MESSAGE, 240 BEGIN_PGP_PUBLIC_KEY_BLOCK, 241 BEGIN_PGP_PRIVATE_KEY_BLOCK, 242 BEGIN_PGP_MULTI, 243 BEGIN_PGP_SIGNATURE, 244 245 END_PGP_MESSAGE, 246 END_PGP_PUBLIC_KEY_BLOCK, 247 END_PGP_PRIVATE_KEY_BLOCK, 248 END_PGP_MULTI, 249 END_PGP_SIGNATURE, 250 251 BEGIN_PGP_SIGNED_MESSAGE 252 }; 253 254 /** 255 * \struct dearmour_t 256 */ 257 typedef struct { 258 enum { 259 OUTSIDE_BLOCK = 0, 260 BASE64, 261 AT_TRAILER_NAME 262 } state; 263 int lastseen; 264 __ops_stream_t *parse_info; 265 unsigned seen_nl:1; 266 unsigned prev_nl:1; 267 unsigned allow_headers_without_gap:1; 268 /* !< allow headers in armoured data that are 269 * not separated from the data by a blank line 270 * */ 271 unsigned allow_no_gap:1; 272 /* !< allow no blank line at the start of 273 * armoured data */ 274 unsigned allow_trailing_whitespace:1; 275 /* !< allow armoured stuff to have trailing 276 * whitespace where we wouldn't strictly expect 277 * it */ 278 /* it is an error to get a cleartext message without a sig */ 279 unsigned expect_sig:1; 280 unsigned got_sig:1; 281 /* base64 stuff */ 282 unsigned buffered; 283 uint8_t buffer[3]; 284 unsigned eof64; 285 uint32_t checksum; 286 uint32_t read_checksum; 287 /* unarmoured text blocks */ 288 uint8_t unarmoured[NETPGP_BUFSIZ]; 289 size_t unarmoredc; 290 /* pushed back data (stored backwards) */ 291 uint8_t *pushback; 292 unsigned pushbackc; 293 /* armoured block headers */ 294 __ops_headers_t headers; 295 } dearmour_t; 296 297 static void 298 push_back(dearmour_t *dearmour, const uint8_t *buf, 299 unsigned length) 300 { 301 unsigned n; 302 303 if (dearmour->pushback) { 304 (void) fprintf(stderr, "push_back: already pushed back\n"); 305 } else if ((dearmour->pushback = calloc(1, length)) == NULL) { 306 (void) fprintf(stderr, "push_back: bad alloc\n"); 307 } else { 308 for (n = 0; n < length; ++n) { 309 dearmour->pushback[n] = buf[(length - n) - 1]; 310 } 311 dearmour->pushbackc = length; 312 } 313 } 314 315 /* this struct holds a textual header line */ 316 typedef struct headerline_t { 317 const char *s; /* the header line */ 318 size_t len; /* its length */ 319 int type; /* the defined type */ 320 } headerline_t; 321 322 static headerline_t headerlines[] = { 323 { "BEGIN PGP MESSAGE", 17, BEGIN_PGP_MESSAGE }, 324 { "BEGIN PGP PUBLIC KEY BLOCK", 26, BEGIN_PGP_PUBLIC_KEY_BLOCK }, 325 { "BEGIN PGP PRIVATE KEY BLOCK",27, BEGIN_PGP_PRIVATE_KEY_BLOCK }, 326 { "BEGIN PGP MESSAGE, PART ", 25, BEGIN_PGP_MULTI }, 327 { "BEGIN PGP SIGNATURE", 19, BEGIN_PGP_SIGNATURE }, 328 329 { "END PGP MESSAGE", 15, END_PGP_MESSAGE }, 330 { "END PGP PUBLIC KEY BLOCK", 24, END_PGP_PUBLIC_KEY_BLOCK }, 331 { "END PGP PRIVATE KEY BLOCK", 25, END_PGP_PRIVATE_KEY_BLOCK }, 332 { "END PGP MESSAGE, PART ", 22, END_PGP_MULTI }, 333 { "END PGP SIGNATURE", 17, END_PGP_SIGNATURE }, 334 335 { "BEGIN PGP SIGNED MESSAGE", 24, BEGIN_PGP_SIGNED_MESSAGE }, 336 337 { NULL, 0, -1 } 338 }; 339 340 /* search through the table of header lines */ 341 static int 342 findheaderline(char *headerline) 343 { 344 headerline_t *hp; 345 346 for (hp = headerlines ; hp->s ; hp++) { 347 if (strncmp(headerline, hp->s, hp->len) == 0) { 348 break; 349 } 350 } 351 return hp->type; 352 } 353 354 static int 355 set_lastseen_headerline(dearmour_t *dearmour, char *hdr, __ops_error_t **errors) 356 { 357 int lastseen; 358 int prev; 359 360 prev = dearmour->lastseen; 361 if ((lastseen = findheaderline(hdr)) == -1) { 362 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT, 363 "Unrecognised Header Line %s", hdr); 364 return 0; 365 } 366 dearmour->lastseen = lastseen; 367 if (__ops_get_debug_level(__FILE__)) { 368 printf("set header: hdr=%s, dearmour->lastseen=%d, prev=%d\n", 369 hdr, dearmour->lastseen, prev); 370 } 371 switch (dearmour->lastseen) { 372 case NONE: 373 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT, 374 "Unrecognised last seen Header Line %s", hdr); 375 break; 376 377 case END_PGP_MESSAGE: 378 if (prev != BEGIN_PGP_MESSAGE) { 379 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 380 "Got END PGP MESSAGE, but not after BEGIN"); 381 } 382 break; 383 384 case END_PGP_PUBLIC_KEY_BLOCK: 385 if (prev != BEGIN_PGP_PUBLIC_KEY_BLOCK) { 386 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 387 "Got END PGP PUBLIC KEY BLOCK, but not after BEGIN"); 388 } 389 break; 390 391 case END_PGP_PRIVATE_KEY_BLOCK: 392 if (prev != BEGIN_PGP_PRIVATE_KEY_BLOCK) { 393 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 394 "Got END PGP PRIVATE KEY BLOCK, but not after BEGIN"); 395 } 396 break; 397 398 case BEGIN_PGP_MULTI: 399 case END_PGP_MULTI: 400 OPS_ERROR(errors, OPS_E_R_UNSUPPORTED, 401 "Multi-part messages are not yet supported"); 402 break; 403 404 case END_PGP_SIGNATURE: 405 if (prev != BEGIN_PGP_SIGNATURE) { 406 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 407 "Got END PGP SIGNATURE, but not after BEGIN"); 408 } 409 break; 410 411 case BEGIN_PGP_MESSAGE: 412 case BEGIN_PGP_PUBLIC_KEY_BLOCK: 413 case BEGIN_PGP_PRIVATE_KEY_BLOCK: 414 case BEGIN_PGP_SIGNATURE: 415 case BEGIN_PGP_SIGNED_MESSAGE: 416 break; 417 } 418 return 1; 419 } 420 421 static int 422 read_char(dearmour_t *dearmour, 423 __ops_error_t **errors, 424 __ops_reader_t *readinfo, 425 __ops_cbdata_t *cbinfo, 426 unsigned skip) 427 { 428 uint8_t c; 429 430 do { 431 if (dearmour->pushbackc) { 432 c = dearmour->pushback[--dearmour->pushbackc]; 433 if (dearmour->pushbackc == 0) { 434 free(dearmour->pushback); 435 dearmour->pushback = NULL; 436 } 437 } else if (__ops_stacked_read(&c, 1, errors, readinfo, 438 cbinfo) != 1) { 439 return -1; 440 } 441 } while (skip && c == '\r'); 442 dearmour->prev_nl = dearmour->seen_nl; 443 dearmour->seen_nl = c == '\n'; 444 return c; 445 } 446 447 static int 448 eat_whitespace(int first, 449 dearmour_t *dearmour, 450 __ops_error_t **errors, 451 __ops_reader_t *readinfo, 452 __ops_cbdata_t *cbinfo, 453 unsigned skip) 454 { 455 int c = first; 456 457 while (c == ' ' || c == '\t') { 458 c = read_char(dearmour, errors, readinfo, cbinfo, skip); 459 } 460 return c; 461 } 462 463 static int 464 read_and_eat_whitespace(dearmour_t *dearmour, 465 __ops_error_t **errors, 466 __ops_reader_t *readinfo, 467 __ops_cbdata_t *cbinfo, 468 unsigned skip) 469 { 470 int c; 471 472 do { 473 c = read_char(dearmour, errors, readinfo, cbinfo, skip); 474 } while (c == ' ' || c == '\t'); 475 return c; 476 } 477 478 static void 479 flush(dearmour_t *dearmour, __ops_cbdata_t *cbinfo) 480 { 481 __ops_packet_t content; 482 483 if (dearmour->unarmoredc > 0) { 484 content.u.unarmoured_text.data = dearmour->unarmoured; 485 content.u.unarmoured_text.length = (unsigned)dearmour->unarmoredc; 486 CALLBACK(OPS_PTAG_CT_UNARMOURED_TEXT, cbinfo, &content); 487 dearmour->unarmoredc = 0; 488 } 489 } 490 491 static int 492 unarmoured_read_char(dearmour_t *dearmour, 493 __ops_error_t **errors, 494 __ops_reader_t *readinfo, 495 __ops_cbdata_t *cbinfo, 496 unsigned skip) 497 { 498 int c; 499 500 do { 501 c = read_char(dearmour, errors, readinfo, cbinfo, 0); 502 if (c < 0) { 503 return c; 504 } 505 dearmour->unarmoured[dearmour->unarmoredc++] = c; 506 if (dearmour->unarmoredc == sizeof(dearmour->unarmoured)) { 507 flush(dearmour, cbinfo); 508 } 509 } while (skip && c == '\r'); 510 return c; 511 } 512 513 /** 514 * \param headers 515 * \param key 516 * 517 * \return header value if found, otherwise NULL 518 */ 519 static const char * 520 __ops_find_header(__ops_headers_t *headers, const char *key) 521 { 522 unsigned n; 523 524 for (n = 0; n < headers->headerc; ++n) { 525 if (strcmp(headers->headers[n].key, key) == 0) { 526 return headers->headers[n].value; 527 } 528 } 529 return NULL; 530 } 531 532 /** 533 * \param dest 534 * \param src 535 */ 536 static void 537 __ops_dup_headers(__ops_headers_t *dest, const __ops_headers_t *src) 538 { 539 unsigned n; 540 541 if ((dest->headers = calloc(src->headerc, sizeof(*dest->headers))) == NULL) { 542 (void) fprintf(stderr, "__ops_dup_headers: bad alloc\n"); 543 } else { 544 dest->headerc = src->headerc; 545 for (n = 0; n < src->headerc; ++n) { 546 dest->headers[n].key = netpgp_strdup(src->headers[n].key); 547 dest->headers[n].value = netpgp_strdup(src->headers[n].value); 548 } 549 } 550 } 551 552 /* 553 * Note that this skips CRs so implementations always see just straight LFs 554 * as line terminators 555 */ 556 static int 557 process_dash_escaped(dearmour_t *dearmour, 558 __ops_error_t **errors, 559 __ops_reader_t *readinfo, 560 __ops_cbdata_t *cbinfo) 561 { 562 __ops_fixed_body_t *body; 563 __ops_packet_t content2; 564 __ops_packet_t content; 565 const char *hashstr; 566 __ops_hash_t *hash; 567 int total; 568 569 body = &content.u.cleartext_body; 570 if ((hash = calloc(1, sizeof(*hash))) == NULL) { 571 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 572 "process_dash_escaped: bad alloc"); 573 return -1; 574 } 575 hashstr = __ops_find_header(&dearmour->headers, "Hash"); 576 if (hashstr) { 577 __ops_hash_alg_t alg; 578 579 alg = __ops_str_to_hash_alg(hashstr); 580 if (!__ops_is_hash_alg_supported(&alg)) { 581 free(hash); 582 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT, 583 "Unsupported hash algorithm '%s'", hashstr); 584 return -1; 585 } 586 if (alg == OPS_HASH_UNKNOWN) { 587 free(hash); 588 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT, 589 "Unknown hash algorithm '%s'", hashstr); 590 return -1; 591 } 592 __ops_hash_any(hash, alg); 593 } else { 594 __ops_hash_md5(hash); 595 } 596 597 if (!hash->init(hash)) { 598 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 599 "can't initialise hash"); 600 return -1; 601 } 602 603 body->length = 0; 604 total = 0; 605 for (;;) { 606 int c; 607 unsigned count; 608 609 c = read_char(dearmour, errors, readinfo, cbinfo, 1); 610 if (c < 0) { 611 return -1; 612 } 613 if (dearmour->prev_nl && c == '-') { 614 if ((c = read_char(dearmour, errors, readinfo, cbinfo, 615 0)) < 0) { 616 return -1; 617 } 618 if (c != ' ') { 619 /* then this had better be a trailer! */ 620 if (c != '-') { 621 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 622 "Bad dash-escaping"); 623 } 624 for (count = 2; count < 5; ++count) { 625 if ((c = read_char(dearmour, errors, 626 readinfo, cbinfo, 0)) < 0) { 627 return -1; 628 } 629 if (c != '-') { 630 OPS_ERROR(errors, 631 OPS_E_R_BAD_FORMAT, 632 "Bad dash-escaping (2)"); 633 } 634 } 635 dearmour->state = AT_TRAILER_NAME; 636 break; 637 } 638 /* otherwise we read the next character */ 639 if ((c = read_char(dearmour, errors, readinfo, cbinfo, 640 0)) < 0) { 641 return -1; 642 } 643 } 644 if (c == '\n' && body->length) { 645 if (memchr(body->data + 1, '\n', body->length - 1) 646 != NULL) { 647 (void) fprintf(stderr, 648 "process_dash_escaped: newline found\n"); 649 return -1; 650 } 651 if (body->data[0] == '\n') { 652 hash->add(hash, (const uint8_t *)"\r", 1); 653 } 654 hash->add(hash, body->data, body->length); 655 if (__ops_get_debug_level(__FILE__)) { 656 fprintf(stderr, "Got body:\n%s\n", body->data); 657 } 658 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbinfo, 659 &content); 660 body->length = 0; 661 } 662 body->data[body->length++] = c; 663 total += 1; 664 if (body->length == sizeof(body->data)) { 665 if (__ops_get_debug_level(__FILE__)) { 666 (void) fprintf(stderr, "Got body (2):\n%s\n", 667 body->data); 668 } 669 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_BODY, cbinfo, 670 &content); 671 body->length = 0; 672 } 673 } 674 if (body->data[0] != '\n') { 675 (void) fprintf(stderr, 676 "process_dash_escaped: no newline in body data\n"); 677 return -1; 678 } 679 if (body->length != 1) { 680 (void) fprintf(stderr, 681 "process_dash_escaped: bad body length\n"); 682 return -1; 683 } 684 685 /* don't send that one character, because it's part of the trailer */ 686 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_TRAILER, cbinfo, &content2); 687 return total; 688 } 689 690 static int 691 add_header(dearmour_t *dearmour, const char *key, const char *value) 692 { 693 int n; 694 695 /* 696 * Check that the header is valid 697 */ 698 if (strcmp(key, "Version") == 0 || 699 strcmp(key, "Comment") == 0 || 700 strcmp(key, "MessageID") == 0 || 701 strcmp(key, "Hash") == 0 || 702 strcmp(key, "Charset") == 0) { 703 n = dearmour->headers.headerc; 704 dearmour->headers.headers = realloc(dearmour->headers.headers, 705 (n + 1) * sizeof(*dearmour->headers.headers)); 706 if (dearmour->headers.headers == NULL) { 707 (void) fprintf(stderr, "add_header: bad alloc\n"); 708 return 0; 709 } 710 dearmour->headers.headers[n].key = netpgp_strdup(key); 711 dearmour->headers.headers[n].value = netpgp_strdup(value); 712 dearmour->headers.headerc = n + 1; 713 return 1; 714 } 715 return 0; 716 } 717 718 /* \todo what does a return value of 0 indicate? 1 is good, -1 is bad */ 719 static int 720 parse_headers(dearmour_t *dearmour, __ops_error_t **errors, 721 __ops_reader_t * readinfo, __ops_cbdata_t * cbinfo) 722 { 723 unsigned nbuf; 724 unsigned size; 725 unsigned first = 1; 726 char *buf; 727 int ret = 1; 728 729 nbuf = 0; 730 size = 80; 731 if ((buf = calloc(1, size)) == NULL) { 732 (void) fprintf(stderr, "parse_headers: bad calloc\n"); 733 return -1; 734 } 735 for (;;) { 736 int c; 737 738 if ((c = read_char(dearmour, errors, readinfo, cbinfo, 1)) < 0) { 739 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "Unexpected EOF"); 740 ret = -1; 741 break; 742 } 743 if (c == '\n') { 744 char *s; 745 746 if (nbuf == 0) { 747 break; 748 } 749 750 if (nbuf >= size) { 751 (void) fprintf(stderr, 752 "parse_headers: bad size\n"); 753 return -1; 754 } 755 buf[nbuf] = '\0'; 756 757 if ((s = strchr(buf, ':')) == NULL) { 758 if (!first && !dearmour->allow_headers_without_gap) { 759 /* 760 * then we have seriously malformed 761 * armour 762 */ 763 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "No colon in armour header"); 764 ret = -1; 765 break; 766 } else { 767 if (first && 768 !(dearmour->allow_headers_without_gap || dearmour->allow_no_gap)) { 769 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "No colon in armour header (2)"); 770 /* 771 * then we have a nasty 772 * armoured block with no 773 * headers, not even a blank 774 * line. 775 */ 776 buf[nbuf] = '\n'; 777 push_back(dearmour, (uint8_t *) buf, nbuf + 1); 778 ret = -1; 779 break; 780 } 781 } 782 } else { 783 *s = '\0'; 784 if (s[1] != ' ') { 785 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "No space in armour header"); 786 ret = -1; 787 goto end; 788 } 789 if (!add_header(dearmour, buf, s + 2)) { 790 OPS_ERROR_1(errors, OPS_E_R_BAD_FORMAT, "Invalid header %s", buf); 791 ret = -1; 792 goto end; 793 } 794 nbuf = 0; 795 } 796 first = 0; 797 } else { 798 if (size <= nbuf + 1) { 799 size += size + 80; 800 buf = realloc(buf, size); 801 if (buf == NULL) { 802 (void) fprintf(stderr, "bad alloc\n"); 803 ret = -1; 804 goto end; 805 } 806 } 807 buf[nbuf++] = c; 808 } 809 } 810 811 end: 812 free(buf); 813 814 return ret; 815 } 816 817 static int 818 read4(dearmour_t *dearmour, __ops_error_t **errors, 819 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo, 820 int *pc, unsigned *pn, uint32_t *pl) 821 { 822 int n, c; 823 uint32_t l = 0; 824 825 for (n = 0; n < 4; ++n) { 826 c = read_char(dearmour, errors, readinfo, cbinfo, 1); 827 if (c < 0) { 828 dearmour->eof64 = 1; 829 return -1; 830 } 831 if (c == '-' || c == '=') { 832 break; 833 } 834 l <<= 6; 835 if (c >= 'A' && c <= 'Z') { 836 l += (uint32_t)(c - 'A'); 837 } else if (c >= 'a' && c <= 'z') { 838 l += (uint32_t)(c - 'a') + 26; 839 } else if (c >= '0' && c <= '9') { 840 l += (uint32_t)(c - '0') + 52; 841 } else if (c == '+') { 842 l += 62; 843 } else if (c == '/') { 844 l += 63; 845 } else { 846 --n; 847 l >>= 6; 848 } 849 } 850 851 *pc = c; 852 *pn = n; 853 *pl = l; 854 855 return 4; 856 } 857 858 unsigned 859 __ops_crc24(unsigned checksum, uint8_t c) 860 { 861 unsigned i; 862 863 checksum ^= c << 16; 864 for (i = 0; i < 8; i++) { 865 checksum <<= 1; 866 if (checksum & 0x1000000) 867 checksum ^= CRC24_POLY; 868 } 869 return (unsigned)(checksum & 0xffffffL); 870 } 871 872 static int 873 decode64(dearmour_t *dearmour, __ops_error_t **errors, 874 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 875 { 876 unsigned n; 877 int n2; 878 uint32_t l; 879 int c; 880 int ret; 881 882 if (dearmour->buffered) { 883 (void) fprintf(stderr, "decode64: bad dearmour->buffered\n"); 884 return 0; 885 } 886 887 ret = read4(dearmour, errors, readinfo, cbinfo, &c, &n, &l); 888 if (ret < 0) { 889 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "Badly formed base64"); 890 return 0; 891 } 892 if (n == 3) { 893 if (c != '=') { 894 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 895 "Badly terminated base64 (2)"); 896 return 0; 897 } 898 dearmour->buffered = 2; 899 dearmour->eof64 = 1; 900 l >>= 2; 901 } else if (n == 2) { 902 if (c != '=') { 903 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 904 "Badly terminated base64 (3)"); 905 return 0; 906 } 907 dearmour->buffered = 1; 908 dearmour->eof64 = 1; 909 l >>= 4; 910 c = read_char(dearmour, errors, readinfo, cbinfo, 0); 911 if (c != '=') { 912 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 913 "Badly terminated base64"); 914 return 0; 915 } 916 } else if (n == 0) { 917 if (!dearmour->prev_nl || c != '=') { 918 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 919 "Badly terminated base64 (4)"); 920 return 0; 921 } 922 dearmour->buffered = 0; 923 } else { 924 if (n != 4) { 925 (void) fprintf(stderr, 926 "decode64: bad n (!= 4)\n"); 927 return 0; 928 } 929 dearmour->buffered = 3; 930 if (c == '-' || c == '=') { 931 (void) fprintf(stderr, "decode64: bad c\n"); 932 return 0; 933 } 934 } 935 936 if (dearmour->buffered < 3 && dearmour->buffered > 0) { 937 /* then we saw padding */ 938 if (c != '=') { 939 (void) fprintf(stderr, "decode64: bad c (=)\n"); 940 return 0; 941 } 942 c = read_and_eat_whitespace(dearmour, errors, readinfo, cbinfo, 943 1); 944 if (c != '\n') { 945 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 946 "No newline at base64 end"); 947 return 0; 948 } 949 c = read_char(dearmour, errors, readinfo, cbinfo, 0); 950 if (c != '=') { 951 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 952 "No checksum at base64 end"); 953 return 0; 954 } 955 } 956 if (c == '=') { 957 /* now we are at the checksum */ 958 ret = read4(dearmour, errors, readinfo, cbinfo, &c, &n, 959 &dearmour->read_checksum); 960 if (ret < 0 || n != 4) { 961 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 962 "Error in checksum"); 963 return 0; 964 } 965 c = read_char(dearmour, errors, readinfo, cbinfo, 1); 966 if (dearmour->allow_trailing_whitespace) 967 c = eat_whitespace(c, dearmour, errors, readinfo, cbinfo, 968 1); 969 if (c != '\n') { 970 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 971 "Badly terminated checksum"); 972 return 0; 973 } 974 c = read_char(dearmour, errors, readinfo, cbinfo, 0); 975 if (c != '-') { 976 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 977 "Bad base64 trailer (2)"); 978 return 0; 979 } 980 } 981 if (c == '-') { 982 for (n = 0; n < 4; ++n) 983 if (read_char(dearmour, errors, readinfo, cbinfo, 984 0) != '-') { 985 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 986 "Bad base64 trailer"); 987 return 0; 988 } 989 dearmour->eof64 = 1; 990 } else { 991 if (!dearmour->buffered) { 992 (void) fprintf(stderr, "decode64: not buffered\n"); 993 return 0; 994 } 995 } 996 997 for (n = 0; n < dearmour->buffered; ++n) { 998 dearmour->buffer[n] = (uint8_t)l; 999 l >>= 8; 1000 } 1001 1002 for (n2 = dearmour->buffered - 1; n2 >= 0; --n2) 1003 dearmour->checksum = __ops_crc24((unsigned)dearmour->checksum, 1004 dearmour->buffer[n2]); 1005 1006 if (dearmour->eof64 && dearmour->read_checksum != dearmour->checksum) { 1007 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, "Checksum mismatch"); 1008 return 0; 1009 } 1010 return 1; 1011 } 1012 1013 static void 1014 base64(dearmour_t *dearmour) 1015 { 1016 dearmour->state = BASE64; 1017 dearmour->checksum = CRC24_INIT; 1018 dearmour->eof64 = 0; 1019 dearmour->buffered = 0; 1020 } 1021 1022 /* This reader is rather strange in that it can generate callbacks for */ 1023 /* content - this is because plaintext is not encapsulated in PGP */ 1024 /* packets... it also calls back for the text between the blocks. */ 1025 1026 static int 1027 armoured_data_reader(void *dest_, size_t length, __ops_error_t **errors, 1028 __ops_reader_t *readinfo, 1029 __ops_cbdata_t *cbinfo) 1030 { 1031 __ops_packet_t content; 1032 dearmour_t *dearmour; 1033 unsigned first; 1034 uint8_t *dest = dest_; 1035 char buf[1024]; 1036 int saved; 1037 int ret; 1038 1039 dearmour = __ops_reader_get_arg(readinfo); 1040 saved = (int)length; 1041 if (dearmour->eof64 && !dearmour->buffered) { 1042 if (dearmour->state != OUTSIDE_BLOCK && 1043 dearmour->state != AT_TRAILER_NAME) { 1044 (void) fprintf(stderr, 1045 "armoured_data_reader: bad dearmour state\n"); 1046 return 0; 1047 } 1048 } 1049 1050 while (length > 0) { 1051 unsigned count; 1052 unsigned n; 1053 int c; 1054 1055 flush(dearmour, cbinfo); 1056 switch (dearmour->state) { 1057 case OUTSIDE_BLOCK: 1058 /* 1059 * This code returns EOF rather than EARLY_EOF 1060 * because if we don't see a header line at all, then 1061 * it is just an EOF (and not a BLOCK_END) 1062 */ 1063 while (!dearmour->seen_nl) { 1064 if ((c = unarmoured_read_char(dearmour, errors, 1065 readinfo, cbinfo, 1)) < 0) { 1066 return 0; 1067 } 1068 } 1069 1070 /* 1071 * flush at this point so we definitely have room for 1072 * the header, and so we can easily erase it from the 1073 * buffer 1074 */ 1075 flush(dearmour, cbinfo); 1076 /* Find and consume the 5 leading '-' */ 1077 for (count = 0; count < 5; ++count) { 1078 if ((c = unarmoured_read_char(dearmour, errors, 1079 readinfo, cbinfo, 0)) < 0) { 1080 return 0; 1081 } 1082 if (c != '-') { 1083 goto reloop; 1084 } 1085 } 1086 1087 /* Now find the block type */ 1088 for (n = 0; n < sizeof(buf) - 1;) { 1089 if ((c = unarmoured_read_char(dearmour, errors, 1090 readinfo, cbinfo, 0)) < 0) { 1091 return 0; 1092 } 1093 if (c == '-') { 1094 goto got_minus; 1095 } 1096 buf[n++] = c; 1097 } 1098 /* then I guess this wasn't a proper header */ 1099 break; 1100 1101 got_minus: 1102 buf[n] = '\0'; 1103 1104 /* Consume trailing '-' */ 1105 for (count = 1; count < 5; ++count) { 1106 if ((c = unarmoured_read_char(dearmour, errors, 1107 readinfo, cbinfo, 0)) < 0) { 1108 return 0; 1109 } 1110 if (c != '-') { 1111 /* wasn't a header after all */ 1112 goto reloop; 1113 } 1114 } 1115 1116 /* Consume final NL */ 1117 if ((c = unarmoured_read_char(dearmour, errors, readinfo, 1118 cbinfo, 1)) < 0) { 1119 return 0; 1120 } 1121 if (dearmour->allow_trailing_whitespace) { 1122 if ((c = eat_whitespace(c, dearmour, errors, 1123 readinfo, cbinfo, 1)) < 0) { 1124 return 0; 1125 } 1126 } 1127 if (c != '\n') { 1128 /* wasn't a header line after all */ 1129 break; 1130 } 1131 1132 /* 1133 * Now we've seen the header, scrub it from the 1134 * buffer 1135 */ 1136 dearmour->unarmoredc = 0; 1137 1138 /* 1139 * But now we've seen a header line, then errors are 1140 * EARLY_EOF 1141 */ 1142 if ((ret = parse_headers(dearmour, errors, readinfo, 1143 cbinfo)) <= 0) { 1144 return -1; 1145 } 1146 1147 if (!set_lastseen_headerline(dearmour, buf, errors)) { 1148 return -1; 1149 } 1150 1151 if (strcmp(buf, "BEGIN PGP SIGNED MESSAGE") == 0) { 1152 __ops_dup_headers( 1153 &content.u.cleartext_head, 1154 &dearmour->headers); 1155 CALLBACK(OPS_PTAG_CT_SIGNED_CLEARTEXT_HEADER, 1156 cbinfo, 1157 &content); 1158 ret = process_dash_escaped(dearmour, errors, 1159 readinfo, cbinfo); 1160 if (ret <= 0) { 1161 return ret; 1162 } 1163 } else { 1164 content.u.armour_header.type = buf; 1165 content.u.armour_header.headers = 1166 dearmour->headers; 1167 (void) memset(&dearmour->headers, 0x0, 1168 sizeof(dearmour->headers)); 1169 CALLBACK(OPS_PTAG_CT_ARMOUR_HEADER, cbinfo, 1170 &content); 1171 base64(dearmour); 1172 } 1173 break; 1174 1175 case BASE64: 1176 first = 1; 1177 while (length > 0) { 1178 if (!dearmour->buffered) { 1179 if (!dearmour->eof64) { 1180 ret = decode64(dearmour, 1181 errors, readinfo, cbinfo); 1182 if (ret <= 0) { 1183 return ret; 1184 } 1185 } 1186 if (!dearmour->buffered) { 1187 if (!dearmour->eof64) { 1188 (void) fprintf(stderr, 1189 "armoured_data_reader: bad dearmour eof64\n"); 1190 return 0; 1191 } 1192 if (first) { 1193 dearmour->state = 1194 AT_TRAILER_NAME; 1195 goto reloop; 1196 } 1197 return -1; 1198 } 1199 } 1200 if (!dearmour->buffered) { 1201 (void) fprintf(stderr, 1202 "armoured_data_reader: bad dearmour buffered\n"); 1203 return 0; 1204 } 1205 *dest = dearmour->buffer[--dearmour->buffered]; 1206 ++dest; 1207 --length; 1208 first = 0; 1209 } 1210 if (dearmour->eof64 && !dearmour->buffered) { 1211 dearmour->state = AT_TRAILER_NAME; 1212 } 1213 break; 1214 1215 case AT_TRAILER_NAME: 1216 for (n = 0; n < sizeof(buf) - 1;) { 1217 if ((c = read_char(dearmour, errors, readinfo, 1218 cbinfo, 0)) < 0) { 1219 return -1; 1220 } 1221 if (c == '-') { 1222 goto got_minus2; 1223 } 1224 buf[n++] = c; 1225 } 1226 /* then I guess this wasn't a proper trailer */ 1227 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 1228 "Bad ASCII armour trailer"); 1229 break; 1230 1231 got_minus2: 1232 buf[n] = '\0'; 1233 1234 if (!set_lastseen_headerline(dearmour, buf, errors)) { 1235 return -1; 1236 } 1237 1238 /* Consume trailing '-' */ 1239 for (count = 1; count < 5; ++count) { 1240 if ((c = read_char(dearmour, errors, readinfo, 1241 cbinfo, 0)) < 0) { 1242 return -1; 1243 } 1244 if (c != '-') { 1245 /* wasn't a trailer after all */ 1246 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 1247 "Bad ASCII armour trailer (2)"); 1248 } 1249 } 1250 1251 /* Consume final NL */ 1252 if ((c = read_char(dearmour, errors, readinfo, cbinfo, 1253 1)) < 0) { 1254 return -1; 1255 } 1256 if (dearmour->allow_trailing_whitespace) { 1257 if ((c = eat_whitespace(c, dearmour, errors, 1258 readinfo, cbinfo, 1)) < 0) { 1259 return 0; 1260 } 1261 } 1262 if (c != '\n') { 1263 /* wasn't a trailer line after all */ 1264 OPS_ERROR(errors, OPS_E_R_BAD_FORMAT, 1265 "Bad ASCII armour trailer (3)"); 1266 } 1267 1268 if (strncmp(buf, "BEGIN ", 6) == 0) { 1269 if (!set_lastseen_headerline(dearmour, buf, 1270 errors)) { 1271 return -1; 1272 } 1273 if ((ret = parse_headers(dearmour, errors, 1274 readinfo, cbinfo)) <= 0) { 1275 return ret; 1276 } 1277 content.u.armour_header.type = buf; 1278 content.u.armour_header.headers = 1279 dearmour->headers; 1280 (void) memset(&dearmour->headers, 0x0, 1281 sizeof(dearmour->headers)); 1282 CALLBACK(OPS_PTAG_CT_ARMOUR_HEADER, cbinfo, 1283 &content); 1284 base64(dearmour); 1285 } else { 1286 content.u.armour_trailer = buf; 1287 CALLBACK(OPS_PTAG_CT_ARMOUR_TRAILER, cbinfo, 1288 &content); 1289 dearmour->state = OUTSIDE_BLOCK; 1290 } 1291 break; 1292 } 1293 reloop: 1294 continue; 1295 } 1296 1297 return saved; 1298 } 1299 1300 static void 1301 armoured_data_destroyer(__ops_reader_t *readinfo) 1302 { 1303 free(__ops_reader_get_arg(readinfo)); 1304 } 1305 1306 /** 1307 * \ingroup Core_Readers_Armour 1308 * \brief Pushes dearmouring reader onto stack 1309 * \param parse_info Usual structure containing information about to how to do the parse 1310 * \sa __ops_reader_pop_dearmour() 1311 */ 1312 void 1313 __ops_reader_push_dearmour(__ops_stream_t *parse_info) 1314 /* 1315 * This function originally had these params to cater for packets which 1316 * didn't strictly match the RFC. The initial 0.5 release is only going to 1317 * support strict checking. If it becomes desirable to support loose checking 1318 * of armoured packets and these params are reinstated, parse_headers() must 1319 * be fixed so that these flags work correctly. 1320 * 1321 * // Allow headers in armoured data that are not separated from the data by a 1322 * blank line unsigned without_gap, 1323 * 1324 * // Allow no blank line at the start of armoured data unsigned no_gap, 1325 * 1326 * //Allow armoured data to have trailing whitespace where we strictly would not 1327 * expect it unsigned trailing_whitespace 1328 */ 1329 { 1330 dearmour_t *dearmour; 1331 1332 if ((dearmour = calloc(1, sizeof(*dearmour))) == NULL) { 1333 (void) fprintf(stderr, "__ops_reader_push_dearmour: bad alloc\n"); 1334 } else { 1335 dearmour->seen_nl = 1; 1336 /* 1337 dearmour->allow_headers_without_gap=without_gap; 1338 dearmour->allow_no_gap=no_gap; 1339 dearmour->allow_trailing_whitespace=trailing_whitespace; 1340 */ 1341 dearmour->expect_sig = 0; 1342 dearmour->got_sig = 0; 1343 1344 __ops_reader_push(parse_info, armoured_data_reader, 1345 armoured_data_destroyer, dearmour); 1346 } 1347 } 1348 1349 /** 1350 * \ingroup Core_Readers_Armour 1351 * \brief Pops dearmour reader from stock 1352 * \param stream 1353 * \sa __ops_reader_push_dearmour() 1354 */ 1355 void 1356 __ops_reader_pop_dearmour(__ops_stream_t *stream) 1357 { 1358 dearmour_t *dearmour; 1359 1360 dearmour = __ops_reader_get_arg(__ops_readinfo(stream)); 1361 free(dearmour); 1362 __ops_reader_pop(stream); 1363 } 1364 1365 /**************************************************************************/ 1366 1367 /* this is actually used for *decrypting* */ 1368 typedef struct { 1369 uint8_t decrypted[1024 * 15]; 1370 size_t c; 1371 size_t off; 1372 __ops_crypt_t *decrypt; 1373 __ops_region_t *region; 1374 unsigned prevplain:1; 1375 } encrypted_t; 1376 1377 static int 1378 encrypted_data_reader(void *dest, 1379 size_t length, 1380 __ops_error_t **errors, 1381 __ops_reader_t *readinfo, 1382 __ops_cbdata_t *cbinfo) 1383 { 1384 encrypted_t *encrypted; 1385 char *cdest; 1386 int saved; 1387 1388 encrypted = __ops_reader_get_arg(readinfo); 1389 saved = (int)length; 1390 /* 1391 * V3 MPIs have the count plain and the cipher is reset after each 1392 * count 1393 */ 1394 if (encrypted->prevplain && !readinfo->parent->reading_mpi_len) { 1395 if (!readinfo->parent->reading_v3_secret) { 1396 (void) fprintf(stderr, 1397 "encrypted_data_reader: bad v3 secret\n"); 1398 return -1; 1399 } 1400 encrypted->decrypt->decrypt_resync(encrypted->decrypt); 1401 encrypted->prevplain = 0; 1402 } else if (readinfo->parent->reading_v3_secret && 1403 readinfo->parent->reading_mpi_len) { 1404 encrypted->prevplain = 1; 1405 } 1406 while (length > 0) { 1407 if (encrypted->c) { 1408 unsigned n; 1409 1410 /* 1411 * if we are reading v3 we should never read 1412 * more than we're asked for */ 1413 if (length < encrypted->c && 1414 (readinfo->parent->reading_v3_secret || 1415 readinfo->parent->exact_read)) { 1416 (void) fprintf(stderr, 1417 "encrypted_data_reader: bad v3 read\n"); 1418 return 0; 1419 } 1420 n = (int)MIN(length, encrypted->c); 1421 (void) memcpy(dest, 1422 encrypted->decrypted + encrypted->off, n); 1423 encrypted->c -= n; 1424 encrypted->off += n; 1425 length -= n; 1426 cdest = dest; 1427 cdest += n; 1428 dest = cdest; 1429 } else { 1430 unsigned n = encrypted->region->length; 1431 uint8_t buffer[1024]; 1432 1433 if (!n) { 1434 return -1; 1435 } 1436 if (!encrypted->region->indeterminate) { 1437 n -= encrypted->region->readc; 1438 if (n == 0) { 1439 return (int)(saved - length); 1440 } 1441 if (n > sizeof(buffer)) { 1442 n = sizeof(buffer); 1443 } 1444 } else { 1445 n = sizeof(buffer); 1446 } 1447 1448 /* 1449 * we can only read as much as we're asked for 1450 * in v3 keys because they're partially 1451 * unencrypted! */ 1452 if ((readinfo->parent->reading_v3_secret || 1453 readinfo->parent->exact_read) && n > length) { 1454 n = (unsigned)length; 1455 } 1456 1457 if (!__ops_stacked_limited_read(buffer, n, 1458 encrypted->region, errors, readinfo, cbinfo)) { 1459 return -1; 1460 } 1461 if (!readinfo->parent->reading_v3_secret || 1462 !readinfo->parent->reading_mpi_len) { 1463 encrypted->c = 1464 __ops_decrypt_se_ip(encrypted->decrypt, 1465 encrypted->decrypted, buffer, n); 1466 1467 if (__ops_get_debug_level(__FILE__)) { 1468 hexdump(stderr, "encrypted", buffer, 16); 1469 hexdump(stderr, "decrypted", encrypted->decrypted, 16); 1470 } 1471 } else { 1472 (void) memcpy( 1473 &encrypted->decrypted[encrypted->off], buffer, n); 1474 encrypted->c = n; 1475 } 1476 1477 if (encrypted->c == 0) { 1478 (void) fprintf(stderr, 1479 "encrypted_data_reader: 0 decrypted count\n"); 1480 return 0; 1481 } 1482 1483 encrypted->off = 0; 1484 } 1485 } 1486 1487 return saved; 1488 } 1489 1490 static void 1491 encrypted_data_destroyer(__ops_reader_t *readinfo) 1492 { 1493 free(__ops_reader_get_arg(readinfo)); 1494 } 1495 1496 /** 1497 * \ingroup Core_Readers_SE 1498 * \brief Pushes decryption reader onto stack 1499 * \sa __ops_reader_pop_decrypt() 1500 */ 1501 void 1502 __ops_reader_push_decrypt(__ops_stream_t *stream, __ops_crypt_t *decrypt, 1503 __ops_region_t *region) 1504 { 1505 encrypted_t *encrypted; 1506 1507 if ((encrypted = calloc(1, sizeof(*encrypted))) == NULL) { 1508 (void) fprintf(stderr, "__ops_reader_push_decrypted: bad alloc\n"); 1509 } else { 1510 encrypted->decrypt = decrypt; 1511 encrypted->region = region; 1512 __ops_decrypt_init(encrypted->decrypt); 1513 __ops_reader_push(stream, encrypted_data_reader, 1514 encrypted_data_destroyer, encrypted); 1515 } 1516 } 1517 1518 /** 1519 * \ingroup Core_Readers_Encrypted 1520 * \brief Pops decryption reader from stack 1521 * \sa __ops_reader_push_decrypt() 1522 */ 1523 void 1524 __ops_reader_pop_decrypt(__ops_stream_t *stream) 1525 { 1526 encrypted_t *encrypted; 1527 1528 encrypted = __ops_reader_get_arg(__ops_readinfo(stream)); 1529 encrypted->decrypt->decrypt_finish(encrypted->decrypt); 1530 free(encrypted); 1531 __ops_reader_pop(stream); 1532 } 1533 1534 /**************************************************************************/ 1535 1536 typedef struct { 1537 /* boolean: 0 once we've done the preamble/MDC checks */ 1538 /* and are reading from the plaintext */ 1539 int passed_checks; 1540 uint8_t *plaintext; 1541 size_t plaintext_available; 1542 size_t plaintext_offset; 1543 __ops_region_t *region; 1544 __ops_crypt_t *decrypt; 1545 } decrypt_se_ip_t; 1546 1547 /* 1548 Gets entire SE_IP data packet. 1549 Verifies leading preamble 1550 Verifies trailing MDC packet 1551 Then passes up plaintext as requested 1552 */ 1553 static int 1554 se_ip_data_reader(void *dest_, 1555 size_t len, 1556 __ops_error_t **errors, 1557 __ops_reader_t *readinfo, 1558 __ops_cbdata_t *cbinfo) 1559 { 1560 decrypt_se_ip_t *se_ip; 1561 __ops_region_t decrypted_region; 1562 unsigned n = 0; 1563 1564 se_ip = __ops_reader_get_arg(readinfo); 1565 if (!se_ip->passed_checks) { 1566 uint8_t *buf = NULL; 1567 uint8_t hashed[OPS_SHA1_HASH_SIZE]; 1568 uint8_t *preamble; 1569 uint8_t *plaintext; 1570 uint8_t *mdc; 1571 uint8_t *mdc_hash; 1572 __ops_hash_t hash; 1573 size_t b; 1574 size_t sz_preamble; 1575 size_t sz_mdc_hash; 1576 size_t sz_mdc; 1577 size_t sz_plaintext; 1578 1579 __ops_hash_any(&hash, OPS_HASH_SHA1); 1580 if (!hash.init(&hash)) { 1581 (void) fprintf(stderr, 1582 "se_ip_data_reader: can't init hash\n"); 1583 return -1; 1584 } 1585 1586 __ops_init_subregion(&decrypted_region, NULL); 1587 decrypted_region.length = 1588 se_ip->region->length - se_ip->region->readc; 1589 if ((buf = calloc(1, decrypted_region.length)) == NULL) { 1590 (void) fprintf(stderr, "se_ip_data_reader: bad alloc\n"); 1591 return -1; 1592 } 1593 1594 /* read entire SE IP packet */ 1595 if (!__ops_stacked_limited_read(buf, decrypted_region.length, 1596 &decrypted_region, errors, readinfo, cbinfo)) { 1597 free(buf); 1598 return -1; 1599 } 1600 if (__ops_get_debug_level(__FILE__)) { 1601 hexdump(stderr, "SE IP packet", buf, decrypted_region.length); 1602 } 1603 /* verify leading preamble */ 1604 if (__ops_get_debug_level(__FILE__)) { 1605 hexdump(stderr, "preamble", buf, se_ip->decrypt->blocksize); 1606 } 1607 b = se_ip->decrypt->blocksize; 1608 if (buf[b - 2] != buf[b] || buf[b - 1] != buf[b + 1]) { 1609 fprintf(stderr, 1610 "Bad symmetric decrypt (%02x%02x vs %02x%02x)\n", 1611 buf[b - 2], buf[b - 1], buf[b], buf[b + 1]); 1612 OPS_ERROR(errors, OPS_E_PROTO_BAD_SYMMETRIC_DECRYPT, 1613 "Bad symmetric decrypt when parsing SE IP packet"); 1614 free(buf); 1615 return -1; 1616 } 1617 /* Verify trailing MDC hash */ 1618 1619 sz_preamble = se_ip->decrypt->blocksize + 2; 1620 sz_mdc_hash = OPS_SHA1_HASH_SIZE; 1621 sz_mdc = 1 + 1 + sz_mdc_hash; 1622 sz_plaintext = (decrypted_region.length - sz_preamble) - sz_mdc; 1623 1624 preamble = buf; 1625 plaintext = buf + sz_preamble; 1626 mdc = plaintext + sz_plaintext; 1627 mdc_hash = mdc + 2; 1628 1629 if (__ops_get_debug_level(__FILE__)) { 1630 hexdump(stderr, "plaintext", plaintext, sz_plaintext); 1631 hexdump(stderr, "mdc", mdc, sz_mdc); 1632 } 1633 __ops_calc_mdc_hash(preamble, sz_preamble, plaintext, 1634 (unsigned)sz_plaintext, hashed); 1635 1636 if (memcmp(mdc_hash, hashed, OPS_SHA1_HASH_SIZE) != 0) { 1637 OPS_ERROR(errors, OPS_E_V_BAD_HASH, 1638 "Bad hash in MDC packet"); 1639 free(buf); 1640 return 0; 1641 } 1642 /* all done with the checks */ 1643 /* now can start reading from the plaintext */ 1644 if (se_ip->plaintext) { 1645 (void) fprintf(stderr, 1646 "se_ip_data_reader: bad plaintext\n"); 1647 return 0; 1648 } 1649 if ((se_ip->plaintext = calloc(1, sz_plaintext)) == NULL) { 1650 (void) fprintf(stderr, 1651 "se_ip_data_reader: bad alloc\n"); 1652 return 0; 1653 } 1654 memcpy(se_ip->plaintext, plaintext, sz_plaintext); 1655 se_ip->plaintext_available = sz_plaintext; 1656 1657 se_ip->passed_checks = 1; 1658 1659 free(buf); 1660 } 1661 n = (unsigned)len; 1662 if (n > se_ip->plaintext_available) { 1663 n = (unsigned)se_ip->plaintext_available; 1664 } 1665 1666 memcpy(dest_, se_ip->plaintext + se_ip->plaintext_offset, n); 1667 se_ip->plaintext_available -= n; 1668 se_ip->plaintext_offset += n; 1669 /* len -= n; - not used at all, for info only */ 1670 1671 return n; 1672 } 1673 1674 static void 1675 se_ip_data_destroyer(__ops_reader_t *readinfo) 1676 { 1677 decrypt_se_ip_t *se_ip; 1678 1679 se_ip = __ops_reader_get_arg(readinfo); 1680 free(se_ip->plaintext); 1681 free(se_ip); 1682 } 1683 1684 /** 1685 \ingroup Internal_Readers_SEIP 1686 */ 1687 void 1688 __ops_reader_push_se_ip_data(__ops_stream_t *stream, __ops_crypt_t *decrypt, 1689 __ops_region_t * region) 1690 { 1691 decrypt_se_ip_t *se_ip; 1692 1693 if ((se_ip = calloc(1, sizeof(*se_ip))) == NULL) { 1694 (void) fprintf(stderr, "__ops_reader_push_se_ip_data: bad alloc\n"); 1695 } else { 1696 se_ip->region = region; 1697 se_ip->decrypt = decrypt; 1698 __ops_reader_push(stream, se_ip_data_reader, se_ip_data_destroyer, 1699 se_ip); 1700 } 1701 } 1702 1703 /** 1704 \ingroup Internal_Readers_SEIP 1705 */ 1706 void 1707 __ops_reader_pop_se_ip_data(__ops_stream_t *stream) 1708 { 1709 /* 1710 * decrypt_se_ip_t 1711 * *se_ip=__ops_reader_get_arg(__ops_readinfo(stream)); 1712 */ 1713 /* free(se_ip); */ 1714 __ops_reader_pop(stream); 1715 } 1716 1717 /**************************************************************************/ 1718 1719 /** Arguments for reader_fd 1720 */ 1721 typedef struct mmap_reader_t { 1722 void *mem; /* memory mapped file */ 1723 uint64_t size; /* size of file */ 1724 uint64_t offset; /* current offset in file */ 1725 int fd; /* file descriptor */ 1726 } mmap_reader_t; 1727 1728 1729 /** 1730 * \ingroup Core_Readers 1731 * 1732 * __ops_reader_fd() attempts to read up to "plength" bytes from the file 1733 * descriptor in "parse_info" into the buffer starting at "dest" using the 1734 * rules contained in "flags" 1735 * 1736 * \param dest Pointer to previously allocated buffer 1737 * \param plength Number of bytes to try to read 1738 * \param flags Rules about reading to use 1739 * \param readinfo Reader info 1740 * \param cbinfo Callback info 1741 * 1742 * \return n Number of bytes read 1743 * 1744 * OPS_R_EARLY_EOF and OPS_R_ERROR push errors on the stack 1745 */ 1746 static int 1747 fd_reader(void *dest, size_t length, __ops_error_t **errors, 1748 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 1749 { 1750 mmap_reader_t *reader; 1751 int n; 1752 1753 __OPS_USED(cbinfo); 1754 reader = __ops_reader_get_arg(readinfo); 1755 n = (int)read(reader->fd, dest, length); 1756 if (n == 0) 1757 return 0; 1758 if (n < 0) { 1759 OPS_SYSTEM_ERROR_1(errors, OPS_E_R_READ_FAILED, "read", 1760 "file descriptor %d", reader->fd); 1761 return -1; 1762 } 1763 return n; 1764 } 1765 1766 static void 1767 reader_fd_destroyer(__ops_reader_t *readinfo) 1768 { 1769 free(__ops_reader_get_arg(readinfo)); 1770 } 1771 1772 /** 1773 \ingroup Core_Readers_First 1774 \brief Starts stack with file reader 1775 */ 1776 1777 void 1778 __ops_reader_set_fd(__ops_stream_t *stream, int fd) 1779 { 1780 mmap_reader_t *reader; 1781 1782 if ((reader = calloc(1, sizeof(*reader))) == NULL) { 1783 (void) fprintf(stderr, "__ops_reader_set_fd: bad alloc\n"); 1784 } else { 1785 reader->fd = fd; 1786 __ops_reader_set(stream, fd_reader, reader_fd_destroyer, reader); 1787 } 1788 } 1789 1790 /**************************************************************************/ 1791 1792 typedef struct { 1793 const uint8_t *buffer; 1794 size_t length; 1795 size_t offset; 1796 } reader_mem_t; 1797 1798 static int 1799 mem_reader(void *dest, size_t length, __ops_error_t **errors, 1800 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 1801 { 1802 reader_mem_t *reader = __ops_reader_get_arg(readinfo); 1803 unsigned n; 1804 1805 __OPS_USED(cbinfo); 1806 __OPS_USED(errors); 1807 1808 if (reader->offset + length > reader->length) 1809 n = (unsigned)(reader->length - reader->offset); 1810 else 1811 n = (unsigned)length; 1812 1813 if (n == (unsigned)0) 1814 return 0; 1815 1816 memcpy(dest, reader->buffer + reader->offset, n); 1817 reader->offset += n; 1818 1819 return n; 1820 } 1821 1822 static void 1823 mem_destroyer(__ops_reader_t *readinfo) 1824 { 1825 free(__ops_reader_get_arg(readinfo)); 1826 } 1827 1828 /** 1829 \ingroup Core_Readers_First 1830 \brief Starts stack with memory reader 1831 */ 1832 1833 void 1834 __ops_reader_set_memory(__ops_stream_t *stream, const void *buffer, 1835 size_t length) 1836 { 1837 reader_mem_t *mem; 1838 1839 if ((mem = calloc(1, sizeof(*mem))) == NULL) { 1840 (void) fprintf(stderr, "__ops_reader_set_memory: bad alloc\n"); 1841 } else { 1842 mem->buffer = buffer; 1843 mem->length = length; 1844 mem->offset = 0; 1845 __ops_reader_set(stream, mem_reader, mem_destroyer, mem); 1846 } 1847 } 1848 1849 /**************************************************************************/ 1850 1851 /** 1852 \ingroup Core_Writers 1853 \brief Create and initialise output and mem; Set for writing to mem 1854 \param output Address where new output pointer will be set 1855 \param mem Address when new mem pointer will be set 1856 \param bufsz Initial buffer size (will automatically be increased when necessary) 1857 \note It is the caller's responsiblity to free output and mem. 1858 \sa __ops_teardown_memory_write() 1859 */ 1860 void 1861 __ops_setup_memory_write(__ops_output_t **output, __ops_memory_t **mem, size_t bufsz) 1862 { 1863 /* 1864 * initialise needed structures for writing to memory 1865 */ 1866 1867 *output = __ops_output_new(); 1868 *mem = __ops_memory_new(); 1869 1870 __ops_memory_init(*mem, bufsz); 1871 1872 __ops_writer_set_memory(*output, *mem); 1873 } 1874 1875 /** 1876 \ingroup Core_Writers 1877 \brief Closes writer and frees output and mem 1878 \param output 1879 \param mem 1880 \sa __ops_setup_memory_write() 1881 */ 1882 void 1883 __ops_teardown_memory_write(__ops_output_t *output, __ops_memory_t *mem) 1884 { 1885 __ops_writer_close(output);/* new */ 1886 __ops_output_delete(output); 1887 __ops_memory_free(mem); 1888 } 1889 1890 /** 1891 \ingroup Core_Readers 1892 \brief Create parse_info and sets to read from memory 1893 \param stream Address where new parse_info will be set 1894 \param mem Memory to read from 1895 \param arg Reader-specific arg 1896 \param callback Callback to use with reader 1897 \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification) 1898 \note It is the caller's responsiblity to free parse_info 1899 \sa __ops_teardown_memory_read() 1900 */ 1901 void 1902 __ops_setup_memory_read(__ops_io_t *io, 1903 __ops_stream_t **stream, 1904 __ops_memory_t *mem, 1905 void *vp, 1906 __ops_cb_ret_t callback(const __ops_packet_t *, 1907 __ops_cbdata_t *), 1908 unsigned accumulate) 1909 { 1910 *stream = __ops_new(sizeof(**stream)); 1911 (*stream)->io = (*stream)->cbinfo.io = io; 1912 __ops_set_callback(*stream, callback, vp); 1913 __ops_reader_set_memory(*stream, 1914 __ops_mem_data(mem), 1915 __ops_mem_len(mem)); 1916 if (accumulate) { 1917 (*stream)->readinfo.accumulate = 1; 1918 } 1919 } 1920 1921 /** 1922 \ingroup Core_Readers 1923 \brief Frees stream and mem 1924 \param stream 1925 \param mem 1926 \sa __ops_setup_memory_read() 1927 */ 1928 void 1929 __ops_teardown_memory_read(__ops_stream_t *stream, __ops_memory_t *mem) 1930 { 1931 __ops_stream_delete(stream); 1932 __ops_memory_free(mem); 1933 } 1934 1935 /** 1936 \ingroup Core_Writers 1937 \brief Create and initialise output and mem; Set for writing to file 1938 \param output Address where new output pointer will be set 1939 \param filename File to write to 1940 \param allow_overwrite Allows file to be overwritten, if set. 1941 \return Newly-opened file descriptor 1942 \note It is the caller's responsiblity to free output and to close fd. 1943 \sa __ops_teardown_file_write() 1944 */ 1945 int 1946 __ops_setup_file_write(__ops_output_t **output, const char *filename, 1947 unsigned allow_overwrite) 1948 { 1949 int fd = 0; 1950 int flags = 0; 1951 1952 /* 1953 * initialise needed structures for writing to file 1954 */ 1955 if (filename == NULL) { 1956 /* write to stdout */ 1957 fd = STDOUT_FILENO; 1958 } else { 1959 flags = O_WRONLY | O_CREAT; 1960 if (allow_overwrite) 1961 flags |= O_TRUNC; 1962 else 1963 flags |= O_EXCL; 1964 #ifdef O_BINARY 1965 flags |= O_BINARY; 1966 #endif 1967 fd = open(filename, flags, 0600); 1968 if (fd < 0) { 1969 perror(filename); 1970 return fd; 1971 } 1972 } 1973 *output = __ops_output_new(); 1974 __ops_writer_set_fd(*output, fd); 1975 return fd; 1976 } 1977 1978 /** 1979 \ingroup Core_Writers 1980 \brief Closes writer, frees info, closes fd 1981 \param output 1982 \param fd 1983 */ 1984 void 1985 __ops_teardown_file_write(__ops_output_t *output, int fd) 1986 { 1987 __ops_writer_close(output); 1988 close(fd); 1989 __ops_output_delete(output); 1990 } 1991 1992 /** 1993 \ingroup Core_Writers 1994 \brief As __ops_setup_file_write, but appends to file 1995 */ 1996 int 1997 __ops_setup_file_append(__ops_output_t **output, const char *filename) 1998 { 1999 int fd; 2000 2001 /* 2002 * initialise needed structures for writing to file 2003 */ 2004 #ifdef O_BINARY 2005 fd = open(filename, O_WRONLY | O_APPEND | O_BINARY, 0600); 2006 #else 2007 fd = open(filename, O_WRONLY | O_APPEND, 0600); 2008 #endif 2009 if (fd >= 0) { 2010 *output = __ops_output_new(); 2011 __ops_writer_set_fd(*output, fd); 2012 } 2013 return fd; 2014 } 2015 2016 /** 2017 \ingroup Core_Writers 2018 \brief As __ops_teardown_file_write() 2019 */ 2020 void 2021 __ops_teardown_file_append(__ops_output_t *output, int fd) 2022 { 2023 __ops_teardown_file_write(output, fd); 2024 } 2025 2026 /** 2027 \ingroup Core_Readers 2028 \brief Creates parse_info, opens file, and sets to read from file 2029 \param stream Address where new parse_info will be set 2030 \param filename Name of file to read 2031 \param vp Reader-specific arg 2032 \param callback Callback to use when reading 2033 \param accumulate Set if we need to accumulate as we read. (Usually 0 unless doing signature verification) 2034 \note It is the caller's responsiblity to free parse_info and to close fd 2035 \sa __ops_teardown_file_read() 2036 */ 2037 int 2038 __ops_setup_file_read(__ops_io_t *io, 2039 __ops_stream_t **stream, 2040 const char *filename, 2041 void *vp, 2042 __ops_cb_ret_t callback(const __ops_packet_t *, 2043 __ops_cbdata_t *), 2044 unsigned accumulate) 2045 { 2046 int fd; 2047 2048 #ifdef O_BINARY 2049 fd = open(filename, O_RDONLY | O_BINARY); 2050 #else 2051 fd = open(filename, O_RDONLY); 2052 #endif 2053 if (fd < 0) { 2054 (void) fprintf(io->errs, "can't open \"%s\"\n", filename); 2055 return fd; 2056 } 2057 *stream = __ops_new(sizeof(**stream)); 2058 (*stream)->io = (*stream)->cbinfo.io = io; 2059 __ops_set_callback(*stream, callback, vp); 2060 #ifdef USE_MMAP_FOR_FILES 2061 __ops_reader_set_mmap(*stream, fd); 2062 #else 2063 __ops_reader_set_fd(*stream, fd); 2064 #endif 2065 if (accumulate) { 2066 (*stream)->readinfo.accumulate = 1; 2067 } 2068 return fd; 2069 } 2070 2071 /** 2072 \ingroup Core_Readers 2073 \brief Frees stream and closes fd 2074 \param stream 2075 \param fd 2076 \sa __ops_setup_file_read() 2077 */ 2078 void 2079 __ops_teardown_file_read(__ops_stream_t *stream, int fd) 2080 { 2081 close(fd); 2082 __ops_stream_delete(stream); 2083 } 2084 2085 __ops_cb_ret_t 2086 __ops_litdata_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 2087 { 2088 const __ops_contents_t *content = &pkt->u; 2089 2090 if (__ops_get_debug_level(__FILE__)) { 2091 printf("__ops_litdata_cb: "); 2092 __ops_print_packet(&cbinfo->printstate, pkt); 2093 } 2094 /* Read data from packet into static buffer */ 2095 switch (pkt->tag) { 2096 case OPS_PTAG_CT_LITDATA_BODY: 2097 /* if writer enabled, use it */ 2098 if (cbinfo->output) { 2099 if (__ops_get_debug_level(__FILE__)) { 2100 printf("__ops_litdata_cb: length is %u\n", 2101 content->litdata_body.length); 2102 } 2103 __ops_write(cbinfo->output, 2104 content->litdata_body.data, 2105 content->litdata_body.length); 2106 } 2107 break; 2108 2109 case OPS_PTAG_CT_LITDATA_HEADER: 2110 /* ignore */ 2111 break; 2112 2113 default: 2114 break; 2115 } 2116 2117 return OPS_RELEASE_MEMORY; 2118 } 2119 2120 __ops_cb_ret_t 2121 __ops_pk_sesskey_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 2122 { 2123 const __ops_contents_t *content = &pkt->u; 2124 unsigned from; 2125 __ops_io_t *io; 2126 2127 io = cbinfo->io; 2128 if (__ops_get_debug_level(__FILE__)) { 2129 __ops_print_packet(&cbinfo->printstate, pkt); 2130 } 2131 /* Read data from packet into static buffer */ 2132 switch (pkt->tag) { 2133 case OPS_PTAG_CT_PK_SESSION_KEY: 2134 if (__ops_get_debug_level(__FILE__)) { 2135 printf("OPS_PTAG_CT_PK_SESSION_KEY\n"); 2136 } 2137 if (!cbinfo->cryptinfo.secring) { 2138 (void) fprintf(io->errs, 2139 "__ops_pk_sesskey_cb: bad keyring\n"); 2140 return (__ops_cb_ret_t)0; 2141 } 2142 from = 0; 2143 cbinfo->cryptinfo.keydata = 2144 __ops_getkeybyid(io, cbinfo->cryptinfo.secring, 2145 content->pk_sesskey.key_id, &from, NULL); 2146 if (!cbinfo->cryptinfo.keydata) { 2147 break; 2148 } 2149 break; 2150 2151 default: 2152 break; 2153 } 2154 2155 return OPS_RELEASE_MEMORY; 2156 } 2157 2158 /** 2159 \ingroup Core_Callbacks 2160 2161 \brief Callback to get secret key, decrypting if necessary. 2162 2163 @verbatim 2164 This callback does the following: 2165 * finds the session key in the keyring 2166 * gets a passphrase if required 2167 * decrypts the secret key, if necessary 2168 * sets the seckey in the content struct 2169 @endverbatim 2170 */ 2171 2172 __ops_cb_ret_t 2173 __ops_get_seckey_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 2174 { 2175 const __ops_contents_t *content = &pkt->u; 2176 const __ops_seckey_t *secret; 2177 const __ops_key_t *pubkey; 2178 const __ops_key_t *keypair; 2179 unsigned from; 2180 __ops_io_t *io; 2181 2182 io = cbinfo->io; 2183 if (__ops_get_debug_level(__FILE__)) { 2184 __ops_print_packet(&cbinfo->printstate, pkt); 2185 } 2186 switch (pkt->tag) { 2187 case OPS_GET_SECKEY: 2188 /* print key from pubring */ 2189 from = 0; 2190 pubkey = __ops_getkeybyid(io, cbinfo->cryptinfo.pubring, 2191 content->get_seckey.pk_sesskey->key_id, 2192 &from, NULL); 2193 /* validate key from secring */ 2194 from = 0; 2195 cbinfo->cryptinfo.keydata = 2196 __ops_getkeybyid(io, cbinfo->cryptinfo.secring, 2197 content->get_seckey.pk_sesskey->key_id, 2198 &from, NULL); 2199 if (!cbinfo->cryptinfo.keydata || 2200 !__ops_is_key_secret(cbinfo->cryptinfo.keydata)) { 2201 return (__ops_cb_ret_t)0; 2202 } 2203 keypair = cbinfo->cryptinfo.keydata; 2204 if (pubkey == NULL) { 2205 pubkey = keypair; 2206 } 2207 do { 2208 /* print out the user id */ 2209 __ops_print_keydata(io, cbinfo->cryptinfo.pubring, pubkey, 2210 "signature ", &pubkey->key.pubkey, 0); 2211 /* now decrypt key */ 2212 secret = __ops_decrypt_seckey(keypair, cbinfo->passfp); 2213 if (secret == NULL) { 2214 (void) fprintf(io->errs, "Bad passphrase\n"); 2215 } 2216 } while (secret == NULL); 2217 *content->get_seckey.seckey = secret; 2218 break; 2219 2220 default: 2221 break; 2222 } 2223 2224 return OPS_RELEASE_MEMORY; 2225 } 2226 2227 /** 2228 \ingroup HighLevel_Callbacks 2229 \brief Callback to use when you need to prompt user for passphrase 2230 \param contents 2231 \param cbinfo 2232 */ 2233 __ops_cb_ret_t 2234 get_passphrase_cb(const __ops_packet_t *pkt, __ops_cbdata_t *cbinfo) 2235 { 2236 const __ops_contents_t *content = &pkt->u; 2237 __ops_io_t *io; 2238 2239 io = cbinfo->io; 2240 if (__ops_get_debug_level(__FILE__)) { 2241 __ops_print_packet(&cbinfo->printstate, pkt); 2242 } 2243 if (cbinfo->cryptinfo.keydata == NULL) { 2244 (void) fprintf(io->errs, "get_passphrase_cb: NULL keydata\n"); 2245 } else { 2246 __ops_print_keydata(io, cbinfo->cryptinfo.pubring, cbinfo->cryptinfo.keydata, "signature ", 2247 &cbinfo->cryptinfo.keydata->key.pubkey, 0); 2248 } 2249 switch (pkt->tag) { 2250 case OPS_GET_PASSPHRASE: 2251 *(content->skey_passphrase.passphrase) = 2252 netpgp_strdup(getpass("netpgp passphrase: ")); 2253 return OPS_KEEP_MEMORY; 2254 default: 2255 break; 2256 } 2257 return OPS_RELEASE_MEMORY; 2258 } 2259 2260 unsigned 2261 __ops_reader_set_accumulate(__ops_stream_t *stream, unsigned state) 2262 { 2263 return stream->readinfo.accumulate = state; 2264 } 2265 2266 /**************************************************************************/ 2267 2268 static int 2269 hash_reader(void *dest, 2270 size_t length, 2271 __ops_error_t **errors, 2272 __ops_reader_t *readinfo, 2273 __ops_cbdata_t *cbinfo) 2274 { 2275 __ops_hash_t *hash = __ops_reader_get_arg(readinfo); 2276 int r; 2277 2278 r = __ops_stacked_read(dest, length, errors, readinfo, cbinfo); 2279 if (r <= 0) { 2280 return r; 2281 } 2282 hash->add(hash, dest, (unsigned)r); 2283 return r; 2284 } 2285 2286 /** 2287 \ingroup Internal_Readers_Hash 2288 \brief Push hashed data reader on stack 2289 */ 2290 void 2291 __ops_reader_push_hash(__ops_stream_t *stream, __ops_hash_t *hash) 2292 { 2293 if (!hash->init(hash)) { 2294 (void) fprintf(stderr, "__ops_reader_push_hash: can't init hash\n"); 2295 /* just continue and die */ 2296 /* XXX - agc - no way to return failure */ 2297 } 2298 __ops_reader_push(stream, hash_reader, NULL, hash); 2299 } 2300 2301 /** 2302 \ingroup Internal_Readers_Hash 2303 \brief Pop hashed data reader from stack 2304 */ 2305 void 2306 __ops_reader_pop_hash(__ops_stream_t *stream) 2307 { 2308 __ops_reader_pop(stream); 2309 } 2310 2311 /* read memory from the previously mmap-ed file */ 2312 static int 2313 mmap_reader(void *dest, size_t length, __ops_error_t **errors, 2314 __ops_reader_t *readinfo, __ops_cbdata_t *cbinfo) 2315 { 2316 mmap_reader_t *mem = __ops_reader_get_arg(readinfo); 2317 unsigned n; 2318 char *cmem = mem->mem; 2319 2320 __OPS_USED(errors); 2321 __OPS_USED(cbinfo); 2322 n = (unsigned)MIN(length, (unsigned)(mem->size - mem->offset)); 2323 if (n > 0) { 2324 (void) memcpy(dest, &cmem[(int)mem->offset], (unsigned)n); 2325 mem->offset += n; 2326 } 2327 return (int)n; 2328 } 2329 2330 /* tear down the mmap, close the fd */ 2331 static void 2332 mmap_destroyer(__ops_reader_t *readinfo) 2333 { 2334 mmap_reader_t *mem = __ops_reader_get_arg(readinfo); 2335 2336 (void) munmap(mem->mem, (unsigned)mem->size); 2337 (void) close(mem->fd); 2338 free(__ops_reader_get_arg(readinfo)); 2339 } 2340 2341 /* set up the file to use mmap-ed memory if available, file IO otherwise */ 2342 void 2343 __ops_reader_set_mmap(__ops_stream_t *stream, int fd) 2344 { 2345 mmap_reader_t *mem; 2346 struct stat st; 2347 2348 if (fstat(fd, &st) != 0) { 2349 (void) fprintf(stderr, "__ops_reader_set_mmap: can't fstat\n"); 2350 } else if ((mem = calloc(1, sizeof(*mem))) == NULL) { 2351 (void) fprintf(stderr, "__ops_reader_set_mmap: bad alloc\n"); 2352 } else { 2353 mem->size = (uint64_t)st.st_size; 2354 mem->offset = 0; 2355 mem->fd = fd; 2356 mem->mem = mmap(NULL, (size_t)st.st_size, PROT_READ, 2357 MAP_PRIVATE | MAP_FILE, fd, 0); 2358 if (mem->mem == MAP_FAILED) { 2359 __ops_reader_set(stream, fd_reader, reader_fd_destroyer, 2360 mem); 2361 } else { 2362 __ops_reader_set(stream, mmap_reader, mmap_destroyer, 2363 mem); 2364 } 2365 } 2366 } 2367