/*
 * pgp-encrypt.c
 *	  OpenPGP encrypt.
 *
 * 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-encrypt.c
 */

#include "postgres.h"

#include <time.h>

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


#define MDC_DIGEST_LEN 20
#define STREAM_ID 0xE0
#define STREAM_BLOCK_SHIFT	14

static uint8 *
render_newlen(uint8 *h, int len)
{
	if (len <= 191)
	{
		*h++ = len & 255;
	}
	else if (len > 191 && len <= 8383)
	{
		*h++ = ((len - 192) >> 8) + 192;
		*h++ = (len - 192) & 255;
	}
	else
	{
		*h++ = 255;
		*h++ = (len >> 24) & 255;
		*h++ = (len >> 16) & 255;
		*h++ = (len >> 8) & 255;
		*h++ = len & 255;
	}
	return h;
}

static int
write_tag_only(PushFilter *dst, int tag)
{
	uint8		hdr = 0xC0 | tag;

	return pushf_write(dst, &hdr, 1);
}

static int
write_normal_header(PushFilter *dst, int tag, int len)
{
	uint8		hdr[8];
	uint8	   *h = hdr;

	*h++ = 0xC0 | tag;
	h = render_newlen(h, len);
	return pushf_write(dst, hdr, h - hdr);
}


/*
 * MAC writer
 */

static int
mdc_init(PushFilter *dst, void *init_arg, void **priv_p)
{
	int			res;
	PX_MD	   *md;

	res = pgp_load_digest(PGP_DIGEST_SHA1, &md);
	if (res < 0)
		return res;

	*priv_p = md;
	return 0;
}

static int
mdc_write(PushFilter *dst, void *priv, const uint8 *data, int len)
{
	PX_MD	   *md = priv;

	px_md_update(md, data, len);
	return pushf_write(dst, data, len);
}

static int
mdc_flush(PushFilter *dst, void *priv)
{
	int			res;
	uint8		pkt[2 + MDC_DIGEST_LEN];
	PX_MD	   *md = priv;

	/*
	 * create mdc pkt
	 */
	pkt[0] = 0xD3;
	pkt[1] = 0x14;				/* MDC_DIGEST_LEN */
	px_md_update(md, pkt, 2);
	px_md_finish(md, pkt + 2);

	res = pushf_write(dst, pkt, 2 + MDC_DIGEST_LEN);
	memset(pkt, 0, 2 + MDC_DIGEST_LEN);
	return res;
}

static void
mdc_free(void *priv)
{
	PX_MD	   *md = priv;

	px_md_free(md);
}

static const PushFilterOps mdc_filter = {
	mdc_init, mdc_write, mdc_flush, mdc_free
};


/*
 * Encrypted pkt writer
 */
#define ENCBUF 8192
struct EncStat
{
	PGP_CFB    *ciph;
	uint8		buf[ENCBUF];
};

static int
encrypt_init(PushFilter *next, void *init_arg, void **priv_p)
{
	struct EncStat *st;
	PGP_Context *ctx = init_arg;
	PGP_CFB    *ciph;
	int			resync = 1;
	int			res;

	/* should we use newer packet format? */
	if (ctx->disable_mdc == 0)
	{
		uint8		ver = 1;

		resync = 0;
		res = pushf_write(next, &ver, 1);
		if (res < 0)
			return res;
	}
	res = pgp_cfb_create(&ciph, ctx->cipher_algo,
						 ctx->sess_key, ctx->sess_key_len, resync, NULL);
	if (res < 0)
		return res;

	st = px_alloc(sizeof(*st));
	memset(st, 0, sizeof(*st));
	st->ciph = ciph;

	*priv_p = st;
	return ENCBUF;
}

static int
encrypt_process(PushFilter *next, void *priv, const uint8 *data, int len)
{
	int			res;
	struct EncStat *st = priv;
	int			avail = len;

	while (avail > 0)
	{
		int			tmplen = avail > ENCBUF ? ENCBUF : avail;

		res = pgp_cfb_encrypt(st->ciph, data, tmplen, st->buf);
		if (res < 0)
			return res;

		res = pushf_write(next, st->buf, tmplen);
		if (res < 0)
			return res;

		data += tmplen;
		avail -= tmplen;
	}
	return 0;
}

static void
encrypt_free(void *priv)
{
	struct EncStat *st = priv;

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

static const PushFilterOps encrypt_filter = {
	encrypt_init, encrypt_process, NULL, encrypt_free
};

/*
 * Write Streamable pkts
 */

struct PktStreamStat
{
	int			final_done;
	int			pkt_block;
};

static int
pkt_stream_init(PushFilter *next, void *init_arg, void **priv_p)
{
	struct PktStreamStat *st;

	st = px_alloc(sizeof(*st));
	st->final_done = 0;
	st->pkt_block = 1 << STREAM_BLOCK_SHIFT;
	*priv_p = st;

	return st->pkt_block;
}

static int
pkt_stream_process(PushFilter *next, void *priv, const uint8 *data, int len)
{
	int			res;
	uint8		hdr[8];
	uint8	   *h = hdr;
	struct PktStreamStat *st = priv;

	if (st->final_done)
		return PXE_BUG;

	if (len == st->pkt_block)
		*h++ = STREAM_ID | STREAM_BLOCK_SHIFT;
	else
	{
		h = render_newlen(h, len);
		st->final_done = 1;
	}

	res = pushf_write(next, hdr, h - hdr);
	if (res < 0)
		return res;

	return pushf_write(next, data, len);
}

static int
pkt_stream_flush(PushFilter *next, void *priv)
{
	int			res;
	uint8		hdr[8];
	uint8	   *h = hdr;
	struct PktStreamStat *st = priv;

	/* stream MUST end with normal packet. */
	if (!st->final_done)
	{
		h = render_newlen(h, 0);
		res = pushf_write(next, hdr, h - hdr);
		if (res < 0)
			return res;
		st->final_done = 1;
	}
	return 0;
}

static void
pkt_stream_free(void *priv)
{
	struct PktStreamStat *st = priv;

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

static const PushFilterOps pkt_stream_filter = {
	pkt_stream_init, pkt_stream_process, pkt_stream_flush, pkt_stream_free
};

int
pgp_create_pkt_writer(PushFilter *dst, int tag, PushFilter **res_p)
{
	int			res;

	res = write_tag_only(dst, tag);
	if (res < 0)
		return res;

	return pushf_create(res_p, &pkt_stream_filter, NULL, dst);
}

/*
 * Text conversion filter
 */

static int
crlf_process(PushFilter *dst, void *priv, const uint8 *data, int len)
{
	const uint8 *data_end = data + len;
	const uint8 *p2,
			   *p1 = data;
	int			line_len;
	static const uint8 crlf[] = {'\r', '\n'};
	int			res = 0;

	while (p1 < data_end)
	{
		p2 = memchr(p1, '\n', data_end - p1);
		if (p2 == NULL)
			p2 = data_end;

		line_len = p2 - p1;

		/* write data */
		res = 0;
		if (line_len > 0)
		{
			res = pushf_write(dst, p1, line_len);
			if (res < 0)
				break;
			p1 += line_len;
		}

		/* write crlf */
		while (p1 < data_end && *p1 == '\n')
		{
			res = pushf_write(dst, crlf, 2);
			if (res < 0)
				break;
			p1++;
		}
	}
	return res;
}

static const PushFilterOps crlf_filter = {
	NULL, crlf_process, NULL, NULL
};

/*
 * Initialize literal data packet
 */
static int
init_litdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
{
	int			res;
	int			hdrlen;
	uint8		hdr[6];
	uint32		t;
	PushFilter *pkt;
	int			type;

	/*
	 * Create header
	 */

	if (ctx->text_mode)
		type = ctx->unicode_mode ? 'u' : 't';
	else
		type = 'b';

	/*
	 * Store the creation time into packet. The goal is to have as few known
	 * bytes as possible.
	 */
	t = (uint32) time(NULL);

	hdr[0] = type;
	hdr[1] = 0;
	hdr[2] = (t >> 24) & 255;
	hdr[3] = (t >> 16) & 255;
	hdr[4] = (t >> 8) & 255;
	hdr[5] = t & 255;
	hdrlen = 6;

	res = write_tag_only(dst, PGP_PKT_LITERAL_DATA);
	if (res < 0)
		return res;

	res = pushf_create(&pkt, &pkt_stream_filter, ctx, dst);
	if (res < 0)
		return res;

	res = pushf_write(pkt, hdr, hdrlen);
	if (res < 0)
	{
		pushf_free(pkt);
		return res;
	}

	*pf_res = pkt;
	return 0;
}

/*
 * Initialize compression filter
 */
static int
init_compress(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
{
	int			res;
	uint8		type = ctx->compress_algo;
	PushFilter *pkt;

	res = write_tag_only(dst, PGP_PKT_COMPRESSED_DATA);
	if (res < 0)
		return res;

	res = pushf_create(&pkt, &pkt_stream_filter, ctx, dst);
	if (res < 0)
		return res;

	res = pushf_write(pkt, &type, 1);
	if (res >= 0)
		res = pgp_compress_filter(pf_res, ctx, pkt);

	if (res < 0)
		pushf_free(pkt);

	return res;
}

/*
 * Initialize encdata packet
 */
static int
init_encdata_packet(PushFilter **pf_res, PGP_Context *ctx, PushFilter *dst)
{
	int			res;
	int			tag;

	if (ctx->disable_mdc)
		tag = PGP_PKT_SYMENCRYPTED_DATA;
	else
		tag = PGP_PKT_SYMENCRYPTED_DATA_MDC;

	res = write_tag_only(dst, tag);
	if (res < 0)
		return res;

	return pushf_create(pf_res, &pkt_stream_filter, ctx, dst);
}

/*
 * write prefix
 */
static int
write_prefix(PGP_Context *ctx, PushFilter *dst)
{
	uint8		prefix[PGP_MAX_BLOCK + 2];
	int			res,
				bs;

	bs = pgp_get_cipher_block_size(ctx->cipher_algo);
	res = px_get_random_bytes(prefix, bs);
	if (res < 0)
		return res;

	prefix[bs + 0] = prefix[bs - 2];
	prefix[bs + 1] = prefix[bs - 1];

	res = pushf_write(dst, prefix, bs + 2);
	memset(prefix, 0, bs + 2);
	return res < 0 ? res : 0;
}

/*
 * write symmetrically encrypted session key packet
 */

static int
symencrypt_sesskey(PGP_Context *ctx, uint8 *dst)
{
	int			res;
	PGP_CFB    *cfb;
	uint8		algo = ctx->cipher_algo;

	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_encrypt(cfb, &algo, 1, dst);
	pgp_cfb_encrypt(cfb, ctx->sess_key, ctx->sess_key_len, dst + 1);

	pgp_cfb_free(cfb);
	return ctx->sess_key_len + 1;
}

/* 5.3: Symmetric-Key Encrypted Session-Key */
static int
write_symenc_sesskey(PGP_Context *ctx, PushFilter *dst)
{
	uint8		pkt[256];
	int			pktlen;
	int			res;
	uint8	   *p = pkt;

	*p++ = 4;					/* 5.3 - version number  */
	*p++ = ctx->s2k_cipher_algo;

	*p++ = ctx->s2k.mode;
	*p++ = ctx->s2k.digest_algo;
	if (ctx->s2k.mode > 0)
	{
		memcpy(p, ctx->s2k.salt, 8);
		p += 8;
	}
	if (ctx->s2k.mode == 3)
		*p++ = ctx->s2k.iter;

	if (ctx->use_sess_key)
	{
		res = symencrypt_sesskey(ctx, p);
		if (res < 0)
			return res;
		p += res;
	}

	pktlen = p - pkt;
	res = write_normal_header(dst, PGP_PKT_SYMENCRYPTED_SESSKEY, pktlen);
	if (res >= 0)
		res = pushf_write(dst, pkt, pktlen);

	memset(pkt, 0, pktlen);
	return res;
}

/*
 * key setup
 */
static int
init_s2k_key(PGP_Context *ctx)
{
	int			res;

	if (ctx->s2k_cipher_algo < 0)
		ctx->s2k_cipher_algo = ctx->cipher_algo;

	res = pgp_s2k_fill(&ctx->s2k, ctx->s2k_mode, ctx->s2k_digest_algo);
	if (res < 0)
		return res;

	return pgp_s2k_process(&ctx->s2k, ctx->s2k_cipher_algo,
						   ctx->sym_key, ctx->sym_key_len);
}

static int
init_sess_key(PGP_Context *ctx)
{
	int			res;

	if (ctx->use_sess_key || ctx->pub_key)
	{
		ctx->sess_key_len = pgp_get_cipher_key_size(ctx->cipher_algo);
		res = px_get_random_bytes(ctx->sess_key, ctx->sess_key_len);
		if (res < 0)
			return res;
	}
	else
	{
		ctx->sess_key_len = ctx->s2k.key_len;
		memcpy(ctx->sess_key, ctx->s2k.key, ctx->s2k.key_len);
	}

	return 0;
}

/*
 * combine
 */
int
pgp_encrypt(PGP_Context *ctx, MBuf *src, MBuf *dst)
{
	int			res;
	int			len;
	uint8	   *buf;
	PushFilter *pf,
			   *pf_tmp;

	/*
	 * do we have any key
	 */
	if (!ctx->sym_key && !ctx->pub_key)
		return PXE_ARGUMENT_ERROR;

	/* MBuf writer */
	res = pushf_create_mbuf_writer(&pf, dst);
	if (res < 0)
		goto out;

	/*
	 * initialize symkey
	 */
	if (ctx->sym_key)
	{
		res = init_s2k_key(ctx);
		if (res < 0)
			goto out;
	}

	res = init_sess_key(ctx);
	if (res < 0)
		goto out;

	/*
	 * write keypkt
	 */
	if (ctx->pub_key)
		res = pgp_write_pubenc_sesskey(ctx, pf);
	else
		res = write_symenc_sesskey(ctx, pf);
	if (res < 0)
		goto out;

	/* encrypted data pkt */
	res = init_encdata_packet(&pf_tmp, ctx, pf);
	if (res < 0)
		goto out;
	pf = pf_tmp;

	/* encrypter */
	res = pushf_create(&pf_tmp, &encrypt_filter, ctx, pf);
	if (res < 0)
		goto out;
	pf = pf_tmp;

	/* hasher */
	if (ctx->disable_mdc == 0)
	{
		res = pushf_create(&pf_tmp, &mdc_filter, ctx, pf);
		if (res < 0)
			goto out;
		pf = pf_tmp;
	}

	/* prefix */
	res = write_prefix(ctx, pf);
	if (res < 0)
		goto out;

	/* compressor */
	if (ctx->compress_algo > 0 && ctx->compress_level > 0)
	{
		res = init_compress(&pf_tmp, ctx, pf);
		if (res < 0)
			goto out;
		pf = pf_tmp;
	}

	/* data streamer */
	res = init_litdata_packet(&pf_tmp, ctx, pf);
	if (res < 0)
		goto out;
	pf = pf_tmp;


	/* text conversion? */
	if (ctx->text_mode && ctx->convert_crlf)
	{
		res = pushf_create(&pf_tmp, &crlf_filter, ctx, pf);
		if (res < 0)
			goto out;
		pf = pf_tmp;
	}

	/*
	 * chain complete
	 */

	len = mbuf_grab(src, mbuf_avail(src), &buf);
	res = pushf_write(pf, buf, len);
	if (res >= 0)
		res = pushf_flush(pf);
out:
	pushf_free_all(pf);
	return res;
}
