doc: Fix section of functions age(xid) and mxid_age(xid)
[pgsql.git] / contrib / pgcrypto / pgp-decrypt.c
blobe1ea5b3e58dcfba87cd44be7354364496ac0df2b
1 /*
2 * pgp-decrypt.c
3 * OpenPGP decrypt.
5 * Copyright (c) 2005 Marko Kreen
6 * All rights reserved.
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.
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.
29 * contrib/pgcrypto/pgp-decrypt.c
32 #include "postgres.h"
34 #include "mbuf.h"
35 #include "pgp.h"
36 #include "px.h"
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
45 #define PKT_NORMAL 1
46 #define PKT_STREAM 2
47 #define PKT_CONTEXT 3
49 #define MAX_CHUNK (16*1024*1024)
51 static int
52 parse_new_len(PullFilter *src, int *len_p)
54 uint8 b;
55 int len;
56 int pkttype = PKT_NORMAL;
58 GETBYTE(src, b);
59 if (b <= 191)
60 len = b;
61 else if (b >= 192 && b <= 223)
63 len = ((unsigned) (b) - 192) << 8;
64 GETBYTE(src, b);
65 len += 192 + b;
67 else if (b == 255)
69 GETBYTE(src, b);
70 len = b;
71 GETBYTE(src, b);
72 len = (len << 8) | b;
73 GETBYTE(src, b);
74 len = (len << 8) | b;
75 GETBYTE(src, b);
76 len = (len << 8) | b;
78 else
80 len = 1 << (b & 0x1F);
81 pkttype = PKT_STREAM;
84 if (len < 0 || len > MAX_CHUNK)
86 px_debug("parse_new_len: weird length");
87 return PXE_PGP_CORRUPT_DATA;
90 *len_p = len;
91 return pkttype;
94 static int
95 parse_old_len(PullFilter *src, int *len_p, int lentype)
97 uint8 b;
98 int len;
100 GETBYTE(src, b);
101 len = b;
103 if (lentype == 1)
105 GETBYTE(src, b);
106 len = (len << 8) | b;
108 else if (lentype == 2)
110 GETBYTE(src, b);
111 len = (len << 8) | b;
112 GETBYTE(src, b);
113 len = (len << 8) | b;
114 GETBYTE(src, b);
115 len = (len << 8) | b;
118 if (len < 0 || len > MAX_CHUNK)
120 px_debug("parse_old_len: weird length");
121 return PXE_PGP_CORRUPT_DATA;
123 *len_p = len;
124 return PKT_NORMAL;
127 /* returns pkttype or 0 on eof */
129 pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
131 int lentype;
132 int res;
133 uint8 *p;
135 /* EOF is normal here, thus we don't use GETBYTE */
136 res = pullf_read(src, 1, &p);
137 if (res < 0)
138 return res;
139 if (res == 0)
140 return 0;
142 if ((*p & 0x80) == 0)
144 px_debug("pgp_parse_pkt_hdr: not pkt hdr");
145 return PXE_PGP_CORRUPT_DATA;
148 if (*p & 0x40)
150 *tag = *p & 0x3f;
151 res = parse_new_len(src, len_p);
153 else
155 lentype = *p & 3;
156 *tag = (*p >> 2) & 0x0F;
157 if (lentype == 3)
158 res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
159 else
160 res = parse_old_len(src, len_p, lentype);
162 return res;
166 * Packet reader
168 struct PktData
170 int type;
171 int len;
174 static int
175 pktreader_pull(void *priv, PullFilter *src, int len,
176 uint8 **data_p, uint8 *buf, int buflen)
178 int res;
179 struct PktData *pkt = priv;
181 /* PKT_CONTEXT means: whatever there is */
182 if (pkt->type == PKT_CONTEXT)
183 return pullf_read(src, len, data_p);
185 while (pkt->len == 0)
187 /* this was last chunk in stream */
188 if (pkt->type == PKT_NORMAL)
189 return 0;
191 /* next chunk in stream */
192 res = parse_new_len(src, &pkt->len);
193 if (res < 0)
194 return res;
195 pkt->type = res;
198 if (len > pkt->len)
199 len = pkt->len;
201 res = pullf_read(src, len, data_p);
202 if (res > 0)
203 pkt->len -= res;
205 return res;
208 static void
209 pktreader_free(void *priv)
211 struct PktData *pkt = priv;
213 px_memset(pkt, 0, sizeof(*pkt));
214 pfree(pkt);
217 static struct PullFilterOps pktreader_filter = {
218 NULL, pktreader_pull, pktreader_free
221 /* needs helper function to pass several parameters */
223 pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
224 int pkttype, PGP_Context *ctx)
226 int res;
227 struct PktData *pkt = palloc(sizeof(*pkt));
229 pkt->type = pkttype;
230 pkt->len = len;
231 res = pullf_create(pf_p, &pktreader_filter, pkt, src);
232 if (res < 0)
233 pfree(pkt);
234 return res;
238 * Prefix check filter
239 * https://tools.ietf.org/html/rfc4880#section-5.7
240 * https://tools.ietf.org/html/rfc4880#section-5.13
243 static int
244 prefix_init(void **priv_p, void *arg, PullFilter *src)
246 PGP_Context *ctx = arg;
247 int len;
248 int res;
249 uint8 *buf;
250 uint8 tmpbuf[PGP_MAX_BLOCK + 2];
252 len = pgp_get_cipher_block_size(ctx->cipher_algo);
253 /* Make sure we have space for prefix */
254 if (len > PGP_MAX_BLOCK)
255 return PXE_BUG;
257 res = pullf_read_max(src, len + 2, &buf, tmpbuf);
258 if (res < 0)
259 return res;
260 if (res != len + 2)
262 px_debug("prefix_init: short read");
263 px_memset(tmpbuf, 0, sizeof(tmpbuf));
264 return PXE_PGP_CORRUPT_DATA;
267 if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
269 px_debug("prefix_init: corrupt prefix");
270 /* report error in pgp_decrypt() */
271 ctx->corrupt_prefix = 1;
273 px_memset(tmpbuf, 0, sizeof(tmpbuf));
274 return 0;
277 static struct PullFilterOps prefix_filter = {
278 prefix_init, NULL, NULL
283 * Decrypt filter
286 static int
287 decrypt_init(void **priv_p, void *arg, PullFilter *src)
289 PGP_CFB *cfb = arg;
291 *priv_p = cfb;
293 /* we need to write somewhere, so ask for a buffer */
294 return 4096;
297 static int
298 decrypt_read(void *priv, PullFilter *src, int len,
299 uint8 **data_p, uint8 *buf, int buflen)
301 PGP_CFB *cfb = priv;
302 uint8 *tmp;
303 int res;
305 res = pullf_read(src, len, &tmp);
306 if (res > 0)
308 pgp_cfb_decrypt(cfb, tmp, res, buf);
309 *data_p = buf;
311 return res;
314 struct PullFilterOps pgp_decrypt_filter = {
315 decrypt_init, decrypt_read, NULL
320 * MDC hasher filter
323 static int
324 mdc_init(void **priv_p, void *arg, PullFilter *src)
326 PGP_Context *ctx = arg;
328 *priv_p = ctx;
329 return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
332 static void
333 mdc_free(void *priv)
335 PGP_Context *ctx = priv;
337 if (ctx->use_mdcbuf_filter)
338 return;
339 px_md_free(ctx->mdc_ctx);
340 ctx->mdc_ctx = NULL;
343 static int
344 mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
346 int res;
347 uint8 hash[20];
348 uint8 tmpbuf[20];
349 uint8 *data;
351 /* should not happen */
352 if (ctx->use_mdcbuf_filter)
353 return PXE_BUG;
355 /* It's SHA1 */
356 if (len != 20)
357 return PXE_PGP_CORRUPT_DATA;
359 /* mdc_read should not call px_md_update */
360 ctx->in_mdc_pkt = 1;
362 /* read data */
363 res = pullf_read_max(src, len, &data, tmpbuf);
364 if (res < 0)
365 return res;
366 if (res == 0)
368 px_debug("no mdc");
369 return PXE_PGP_CORRUPT_DATA;
372 /* is the packet sane? */
373 if (res != 20)
375 px_debug("mdc_finish: read failed, res=%d", res);
376 return PXE_PGP_CORRUPT_DATA;
380 * ok, we got the hash, now check
382 px_md_finish(ctx->mdc_ctx, hash);
383 res = memcmp(hash, data, 20);
384 px_memset(hash, 0, 20);
385 px_memset(tmpbuf, 0, sizeof(tmpbuf));
386 if (res != 0)
388 px_debug("mdc_finish: mdc failed");
389 return PXE_PGP_CORRUPT_DATA;
391 ctx->mdc_checked = 1;
392 return 0;
395 static int
396 mdc_read(void *priv, PullFilter *src, int len,
397 uint8 **data_p, uint8 *buf, int buflen)
399 int res;
400 PGP_Context *ctx = priv;
402 /* skip this filter? */
403 if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
404 return pullf_read(src, len, data_p);
406 res = pullf_read(src, len, data_p);
407 if (res < 0)
408 return res;
409 if (res == 0)
411 px_debug("mdc_read: unexpected eof");
412 return PXE_PGP_CORRUPT_DATA;
414 px_md_update(ctx->mdc_ctx, *data_p, res);
416 return res;
419 static struct PullFilterOps mdc_filter = {
420 mdc_init, mdc_read, mdc_free
425 * Combined Pkt reader and MDC hasher.
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.
432 #define MDCBUF_LEN 8192
433 struct MDCBufData
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];
445 static int
446 mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
448 PGP_Context *ctx = arg;
449 struct MDCBufData *st;
451 st = palloc0(sizeof(*st));
452 st->buflen = sizeof(st->buf);
453 st->ctx = ctx;
454 *priv_p = st;
456 /* take over the work of mdc_filter */
457 ctx->use_mdcbuf_filter = 1;
459 return 0;
462 static int
463 mdcbuf_finish(struct MDCBufData *st)
465 uint8 hash[20];
466 int res;
468 st->eof = 1;
470 if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
472 px_debug("mdcbuf_finish: bad MDC pkt hdr");
473 return PXE_PGP_CORRUPT_DATA;
475 px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
476 px_md_finish(st->ctx->mdc_ctx, hash);
477 res = memcmp(hash, st->mdc_buf + 2, 20);
478 px_memset(hash, 0, 20);
479 if (res)
481 px_debug("mdcbuf_finish: MDC does not match");
482 res = PXE_PGP_CORRUPT_DATA;
484 return res;
487 static void
488 mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
490 uint8 *dst = st->pos + st->avail;
492 memcpy(dst, src, len);
493 px_md_update(st->ctx->mdc_ctx, src, len);
494 st->avail += len;
497 static void
498 mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
500 memmove(st->mdc_buf + st->mdc_avail, src, len);
501 st->mdc_avail += len;
504 static int
505 mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
507 uint8 *data;
508 int res;
509 int need;
511 /* put avail data in start */
512 if (st->avail > 0 && st->pos != st->buf)
513 memmove(st->buf, st->pos, st->avail);
514 st->pos = st->buf;
516 /* read new data */
517 need = st->buflen + 22 - st->avail - st->mdc_avail;
518 res = pullf_read(src, need, &data);
519 if (res < 0)
520 return res;
521 if (res == 0)
522 return mdcbuf_finish(st);
524 /* add to buffer */
525 if (res >= 22)
527 mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
528 st->mdc_avail = 0;
530 mdcbuf_load_data(st, data, res - 22);
531 mdcbuf_load_mdc(st, data + res - 22, 22);
533 else
535 int canmove = st->mdc_avail + res - 22;
537 if (canmove > 0)
539 mdcbuf_load_data(st, st->mdc_buf, canmove);
540 st->mdc_avail -= canmove;
541 memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
543 mdcbuf_load_mdc(st, data, res);
545 return 0;
548 static int
549 mdcbuf_read(void *priv, PullFilter *src, int len,
550 uint8 **data_p, uint8 *buf, int buflen)
552 struct MDCBufData *st = priv;
553 int res;
555 if (!st->eof && len > st->avail)
557 res = mdcbuf_refill(st, src);
558 if (res < 0)
559 return res;
562 if (len > st->avail)
563 len = st->avail;
565 *data_p = st->pos;
566 st->pos += len;
567 st->avail -= len;
568 return len;
571 static void
572 mdcbuf_free(void *priv)
574 struct MDCBufData *st = priv;
576 px_md_free(st->ctx->mdc_ctx);
577 st->ctx->mdc_ctx = NULL;
578 px_memset(st, 0, sizeof(*st));
579 pfree(st);
582 static struct PullFilterOps mdcbuf_filter = {
583 mdcbuf_init, mdcbuf_read, mdcbuf_free
588 * Decrypt separate session key
590 static int
591 decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
593 int res;
594 uint8 algo;
595 PGP_CFB *cfb;
597 res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
598 ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
599 if (res < 0)
600 return res;
602 pgp_cfb_decrypt(cfb, src, 1, &algo);
603 src++;
604 len--;
606 pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
607 pgp_cfb_free(cfb);
608 ctx->sess_key_len = len;
609 ctx->cipher_algo = algo;
611 if (pgp_get_cipher_key_size(algo) != len)
613 px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
614 algo, pgp_get_cipher_key_size(algo), len);
615 return PXE_PGP_CORRUPT_DATA;
617 return 0;
621 * Handle key packet
623 static int
624 parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
626 uint8 *p;
627 int res;
628 uint8 tmpbuf[PGP_MAX_KEY + 2];
629 uint8 ver;
631 GETBYTE(src, ver);
632 GETBYTE(src, ctx->s2k_cipher_algo);
633 if (ver != 4)
635 px_debug("bad key pkt ver");
636 return PXE_PGP_CORRUPT_DATA;
640 * read S2K info
642 res = pgp_s2k_read(src, &ctx->s2k);
643 if (res < 0)
644 return res;
645 ctx->s2k_mode = ctx->s2k.mode;
646 ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
647 ctx->s2k_digest_algo = ctx->s2k.digest_algo;
650 * generate key from password
652 res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
653 ctx->sym_key, ctx->sym_key_len);
654 if (res < 0)
655 return res;
658 * do we have separate session key?
660 res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
661 if (res < 0)
662 return res;
664 if (res == 0)
667 * no, s2k key is session key
669 memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
670 ctx->sess_key_len = ctx->s2k.key_len;
671 ctx->cipher_algo = ctx->s2k_cipher_algo;
672 res = 0;
673 ctx->use_sess_key = 0;
675 else
678 * yes, decrypt it
680 if (res < 17 || res > PGP_MAX_KEY + 1)
682 px_debug("expect key, but bad data");
683 return PXE_PGP_CORRUPT_DATA;
685 ctx->use_sess_key = 1;
686 res = decrypt_key(ctx, p, res);
689 px_memset(tmpbuf, 0, sizeof(tmpbuf));
690 return res;
693 static int
694 copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
696 uint8 *data_end = data + len;
697 uint8 tmpbuf[1024];
698 uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
699 uint8 *p;
700 int res;
702 p = tmpbuf;
703 if (*got_cr)
705 if (*data != '\n')
706 *p++ = '\r';
707 *got_cr = 0;
709 while (data < data_end)
711 if (*data == '\r')
713 if (data + 1 < data_end)
715 if (*(data + 1) == '\n')
716 data++;
718 else
720 *got_cr = 1;
721 break;
724 *p++ = *data++;
725 if (p >= tmp_end)
727 res = mbuf_append(dst, tmpbuf, p - tmpbuf);
728 if (res < 0)
729 return res;
730 p = tmpbuf;
733 if (p - tmpbuf > 0)
735 res = mbuf_append(dst, tmpbuf, p - tmpbuf);
736 if (res < 0)
737 return res;
739 px_memset(tmpbuf, 0, sizeof(tmpbuf));
740 return 0;
743 static int
744 parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
746 int type;
747 int name_len;
748 int res;
749 uint8 *buf;
750 uint8 tmpbuf[4];
751 int got_cr = 0;
753 GETBYTE(pkt, type);
754 GETBYTE(pkt, name_len);
756 /* skip name */
757 while (name_len > 0)
759 res = pullf_read(pkt, name_len, &buf);
760 if (res < 0)
761 return res;
762 if (res == 0)
763 break;
764 name_len -= res;
766 if (name_len > 0)
768 px_debug("parse_literal_data: unexpected eof");
769 return PXE_PGP_CORRUPT_DATA;
772 /* skip date */
773 res = pullf_read_max(pkt, 4, &buf, tmpbuf);
774 if (res != 4)
776 px_debug("parse_literal_data: unexpected eof");
777 return PXE_PGP_CORRUPT_DATA;
779 px_memset(tmpbuf, 0, 4);
782 * If called from an SQL function that returns text, pgp_decrypt() rejects
783 * inputs not self-identifying as text.
785 if (ctx->text_mode)
786 if (type != 't' && type != 'u')
788 px_debug("parse_literal_data: data type=%c", type);
789 ctx->unexpected_binary = true;
792 ctx->unicode_mode = (type == 'u') ? 1 : 0;
794 /* read data */
795 while (1)
797 res = pullf_read(pkt, 32 * 1024, &buf);
798 if (res <= 0)
799 break;
801 if (ctx->text_mode && ctx->convert_crlf)
802 res = copy_crlf(dst, buf, res, &got_cr);
803 else
804 res = mbuf_append(dst, buf, res);
805 if (res < 0)
806 break;
808 if (res >= 0 && got_cr)
809 res = mbuf_append(dst, (const uint8 *) "\r", 1);
810 return res;
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);
817 static int
818 parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
820 int res;
821 uint8 type;
822 PullFilter *pf_decompr;
823 uint8 *discard_buf;
825 GETBYTE(pkt, type);
827 ctx->compress_algo = type;
828 switch (type)
830 case PGP_COMPR_NONE:
831 res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
832 break;
834 case PGP_COMPR_ZIP:
835 case PGP_COMPR_ZLIB:
836 res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
837 if (res >= 0)
839 res = process_data_packets(ctx, dst, pf_decompr,
840 NO_COMPR, NO_MDC);
841 pullf_free(pf_decompr);
843 break;
845 case PGP_COMPR_BZIP2:
846 px_debug("parse_compressed_data: bzip2 unsupported");
847 /* report error in pgp_decrypt() */
848 ctx->unsupported_compr = 1;
851 * Discard the compressed data, allowing it to first affect any
852 * MDC digest computation.
854 while (1)
856 res = pullf_read(pkt, 32 * 1024, &discard_buf);
857 if (res <= 0)
858 break;
861 break;
863 default:
864 px_debug("parse_compressed_data: unknown compr type");
865 res = PXE_PGP_CORRUPT_DATA;
868 return res;
871 static int
872 process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
873 int allow_compr, int need_mdc)
875 uint8 tag;
876 int len,
877 res;
878 int got_data = 0;
879 int got_mdc = 0;
880 PullFilter *pkt = NULL;
882 while (1)
884 res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
885 if (res <= 0)
886 break;
889 /* mdc packet should be last */
890 if (got_mdc)
892 px_debug("process_data_packets: data after mdc");
893 res = PXE_PGP_CORRUPT_DATA;
894 break;
898 * Context length inside SYMENCRYPTED_DATA_MDC packet needs special
899 * handling.
901 if (need_mdc && res == PKT_CONTEXT)
902 res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
903 else
904 res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
905 if (res < 0)
906 break;
908 switch (tag)
910 case PGP_PKT_LITERAL_DATA:
911 got_data = 1;
912 res = parse_literal_data(ctx, dst, pkt);
913 break;
914 case PGP_PKT_COMPRESSED_DATA:
915 if (allow_compr == 0)
917 px_debug("process_data_packets: unexpected compression");
918 res = PXE_PGP_CORRUPT_DATA;
920 else if (got_data)
923 * compr data must be alone
925 px_debug("process_data_packets: only one cmpr pkt allowed");
926 res = PXE_PGP_CORRUPT_DATA;
928 else
930 got_data = 1;
931 res = parse_compressed_data(ctx, dst, pkt);
933 break;
934 case PGP_PKT_MDC:
935 if (need_mdc == NO_MDC)
937 px_debug("process_data_packets: unexpected MDC");
938 res = PXE_PGP_CORRUPT_DATA;
939 break;
942 res = mdc_finish(ctx, pkt, len);
943 if (res >= 0)
944 got_mdc = 1;
945 break;
946 default:
947 px_debug("process_data_packets: unexpected pkt tag=%d", tag);
948 res = PXE_PGP_CORRUPT_DATA;
951 pullf_free(pkt);
952 pkt = NULL;
954 if (res < 0)
955 break;
958 if (pkt)
959 pullf_free(pkt);
961 if (res < 0)
962 return res;
964 if (!got_data)
966 px_debug("process_data_packets: no data");
967 res = PXE_PGP_CORRUPT_DATA;
969 if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
971 px_debug("process_data_packets: got no mdc");
972 res = PXE_PGP_CORRUPT_DATA;
974 return res;
977 static int
978 parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
980 int res;
981 PGP_CFB *cfb = NULL;
982 PullFilter *pf_decrypt = NULL;
983 PullFilter *pf_prefix = NULL;
985 res = pgp_cfb_create(&cfb, ctx->cipher_algo,
986 ctx->sess_key, ctx->sess_key_len, 1, NULL);
987 if (res < 0)
988 goto out;
990 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
991 if (res < 0)
992 goto out;
994 res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
995 if (res < 0)
996 goto out;
998 res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
1000 out:
1001 if (pf_prefix)
1002 pullf_free(pf_prefix);
1003 if (pf_decrypt)
1004 pullf_free(pf_decrypt);
1005 if (cfb)
1006 pgp_cfb_free(cfb);
1008 return res;
1011 static int
1012 parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
1014 int res;
1015 PGP_CFB *cfb = NULL;
1016 PullFilter *pf_decrypt = NULL;
1017 PullFilter *pf_prefix = NULL;
1018 PullFilter *pf_mdc = NULL;
1019 uint8 ver;
1021 GETBYTE(pkt, ver);
1022 if (ver != 1)
1024 px_debug("parse_symenc_mdc_data: pkt ver != 1");
1025 return PXE_PGP_CORRUPT_DATA;
1028 res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1029 ctx->sess_key, ctx->sess_key_len, 0, NULL);
1030 if (res < 0)
1031 goto out;
1033 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1034 if (res < 0)
1035 goto out;
1037 res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1038 if (res < 0)
1039 goto out;
1041 res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1042 if (res < 0)
1043 goto out;
1045 res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1047 out:
1048 if (pf_prefix)
1049 pullf_free(pf_prefix);
1050 if (pf_mdc)
1051 pullf_free(pf_mdc);
1052 if (pf_decrypt)
1053 pullf_free(pf_decrypt);
1054 if (cfb)
1055 pgp_cfb_free(cfb);
1057 return res;
1061 * skip over packet contents
1064 pgp_skip_packet(PullFilter *pkt)
1066 int res = 1;
1067 uint8 *tmp;
1069 while (res > 0)
1070 res = pullf_read(pkt, 32 * 1024, &tmp);
1071 return res;
1075 * expect to be at packet end, any data is error
1078 pgp_expect_packet_end(PullFilter *pkt)
1080 int res;
1081 uint8 *tmp;
1083 res = pullf_read(pkt, 32 * 1024, &tmp);
1084 if (res > 0)
1086 px_debug("pgp_expect_packet_end: got data");
1087 return PXE_PGP_CORRUPT_DATA;
1089 return res;
1093 pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
1095 int res;
1096 PullFilter *src = NULL;
1097 PullFilter *pkt = NULL;
1098 uint8 tag;
1099 int len;
1100 int got_key = 0;
1101 int got_data = 0;
1103 res = pullf_create_mbuf_reader(&src, msrc);
1105 while (res >= 0)
1107 res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
1108 if (res <= 0)
1109 break;
1111 res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
1112 if (res < 0)
1113 break;
1115 res = PXE_PGP_CORRUPT_DATA;
1116 switch (tag)
1118 case PGP_PKT_MARKER:
1119 res = pgp_skip_packet(pkt);
1120 break;
1121 case PGP_PKT_PUBENCRYPTED_SESSKEY:
1122 /* fixme: skip those */
1123 res = pgp_parse_pubenc_sesskey(ctx, pkt);
1124 got_key = 1;
1125 break;
1126 case PGP_PKT_SYMENCRYPTED_SESSKEY:
1127 if (got_key)
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.
1134 px_debug("pgp_decrypt: using first of several keys");
1135 else
1137 got_key = 1;
1138 res = parse_symenc_sesskey(ctx, pkt);
1140 break;
1141 case PGP_PKT_SYMENCRYPTED_DATA:
1142 if (!got_key)
1143 px_debug("pgp_decrypt: have data but no key");
1144 else if (got_data)
1145 px_debug("pgp_decrypt: got second data packet");
1146 else
1148 got_data = 1;
1149 ctx->disable_mdc = 1;
1150 res = parse_symenc_data(ctx, pkt, mdst);
1152 break;
1153 case PGP_PKT_SYMENCRYPTED_DATA_MDC:
1154 if (!got_key)
1155 px_debug("pgp_decrypt: have data but no key");
1156 else if (got_data)
1157 px_debug("pgp_decrypt: several data pkts not supported");
1158 else
1160 got_data = 1;
1161 ctx->disable_mdc = 0;
1162 res = parse_symenc_mdc_data(ctx, pkt, mdst);
1164 break;
1165 default:
1166 px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
1168 pullf_free(pkt);
1169 pkt = NULL;
1172 if (pkt)
1173 pullf_free(pkt);
1175 if (src)
1176 pullf_free(src);
1178 if (res < 0)
1179 return res;
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.
1186 if (!got_data || ctx->corrupt_prefix)
1187 return PXE_PGP_CORRUPT_DATA;
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.
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.
1207 if (ctx->unsupported_compr)
1208 return PXE_PGP_UNSUPPORTED_COMPR;
1209 if (ctx->unexpected_binary)
1210 return PXE_PGP_NOT_TEXT;
1212 return res;