#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)) {
			COSE_Recipient_Free(hRecip);
			goto failTest;
		}

		if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
			fFail = true;
			COSE_Recipient_Free(hRecip);
			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) {
				COSE_Recipient_Free(hRecip);
				goto failTest;
			}
			int count = countersigners->length;
			bool forward = true;

			if (COSE_Recipient_map_get_int(hRecip, COSE_Header_CounterSign,
					COSE_UNPROTECT_ONLY, 0) == NULL) {
				COSE_Recipient_Free(hRecip);
				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
