README: remove duplicate download link & mention related softw.
[pgsql.git] / contrib / pgcrypto / pgp-decrypt.c
blobd12dcad19452d3c651ea9a1711e16c8927cde7ac
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 if (len > sizeof(tmpbuf))
254 return PXE_BUG;
256 res = pullf_read_max(src, len + 2, &buf, tmpbuf);
257 if (res < 0)
258 return res;
259 if (res != len + 2)
261 px_debug("prefix_init: short read");
262 px_memset(tmpbuf, 0, sizeof(tmpbuf));
263 return PXE_PGP_CORRUPT_DATA;
266 if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
268 px_debug("prefix_init: corrupt prefix");
269 /* report error in pgp_decrypt() */
270 ctx->corrupt_prefix = 1;
272 px_memset(tmpbuf, 0, sizeof(tmpbuf));
273 return 0;
276 static struct PullFilterOps prefix_filter = {
277 prefix_init, NULL, NULL
282 * Decrypt filter
285 static int
286 decrypt_init(void **priv_p, void *arg, PullFilter *src)
288 PGP_CFB *cfb = arg;
290 *priv_p = cfb;
292 /* we need to write somewhere, so ask for a buffer */
293 return 4096;
296 static int
297 decrypt_read(void *priv, PullFilter *src, int len,
298 uint8 **data_p, uint8 *buf, int buflen)
300 PGP_CFB *cfb = priv;
301 uint8 *tmp;
302 int res;
304 res = pullf_read(src, len, &tmp);
305 if (res > 0)
307 pgp_cfb_decrypt(cfb, tmp, res, buf);
308 *data_p = buf;
310 return res;
313 struct PullFilterOps pgp_decrypt_filter = {
314 decrypt_init, decrypt_read, NULL
319 * MDC hasher filter
322 static int
323 mdc_init(void **priv_p, void *arg, PullFilter *src)
325 PGP_Context *ctx = arg;
327 *priv_p = ctx;
328 return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
331 static void
332 mdc_free(void *priv)
334 PGP_Context *ctx = priv;
336 if (ctx->use_mdcbuf_filter)
337 return;
338 px_md_free(ctx->mdc_ctx);
339 ctx->mdc_ctx = NULL;
342 static int
343 mdc_finish(PGP_Context *ctx, PullFilter *src, int len)
345 int res;
346 uint8 hash[20];
347 uint8 tmpbuf[20];
348 uint8 *data;
350 /* should not happen */
351 if (ctx->use_mdcbuf_filter)
352 return PXE_BUG;
354 /* It's SHA1 */
355 if (len != 20)
356 return PXE_PGP_CORRUPT_DATA;
358 /* mdc_read should not call px_md_update */
359 ctx->in_mdc_pkt = 1;
361 /* read data */
362 res = pullf_read_max(src, len, &data, tmpbuf);
363 if (res < 0)
364 return res;
365 if (res == 0)
367 px_debug("no mdc");
368 return PXE_PGP_CORRUPT_DATA;
371 /* is the packet sane? */
372 if (res != 20)
374 px_debug("mdc_finish: read failed, res=%d", res);
375 return PXE_PGP_CORRUPT_DATA;
379 * ok, we got the hash, now check
381 px_md_finish(ctx->mdc_ctx, hash);
382 res = memcmp(hash, data, 20);
383 px_memset(hash, 0, 20);
384 px_memset(tmpbuf, 0, sizeof(tmpbuf));
385 if (res != 0)
387 px_debug("mdc_finish: mdc failed");
388 return PXE_PGP_CORRUPT_DATA;
390 ctx->mdc_checked = 1;
391 return 0;
394 static int
395 mdc_read(void *priv, PullFilter *src, int len,
396 uint8 **data_p, uint8 *buf, int buflen)
398 int res;
399 PGP_Context *ctx = priv;
401 /* skip this filter? */
402 if (ctx->use_mdcbuf_filter || ctx->in_mdc_pkt)
403 return pullf_read(src, len, data_p);
405 res = pullf_read(src, len, data_p);
406 if (res < 0)
407 return res;
408 if (res == 0)
410 px_debug("mdc_read: unexpected eof");
411 return PXE_PGP_CORRUPT_DATA;
413 px_md_update(ctx->mdc_ctx, *data_p, res);
415 return res;
418 static struct PullFilterOps mdc_filter = {
419 mdc_init, mdc_read, mdc_free
424 * Combined Pkt reader and MDC hasher.
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.
431 #define MDCBUF_LEN 8192
432 struct MDCBufData
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];
444 static int
445 mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
447 PGP_Context *ctx = arg;
448 struct MDCBufData *st;
450 st = palloc0(sizeof(*st));
451 st->buflen = sizeof(st->buf);
452 st->ctx = ctx;
453 *priv_p = st;
455 /* take over the work of mdc_filter */
456 ctx->use_mdcbuf_filter = 1;
458 return 0;
461 static int
462 mdcbuf_finish(struct MDCBufData *st)
464 uint8 hash[20];
465 int res;
467 st->eof = 1;
469 if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
471 px_debug("mdcbuf_finish: bad MDC pkt hdr");
472 return PXE_PGP_CORRUPT_DATA;
474 px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
475 px_md_finish(st->ctx->mdc_ctx, hash);
476 res = memcmp(hash, st->mdc_buf + 2, 20);
477 px_memset(hash, 0, 20);
478 if (res)
480 px_debug("mdcbuf_finish: MDC does not match");
481 res = PXE_PGP_CORRUPT_DATA;
483 return res;
486 static void
487 mdcbuf_load_data(struct MDCBufData *st, uint8 *src, int len)
489 uint8 *dst = st->pos + st->avail;
491 memcpy(dst, src, len);
492 px_md_update(st->ctx->mdc_ctx, src, len);
493 st->avail += len;
496 static void
497 mdcbuf_load_mdc(struct MDCBufData *st, uint8 *src, int len)
499 memmove(st->mdc_buf + st->mdc_avail, src, len);
500 st->mdc_avail += len;
503 static int
504 mdcbuf_refill(struct MDCBufData *st, PullFilter *src)
506 uint8 *data;
507 int res;
508 int need;
510 /* put avail data in start */
511 if (st->avail > 0 && st->pos != st->buf)
512 memmove(st->buf, st->pos, st->avail);
513 st->pos = st->buf;
515 /* read new data */
516 need = st->buflen + 22 - st->avail - st->mdc_avail;
517 res = pullf_read(src, need, &data);
518 if (res < 0)
519 return res;
520 if (res == 0)
521 return mdcbuf_finish(st);
523 /* add to buffer */
524 if (res >= 22)
526 mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
527 st->mdc_avail = 0;
529 mdcbuf_load_data(st, data, res - 22);
530 mdcbuf_load_mdc(st, data + res - 22, 22);
532 else
534 int canmove = st->mdc_avail + res - 22;
536 if (canmove > 0)
538 mdcbuf_load_data(st, st->mdc_buf, canmove);
539 st->mdc_avail -= canmove;
540 memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
542 mdcbuf_load_mdc(st, data, res);
544 return 0;
547 static int
548 mdcbuf_read(void *priv, PullFilter *src, int len,
549 uint8 **data_p, uint8 *buf, int buflen)
551 struct MDCBufData *st = priv;
552 int res;
554 if (!st->eof && len > st->avail)
556 res = mdcbuf_refill(st, src);
557 if (res < 0)
558 return res;
561 if (len > st->avail)
562 len = st->avail;
564 *data_p = st->pos;
565 st->pos += len;
566 st->avail -= len;
567 return len;
570 static void
571 mdcbuf_free(void *priv)
573 struct MDCBufData *st = priv;
575 px_md_free(st->ctx->mdc_ctx);
576 st->ctx->mdc_ctx = NULL;
577 px_memset(st, 0, sizeof(*st));
578 pfree(st);
581 static struct PullFilterOps mdcbuf_filter = {
582 mdcbuf_init, mdcbuf_read, mdcbuf_free
587 * Decrypt separate session key
589 static int
590 decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
592 int res;
593 uint8 algo;
594 PGP_CFB *cfb;
596 res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
597 ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
598 if (res < 0)
599 return res;
601 pgp_cfb_decrypt(cfb, src, 1, &algo);
602 src++;
603 len--;
605 pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
606 pgp_cfb_free(cfb);
607 ctx->sess_key_len = len;
608 ctx->cipher_algo = algo;
610 if (pgp_get_cipher_key_size(algo) != len)
612 px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
613 algo, pgp_get_cipher_key_size(algo), len);
614 return PXE_PGP_CORRUPT_DATA;
616 return 0;
620 * Handle key packet
622 static int
623 parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
625 uint8 *p;
626 int res;
627 uint8 tmpbuf[PGP_MAX_KEY + 2];
628 uint8 ver;
630 GETBYTE(src, ver);
631 GETBYTE(src, ctx->s2k_cipher_algo);
632 if (ver != 4)
634 px_debug("bad key pkt ver");
635 return PXE_PGP_CORRUPT_DATA;
639 * read S2K info
641 res = pgp_s2k_read(src, &ctx->s2k);
642 if (res < 0)
643 return res;
644 ctx->s2k_mode = ctx->s2k.mode;
645 ctx->s2k_count = s2k_decode_count(ctx->s2k.iter);
646 ctx->s2k_digest_algo = ctx->s2k.digest_algo;
649 * generate key from password
651 res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
652 ctx->sym_key, ctx->sym_key_len);
653 if (res < 0)
654 return res;
657 * do we have separate session key?
659 res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
660 if (res < 0)
661 return res;
663 if (res == 0)
666 * no, s2k key is session key
668 memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
669 ctx->sess_key_len = ctx->s2k.key_len;
670 ctx->cipher_algo = ctx->s2k_cipher_algo;
671 res = 0;
672 ctx->use_sess_key = 0;
674 else
677 * yes, decrypt it
679 if (res < 17 || res > PGP_MAX_KEY + 1)
681 px_debug("expect key, but bad data");
682 return PXE_PGP_CORRUPT_DATA;
684 ctx->use_sess_key = 1;
685 res = decrypt_key(ctx, p, res);
688 px_memset(tmpbuf, 0, sizeof(tmpbuf));
689 return res;
692 static int
693 copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
695 uint8 *data_end = data + len;
696 uint8 tmpbuf[1024];
697 uint8 *tmp_end = tmpbuf + sizeof(tmpbuf);
698 uint8 *p;
699 int res;
701 p = tmpbuf;
702 if (*got_cr)
704 if (*data != '\n')
705 *p++ = '\r';
706 *got_cr = 0;
708 while (data < data_end)
710 if (*data == '\r')
712 if (data + 1 < data_end)
714 if (*(data + 1) == '\n')
715 data++;
717 else
719 *got_cr = 1;
720 break;
723 *p++ = *data++;
724 if (p >= tmp_end)
726 res = mbuf_append(dst, tmpbuf, p - tmpbuf);
727 if (res < 0)
728 return res;
729 p = tmpbuf;
732 if (p - tmpbuf > 0)
734 res = mbuf_append(dst, tmpbuf, p - tmpbuf);
735 if (res < 0)
736 return res;
738 px_memset(tmpbuf, 0, sizeof(tmpbuf));
739 return 0;
742 static int
743 parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
745 int type;
746 int name_len;
747 int res;
748 uint8 *buf;
749 uint8 tmpbuf[4];
750 int got_cr = 0;
752 GETBYTE(pkt, type);
753 GETBYTE(pkt, name_len);
755 /* skip name */
756 while (name_len > 0)
758 res = pullf_read(pkt, name_len, &buf);
759 if (res < 0)
760 return res;
761 if (res == 0)
762 break;
763 name_len -= res;
765 if (name_len > 0)
767 px_debug("parse_literal_data: unexpected eof");
768 return PXE_PGP_CORRUPT_DATA;
771 /* skip date */
772 res = pullf_read_max(pkt, 4, &buf, tmpbuf);
773 if (res != 4)
775 px_debug("parse_literal_data: unexpected eof");
776 return PXE_PGP_CORRUPT_DATA;
778 px_memset(tmpbuf, 0, 4);
781 * If called from an SQL function that returns text, pgp_decrypt() rejects
782 * inputs not self-identifying as text.
784 if (ctx->text_mode)
785 if (type != 't' && type != 'u')
787 px_debug("parse_literal_data: data type=%c", type);
788 ctx->unexpected_binary = true;
791 ctx->unicode_mode = (type == 'u') ? 1 : 0;
793 /* read data */
794 while (1)
796 res = pullf_read(pkt, 32 * 1024, &buf);
797 if (res <= 0)
798 break;
800 if (ctx->text_mode && ctx->convert_crlf)
801 res = copy_crlf(dst, buf, res, &got_cr);
802 else
803 res = mbuf_append(dst, buf, res);
804 if (res < 0)
805 break;
807 if (res >= 0 && got_cr)
808 res = mbuf_append(dst, (const uint8 *) "\r", 1);
809 return res;
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);
816 static int
817 parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
819 int res;
820 uint8 type;
821 PullFilter *pf_decompr;
822 uint8 *discard_buf;
824 GETBYTE(pkt, type);
826 ctx->compress_algo = type;
827 switch (type)
829 case PGP_COMPR_NONE:
830 res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
831 break;
833 case PGP_COMPR_ZIP:
834 case PGP_COMPR_ZLIB:
835 res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
836 if (res >= 0)
838 res = process_data_packets(ctx, dst, pf_decompr,
839 NO_COMPR, NO_MDC);
840 pullf_free(pf_decompr);
842 break;
844 case PGP_COMPR_BZIP2:
845 px_debug("parse_compressed_data: bzip2 unsupported");
846 /* report error in pgp_decrypt() */
847 ctx->unsupported_compr = 1;
850 * Discard the compressed data, allowing it to first affect any
851 * MDC digest computation.
853 while (1)
855 res = pullf_read(pkt, 32 * 1024, &discard_buf);
856 if (res <= 0)
857 break;
860 break;
862 default:
863 px_debug("parse_compressed_data: unknown compr type");
864 res = PXE_PGP_CORRUPT_DATA;
867 return res;
870 static int
871 process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
872 int allow_compr, int need_mdc)
874 uint8 tag;
875 int len,
876 res;
877 int got_data = 0;
878 int got_mdc = 0;
879 PullFilter *pkt = NULL;
881 while (1)
883 res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
884 if (res <= 0)
885 break;
888 /* mdc packet should be last */
889 if (got_mdc)
891 px_debug("process_data_packets: data after mdc");
892 res = PXE_PGP_CORRUPT_DATA;
893 break;
897 * Context length inside SYMENCRYPTED_DATA_MDC packet needs special
898 * handling.
900 if (need_mdc && res == PKT_CONTEXT)
901 res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
902 else
903 res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
904 if (res < 0)
905 break;
907 switch (tag)
909 case PGP_PKT_LITERAL_DATA:
910 got_data = 1;
911 res = parse_literal_data(ctx, dst, pkt);
912 break;
913 case PGP_PKT_COMPRESSED_DATA:
914 if (allow_compr == 0)
916 px_debug("process_data_packets: unexpected compression");
917 res = PXE_PGP_CORRUPT_DATA;
919 else if (got_data)
922 * compr data must be alone
924 px_debug("process_data_packets: only one cmpr pkt allowed");
925 res = PXE_PGP_CORRUPT_DATA;
927 else
929 got_data = 1;
930 res = parse_compressed_data(ctx, dst, pkt);
932 break;
933 case PGP_PKT_MDC:
934 if (need_mdc == NO_MDC)
936 px_debug("process_data_packets: unexpected MDC");
937 res = PXE_PGP_CORRUPT_DATA;
938 break;
941 res = mdc_finish(ctx, pkt, len);
942 if (res >= 0)
943 got_mdc = 1;
944 break;
945 default:
946 px_debug("process_data_packets: unexpected pkt tag=%d", tag);
947 res = PXE_PGP_CORRUPT_DATA;
950 pullf_free(pkt);
951 pkt = NULL;
953 if (res < 0)
954 break;
957 if (pkt)
958 pullf_free(pkt);
960 if (res < 0)
961 return res;
963 if (!got_data)
965 px_debug("process_data_packets: no data");
966 res = PXE_PGP_CORRUPT_DATA;
968 if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
970 px_debug("process_data_packets: got no mdc");
971 res = PXE_PGP_CORRUPT_DATA;
973 return res;
976 static int
977 parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
979 int res;
980 PGP_CFB *cfb = NULL;
981 PullFilter *pf_decrypt = NULL;
982 PullFilter *pf_prefix = NULL;
984 res = pgp_cfb_create(&cfb, ctx->cipher_algo,
985 ctx->sess_key, ctx->sess_key_len, 1, NULL);
986 if (res < 0)
987 goto out;
989 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
990 if (res < 0)
991 goto out;
993 res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
994 if (res < 0)
995 goto out;
997 res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);
999 out:
1000 if (pf_prefix)
1001 pullf_free(pf_prefix);
1002 if (pf_decrypt)
1003 pullf_free(pf_decrypt);
1004 if (cfb)
1005 pgp_cfb_free(cfb);
1007 return res;
1010 static int
1011 parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
1013 int res;
1014 PGP_CFB *cfb = NULL;
1015 PullFilter *pf_decrypt = NULL;
1016 PullFilter *pf_prefix = NULL;
1017 PullFilter *pf_mdc = NULL;
1018 uint8 ver;
1020 GETBYTE(pkt, ver);
1021 if (ver != 1)
1023 px_debug("parse_symenc_mdc_data: pkt ver != 1");
1024 return PXE_PGP_CORRUPT_DATA;
1027 res = pgp_cfb_create(&cfb, ctx->cipher_algo,
1028 ctx->sess_key, ctx->sess_key_len, 0, NULL);
1029 if (res < 0)
1030 goto out;
1032 res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
1033 if (res < 0)
1034 goto out;
1036 res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
1037 if (res < 0)
1038 goto out;
1040 res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
1041 if (res < 0)
1042 goto out;
1044 res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);
1046 out:
1047 if (pf_prefix)
1048 pullf_free(pf_prefix);
1049 if (pf_mdc)
1050 pullf_free(pf_mdc);
1051 if (pf_decrypt)
1052 pullf_free(pf_decrypt);
1053 if (cfb)
1054 pgp_cfb_free(cfb);
1056 return res;
1060 * skip over packet contents
1063 pgp_skip_packet(PullFilter *pkt)
1065 int res = 1;
1066 uint8 *tmp;
1068 while (res > 0)
1069 res = pullf_read(pkt, 32 * 1024, &tmp);
1070 return res;
1074 * expect to be at packet end, any data is error
1077 pgp_expect_packet_end(PullFilter *pkt)
1079 int res;
1080 uint8 *tmp;
1082 res = pullf_read(pkt, 32 * 1024, &tmp);
1083 if (res > 0)
1085 px_debug("pgp_expect_packet_end: got data");
1086 return PXE_PGP_CORRUPT_DATA;
1088 return res;
1092 pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
1094 int res;
1095 PullFilter *src = NULL;
1096 PullFilter *pkt = NULL;
1097 uint8 tag;
1098 int len;
1099 int got_key = 0;
1100 int got_data = 0;
1102 res = pullf_create_mbuf_reader(&src, msrc);
1104 while (res >= 0)
1106 res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
1107 if (res <= 0)
1108 break;
1110 res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
1111 if (res < 0)
1112 break;
1114 res = PXE_PGP_CORRUPT_DATA;
1115 switch (tag)
1117 case PGP_PKT_MARKER:
1118 res = pgp_skip_packet(pkt);
1119 break;
1120 case PGP_PKT_PUBENCRYPTED_SESSKEY:
1121 /* fixme: skip those */
1122 res = pgp_parse_pubenc_sesskey(ctx, pkt);
1123 got_key = 1;
1124 break;
1125 case PGP_PKT_SYMENCRYPTED_SESSKEY:
1126 if (got_key)
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.
1133 px_debug("pgp_decrypt: using first of several keys");
1134 else
1136 got_key = 1;
1137 res = parse_symenc_sesskey(ctx, pkt);
1139 break;
1140 case PGP_PKT_SYMENCRYPTED_DATA:
1141 if (!got_key)
1142 px_debug("pgp_decrypt: have data but no key");
1143 else if (got_data)
1144 px_debug("pgp_decrypt: got second data packet");
1145 else
1147 got_data = 1;
1148 ctx->disable_mdc = 1;
1149 res = parse_symenc_data(ctx, pkt, mdst);
1151 break;
1152 case PGP_PKT_SYMENCRYPTED_DATA_MDC:
1153 if (!got_key)
1154 px_debug("pgp_decrypt: have data but no key");
1155 else if (got_data)
1156 px_debug("pgp_decrypt: several data pkts not supported");
1157 else
1159 got_data = 1;
1160 ctx->disable_mdc = 0;
1161 res = parse_symenc_mdc_data(ctx, pkt, mdst);
1163 break;
1164 default:
1165 px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
1167 pullf_free(pkt);
1168 pkt = NULL;
1171 if (pkt)
1172 pullf_free(pkt);
1174 if (src)
1175 pullf_free(src);
1177 if (res < 0)
1178 return res;
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.
1185 if (!got_data || ctx->corrupt_prefix)
1186 return PXE_PGP_CORRUPT_DATA;
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.
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.
1206 if (ctx->unsupported_compr)
1207 return PXE_PGP_UNSUPPORTED_COMPR;
1208 if (ctx->unexpected_binary)
1209 return PXE_PGP_NOT_TEXT;
1211 return res;