/** \file Sign.c
 * Contains implementation of the functions related to HCOSE_SIGN handle
 * objects.
 */

#include <stdlib.h>

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

#if INCLUDE_SIGN

COSE *SignRoot = nullptr;

/*! \private
 * @brief Test if a HCOSE_SIGN handle is valid
 *
 *  Internal function to test if a sign 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 IsValidSignHandle(HCOSE_SIGN h)
{
	COSE_SignMessage *p = (COSE_SignMessage *)h;

	if (p == nullptr) {
		return false;
	}
	return _COSE_IsInList(SignRoot, (COSE *)p);
}

/** Allocate a SIGN message structure.
 *
 * Allocate a new SIGN message structure for creation of a COSE_Sign object.
 * @param context is a cn_cbor context object
 * @param perr is a cose_errback return variable
 * @return HCOSE_SIGN a handle for the newly allocated object
 */
HCOSE_SIGN COSE_Sign_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_SignMessage *pobj =
		(COSE_SignMessage *)COSE_CALLOC(1, sizeof(COSE_SignMessage), context);
	CHECK_CONDITION(pobj != nullptr, COSE_ERR_OUT_OF_MEMORY);

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

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

	return (HCOSE_SIGN)pobj;
}

HCOSE_SIGN _COSE_Sign_Init_From_Object(cn_cbor *cbor,
	COSE_SignMessage *pIn,
	CBOR_CONTEXT_COMMA cose_errback *perr)
{
	COSE_SignMessage *pobj = pIn;
	cn_cbor *pSigners = nullptr;
	// cn_cbor * tmp;
	cose_errback error = {COSE_ERR_NONE};
	if (perr == nullptr) {
		perr = &error;
	}

	if (pobj == nullptr) {
		pobj = (COSE_SignMessage *)COSE_CALLOC(
			1, sizeof(COSE_SignMessage), context);
	}
	CHECK_CONDITION(pobj != nullptr, COSE_ERR_OUT_OF_MEMORY);

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

	pSigners = _COSE_arrayget_int(&pobj->m_message, INDEX_SIGNERS);
	CHECK_CONDITION(pSigners != nullptr, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(
		pSigners->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
	CHECK_CONDITION(pSigners->length > 0,
		COSE_ERR_INVALID_PARAMETER);  // Must be at least one signer

	pSigners = pSigners->first_child;
	do {
		COSE_SignerInfo *pInfo = _COSE_SignerInfo_Init_From_Object(
			pSigners, nullptr, CBOR_CONTEXT_PARAM_COMMA perr);
		if (pInfo == nullptr) {
			goto errorReturn;
		}

		pInfo->m_signerNext = pobj->m_signerFirst;
		pobj->m_signerFirst = pInfo;
		pSigners = pSigners->next;
	} while (pSigners != nullptr);

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

	return (HCOSE_SIGN)pobj;

errorReturn:
	if (pobj != nullptr) {
		pobj->m_message.m_ownMsg = false;
		_COSE_Sign_Release(pobj);
		if (pIn == nullptr) {
			COSE_FREE(pobj, context);
		}
	}
	return nullptr;
}

bool COSE_Sign_Free(HCOSE_SIGN h)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context;
#endif
	COSE_SignMessage *pMessage = (COSE_SignMessage *)h;

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

	//  Check reference counting
	if (pMessage->m_message.m_refCount > 1) {
		pMessage->m_message.m_refCount--;
		return true;
	}

	_COSE_RemoveFromList(&SignRoot, &pMessage->m_message);

#ifdef USE_CBOR_CONTEXT
	context = &pMessage->m_message.m_allocContext;
#endif

	_COSE_Sign_Release(pMessage);

	COSE_FREE(pMessage, context);

	return true;
}

void _COSE_Sign_Release(COSE_SignMessage *p)
{
	COSE_SignerInfo *pSigner;
	COSE_SignerInfo *pSigner2;

	for (pSigner = p->m_signerFirst; pSigner != nullptr; pSigner = pSigner2) {
		pSigner2 = pSigner->m_signerNext;
		COSE_Signer_Free((HCOSE_SIGNER)pSigner);
	}

	_COSE_Release(&p->m_message);
}

bool COSE_Sign_SetContent(HCOSE_SIGN h,
	const byte *rgb,
	size_t cb,
	cose_errback *perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = nullptr;
#endif
	cn_cbor *p = nullptr;
	COSE_SignMessage *pMessage = (COSE_SignMessage *)h;
	bool f = false;

	CHECK_CONDITION(IsValidSignHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(rgb != nullptr, COSE_ERR_INVALID_PARAMETER);

#ifdef USE_CBOR_CONTEXT
	context = &pMessage->m_message.m_allocContext;
#endif

	p = cn_cbor_data_create(rgb, (int)cb, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_CONDITION(p != nullptr, COSE_ERR_OUT_OF_MEMORY);

	CHECK_CONDITION(_COSE_array_replace(&pMessage->m_message, p, INDEX_BODY,
						CBOR_CONTEXT_PARAM_COMMA nullptr),
		COSE_ERR_OUT_OF_MEMORY);
	p = nullptr;

	f = true;
errorReturn:
	if (p != nullptr) {
		CN_CBOR_FREE(p, context);
	}

	return f;
}

HCOSE_SIGNER COSE_Sign_add_signer(HCOSE_SIGN hSign,
	const cn_cbor *pkey,
	int algId,
	cose_errback *perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = nullptr;
	COSE_SignMessage *pMessage = (COSE_SignMessage *)hSign;
#endif
	const cn_cbor *cbor;
	cn_cbor *cbor2 = nullptr;
	HCOSE_SIGNER hSigner = nullptr;
	cn_cbor_errback cbor_error;

	CHECK_CONDITION(IsValidSignHandle(hSign), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(pkey != nullptr, COSE_ERR_INVALID_PARAMETER);

#ifdef USE_CBOR_CONTEXT
	context = &pMessage->m_message.m_allocContext;
#endif

	hSigner = COSE_Signer_Init(CBOR_CONTEXT_PARAM_COMMA perr);
	if (hSigner == nullptr) {
		goto errorReturn;
	}

	cbor2 = cn_cbor_int_create(algId, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
	CHECK_CONDITION_CBOR(cbor2 != nullptr, cbor_error);
	if (!COSE_Signer_map_put_int(
			hSigner, COSE_Header_Algorithm, cbor2, COSE_PROTECT_ONLY, perr)) {
		goto errorReturn;
	}
	cbor2 = nullptr;

	cbor = cn_cbor_mapget_int(pkey, COSE_Key_ID);
	if (cbor != nullptr) {
		CHECK_CONDITION(
			cbor->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
		cbor2 = cn_cbor_data_create(cbor->v.bytes, (int)cbor->length,
			CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(cbor2 != nullptr, cbor_error);
		if (!COSE_Signer_map_put_int(
				hSigner, COSE_Header_KID, cbor2, COSE_UNPROTECT_ONLY, perr)) {
			goto errorReturn;
		}
		cbor2 = nullptr;
	}

	if (!COSE_Signer_SetKey(hSigner, pkey, perr)) {
		goto errorReturn;
	}

	if (!COSE_Sign_AddSigner(hSign, hSigner, perr)) {
		goto errorReturn;
	}

	return hSigner;

errorReturn:
	if (cbor2 != nullptr) {
		CN_CBOR_FREE(cbor2, context);
	}
	if (hSigner != nullptr) {
		COSE_Signer_Free(hSigner);
	}
	return nullptr;
}

bool COSE_Sign_Sign(HCOSE_SIGN h, cose_errback *perr)
{
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = nullptr;
#endif
	COSE_SignMessage *pMessage = (COSE_SignMessage *)h;
	COSE_SignerInfo *pSigner;
	const cn_cbor *pcborBody;
	const cn_cbor *pcborProtected;

	if (!IsValidSignHandle(h)) {
		CHECK_CONDITION(false, COSE_ERR_INVALID_HANDLE);
	errorReturn:
		return false;
	}
#ifdef USE_CBOR_CONTEXT
	context = &pMessage->m_message.m_allocContext;
#endif

	pcborBody = _COSE_arrayget_int(&pMessage->m_message, INDEX_BODY);
	CHECK_CONDITION(
		(pcborBody != nullptr) && (pcborBody->type == CN_CBOR_BYTES),
		COSE_ERR_INVALID_PARAMETER);

	pcborProtected = _COSE_encode_protected(&pMessage->m_message, perr);
	if (pcborProtected == nullptr) {
		goto errorReturn;
	}

	for (pSigner = pMessage->m_signerFirst; pSigner != nullptr;
		 pSigner = pSigner->m_signerNext) {
		if (!_COSE_Signer_sign(
				pSigner, pcborBody, pcborProtected, "Signature", perr)) {
			goto errorReturn;
		}
	}

#if INCLUDE_COUNTERSIGNATURE
	if (pMessage->m_message.m_counterSigners != nullptr) {
		if (!_COSE_CounterSign_Sign(
				&pMessage->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
			goto errorReturn;
		}
	}
#endif

#if INCLUDE_COUNTERSIGNATURE1
	if (pMessage->m_message.m_counterSign1 != NULL) {
		if (!_COSE_CounterSign1_Sign(
				&pMessage->m_message, CBOR_CONTEXT_PARAM_COMMA perr)) {
			goto errorReturn;
		}
	}
#endif

	return true;
}

bool COSE_Sign_validate(HCOSE_SIGN hSign,
	HCOSE_SIGNER hSigner,
	cose_errback *perr)
{
	bool f;
	COSE_SignMessage *pSign;
	COSE_SignerInfo *pSigner;
	const cn_cbor *cnContent;
	const cn_cbor *cnProtected;

	CHECK_CONDITION(IsValidSignHandle(hSign), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);

	pSign = (COSE_SignMessage *)hSign;
	pSigner = (COSE_SignerInfo *)hSigner;

	cnContent = _COSE_arrayget_int(&pSign->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != nullptr && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	cnProtected = _COSE_arrayget_int(&pSign->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(
		cnProtected != nullptr && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	f = _COSE_Signer_validate(
		pSigner, cnContent, cnProtected, "Signature", perr);

	return f;

errorReturn:
	return false;
}

bool COSE_Sign_AddSigner(HCOSE_SIGN hSign,
	HCOSE_SIGNER hSigner,
	cose_errback *perr)
{
	COSE_SignerInfo *pSigner;
	COSE_SignMessage *pSign;
	cn_cbor *pSigners = nullptr;
	cn_cbor *pSignersT = nullptr;
#ifdef USE_CBOR_CONTEXT
	cn_cbor_context *context = nullptr;
#endif
	cn_cbor_errback cbor_error;

	CHECK_CONDITION(IsValidSignHandle(hSign), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);

	pSign = (COSE_SignMessage *)hSign;
	pSigner = (COSE_SignerInfo *)hSigner;

#ifdef USE_CBOR_CONTEXT
	context = &pSign->m_message.m_allocContext;
#endif	// USE_CBOR_CONTEXT

	pSigners = _COSE_arrayget_int(&pSign->m_message, INDEX_SIGNERS);
	if (pSigners == nullptr) {
		pSignersT = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cbor_error);
		CHECK_CONDITION_CBOR(pSignersT != nullptr, cbor_error);

		CHECK_CONDITION_CBOR(
			_COSE_array_replace(&pSign->m_message, pSignersT, INDEX_SIGNERS,
				CBOR_CONTEXT_PARAM_COMMA & cbor_error),
			cbor_error);
		pSigners = pSignersT;
		pSignersT = nullptr;
	}

	CHECK_CONDITION_CBOR(
		cn_cbor_array_append(pSigners, pSigner->m_message.m_cbor, &cbor_error),
		cbor_error);

	pSigner->m_signerNext = pSign->m_signerFirst;
	pSign->m_signerFirst = pSigner;
	pSigner->m_message.m_refCount++;

	return true;

errorReturn:
	if (pSignersT == nullptr) {
		CN_CBOR_FREE(pSignersT, context);
	}
	return false;
}

cn_cbor *COSE_Sign_map_get_int(HCOSE_SIGN h,
	int key,
	int flags,
	cose_errback *perror)
{
	if (!IsValidSignHandle(h)) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_HANDLE;
		}
		return nullptr;
	}

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

bool COSE_Sign_map_put_int(HCOSE_SIGN h,
	int key,
	cn_cbor *value,
	int flags,
	cose_errback *perror)
{
	if (!IsValidSignHandle(h)) {
		if (perror != nullptr) {
			perror->err = COSE_ERR_INVALID_HANDLE;
		}
		return false;
	}

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

HCOSE_SIGNER COSE_Sign_GetSigner(HCOSE_SIGN cose,
	int iSigner,
	cose_errback *perr)
{
	int i;
	COSE_SignerInfo *p;

	if (!IsValidSignHandle(cose)) {
		if (perr != nullptr) {
			perr->err = COSE_ERR_INVALID_HANDLE;
		}
		return nullptr;
	}

	p = ((COSE_SignMessage *)cose)->m_signerFirst;
	for (i = 0; i < iSigner; i++) {
		if (p == nullptr) {
			if (perr != nullptr) {
				perr->err = COSE_ERR_INVALID_PARAMETER;
			}
			return nullptr;
		}
		p = p->m_signerNext;
	}
	p->m_message.m_refCount++;

	return (HCOSE_SIGNER)p;
}

#endif
