Line data Source code
1 : /*
2 : * pgp-decrypt.c
3 : * OpenPGP decrypt.
4 : *
5 : * Copyright (c) 2005 Marko Kreen
6 : * All rights reserved.
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 AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18 : * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19 : * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20 : * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21 : * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 : * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23 : * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24 : * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25 : * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26 : * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27 : * SUCH DAMAGE.
28 : *
29 : * contrib/pgcrypto/pgp-decrypt.c
30 : */
31 :
32 : #include "postgres.h"
33 :
34 : #include "mbuf.h"
35 : #include "pgp.h"
36 : #include "px.h"
37 :
38 : #define NO_CTX_SIZE 0
39 : #define ALLOW_CTX_SIZE 1
40 : #define NO_COMPR 0
41 : #define ALLOW_COMPR 1
42 : #define NO_MDC 0
43 : #define NEED_MDC 1
44 :
45 : #define PKT_NORMAL 1
46 : #define PKT_STREAM 2
47 : #define PKT_CONTEXT 3
48 :
49 : #define MAX_CHUNK (16*1024*1024)
50 :
51 : static int
52 544 : parse_new_len(PullFilter *src, int *len_p)
53 : {
54 : uint8 b;
55 : int len;
56 544 : int pkttype = PKT_NORMAL;
57 :
58 544 : GETBYTE(src, b);
59 544 : if (b <= 191)
60 496 : len = b;
61 48 : else if (b >= 192 && b <= 223)
62 : {
63 16 : len = ((unsigned) (b) - 192) << 8;
64 16 : GETBYTE(src, b);
65 16 : len += 192 + b;
66 : }
67 32 : else if (b == 255)
68 : {
69 2 : GETBYTE(src, b);
70 2 : len = b;
71 2 : GETBYTE(src, b);
72 2 : len = (len << 8) | b;
73 2 : GETBYTE(src, b);
74 2 : len = (len << 8) | b;
75 2 : GETBYTE(src, b);
76 2 : len = (len << 8) | b;
77 : }
78 : else
79 : {
80 30 : len = 1 << (b & 0x1F);
81 30 : pkttype = PKT_STREAM;
82 : }
83 :
84 544 : if (len < 0 || len > MAX_CHUNK)
85 : {
86 0 : px_debug("parse_new_len: weird length");
87 0 : return PXE_PGP_CORRUPT_DATA;
88 : }
89 :
90 544 : *len_p = len;
91 544 : return pkttype;
92 : }
93 :
94 : static int
95 426 : parse_old_len(PullFilter *src, int *len_p, int lentype)
96 : {
97 : uint8 b;
98 : int len;
99 :
100 426 : GETBYTE(src, b);
101 426 : len = b;
102 :
103 426 : if (lentype == 1)
104 : {
105 204 : GETBYTE(src, b);
106 204 : len = (len << 8) | b;
107 : }
108 222 : else if (lentype == 2)
109 : {
110 0 : GETBYTE(src, b);
111 0 : len = (len << 8) | b;
112 0 : GETBYTE(src, b);
113 0 : len = (len << 8) | b;
114 0 : GETBYTE(src, b);
115 0 : len = (len << 8) | b;
116 : }
117 :
118 426 : if (len < 0 || len > MAX_CHUNK)
119 : {
120 0 : px_debug("parse_old_len: weird length");
121 0 : return PXE_PGP_CORRUPT_DATA;
122 : }
123 426 : *len_p = len;
124 426 : return PKT_NORMAL;
125 : }
126 :
127 : /* returns pkttype or 0 on eof */
128 : int
129 1302 : pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
130 : {
131 : int lentype;
132 : int res;
133 : uint8 *p;
134 :
135 : /* EOF is normal here, thus we don't use GETBYTE */
136 1302 : res = pullf_read(src, 1, &p);
137 1302 : if (res < 0)
138 0 : return res;
139 1302 : if (res == 0)
140 352 : return 0;
141 :
142 950 : if ((*p & 0x80) == 0)
143 : {
144 0 : px_debug("pgp_parse_pkt_hdr: not pkt hdr");
145 0 : return PXE_PGP_CORRUPT_DATA;
146 : }
147 :
148 950 : if (*p & 0x40)
149 : {
150 518 : *tag = *p & 0x3f;
151 518 : res = parse_new_len(src, len_p);
152 : }
153 : else
154 : {
155 432 : lentype = *p & 3;
156 432 : *tag = (*p >> 2) & 0x0F;
157 432 : if (lentype == 3)
158 6 : res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
159 : else
160 426 : res = parse_old_len(src, len_p, lentype);
161 : }
162 950 : return res;
163 : }
164 :
165 : /*
166 : * Packet reader
167 : */
168 : struct PktData
169 : {
170 : int type;
171 : int len;
172 : };
173 :
174 : static int
175 5148 : pktreader_pull(void *priv, PullFilter *src, int len,
176 : uint8 **data_p, uint8 *buf, int buflen)
177 : {
178 : int res;
179 5148 : struct PktData *pkt = priv;
180 :
181 : /* PKT_CONTEXT means: whatever there is */
182 5148 : if (pkt->type == PKT_CONTEXT)
183 0 : return pullf_read(src, len, data_p);
184 :
185 5174 : while (pkt->len == 0)
186 : {
187 : /* this was last chunk in stream */
188 808 : if (pkt->type == PKT_NORMAL)
189 782 : return 0;
190 :
191 : /* next chunk in stream */
192 26 : res = parse_new_len(src, &pkt->len);
193 26 : if (res < 0)
194 0 : return res;
195 26 : pkt->type = res;
196 : }
197 :
198 4366 : if (len > pkt->len)
199 530 : len = pkt->len;
200 :
201 4366 : res = pullf_read(src, len, data_p);
202 4366 : if (res > 0)
203 4366 : pkt->len -= res;
204 :
205 4366 : return res;
206 : }
207 :
208 : static void
209 944 : pktreader_free(void *priv)
210 : {
211 944 : struct PktData *pkt = priv;
212 :
213 944 : px_memset(pkt, 0, sizeof(*pkt));
214 944 : pfree(pkt);
215 944 : }
216 :
217 : static struct PullFilterOps pktreader_filter = {
218 : NULL, pktreader_pull, pktreader_free
219 : };
220 :
221 : /* needs helper function to pass several parameters */
222 : int
223 944 : pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
224 : int pkttype, PGP_Context *ctx)
225 : {
226 : int res;
227 944 : struct PktData *pkt = palloc(sizeof(*pkt));
228 :
229 944 : pkt->type = pkttype;
230 944 : pkt->len = len;
231 944 : res = pullf_create(pf_p, &pktreader_filter, pkt, src);
232 944 : if (res < 0)
233 0 : pfree(pkt);
234 944 : return res;
235 : }
236 :
237 : /*
238 : * Prefix check filter
239 : * https://tools.ietf.org/html/rfc4880#section-5.7
240 : * https://tools.ietf.org/html/rfc4880#section-5.13
241 : */
242 :
243 : static int
244 144 : prefix_init(void **priv_p, void *arg, PullFilter *src)
245 : {
246 144 : PGP_Context *ctx = arg;
247 : int len;
248 : int res;
249 : uint8 *buf;
250 : uint8 tmpbuf[PGP_MAX_BLOCK + 2];
251 :
252 144 : len = pgp_get_cipher_block_size(ctx->cipher_algo);
253 144 : if (len > sizeof(tmpbuf))
254 0 : return PXE_BUG;
255 :
256 144 : res = pullf_read_max(src, len + 2, &buf, tmpbuf);
257 144 : if (res < 0)
258 0 : return res;
259 144 : if (res != len + 2)
260 : {
261 0 : px_debug("prefix_init: short read");
262 0 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
263 0 : return PXE_PGP_CORRUPT_DATA;
264 : }
265 :
266 144 : if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
267 : {
268 4 : px_debug("prefix_init: corrupt prefix");
269 : /* report error in pgp_decrypt() */
270 4 : ctx->corrupt_prefix = 1;
271 : }
272 144 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
273 144 : return 0;
274 : }
275 :
276 : static struct PullFilterOps prefix_filter = {
277 : prefix_init, NULL, NULL
278 : };
279 :
280 :
281 : /*
282 : * Decrypt filter
283 : */
284 :
285 : static int
286 152 : decrypt_init(void **priv_p, void *arg, PullFilter *src)
287 : {
288 152 : PGP_CFB *cfb = arg;
289 :
290 152 : *priv_p = cfb;
291 :
292 : /* we need to write somewhere, so ask for a buffer */
293 152 : return 4096;
294 : }
295 :
296 : static int
297 1646 : decrypt_read(void *priv, PullFilter *src, int len,
298 : uint8 **data_p, uint8 *buf, int buflen)
299 : {
300 1646 : PGP_CFB *cfb = priv;
301 : uint8 *tmp;
302 : int res;
303 :
304 1646 : res = pullf_read(src, len, &tmp);
305 1646 : if (res > 0)
306 : {
307 1494 : pgp_cfb_decrypt(cfb, tmp, res, buf);
308 1494 : *data_p = buf;
309 : }
310 1646 : return res;
311 : }
312 :
313 : struct PullFilterOps pgp_decrypt_filter = {
314 : decrypt_init, decrypt_read, NULL
315 : };
316 :
317 :
318 : /*
319 : * MDC hasher filter
320 : */
321 :
322 : static int
323 140 : mdc_init(void **priv_p, void *arg, PullFilter *src)
324 : {
325 140 : PGP_Context *ctx = arg;
326 :
327 140 : *priv_p = ctx;
328 140 : return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
329 : }
330 :
331 : static void
332 140 : mdc_free(void *priv)
333 : {
334 140 : PGP_Context *ctx = priv;
335 :
336 140 : if (ctx->use_mdcbuf_filter)
337 6 : return;
338 134 : px_md_free(ctx->mdc_ctx);
339 134 : ctx->mdc_ctx = NULL;
340 : }
341 :
342 : static int
343 132 : mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
344 : {
345 : int res;
346 : uint8 hash[20];
347 : uint8 tmpbuf[20];
348 : uint8 *data;
349 :
350 : /* should not happen */
351 132 : if (ctx->use_mdcbuf_filter)
352 0 : return PXE_BUG;
353 :
354 : /* It's SHA1 */
355 132 : if (len != 20)
356 0 : return PXE_PGP_CORRUPT_DATA;
357 :
358 : /* mdc_read should not call px_md_update */
359 132 : ctx->in_mdc_pkt = 1;
360 :
361 : /* read data */
362 132 : res = pullf_read_max(src, len, &data, tmpbuf);
363 132 : if (res < 0)
364 0 : return res;
365 132 : if (res == 0)
366 : {
367 0 : px_debug("no mdc");
368 0 : return PXE_PGP_CORRUPT_DATA;
369 : }
370 :
371 : /* is the packet sane? */
372 132 : if (res != 20)
373 : {
374 0 : px_debug("mdc_finish: read failed, res=%d", res);
375 0 : return PXE_PGP_CORRUPT_DATA;
376 : }
377 :
378 : /*
379 : * ok, we got the hash, now check
380 : */
381 132 : px_md_finish(ctx->mdc_ctx, hash);
382 132 : res = memcmp(hash, data, 20);
383 132 : px_memset(hash, 0, 20);
384 132 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
385 132 : if (res != 0)
386 : {
387 0 : px_debug("mdc_finish: mdc failed");
388 0 : return PXE_PGP_CORRUPT_DATA;
389 : }
390 132 : ctx->mdc_checked = 1;
391 132 : return 0;
392 : }
393 :
394 : static int
395 1568 : mdc_read(void *priv, PullFilter *src, int len,
396 : uint8 **data_p, uint8 *buf, int buflen)
397 : {
398 : int res;
399 1568 : PGP_Context *ctx = priv;
400 :
401 : /* skip this filter? */
402 1568 : if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
403 278 : return pullf_read(src, len, data_p);
404 :
405 1290 : res = pullf_read(src, len, data_p);
406 1290 : if (res < 0)
407 0 : return res;
408 1290 : if (res == 0)
409 : {
410 0 : px_debug("mdc_read: unexpected eof");
411 0 : return PXE_PGP_CORRUPT_DATA;
412 : }
413 1290 : px_md_update(ctx->mdc_ctx, *data_p, res);
414 :
415 1290 : return res;
416 : }
417 :
418 : static struct PullFilterOps mdc_filter = {
419 : mdc_init, mdc_read, mdc_free
420 : };
421 :
422 :
423 : /*
424 : * Combined Pkt reader and MDC hasher.
425 : *
426 : * For the case of SYMENCRYPTED_DATA_MDC packet, where
427 : * the data part has 'context length', which means
428 : * that data packet ends 22 bytes before end of parent
429 : * packet, which is silly.
430 : */
431 : #define MDCBUF_LEN 8192
432 : struct MDCBufData
433 : {
434 : PGP_Context *ctx;
435 : int eof;
436 : int buflen;
437 : int avail;
438 : uint8 *pos;
439 : int mdc_avail;
440 : uint8 mdc_buf[22];
441 : uint8 buf[MDCBUF_LEN];
442 : };
443 :
444 : static int
445 6 : mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
446 : {
447 6 : PGP_Context *ctx = arg;
448 : struct MDCBufData *st;
449 :
450 6 : st = palloc0(sizeof(*st));
451 6 : st->buflen = sizeof(st->buf);
452 6 : st->ctx = ctx;
453 6 : *priv_p = st;
454 :
455 : /* take over the work of mdc_filter */
456 6 : ctx->use_mdcbuf_filter = 1;
457 :
458 6 : return 0;
459 : }
460 :
461 : static int
462 6 : mdcbuf_finish(struct MDCBufData *st)
463 : {
464 : uint8 hash[20];
465 : int res;
466 :
467 6 : st->eof = 1;
468 :
469 6 : if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
470 : {
471 4 : px_debug("mdcbuf_finish: bad MDC pkt hdr");
472 4 : return PXE_PGP_CORRUPT_DATA;
473 : }
474 2 : px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
475 2 : px_md_finish(st->ctx->mdc_ctx, hash);
476 2 : res = memcmp(hash, st->mdc_buf + 2, 20);
477 2 : px_memset(hash, 0, 20);
478 2 : if (res)
479 : {
480 0 : px_debug("mdcbuf_finish: MDC does not match");
481 0 : res = PXE_PGP_CORRUPT_DATA;
482 : }
483 2 : return res;
484 : }
485 :
486 : static void
487 12 : mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
488 : {
489 12 : uint8 *dst = st->pos + st->avail;
490 :
491 12 : memcpy(dst, src, len);
492 12 : px_md_update(st->ctx->mdc_ctx, src, len);
493 12 : st->avail += len;
494 12 : }
495 :
496 : static void
497 6 : mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
498 : {
499 6 : memmove(st->mdc_buf + st->mdc_avail, src, len);
500 6 : st->mdc_avail += len;
501 6 : }
502 :
503 : static int
504 12 : mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
505 : {
506 : uint8 *data;
507 : int res;
508 : int need;
509 :
510 : /* put avail data in start */
511 12 : if (st->avail > 0 && st->pos != st->buf)
512 6 : memmove(st->buf, st->pos, st->avail);
513 12 : st->pos = st->buf;
514 :
515 : /* read new data */
516 12 : need = st->buflen + 22 - st->avail - st->mdc_avail;
517 12 : res = pullf_read(src, need, &data);
518 12 : if (res < 0)
519 0 : return res;
520 12 : if (res == 0)
521 6 : return mdcbuf_finish(st);
522 :
523 : /* add to buffer */
524 6 : if (res >= 22)
525 : {
526 6 : mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
527 6 : st->mdc_avail = 0;
528 :
529 6 : mdcbuf_load_data(st, data, res - 22);
530 6 : mdcbuf_load_mdc(st, data + res - 22, 22);
531 : }
532 : else
533 : {
534 0 : int canmove = st->mdc_avail + res - 22;
535 :
536 0 : if (canmove > 0)
537 : {
538 0 : mdcbuf_load_data(st, st->mdc_buf, canmove);
539 0 : st->mdc_avail -= canmove;
540 0 : memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
541 : }
542 0 : mdcbuf_load_mdc(st, data, res);
543 : }
544 6 : return 0;
545 : }
546 :
547 : static int
548 20 : mdcbuf_read(void *priv, PullFilter *src, int len,
549 : uint8 **data_p, uint8 *buf, int buflen)
550 : {
551 20 : struct MDCBufData *st = priv;
552 : int res;
553 :
554 20 : if (!st->eof && len > st->avail)
555 : {
556 12 : res = mdcbuf_refill(st, src);
557 12 : if (res < 0)
558 4 : return res;
559 : }
560 :
561 16 : if (len > st->avail)
562 4 : len = st->avail;
563 :
564 16 : *data_p = st->pos;
565 16 : st->pos += len;
566 16 : st->avail -= len;
567 16 : return len;
568 : }
569 :
570 : static void
571 6 : mdcbuf_free(void *priv)
572 : {
573 6 : struct MDCBufData *st = priv;
574 :
575 6 : px_md_free(st->ctx->mdc_ctx);
576 6 : st->ctx->mdc_ctx = NULL;
577 6 : px_memset(st, 0, sizeof(*st));
578 6 : pfree(st);
579 6 : }
580 :
581 : static struct PullFilterOps mdcbuf_filter = {
582 : mdcbuf_init, mdcbuf_read, mdcbuf_free
583 : };
584 :
585 :
586 : /*
587 : * Decrypt separate session key
588 : */
589 : static int
590 8 : decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
591 : {
592 : int res;
593 : uint8 algo;
594 : PGP_CFB *cfb;
595 :
596 8 : res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
597 8 : ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
598 8 : if (res < 0)
599 0 : return res;
600 :
601 8 : pgp_cfb_decrypt(cfb, src, 1, &algo);
602 8 : src++;
603 8 : len--;
604 :
605 8 : pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
606 8 : pgp_cfb_free(cfb);
607 8 : ctx->sess_key_len = len;
608 8 : ctx->cipher_algo = algo;
609 :
610 8 : if (pgp_get_cipher_key_size(algo) != len)
611 : {
612 0 : px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
613 : algo, pgp_get_cipher_key_size(algo), len);
614 0 : return PXE_PGP_CORRUPT_DATA;
615 : }
616 8 : return 0;
617 : }
618 :
619 : /*
620 : * Handle key packet
621 : */
622 : static int
623 118 : parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
624 : {
625 : uint8 *p;
626 : int res;
627 : uint8 tmpbuf[PGP_MAX_KEY + 2];
628 : uint8 ver;
629 :
630 118 : GETBYTE(src, ver);
631 118 : GETBYTE(src, ctx->s2k_cipher_algo);
632 118 : if (ver != 4)
633 : {
634 0 : px_debug("bad key pkt ver");
635 0 : return PXE_PGP_CORRUPT_DATA;
636 : }
637 :
638 : /*
639 : * read S2K info
640 : */
641 118 : res = pgp_s2k_read(src, &ctx->s2k);
642 118 : if (res < 0)
643 0 : return res;
644 118 : ctx->s2k_mode = ctx->s2k.mode;
645 118 : ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
646 118 : ctx->s2k_digest_algo = ctx->s2k.digest_algo;
647 :
648 : /*
649 : * generate key from password
650 : */
651 118 : res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
652 : ctx->sym_key, ctx->sym_key_len);
653 118 : if (res < 0)
654 0 : return res;
655 :
656 : /*
657 : * do we have separate session key?
658 : */
659 118 : res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
660 118 : if (res < 0)
661 0 : return res;
662 :
663 118 : if (res == 0)
664 : {
665 : /*
666 : * no, s2k key is session key
667 : */
668 110 : memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
669 110 : ctx->sess_key_len = ctx->s2k.key_len;
670 110 : ctx->cipher_algo = ctx->s2k_cipher_algo;
671 110 : res = 0;
672 110 : ctx->use_sess_key = 0;
673 : }
674 : else
675 : {
676 : /*
677 : * yes, decrypt it
678 : */
679 8 : if (res < 17 || res > PGP_MAX_KEY + 1)
680 : {
681 0 : px_debug("expect key, but bad data");
682 0 : return PXE_PGP_CORRUPT_DATA;
683 : }
684 8 : ctx->use_sess_key = 1;
685 8 : res = decrypt_key(ctx, p, res);
686 : }
687 :
688 118 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
689 118 : return res;
690 : }
691 :
692 : static int
693 4 : copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
694 : {
695 4 : uint8 *data_end = data + len;
696 : uint8 tmpbuf[1024];
697 4 : uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
698 : uint8 *p;
699 : int res;
700 :
701 4 : p = tmpbuf;
702 4 : if (*got_cr)
703 : {
704 0 : if (*data != '\n')
705 0 : *p++ = '\r';
706 0 : *got_cr = 0;
707 : }
708 94 : while (data < data_end)
709 : {
710 94 : if (*data == '\r')
711 : {
712 28 : if (data + 1 < data_end)
713 : {
714 24 : if (*(data + 1) == '\n')
715 14 : data++;
716 : }
717 : else
718 : {
719 4 : *got_cr = 1;
720 4 : break;
721 : }
722 : }
723 90 : *p++ = *data++;
724 90 : if (p >= tmp_end)
725 : {
726 0 : res = mbuf_append(dst, tmpbuf, p - tmpbuf);
727 0 : if (res < 0)
728 0 : return res;
729 0 : p = tmpbuf;
730 : }
731 : }
732 4 : if (p - tmpbuf > 0)
733 : {
734 4 : res = mbuf_append(dst, tmpbuf, p - tmpbuf);
735 4 : if (res < 0)
736 0 : return res;
737 : }
738 4 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
739 4 : return 0;
740 : }
741 :
742 : static int
743 138 : parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
744 : {
745 : int type;
746 : int name_len;
747 : int res;
748 : uint8 *buf;
749 : uint8 tmpbuf[4];
750 138 : int got_cr = 0;
751 :
752 138 : GETBYTE(pkt, type);
753 138 : GETBYTE(pkt, name_len);
754 :
755 : /* skip name */
756 186 : while (name_len > 0)
757 : {
758 48 : res = pullf_read(pkt, name_len, &buf);
759 48 : if (res < 0)
760 0 : return res;
761 48 : if (res == 0)
762 0 : break;
763 48 : name_len -= res;
764 : }
765 138 : if (name_len > 0)
766 : {
767 0 : px_debug("parse_literal_data: unexpected eof");
768 0 : return PXE_PGP_CORRUPT_DATA;
769 : }
770 :
771 : /* skip date */
772 138 : res = pullf_read_max(pkt, 4, &buf, tmpbuf);
773 138 : if (res != 4)
774 : {
775 0 : px_debug("parse_literal_data: unexpected eof");
776 0 : return PXE_PGP_CORRUPT_DATA;
777 : }
778 138 : px_memset(tmpbuf, 0, 4);
779 :
780 : /*
781 : * If called from an SQL function that returns text, pgp_decrypt() rejects
782 : * inputs not self-identifying as text.
783 : */
784 138 : if (ctx->text_mode)
785 130 : if (type != 't' && type != 'u')
786 : {
787 8 : px_debug("parse_literal_data: data type=%c", type);
788 8 : ctx->unexpected_binary = true;
789 : }
790 :
791 138 : ctx->unicode_mode = (type == 'u') ? 1 : 0;
792 :
793 : /* read data */
794 : while (1)
795 : {
796 318 : res = pullf_read(pkt, 32 * 1024, &buf);
797 318 : if (res <= 0)
798 138 : break;
799 :
800 180 : if (ctx->text_mode && ctx->convert_crlf)
801 4 : res = copy_crlf(dst, buf, res, &got_cr);
802 : else
803 176 : res = mbuf_append(dst, buf, res);
804 180 : if (res < 0)
805 0 : break;
806 : }
807 138 : if (res >= 0 && got_cr)
808 4 : res = mbuf_append(dst, (const uint8 *) "\r", 1);
809 138 : return res;
810 : }
811 :
812 : /* process_data_packets and parse_compressed_data call each other */
813 : static int process_data_packets(PGP_Context *ctx, MBuf *dst,
814 : PullFilter *src, int allow_compr, int need_mdc);
815 :
816 : static int
817 12 : parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
818 : {
819 : int res;
820 : uint8 type;
821 : PullFilter *pf_decompr;
822 : uint8 *discard_buf;
823 :
824 12 : GETBYTE(pkt, type);
825 :
826 12 : ctx->compress_algo = type;
827 12 : switch (type)
828 : {
829 0 : case PGP_COMPR_NONE:
830 0 : res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
831 0 : break;
832 :
833 8 : case PGP_COMPR_ZIP:
834 : case PGP_COMPR_ZLIB:
835 8 : res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
836 8 : if (res >= 0)
837 : {
838 8 : res = process_data_packets(ctx, dst, pf_decompr,
839 : NO_COMPR, NO_MDC);
840 8 : pullf_free(pf_decompr);
841 : }
842 8 : break;
843 :
844 4 : case PGP_COMPR_BZIP2:
845 4 : px_debug("parse_compressed_data: bzip2 unsupported");
846 : /* report error in pgp_decrypt() */
847 4 : ctx->unsupported_compr = 1;
848 :
849 : /*
850 : * Discard the compressed data, allowing it to first affect any
851 : * MDC digest computation.
852 : */
853 : while (1)
854 : {
855 6 : res = pullf_read(pkt, 32 * 1024, &discard_buf);
856 6 : if (res <= 0)
857 4 : break;
858 : }
859 :
860 4 : break;
861 :
862 0 : default:
863 0 : px_debug("parse_compressed_data: unknown compr type");
864 0 : res = PXE_PGP_CORRUPT_DATA;
865 : }
866 :
867 12 : return res;
868 : }
869 :
870 : static int
871 152 : process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
872 : int allow_compr, int need_mdc)
873 : {
874 : uint8 tag;
875 : int len,
876 : res;
877 152 : int got_data = 0;
878 152 : int got_mdc = 0;
879 152 : PullFilter *pkt = NULL;
880 :
881 : while (1)
882 : {
883 430 : res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
884 430 : if (res <= 0)
885 146 : break;
886 :
887 :
888 : /* mdc packet should be last */
889 284 : if (got_mdc)
890 : {
891 0 : px_debug("process_data_packets: data after mdc");
892 0 : res = PXE_PGP_CORRUPT_DATA;
893 0 : break;
894 : }
895 :
896 : /*
897 : * Context length inside SYMENCRYPTED_DATA_MDC packet needs special
898 : * handling.
899 : */
900 284 : if (need_mdc && res == PKT_CONTEXT)
901 6 : res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
902 : else
903 278 : res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
904 284 : if (res < 0)
905 0 : break;
906 :
907 284 : switch (tag)
908 : {
909 138 : case PGP_PKT_LITERAL_DATA:
910 138 : got_data = 1;
911 138 : res = parse_literal_data(ctx, dst, pkt);
912 138 : break;
913 12 : case PGP_PKT_COMPRESSED_DATA:
914 12 : if (allow_compr == 0)
915 : {
916 0 : px_debug("process_data_packets: unexpected compression");
917 0 : res = PXE_PGP_CORRUPT_DATA;
918 : }
919 12 : else if (got_data)
920 : {
921 : /*
922 : * compr data must be alone
923 : */
924 0 : px_debug("process_data_packets: only one cmpr pkt allowed");
925 0 : res = PXE_PGP_CORRUPT_DATA;
926 : }
927 : else
928 : {
929 12 : got_data = 1;
930 12 : res = parse_compressed_data(ctx, dst, pkt);
931 : }
932 12 : break;
933 132 : case PGP_PKT_MDC:
934 132 : if (need_mdc == NO_MDC)
935 : {
936 0 : px_debug("process_data_packets: unexpected MDC");
937 0 : res = PXE_PGP_CORRUPT_DATA;
938 0 : break;
939 : }
940 :
941 132 : res = mdc_finish(ctx, pkt, len);
942 132 : if (res >= 0)
943 132 : got_mdc = 1;
944 132 : break;
945 2 : default:
946 2 : px_debug("process_data_packets: unexpected pkt tag=%d", tag);
947 2 : res = PXE_PGP_CORRUPT_DATA;
948 : }
949 :
950 284 : pullf_free(pkt);
951 284 : pkt = NULL;
952 :
953 284 : if (res < 0)
954 6 : break;
955 : }
956 :
957 152 : if (pkt)
958 0 : pullf_free(pkt);
959 :
960 152 : if (res < 0)
961 6 : return res;
962 :
963 146 : if (!got_data)
964 : {
965 0 : px_debug("process_data_packets: no data");
966 0 : res = PXE_PGP_CORRUPT_DATA;
967 : }
968 146 : if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
969 : {
970 0 : px_debug("process_data_packets: got no mdc");
971 0 : res = PXE_PGP_CORRUPT_DATA;
972 : }
973 146 : return res;
974 : }
975 :
976 : static int
977 4 : parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
978 : {
979 : int res;
980 4 : PGP_CFB *cfb = NULL;
981 4 : PullFilter *pf_decrypt = NULL;
982 4 : PullFilter *pf_prefix = NULL;
983 :
984 4 : res = pgp_cfb_create(&cfb, ctx->cipher_algo,
985 4 : ctx->sess_key, ctx->sess_key_len, 1, NULL);
986 4 : if (res < 0)
987 0 : goto out;
988 :
989 4 : res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
990 4 : if (res < 0)
991 0 : goto out;
992 :
993 4 : res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
994 4 : if (res < 0)
995 0 : goto out;
996 :
997 4 : res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
998 :
999 4 : out:
1000 4 : if (pf_prefix)
1001 4 : pullf_free(pf_prefix);
1002 4 : if (pf_decrypt)
1003 4 : pullf_free(pf_decrypt);
1004 4 : if (cfb)
1005 4 : pgp_cfb_free(cfb);
1006 :
1007 4 : return res;
1008 : }
1009 :
1010 : static int
1011 140 : parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
1012 : {
1013 : int res;
1014 140 : PGP_CFB *cfb = NULL;
1015 140 : PullFilter *pf_decrypt = NULL;
1016 140 : PullFilter *pf_prefix = NULL;
1017 140 : PullFilter *pf_mdc = NULL;
1018 : uint8 ver;
1019 :
1020 140 : GETBYTE(pkt, ver);
1021 140 : if (ver != 1)
1022 : {
1023 0 : px_debug("parse_symenc_mdc_data: pkt ver != 1");
1024 0 : return PXE_PGP_CORRUPT_DATA;
1025 : }
1026 :
1027 140 : res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1028 140 : ctx->sess_key, ctx->sess_key_len, 0, NULL);
1029 140 : if (res < 0)
1030 0 : goto out;
1031 :
1032 140 : res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1033 140 : if (res < 0)
1034 0 : goto out;
1035 :
1036 140 : res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1037 140 : if (res < 0)
1038 0 : goto out;
1039 :
1040 140 : res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1041 140 : if (res < 0)
1042 0 : goto out;
1043 :
1044 140 : res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1045 :
1046 140 : out:
1047 140 : if (pf_prefix)
1048 140 : pullf_free(pf_prefix);
1049 140 : if (pf_mdc)
1050 140 : pullf_free(pf_mdc);
1051 140 : if (pf_decrypt)
1052 140 : pullf_free(pf_decrypt);
1053 140 : if (cfb)
1054 140 : pgp_cfb_free(cfb);
1055 :
1056 140 : return res;
1057 : }
1058 :
1059 : /*
1060 : * skip over packet contents
1061 : */
1062 : int
1063 318 : pgp_skip_packet(PullFilter *pkt)
1064 : {
1065 318 : int res = 1;
1066 : uint8 *tmp;
1067 :
1068 944 : while (res > 0)
1069 626 : res = pullf_read(pkt, 32 * 1024, &tmp);
1070 318 : return res;
1071 : }
1072 :
1073 : /*
1074 : * expect to be at packet end, any data is error
1075 : */
1076 : int
1077 54 : pgp_expect_packet_end(PullFilter *pkt)
1078 : {
1079 : int res;
1080 : uint8 *tmp;
1081 :
1082 54 : res = pullf_read(pkt, 32 * 1024, &tmp);
1083 54 : if (res > 0)
1084 : {
1085 0 : px_debug("pgp_expect_packet_end: got data");
1086 0 : return PXE_PGP_CORRUPT_DATA;
1087 : }
1088 54 : return res;
1089 : }
1090 :
1091 : int
1092 146 : pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
1093 : {
1094 : int res;
1095 146 : PullFilter *src = NULL;
1096 146 : PullFilter *pkt = NULL;
1097 : uint8 tag;
1098 : int len;
1099 146 : int got_key = 0;
1100 146 : int got_data = 0;
1101 :
1102 146 : res = pullf_create_mbuf_reader(&src, msrc);
1103 :
1104 436 : while (res >= 0)
1105 : {
1106 428 : res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
1107 428 : if (res <= 0)
1108 138 : break;
1109 :
1110 290 : res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
1111 290 : if (res < 0)
1112 0 : break;
1113 :
1114 290 : res = PXE_PGP_CORRUPT_DATA;
1115 290 : switch (tag)
1116 : {
1117 0 : case PGP_PKT_MARKER:
1118 0 : res = pgp_skip_packet(pkt);
1119 0 : break;
1120 28 : case PGP_PKT_PUBENCRYPTED_SESSKEY:
1121 : /* fixme: skip those */
1122 28 : res = pgp_parse_pubenc_sesskey(ctx, pkt);
1123 28 : got_key = 1;
1124 28 : break;
1125 118 : case PGP_PKT_SYMENCRYPTED_SESSKEY:
1126 118 : if (got_key)
1127 :
1128 : /*
1129 : * Theoretically, there could be several keys, both public
1130 : * and symmetric, all of which encrypt same session key.
1131 : * Decrypt should try with each one, before failing.
1132 : */
1133 0 : px_debug("pgp_decrypt: using first of several keys");
1134 : else
1135 : {
1136 118 : got_key = 1;
1137 118 : res = parse_symenc_sesskey(ctx, pkt);
1138 : }
1139 118 : break;
1140 4 : case PGP_PKT_SYMENCRYPTED_DATA:
1141 4 : if (!got_key)
1142 0 : px_debug("pgp_decrypt: have data but no key");
1143 4 : else if (got_data)
1144 0 : px_debug("pgp_decrypt: got second data packet");
1145 : else
1146 : {
1147 4 : got_data = 1;
1148 4 : ctx->disable_mdc = 1;
1149 4 : res = parse_symenc_data(ctx, pkt, mdst);
1150 : }
1151 4 : break;
1152 140 : case PGP_PKT_SYMENCRYPTED_DATA_MDC:
1153 140 : if (!got_key)
1154 0 : px_debug("pgp_decrypt: have data but no key");
1155 140 : else if (got_data)
1156 0 : px_debug("pgp_decrypt: several data pkts not supported");
1157 : else
1158 : {
1159 140 : got_data = 1;
1160 140 : ctx->disable_mdc = 0;
1161 140 : res = parse_symenc_mdc_data(ctx, pkt, mdst);
1162 : }
1163 140 : break;
1164 0 : default:
1165 0 : px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
1166 : }
1167 290 : pullf_free(pkt);
1168 290 : pkt = NULL;
1169 : }
1170 :
1171 146 : if (pkt)
1172 0 : pullf_free(pkt);
1173 :
1174 146 : if (src)
1175 146 : pullf_free(src);
1176 :
1177 146 : if (res < 0)
1178 8 : return res;
1179 :
1180 : /*
1181 : * Report a failure of the prefix_init() "quick check" now, rather than
1182 : * upon detection, to hinder timing attacks. pgcrypto is not generally
1183 : * secure against timing attacks, but this helps.
1184 : */
1185 138 : if (!got_data || ctx->corrupt_prefix)
1186 0 : return PXE_PGP_CORRUPT_DATA;
1187 :
1188 : /*
1189 : * Code interpreting purportedly-decrypted data prior to this stage shall
1190 : * report no error other than PXE_PGP_CORRUPT_DATA. (PXE_BUG is okay so
1191 : * long as it remains unreachable.) This ensures that an attacker able to
1192 : * choose a ciphertext and receive a corresponding decryption error
1193 : * message cannot use that oracle to gather clues about the decryption
1194 : * key. See "An Attack on CFB Mode Encryption As Used By OpenPGP" by
1195 : * Serge Mister and Robert Zuccherato.
1196 : *
1197 : * A problematic value in the first octet of a Literal Data or Compressed
1198 : * Data packet may indicate a simple user error, such as the need to call
1199 : * pgp_sym_decrypt_bytea instead of pgp_sym_decrypt. Occasionally,
1200 : * though, it is the first symptom of the encryption key not matching the
1201 : * decryption key. When this was the only problem encountered, report a
1202 : * specific error to guide the user; otherwise, we will have reported
1203 : * PXE_PGP_CORRUPT_DATA before now. A key mismatch makes the other errors
1204 : * into red herrings, and this avoids leaking clues to attackers.
1205 : */
1206 138 : if (ctx->unsupported_compr)
1207 2 : return PXE_PGP_UNSUPPORTED_COMPR;
1208 136 : if (ctx->unexpected_binary)
1209 6 : return PXE_PGP_NOT_TEXT;
1210 :
1211 130 : return res;
1212 : }
|