/[pkg-mixmaster]/trunk/Mix/Src/pgpget.c
ViewVC logotype

Contents of /trunk/Mix/Src/pgpget.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 332 - (show annotations) (download)
Wed Oct 9 20:53:32 2002 UTC (10 years, 7 months ago) by weaselp
File MIME type: text/plain
File size: 18718 byte(s)
Whitespace cleanup:
for i in *.c; do cp -a $i $i.orig; sed -e 's/^        /<TAB>/' $i.orig > $i; rm $i.orig; done
for i in *.c *.h; do cp -a $i $i.orig; sed -e 's/[ <TAB>]*$//' $i.orig > $i; rm $i.orig; done
1 /* Mixmaster version 3 -- (C) 1999 Anonymizer Inc.
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,v 1.12 2002/10/09 20:53:31 weaselp Exp $ */
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 #ifdef USE_RSA
276 case PGP_ES_RSA:
277 mpi_get(p, i);
278 if (pgp_rsa(i, sigkey, PK_VERIFY) == -1 ||
279 memcmp(i->data, MD5PREFIX, sizeof(MD5PREFIX) - 1) != 0)
280 goto end;
281 memcpy(sig->hash, i->data + sizeof(MD5PREFIX) - 1, 16);
282 if (sig->hash[0] * 256 + sig->hash[1] != hash)
283 goto end;
284 sig->ok = PGP_SIGVRFY;
285 break;
286 #endif /* USE_RSA */
287 default:
288 break;
289 }
290 end:
291 buf_free(sigkey);
292 buf_free(id);
293 buf_free(i);
294 return (sig->ok);
295 }
296
297 void pgp_verify(BUFFER *msg, BUFFER *detached, pgpsig *sig)
298 {
299 MD5_CTX c;
300 BUFFER *t;
301 byte md[16];
302
303 t = buf_new();
304 sig->ok = PGP_SIGBAD;
305
306 if (msg->length == 0) { /* detached signature */
307 if (detached && detached->length) {
308 buf_move(msg, detached);
309 if (sig->sigtype == PGP_SIG_CANONIC)
310 pgp_sigcanonic(msg); /* for cleartext signatures */
311 } else
312 sig->ok = PGP_NODATA;
313 }
314 MD5_Init(&c);
315 switch (sig->sigtype) {
316 case PGP_SIG_BINARY:
317 MD5_Update(&c, msg->data, msg->length);
318 break;
319 case PGP_SIG_CANONIC:
320 while (buf_getline(msg, t) != -1) {
321 #if 0
322 pgp_sigcanonic(t); /* according to OpenPGP */
323 #else /* end of 0 */
324 buf_appends(t, "\r\n");
325 #endif /* else if not 0 */
326 MD5_Update(&c, t->data, t->length);
327 }
328 break;
329 default:
330 sig->ok = PGP_SIGBAD;
331 }
332 MD5_Update(&c, &(sig->sigtype), 1);
333 buf_appendl(t, sig->sigtime);
334 MD5_Update(&c, t->data, 4);
335 MD5_Final(md, &c);
336 if (memcmp(md, sig->hash, 16) == 0)
337 sig->ok = PGP_SIGOK;
338 buf_free(t);
339 }
340
341 #ifdef USE_IDEA
342 static int pgp_ideadecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
343 {
344 int err = 0;
345 byte iv[8];
346 byte hdr[10];
347 int i, n;
348 IDEA_KEY_SCHEDULE ks;
349 SHA_CTX c;
350 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */
351
352 if (key->length != 16 || in->length <= (mdc?(1+10+22):10))
353 return (-1);
354
355 if (mdc) {
356 mdc = 1;
357 if (in->data[0] != 1)
358 return (-1);
359 }
360
361 buf_prepare(out, in->length - 10 - mdc);
362
363 for (i = 0; i < 8; i++)
364 iv[i] = 0;
365
366 idea_set_encrypt_key(key->data, &ks);
367
368 n = 0;
369 idea_cfb64_encrypt(in->data + mdc, hdr, 10, &ks, iv, &n, IDEA_DECRYPT);
370 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) {
371 err = -1;
372 goto end;
373 }
374 if (mdc) {
375 SHA1_Init(&c);
376 SHA1_Update(&c, hdr, 10);
377 } else {
378 iv[6] = iv[0], iv[7] = iv[1];
379 memcpy(iv, in->data + 2, 6);
380 n = 0;
381 }
382 idea_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 - mdc, &ks, iv, &n,
383 IDEA_DECRYPT);
384 if (mdc) {
385 if (out->length > 22) {
386 out->length -= 22;
387 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) {
388 SHA1_Update(&c, out->data, out->length + 2);
389 SHA1_Final(md, &c);
390 if (memcmp(out->data + out->length + 2, md, 20))
391 err = -1;
392 } else
393 err = -1;
394 } else
395 err = -1;
396 }
397 end:
398 return (err);
399 }
400 #endif /* USE_IDEA */
401
402 static int pgp_3desdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
403 {
404 int err = 0;
405 des_cblock iv;
406 byte hdr[10];
407 int i, n;
408 des_key_schedule ks1;
409 des_key_schedule ks2;
410 des_key_schedule ks3;
411 SHA_CTX c;
412 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */
413
414 if (key->length != 24 || in->length <= (mdc?(1+10+22):10))
415 return (-1);
416
417 if (mdc) {
418 mdc = 1;
419 if (in->data[0] != 1)
420 return (-1);
421 }
422
423 buf_prepare(out, in->length - 10 - mdc);
424
425 for (i = 0; i < 8; i++)
426 iv[i] = 0;
427
428 des_set_key((const_des_cblock *) key->data, ks1);
429 des_set_key((const_des_cblock *) (key->data + 8), ks2);
430 des_set_key((const_des_cblock *) (key->data+ 16), ks3);
431
432 n = 0;
433 des_ede3_cfb64_encrypt(in->data + mdc, hdr, 10, ks1, ks2, ks3, &iv, &n, DECRYPT);
434 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) {
435 err = -1;
436 goto end;
437 }
438 if (mdc) {
439 SHA1_Init(&c);
440 SHA1_Update(&c, hdr, 10);
441 } else {
442 iv[6] = iv[0], iv[7] = iv[1];
443 memcpy(iv, in->data + 2, 6);
444 n = 0;
445 }
446 des_ede3_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 + mdc, ks1,
447 ks2, ks3, &iv, &n, DECRYPT);
448 if (mdc) {
449 if (out->length > 22) {
450 out->length -= 22;
451 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) {
452 SHA1_Update(&c, out->data, out->length + 2);
453 SHA1_Final(md, &c);
454 if (memcmp(out->data + out->length + 2, md, 20))
455 err = -1;
456 } else
457 err = -1;
458 } else
459 err = -1;
460 }
461 end:
462 return (err);
463 }
464
465 static int pgp_castdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
466 {
467 int err = 0;
468 byte iv[8];
469 byte hdr[10];
470 int i, n;
471 SHA_CTX c;
472 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */
473
474 CAST_KEY ks;
475
476 if (key->length != 16 || in->length <= (mdc?(1+10+22):10))
477 return (-1);
478
479 if (mdc) {
480 mdc = 1;
481 if (in->data[0] != 1)
482 return (-1);
483 }
484
485 buf_prepare(out, in->length - 10 - mdc);
486
487 for (i = 0; i < 8; i++)
488 iv[i] = 0;
489
490 CAST_set_key(&ks, 16, key->data);
491
492 n = 0;
493 CAST_cfb64_encrypt(in->data + mdc, hdr, 10, &ks, iv, &n, CAST_DECRYPT);
494 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) {
495 err = -1;
496 goto end;
497 }
498 if (mdc) {
499 SHA1_Init(&c);
500 SHA1_Update(&c, hdr, 10);
501 } else {
502 iv[6] = iv[0], iv[7] = iv[1];
503 memcpy(iv, in->data + 2, 6);
504 n = 0;
505 }
506 CAST_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 - mdc, &ks,
507 iv, &n, CAST_DECRYPT);
508 if (mdc) {
509 if (out->length > 22) {
510 out->length -= 22;
511 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) {
512 SHA1_Update(&c, out->data, out->length + 2);
513 SHA1_Final(md, &c);
514 if (memcmp(out->data + out->length + 2, md, 20))
515 err = -1;
516 } else
517 err = -1;
518 } else
519 err = -1;
520 }
521 end:
522 return (err);
523 }
524
525 static int pgp_bfdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
526 {
527 int err = 0;
528 byte iv[8];
529 byte hdr[10];
530 int i, n;
531 SHA_CTX c;
532 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */
533
534 BF_KEY ks;
535
536 if (key->length != 16 || in->length <= (mdc?(1+10+22):10))
537 return (-1);
538
539 if (mdc) {
540 mdc = 1;
541 if (in->data[0] != 1)
542 return (-1);
543 }
544
545 buf_prepare(out, in->length - 10 - mdc);
546
547 for (i = 0; i < 8; i++)
548 iv[i] = 0;
549
550 BF_set_key(&ks, 16, key->data);
551
552 n = 0;
553 BF_cfb64_encrypt(in->data + mdc, hdr, 10, &ks, iv, &n, BF_DECRYPT);
554 if (n != 2 || hdr[8] != hdr[6] || hdr[9] != hdr[7]) {
555 err = -1;
556 goto end;
557 }
558 if (mdc) {
559 SHA1_Init(&c);
560 SHA1_Update(&c, hdr, 10);
561 } else {
562 iv[6] = iv[0], iv[7] = iv[1];
563 memcpy(iv, in->data + 2, 6);
564 n = 0;
565 }
566 BF_cfb64_encrypt(in->data + 10 + mdc, out->data, in->length - 10 - mdc, &ks,
567 iv, &n, BF_DECRYPT);
568 if (mdc) {
569 if (out->length > 22) {
570 out->length -= 22;
571 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) {
572 SHA1_Update(&c, out->data, out->length + 2);
573 SHA1_Final(md, &c);
574 if (memcmp(out->data + out->length + 2, md, 20))
575 err = -1;
576 } else
577 err = -1;
578 } else
579 err = -1;
580 }
581 end:
582 return (err);
583 }
584
585 #ifdef USE_AES
586 static int pgp_aesdecrypt(BUFFER *in, BUFFER *out, BUFFER *key, int mdc)
587 {
588 int err = 0;
589 byte iv[16];
590 byte hdr[18];
591 int i, n;
592 SHA_CTX c;
593 char md[20]; /* we could make hdr 20 bytes long and reuse it for md */
594
595 AES_KEY ks;
596
597 if ((key->length != 16 && key->length != 24 && key->length != 32) || in->length <= (mdc?(1+18+22):18))
598 return (-1);
599
600 if (mdc) {
601 mdc = 1;
602 if (in->data[0] != 1)
603 return (-1);
604 }
605
606 buf_prepare(out, in->length - 18 - mdc);
607
608 for (i = 0; i < 16; i++)
609 iv[i] = 0;
610
611 AES_set_encrypt_key(key->data, key->length<<3, &ks);
612
613 n = 0;
614 AES_cfb128_encrypt(in->data + mdc, hdr, 18, &ks, iv, &n, AES_DECRYPT);
615 if (n != 2 || hdr[16] != hdr[14] || hdr[17] != hdr[15]) {
616 err = -1;
617 goto end;
618 }
619 if (mdc) {
620 SHA1_Init(&c);
621 SHA1_Update(&c, hdr, 18);
622 } else {
623 iv[14] = iv[0], iv[15] = iv[1];
624 memcpy(iv, in->data + 2, 14);
625 n = 0;
626 }
627 AES_cfb128_encrypt(in->data + 18 + mdc, out->data, in->length - 18 - mdc, &ks,
628 iv, &n, AES_DECRYPT);
629 if (mdc) {
630 if (out->length > 22) {
631 out->length -= 22;
632 if (out->data[out->length] == 0xD3 && out->data[out->length + 1] == 0x14) {
633 SHA1_Update(&c, out->data, out->length + 2);
634 SHA1_Final(md, &c);
635 if (memcmp(out->data + out->length + 2, md, 20))
636 err = -1;
637 } else
638 err = -1;
639 } else
640 err = -1;
641 }
642 end:
643 return (err);
644 }
645 #endif /* USE_AES */
646
647 int pgp_getsymmetric(BUFFER *in, BUFFER *key, int algo, int mdc)
648 {
649 int err = -1;
650 BUFFER *out;
651
652 out = buf_new();
653
654 switch (algo) {
655 #ifdef USE_AES
656 case PGP_K_AES128:
657 case PGP_K_AES192:
658 case PGP_K_AES256:
659 err = pgp_aesdecrypt(in, out, key, mdc);
660 break;
661 #endif /* USE_AES */
662 #ifdef USE_IDEA
663 case PGP_K_IDEA:
664 err = pgp_ideadecrypt(in, out, key, mdc);
665 break;
666 #endif /* USE_IDEA */
667 case PGP_K_3DES:
668 err = pgp_3desdecrypt(in, out, key, mdc);
669 break;
670 case PGP_K_CAST5:
671 err = pgp_castdecrypt(in, out, key, mdc);
672 break;
673 case PGP_K_BF:
674 err = pgp_bfdecrypt(in, out, key, mdc);
675 break;
676 }
677
678 if (err < 0)
679 errlog(ERRORMSG, "PGP decryption failed.\n");
680
681 buf_move(in, out);
682 buf_free(out);
683 return (err);
684 }
685
686 int pgp_getliteral(BUFFER *in)
687 {
688 long fnlen;
689 int err = 0;
690 int mode;
691 BUFFER *out;
692 BUFFER *line;
693
694 out = buf_new();
695 line = buf_new();
696 mode = buf_getc(in);
697 fnlen = buf_getc(in);
698 in->ptr += fnlen; /* skip filename */
699 if (in->ptr + 4 > in->length)
700 err = -1;
701 else {
702 buf_getl(in); /* timestamp */
703 if (mode == 't')
704 while (buf_getline(in, line) != -1) {
705 buf_cat(out, line);
706 buf_nl(out);
707 } else
708 buf_rest(out, in);
709 }
710 buf_move(in, out);
711 buf_free(line);
712 buf_free(out);
713 return (err);
714 }
715
716 int pgp_uncompress(BUFFER *in)
717 {
718 int err = -1;
719
720 switch(buf_getc(in)) {
721 case 0:
722 err = 0;
723 break;
724 case 1:
725 err = buf_unzip(in, 0);
726 break;
727 case 2:
728 err = buf_unzip(in, 1);
729 break;
730 default:
731 err = -1;
732 break;
733 }
734 return (err);
735 }
736
737 int pgp_getsessionkey(BUFFER *in, BUFFER *pass, char *secring)
738 {
739 BUFFER *out;
740 BUFFER *key;
741 BUFFER *keyid;
742 int type;
743 int i, csum = 0;
744 int algo = 0;
745 int err = -1;
746 long expires;
747
748 out = buf_new();
749 key = buf_new();
750 keyid = buf_new();
751 type = buf_getc(in); /* packet type */
752 if (type < 2 || type > 3)
753 goto end;
754 buf_get(in, keyid, 8);
755 algo = buf_getc(in);
756 err = pgpdb_getkey(PK_DECRYPT, algo, NULL, NULL, &expires, key, NULL, NULL, keyid,
757 secring, pass);
758 if (err < 0)
759 goto end;
760 if (expires > 0 && (expires + KEYGRACEPERIOD < time(NULL))) {
761 errlog(DEBUGINFO, "Key expired.\n"); /* DEBUGINFO ? */
762 err = -1;
763 goto end;
764 }
765 switch (algo) {
766 #ifdef USE_RSA
767 case PGP_ES_RSA:
768 mpi_get(in, out);
769 err = pgp_rsa(out, key, PK_DECRYPT);
770 break;
771 #endif /* USE_RSA */
772 case PGP_E_ELG:
773 buf_rest(out, in);
774 err = pgp_elgdecrypt(out, key);
775 break;
776 default:
777 err = -1;
778 }
779 if (err == 0 && out->length > 3) {
780 algo = buf_getc(out);
781 buf_get(out, in, out->length - 3); /* return recovered key */
782 csum = buf_geti(out);
783 for (i = 0; i < in->length; i++)
784 csum = (csum - in->data[i]) % 65536;
785 if (csum != 0)
786 err = -1;
787 } else
788 err = -1;
789 end:
790 buf_free(out);
791 buf_free(key);
792 buf_free(keyid);
793 return (err == 0 ? algo : err);
794 }
795
796 void pgp_iteratedsk(BUFFER *out, BUFFER *salt, BUFFER *pass, byte c)
797 {
798 int count;
799 BUFFER *temp;
800 temp = buf_new();
801
802 count = (16l + (c & 15)) << ((c >> 4) + 6);
803 while (temp->length < count) {
804 buf_cat(temp, salt);
805 buf_cat(temp, pass);
806 }
807 buf_get(temp, out, count);
808 buf_free(temp);
809 }
810
811 int pgp_getsk(BUFFER *p, BUFFER *pass, BUFFER *key)
812 {
813 int skalgo, skspecifier, hashalgo;
814 BUFFER *salted; /* passphrase with salt */
815
816 if (!pass)
817 return(-1);
818
819 salted = buf_new();
820
821 skalgo = buf_getc(p);
822 skspecifier = buf_getc(p);
823 hashalgo = buf_getc(p);
824 switch (skspecifier) {
825 case 0:
826 buf_set(salted, pass);
827 break;
828 case 1:
829 buf_get(p, salted, 8); /* salt */
830 buf_cat(salted, pass);
831 break;
832 case 3:
833 buf_get(p, salted, 8); /* salt */
834 pgp_iteratedsk(salted, salted, pass, buf_getc(p));
835 break;
836 default:
837 skalgo = -1;
838 goto end;
839 }
840 if (pgp_expandsk(key, skalgo, hashalgo, salted) == -1)
841 skalgo = -1;
842
843 end:
844 buf_free(salted);
845 return (skalgo);
846 }
847
848 int pgp_getsymsessionkey(BUFFER *in, BUFFER *pass)
849 {
850 BUFFER *temp, *key, *iv;
851 int algo = -1;
852 temp = buf_new();
853 key = buf_new();
854 iv = buf_new();
855
856 if (buf_getc(in) == 4) { /* version */
857 algo = pgp_getsk(in, pass, key);
858 buf_rest(temp, in);
859 if (temp->length) {
860 /* encrypted session key present */
861 buf_appendzero(iv, pgp_blocklen(algo));
862 skcrypt(temp, algo, key, iv, DECRYPT);
863 algo = buf_getc(temp);
864 buf_rest(in, temp);
865 } else
866 buf_set(in, key);
867 }
868 buf_free(temp);
869 buf_free(key);
870 buf_free(iv);
871 return (algo);
872 }
873
874 #endif /* USE_PGP */

  ViewVC Help
Powered by ViewVC 1.1.5