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 : /* Make sure we have space for prefix */
254 144 : if (len > PGP_MAX_BLOCK)
255 0 : return PXE_BUG;
256 :
257 144 : res = pullf_read_max(src, len + 2, &buf, tmpbuf);
258 144 : if (res < 0)
259 0 : return res;
260 144 : 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 144 : 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 144 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
274 144 : 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 152 : decrypt_init(void **priv_p, void *arg, PullFilter *src)
288 : {
289 152 : PGP_CFB *cfb = arg;
290 :
291 152 : *priv_p = cfb;
292 :
293 : /* we need to write somewhere, so ask for a buffer */
294 152 : return 4096;
295 : }
296 :
297 : static int
298 1646 : decrypt_read(void *priv, PullFilter *src, int len,
299 : uint8 **data_p, uint8 *buf, int buflen)
300 : {
301 1646 : PGP_CFB *cfb = priv;
302 : uint8 *tmp;
303 : int res;
304 :
305 1646 : res = pullf_read(src, len, &tmp);
306 1646 : if (res > 0)
307 : {
308 1494 : pgp_cfb_decrypt(cfb, tmp, res, buf);
309 1494 : *data_p = buf;
310 : }
311 1646 : 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 140 : mdc_init(void **priv_p, void *arg, PullFilter *src)
325 : {
326 140 : PGP_Context *ctx = arg;
327 :
328 140 : *priv_p = ctx;
329 140 : return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
330 : }
331 :
332 : static void
333 140 : mdc_free(void *priv)
334 : {
335 140 : PGP_Context *ctx = priv;
336 :
337 140 : if (ctx->use_mdcbuf_filter)
338 6 : return;
339 134 : px_md_free(ctx->mdc_ctx);
340 134 : ctx->mdc_ctx = NULL;
341 : }
342 :
343 : static int
344 132 : 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 132 : if (ctx->use_mdcbuf_filter)
353 0 : return PXE_BUG;
354 :
355 : /* It's SHA1 */
356 132 : if (len != 20)
357 0 : return PXE_PGP_CORRUPT_DATA;
358 :
359 : /* mdc_read should not call px_md_update */
360 132 : ctx->in_mdc_pkt = 1;
361 :
362 : /* read data */
363 132 : res = pullf_read_max(src, len, &data, tmpbuf);
364 132 : if (res < 0)
365 0 : return res;
366 132 : 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 132 : 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 132 : px_md_finish(ctx->mdc_ctx, hash);
383 132 : res = memcmp(hash, data, 20);
384 132 : px_memset(hash, 0, 20);
385 132 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
386 132 : if (res != 0)
387 : {
388 0 : px_debug("mdc_finish: mdc failed");
389 0 : return PXE_PGP_CORRUPT_DATA;
390 : }
391 132 : ctx->mdc_checked = 1;
392 132 : return 0;
393 : }
394 :
395 : static int
396 1568 : mdc_read(void *priv, PullFilter *src, int len,
397 : uint8 **data_p, uint8 *buf, int buflen)
398 : {
399 : int res;
400 1568 : PGP_Context *ctx = priv;
401 :
402 : /* skip this filter? */
403 1568 : if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
404 278 : return pullf_read(src, len, data_p);
405 :
406 1290 : res = pullf_read(src, len, data_p);
407 1290 : if (res < 0)
408 0 : return res;
409 1290 : if (res == 0)
410 : {
411 0 : px_debug("mdc_read: unexpected eof");
412 0 : return PXE_PGP_CORRUPT_DATA;
413 : }
414 1290 : px_md_update(ctx->mdc_ctx, *data_p, res);
415 :
416 1290 : 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 6 : mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
447 : {
448 6 : PGP_Context *ctx = arg;
449 : struct MDCBufData *st;
450 :
451 6 : st = palloc0(sizeof(*st));
452 6 : st->buflen = sizeof(st->buf);
453 6 : st->ctx = ctx;
454 6 : *priv_p = st;
455 :
456 : /* take over the work of mdc_filter */
457 6 : ctx->use_mdcbuf_filter = 1;
458 :
459 6 : return 0;
460 : }
461 :
462 : static int
463 6 : mdcbuf_finish(struct MDCBufData *st)
464 : {
465 : uint8 hash[20];
466 : int res;
467 :
468 6 : st->eof = 1;
469 :
470 6 : if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
471 : {
472 4 : px_debug("mdcbuf_finish: bad MDC pkt hdr");
473 4 : return PXE_PGP_CORRUPT_DATA;
474 : }
475 2 : px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
476 2 : px_md_finish(st->ctx->mdc_ctx, hash);
477 2 : res = memcmp(hash, st->mdc_buf + 2, 20);
478 2 : px_memset(hash, 0, 20);
479 2 : if (res)
480 : {
481 0 : px_debug("mdcbuf_finish: MDC does not match");
482 0 : res = PXE_PGP_CORRUPT_DATA;
483 : }
484 2 : return res;
485 : }
486 :
487 : static void
488 12 : mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
489 : {
490 12 : uint8 *dst = st->pos + st->avail;
491 :
492 12 : memcpy(dst, src, len);
493 12 : px_md_update(st->ctx->mdc_ctx, src, len);
494 12 : st->avail += len;
495 12 : }
496 :
497 : static void
498 6 : mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
499 : {
500 6 : memmove(st->mdc_buf + st->mdc_avail, src, len);
501 6 : st->mdc_avail += len;
502 6 : }
503 :
504 : static int
505 12 : 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 12 : if (st->avail > 0 && st->pos != st->buf)
513 6 : memmove(st->buf, st->pos, st->avail);
514 12 : st->pos = st->buf;
515 :
516 : /* read new data */
517 12 : need = st->buflen + 22 - st->avail - st->mdc_avail;
518 12 : res = pullf_read(src, need, &data);
519 12 : if (res < 0)
520 0 : return res;
521 12 : if (res == 0)
522 6 : return mdcbuf_finish(st);
523 :
524 : /* add to buffer */
525 6 : if (res >= 22)
526 : {
527 6 : mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
528 6 : st->mdc_avail = 0;
529 :
530 6 : mdcbuf_load_data(st, data, res - 22);
531 6 : 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 6 : return 0;
546 : }
547 :
548 : static int
549 20 : mdcbuf_read(void *priv, PullFilter *src, int len,
550 : uint8 **data_p, uint8 *buf, int buflen)
551 : {
552 20 : struct MDCBufData *st = priv;
553 : int res;
554 :
555 20 : if (!st->eof && len > st->avail)
556 : {
557 12 : res = mdcbuf_refill(st, src);
558 12 : if (res < 0)
559 4 : return res;
560 : }
561 :
562 16 : if (len > st->avail)
563 4 : len = st->avail;
564 :
565 16 : *data_p = st->pos;
566 16 : st->pos += len;
567 16 : st->avail -= len;
568 16 : return len;
569 : }
570 :
571 : static void
572 6 : mdcbuf_free(void *priv)
573 : {
574 6 : struct MDCBufData *st = priv;
575 :
576 6 : px_md_free(st->ctx->mdc_ctx);
577 6 : st->ctx->mdc_ctx = NULL;
578 6 : px_memset(st, 0, sizeof(*st));
579 6 : pfree(st);
580 6 : }
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 8 : decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
592 : {
593 : int res;
594 : uint8 algo;
595 : PGP_CFB *cfb;
596 :
597 8 : res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
598 8 : ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
599 8 : if (res < 0)
600 0 : return res;
601 :
602 8 : pgp_cfb_decrypt(cfb, src, 1, &algo);
603 8 : src++;
604 8 : len--;
605 :
606 8 : pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
607 8 : pgp_cfb_free(cfb);
608 8 : ctx->sess_key_len = len;
609 8 : ctx->cipher_algo = algo;
610 :
611 8 : 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 8 : return 0;
618 : }
619 :
620 : /*
621 : * Handle key packet
622 : */
623 : static int
624 118 : 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 118 : GETBYTE(src, ver);
632 118 : GETBYTE(src, ctx->s2k_cipher_algo);
633 118 : 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 118 : res = pgp_s2k_read(src, &ctx->s2k);
643 118 : if (res < 0)
644 0 : return res;
645 118 : ctx->s2k_mode = ctx->s2k.mode;
646 118 : ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
647 118 : ctx->s2k_digest_algo = ctx->s2k.digest_algo;
648 :
649 : /*
650 : * generate key from password
651 : */
652 118 : res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
653 : ctx->sym_key, ctx->sym_key_len);
654 118 : if (res < 0)
655 0 : return res;
656 :
657 : /*
658 : * do we have separate session key?
659 : */
660 118 : res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
661 118 : if (res < 0)
662 0 : return res;
663 :
664 118 : if (res == 0)
665 : {
666 : /*
667 : * no, s2k key is session key
668 : */
669 110 : memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
670 110 : ctx->sess_key_len = ctx->s2k.key_len;
671 110 : ctx->cipher_algo = ctx->s2k_cipher_algo;
672 110 : res = 0;
673 110 : ctx->use_sess_key = 0;
674 : }
675 : else
676 : {
677 : /*
678 : * yes, decrypt it
679 : */
680 8 : 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 8 : ctx->use_sess_key = 1;
686 8 : res = decrypt_key(ctx, p, res);
687 : }
688 :
689 118 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
690 118 : return res;
691 : }
692 :
693 : static int
694 4 : copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
695 : {
696 4 : uint8 *data_end = data + len;
697 : uint8 tmpbuf[1024];
698 4 : uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
699 : uint8 *p;
700 : int res;
701 :
702 4 : p = tmpbuf;
703 4 : if (*got_cr)
704 : {
705 0 : if (*data != '\n')
706 0 : *p++ = '\r';
707 0 : *got_cr = 0;
708 : }
709 94 : while (data < data_end)
710 : {
711 94 : if (*data == '\r')
712 : {
713 28 : if (data + 1 < data_end)
714 : {
715 24 : if (*(data + 1) == '\n')
716 14 : data++;
717 : }
718 : else
719 : {
720 4 : *got_cr = 1;
721 4 : break;
722 : }
723 : }
724 90 : *p++ = *data++;
725 90 : 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 4 : if (p - tmpbuf > 0)
734 : {
735 4 : res = mbuf_append(dst, tmpbuf, p - tmpbuf);
736 4 : if (res < 0)
737 0 : return res;
738 : }
739 4 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
740 4 : return 0;
741 : }
742 :
743 : static int
744 138 : 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 138 : int got_cr = 0;
752 :
753 138 : GETBYTE(pkt, type);
754 138 : GETBYTE(pkt, name_len);
755 :
756 : /* skip name */
757 186 : while (name_len > 0)
758 : {
759 48 : res = pullf_read(pkt, name_len, &buf);
760 48 : if (res < 0)
761 0 : return res;
762 48 : if (res == 0)
763 0 : break;
764 48 : name_len -= res;
765 : }
766 138 : 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 138 : res = pullf_read_max(pkt, 4, &buf, tmpbuf);
774 138 : if (res != 4)
775 : {
776 0 : px_debug("parse_literal_data: unexpected eof");
777 0 : return PXE_PGP_CORRUPT_DATA;
778 : }
779 138 : 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 138 : if (ctx->text_mode)
786 130 : if (type != 't' && type != 'u')
787 : {
788 8 : px_debug("parse_literal_data: data type=%c", type);
789 8 : ctx->unexpected_binary = true;
790 : }
791 :
792 138 : ctx->unicode_mode = (type == 'u') ? 1 : 0;
793 :
794 : /* read data */
795 : while (1)
796 : {
797 318 : res = pullf_read(pkt, 32 * 1024, &buf);
798 318 : if (res <= 0)
799 138 : break;
800 :
801 180 : if (ctx->text_mode && ctx->convert_crlf)
802 4 : res = copy_crlf(dst, buf, res, &got_cr);
803 : else
804 176 : res = mbuf_append(dst, buf, res);
805 180 : if (res < 0)
806 0 : break;
807 : }
808 138 : if (res >= 0 && got_cr)
809 4 : res = mbuf_append(dst, (const uint8 *) "\r", 1);
810 138 : 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 12 : 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 12 : GETBYTE(pkt, type);
826 :
827 12 : ctx->compress_algo = type;
828 12 : 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 8 : case PGP_COMPR_ZIP:
835 : case PGP_COMPR_ZLIB:
836 8 : res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
837 8 : if (res >= 0)
838 : {
839 8 : res = process_data_packets(ctx, dst, pf_decompr,
840 : NO_COMPR, NO_MDC);
841 8 : pullf_free(pf_decompr);
842 : }
843 8 : break;
844 :
845 4 : case PGP_COMPR_BZIP2:
846 4 : px_debug("parse_compressed_data: bzip2 unsupported");
847 : /* report error in pgp_decrypt() */
848 4 : 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 6 : res = pullf_read(pkt, 32 * 1024, &discard_buf);
857 6 : if (res <= 0)
858 4 : break;
859 : }
860 :
861 4 : 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 12 : return res;
869 : }
870 :
871 : static int
872 152 : 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 152 : int got_data = 0;
879 152 : int got_mdc = 0;
880 152 : PullFilter *pkt = NULL;
881 :
882 : while (1)
883 : {
884 430 : res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
885 430 : if (res <= 0)
886 146 : break;
887 :
888 :
889 : /* mdc packet should be last */
890 284 : 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 284 : if (need_mdc && res == PKT_CONTEXT)
902 6 : res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
903 : else
904 278 : res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
905 284 : if (res < 0)
906 0 : break;
907 :
908 284 : switch (tag)
909 : {
910 138 : case PGP_PKT_LITERAL_DATA:
911 138 : got_data = 1;
912 138 : res = parse_literal_data(ctx, dst, pkt);
913 138 : break;
914 12 : case PGP_PKT_COMPRESSED_DATA:
915 12 : if (allow_compr == 0)
916 : {
917 0 : px_debug("process_data_packets: unexpected compression");
918 0 : res = PXE_PGP_CORRUPT_DATA;
919 : }
920 12 : 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 12 : got_data = 1;
931 12 : res = parse_compressed_data(ctx, dst, pkt);
932 : }
933 12 : break;
934 132 : case PGP_PKT_MDC:
935 132 : 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 132 : res = mdc_finish(ctx, pkt, len);
943 132 : if (res >= 0)
944 132 : got_mdc = 1;
945 132 : break;
946 2 : default:
947 2 : px_debug("process_data_packets: unexpected pkt tag=%d", tag);
948 2 : res = PXE_PGP_CORRUPT_DATA;
949 : }
950 :
951 284 : pullf_free(pkt);
952 284 : pkt = NULL;
953 :
954 284 : if (res < 0)
955 6 : break;
956 : }
957 :
958 152 : if (pkt)
959 0 : pullf_free(pkt);
960 :
961 152 : if (res < 0)
962 6 : return res;
963 :
964 146 : if (!got_data)
965 : {
966 0 : px_debug("process_data_packets: no data");
967 0 : res = PXE_PGP_CORRUPT_DATA;
968 : }
969 146 : 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 146 : return res;
975 : }
976 :
977 : static int
978 4 : parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
979 : {
980 : int res;
981 4 : PGP_CFB *cfb = NULL;
982 4 : PullFilter *pf_decrypt = NULL;
983 4 : PullFilter *pf_prefix = NULL;
984 :
985 4 : res = pgp_cfb_create(&cfb, ctx->cipher_algo,
986 4 : ctx->sess_key, ctx->sess_key_len, 1, NULL);
987 4 : if (res < 0)
988 0 : goto out;
989 :
990 4 : res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
991 4 : if (res < 0)
992 0 : goto out;
993 :
994 4 : res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
995 4 : if (res < 0)
996 0 : goto out;
997 :
998 4 : res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
999 :
1000 4 : out:
1001 4 : if (pf_prefix)
1002 4 : pullf_free(pf_prefix);
1003 4 : if (pf_decrypt)
1004 4 : pullf_free(pf_decrypt);
1005 4 : if (cfb)
1006 4 : pgp_cfb_free(cfb);
1007 :
1008 4 : return res;
1009 : }
1010 :
1011 : static int
1012 140 : parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
1013 : {
1014 : int res;
1015 140 : PGP_CFB *cfb = NULL;
1016 140 : PullFilter *pf_decrypt = NULL;
1017 140 : PullFilter *pf_prefix = NULL;
1018 140 : PullFilter *pf_mdc = NULL;
1019 : uint8 ver;
1020 :
1021 140 : GETBYTE(pkt, ver);
1022 140 : 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 140 : res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1029 140 : ctx->sess_key, ctx->sess_key_len, 0, NULL);
1030 140 : if (res < 0)
1031 0 : goto out;
1032 :
1033 140 : res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1034 140 : if (res < 0)
1035 0 : goto out;
1036 :
1037 140 : res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1038 140 : if (res < 0)
1039 0 : goto out;
1040 :
1041 140 : res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1042 140 : if (res < 0)
1043 0 : goto out;
1044 :
1045 140 : res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1046 :
1047 140 : out:
1048 140 : if (pf_prefix)
1049 140 : pullf_free(pf_prefix);
1050 140 : if (pf_mdc)
1051 140 : pullf_free(pf_mdc);
1052 140 : if (pf_decrypt)
1053 140 : pullf_free(pf_decrypt);
1054 140 : if (cfb)
1055 140 : pgp_cfb_free(cfb);
1056 :
1057 140 : return res;
1058 : }
1059 :
1060 : /*
1061 : * skip over packet contents
1062 : */
1063 : int
1064 318 : pgp_skip_packet(PullFilter *pkt)
1065 : {
1066 318 : int res = 1;
1067 : uint8 *tmp;
1068 :
1069 944 : while (res > 0)
1070 626 : res = pullf_read(pkt, 32 * 1024, &tmp);
1071 318 : return res;
1072 : }
1073 :
1074 : /*
1075 : * expect to be at packet end, any data is error
1076 : */
1077 : int
1078 54 : pgp_expect_packet_end(PullFilter *pkt)
1079 : {
1080 : int res;
1081 : uint8 *tmp;
1082 :
1083 54 : res = pullf_read(pkt, 32 * 1024, &tmp);
1084 54 : if (res > 0)
1085 : {
1086 0 : px_debug("pgp_expect_packet_end: got data");
1087 0 : return PXE_PGP_CORRUPT_DATA;
1088 : }
1089 54 : return res;
1090 : }
1091 :
1092 : int
1093 146 : pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
1094 : {
1095 : int res;
1096 146 : PullFilter *src = NULL;
1097 146 : PullFilter *pkt = NULL;
1098 : uint8 tag;
1099 : int len;
1100 146 : int got_key = 0;
1101 146 : int got_data = 0;
1102 :
1103 146 : res = pullf_create_mbuf_reader(&src, msrc);
1104 :
1105 436 : while (res >= 0)
1106 : {
1107 428 : res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
1108 428 : if (res <= 0)
1109 138 : break;
1110 :
1111 290 : res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
1112 290 : if (res < 0)
1113 0 : break;
1114 :
1115 290 : res = PXE_PGP_CORRUPT_DATA;
1116 290 : switch (tag)
1117 : {
1118 0 : case PGP_PKT_MARKER:
1119 0 : res = pgp_skip_packet(pkt);
1120 0 : break;
1121 28 : case PGP_PKT_PUBENCRYPTED_SESSKEY:
1122 : /* fixme: skip those */
1123 28 : res = pgp_parse_pubenc_sesskey(ctx, pkt);
1124 28 : got_key = 1;
1125 28 : break;
1126 118 : case PGP_PKT_SYMENCRYPTED_SESSKEY:
1127 118 : 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 118 : got_key = 1;
1138 118 : res = parse_symenc_sesskey(ctx, pkt);
1139 : }
1140 118 : break;
1141 4 : case PGP_PKT_SYMENCRYPTED_DATA:
1142 4 : if (!got_key)
1143 0 : px_debug("pgp_decrypt: have data but no key");
1144 4 : else if (got_data)
1145 0 : px_debug("pgp_decrypt: got second data packet");
1146 : else
1147 : {
1148 4 : got_data = 1;
1149 4 : ctx->disable_mdc = 1;
1150 4 : res = parse_symenc_data(ctx, pkt, mdst);
1151 : }
1152 4 : break;
1153 140 : case PGP_PKT_SYMENCRYPTED_DATA_MDC:
1154 140 : if (!got_key)
1155 0 : px_debug("pgp_decrypt: have data but no key");
1156 140 : else if (got_data)
1157 0 : px_debug("pgp_decrypt: several data pkts not supported");
1158 : else
1159 : {
1160 140 : got_data = 1;
1161 140 : ctx->disable_mdc = 0;
1162 140 : res = parse_symenc_mdc_data(ctx, pkt, mdst);
1163 : }
1164 140 : break;
1165 0 : default:
1166 0 : px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
1167 : }
1168 290 : pullf_free(pkt);
1169 290 : pkt = NULL;
1170 : }
1171 :
1172 146 : if (pkt)
1173 0 : pullf_free(pkt);
1174 :
1175 146 : if (src)
1176 146 : pullf_free(src);
1177 :
1178 146 : if (res < 0)
1179 8 : 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 138 : 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 138 : if (ctx->unsupported_compr)
1208 2 : return PXE_PGP_UNSUPPORTED_COMPR;
1209 136 : if (ctx->unexpected_binary)
1210 6 : return PXE_PGP_NOT_TEXT;
1211 :
1212 130 : return res;
1213 : }
|