/*
 * pgp-decrypt.c
 *	  OpenPGP decrypt.
 *
 * Copyright (c) 2005 Marko Kreen
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *	  notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *	  notice, this list of conditions and the following disclaimer in the
 *	  documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED.	IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 * SUCH DAMAGE.
 *
 * contrib/pgcrypto/pgp-decrypt.c
 */

#include "postgres.h"

#include "px.h"
#include "mbuf.h"
#include "pgp.h"

#define NO_CTX_SIZE		0
#define ALLOW_CTX_SIZE	1
#define NO_COMPR		0
#define ALLOW_COMPR		1
#define NO_MDC			0
#define NEED_MDC		1

#define PKT_NORMAL 1
#define PKT_STREAM 2
#define PKT_CONTEXT 3

#define MAX_CHUNK (16*1024*1024)

static int
parse_new_len(PullFilter *src, int *len_p)
{
	uint8		b;
	int			len;
	int			pkttype = PKT_NORMAL;

	GETBYTE(src, b);
	if (b <= 191)
		len = b;
	else if (b >= 192 && b <= 223)
	{
		len = ((unsigned) (b) - 192) << 8;
		GETBYTE(src, b);
		len += 192 + b;
	}
	else if (b == 255)
	{
		GETBYTE(src, b);
		len = b;
		GETBYTE(src, b);
		len = (len << 8) | b;
		GETBYTE(src, b);
		len = (len << 8) | b;
		GETBYTE(src, b);
		len = (len << 8) | b;
	}
	else
	{
		len = 1 << (b & 0x1F);
		pkttype = PKT_STREAM;
	}

	if (len < 0 || len > MAX_CHUNK)
	{
		px_debug("parse_new_len: weird length");
		return PXE_PGP_CORRUPT_DATA;
	}

	*len_p = len;
	return pkttype;
}

static int
parse_old_len(PullFilter *src, int *len_p, int lentype)
{
	uint8		b;
	int			len;

	GETBYTE(src, b);
	len = b;

	if (lentype == 1)
	{
		GETBYTE(src, b);
		len = (len << 8) | b;
	}
	else if (lentype == 2)
	{
		GETBYTE(src, b);
		len = (len << 8) | b;
		GETBYTE(src, b);
		len = (len << 8) | b;
		GETBYTE(src, b);
		len = (len << 8) | b;
	}

	if (len < 0 || len > MAX_CHUNK)
	{
		px_debug("parse_old_len: weird length");
		return PXE_PGP_CORRUPT_DATA;
	}
	*len_p = len;
	return PKT_NORMAL;
}

/* returns pkttype or 0 on eof */
int
pgp_parse_pkt_hdr(PullFilter *src, uint8 *tag, int *len_p, int allow_ctx)
{
	int			lentype;
	int			res;
	uint8	   *p;

	/* EOF is normal here, thus we dont use GETBYTE */
	res = pullf_read(src, 1, &p);
	if (res < 0)
		return res;
	if (res == 0)
		return 0;

	if ((*p & 0x80) == 0)
	{
		px_debug("pgp_parse_pkt_hdr: not pkt hdr");
		return PXE_PGP_CORRUPT_DATA;
	}

	if (*p & 0x40)
	{
		*tag = *p & 0x3f;
		res = parse_new_len(src, len_p);
	}
	else
	{
		lentype = *p & 3;
		*tag = (*p >> 2) & 0x0F;
		if (lentype == 3)
			res = allow_ctx ? PKT_CONTEXT : PXE_PGP_CORRUPT_DATA;
		else
			res = parse_old_len(src, len_p, lentype);
	}
	return res;
}

/*
 * Packet reader
 */
struct PktData
{
	int			type;
	int			len;
};

static int
pktreader_pull(void *priv, PullFilter *src, int len,
			   uint8 **data_p, uint8 *buf, int buflen)
{
	int			res;
	struct PktData *pkt = priv;

	/* PKT_CONTEXT means: whatever there is */
	if (pkt->type == PKT_CONTEXT)
		return pullf_read(src, len, data_p);

	if (pkt->len == 0)
	{
		/* this was last chunk in stream */
		if (pkt->type == PKT_NORMAL)
			return 0;

		/* next chunk in stream */
		res = parse_new_len(src, &pkt->len);
		if (res < 0)
			return res;
		pkt->type = res;
	}

	if (len > pkt->len)
		len = pkt->len;

	res = pullf_read(src, len, data_p);
	if (res > 0)
		pkt->len -= res;

	return res;
}

static void
pktreader_free(void *priv)
{
	struct PktData *pkt = priv;

	memset(pkt, 0, sizeof(*pkt));
	px_free(pkt);
}

static struct PullFilterOps pktreader_filter = {
	NULL, pktreader_pull, pktreader_free
};

/* needs helper function to pass several parameters */
int
pgp_create_pkt_reader(PullFilter **pf_p, PullFilter *src, int len,
					  int pkttype, PGP_Context *ctx)
{
	int			res;
	struct PktData *pkt = px_alloc(sizeof(*pkt));

	pkt->type = pkttype;
	pkt->len = len;
	res = pullf_create(pf_p, &pktreader_filter, pkt, src);
	if (res < 0)
		px_free(pkt);
	return res;
}

/*
 * Prefix check filter
 */

static int
prefix_init(void **priv_p, void *arg, PullFilter *src)
{
	PGP_Context *ctx = arg;
	int			len;
	int			res;
	uint8	   *buf;
	uint8		tmpbuf[PGP_MAX_BLOCK + 2];

	len = pgp_get_cipher_block_size(ctx->cipher_algo);
	if (len > sizeof(tmpbuf))
		return PXE_BUG;

	res = pullf_read_max(src, len + 2, &buf, tmpbuf);
	if (res < 0)
		return res;
	if (res != len + 2)
	{
		px_debug("prefix_init: short read");
		memset(tmpbuf, 0, sizeof(tmpbuf));
		return PXE_PGP_CORRUPT_DATA;
	}

	if (buf[len - 2] != buf[len] || buf[len - 1] != buf[len + 1])
	{
		px_debug("prefix_init: corrupt prefix");

		/*
		 * The original purpose of the 2-byte check was to show user a
		 * friendly "wrong key" message. This made following possible:
		 *
		 * "An Attack on CFB Mode Encryption As Used By OpenPGP" by Serge
		 * Mister and Robert Zuccherato
		 *
		 * To avoid being 'oracle', we delay reporting, which basically means
		 * we prefer to run into corrupt packet header.
		 *
		 * We _could_ throw PXE_PGP_CORRUPT_DATA here, but there is
		 * possibility of attack via timing, so we don't.
		 */
		ctx->corrupt_prefix = 1;
	}
	memset(tmpbuf, 0, sizeof(tmpbuf));
	return 0;
}

static struct PullFilterOps prefix_filter = {
	prefix_init, NULL, NULL
};


/*
 * Decrypt filter
 */

static int
decrypt_init(void **priv_p, void *arg, PullFilter *src)
{
	PGP_CFB    *cfb = arg;

	*priv_p = cfb;

	/* we need to write somewhere, so ask for a buffer */
	return 4096;
}

static int
decrypt_read(void *priv, PullFilter *src, int len,
			 uint8 **data_p, uint8 *buf, int buflen)
{
	PGP_CFB    *cfb = priv;
	uint8	   *tmp;
	int			res;

	res = pullf_read(src, len, &tmp);
	if (res > 0)
	{
		pgp_cfb_decrypt(cfb, tmp, res, buf);
		*data_p = buf;
	}
	return res;
}

struct PullFilterOps pgp_decrypt_filter = {
	decrypt_init, decrypt_read, NULL
};


/*
 * MDC hasher filter
 */

static int
mdc_init(void **priv_p, void *arg, PullFilter *src)
{
	PGP_Context *ctx = arg;

	*priv_p = ctx;
	return pgp_load_digest(PGP_DIGEST_SHA1, &ctx->mdc_ctx);
}

static void
mdc_free(void *priv)
{
	PGP_Context *ctx = priv;

	if (ctx->use_mdcbuf_filter)
		return;
	px_md_free(ctx->mdc_ctx);
	ctx->mdc_ctx = NULL;
}

static int
mdc_finish(PGP_Context *ctx, PullFilter *src,
		   int len, uint8 **data_p)
{
	int			res;
	uint8		hash[20];
	uint8		tmpbuf[22];

	if (len + 1 > sizeof(tmpbuf))
		return PXE_BUG;

	/* read data */
	res = pullf_read_max(src, len + 1, data_p, tmpbuf);
	if (res < 0)
		return res;
	if (res == 0)
	{
		if (ctx->mdc_checked == 0)
		{
			px_debug("no mdc");
			return PXE_PGP_CORRUPT_DATA;
		}
		return 0;
	}

	/* safety check */
	if (ctx->in_mdc_pkt > 1)
	{
		px_debug("mdc_finish: several times here?");
		return PXE_PGP_CORRUPT_DATA;
	}
	ctx->in_mdc_pkt++;

	/* is the packet sane? */
	if (res != 20)
	{
		px_debug("mdc_finish: read failed, res=%d", res);
		return PXE_PGP_CORRUPT_DATA;
	}

	/*
	 * ok, we got the hash, now check
	 */
	px_md_finish(ctx->mdc_ctx, hash);
	res = memcmp(hash, *data_p, 20);
	memset(hash, 0, 20);
	memset(tmpbuf, 0, sizeof(tmpbuf));
	if (res != 0)
	{
		px_debug("mdc_finish: mdc failed");
		return PXE_PGP_CORRUPT_DATA;
	}
	ctx->mdc_checked = 1;
	return len;
}

static int
mdc_read(void *priv, PullFilter *src, int len,
		 uint8 **data_p, uint8 *buf, int buflen)
{
	int			res;
	PGP_Context *ctx = priv;

	/* skip this filter? */
	if (ctx->use_mdcbuf_filter)
		return pullf_read(src, len, data_p);

	if (ctx->in_mdc_pkt)
		return mdc_finish(ctx, src, len, data_p);

	res = pullf_read(src, len, data_p);
	if (res < 0)
		return res;
	if (res == 0)
	{
		px_debug("mdc_read: unexpected eof");
		return PXE_PGP_CORRUPT_DATA;
	}
	px_md_update(ctx->mdc_ctx, *data_p, res);

	return res;
}

static struct PullFilterOps mdc_filter = {
	mdc_init, mdc_read, mdc_free
};


/*
 * Combined Pkt reader and MDC hasher.
 *
 * For the case of SYMENCRYPTED_MDC packet, where
 * the data part has 'context length', which means
 * that data packet ends 22 bytes before end of parent
 * packet, which is silly.
 */
#define MDCBUF_LEN 8192
struct MDCBufData
{
	PGP_Context *ctx;
	int			eof;
	int			buflen;
	int			avail;
	uint8	   *pos;
	int			mdc_avail;
	uint8		mdc_buf[22];
	uint8		buf[MDCBUF_LEN];
};

static int
mdcbuf_init(void **priv_p, void *arg, PullFilter *src)
{
	PGP_Context *ctx = arg;
	struct MDCBufData *st;

	st = px_alloc(sizeof(*st));
	memset(st, 0, sizeof(*st));
	st->buflen = sizeof(st->buf);
	st->ctx = ctx;
	*priv_p = st;

	/* take over the work of mdc_filter */
	ctx->use_mdcbuf_filter = 1;

	return 0;
}

static int
mdcbuf_finish(struct MDCBufData * st)
{
	uint8		hash[20];
	int			res;

	st->eof = 1;

	if (st->mdc_buf[0] != 0xD3 || st->mdc_buf[1] != 0x14)
	{
		px_debug("mdcbuf_finish: bad MDC pkt hdr");
		return PXE_PGP_CORRUPT_DATA;
	}
	px_md_update(st->ctx->mdc_ctx, st->mdc_buf, 2);
	px_md_finish(st->ctx->mdc_ctx, hash);
	res = memcmp(hash, st->mdc_buf + 2, 20);
	memset(hash, 0, 20);
	if (res)
	{
		px_debug("mdcbuf_finish: MDC does not match");
		res = PXE_PGP_CORRUPT_DATA;
	}
	return res;
}

static void
mdcbuf_load_data(struct MDCBufData * st, uint8 *src, int len)
{
	uint8	   *dst = st->pos + st->avail;

	memcpy(dst, src, len);
	px_md_update(st->ctx->mdc_ctx, src, len);
	st->avail += len;
}

static void
mdcbuf_load_mdc(struct MDCBufData * st, uint8 *src, int len)
{
	memmove(st->mdc_buf + st->mdc_avail, src, len);
	st->mdc_avail += len;
}

static int
mdcbuf_refill(struct MDCBufData * st, PullFilter *src)
{
	uint8	   *data;
	int			res;
	int			need;

	/* put avail data in start */
	if (st->avail > 0 && st->pos != st->buf)
		memmove(st->buf, st->pos, st->avail);
	st->pos = st->buf;

	/* read new data */
	need = st->buflen + 22 - st->avail - st->mdc_avail;
	res = pullf_read(src, need, &data);
	if (res < 0)
		return res;
	if (res == 0)
		return mdcbuf_finish(st);

	/* add to buffer */
	if (res >= 22)
	{
		mdcbuf_load_data(st, st->mdc_buf, st->mdc_avail);
		st->mdc_avail = 0;

		mdcbuf_load_data(st, data, res - 22);
		mdcbuf_load_mdc(st, data + res - 22, 22);
	}
	else
	{
		int			canmove = st->mdc_avail + res - 22;

		if (canmove > 0)
		{
			mdcbuf_load_data(st, st->mdc_buf, canmove);
			st->mdc_avail -= canmove;
			memmove(st->mdc_buf, st->mdc_buf + canmove, st->mdc_avail);
		}
		mdcbuf_load_mdc(st, data, res);
	}
	return 0;
}

static int
mdcbuf_read(void *priv, PullFilter *src, int len,
			uint8 **data_p, uint8 *buf, int buflen)
{
	struct MDCBufData *st = priv;
	int			res;

	if (!st->eof && len > st->avail)
	{
		res = mdcbuf_refill(st, src);
		if (res < 0)
			return res;
	}

	if (len > st->avail)
		len = st->avail;

	*data_p = st->pos;
	st->pos += len;
	st->avail -= len;
	return len;
}

static void
mdcbuf_free(void *priv)
{
	struct MDCBufData *st = priv;

	px_md_free(st->ctx->mdc_ctx);
	st->ctx->mdc_ctx = NULL;
	memset(st, 0, sizeof(*st));
	px_free(st);
}

static struct PullFilterOps mdcbuf_filter = {
	mdcbuf_init, mdcbuf_read, mdcbuf_free
};


/*
 * Decrypt separate session key
 */
static int
decrypt_key(PGP_Context *ctx, const uint8 *src, int len)
{
	int			res;
	uint8		algo;
	PGP_CFB    *cfb;

	res = pgp_cfb_create(&cfb, ctx->s2k_cipher_algo,
						 ctx->s2k.key, ctx->s2k.key_len, 0, NULL);
	if (res < 0)
		return res;

	pgp_cfb_decrypt(cfb, src, 1, &algo);
	src++;
	len--;

	pgp_cfb_decrypt(cfb, src, len, ctx->sess_key);
	pgp_cfb_free(cfb);
	ctx->sess_key_len = len;
	ctx->cipher_algo = algo;

	if (pgp_get_cipher_key_size(algo) != len)
	{
		px_debug("sesskey bad len: algo=%d, expected=%d, got=%d",
				 algo, pgp_get_cipher_key_size(algo), len);
		return PXE_PGP_CORRUPT_DATA;
	}
	return 0;
}

/*
 * Handle key packet
 */
static int
parse_symenc_sesskey(PGP_Context *ctx, PullFilter *src)
{
	uint8	   *p;
	int			res;
	uint8		tmpbuf[PGP_MAX_KEY + 2];
	uint8		ver;

	GETBYTE(src, ver);
	GETBYTE(src, ctx->s2k_cipher_algo);
	if (ver != 4)
	{
		px_debug("bad key pkt ver");
		return PXE_PGP_CORRUPT_DATA;
	}

	/*
	 * read S2K info
	 */
	res = pgp_s2k_read(src, &ctx->s2k);
	if (res < 0)
		return res;
	ctx->s2k_mode = ctx->s2k.mode;
	ctx->s2k_digest_algo = ctx->s2k.digest_algo;

	/*
	 * generate key from password
	 */
	res = pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
						  ctx->sym_key, ctx->sym_key_len);
	if (res < 0)
		return res;

	/*
	 * do we have separate session key?
	 */
	res = pullf_read_max(src, PGP_MAX_KEY + 2, &p, tmpbuf);
	if (res < 0)
		return res;

	if (res == 0)
	{
		/*
		 * no, s2k key is session key
		 */
		memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
		ctx->sess_key_len = ctx->s2k.key_len;
		ctx->cipher_algo = ctx->s2k_cipher_algo;
		res = 0;
		ctx->use_sess_key = 0;
	}
	else
	{
		/*
		 * yes, decrypt it
		 */
		if (res < 17 || res > PGP_MAX_KEY + 1)
		{
			px_debug("expect key, but bad data");
			return PXE_PGP_CORRUPT_DATA;
		}
		ctx->use_sess_key = 1;
		res = decrypt_key(ctx, p, res);
	}

	memset(tmpbuf, 0, sizeof(tmpbuf));
	return res;
}

static int
copy_crlf(MBuf *dst, uint8 *data, int len, int *got_cr)
{
	uint8	   *data_end = data + len;
	uint8		tmpbuf[1024];
	uint8	   *tmp_end = tmpbuf + sizeof(tmpbuf);
	uint8	   *p;
	int			res;

	p = tmpbuf;
	if (*got_cr)
	{
		if (*data != '\n')
			*p++ = '\r';
		*got_cr = 0;
	}
	while (data < data_end)
	{
		if (*data == '\r')
		{
			if (data + 1 < data_end)
			{
				if (*(data + 1) == '\n')
					data++;
			}
			else
			{
				*got_cr = 1;
				break;
			}
		}
		*p++ = *data++;
		if (p >= tmp_end)
		{
			res = mbuf_append(dst, tmpbuf, p - tmpbuf);
			if (res < 0)
				return res;
			p = tmpbuf;
		}
	}
	if (p - tmpbuf > 0)
	{
		res = mbuf_append(dst, tmpbuf, p - tmpbuf);
		if (res < 0)
			return res;
	}
	return 0;
}

static int
parse_literal_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
{
	int			type;
	int			name_len;
	int			res;
	uint8	   *buf;
	uint8		tmpbuf[4];
	int			got_cr = 0;

	GETBYTE(pkt, type);
	GETBYTE(pkt, name_len);

	/* skip name */
	while (name_len > 0)
	{
		res = pullf_read(pkt, name_len, &buf);
		if (res < 0)
			return res;
		if (res == 0)
			break;
		name_len -= res;
	}
	if (name_len > 0)
	{
		px_debug("parse_literal_data: unexpected eof");
		return PXE_PGP_CORRUPT_DATA;
	}

	/* skip date */
	res = pullf_read_max(pkt, 4, &buf, tmpbuf);
	if (res != 4)
	{
		px_debug("parse_literal_data: unexpected eof");
		return PXE_PGP_CORRUPT_DATA;
	}
	memset(tmpbuf, 0, 4);

	/* check if text */
	if (ctx->text_mode)
		if (type != 't' && type != 'u')
		{
			px_debug("parse_literal_data: data type=%c", type);
			return PXE_PGP_NOT_TEXT;
		}

	ctx->unicode_mode = (type == 'u') ? 1 : 0;

	/* read data */
	while (1)
	{
		res = pullf_read(pkt, 32 * 1024, &buf);
		if (res <= 0)
			break;

		if (ctx->text_mode && ctx->convert_crlf)
			res = copy_crlf(dst, buf, res, &got_cr);
		else
			res = mbuf_append(dst, buf, res);
		if (res < 0)
			break;
	}
	if (res >= 0 && got_cr)
		res = mbuf_append(dst, (const uint8 *) "\r", 1);
	return res;
}

/* process_data_packets and parse_compressed_data call each other */
static int process_data_packets(PGP_Context *ctx, MBuf *dst,
					 PullFilter *src, int allow_compr, int need_mdc);

static int
parse_compressed_data(PGP_Context *ctx, MBuf *dst, PullFilter *pkt)
{
	int			res;
	uint8		type;
	PullFilter *pf_decompr;

	GETBYTE(pkt, type);

	ctx->compress_algo = type;
	switch (type)
	{
		case PGP_COMPR_NONE:
			res = process_data_packets(ctx, dst, pkt, NO_COMPR, NO_MDC);
			break;

		case PGP_COMPR_ZIP:
		case PGP_COMPR_ZLIB:
			res = pgp_decompress_filter(&pf_decompr, ctx, pkt);
			if (res >= 0)
			{
				res = process_data_packets(ctx, dst, pf_decompr,
										   NO_COMPR, NO_MDC);
				pullf_free(pf_decompr);
			}
			break;

		case PGP_COMPR_BZIP2:
			px_debug("parse_compressed_data: bzip2 unsupported");
			res = PXE_PGP_UNSUPPORTED_COMPR;
			break;

		default:
			px_debug("parse_compressed_data: unknown compr type");
			res = PXE_PGP_CORRUPT_DATA;
	}

	return res;
}

static int
process_data_packets(PGP_Context *ctx, MBuf *dst, PullFilter *src,
					 int allow_compr, int need_mdc)
{
	uint8		tag;
	int			len,
				res;
	int			got_data = 0;
	int			got_mdc = 0;
	PullFilter *pkt = NULL;
	uint8	   *tmp;

	while (1)
	{
		res = pgp_parse_pkt_hdr(src, &tag, &len, ALLOW_CTX_SIZE);
		if (res <= 0)
			break;


		/* mdc packet should be last */
		if (got_mdc)
		{
			px_debug("process_data_packets: data after mdc");
			res = PXE_PGP_CORRUPT_DATA;
			break;
		}

		/* context length inside SYMENC_MDC needs special handling */
		if (need_mdc && res == PKT_CONTEXT)
			res = pullf_create(&pkt, &mdcbuf_filter, ctx, src);
		else
			res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
		if (res < 0)
			break;

		switch (tag)
		{
			case PGP_PKT_LITERAL_DATA:
				got_data = 1;
				res = parse_literal_data(ctx, dst, pkt);
				break;
			case PGP_PKT_COMPRESSED_DATA:
				if (allow_compr == 0)
				{
					px_debug("process_data_packets: unexpected compression");
					res = PXE_PGP_CORRUPT_DATA;
				}
				else if (got_data)
				{
					/*
					 * compr data must be alone
					 */
					px_debug("process_data_packets: only one cmpr pkt allowed");
					res = PXE_PGP_CORRUPT_DATA;
				}
				else
				{
					got_data = 1;
					res = parse_compressed_data(ctx, dst, pkt);
				}
				break;
			case PGP_PKT_MDC:
				if (need_mdc == NO_MDC)
				{
					px_debug("process_data_packets: unexpected MDC");
					res = PXE_PGP_CORRUPT_DATA;
					break;
				}

				/* notify mdc_filter */
				ctx->in_mdc_pkt = 1;

				res = pullf_read(pkt, 8192, &tmp);
				if (res > 0)
					got_mdc = 1;
				break;
			default:
				px_debug("process_data_packets: unexpected pkt tag=%d", tag);
				res = PXE_PGP_CORRUPT_DATA;
		}

		pullf_free(pkt);
		pkt = NULL;

		if (res < 0)
			break;
	}

	if (pkt)
		pullf_free(pkt);

	if (res < 0)
		return res;

	if (!got_data)
	{
		px_debug("process_data_packets: no data");
		res = PXE_PGP_CORRUPT_DATA;
	}
	if (need_mdc && !got_mdc && !ctx->use_mdcbuf_filter)
	{
		px_debug("process_data_packets: got no mdc");
		res = PXE_PGP_CORRUPT_DATA;
	}
	return res;
}

static int
parse_symenc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
{
	int			res;
	PGP_CFB    *cfb = NULL;
	PullFilter *pf_decrypt = NULL;
	PullFilter *pf_prefix = NULL;

	res = pgp_cfb_create(&cfb, ctx->cipher_algo,
						 ctx->sess_key, ctx->sess_key_len, 1, NULL);
	if (res < 0)
		goto out;

	res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
	if (res < 0)
		goto out;

	res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_decrypt);
	if (res < 0)
		goto out;

	res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NO_MDC);

out:
	if (pf_prefix)
		pullf_free(pf_prefix);
	if (pf_decrypt)
		pullf_free(pf_decrypt);
	if (cfb)
		pgp_cfb_free(cfb);

	return res;
}

static int
parse_symenc_mdc_data(PGP_Context *ctx, PullFilter *pkt, MBuf *dst)
{
	int			res;
	PGP_CFB    *cfb = NULL;
	PullFilter *pf_decrypt = NULL;
	PullFilter *pf_prefix = NULL;
	PullFilter *pf_mdc = NULL;
	uint8		ver;

	GETBYTE(pkt, ver);
	if (ver != 1)
	{
		px_debug("parse_symenc_mdc_data: pkt ver != 1");
		return PXE_PGP_CORRUPT_DATA;
	}

	res = pgp_cfb_create(&cfb, ctx->cipher_algo,
						 ctx->sess_key, ctx->sess_key_len, 0, NULL);
	if (res < 0)
		goto out;

	res = pullf_create(&pf_decrypt, &pgp_decrypt_filter, cfb, pkt);
	if (res < 0)
		goto out;

	res = pullf_create(&pf_mdc, &mdc_filter, ctx, pf_decrypt);
	if (res < 0)
		goto out;

	res = pullf_create(&pf_prefix, &prefix_filter, ctx, pf_mdc);
	if (res < 0)
		goto out;

	res = process_data_packets(ctx, dst, pf_prefix, ALLOW_COMPR, NEED_MDC);

out:
	if (pf_prefix)
		pullf_free(pf_prefix);
	if (pf_mdc)
		pullf_free(pf_mdc);
	if (pf_decrypt)
		pullf_free(pf_decrypt);
	if (cfb)
		pgp_cfb_free(cfb);

	return res;
}

/*
 * skip over packet contents
 */
int
pgp_skip_packet(PullFilter *pkt)
{
	int			res = 1;
	uint8	   *tmp;

	while (res > 0)
		res = pullf_read(pkt, 32 * 1024, &tmp);
	return res < 0 ? res : 0;
}

/*
 * expect to be at packet end, any data is error
 */
int
pgp_expect_packet_end(PullFilter *pkt)
{
	int			res = 1;
	uint8	   *tmp;

	while (res > 0)
	{
		res = pullf_read(pkt, 32 * 1024, &tmp);
		if (res > 0)
		{
			px_debug("pgp_expect_packet_end: got data");
			return PXE_PGP_CORRUPT_DATA;
		}
	}
	return res < 0 ? res : 0;
}

int
pgp_decrypt(PGP_Context *ctx, MBuf *msrc, MBuf *mdst)
{
	int			res;
	PullFilter *src = NULL;
	PullFilter *pkt = NULL;
	uint8		tag;
	int			len;
	int			got_key = 0;
	int			got_data = 0;

	res = pullf_create_mbuf_reader(&src, msrc);

	while (res >= 0)
	{
		res = pgp_parse_pkt_hdr(src, &tag, &len, NO_CTX_SIZE);
		if (res <= 0)
			break;

		res = pgp_create_pkt_reader(&pkt, src, len, res, ctx);
		if (res < 0)
			break;

		res = PXE_PGP_CORRUPT_DATA;
		switch (tag)
		{
			case PGP_PKT_MARKER:
				res = pgp_skip_packet(pkt);
				break;
			case PGP_PKT_PUBENCRYPTED_SESSKEY:
				/* fixme: skip those */
				res = pgp_parse_pubenc_sesskey(ctx, pkt);
				got_key = 1;
				break;
			case PGP_PKT_SYMENCRYPTED_SESSKEY:
				if (got_key)

					/*
					 * Theoretically, there could be several keys, both public
					 * and symmetric, all of which encrypt same session key.
					 * Decrypt should try with each one, before failing.
					 */
					px_debug("pgp_decrypt: using first of several keys");
				else
				{
					got_key = 1;
					res = parse_symenc_sesskey(ctx, pkt);
				}
				break;
			case PGP_PKT_SYMENCRYPTED_DATA:
				if (!got_key)
					px_debug("pgp_decrypt: have data but no key");
				else if (got_data)
					px_debug("pgp_decrypt: got second data packet");
				else
				{
					got_data = 1;
					ctx->disable_mdc = 1;
					res = parse_symenc_data(ctx, pkt, mdst);
				}
				break;
			case PGP_PKT_SYMENCRYPTED_DATA_MDC:
				if (!got_key)
					px_debug("pgp_decrypt: have data but no key");
				else if (got_data)
					px_debug("pgp_decrypt: several data pkts not supported");
				else
				{
					got_data = 1;
					ctx->disable_mdc = 0;
					res = parse_symenc_mdc_data(ctx, pkt, mdst);
				}
				break;
			default:
				px_debug("pgp_decrypt: unknown tag: 0x%02x", tag);
		}
		pullf_free(pkt);
		pkt = NULL;
	}

	if (pkt)
		pullf_free(pkt);

	if (src)
		pullf_free(src);

	if (res < 0)
		return res;

	if (!got_data || ctx->corrupt_prefix)
		res = PXE_PGP_CORRUPT_DATA;

	return res;
}
