/** \file Encrypt0.c
 * Contains implementation of the functions related to HCOSE_ENCRYPT handle
 * objects.
 */

#include <stdlib.h>
#ifdef __MBED__
#include <string.h>
#else
#include <memory.h>
#endif
#include <stdio.h>
#include <assert.h>

#include "cose/cose.h"
#include "cose_int.h"
#include "cose/cose_configure.h"
#include "cose_crypto.h"

#if INCLUDE_ENCRYPT0 || INCLUDE_MAC0

COSE *EncryptRoot = nullptr;
#endif

#if INCLUDE_ENCRYPT0
/*! \private
 * @brief Test if a HCOSE_ENCRYPT handle is valid
 *
 *  Internal function to test if an encrypt message handle is valid.
 *  This will start returning invalid results and cause the code to
 *  crash if handles are not released before the memory that underlies them
 *  is deallocated.  This is an issue of a block allocator is used since
 *  in that case it is common to allocate memory but never to de-allocate it
 *  and just do that in a single big block.
 *
 *  @param h handle to be validated
 *  @returns result of check
 */

bool IsValidEncryptHandle(HCOSE_ENCRYPT h)
{
	COSE_Encrypt *p = (COSE_Encrypt *)h;
	return _COSE_IsInList(EncryptRoot, (COSE *)p);
}
#endif

#if INCLUDE_ENCRYPT0 || INCLUDE_MAC0
HCOSE_ENCRYPT COSE_Encrypt_Init(COSE_INIT_FLAGS flags,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	if (false) {
	errorReturn:
		return nullptr;		
	}

	CHECK_CONDITION(flags == COSE_INIT_FLAGS_NONE, COSE_ERR_INVALID_PARAMETER);
	COSE_Encrypt *pobj =
		(COSE_Encrypt *)COSE_CALLOC(1, sizeof(COSE_Encrypt), context);
	CHECK_CONDITION(pobj != nullptr, COSE_ERR_OUT_OF_MEMORY);

	if (!_COSE_Init(flags, &pobj->m_message, COSE_enveloped_object,
			CBOR_CONTEXT_PARAM_COMMA perr)) {
		_COSE_Encrypt_Release(pobj);
		COSE_FREE(pobj, context);
		return nullptr;
	}

	_COSE_InsertInList(&EncryptRoot, &pobj->m_message);

	return (HCOSE_ENCRYPT)pobj;
}
#endif

#if INCLUDE_ENCRYPT0
HCOSE_ENCRYPT COSE_Encrypt_Init_From_Object(cn_cbor *cbor,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	COSE_Encrypt *pobj;

	cose_errback error = {COSE_ERR_NONE};
	if (perr == nullptr) {
		perr = &error;
	}

	pobj = (COSE_Encrypt *)COSE_CALLOC(1, sizeof(COSE_Encrypt), context);
	if (pobj == nullptr) {
		perr->err = COSE_ERR_OUT_OF_MEMORY;
	errorReturn:
		if (pobj != nullptr) {
			_COSE_Encrypt_Release(pobj);
			COSE_FREE(pobj, context);
		}
		return nullptr;
	}

	if (!_COSE_Init_From_Object(
			&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

	_COSE_InsertInList(&EncryptRoot, &pobj->m_message);

	return (HCOSE_ENCRYPT)pobj;
}
#endif

#if INCLUDE_ENCRYPT0
HCOSE_ENCRYPT _COSE_Encrypt_Init_From_Object(cn_cbor *cbor,
	COSE_Encrypt *pIn,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	COSE_Encrypt *pobj = pIn;
	cn_cbor *pRecipients = nullptr;
	cose_errback error = {COSE_ERR_NONE};
	if (perr == nullptr) {
		perr = &error;
	}

	if (pobj == nullptr) {
		pobj = (COSE_Encrypt *)COSE_CALLOC(1, sizeof(COSE_Encrypt), context);
	}
	if (pobj == nullptr) {
		perr->err = COSE_ERR_OUT_OF_MEMORY;
	errorReturn:
		if (pobj != nullptr) {
			pobj->m_message.m_ownMsg = false;
			_COSE_Encrypt_Release(pobj);
			if (pIn == nullptr) {
				COSE_FREE(pobj, context);
			}
		}
		return nullptr;
	}

	if (!_COSE_Init_From_Object(
			&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
		goto errorReturn;
	}

	pRecipients = _COSE_arrayget_int(&pobj->m_message, INDEX_RECIPIENTS);
	CHECK_CONDITION(pRecipients == nullptr, COSE_ERR_INVALID_PARAMETER);

	if (pIn == nullptr) {
		_COSE_InsertInList(&EncryptRoot, &pobj->m_message);
	}

	return (HCOSE_ENCRYPT)pobj;
}

bool COSE_Encrypt_Free(HCOSE_ENCRYPT h)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context;
#endif
	COSE_Encrypt *pEncrypt = (COSE_Encrypt *)h;

	if (!IsValidEncryptHandle(h)) {
		return false;
	}

#ifdef USE_CBOR_CONTEXT
	context = &((COSE_Encrypt *)h)->m_message.m_allocContext;
#endif

	_COSE_Encrypt_Release(pEncrypt);

	_COSE_RemoveFromList(&EncryptRoot, &pEncrypt->m_message);

	COSE_FREE((COSE_Encrypt *)h, context);

	return true;
}
#endif

#if INCLUDE_ENCRYPT0 || INCLUDE_MAC0
void _COSE_Encrypt_Release(COSE_Encrypt *p)
{
	if (p->pbContent != nullptr) {
		COSE_FREE((void *)p->pbContent, &p->m_message.m_allocContext);
	}

	_COSE_Release(&p->m_message);
}
#endif

#if INCLUDE_ENCRYPT0
bool COSE_Encrypt_decrypt(HCOSE_ENCRYPT h,
	const byte *pbKey,
	size_t cbKey,
	cose_errback *perr)
{
	COSE_Encrypt *pcose = (COSE_Encrypt *)h;
	bool f;

	if (!IsValidEncryptHandle(h)) {
		if (perr != nullptr) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	f = _COSE_Enveloped_decrypt(pcose, nullptr, pbKey, cbKey, "Encrypt0", perr);
	return f;
}

bool COSE_Encrypt_encrypt(HCOSE_ENCRYPT h,
	const byte *pbKey,
	size_t cbKey,
	cose_errback *perr)
{
	CHECK_CONDITION(IsValidEncryptHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(pbKey != nullptr, COSE_ERR_INVALID_PARAMETER);

	return _COSE_Enveloped_encrypt(
		(COSE_Encrypt *)h, pbKey, cbKey, "Encrypt0", perr);

errorReturn:
	return false;
}

const byte *COSE_Encrypt_GetContent(HCOSE_ENCRYPT h,
	size_t *pcbContent,
	cose_errback *perror)
{
	COSE_Encrypt *cose = (COSE_Encrypt *)h;
	if (!IsValidEncryptHandle(h) || (pcbContent == nullptr)) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_PARAMETER;
		}
		return nullptr;
	}

	*pcbContent = cose->cbContent;
	return cose->pbContent;
}

bool COSE_Encrypt_SetContent(HCOSE_ENCRYPT h,
	const byte *rgb,
	size_t cb,
	cose_errback *perror)
{
	if (!IsValidEncryptHandle(h) || (rgb == nullptr)) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	return _COSE_Encrypt_SetContent((COSE_Encrypt *)h, rgb, cb, perror);
}

bool _COSE_Encrypt_SetContent(COSE_Encrypt *cose,
	const byte *rgb,
	size_t cb,
	cose_errback *perror)
{
	byte *pb;
	cose->pbContent = pb =
		(byte *)COSE_CALLOC(cb, 1, &cose->m_message.m_allocContext);
	if (cose->pbContent == nullptr) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_PARAMETER;
		}
		return false;
	}
	memcpy(pb, rgb, cb);
	cose->cbContent = cb;

	return true;
}

/*!
 * @brief Set the application external data for authentication
 *
 * Enveloped data objects support the authentication of external application
 * supplied data.  This function is provided to supply that data to the library.
 *
 * The external data is not copied, nor will be it freed when the handle is
 * released.
 *
 * @param hcose  Handle for the COSE Enveloped data object
 * @param pbEternalData  point to the external data
 * @param cbExternalData size of the external data
 * @param perr  location to return errors
 * @return result of the operation.
 */

bool COSE_Encrypt_SetExternal(HCOSE_ENCRYPT hcose,
	const byte *pbExternalData,
	size_t cbExternalData,
	cose_errback *perr)
{
	if (!IsValidEncryptHandle(hcose)) {
		if (perr != nullptr) {
			perr->err = COSE_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	return _COSE_SetExternal(&((COSE_Encrypt *)hcose)->m_message,
		pbExternalData, cbExternalData, perr);
}

cn_cbor *COSE_Encrypt_map_get_int(HCOSE_ENCRYPT h,
	int key,
	int flags,
	cose_errback *perror)
{
	if (!IsValidEncryptHandle(h)) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_PARAMETER;
		}
		return nullptr;
	}

	return _COSE_map_get_int(
		&((COSE_Encrypt *)h)->m_message, key, flags, perror);
}

bool COSE_Encrypt_map_put_int(HCOSE_ENCRYPT h,
	int key,
	cn_cbor *value,
	int flags,
	cose_errback *perror)
{
	if (!IsValidEncryptHandle(h) || (value == nullptr)) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_PARAMETER;
		}
		return false;
	}

	return _COSE_map_put(
		&((COSE_Encrypt *)h)->m_message, key, value, flags, perror);
}

#endif
