pgpget.c (18668B)
1 /* Mixmaster version 3.0 -- (C) 1999 - 2006 Anonymizer Inc. and others. 2 3 Mixmaster may be redistributed and modified under certain conditions. 4 This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF 5 ANY KIND, either express or implied. See the file COPYRIGHT for 6 details. 7 8 Read OpenPGP packets 9 $Id: pgpget.c 934 2006-06-24 13:40:39Z rabbi $ */ 10 11 12 #include "mix3.h" 13 #ifdef USE_PGP 14 #include "pgp.h" 15 #include "crypto.h" 16 #include <time.h> 17 #include <assert.h> 18 #include <string.h> 19 20 int pgp_getmsg(BUFFER *in, BUFFER *key, BUFFER *sig, char *pubring, 21 char *secring) 22 { 23 BUFFER *p; 24 BUFFER *out; 25 int type, algo = 0; 26 int err = PGP_NOMSG; 27 pgpsig signature = {0, NULL, 0, 0, {0,} }; 28 29 p = buf_new(); 30 out = buf_new(); 31 32 if (sig) 33 signature.userid = buf_new(); 34 35 while ((type = pgp_getpacket(in, p)) > 0) 36 switch (type) { 37 case PGP_LITERAL: 38 pgp_getliteral(p); 39 buf_move(out, p); 40 err = 0; 41 break; 42 case PGP_COMPRESSED: 43 err = pgp_uncompress(p); 44 if (err == 0) 45 err = pgp_getmsg(p, key, sig, pubring, secring); 46 if (err != PGP_ERR && err != PGP_PASS) 47 buf_move(out, p); 48 break; 49 case PGP_ENCRYPTED: 50 case PGP_ENCRYPTEDMDC: 51 if (!key) { 52 err = -1; 53 break; 54 } 55 if (/*key->length > 0 &&*/ algo == 0) { 56 algo = PGP_K_IDEA; 57 digest_md5(key, key); 58 } 59 if (key->length > 0) 60 err = pgp_getsymmetric(p, key, algo, type==PGP_ENCRYPTEDMDC); 61 else 62 err = -1; 63 if (err == 0) 64 err = pgp_getmsg(p, NULL, sig, pubring, secring); 65 if (err != PGP_ERR) 66 buf_move(out, p); 67 break; 68 case PGP_SESKEY: 69 if (!key) { 70 err = -1; 71 break; 72 } 73 err = pgp_getsessionkey(p, key, secring); 74 if (err >= 0) { 75 algo = err; 76 err = 0; 77 buf_set(key, p); 78 } 79 break; 80 case PGP_SYMSESKEY: 81 if (!key) { 82 err = -1; 83 break; 84 } 85 err = pgp_getsymsessionkey(p, key); 86 if (err >= 0) { 87 algo = err; 88 err = 0; 89 if (key) buf_set(key, p); 90 } 91 break; 92 case PGP_MARKER: 93 err = 0; 94 break; /* ignore per RFC2440 */ 95 case PGP_SIG: 96 pgp_getsig(p, &signature, pubring); 97 /* fallthru */ 98 default: 99 if (err == PGP_NOMSG) 100 err = PGP_NODATA; 101 } 102 103 if (signature.ok == PGP_SIGVRFY) 104 pgp_verify(out, sig, &signature); 105 if (signature.ok == PGP_SIGOK) { 106 char line[LINELEN]; 107 time_t t; 108 struct tm *tc; 109 110 t = signature.sigtime; 111 tc = localtime(&t); 112 #if 0 113 strftime(line, LINELEN, "[%Y-%m-%d %H:%M:%S]", tc); 114 #else /* end of 0 */ 115 strftime(line, LINELEN, "[%a %b %d %H:%M:%S %Y]", tc); 116 #endif /* else if not 0 */ 117 if (sig) { 118 buf_cat(sig, signature.userid); 119 buf_appendc(sig, ' '); 120 buf_appends(sig, line); 121 } 122 } 123 if (sig) { 124 if (signature.ok == PGP_SIGNKEY) 125 buf_appendf(sig, "%02X%02X%02X%02X", signature.userid->data[4], 126 signature.userid->data[5], signature.userid->data[6], 127 signature.userid->data[7]); 128 buf_free(signature.userid); 129 } 130 131 if ((err == 0 || err == PGP_NODATA) && signature.ok != 0) 132 err = signature.ok; 133 134 buf_move(in, out); 135 buf_free(out); 136 buf_free(p); 137 138 return (err); 139 } 140 141 int pgp_ispacket(BUFFER *b) 142 { 143 return ((b->data[b->ptr] >> 6) == 2 || (b->data[b->ptr] >> 6) == 3); 144 } 145 146 int pgp_packettype(BUFFER *b, long *len, int *partial) 147 { 148 int ctb; 149 150 ctb = buf_getc(b); 151 switch (ctb >> 6) { 152 case 2: 153 /* old packet type */ 154 switch (ctb & 3) { 155 case 0: 156 *len = buf_getc(b); 157 break; 158 case 1: 159 *len = buf_geti(b); 160 break; 161 case 2: 162 *len = buf_getl(b); 163 break; 164 case 3: 165 *len = b->length - b->ptr; 166 break; 167 } 168 *partial = 0; 169 return (ctb >> 2) & 15; 170 case 3: 171 case 1: /* in GnuPG secret key ring */ 172 /* new packet type */ 173 *len = buf_getc(b); 174 if (*len >= 192 && *len <= 223) 175 *len = (*len - 192) * 256 + buf_getc(b) + 192; 176 else if (*len == 255) 177 *len = buf_getl(b); 178 else if (*len > 223) { 179 *len = 1 <<(*len & 0x1f); 180 *partial = 1; 181 } 182 return (ctb & 63); 183 } 184 return (-1); 185 } 186 187 int pgp_packetpartial(BUFFER *b, long *len, int *partial) 188 { 189 *partial = 0; 190 *len = buf_getc(b); 191 if (*len >= 192 && *len <= 223) 192 *len = (*len - 192) * 256 + buf_getc(b) + 192; 193 else if (*len == 255) 194 *len = buf_getl(b); 195 else if (*len > 223) { 196 *len = 1 <<(*len & 0x1f); 197 *partial = 1; 198 } 199 return 1; 200 } 201 202 int pgp_isconventional(BUFFER *b) 203 { 204 int type; 205 BUFFER *p; 206 p = buf_new(); 207 208 type = pgp_getpacket(b, p); 209 if (type == PGP_MARKER) 210 type = pgp_getpacket(b, p); 211 buf_rewind(b); 212 buf_free(p); 213 return (type == PGP_ENCRYPTED || type == PGP_SYMSESKEY); 214 } 215 216 int pgp_getpacket(BUFFER *in, BUFFER *p) 217 /* returns <0 = error, >0 = packet type */ 218 { 219 int type; 220 long len; 221 int partial = 0; 222 BUFFER *tmp; 223 224 tmp = buf_new(); 225 type = pgp_packettype(in, &len, &partial); 226 if (type > 0 && len > 0) { 227 buf_clear(p); 228 while(partial && len > 0) { 229 buf_get(in, tmp, len); 230 buf_cat(p, tmp); 231 pgp_packetpartial(in, &len, &partial); 232 } 233 if (len > 0) { 234 buf_get(in, tmp, len); 235 buf_cat(p, tmp); 236 } 237 } 238 239 buf_free(tmp); 240 return (type); 241 } 242 243 int pgp_getsig(BUFFER *p, pgpsig *sig, char *pubring) 244 { 245 BUFFER *sigkey, *id, *i; 246 int algo, hashalgo; 247 int hash; 248 249 sigkey = buf_new(); 250 id = buf_new(); 251 i = buf_new(); 252 253 sig->ok = PGP_SIGBAD; 254 255 if (buf_getc(p) > 3) 256 goto end; 257 if (buf_getc(p) != 5) 258 goto end; 259 sig->sigtype = buf_getc(p); 260 sig->sigtime = buf_getl(p); 261 buf_get(p, id, 8); 262 algo = buf_getc(p); 263 hashalgo = buf_getc(p); 264 if (hashalgo != PGP_H_MD5) 265 goto end; 266 hash = buf_geti(p); 267 if (pgpdb_getkey(PK_VERIFY, algo, NULL, NULL, NULL, sigkey, NULL, sig->userid, id, 268 pubring, NULL) < 0) { 269 sig->ok = PGP_SIGNKEY; 270 if (sig->userid) 271 buf_set(sig->userid, id); 272 goto end; 273 } 274 switch (algo) { 275 case PGP_ES_RSA: 276 mpi_get(p, i); 277 if (pgp_rsa(i, sigkey, PK_VERIFY) == -1 || 278 memcmp(i->data, MD5PREFIX, sizeof(MD5PREFIX) - 1) != 0) 279 goto end; 280 memcpy(sig->hash, i->data + sizeof(MD5PREFIX) - 1, 16); 281 if (sig->hash[0] * 256 + sig->hash[1] != hash) 282 goto end; 283 sig->ok = PGP_SIGVRFY; 284 break; 285 default: 286 break; 287 } 288 end: 289 buf_free(sigkey); 290 buf_free(id); 291 buf_free(i); 292 return (sig->ok); 293 } 294 295 void pgp_verify(BUFFER *msg, BUFFER *detached, pgpsig *sig) 296 { 297 MD5_CTX c; 298 BUFFER *t; 299 byte md[16]; 300 301 t = buf_new(); 302 sig->ok = PGP_SIGBAD; 303 304 if (msg->length == 0) { /* detached signature */ 305 if (detached && detached->length) { 306 buf_move(msg, detached); 307 if (sig->sigtype == PGP_SIG_CANONIC) 308 pgp_sigcanonic(msg); /* for cleartext signatures */ 309 } else 310 sig->ok = PGP_NODATA; 311 } 312 MD5_Init(&c); 313 switch (sig->sigtype) { 314 case PGP_SIG_BINARY: 315 MD5_Update(&c, msg->data, msg->length); 316 break; 317 case PGP_SIG_CANONIC: 318 while (buf_getline(msg, t) != -1) { 319 #if 0 320 pgp_sigcanonic(t); /* according to OpenPGP */ 321 #else /* end of 0 */ 322 buf_appends(t, "\r\n"); 323 #endif /* else if not 0 */ 324 MD5_Update(&c, t->data, t->length); 325 } 326 break; 327 default: 328 sig->ok = PGP_SIGBAD; 329 } 330 MD5_Update(&c, &(sig->sigtype), 1); 331 buf_appendl(t, sig->sigtime); 332 MD5_Update(&c, t->data, 4); 333 MD5_Final(md, &c); 334 if (memcmp(md, sig->hash, 16) == 0) 335 sig->ok = PGP_SIGOK; 336 buf_free(t); 337 } 338 339 #ifdef USE_IDEA 340 static int pgp_ideadecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc) 341 { 342 int err = 0; 343 byte iv[8]; 344 byte hdr[10]; 345 int i, n; 346 IDEA_KEY_SCHEDULE ks; 347 SHA_CTX c; 348 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */ 349 350 if (key->length != 16 || in->length <= (mdc?(1+10+22):10)) 351 return (-1); 352 353 if (mdc) { 354 mdc = 1; 355 if (in->data[0] != 1) 356 return (-1); 357 } 358 359 buf_prepare(out, in->length - 10 - mdc); 360 361 for (i = 0; i < 8; i++) 362 iv[i] = 0; 363 364 idea_set_encrypt_key(key->data, &ks); 365 366 n = 0; 367 idea_cfb64_encrypt(in->data + mdc, hdr, 10, &ks, iv, &n, IDEA_DECRYPT); 368 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) { 369 err = -1; 370 goto end; 371 } 372 if (mdc) { 373 SHA1_Init(&c); 374 SHA1_Update(&c, hdr, 10); 375 } else { 376 iv[6] = iv[0], iv[7] = iv[1]; 377 memcpy(iv, in->data + 2, 6); 378 n = 0; 379 } 380 idea_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 - mdc, &ks, iv, &n, 381 IDEA_DECRYPT); 382 if (mdc) { 383 if (out->length > 22) { 384 out->length -= 22; 385 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) { 386 SHA1_Update(&c, out->data, out->length + 2); 387 SHA1_Final(md, &c); 388 if (memcmp(out->data + out->length + 2, md, 20)) 389 err = -1; 390 } else 391 err = -1; 392 } else 393 err = -1; 394 } 395 end: 396 return (err); 397 } 398 #endif /* USE_IDEA */ 399 400 static int pgp_3desdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc) 401 { 402 int err = 0; 403 DES_cblock iv; 404 byte hdr[10]; 405 int i, n; 406 DES_key_schedule ks1; 407 DES_key_schedule ks2; 408 DES_key_schedule ks3; 409 SHA_CTX c; 410 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */ 411 412 if (key->length != 24 || in->length <= (mdc?(1+10+22):10)) 413 return (-1); 414 415 if (mdc) { 416 mdc = 1; 417 if (in->data[0] != 1) 418 return (-1); 419 } 420 421 buf_prepare(out, in->length - 10 - mdc); 422 423 for (i = 0; i < 8; i++) 424 iv[i] = 0; 425 426 DES_set_key((const_DES_cblock *) key->data, &ks1); 427 DES_set_key((const_DES_cblock *) (key->data + 8), &ks2); 428 DES_set_key((const_DES_cblock *) (key->data+ 16), &ks3); 429 430 n = 0; 431 DES_ede3_cfb64_encrypt(in->data + mdc, hdr, 10, &ks1, &ks2, &ks3, &iv, &n, DECRYPT); 432 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) { 433 err = -1; 434 goto end; 435 } 436 if (mdc) { 437 SHA1_Init(&c); 438 SHA1_Update(&c, hdr, 10); 439 } else { 440 iv[6] = iv[0], iv[7] = iv[1]; 441 memcpy(iv, in->data + 2, 6); 442 n = 0; 443 } 444 DES_ede3_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 + mdc, &ks1, 445 &ks2, &ks3, &iv, &n, DECRYPT); 446 if (mdc) { 447 if (out->length > 22) { 448 out->length -= 22; 449 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) { 450 SHA1_Update(&c, out->data, out->length + 2); 451 SHA1_Final(md, &c); 452 if (memcmp(out->data + out->length + 2, md, 20)) 453 err = -1; 454 } else 455 err = -1; 456 } else 457 err = -1; 458 } 459 end: 460 return (err); 461 } 462 463 static int pgp_castdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc) 464 { 465 int err = 0; 466 byte iv[8]; 467 byte hdr[10]; 468 int i, n; 469 SHA_CTX c; 470 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */ 471 472 CAST_KEY ks; 473 474 if (key->length != 16 || in->length <= (mdc?(1+10+22):10)) 475 return (-1); 476 477 if (mdc) { 478 mdc = 1; 479 if (in->data[0] != 1) 480 return (-1); 481 } 482 483 buf_prepare(out, in->length - 10 - mdc); 484 485 for (i = 0; i < 8; i++) 486 iv[i] = 0; 487 488 CAST_set_key(&ks, 16, key->data); 489 490 n = 0; 491 CAST_cfb64_encrypt(in->data + mdc, hdr, 10, &ks, iv, &n, CAST_DECRYPT); 492 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) { 493 err = -1; 494 goto end; 495 } 496 if (mdc) { 497 SHA1_Init(&c); 498 SHA1_Update(&c, hdr, 10); 499 } else { 500 iv[6] = iv[0], iv[7] = iv[1]; 501 memcpy(iv, in->data + 2, 6); 502 n = 0; 503 } 504 CAST_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 - mdc, &ks, 505 iv, &n, CAST_DECRYPT); 506 if (mdc) { 507 if (out->length > 22) { 508 out->length -= 22; 509 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) { 510 SHA1_Update(&c, out->data, out->length + 2); 511 SHA1_Final(md, &c); 512 if (memcmp(out->data + out->length + 2, md, 20)) 513 err = -1; 514 } else 515 err = -1; 516 } else 517 err = -1; 518 } 519 end: 520 return (err); 521 } 522 523 static int pgp_bfdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc) 524 { 525 int err = 0; 526 byte iv[8]; 527 byte hdr[10]; 528 int i, n; 529 SHA_CTX c; 530 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */ 531 532 BF_KEY ks; 533 534 if (key->length != 16 || in->length <= (mdc?(1+10+22):10)) 535 return (-1); 536 537 if (mdc) { 538 mdc = 1; 539 if (in->data[0] != 1) 540 return (-1); 541 } 542 543 buf_prepare(out, in->length - 10 - mdc); 544 545 for (i = 0; i < 8; i++) 546 iv[i] = 0; 547 548 BF_set_key(&ks, 16, key->data); 549 550 n = 0; 551 BF_cfb64_encrypt(in->data + mdc, hdr, 10, &ks, iv, &n, BF_DECRYPT); 552 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) { 553 err = -1; 554 goto end; 555 } 556 if (mdc) { 557 SHA1_Init(&c); 558 SHA1_Update(&c, hdr, 10); 559 } else { 560 iv[6] = iv[0], iv[7] = iv[1]; 561 memcpy(iv, in->data + 2, 6); 562 n = 0; 563 } 564 BF_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 - mdc, &ks, 565 iv, &n, BF_DECRYPT); 566 if (mdc) { 567 if (out->length > 22) { 568 out->length -= 22; 569 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) { 570 SHA1_Update(&c, out->data, out->length + 2); 571 SHA1_Final(md, &c); 572 if (memcmp(out->data + out->length + 2, md, 20)) 573 err = -1; 574 } else 575 err = -1; 576 } else 577 err = -1; 578 } 579 end: 580 return (err); 581 } 582 583 #ifdef USE_AES 584 static int pgp_aesdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc) 585 { 586 int err = 0; 587 byte iv[16]; 588 byte hdr[18]; 589 int i, n; 590 SHA_CTX c; 591 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */ 592 593 AES_KEY ks; 594 595 if ((key->length != 16 && key->length != 24 && key->length != 32) || in->length <= (mdc?(1+18+22):18)) 596 return (-1); 597 598 if (mdc) { 599 mdc = 1; 600 if (in->data[0] != 1) 601 return (-1); 602 } 603 604 buf_prepare(out, in->length - 18 - mdc); 605 606 for (i = 0; i < 16; i++) 607 iv[i] = 0; 608 609 AES_set_encrypt_key(key->data, key->length<<3, &ks); 610 611 n = 0; 612 AES_cfb128_encrypt(in->data + mdc, hdr, 18, &ks, iv, &n, AES_DECRYPT); 613 if (n != 2 || hdr[16] != hdr[14] || hdr[17] != hdr[15]) { 614 err = -1; 615 goto end; 616 } 617 if (mdc) { 618 SHA1_Init(&c); 619 SHA1_Update(&c, hdr, 18); 620 } else { 621 iv[14] = iv[0], iv[15] = iv[1]; 622 memcpy(iv, in->data + 2, 14); 623 n = 0; 624 } 625 AES_cfb128_encrypt(in->data + 18 + mdc, out->data, in->length - 18 - mdc, &ks, 626 iv, &n, AES_DECRYPT); 627 if (mdc) { 628 if (out->length > 22) { 629 out->length -= 22; 630 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) { 631 SHA1_Update(&c, out->data, out->length + 2); 632 SHA1_Final(md, &c); 633 if (memcmp(out->data + out->length + 2, md, 20)) 634 err = -1; 635 } else 636 err = -1; 637 } else 638 err = -1; 639 } 640 end: 641 return (err); 642 } 643 #endif /* USE_AES */ 644 645 int pgp_getsymmetric(BUFFER *in, BUFFER *key, int algo, int mdc) 646 { 647 int err = -1; 648 BUFFER *out; 649 650 out = buf_new(); 651 652 switch (algo) { 653 #ifdef USE_AES 654 case PGP_K_AES128: 655 case PGP_K_AES192: 656 case PGP_K_AES256: 657 err = pgp_aesdecrypt(in, out, key, mdc); 658 break; 659 #endif /* USE_AES */ 660 #ifdef USE_IDEA 661 case PGP_K_IDEA: 662 err = pgp_ideadecrypt(in, out, key, mdc); 663 break; 664 #endif /* USE_IDEA */ 665 case PGP_K_3DES: 666 err = pgp_3desdecrypt(in, out, key, mdc); 667 break; 668 case PGP_K_CAST5: 669 err = pgp_castdecrypt(in, out, key, mdc); 670 break; 671 case PGP_K_BF: 672 err = pgp_bfdecrypt(in, out, key, mdc); 673 break; 674 } 675 676 if (err < 0) 677 errlog(ERRORMSG, "PGP decryption failed.\n"); 678 679 buf_move(in, out); 680 buf_free(out); 681 return (err); 682 } 683 684 int pgp_getliteral(BUFFER *in) 685 { 686 long fnlen; 687 int err = 0; 688 int mode; 689 BUFFER *out; 690 BUFFER *line; 691 692 out = buf_new(); 693 line = buf_new(); 694 mode = buf_getc(in); 695 fnlen = buf_getc(in); 696 in->ptr += fnlen; /* skip filename */ 697 if (in->ptr + 4 > in->length) 698 err = -1; 699 else { 700 buf_getl(in); /* timestamp */ 701 if (mode == 't') 702 while (buf_getline(in, line) != -1) { 703 buf_cat(out, line); 704 buf_nl(out); 705 } else 706 buf_rest(out, in); 707 } 708 buf_move(in, out); 709 buf_free(line); 710 buf_free(out); 711 return (err); 712 } 713 714 int pgp_uncompress(BUFFER *in) 715 { 716 int err = -1; 717 718 switch(buf_getc(in)) { 719 case 0: 720 err = 0; 721 break; 722 case 1: 723 err = buf_unzip(in, 0); 724 break; 725 case 2: 726 err = buf_unzip(in, 1); 727 break; 728 default: 729 err = -1; 730 break; 731 } 732 return (err); 733 } 734 735 int pgp_getsessionkey(BUFFER *in, BUFFER *pass, char *secring) 736 { 737 BUFFER *out; 738 BUFFER *key; 739 BUFFER *keyid; 740 int type; 741 int i, csum = 0; 742 int algo = 0; 743 int err = -1; 744 long expires; 745 746 out = buf_new(); 747 key = buf_new(); 748 keyid = buf_new(); 749 type = buf_getc(in); /* packet type */ 750 if (type < 2 || type > 3) 751 goto end; 752 buf_get(in, keyid, 8); 753 algo = buf_getc(in); 754 err = pgpdb_getkey(PK_DECRYPT, algo, NULL, NULL, &expires, key, NULL, NULL, keyid, 755 secring, pass); 756 if (err < 0) 757 goto end; 758 if (expires > 0 && (expires + KEYGRACEPERIOD < time(NULL))) { 759 errlog(DEBUGINFO, "Key expired.\n"); /* DEBUGINFO ? */ 760 err = -1; 761 goto end; 762 } 763 switch (algo) { 764 case PGP_ES_RSA: 765 mpi_get(in, out); 766 err = pgp_rsa(out, key, PK_DECRYPT); 767 break; 768 case PGP_E_ELG: 769 buf_rest(out, in); 770 err = pgp_elgdecrypt(out, key); 771 break; 772 default: 773 err = -1; 774 } 775 if (err == 0 && out->length > 3) { 776 algo = buf_getc(out); 777 buf_get(out, in, out->length - 3); /* return recovered key */ 778 csum = buf_geti(out); 779 for (i = 0; i < in->length; i++) 780 csum = (csum - in->data[i]) % 65536; 781 if (csum != 0) 782 err = -1; 783 } else 784 err = -1; 785 end: 786 buf_free(out); 787 buf_free(key); 788 buf_free(keyid); 789 return (err == 0 ? algo : err); 790 } 791 792 void pgp_iteratedsk(BUFFER *out, BUFFER *salt, BUFFER *pass, byte c) 793 { 794 int count; 795 BUFFER *temp; 796 temp = buf_new(); 797 798 count = (16l + (c & 15)) << ((c >> 4) + 6); 799 while (temp->length < count) { 800 buf_cat(temp, salt); 801 buf_cat(temp, pass); 802 } 803 buf_get(temp, out, count); 804 buf_free(temp); 805 } 806 807 int pgp_getsk(BUFFER *p, BUFFER *pass, BUFFER *key) 808 { 809 int skalgo, skspecifier, hashalgo; 810 BUFFER *salted; /* passphrase with salt */ 811 812 if (!pass) 813 return(-1); 814 815 salted = buf_new(); 816 817 skalgo = buf_getc(p); 818 skspecifier = buf_getc(p); 819 hashalgo = buf_getc(p); 820 switch (skspecifier) { 821 case 0: 822 buf_set(salted, pass); 823 break; 824 case 1: 825 buf_get(p, salted, 8); /* salt */ 826 buf_cat(salted, pass); 827 break; 828 case 3: 829 buf_get(p, salted, 8); /* salt */ 830 pgp_iteratedsk(salted, salted, pass, buf_getc(p)); 831 break; 832 default: 833 skalgo = -1; 834 goto end; 835 } 836 if (pgp_expandsk(key, skalgo, hashalgo, salted) == -1) 837 skalgo = -1; 838 839 end: 840 buf_free(salted); 841 return (skalgo); 842 } 843 844 int pgp_getsymsessionkey(BUFFER *in, BUFFER *pass) 845 { 846 BUFFER *temp, *key, *iv; 847 int algo = -1; 848 temp = buf_new(); 849 key = buf_new(); 850 iv = buf_new(); 851 852 if (buf_getc(in) == 4) { /* version */ 853 algo = pgp_getsk(in, pass, key); 854 buf_rest(temp, in); 855 if (temp->length) { 856 /* encrypted session key present */ 857 buf_appendzero(iv, pgp_blocklen(algo)); 858 skcrypt(temp, algo, key, iv, DECRYPT); 859 algo = buf_getc(temp); 860 buf_rest(in, temp); 861 } else 862 buf_set(in, key); 863 } 864 buf_free(temp); 865 buf_free(key); 866 buf_free(iv); 867 return (algo); 868 } 869 870 #endif /* USE_PGP */