#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <cose/cose.h>
#include <cose/cose_configure.h>
#include <cn-cbor/cn-cbor.h>
#include "cose_int.h"
#include "json.h"
#include "test.h"
#include "context.h"

#ifdef _MSC_VER
#pragma warning(disable : 4127)
#endif

#if INCLUDE_MAC
int _ValidateMAC(const cn_cbor *pControl,
	const byte *pbEncoded,
	size_t cbEncoded)
{
	const cn_cbor *pInput = cn_cbor_mapget_string(pControl, "input");
	const cn_cbor *pFail;
	const cn_cbor *pMac;
	const cn_cbor *pRecipients;
	HCOSE_MAC hMAC;
	int type;
	int iRecipient;
	bool fFail = false;
	bool fFailBody = false;
	bool fAlgNoSupport = false;
	int returnCode = 1;
	cose_errback error;

	pFail = cn_cbor_mapget_string(pControl, "fail");
	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
		fFailBody = true;
	}

	hMAC = (HCOSE_MAC)COSE_Decode(pbEncoded, cbEncoded, &type, COSE_mac_object,
		CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hMAC == NULL) {
		if (fFailBody) {
			return 0;
		}
		goto failTest;
	}

	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
		goto failTest;
	}
	pMac = cn_cbor_mapget_string(pInput, "mac");
	if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP)) {
		goto failTest;
	}

	if (!SetReceivingAttributes((HCOSE)hMAC, pMac, Attributes_MAC_protected)) {
		goto failTest;
	}

	pRecipients = cn_cbor_mapget_string(pMac, "recipients");
	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
		goto failTest;
	}

	iRecipient = (int)pRecipients->length - 1;
	pRecipients = pRecipients->first_child;
	for (; pRecipients != NULL; iRecipient--, pRecipients = pRecipients->next) {
		fAlgNoSupport = false;
		cn_cbor *pkey =
			BuildKey(cn_cbor_mapget_string(pRecipients, "key"), false);
		if (pkey == NULL) {
			fFail = true;
			continue;
		}

		HCOSE_RECIPIENT hRecip = COSE_Mac_GetRecipient(hMAC, iRecipient, NULL);
		if (hRecip == NULL) {
			fFail = true;
			continue;
		}

		if (!SetReceivingAttributes(
				(HCOSE)hRecip, pRecipients, Attributes_Recipient_protected)) {
			goto failTest;
		}

		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
			fFail = true;
			continue;
		}

		cn_cbor *cnStatic = cn_cbor_mapget_string(pRecipients, "sender_key");
		if (cnStatic != NULL) {
			if (COSE_Recipient_map_get_int(
					hRecip, COSE_Header_ECDH_SPK, COSE_BOTH, NULL) == 0) {
				COSE_Recipient_map_put_int(hRecip, COSE_Header_ECDH_SPK,
					BuildKey(cnStatic, true), COSE_DONT_SEND, NULL);
			}
		}

		pFail = cn_cbor_mapget_string(pRecipients, "fail");

		cn_cbor *alg =
			COSE_Mac_map_get_int(hMAC, COSE_Header_Algorithm, COSE_BOTH, NULL);
		if (!IsAlgorithmSupported(alg)) {
			fAlgNoSupport = true;
		}

		alg = COSE_Recipient_map_get_int(
			hRecip, COSE_Header_Algorithm, COSE_BOTH, NULL);
		if (!IsAlgorithmSupported(alg)) {
			fAlgNoSupport = true;
		}

		if (COSE_Mac_validate(hMAC, hRecip, &error)) {
			if (fAlgNoSupport) {
				fFail = true;
			}
			else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
				fFail = true;
			}
		}
		else {
			if (error.err == COSE_ERR_NO_COMPRESSED_POINTS ||
				error.err == COSE_ERR_UNKNOWN_ALGORITHM) {
				fAlgNoSupport = true;
				returnCode = 0;
			}
			else if (fAlgNoSupport) {
				returnCode = 0;
			}
			else if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
				fFail = true;
			}
		}

#if INCLUDE_COUNTERSIGNATURE
		//  Countersign on Encrypt0 Body

		//  Validate counter signatures on signers
		cn_cbor *countersignList =
			cn_cbor_mapget_string(pRecipients, "countersign");
		if (countersignList != NULL) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == NULL) {
				goto failTest;
			}
			int count = countersigners->length;
			bool forward = true;

			if (COSE_Recipient_map_get_int(hRecip, COSE_Header_CounterSign,
					COSE_UNPROTECT_ONLY, 0) == NULL) {
				goto failTest;
			}

			for (int counterNo = 0; counterNo < count; counterNo++) {
				bool noSignSupport = false;
				HCOSE_COUNTERSIGN h =
					COSE_Recipient_get_countersignature(hRecip, counterNo, 0);
				if (h == NULL) {
					continue;
				}

				alg = COSE_CounterSign_map_get_int(
					h, COSE_Header_Algorithm, COSE_BOTH, NULL);
				if (!IsAlgorithmSupported(alg)) {
					fAlgNoSupport = true;
					noSignSupport = true;
					returnCode = 0;
				}

				cn_cbor *counterSigner = cn_cbor_index(countersigners,
					forward ? counterNo : count - counterNo - 1);

				cn_cbor *pkeyCountersign = BuildKey(
					cn_cbor_mapget_string(counterSigner, "key"), false);
				if (pkeyCountersign == NULL) {
					fFail = true;
					COSE_CounterSign_Free(h);
					continue;
				}

				if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
					fFail = true;
					CN_CBOR_FREE(pkeyCountersign, context);
					COSE_CounterSign_Free(h);
					continue;
				}

				if (COSE_Recipient_CounterSign_validate(hRecip, h, 0)) {
					//  I don't think we have any forced errors yet.
				}
				else {
					if (forward && counterNo == 0 && count > 1) {
						forward = false;
						counterNo -= 1;
					}
					else {
						fFail |= !noSignSupport;
					}
				}

				COSE_CounterSign_Free(h);
			}
		}
#endif

		COSE_Recipient_Free(hRecip);
	}

#if INCLUDE_COUNTERSIGNATURE
	//  Countersign on Signed Body

	//  Validate counter signatures on signers
	cn_cbor *countersignList = cn_cbor_mapget_string(pMac, "countersign");
	if (countersignList != NULL) {
		cn_cbor *countersigners =
			cn_cbor_mapget_string(countersignList, "signers");
		if (countersigners == NULL) {
			goto failTest;
		}
		int count = countersigners->length;
		bool forward = true;

		if (COSE_Mac_map_get_int(hMAC, COSE_Header_CounterSign,
				COSE_UNPROTECT_ONLY, 0) == NULL) {
			goto failTest;
		}

		for (int counterNo = 0; counterNo < count; counterNo++) {
			bool noSignSupport = false;

			HCOSE_COUNTERSIGN h =
				COSE_Mac_get_countersignature(hMAC, counterNo, 0);
			if (h == NULL) {
				fFail = true;
				continue;
			}

			cn_cbor *counterSigner = cn_cbor_index(
				countersigners, forward ? counterNo : count - counterNo - 1);

			cn_cbor *pkeyCountersign =
				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
			if (pkeyCountersign == NULL) {
				fFail = true;
				COSE_CounterSign_Free(h);
				continue;
			}

			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
				fFail = true;
				COSE_CounterSign_Free(h);
				CN_CBOR_FREE(pkeyCountersign, context);
				continue;
			}

			cn_cbor *alg = COSE_CounterSign_map_get_int(
				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
			if (!IsAlgorithmSupported(alg)) {
				fAlgNoSupport = true;
				noSignSupport = true;
				returnCode = 0;
			}

			if (COSE_Mac_CounterSign_validate(hMAC, h, 0)) {
				//  I don't think we have any forced errors yet.
			}
			else {
				if (forward && counterNo == 0 && count > 1) {
					forward = false;
					counterNo -= 1;
				}
				else {
					fFail |= !noSignSupport;
				}
			}

			COSE_CounterSign_Free(h);
		}
	}
#endif

	COSE_Mac_Free(hMAC);

	if (fFailBody) {
		if (!fFail) {
			fFail = true;
		}
		else {
			fFail = false;
		}
	}

	if (fFail && !fAlgNoSupport) {
		CFails += 1;
	}
	return returnCode;

failTest:
	CFails += 1;
	return 0;
}

int ValidateMAC(const cn_cbor *pControl)
{
	int cbEncoded = 0;
	byte *pbEncoded = GetCBOREncoding(pControl, &cbEncoded);

	return _ValidateMAC(pControl, pbEncoded, cbEncoded);
}

int BuildMacMessage(const cn_cbor *pControl)
{
	int iRecipient = 0;
	HCOSE_RECIPIENT hRecip = NULL;

	//
	//  We don't run this for all control sequences - skip those marked fail.
	//

	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
		return 0;
	}

	HCOSE_MAC hMacObj = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);

	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
	if (pInputs == NULL) {
		goto returnError;
	}
	const cn_cbor *pMac = cn_cbor_mapget_string(pInputs, "mac");
	if (pMac == NULL) {
		goto returnError;
	}

	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
	if (!COSE_Mac_SetContent(
			hMacObj, pContent->v.bytes, pContent->length, NULL)) {
		goto returnError;
	}

	if (!SetSendingAttributes((HCOSE)hMacObj, pMac, Attributes_MAC_protected)) {
		goto returnError;
	}

	const cn_cbor *pRecipients = cn_cbor_mapget_string(pMac, "recipients");
	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
		goto returnError;
	}

	pRecipients = pRecipients->first_child;
	for (iRecipient = 0; pRecipients != NULL;
		 iRecipient++, pRecipients = pRecipients->next) {
		cn_cbor *pkey =
			BuildKey(cn_cbor_mapget_string(pRecipients, "key"), true);
		if (pkey == NULL) {
			goto returnError;
		}

		hRecip = COSE_Recipient_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
		if (hRecip == NULL) {
			goto returnError;
		}

		if (!SetSendingAttributes(
				(HCOSE)hRecip, pRecipients, Attributes_Recipient_protected)) {
			goto returnError;
		}

		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
			goto returnError;
		}

		cn_cbor *pSenderKey = cn_cbor_mapget_string(pRecipients, "sender_key");
		if (pSenderKey != NULL) {
			cn_cbor *pSendKey = BuildKey(pSenderKey, false);
			if (!COSE_Recipient_SetSenderKey(hRecip, pSendKey, 2, NULL)) {
				goto returnError;
			}
		}

		if (!COSE_Mac_AddRecipient(hMacObj, hRecip, NULL)) {
			goto returnError;
		}

#if INCLUDE_COUNTERSIGNATURE
		// On the Recipient
		cn_cbor *countersigns1 =
			cn_cbor_mapget_string(pRecipients, "countersign");
		if (countersigns1 != NULL) {
			countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
			cn_cbor *countersign = countersigns1->first_child;

			for (; countersign != NULL; countersign = countersign->next) {
				cn_cbor *pkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (pkeyCountersign == NULL) {
					goto returnError;
				}

				HCOSE_COUNTERSIGN hCountersign =
					COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
				if (hCountersign == NULL) {
					goto returnError;
				}

				if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
						Attributes_Countersign_protected)) {
					goto returnError;
				}

				if (!COSE_CounterSign_SetKey(
						hCountersign, pkeyCountersign, NULL)) {
					goto returnError;
				}

				if (!COSE_Recipient_add_countersignature(
						hRecip, hCountersign, NULL)) {
					goto returnError;
				}

				COSE_CounterSign_Free(hCountersign);
			}
		}

#endif

		COSE_Recipient_Free(hRecip);
		hRecip = NULL;
	}

#if INCLUDE_COUNTERSIGNATURE
	// On the Evneloped body
	cn_cbor *countersigns1 = cn_cbor_mapget_string(pMac, "countersign");
	if (countersigns1 != NULL) {
		countersigns1 = cn_cbor_mapget_string(countersigns1, "signers");
		cn_cbor *countersign = countersigns1->first_child;

		for (; countersign != NULL; countersign = countersign->next) {
			cn_cbor *pkeyCountersign =
				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
			if (pkeyCountersign == NULL) {
				goto returnError;
			}

			HCOSE_COUNTERSIGN hCountersign =
				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
			if (hCountersign == NULL) {
				goto returnError;
			}

			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
					Attributes_Countersign_protected)) {
				COSE_CounterSign_Free(hCountersign);
				goto returnError;
			}

			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
				COSE_CounterSign_Free(hCountersign);
				goto returnError;
			}

			if (!COSE_Mac_add_countersignature(hMacObj, hCountersign, NULL)) {
				COSE_CounterSign_Free(hCountersign);
				goto returnError;
			}

			COSE_CounterSign_Free(hCountersign);
		}
	}

#endif

	if (!COSE_Mac_encrypt(hMacObj, NULL)) {
		goto returnError;
	}

	size_t cb = COSE_Encode((HCOSE)hMacObj, NULL, 0, 0) + 1;
	byte *rgb = (byte *)malloc(cb);
	cb = COSE_Encode((HCOSE)hMacObj, rgb, 0, cb);

	COSE_Mac_Free(hMacObj);

	int f = _ValidateMAC(pControl, rgb, cb);

	free(rgb);
	return f;

returnError:
	if (hMacObj != NULL) {
		COSE_Mac_Free(hMacObj);
	}
	if (hRecip != NULL) {
		COSE_Recipient_Free(hRecip);
	}
	CFails += 1;
	return 1;
}

int MacMessage()
{
	HCOSE_MAC hEncObj = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
	char *sz = "This is the content to be used";
	byte rgbSecret[256 / 8] = {'a', 'b', 'c'};
	byte rgbKid[6] = {'a', 'b', 'c', 'd', 'e', 'f'};
	int cbKid = 6;
	size_t cb = 0;
	byte *rgb = NULL;

	if (hEncObj == NULL) {
		goto errorReturn;
	}

	if (!COSE_Mac_map_put_int(hEncObj, COSE_Header_Algorithm,
			cn_cbor_int_create(
				COSE_Algorithm_HMAC_256_256, CBOR_CONTEXT_PARAM_COMMA NULL),
			COSE_PROTECT_ONLY, NULL)) {
		goto errorReturn;
	}
	if (!COSE_Mac_SetContent(hEncObj, (byte *)sz, strlen(sz), NULL)) {
		goto errorReturn;
	}

	HCOSE_RECIPIENT hRecip = COSE_Recipient_from_shared_secret(rgbSecret,
		sizeof(rgbSecret), rgbKid, cbKid, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hRecip == NULL) {
		goto errorReturn;
	}
	if (!COSE_Mac_AddRecipient(hEncObj, hRecip, NULL)) {
		goto errorReturn;
	}

	if (!COSE_Mac_encrypt(hEncObj, NULL)) {
		goto errorReturn;
	}

	cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0);
	if (cb == 0) {
		goto errorReturn;
	}

	rgb = (byte *)malloc(cb);
	if (rgb == NULL) {
		goto errorReturn;
	}
	cb = COSE_Encode((HCOSE)hEncObj, rgb, 0, cb);
	if (cb == 0) {
		goto errorReturn;
	}

	COSE_Mac_Free(hEncObj);

	FILE *fp = fopen("test.mac.cbor", "wb");
	fwrite(rgb, cb, 1, fp);
	fclose(fp);

#if 0
	char * szX;
	int cbPrint = 0;
	cn_cbor * cbor = COSE_get_cbor((HCOSE)hEncObj);
	cbPrint = cn_cbor_printer_write(NULL, 0, cbor, "  ", "\r\n");
	szX = malloc(cbPrint);
	cn_cbor_printer_write(szX, cbPrint, cbor, "  ", "\r\n");
	fprintf(stdout, "%s", szX);
	fprintf(stdout, "\r\n");
#endif

	int typ;
	hEncObj = (HCOSE_MAC)COSE_Decode(
		rgb, (int)cb, &typ, COSE_mac_object, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hEncObj == NULL) {
		goto errorReturn;
	}

	int iRecipient = 0;
	do {
		HCOSE_RECIPIENT hRecip2;

		hRecip2 = COSE_Mac_GetRecipient(hEncObj, iRecipient, NULL);
		if (hRecip2 == NULL) {
			break;
		}

		if (!COSE_Recipient_SetKey_secret(
				hRecip2, rgbSecret, sizeof(rgbSecret), NULL, 0, NULL)) {
			goto errorReturn;
		}

		if (!COSE_Mac_validate(hEncObj, hRecip2, NULL)) {
			goto errorReturn;
		}

		iRecipient += 1;

		COSE_Recipient_Free(hRecip2);

	} while (true);

	COSE_Mac_Free(hEncObj);

	return 1;

errorReturn:
	CFails++;
	return 1;
}
#endif

#if INCLUDE_MAC0
int _ValidateMac0(const cn_cbor *pControl,
	const byte *pbEncoded,
	size_t cbEncoded)
{
	const cn_cbor *pInput = cn_cbor_mapget_string(pControl, "input");
	const cn_cbor *pFail = NULL;
	const cn_cbor *pMac = NULL;
	const cn_cbor *pRecipients = NULL;
	cn_cbor *pkey = NULL;	
	HCOSE_MAC0 hMAC = NULL;
	int type;
	bool fFail = false;
	bool fFailBody = false;
	bool fUnsuportedAlg = false;

	pFail = cn_cbor_mapget_string(pControl, "fail");
	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
		fFailBody = true;
	}

	hMAC = (HCOSE_MAC0)COSE_Decode(pbEncoded, cbEncoded, &type,
		COSE_mac0_object, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hMAC == NULL) {
		if (fFailBody) {
			return 0;
		}
		else {
			goto errorReturn;
		}
	}

	if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) {
		goto errorReturn;
	}
	pMac = cn_cbor_mapget_string(pInput, "mac0");
	if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP)) {
		goto errorReturn;
	}

	if (!SetReceivingAttributes((HCOSE)hMAC, pMac, Attributes_MAC0_protected)) {
		goto errorReturn;
	}

	pRecipients = cn_cbor_mapget_string(pMac, "recipients");
	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
		goto errorReturn;
	}

	pRecipients = pRecipients->first_child;

	pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"), true);
	if (pkey == NULL) {
		fFail = true;
		goto exitHere;
	}

	cn_cbor *k = cn_cbor_mapget_int(pkey, -1);

	cn_cbor *alg =
		COSE_Mac0_map_get_int(hMAC, COSE_Header_Algorithm, COSE_BOTH, NULL);
	if (!IsAlgorithmSupported(alg)) {
		fUnsuportedAlg = true;
	}

	pFail = cn_cbor_mapget_string(pRecipients, "fail");
	if (COSE_Mac0_validate(hMAC, k->v.bytes, k->length, NULL)) {
		if (fUnsuportedAlg) {
			fFail = true;
			fUnsuportedAlg = false;
		}
		else if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) {
			fFail = true;
		}
	}
	else {
		if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) {
			fFail = true;
		}
		if (fUnsuportedAlg) {
			fFail = false;
		}
	}

#if INCLUDE_COUNTERSIGNATURE
	//  Countersign on Mac0 Body

	//  Validate counter signatures on signers
	cn_cbor *countersignList = cn_cbor_mapget_string(pMac, "countersign");
	if (countersignList != NULL) {
		cn_cbor *countersigners =
			cn_cbor_mapget_string(countersignList, "signers");
		if (countersigners == NULL) {
			fFail = true;
			goto exitHere;
		}
		int count = countersigners->length;
		bool forward = true;

		if (COSE_Mac0_map_get_int(hMAC, COSE_Header_CounterSign,
				COSE_UNPROTECT_ONLY, 0) == NULL) {
			fFail = true;
			goto exitHere;
		}

		for (int counterNo = 0; counterNo < count; counterNo++) {
			bool noSignAlg = false;

			HCOSE_COUNTERSIGN h =
				COSE_Mac0_get_countersignature(hMAC, counterNo, 0);
			if (h == NULL) {
				fFail = true;
				continue;
			}

			cn_cbor *counterSigner = cn_cbor_index(
				countersigners, forward ? counterNo : count - counterNo - 1);

			cn_cbor *pkeyCountersign =
				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
			if (pkeyCountersign == NULL) {
				fFail = true;
				COSE_CounterSign_Free(h);
				continue;
			}

			if (!COSE_CounterSign_SetKey(h, pkeyCountersign, 0)) {
				fFail = true;
				COSE_CounterSign_Free(h);
				CN_CBOR_FREE(pkeyCountersign, context);
				continue;
			}

			alg = COSE_CounterSign_map_get_int(
				h, COSE_Header_Algorithm, COSE_BOTH, NULL);
			if (!IsAlgorithmSupported(alg)) {
				fUnsuportedAlg = true;
				noSignAlg = true;
			}

			if (COSE_Mac0_CounterSign_validate(hMAC, h, 0)) {
				//  I don't think we have any forced errors yet.
			}
			else {
				if (forward && counterNo == 0 && count > 1) {
					forward = false;
					counterNo -= 1;
				}
				else {
					fFail |= !noSignAlg;
				}
			}

			COSE_CounterSign_Free(h);
		}
	}
#endif

	if (fFailBody) {
		if (!fFail) {
			fFail = true;
		}
		else {
			fFail = false;
		}
	}

exitHere:
	if (pkey != NULL) {
		CN_CBOR_FREE(pkey, context);
	}
	if (hMAC != NULL) {
		COSE_Mac0_Free(hMAC);
	}

	if (fFail) {
		CFails += 1;
	}
	return fUnsuportedAlg ? 0 : 1;

errorReturn:
	if (hMAC != NULL) {
		COSE_Mac0_Free(hMAC);
	}
	CFails += 1;
	return (fFail || fUnsuportedAlg) ? 0 : 1;
}

int ValidateMac0(const cn_cbor *pControl)
{
	int cbEncoded;
	byte *pbEncoded = GetCBOREncoding(pControl, &cbEncoded);

	return _ValidateMac0(pControl, pbEncoded, cbEncoded);
}

int BuildMac0Message(const cn_cbor *pControl)
{
	cn_cbor *pkey = NULL;

	//
	//  We don't run this for all control sequences - skip those marked fail.
	//

	const cn_cbor *pFail = cn_cbor_mapget_string(pControl, "fail");
	if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
		return 0;
	}

	HCOSE_MAC0 hMacObj = COSE_Mac0_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);

	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
	if (pInputs == NULL) {
		goto returnError;
	}
	const cn_cbor *pMac = cn_cbor_mapget_string(pInputs, "mac0");
	if (pMac == NULL) {
		goto returnError;
	}

	const cn_cbor *pContent = cn_cbor_mapget_string(pInputs, "plaintext");
	if (!COSE_Mac0_SetContent(
			hMacObj, pContent->v.bytes, pContent->length, NULL)) {
		goto returnError;
	}

	if (!SetSendingAttributes(
			(HCOSE)hMacObj, pMac, Attributes_MAC0_protected)) {
		goto returnError;
	}

	const cn_cbor *pRecipients = cn_cbor_mapget_string(pMac, "recipients");
	if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) {
		goto returnError;
	}

	pRecipients = pRecipients->first_child;

	pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"), false);
	if (pkey == NULL) {
		goto returnError;
	}

	cn_cbor *k = cn_cbor_mapget_int(pkey, -1);

#if INCLUDE_COUNTERSIGNATURE
	// On the sign body
	cn_cbor *countersigns = cn_cbor_mapget_string(pMac, "countersign");
	if (countersigns != NULL) {
		countersigns = cn_cbor_mapget_string(countersigns, "signers");
		cn_cbor *countersign = countersigns->first_child;

		for (; countersign != NULL; countersign = countersign->next) {
			cn_cbor *pkeyCountersign =
				BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
			if (pkeyCountersign == NULL) {
				goto returnError;
			}

			HCOSE_COUNTERSIGN hCountersign =
				COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
			if (hCountersign == NULL) {
				goto returnError;
			}

			if (!SetSendingAttributes((HCOSE)hCountersign, countersign,
					Attributes_Countersign_protected)) {
				COSE_CounterSign_Free(hCountersign);
				goto returnError;
			}

			if (!COSE_CounterSign_SetKey(hCountersign, pkeyCountersign, NULL)) {
				COSE_CounterSign_Free(hCountersign);
				goto returnError;
			}

			if (!COSE_Mac0_add_countersignature(hMacObj, hCountersign, NULL)) {
				COSE_CounterSign_Free(hCountersign);
				goto returnError;
			}

			COSE_CounterSign_Free(hCountersign);
		}
	}

#endif

	if (!COSE_Mac0_encrypt(hMacObj, k->v.bytes, k->length, NULL)) {
		goto returnError;
	}

	size_t cb = COSE_Encode((HCOSE)hMacObj, NULL, 0, 0) + 1;
	byte *rgb = (byte *)malloc(cb);
	cb = COSE_Encode((HCOSE)hMacObj, rgb, 0, cb);

	COSE_Mac0_Free(hMacObj);
	CN_CBOR_FREE(pkey, context);

	int f = _ValidateMac0(pControl, rgb, cb);

	free(rgb);
	return f;

returnError:
	if (pkey != NULL) {
		CN_CBOR_FREE(pkey, context);
	}
	COSE_Mac0_Free(hMacObj);
	CFails += 1;
	return 1;
}
#endif

#if INCLUDE_MAC
void MAC_Corners()
{
	HCOSE_MAC hMAC = NULL;
	HCOSE_ENCRYPT hEncrypt = NULL;
	HCOSE_RECIPIENT hRecipient = NULL;
	byte rgb[10];
	cn_cbor *cn = cn_cbor_int_create(5, CBOR_CONTEXT_PARAM_COMMA NULL);
	cose_errback cose_error;

	//  Missing case - addref then release on item

	//  Incorrect algorithm

	hMAC = (HCOSE_MAC)COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);

	//  Invalid Handle checks

	if (COSE_Mac_SetContent((HCOSE_MAC)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac_map_get_int((HCOSE_MAC)hEncrypt, 1, COSE_BOTH, NULL)) {
		CFails++;
	}
	if (COSE_Mac_map_put_int(
			(HCOSE_MAC)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	if (COSE_Mac_encrypt((HCOSE_MAC)hEncrypt, NULL)) {
		CFails++;
	}
	if (COSE_Mac_validate((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
		CFails++;
	}
	if (COSE_Mac_AddRecipient(
			(HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
		CFails++;
	}
	if (COSE_Mac_GetRecipient((HCOSE_MAC)hEncrypt, 0, NULL)) {
		CFails++;
	}
	if (COSE_Mac_SetExternal((HCOSE_MAC)hEncrypt, rgb, 0, NULL)) {
		CFails++;
	}
	if (COSE_Mac_Free((HCOSE_MAC)hEncrypt)) {
		CFails++;
	}

#if INCLUDE_ENCRYPT0
	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
#else
	hEncrypt = (HCOSE_ENCRYPT)COSE_CALLOC(1, sizeof(COSE), context);
#endif

	if (COSE_Mac_SetContent((HCOSE_MAC)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac_map_get_int((HCOSE_MAC)hEncrypt, 1, COSE_BOTH, NULL)) {
		CFails++;
	}
	if (COSE_Mac_map_put_int(
			(HCOSE_MAC)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	if (COSE_Mac_encrypt((HCOSE_MAC)hEncrypt, NULL)) {
		CFails++;
	}
	if (COSE_Mac_validate((HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
		CFails++;
	}
	if (COSE_Mac_AddRecipient(
			(HCOSE_MAC)hEncrypt, (HCOSE_RECIPIENT)hMAC, NULL)) {
		CFails++;
	}
	if (COSE_Mac_GetRecipient((HCOSE_MAC)hEncrypt, 0, NULL)) {
		CFails++;
	}
	if (COSE_Mac_SetExternal((HCOSE_MAC)hEncrypt, rgb, 0, NULL)) {
		CFails++;
	}
	if (COSE_Mac_Free((HCOSE_MAC)hEncrypt)) {
		CFails++;
	}

	//
	//  Unsupported algorithm

	hMAC = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hMAC == NULL) {
		CFails++;
	}
	if (!COSE_Mac_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
		CFails++;
	}
	if (!COSE_Mac_map_put_int(hMAC, COSE_Header_Algorithm,
			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
			COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	hRecipient = COSE_Recipient_from_shared_secret(
		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hRecipient == NULL) {
		CFails++;
	}
	if (!COSE_Mac_AddRecipient(hMAC, hRecipient, NULL)) {
		CFails++;
	}
	CHECK_FAILURE(COSE_Mac_encrypt(hMAC, &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Mac_Free(hMAC);
	COSE_Recipient_Free(hRecipient);

	hMAC = COSE_Mac_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hMAC == NULL) {
		CFails++;
	}
	if (!COSE_Mac_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
		CFails++;
	}
	if (!COSE_Mac_map_put_int(hMAC, COSE_Header_Algorithm,
			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA NULL),
			COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	hRecipient = COSE_Recipient_from_shared_secret(
		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hRecipient == NULL) {
		CFails++;
	}
	if (!COSE_Mac_AddRecipient(hMAC, hRecipient, NULL)) {
		CFails++;
	}
	CHECK_FAILURE(COSE_Mac_encrypt(hMAC, &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Recipient_Free(hRecipient);
	COSE_Mac_Free(hMAC);

	if (COSE_Mac_GetRecipient(hMAC, 9, NULL)) {
		CFails++;
	}
}
#endif

#if INCLUDE_MAC0
void MAC0_Corners()
{
	HCOSE_ENCRYPT hEncrypt = NULL;
	HCOSE_MAC0 hMAC = NULL;
	byte rgb[10];
	cn_cbor *cn = cn_cbor_int_create(5, CBOR_CONTEXT_PARAM_COMMA NULL);
	cose_errback cose_error;

	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);

	//  Missing case - addref then release on item

	//  Invalid Handle checks

	if (COSE_Mac0_SetContent((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_map_get_int((HCOSE_MAC0)hEncrypt, 1, COSE_BOTH, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_map_put_int(
			(HCOSE_MAC0)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_encrypt((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_validate((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_SetExternal((HCOSE_MAC0)hEncrypt, rgb, 0, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_Free((HCOSE_MAC0)hEncrypt)) {
		CFails++;
	}

	hEncrypt = COSE_Encrypt_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);

	if (COSE_Mac0_SetContent((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_map_get_int((HCOSE_MAC0)hEncrypt, 1, COSE_BOTH, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_map_put_int(
			(HCOSE_MAC0)hEncrypt, 1, cn, COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_encrypt((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_validate((HCOSE_MAC0)hEncrypt, rgb, 10, NULL)) {
		CFails++;
	}
	if (COSE_Mac0_SetExternal((HCOSE_MAC0)hEncrypt, rgb, 0, NULL)) {
		CFails++;
	}

	if (COSE_Mac0_Free((HCOSE_MAC0)hEncrypt)) {
		CFails++;
	}

	//
	//  Unsupported algorithm

	hMAC = COSE_Mac0_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hMAC == NULL) {
		CFails++;
	}
	if (!COSE_Mac0_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
		CFails++;
	}
	if (!COSE_Mac0_map_put_int(hMAC, COSE_Header_Algorithm,
			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA NULL),
			COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	CHECK_FAILURE(COSE_Mac0_encrypt(hMAC, rgb, sizeof(rgb), &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Mac0_Free(hMAC);

	hMAC = COSE_Mac0_Init(0, CBOR_CONTEXT_PARAM_COMMA NULL);
	if (hMAC == NULL) {
		CFails++;
	}
	if (!COSE_Mac0_SetContent(hMAC, (byte *)"Message", 7, NULL)) {
		CFails++;
	}
	if (!COSE_Mac0_map_put_int(hMAC, COSE_Header_Algorithm,
			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA NULL),
			COSE_PROTECT_ONLY, NULL)) {
		CFails++;
	}
	CHECK_FAILURE(COSE_Mac0_encrypt(hMAC, rgb, sizeof(rgb), &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Mac0_Free(hMAC);
}
#endif
