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