#include <stdlib.h>
#ifndef __MBED__
#include <memory.h>
#endif

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

#if INCLUDE_COUNTERSIGNATURE

COSE* CountersignRoot = NULL;

bool IsValidCounterSignHandle(HCOSE_COUNTERSIGN h)
{
	COSE_CounterSign* p = (COSE_CounterSign*)h;
	return _COSE_IsInList(CountersignRoot, &p->m_signer.m_message);
}

bool _COSE_CounterSign_Free(COSE_CounterSign* pSigner)
{
	if (pSigner->m_signer.m_message.m_refCount > 1) {
		pSigner->m_signer.m_message.m_refCount--;
		return true;
	}

	_COSE_SignerInfo_Release(&pSigner->m_signer);

	COSE_FREE(pSigner, &pSigner->m_signer.m_message.m_allocContext);

	return true;
}

COSE_CounterSign* _COSE_CounterSign_Init_From_Object(cn_cbor* cbor,
	COSE_CounterSign* pIn,
	CBOR_CONTEXT_COMMA cose_errback* perr)
{
	COSE_CounterSign* pobj = pIn;

	cose_errback error = {0};
	if (perr == NULL) {
		perr = &error;
	}

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

	CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
	if (!_COSE_SignerInfo_Init_From_Object(
			cbor, &pobj->m_signer, CBOR_CONTEXT_PARAM_COMMA perr)) {
		_COSE_SignerInfo_Release(&pobj->m_signer);
		if (pIn == NULL) {
			COSE_FREE(pobj, context);
		}
		return NULL;
	}

	if (pIn == NULL) {
		_COSE_InsertInList(&CountersignRoot, &pobj->m_signer.m_message);
	}

	return pobj;

errorReturn:
	if (pobj != NULL) {
		_COSE_CounterSign_Free(pobj);
	}
	return NULL;
}

bool _COSE_CounterSign_Init(COSE_CounterSign* pobject,
	CBOR_CONTEXT_COMMA cose_errback* perror)
{
	return _COSE_SignerInfo_Init(COSE_INIT_FLAGS_NO_CBOR_TAG,
		&pobject->m_signer, COSE_countersign_object,
		CBOR_CONTEXT_PARAM_COMMA perror);
}

HCOSE_COUNTERSIGN COSE_CounterSign_Init(CBOR_CONTEXT_COMMA cose_errback* perror)
{
	COSE_CounterSign* pobject =
		(COSE_CounterSign*)COSE_CALLOC(1, sizeof(COSE_CounterSign), context);
	if (pobject == NULL) {
		if (perror != NULL) {
			perror->err = COSE_ERR_OUT_OF_MEMORY;
		}
		return NULL;
	}

	if (!_COSE_CounterSign_Init(pobject, CBOR_CONTEXT_PARAM_COMMA perror)) {
		_COSE_CounterSign_Free(pobject);
		return NULL;
	}

	_COSE_InsertInList(&CountersignRoot, &pobject->m_signer.m_message);
	return (HCOSE_COUNTERSIGN)pobject;
}

bool COSE_CounterSign_Free(HCOSE_COUNTERSIGN h)
{
	COSE_CounterSign* p = (COSE_CounterSign*)h;
	bool fRet = false;

	if (!IsValidCounterSignHandle(h)) {
		goto errorReturn;
	}

	if (p->m_signer.m_message.m_refCount > 1) {
		p->m_signer.m_message.m_refCount--;
		return true;
	}

	_COSE_RemoveFromList(&CountersignRoot, &p->m_signer.m_message);

	fRet = _COSE_CounterSign_Free(p);

errorReturn:
	return fRet;
}

///  Add a countersignature to the list used to create the attribute
///
bool _COSE_CounterSign_add(COSE* pMessage,
	HCOSE_COUNTERSIGN hSigner,
	cose_errback* perr)
{
	COSE_CounterSign* pSigner = (COSE_CounterSign*)hSigner;

	CHECK_CONDITION(IsValidCounterSignHandle(hSigner), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(pSigner->m_next == NULL, COSE_ERR_INVALID_PARAMETER);

	pSigner->m_next = pMessage->m_counterSigners;
	pMessage->m_counterSigners = pSigner;
	pSigner->m_signer.m_message.m_refCount += 1;
	return true;

errorReturn:
	return false;
}

#if 0
I Don't remember why I wrote this and if I don't need it any more.
Keep for a little while and then delete
/// _COSE_CounterSign_create
///
///	Create the CounterSign attribute based on the set of countersignatures added
/// to the message.
///

bool _COSE_CounterSign_create(COSE* pMessage,
	cn_cbor* pcnBody,
	CBOR_CONTEXT_COMMA cose_errback* perr)
{
	cn_cbor* pArray = NULL;
	cn_cbor_errback cbor_err;
	COSE_CounterSign* pSigner = NULL;
	cn_cbor* pcnProtected = NULL;
	cn_cbor* pcn = NULL;
	cn_cbor* pcn2 = NULL;

	if (pMessage->m_counterSigners == NULL) {
		return true;
	}

	//  One or more than one?
	if (pMessage->m_counterSigners->m_signer.m_signerNext != NULL) {
		pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cbor_err);
		CHECK_CONDITION_CBOR(pArray != NULL, cbor_err);
	}

	pcnProtected = _COSE_arrayget_int(pMessage, INDEX_PROTECTED);
	CHECK_CONDITION(pcnProtected != NULL, COSE_ERR_INTERNAL);

	for (pSigner = pMessage->m_counterSigners; pSigner != NULL;
		 pSigner = pSigner->m_next) {
		CHECK_CONDITION(
			pSigner->m_signer.m_signerNext == NULL, COSE_ERR_INTERNAL);

		pcn = cn_cbor_data_create(pcnProtected->v.bytes, pcnProtected->length,
			CBOR_CONTEXT_PARAM_COMMA & cbor_err);
		CHECK_CONDITION_CBOR(pcnProtected != NULL, cbor_err);

		pcn2 = cn_cbor_clone(pcnBody, CBOR_CONTEXT_PARAM_COMMA & cbor_err);
		CHECK_CONDITION_CBOR(pcnBody != NULL, cbor_err);

		if (!_COSE_Signer_sign(
				&pSigner->m_signer, pcnBody, pcn2, "CounterSignature", perr)) {
			goto errorReturn;
		}
		pcn = NULL;
		pcn2 = NULL;

		if (pArray != NULL) {
			bool f = cn_cbor_array_append(
				pArray, pSigner->m_signer.m_message.m_cborRoot, &cbor_err);
			CHECK_CONDITION_CBOR(f, cbor_err);
		}
		else {
			pArray = pSigner->m_signer.m_message.m_cborRoot;
		}
	}

	if (!_COSE_map_put(pMessage, COSE_Header_CounterSign, pArray,
			COSE_UNPROTECT_ONLY, perr)) {
		goto errorReturn;
	}

	return true;

errorReturn:
	if (pArray != NULL) {
		CN_CBOR_FREE(pArray, context);
	}
	if ((pcn != NULL) && (pcn->parent != NULL)) {
		CN_CBOR_FREE(pcn, context);
	}
	if ((pcn2 != NULL) && (pcn2->parent != NULL)) {
		CN_CBOR_FREE(pcn2, context);
	}
	return false;
}
#endif

bool COSE_CounterSign_SetKey(HCOSE_COUNTERSIGN h,
	const cn_cbor* pkey,
	cose_errback* perr)
{
	bool fRet = false;
	CHECK_CONDITION(IsValidCounterSignHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(pkey != NULL, COSE_ERR_INVALID_PARAMETER);

	COSE_CounterSign* p = (COSE_CounterSign*)h;
	if (p->m_signer.m_pkey != NULL) {
		CN_CBOR_FREE(p->m_signer.m_pkey, &p->m_signer.m_message.m_allocContext);
	}
	p->m_signer.m_pkey = (cn_cbor *) pkey;

	fRet = true;
errorReturn:
	return fRet;
}

COSE_CounterSign* _COSE_Message_get_countersignature(COSE* pMessage,
	int index,
	cose_errback* perr)
{
	CHECK_CONDITION(
		pMessage->m_counterSigners != NULL, COSE_ERR_INVALID_PARAMETER);

	COSE_CounterSign* pCounterSign = pMessage->m_counterSigners;

	for (int i = 0; i < index; i++) {
		pCounterSign = pCounterSign->m_next;
		CHECK_CONDITION(pCounterSign != NULL, COSE_ERR_INVALID_PARAMETER);
	}

	pCounterSign->m_signer.m_message.m_refCount += 1;

	return pCounterSign;

errorReturn:
	return NULL;
}

bool COSE_CounterSign_map_put_int(HCOSE_COUNTERSIGN h,
	int key,
	cn_cbor* value,
	int flags,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidCounterSignHandle(h), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(value != NULL, COSE_ERR_INVALID_PARAMETER);

	return _COSE_map_put(
		&((COSE_CounterSign*)h)->m_signer.m_message, key, value, flags, perr);

errorReturn:
	return false;
}

/*!
 * @brief Set the application external data for authentication
 *
 * Signer 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 MAC 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_CounterSign_SetExternal(HCOSE_COUNTERSIGN hcose,
	const byte* pbExternalData,
	size_t cbExternalData,
	cose_errback* perr)
{
	if (!IsValidCounterSignHandle(hcose)) {
		if (perr != NULL) {
			perr->err = COSE_ERR_INVALID_HANDLE;
		}
		return false;
	}

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

bool _COSE_CounterSign_Sign(COSE* baseMessage,
	CBOR_CONTEXT_COMMA cose_errback* perr)
{
	bool fRet = false;
	cn_cbor* pcborProtectedSign = NULL;

	cn_cbor* pSignature = _COSE_arrayget_int(baseMessage, INDEX_SIGNATURE);
	int count = 0;

	COSE_CounterSign* pCountersign = baseMessage->m_counterSigners;
	for (; pCountersign != NULL;
		 pCountersign = pCountersign->m_next, count += 1) {
		pcborProtectedSign = _COSE_encode_protected(baseMessage, perr);
		if (pcborProtectedSign == NULL) {
			goto errorReturn;
		}
		if (!_COSE_Signer_sign(&pCountersign->m_signer, pSignature,
				pcborProtectedSign, "CounterSignature", perr)) {
			goto errorReturn;
		}
	}

	if (count == 1) {
		cn_cbor* cn = COSE_get_cbor((HCOSE)baseMessage->m_counterSigners);
		CHECK_CONDITION(_COSE_map_put(baseMessage, COSE_Header_CounterSign, cn,
							COSE_UNPROTECT_ONLY, perr),
			COSE_ERR_OUT_OF_MEMORY);
	}
	else {
		cn_cbor_errback cn_error;
		cn_cbor* cn_counterSign =
			cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA & cn_error);
		CHECK_CONDITION_CBOR(cn_counterSign, cn_error);

		for (pCountersign = baseMessage->m_counterSigners; pCountersign != NULL;
			 pCountersign = pCountersign->m_next) {
			cn_cbor* cn = COSE_get_cbor((HCOSE)pCountersign);
			CHECK_CONDITION_CBOR(
				cn_cbor_array_append(cn_counterSign, cn, &cn_error), cn_error);
		}
		CHECK_CONDITION(_COSE_map_put(baseMessage, COSE_Header_CounterSign,
							cn_counterSign, COSE_UNPROTECT_ONLY, perr),
			COSE_ERR_OUT_OF_MEMORY);
	}

	fRet = true;
errorReturn:
	return fRet;
}

/*! brief Retrieve header parameter from an enveloped message structure
 *
 * Retrieve a header parameter from the message.
 * Retrieved object is the same as the one in the message - do not delete it
 *
 * @param[in]	h	Handle of recipient object
 * @param[in]    key	Key to look for
 * @param[in]	flags	What buckets should we look for the message
 * @param[out]	perror	Location to return error codes
 * @return	Object which is found or NULL
 */

cn_cbor* COSE_CounterSign_map_get_int(HCOSE_COUNTERSIGN h,
	int key,
	int flags,
	cose_errback* perror)
{
	if (!IsValidCounterSignHandle(h)) {
		if (perror != NULL) {
			perror->err = COSE_ERR_INVALID_HANDLE;
		}
		return NULL;
	}

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

#if INCLUDE_SIGN
/***************************************************************************************************
 *
 *   SIGNER
 */
HCOSE_COUNTERSIGN COSE_Signer_add_countersignature(HCOSE_SIGNER hSigner,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_SignerInfo*)hSigner)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Signer_get_countersignature(HCOSE_SIGNER hSigner,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_SignerInfo*)hSigner)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Signer_CounterSign_validate(HCOSE_SIGNER hSigner,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_SignerInfo* pSigner = (COSE_SignerInfo*)hSigner;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSigner->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSigner->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}

/***************************************************************************************************
 *
 *   SIGN MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Sign_add_countersignature(HCOSE_SIGN hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidSignHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Sign_get_countersignature(HCOSE_SIGN hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidSignHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Sign_CounterSign_validate(HCOSE_SIGN hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidSignHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_SignMessage* pSignMsg = (COSE_SignMessage*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#if INCLUDE_SIGN1
/***************************************************************************************************
 *
 *   SIGN1 MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Sign1_add_countersignature(HCOSE_SIGN1 hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidSign1Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Sign1_get_countersignature(HCOSE_SIGN1 hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidSign1Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Sign1_CounterSign_validate(HCOSE_SIGN1 hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidSign1Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_Sign1Message* pSignMsg = (COSE_Sign1Message*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#if INCLUDE_ENCRYPT
/***************************************************************************************************
 *
 *   ENVELOPED MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Enveloped_add_countersignature(HCOSE_ENVELOPED hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidEnvelopedHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_Enveloped*)hSignMsg)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Enveloped_get_countersignature(HCOSE_ENVELOPED hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidEnvelopedHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_Enveloped*)hSignMsg)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Enveloped_CounterSign_validate(HCOSE_ENVELOPED hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidEnvelopedHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_Enveloped* pSignMsg = (COSE_Enveloped*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_MAC
/***************************************************************************************************
 *
 *   RECIPIENT MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Recipient_add_countersignature(HCOSE_RECIPIENT hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidRecipientHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_RecipientInfo*)hSignMsg)->m_encrypt.m_message, hCountersign,
			perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Recipient_get_countersignature(HCOSE_RECIPIENT hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidRecipientHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_RecipientInfo*)hSignMsg)->m_encrypt.m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Recipient_CounterSign_validate(HCOSE_RECIPIENT hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidRecipientHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_RecipientInfo* pSignMsg = (COSE_RecipientInfo*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_encrypt.m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_encrypt.m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#if INCLUDE_ENCRYPT0
/***************************************************************************************************
 *
 *   ENCRYPT0 MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Encrypt0_add_countersignature(HCOSE_ENCRYPT hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidEncryptHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Encrypt0_get_countersignature(HCOSE_ENCRYPT hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidEncryptHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Encrypt0_CounterSign_validate(HCOSE_ENCRYPT hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidEncryptHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_Encrypt* pSignMsg = (COSE_Encrypt*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#if INCLUDE_MAC0
/***************************************************************************************************
 *
 *   MAC0 MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Mac0_add_countersignature(HCOSE_MAC0 hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidMac0Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_SignMessage*)hSignMsg)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Mac0_get_countersignature(HCOSE_MAC0 hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidMac0Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_SignMessage*)hSignMsg)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Mac0_CounterSign_validate(HCOSE_MAC0 hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidMac0Handle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_Mac0Message* pSignMsg = (COSE_Mac0Message*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#if INCLUDE_MAC
/***************************************************************************************************
 *
 *   ENCRYPT0 MESSAGE
 */
HCOSE_COUNTERSIGN COSE_Mac_add_countersignature(HCOSE_MAC hSignMsg,
	HCOSE_COUNTERSIGN hCountersign,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidMacHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersign), COSE_ERR_INVALID_HANDLE);

	if (!_COSE_CounterSign_add(
			&((COSE_MacMessage*)hSignMsg)->m_message, hCountersign, perr)) {
		goto errorReturn;
	}

	return hCountersign;

errorReturn:
	return NULL;
}

HCOSE_COUNTERSIGN COSE_Mac_get_countersignature(HCOSE_MAC hSignMsg,
	int index,
	cose_errback* perr)
{
	COSE_CounterSign* p = NULL;

	CHECK_CONDITION(IsValidMacHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);

	p = _COSE_Message_get_countersignature(
		&((COSE_MacMessage*)hSignMsg)->m_message, index, perr);

errorReturn:
	return (HCOSE_COUNTERSIGN)p;
}

bool COSE_Mac_CounterSign_validate(HCOSE_MAC hSignMsg,
	HCOSE_COUNTERSIGN hCountersignature,
	cose_errback* perr)
{
	CHECK_CONDITION(IsValidMacHandle(hSignMsg), COSE_ERR_INVALID_HANDLE);
	CHECK_CONDITION(
		IsValidCounterSignHandle(hCountersignature), COSE_ERR_INVALID_HANDLE);

	COSE_MacMessage* pSignMsg = (COSE_MacMessage*)hSignMsg;
	COSE_CounterSign* pCountersign = (COSE_CounterSign*)hCountersignature;

	const cn_cbor* cnContent =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_BODY);
	CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	const cn_cbor* cnProtected =
		_COSE_arrayget_int(&pSignMsg->m_message, INDEX_PROTECTED);
	CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES,
		COSE_ERR_INVALID_PARAMETER);

	bool f = _COSE_Signer_validate(&pCountersign->m_signer, cnContent,
		cnProtected, "CounterSignature", perr);

	return f;

errorReturn:
	return false;
}
#endif

#endif
