Age Owner TLA 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
5050 bruce 52 CBC 268 : parse_new_len(PullFilter *src, int *len_p)
53 : {
54 : uint8 b;
55 : int len;
6482 56 268 : int pkttype = PKT_NORMAL;
57 :
58 268 : GETBYTE(src, b);
59 268 : if (b <= 191)
60 244 : len = b;
61 24 : else if (b >= 192 && b <= 223)
62 : {
63 8 : len = ((unsigned) (b) - 192) << 8;
64 8 : GETBYTE(src, b);
65 8 : 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 268 : if (len < 0 || len > MAX_CHUNK)
85 : {
6482 bruce 86 UBC 0 : px_debug("parse_new_len: weird length");
87 0 : return PXE_PGP_CORRUPT_DATA;
88 : }
89 :
6482 bruce 90 CBC 268 : *len_p = len;
91 268 : return pkttype;
92 : }
93 :
94 : static int
5050 95 213 : parse_old_len(PullFilter *src, int *len_p, int lentype)
96 : {
97 : uint8 b;
98 : int len;
99 :
6482 100 213 : GETBYTE(src, b);
101 213 : len = b;
102 :
103 213 : if (lentype == 1)
104 : {
105 102 : GETBYTE(src, b);
106 102 : len = (len << 8) | b;
107 : }
108 111 : else if (lentype == 2)
109 : {
6482 bruce 110 UBC 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 :
6482 bruce 118 CBC 213 : if (len < 0 || len > MAX_CHUNK)
119 : {
6482 bruce 120 UBC 0 : px_debug("parse_old_len: weird length");
121 0 : return PXE_PGP_CORRUPT_DATA;
122 : }
6482 bruce 123 CBC 213 : *len_p = len;
124 213 : return PKT_NORMAL;
125 : }
126 :
127 : /* returns pkttype or 0 on eof */
128 : int
5050 129 645 : 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 */
6482 136 645 : res = pullf_read(src, 1, &p);
137 645 : if (res < 0)
6482 bruce 138 UBC 0 : return res;
6482 bruce 139 CBC 645 : if (res == 0)
140 172 : return 0;
141 :
142 473 : 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 471 : if (*p & 0x40)
149 : {
150 255 : *tag = *p & 0x3f;
151 255 : res = parse_new_len(src, len_p);
152 : }
153 : else
154 : {
155 216 : lentype = *p & 3;
156 216 : *tag = (*p >> 2) & 0x0F;
157 216 : if (lentype == 3)
158 3 : res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
159 : else
160 213 : res = parse_old_len(src, len_p, lentype);
161 : }
162 471 : return res;
163 : }
164 :
165 : /*
166 : * Packet reader
167 : */
168 : struct PktData
169 : {
170 : int type;
171 : int len;
172 : };
173 :
174 : static int
5050 175 2542 : pktreader_pull(void *priv, PullFilter *src, int len,
176 : uint8 **data_p, uint8 *buf, int buflen)
177 : {
178 : int res;
6482 179 2542 : struct PktData *pkt = priv;
180 :
181 : /* PKT_CONTEXT means: whatever there is */
182 2542 : if (pkt->type == PKT_CONTEXT)
6482 bruce 183 UBC 0 : return pullf_read(src, len, data_p);
184 :
3071 tgl 185 CBC 2555 : while (pkt->len == 0)
186 : {
187 : /* this was last chunk in stream */
6482 bruce 188 400 : if (pkt->type == PKT_NORMAL)
189 387 : return 0;
190 :
191 : /* next chunk in stream */
192 13 : res = parse_new_len(src, &pkt->len);
193 13 : if (res < 0)
6482 bruce 194 UBC 0 : return res;
6482 bruce 195 CBC 13 : pkt->type = res;
196 : }
197 :
198 2155 : if (len > pkt->len)
199 263 : len = pkt->len;
200 :
201 2155 : res = pullf_read(src, len, data_p);
202 2155 : if (res > 0)
203 2155 : pkt->len -= res;
204 :
205 2155 : return res;
206 : }
207 :
208 : static void
209 468 : pktreader_free(void *priv)
210 : {
211 468 : struct PktData *pkt = priv;
212 :
3279 213 468 : px_memset(pkt, 0, sizeof(*pkt));
926 michael 214 468 : pfree(pkt);
6482 bruce 215 468 : }
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
5050 223 468 : pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
224 : int pkttype, PGP_Context *ctx)
225 : {
226 : int res;
926 michael 227 468 : struct PktData *pkt = palloc(sizeof(*pkt));
228 :
6482 bruce 229 468 : pkt->type = pkttype;
230 468 : pkt->len = len;
231 468 : res = pullf_create(pf_p, &pktreader_filter, pkt, src);
232 468 : if (res < 0)
926 michael 233 UBC 0 : pfree(pkt);
6482 bruce 234 CBC 468 : 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
5050 244 72 : prefix_init(void **priv_p, void *arg, PullFilter *src)
245 : {
6482 246 72 : PGP_Context *ctx = arg;
247 : int len;
248 : int res;
249 : uint8 *buf;
250 : uint8 tmpbuf[PGP_MAX_BLOCK + 2];
251 :
252 72 : len = pgp_get_cipher_block_size(ctx->cipher_algo);
253 72 : if (len > sizeof(tmpbuf))
6482 bruce 254 UBC 0 : return PXE_BUG;
255 :
6482 bruce 256 CBC 72 : res = pullf_read_max(src, len + 2, &buf, tmpbuf);
257 72 : if (res < 0)
6482 bruce 258 UBC 0 : return res;
6482 bruce 259 CBC 72 : if (res != len + 2)
260 : {
6482 bruce 261 UBC 0 : px_debug("prefix_init: short read");
3279 262 0 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
6482 263 0 : return PXE_PGP_CORRUPT_DATA;
264 : }
265 :
6482 bruce 266 CBC 72 : 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 : }
3279 272 72 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
6482 273 72 : 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
5050 286 76 : decrypt_init(void **priv_p, void *arg, PullFilter *src)
287 : {
6385 288 76 : PGP_CFB *cfb = arg;
289 :
6482 290 76 : *priv_p = cfb;
291 :
292 : /* we need to write somewhere, so ask for a buffer */
293 76 : return 4096;
294 : }
295 :
296 : static int
5050 297 804 : decrypt_read(void *priv, PullFilter *src, int len,
298 : uint8 **data_p, uint8 *buf, int buflen)
299 : {
6385 300 804 : PGP_CFB *cfb = priv;
301 : uint8 *tmp;
302 : int res;
303 :
6482 304 804 : res = pullf_read(src, len, &tmp);
6385 305 804 : if (res > 0)
306 : {
6482 307 730 : pgp_cfb_decrypt(cfb, tmp, res, buf);
308 730 : *data_p = buf;
309 : }
310 804 : 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
5050 323 70 : mdc_init(void **priv_p, void *arg, PullFilter *src)
324 : {
6482 325 70 : PGP_Context *ctx = arg;
326 :
327 70 : *priv_p = ctx;
328 70 : return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
329 : }
330 :
331 : static void
6385 332 70 : mdc_free(void *priv)
333 : {
6482 334 70 : PGP_Context *ctx = priv;
335 :
336 70 : if (ctx->use_mdcbuf_filter)
337 3 : return;
338 67 : px_md_free(ctx->mdc_ctx);
339 67 : ctx->mdc_ctx = NULL;
340 : }
341 :
342 : static int
2991 tgl 343 64 : 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 64 : if (ctx->use_mdcbuf_filter)
6482 bruce 352 UBC 0 : return PXE_BUG;
353 :
354 : /* It's SHA1 */
2991 tgl 355 CBC 64 : if (len != 20)
2991 tgl 356 UBC 0 : return PXE_PGP_CORRUPT_DATA;
357 :
358 : /* mdc_read should not call px_md_update */
2991 tgl 359 CBC 64 : ctx->in_mdc_pkt = 1;
360 :
361 : /* read data */
362 64 : res = pullf_read_max(src, len, &data, tmpbuf);
6482 bruce 363 64 : if (res < 0)
6482 bruce 364 UBC 0 : return res;
6482 bruce 365 CBC 64 : if (res == 0)
366 : {
2991 tgl 367 UBC 0 : px_debug("no mdc");
6482 bruce 368 0 : return PXE_PGP_CORRUPT_DATA;
369 : }
370 :
371 : /* is the packet sane? */
6482 bruce 372 CBC 64 : if (res != 20)
373 : {
6482 bruce 374 UBC 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 : */
6482 bruce 381 CBC 64 : px_md_finish(ctx->mdc_ctx, hash);
2991 tgl 382 64 : res = memcmp(hash, data, 20);
3279 bruce 383 64 : px_memset(hash, 0, 20);
384 64 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
6482 385 64 : if (res != 0)
386 : {
6482 bruce 387 UBC 0 : px_debug("mdc_finish: mdc failed");
388 0 : return PXE_PGP_CORRUPT_DATA;
389 : }
6482 bruce 390 CBC 64 : ctx->mdc_checked = 1;
2991 tgl 391 64 : return 0;
392 : }
393 :
394 : static int
5050 bruce 395 765 : mdc_read(void *priv, PullFilter *src, int len,
396 : uint8 **data_p, uint8 *buf, int buflen)
397 : {
398 : int res;
6482 399 765 : PGP_Context *ctx = priv;
400 :
401 : /* skip this filter? */
2991 tgl 402 765 : if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
6482 bruce 403 135 : return pullf_read(src, len, data_p);
404 :
405 630 : res = pullf_read(src, len, data_p);
406 630 : if (res < 0)
6482 bruce 407 UBC 0 : return res;
6482 bruce 408 CBC 630 : if (res == 0)
409 : {
6482 bruce 410 UBC 0 : px_debug("mdc_read: unexpected eof");
411 0 : return PXE_PGP_CORRUPT_DATA;
412 : }
6482 bruce 413 CBC 630 : px_md_update(ctx->mdc_ctx, *data_p, res);
414 :
415 630 : 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
5050 445 3 : mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
446 : {
6482 447 3 : PGP_Context *ctx = arg;
448 : struct MDCBufData *st;
449 :
926 michael 450 3 : st = palloc0(sizeof(*st));
6482 bruce 451 3 : st->buflen = sizeof(st->buf);
452 3 : st->ctx = ctx;
453 3 : *priv_p = st;
454 :
455 : /* take over the work of mdc_filter */
456 3 : ctx->use_mdcbuf_filter = 1;
457 :
458 3 : return 0;
459 : }
460 :
461 : static int
2118 tgl 462 3 : mdcbuf_finish(struct MDCBufData *st)
463 : {
464 : uint8 hash[20];
465 : int res;
466 :
6482 bruce 467 3 : st->eof = 1;
468 :
469 3 : if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
470 : {
471 2 : px_debug("mdcbuf_finish: bad MDC pkt hdr");
472 2 : return PXE_PGP_CORRUPT_DATA;
473 : }
474 1 : px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
475 1 : px_md_finish(st->ctx->mdc_ctx, hash);
476 1 : res = memcmp(hash, st->mdc_buf + 2, 20);
3279 477 1 : px_memset(hash, 0, 20);
6482 478 1 : if (res)
479 : {
6482 bruce 480 UBC 0 : px_debug("mdcbuf_finish: MDC does not match");
481 0 : res = PXE_PGP_CORRUPT_DATA;
482 : }
6482 bruce 483 CBC 1 : return res;
484 : }
485 :
486 : static void
2118 tgl 487 6 : mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
488 : {
6385 bruce 489 6 : uint8 *dst = st->pos + st->avail;
490 :
6482 491 6 : memcpy(dst, src, len);
492 6 : px_md_update(st->ctx->mdc_ctx, src, len);
493 6 : st->avail += len;
494 6 : }
495 :
496 : static void
2118 tgl 497 3 : mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
498 : {
6482 bruce 499 3 : memmove(st->mdc_buf + st->mdc_avail, src, len);
500 3 : st->mdc_avail += len;
501 3 : }
502 :
503 : static int
2118 tgl 504 6 : mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
505 : {
506 : uint8 *data;
507 : int res;
508 : int need;
509 :
510 : /* put avail data in start */
6482 bruce 511 6 : if (st->avail > 0 && st->pos != st->buf)
512 3 : memmove(st->buf, st->pos, st->avail);
513 6 : st->pos = st->buf;
514 :
515 : /* read new data */
516 6 : need = st->buflen + 22 - st->avail - st->mdc_avail;
517 6 : res = pullf_read(src, need, &data);
518 6 : if (res < 0)
6482 bruce 519 UBC 0 : return res;
6482 bruce 520 CBC 6 : if (res == 0)
521 3 : return mdcbuf_finish(st);
522 :
523 : /* add to buffer */
524 3 : if (res >= 22)
525 : {
526 3 : mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
527 3 : st->mdc_avail = 0;
528 :
529 3 : mdcbuf_load_data(st, data, res - 22);
530 3 : mdcbuf_load_mdc(st, data + res - 22, 22);
531 : }
532 : else
533 : {
6385 bruce 534 UBC 0 : int canmove = st->mdc_avail + res - 22;
535 :
6482 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 : }
6482 bruce 544 CBC 3 : return 0;
545 : }
546 :
547 : static int
5050 548 10 : mdcbuf_read(void *priv, PullFilter *src, int len,
549 : uint8 **data_p, uint8 *buf, int buflen)
550 : {
6482 551 10 : struct MDCBufData *st = priv;
552 : int res;
553 :
554 10 : if (!st->eof && len > st->avail)
555 : {
556 6 : res = mdcbuf_refill(st, src);
557 6 : if (res < 0)
558 2 : return res;
559 : }
560 :
561 8 : if (len > st->avail)
562 2 : len = st->avail;
563 :
564 8 : *data_p = st->pos;
565 8 : st->pos += len;
566 8 : st->avail -= len;
567 8 : return len;
568 : }
569 :
570 : static void
571 3 : mdcbuf_free(void *priv)
572 : {
573 3 : struct MDCBufData *st = priv;
574 :
575 3 : px_md_free(st->ctx->mdc_ctx);
576 3 : st->ctx->mdc_ctx = NULL;
3279 577 3 : px_memset(st, 0, sizeof(*st));
926 michael 578 3 : pfree(st);
6482 bruce 579 3 : }
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
5050 590 4 : decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
591 : {
592 : int res;
593 : uint8 algo;
594 : PGP_CFB *cfb;
595 :
6482 596 4 : res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
6385 597 4 : ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
6482 598 4 : if (res < 0)
6482 bruce 599 UBC 0 : return res;
600 :
6482 bruce 601 CBC 4 : pgp_cfb_decrypt(cfb, src, 1, &algo);
6385 602 4 : src++;
603 4 : len--;
604 :
6482 605 4 : pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
606 4 : pgp_cfb_free(cfb);
607 4 : ctx->sess_key_len = len;
608 4 : ctx->cipher_algo = algo;
609 :
6385 610 4 : if (pgp_get_cipher_key_size(algo) != len)
611 : {
6482 bruce 612 UBC 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 : }
6482 bruce 616 CBC 4 : return 0;
617 : }
618 :
619 : /*
620 : * Handle key packet
621 : */
622 : static int
5050 623 59 : 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 :
6482 630 59 : GETBYTE(src, ver);
631 59 : GETBYTE(src, ctx->s2k_cipher_algo);
632 59 : if (ver != 4)
633 : {
6482 bruce 634 UBC 0 : px_debug("bad key pkt ver");
635 0 : return PXE_PGP_CORRUPT_DATA;
636 : }
637 :
638 : /*
639 : * read S2K info
640 : */
6482 bruce 641 CBC 59 : res = pgp_s2k_read(src, &ctx->s2k);
642 59 : if (res < 0)
6482 bruce 643 UBC 0 : return res;
6482 bruce 644 CBC 59 : ctx->s2k_mode = ctx->s2k.mode;
2587 alvherre 645 59 : ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
6482 bruce 646 59 : ctx->s2k_digest_algo = ctx->s2k.digest_algo;
647 :
648 : /*
649 : * generate key from password
650 : */
651 59 : res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
652 : ctx->sym_key, ctx->sym_key_len);
653 59 : if (res < 0)
6482 bruce 654 UBC 0 : return res;
655 :
656 : /*
657 : * do we have separate session key?
658 : */
6482 bruce 659 CBC 59 : res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
660 59 : if (res < 0)
6482 bruce 661 UBC 0 : return res;
662 :
6482 bruce 663 CBC 59 : if (res == 0)
664 : {
665 : /*
666 : * no, s2k key is session key
667 : */
668 55 : memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
669 55 : ctx->sess_key_len = ctx->s2k.key_len;
670 55 : ctx->cipher_algo = ctx->s2k_cipher_algo;
671 55 : res = 0;
672 55 : ctx->use_sess_key = 0;
673 : }
674 : else
675 : {
676 : /*
677 : * yes, decrypt it
678 : */
679 4 : if (res < 17 || res > PGP_MAX_KEY + 1)
680 : {
6482 bruce 681 UBC 0 : px_debug("expect key, but bad data");
682 0 : return PXE_PGP_CORRUPT_DATA;
683 : }
6482 bruce 684 CBC 4 : ctx->use_sess_key = 1;
685 4 : res = decrypt_key(ctx, p, res);
686 : }
687 :
3279 688 59 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
6482 689 59 : return res;
690 : }
691 :
692 : static int
5050 693 2 : copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
694 : {
6385 695 2 : uint8 *data_end = data + len;
696 : uint8 tmpbuf[1024];
697 2 : uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
698 : uint8 *p;
699 : int res;
700 :
6482 701 2 : p = tmpbuf;
6385 702 2 : if (*got_cr)
703 : {
6482 bruce 704 UBC 0 : if (*data != '\n')
705 0 : *p++ = '\r';
706 0 : *got_cr = 0;
707 : }
6385 bruce 708 CBC 47 : while (data < data_end)
709 : {
6482 710 47 : if (*data == '\r')
711 : {
712 14 : if (data + 1 < data_end)
713 : {
714 12 : if (*(data + 1) == '\n')
715 7 : data++;
716 : }
717 : else
718 : {
719 2 : *got_cr = 1;
720 2 : break;
721 : }
722 : }
723 45 : *p++ = *data++;
724 45 : if (p >= tmp_end)
725 : {
6482 bruce 726 UBC 0 : res = mbuf_append(dst, tmpbuf, p - tmpbuf);
727 0 : if (res < 0)
728 0 : return res;
729 0 : p = tmpbuf;
730 : }
731 : }
6482 bruce 732 CBC 2 : if (p - tmpbuf > 0)
733 : {
734 2 : res = mbuf_append(dst, tmpbuf, p - tmpbuf);
735 2 : if (res < 0)
6482 bruce 736 UBC 0 : return res;
737 : }
3279 bruce 738 CBC 2 : px_memset(tmpbuf, 0, sizeof(tmpbuf));
6482 739 2 : return 0;
740 : }
741 :
742 : static int
5050 743 67 : 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];
6482 750 67 : int got_cr = 0;
751 :
752 67 : GETBYTE(pkt, type);
753 67 : GETBYTE(pkt, name_len);
754 :
755 : /* skip name */
756 90 : while (name_len > 0)
757 : {
758 23 : res = pullf_read(pkt, name_len, &buf);
759 23 : if (res < 0)
6482 bruce 760 UBC 0 : return res;
6482 bruce 761 CBC 23 : if (res == 0)
6482 bruce 762 UBC 0 : break;
6482 bruce 763 CBC 23 : name_len -= res;
764 : }
765 67 : if (name_len > 0)
766 : {
6482 bruce 767 UBC 0 : px_debug("parse_literal_data: unexpected eof");
768 0 : return PXE_PGP_CORRUPT_DATA;
769 : }
770 :
771 : /* skip date */
6482 bruce 772 CBC 67 : res = pullf_read_max(pkt, 4, &buf, tmpbuf);
773 67 : if (res != 4)
774 : {
6482 bruce 775 UBC 0 : px_debug("parse_literal_data: unexpected eof");
776 0 : return PXE_PGP_CORRUPT_DATA;
777 : }
3279 bruce 778 CBC 67 : 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 : */
6482 784 67 : if (ctx->text_mode)
785 63 : if (type != 't' && type != 'u')
786 : {
787 4 : px_debug("parse_literal_data: data type=%c", type);
2883 noah 788 4 : ctx->unexpected_binary = true;
789 : }
790 :
6482 bruce 791 67 : ctx->unicode_mode = (type == 'u') ? 1 : 0;
792 :
793 : /* read data */
794 : while (1)
795 : {
6385 796 155 : res = pullf_read(pkt, 32 * 1024, &buf);
6482 797 155 : if (res <= 0)
798 67 : break;
799 :
800 88 : if (ctx->text_mode && ctx->convert_crlf)
801 2 : res = copy_crlf(dst, buf, res, &got_cr);
802 : else
803 86 : res = mbuf_append(dst, buf, res);
804 88 : if (res < 0)
6482 bruce 805 UBC 0 : break;
806 : }
6482 bruce 807 CBC 67 : if (res >= 0 && got_cr)
6406 tgl 808 2 : res = mbuf_append(dst, (const uint8 *) "\r", 1);
6482 bruce 809 67 : 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
5050 817 6 : 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 :
6482 824 6 : GETBYTE(pkt, type);
825 :
826 6 : ctx->compress_algo = type;
827 6 : switch (type)
828 : {
6482 bruce 829 UBC 0 : case PGP_COMPR_NONE:
830 0 : res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
831 0 : break;
832 :
6482 bruce 833 CBC 4 : case PGP_COMPR_ZIP:
834 : case PGP_COMPR_ZLIB:
835 4 : res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
836 4 : if (res >= 0)
837 : {
838 4 : res = process_data_packets(ctx, dst, pf_decompr,
839 : NO_COMPR, NO_MDC);
840 4 : pullf_free(pf_decompr);
841 : }
842 4 : break;
843 :
844 2 : case PGP_COMPR_BZIP2:
845 2 : px_debug("parse_compressed_data: bzip2 unsupported");
846 : /* report error in pgp_decrypt() */
2883 noah 847 2 : 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 3 : res = pullf_read(pkt, 32 * 1024, &discard_buf);
856 3 : if (res <= 0)
857 2 : break;
858 : }
859 :
6482 bruce 860 2 : break;
861 :
6482 bruce 862 UBC 0 : default:
863 0 : px_debug("parse_compressed_data: unknown compr type");
864 0 : res = PXE_PGP_CORRUPT_DATA;
865 : }
866 :
6482 bruce 867 CBC 6 : return res;
868 : }
869 :
870 : static int
5050 871 76 : 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;
6482 877 76 : int got_data = 0;
878 76 : int got_mdc = 0;
879 76 : PullFilter *pkt = NULL;
880 :
881 : while (1)
882 : {
883 211 : res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
884 211 : if (res <= 0)
885 73 : break;
886 :
887 :
888 : /* mdc packet should be last */
889 138 : if (got_mdc)
890 : {
6482 bruce 891 UBC 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 : */
6482 bruce 900 CBC 138 : if (need_mdc && res == PKT_CONTEXT)
901 3 : res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
902 : else
903 135 : res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
904 138 : if (res < 0)
6482 bruce 905 UBC 0 : break;
906 :
6482 bruce 907 CBC 138 : switch (tag)
908 : {
909 67 : case PGP_PKT_LITERAL_DATA:
910 67 : got_data = 1;
911 67 : res = parse_literal_data(ctx, dst, pkt);
912 67 : break;
913 6 : case PGP_PKT_COMPRESSED_DATA:
914 6 : if (allow_compr == 0)
915 : {
6482 bruce 916 UBC 0 : px_debug("process_data_packets: unexpected compression");
917 0 : res = PXE_PGP_CORRUPT_DATA;
918 : }
6482 bruce 919 CBC 6 : else if (got_data)
920 : {
921 : /*
922 : * compr data must be alone
923 : */
6482 bruce 924 UBC 0 : px_debug("process_data_packets: only one cmpr pkt allowed");
925 0 : res = PXE_PGP_CORRUPT_DATA;
926 : }
927 : else
928 : {
6482 bruce 929 CBC 6 : got_data = 1;
930 6 : res = parse_compressed_data(ctx, dst, pkt);
931 : }
932 6 : break;
933 64 : case PGP_PKT_MDC:
934 64 : if (need_mdc == NO_MDC)
935 : {
6482 bruce 936 UBC 0 : px_debug("process_data_packets: unexpected MDC");
937 0 : res = PXE_PGP_CORRUPT_DATA;
938 0 : break;
939 : }
940 :
2991 tgl 941 CBC 64 : res = mdc_finish(ctx, pkt, len);
942 64 : if (res >= 0)
6482 bruce 943 64 : got_mdc = 1;
944 64 : break;
945 1 : default:
946 1 : px_debug("process_data_packets: unexpected pkt tag=%d", tag);
947 1 : res = PXE_PGP_CORRUPT_DATA;
948 : }
949 :
950 138 : pullf_free(pkt);
951 138 : pkt = NULL;
952 :
953 138 : if (res < 0)
954 3 : break;
955 : }
956 :
957 76 : if (pkt)
6482 bruce 958 UBC 0 : pullf_free(pkt);
959 :
6482 bruce 960 CBC 76 : if (res < 0)
961 5 : return res;
962 :
963 71 : if (!got_data)
964 : {
6482 bruce 965 UBC 0 : px_debug("process_data_packets: no data");
966 0 : res = PXE_PGP_CORRUPT_DATA;
967 : }
6482 bruce 968 CBC 71 : if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
969 : {
6482 bruce 970 UBC 0 : px_debug("process_data_packets: got no mdc");
971 0 : res = PXE_PGP_CORRUPT_DATA;
972 : }
6482 bruce 973 CBC 71 : return res;
974 : }
975 :
976 : static int
5050 977 2 : parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
978 : {
979 : int res;
6385 980 2 : PGP_CFB *cfb = NULL;
6482 981 2 : PullFilter *pf_decrypt = NULL;
982 2 : PullFilter *pf_prefix = NULL;
983 :
984 2 : res = pgp_cfb_create(&cfb, ctx->cipher_algo,
6385 985 2 : ctx->sess_key, ctx->sess_key_len, 1, NULL);
6482 986 2 : if (res < 0)
6482 bruce 987 UBC 0 : goto out;
988 :
6482 bruce 989 CBC 2 : res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
990 2 : if (res < 0)
6482 bruce 991 UBC 0 : goto out;
992 :
6482 bruce 993 CBC 2 : res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
994 2 : if (res < 0)
6482 bruce 995 UBC 0 : goto out;
996 :
6482 bruce 997 CBC 2 : res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
998 :
999 2 : out:
1000 2 : if (pf_prefix)
1001 2 : pullf_free(pf_prefix);
1002 2 : if (pf_decrypt)
1003 2 : pullf_free(pf_decrypt);
1004 2 : if (cfb)
1005 2 : pgp_cfb_free(cfb);
1006 :
1007 2 : return res;
1008 : }
1009 :
1010 : static int
5050 1011 70 : parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
1012 : {
1013 : int res;
6385 1014 70 : PGP_CFB *cfb = NULL;
6482 1015 70 : PullFilter *pf_decrypt = NULL;
1016 70 : PullFilter *pf_prefix = NULL;
1017 70 : PullFilter *pf_mdc = NULL;
1018 : uint8 ver;
1019 :
1020 70 : GETBYTE(pkt, ver);
1021 70 : if (ver != 1)
1022 : {
6482 bruce 1023 UBC 0 : px_debug("parse_symenc_mdc_data: pkt ver != 1");
1024 0 : return PXE_PGP_CORRUPT_DATA;
1025 : }
1026 :
6482 bruce 1027 CBC 70 : res = pgp_cfb_create(&cfb, ctx->cipher_algo,
6385 1028 70 : ctx->sess_key, ctx->sess_key_len, 0, NULL);
6482 1029 70 : if (res < 0)
6482 bruce 1030 UBC 0 : goto out;
1031 :
6482 bruce 1032 CBC 70 : res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1033 70 : if (res < 0)
6482 bruce 1034 UBC 0 : goto out;
1035 :
6482 bruce 1036 CBC 70 : res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1037 70 : if (res < 0)
6482 bruce 1038 UBC 0 : goto out;
1039 :
6482 bruce 1040 CBC 70 : res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1041 70 : if (res < 0)
6482 bruce 1042 UBC 0 : goto out;
1043 :
6482 bruce 1044 CBC 70 : res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1045 :
1046 70 : out:
1047 70 : if (pf_prefix)
1048 70 : pullf_free(pf_prefix);
1049 70 : if (pf_mdc)
1050 70 : pullf_free(pf_mdc);
1051 70 : if (pf_decrypt)
1052 70 : pullf_free(pf_decrypt);
1053 70 : if (cfb)
1054 70 : pgp_cfb_free(cfb);
1055 :
1056 70 : return res;
1057 : }
1058 :
1059 : /*
1060 : * skip over packet contents
1061 : */
1062 : int
5050 1063 159 : pgp_skip_packet(PullFilter *pkt)
1064 : {
6385 1065 159 : int res = 1;
1066 : uint8 *tmp;
1067 :
1068 472 : while (res > 0)
1069 313 : res = pullf_read(pkt, 32 * 1024, &tmp);
3080 noah 1070 159 : return res;
1071 : }
1072 :
1073 : /*
1074 : * expect to be at packet end, any data is error
1075 : */
1076 : int
5050 bruce 1077 27 : pgp_expect_packet_end(PullFilter *pkt)
1078 : {
1079 : int res;
1080 : uint8 *tmp;
1081 :
3080 noah 1082 27 : res = pullf_read(pkt, 32 * 1024, &tmp);
1083 27 : if (res > 0)
1084 : {
3080 noah 1085 UBC 0 : px_debug("pgp_expect_packet_end: got data");
1086 0 : return PXE_PGP_CORRUPT_DATA;
1087 : }
3080 noah 1088 CBC 27 : return res;
1089 : }
1090 :
1091 : int
5050 bruce 1092 73 : pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
1093 : {
1094 : int res;
6482 1095 73 : PullFilter *src = NULL;
1096 73 : PullFilter *pkt = NULL;
1097 : uint8 tag;
1098 : int len;
6385 1099 73 : int got_key = 0;
1100 73 : int got_data = 0;
1101 :
6482 1102 73 : res = pullf_create_mbuf_reader(&src, msrc);
1103 :
6385 1104 218 : while (res >= 0)
1105 : {
6482 1106 212 : res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
1107 212 : if (res <= 0)
1108 67 : break;
1109 :
1110 145 : res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
1111 145 : if (res < 0)
6482 bruce 1112 UBC 0 : break;
1113 :
6482 bruce 1114 CBC 145 : res = PXE_PGP_CORRUPT_DATA;
6385 1115 145 : switch (tag)
1116 : {
6482 bruce 1117 UBC 0 : case PGP_PKT_MARKER:
1118 0 : res = pgp_skip_packet(pkt);
1119 0 : break;
6482 bruce 1120 CBC 14 : case PGP_PKT_PUBENCRYPTED_SESSKEY:
1121 : /* fixme: skip those */
1122 14 : res = pgp_parse_pubenc_sesskey(ctx, pkt);
1123 14 : got_key = 1;
1124 14 : break;
1125 59 : case PGP_PKT_SYMENCRYPTED_SESSKEY:
1126 59 : 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 : */
6482 bruce 1133 UBC 0 : px_debug("pgp_decrypt: using first of several keys");
1134 : else
1135 : {
6482 bruce 1136 CBC 59 : got_key = 1;
1137 59 : res = parse_symenc_sesskey(ctx, pkt);
1138 : }
1139 59 : break;
1140 2 : case PGP_PKT_SYMENCRYPTED_DATA:
1141 2 : if (!got_key)
6482 bruce 1142 UBC 0 : px_debug("pgp_decrypt: have data but no key");
6482 bruce 1143 CBC 2 : else if (got_data)
6482 bruce 1144 UBC 0 : px_debug("pgp_decrypt: got second data packet");
1145 : else
1146 : {
6482 bruce 1147 CBC 2 : got_data = 1;
1148 2 : ctx->disable_mdc = 1;
1149 2 : res = parse_symenc_data(ctx, pkt, mdst);
1150 : }
1151 2 : break;
1152 70 : case PGP_PKT_SYMENCRYPTED_DATA_MDC:
1153 70 : if (!got_key)
6482 bruce 1154 UBC 0 : px_debug("pgp_decrypt: have data but no key");
6482 bruce 1155 CBC 70 : else if (got_data)
6482 bruce 1156 UBC 0 : px_debug("pgp_decrypt: several data pkts not supported");
1157 : else
1158 : {
6482 bruce 1159 CBC 70 : got_data = 1;
1160 70 : ctx->disable_mdc = 0;
1161 70 : res = parse_symenc_mdc_data(ctx, pkt, mdst);
1162 : }
1163 70 : break;
6482 bruce 1164 UBC 0 : default:
1165 0 : px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
1166 : }
6482 bruce 1167 CBC 145 : pullf_free(pkt);
1168 145 : pkt = NULL;
1169 : }
1170 :
1171 73 : if (pkt)
6482 bruce 1172 UBC 0 : pullf_free(pkt);
1173 :
6482 bruce 1174 CBC 73 : if (src)
1175 73 : pullf_free(src);
1176 :
1177 73 : if (res < 0)
1178 6 : 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 67 : if (!got_data || ctx->corrupt_prefix)
2883 noah 1186 UBC 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 : */
2883 noah 1206 CBC 67 : if (ctx->unsupported_compr)
1207 1 : return PXE_PGP_UNSUPPORTED_COMPR;
1208 66 : if (ctx->unexpected_binary)
1209 3 : return PXE_PGP_NOT_TEXT;
1210 :
6482 bruce 1211 63 : return res;
1212 : }
|