#define _CRT_SECURE_NO_WARNINGS

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <memory>
#include <cose/cose.h>
#include <cose/cose_configure.h>
#include <cn-cbor/cn-cbor.h>
#if (INCLUDE_ENCRYPT || INCLUDE_ENCRYPT0 || INCLUDE_MAC) && \
	(!INCLUDE_MAC || !INCLUDE_SIGN)
#include <cose_int.h>
#endif
#include "test.h"
#include "context.h"
#include "cose_int.h"
#include "utils.hpp"

using namespace cose;

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

#if INCLUDE_ENCRYPT
//  Return 1=expected failure, 0 = failure, 2 = success
int DecryptMessage(const byte *pbEncoded,
	size_t cbEncoded,
	bool fFailBody,
	const cn_cbor *pEnveloped,
	const cn_cbor *pRecipient1,
	int iRecipient1,
	const cn_cbor *pRecipient2,
	int iRecipient2)
{
	int type = 0;
	cose_errback cose_err;
	bool fNoSupport = false;
	int returnValue = 2;

	Safe_HCOSE_ENVELOPED hEnc =
		reinterpret_cast<HCOSE_ENVELOPED>(COSE_Decode(pbEncoded, cbEncoded,
			&type, COSE_enveloped_object, CBOR_CONTEXT_PARAM_COMMA & cose_err));
	if (hEnc.IsNull()) {
		if (fFailBody && (cose_err.err == COSE_ERR_INVALID_PARAMETER)) {
			return 1;
		}
		return 0;
	}

	if (!SetReceivingAttributes(
			hEnc, pEnveloped, Attributes_Enveloped_protected)) {
		return 0;
	}

	cn_cbor *alg = COSE_Enveloped_map_get_int(
		hEnc, COSE_Header_Algorithm, COSE_BOTH, nullptr);
	if (!IsAlgorithmSupported(alg)) {
		fNoSupport = true;
	}

	Safe_HCOSE_RECIPIENT hRecip =
		COSE_Enveloped_GetRecipient(hEnc, iRecipient1, nullptr);
	if (hRecip.IsNull()) {
		return 0;
	}
	if (!SetReceivingAttributes(
			hRecip, pRecipient1, Attributes_Recipient_protected)) {
		return 0;
	}

	if (pRecipient2 != nullptr) {
		Safe_HCOSE_KEY hkey =
			BuildKey(cn_cbor_mapget_string(pRecipient2, "key"), false);
		if (hkey == nullptr) {
			return 0;
		}

		Safe_HCOSE_RECIPIENT hRecip2 =
			COSE_Recipient_GetRecipient(hRecip, iRecipient2, nullptr);
		if (hRecip2.IsNull()) {
			return 0;
		}

		if (!SetReceivingAttributes(
				hRecip2, pRecipient2, Attributes_Recipient_protected)) {
			return 0;
		}
		if (!COSE_Recipient_SetKey2(hRecip2, hkey, nullptr)) {
			return 0;
		}

		cn_cbor *cnStatic = cn_cbor_mapget_string(pRecipient2, "sender_key");
		if (cnStatic != nullptr) {
			if (COSE_Recipient_map_get_int(hRecip2, COSE_Header_ECDH_SPK,
					COSE_BOTH, nullptr) == nullptr) {
				Safe_HCOSE_KEY senderKey = BuildKey(cnStatic, true);
				if (senderKey == nullptr) {
					return 0;
				}
				if (!COSE_Recipient_SetSenderKey2(
						hRecip2, senderKey, COSE_DONT_SEND, nullptr)) {
					return 0;
				}
			}
		}

		hRecip.Transfer(&hRecip2);
	}
	else {
		Safe_HCOSE_KEY hkey =
			BuildKey(cn_cbor_mapget_string(pRecipient1, "key"), false);
		if (hkey == nullptr) {
			return 0;
		}
		if (!COSE_Recipient_SetKey2(hRecip, hkey, nullptr)) {
			return 0;
		}

		cn_cbor *cnStatic = cn_cbor_mapget_string(pRecipient1, "sender_key");
		if (cnStatic != nullptr) {
			if (COSE_Recipient_map_get_int(hRecip, COSE_Header_ECDH_SPK,
					COSE_BOTH, nullptr) == nullptr) {
				Safe_HCOSE_KEY senderKey = BuildKey(cnStatic, true);
				if (senderKey == nullptr) {
					return 0;
				}
				if (!COSE_Recipient_SetSenderKey2(
						hRecip, senderKey, COSE_DONT_SEND, nullptr)) {
					return 0;
				}
			}
		}
	}

	if (!fFailBody) {
		cn_cbor *cn = cn_cbor_mapget_string(pRecipient1, "fail");
		if (cn != nullptr && (cn->type == CN_CBOR_TRUE)) {
			fFailBody = true;
		}
		if (fFailBody && (pRecipient2 != nullptr)) {
			cn = cn_cbor_mapget_string(pRecipient2, "fail");
			if (cn != nullptr && (cn->type == CN_CBOR_TRUE)) {
				fFailBody = true;
			}
		}
	}

	if (COSE_Enveloped_decrypt(hEnc, hRecip, &cose_err)) {
		returnValue = COSE_MIN(fFailBody ? 1 : 2, returnValue);
	}
	else {
		if (cose_err.err == COSE_ERR_NO_COMPRESSED_POINTS ||
			cose_err.err == COSE_ERR_UNKNOWN_ALGORITHM) {
			returnValue = COSE_MIN(1, returnValue);
		}
		else if (fNoSupport) {
			returnValue = 0;
		}
		else {
			returnValue = COSE_MIN(fFailBody ? 1 : 0, returnValue);
		}
	}

#if INCLUDE_COUNTERSIGNATURE
	{
		//  Countersign on Recipient Body

		//  Validate counter signatures on signers
		cn_cbor *countersignList =
			cn_cbor_mapget_string(pRecipient1, "countersign");
		if (countersignList != nullptr) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == nullptr) {
				return 0;
			}
			const int count = (int)countersigners->length;
			bool forward = true;

			if (COSE_Recipient_map_get_int(hRecip, COSE_Header_CounterSign,
					COSE_UNPROTECT_ONLY, nullptr) == nullptr) {
				return 0;
			}

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

				Safe_HCOSE_COUNTERSIGN h = COSE_Recipient_get_countersignature(
					hRecip, counterNo, nullptr);
				if (h.IsNull()) {
					returnValue = 0;
					continue;
				}

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

				Safe_HCOSE_KEY hkeyCountersign = BuildKey(
					cn_cbor_mapget_string(counterSigner, "key"), false);
				if (hkeyCountersign == nullptr) {
					returnValue = 0;
					continue;
				}

				if (!COSE_CounterSign_SetKey2(h, hkeyCountersign, nullptr)) {
					returnValue = 0;
					continue;
				}

				cose_errback coseError;

				if (COSE_Recipient_CounterSign_validate(
						hRecip, h, &coseError)) {
					//  I don't think we have any forced errors yet.
				}
				else {
					if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
						returnValue = COSE_MIN(1, returnValue);
						continue;
					}

					if (forward && counterNo == 0 && count > 1) {
						forward = false;
						counterNo -= 1;
						continue;
					}
					returnValue = 0;
				}
			}
		}
	}
#endif

#if INCLUDE_COUNTERSIGNATURE1
	{
		//  Countersign1 on Recipient Body

		//  Validate counter signatures on signers
		const cn_cbor *countersignList =
			cn_cbor_mapget_string(pRecipient1, "countersign0");
		if (countersignList != nullptr) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == nullptr) {
				return 0;
			}

			if (COSE_Recipient_map_get_int(hRecip, COSE_Header_CounterSign1,
					COSE_UNPROTECT_ONLY, nullptr) == nullptr) {
				return 0;
			}

			Safe_HCOSE_COUNTERSIGN1 h(
				COSE_Recipient_get_countersignature1(hRecip, nullptr));
			if (h.IsNull()) {
				return 0;
			}

			cn_cbor *counterSigner = cn_cbor_index(countersigners, 0);

			Safe_HCOSE_KEY hkeyCountersign =
				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false);
			if (hkeyCountersign == nullptr) {
				return 0;
			}

			if (!COSE_CounterSign1_SetKey(h, hkeyCountersign, nullptr)) {
				return 0;
			}

			if (!SetReceivingAttributes(h, counterSigner, Attributes_Countersign1_protected)) {
				return 0;
			}

			cose_errback coseError;
			if (COSE_Recipient_CounterSign1_validate(hRecip, h, &coseError)) {
				//  I don't think we have any forced errors yet.
			}
			else {
				if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
					returnValue = COSE_MIN(1, returnValue);
				}
				else {
					returnValue = 0;
				}
			}
		}
	}
#endif

#if INCLUDE_COUNTERSIGNATURE
	{
		//  Countersign on Enveloped Body

		//  Validate counter signatures on signers
		const cn_cbor *countersignList =
			cn_cbor_mapget_string(pEnveloped, "countersign");
		if (countersignList != nullptr) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == nullptr) {
				return 0;
			}
			const int count = (int)countersigners->length;
			bool forward = true;

			if (COSE_Enveloped_map_get_int(hEnc, COSE_Header_CounterSign,
					COSE_UNPROTECT_ONLY, nullptr) == nullptr) {
				return false;
			}

			for (int counterNo = 0; counterNo < count; counterNo++) {
				Safe_HCOSE_COUNTERSIGN h = COSE_Enveloped_get_countersignature(
					hEnc, counterNo, nullptr);
				if (h == nullptr) {
					return 0;
				}

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

				Safe_HCOSE_KEY hkeyCountersign = BuildKey(
					cn_cbor_mapget_string(counterSigner, "key"), false);
				if (hkeyCountersign == nullptr) {
					returnValue = 0;
					continue;
				}

				if (!COSE_CounterSign_SetKey2(h, hkeyCountersign, nullptr)) {
					returnValue = 0;
					continue;
				}

				cose_errback coseError;

				if (COSE_Enveloped_CounterSign_validate(hEnc, h, &coseError)) {
					//  I don't think we have any forced errors yet.
				}
				else {
					if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
						returnValue = COSE_MIN(1, returnValue);
						continue;
					}

					if (forward && counterNo == 0 && count > 1) {
						forward = false;
						counterNo -= 1;
						continue;
					}

					returnValue = 0;
				}
			}
		}
	}
#endif

#if INCLUDE_COUNTERSIGNATURE1
	{
		//  Countersign1 on Enveloped Body

		//  Validate counter signatures on signers
		const cn_cbor *countersignList =
			cn_cbor_mapget_string(pEnveloped, "countersign0");
		if (countersignList != nullptr) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == nullptr) {
				return 0;
			}

			if (COSE_Enveloped_map_get_int(hEnc, COSE_Header_CounterSign1,
					COSE_UNPROTECT_ONLY, nullptr) == nullptr) {
				return 0;
			}

			bool noSupportSign = false;
			Safe_HCOSE_COUNTERSIGN1 h =
				COSE_Enveloped_get_countersignature1(hEnc, nullptr);
			if (h.IsNull()) {
				return 0;
			}

			cn_cbor *counterSigner = cn_cbor_index(countersigners, 0);

			Safe_HCOSE_KEY hkeyCountersign(
				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false));
			if (hkeyCountersign == nullptr) {
				return 0;
			}

			if (!COSE_CounterSign1_SetKey(h, hkeyCountersign, nullptr)) {
				return false;
			}

			if (!SetReceivingAttributes(
					h, counterSigner, Attributes_Countersign1_protected)) {
				return false;
			}

			cose_errback coseError;
			if (COSE_Enveloped_CounterSign1_validate(hEnc, h, &coseError)) {
				//  I don't think we have any forced errors yet.
			}
			else {
				if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
					returnValue = COSE_MIN(1, returnValue);
				}
				else {
					returnValue = 0;
				}
			}
		}
	}
#endif

	if (returnValue == 0) {
		CFails++;
	}
	return returnValue;
}

//  Return 1=expected failure, 0 = failure, 2 = success
int _ValidateEnveloped(const cn_cbor *pControl,
	const byte *pbEncoded,
	size_t cbEncoded)
{
	const cn_cbor *pInput = cn_cbor_mapget_string(pControl, "input");
	bool fFailBody = false;
	int passCount = 0;
	int returnValue = 2;

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

	if ((pInput == nullptr) || (pInput->type != CN_CBOR_MAP)) {
		return 0;
	}

	const cn_cbor *pEnveloped = cn_cbor_mapget_string(pInput, "enveloped");
	if ((pEnveloped == nullptr) || (pEnveloped->type != CN_CBOR_MAP)) {
		return 0;
	}

	const cn_cbor *pRecipients =
		cn_cbor_mapget_string(pEnveloped, "recipients");
	if ((pRecipients == nullptr) || (pRecipients->type != CN_CBOR_ARRAY)) {
		return 0;
	}

	int iRecipient = static_cast<int>(pRecipients->length) - 1;
	pRecipients = pRecipients->first_child;
	for (; pRecipients != nullptr;
		 iRecipient--, pRecipients = pRecipients->next) {
		const cn_cbor *pRecip2 =
			cn_cbor_mapget_string(pRecipients, "recipients");
		if (pRecip2 == nullptr) {
			int value = DecryptMessage(pbEncoded, cbEncoded, fFailBody,
				pEnveloped, pRecipients, iRecipient, nullptr, 0);
			returnValue = COSE_MIN(value, returnValue);
		}
		else {
			int iRecipient2 = static_cast<int>(pRecip2->length - 1);
			pRecip2 = pRecip2->first_child;
			for (; pRecip2 != nullptr; pRecip2 = pRecip2->next, iRecipient2--) {
				int value = DecryptMessage(pbEncoded, cbEncoded, fFailBody,
					pEnveloped, pRecipients, iRecipient, pRecip2, iRecipient2);
				returnValue = COSE_MIN(value, returnValue);
			}
		}
	}
	return returnValue;
}

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

	int i = _ValidateEnveloped(pControl, pbEncoded, cbEncoded);
	if (i == 0) {
		CFails += 1;
	}
	return i == 2;
}

HCOSE_RECIPIENT BuildRecipient(const cn_cbor *pRecipient)
{
	Safe_HCOSE_RECIPIENT hRecip = COSE_Recipient_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hRecip == nullptr) {
		return nullptr;
	}

	if (!SetSendingAttributes(
			hRecip, pRecipient, Attributes_Recipient_protected)) {
		return nullptr;
	}

	cn_cbor *cnKey = cn_cbor_mapget_string(pRecipient, "key");
	if (cnKey != nullptr) {
		Safe_HCOSE_KEY hkey = BuildKey(cnKey, true);
		if (hkey == nullptr) {
			return nullptr;
		}

		if (!COSE_Recipient_SetKey2(hRecip, hkey, nullptr)) {
			return nullptr;
		}
	}

	cnKey = cn_cbor_mapget_string(pRecipient, "recipients");
	if (cnKey != nullptr) {
		for (cnKey = cnKey->first_child; cnKey != nullptr;
			 cnKey = cnKey->next) {
			Safe_HCOSE_RECIPIENT hRecip2 = BuildRecipient(cnKey);
			if (hRecip2 == nullptr) {
				return nullptr;
			}
			if (!COSE_Recipient_AddRecipient(hRecip, hRecip2, nullptr)) {
				return nullptr;
			}
		}
	}

	cn_cbor *pSenderKey = cn_cbor_mapget_string(pRecipient, "sender_key");
	if (pSenderKey != nullptr) {
		Safe_HCOSE_KEY hSendKey = BuildKey(pSenderKey, false);
		cn_cbor *pKid = cn_cbor_mapget_string(pSenderKey, "kid");
		if (!COSE_Recipient_SetSenderKey2(
				hRecip, hSendKey, (pKid == nullptr) ? 2 : 1, nullptr)) {
			return nullptr;
		}
	}

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

			for (; countersign != nullptr; countersign = countersign->next) {
				Safe_HCOSE_KEY hkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (hkeyCountersign == nullptr) {
					return nullptr;
				}

				Safe_HCOSE_COUNTERSIGN hCountersign =
					COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA nullptr);
				if (hCountersign == nullptr) {
					return nullptr;
				}

				if (!SetSendingAttributes(hCountersign, countersign,
						Attributes_Countersign_protected)) {
					return nullptr;
				}

				if (!COSE_CounterSign_SetKey2(
						hCountersign, hkeyCountersign, nullptr)) {
					return nullptr;
				}

				if (!COSE_Recipient_add_countersignature(
						hRecip, hCountersign, nullptr)) {
					return nullptr;
				}
			}
		}
	}

#endif

#if INCLUDE_COUNTERSIGNATURE1
	{
		// On the Recipient
		cn_cbor *countersigns2 =
			cn_cbor_mapget_string(pRecipient, "countersign0");
		if (countersigns2 != nullptr) {
			countersigns2 = cn_cbor_mapget_string(countersigns2, "signers");
			cn_cbor *countersign = countersigns2->first_child;

			for (; countersign != nullptr; countersign = countersign->next) {
				Safe_HCOSE_KEY hkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (hkeyCountersign == nullptr) {
					return nullptr;
				}

				Safe_HCOSE_COUNTERSIGN1 hCountersign1;
				hCountersign1.Set(
					COSE_CounterSign1_Init(CBOR_CONTEXT_PARAM_COMMA nullptr));
				if (hCountersign1.IsNull()) {
					return nullptr;
				}

				if (!SetSendingAttributes(hCountersign1, countersign,
						Attributes_Countersign1_protected)) {
					return nullptr;
				}

				if (!COSE_CounterSign1_SetKey(
						hCountersign1, hkeyCountersign, nullptr)) {
					return nullptr;
				}

				if (!COSE_Recipient_add_countersignature1(
						hRecip, hCountersign1, nullptr)) {
					return nullptr;
				}
			}
		}
	}
#endif

	HCOSE_RECIPIENT r = hRecip;
	hRecip.Clear();
	return r;
}

bool BuildEnvelopedMessage(const cn_cbor *pControl)
{
	//
	//  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 != nullptr) && (pFail->type == CN_CBOR_TRUE)) {
	returnError:
		CFails += 1;
		return false;
	}

	Safe_HCOSE_ENVELOPED hEncObj = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);

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

	const cn_cbor *pEnveloped = cn_cbor_mapget_string(pInputs, "enveloped");
	if (pEnveloped == nullptr) {
		goto returnError;
	}

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

	if (!SetSendingAttributes(
			hEncObj, pEnveloped, Attributes_Enveloped_protected)) {
		goto returnError;
	}

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

	pRecipients = pRecipients->first_child;
	for (int iRecipient = 0; pRecipients != nullptr;
		 iRecipient++, pRecipients = pRecipients->next) {
		Safe_HCOSE_RECIPIENT hRecip = BuildRecipient(pRecipients);
		if (hRecip == nullptr) {
			goto returnError;
		}

		if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, nullptr)) {
			goto returnError;
		}

		
	}

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

			for (; countersign != nullptr; countersign = countersign->next) {
				Safe_HCOSE_KEY hkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (hkeyCountersign == nullptr) {
					goto returnError;
				}

				Safe_HCOSE_COUNTERSIGN hCountersign =
					COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA nullptr);

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

				if (!COSE_CounterSign_SetKey2(
						hCountersign, hkeyCountersign, nullptr)) {
					goto returnError;
				}

				if (!COSE_Enveloped_add_countersignature(
						hEncObj, hCountersign, nullptr)) {
					goto returnError;
				}
			}
		}
	}
#endif

#if INCLUDE_COUNTERSIGNATURE1
	{
		// On the Enveloped body
		cn_cbor *countersigns2 =
			cn_cbor_mapget_string(pEnveloped, "countersign0");
		if (countersigns2 != nullptr) {
			countersigns2 = cn_cbor_mapget_string(countersigns2, "signers");
			cn_cbor *countersign = countersigns2->first_child;

			for (; countersign != nullptr; countersign = countersign->next) {
				Safe_HCOSE_KEY hkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (hkeyCountersign == nullptr) {
					goto returnError;
				}

				Safe_HCOSE_COUNTERSIGN1 hCountersign1 =
					COSE_CounterSign1_Init(CBOR_CONTEXT_PARAM_COMMA nullptr);
				if (hCountersign1.IsNull()) {
					goto returnError;
				}

				if (!SetSendingAttributes(hCountersign1, countersign,
						Attributes_Countersign1_protected)) {
					goto returnError;
				}

				if (!COSE_CounterSign1_SetKey(
						hCountersign1, hkeyCountersign, nullptr)) {
					goto returnError;
				}

				if (!COSE_Enveloped_add_countersignature1(
						hEncObj, hCountersign1, nullptr)) {
					goto returnError;
				}
			}
		}
	}
#endif

	if (!COSE_Enveloped_encrypt(hEncObj, nullptr)) {
		goto returnError;
	}

	size_t cb = COSE_Encode(hEncObj.ToCOSE(), nullptr, 0, 0) + 1;
	std::unique_ptr<byte> rgb(new byte[cb]);
	cb = COSE_Encode(hEncObj.ToCOSE(), rgb.get(), 0, cb);

	hEncObj = nullptr;

	int f = _ValidateEnveloped(pControl, rgb.get(), cb);
	if (f == 0) {
		CFails += 1;
	}
	return f == 2;
}

int EncryptMessage()
{
	Safe_HCOSE_ENVELOPED hEncObj = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	byte rgbSecret[128 / 8] = {'a', 'b', 'c'};
	int cbSecret = 128 / 8;
	byte rgbKid[15] = {'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'l',
		'm', 'n', 'o', 'p'};
	int cbKid = 6;
	size_t cb;
	const char *sz = "This is the content to be used";

	if (hEncObj == nullptr) {
	errorReturn:
		CFails++;
		return 0;
	}
	if (!COSE_Enveloped_map_put_int(hEncObj, COSE_Header_Algorithm,
			cn_cbor_int_create(COSE_Algorithm_AES_CCM_16_64_128,
				CBOR_CONTEXT_PARAM_COMMA nullptr),
			COSE_PROTECT_ONLY, nullptr)) {
		goto errorReturn;
	}
	if (!COSE_Enveloped_SetContent(
			hEncObj, (const byte *)sz, strlen(sz), nullptr)) {
		goto errorReturn;
	}
	if (!COSE_Enveloped_map_put_int(hEncObj, COSE_Header_IV,
			cn_cbor_data_create(rgbKid, 13, CBOR_CONTEXT_PARAM_COMMA nullptr),
			COSE_UNPROTECT_ONLY, nullptr)) {
		goto errorReturn;
	}

	Safe_HCOSE_RECIPIENT hRecip = COSE_Recipient_from_shared_secret(
		rgbSecret, cbSecret, rgbKid, cbKid, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hRecip == nullptr) {
		goto errorReturn;
	}
	if (!COSE_Enveloped_AddRecipient(hEncObj, hRecip, nullptr)) {
		goto errorReturn;
	}

	if (!COSE_Enveloped_encrypt(hEncObj, nullptr)) {
		goto errorReturn;
	}

	cb = COSE_Encode(hEncObj.ToCOSE(), nullptr, 0, 0);
	if (cb < 1) {
		goto errorReturn;
	}
	std::unique_ptr<byte> rgb(new byte[cb]);
	cb = COSE_Encode(hEncObj.ToCOSE(), rgb.get(), 0, cb);
	if (cb < 1) {
		goto errorReturn;
	}

	hRecip = nullptr;
	hEncObj = nullptr;

	/* */

	int typ;
	hEncObj = (HCOSE_ENVELOPED)COSE_Decode(rgb.get(), (int)cb, &typ,
		COSE_enveloped_object, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hEncObj == nullptr) {
		goto errorReturn;
	}

	int iRecipient = 0;
	do {
		hRecip = COSE_Enveloped_GetRecipient(hEncObj, iRecipient, nullptr);
		if (hRecip == nullptr) {
			break;
		}

		if (!COSE_Recipient_SetKey_secret(
				hRecip, rgbSecret, cbSecret, nullptr, 0, nullptr)) {
			goto errorReturn;
		}

		if (!COSE_Enveloped_decrypt(hEncObj, hRecip, nullptr)) {
			goto errorReturn;
		}

		hRecip = nullptr;

		iRecipient += 1;

	} while (true);

	return 1;
}
#endif

/********************************************/
#if INCLUDE_ENCRYPT0

//  Return 1=expected failure, 0 = failure, 2 = success
int _ValidateEncrypt(const cn_cbor *pControl,
	const byte *pbEncoded,
	size_t cbEncoded,
	cn_cbor *pcnEncoded)
{
	const cn_cbor *pInput = cn_cbor_mapget_string(pControl, "input");
	const cn_cbor *pFail = nullptr;
	const cn_cbor *pEncrypt = nullptr;
	const cn_cbor *pRecipients = nullptr;
	int type;
	bool fFail = false;
	bool fFailBody = false;
	bool fAlgSupport = true;
	int returnValue = 2;

	if (false) {
	returnError:
		CFails += 1;
		return 0;
	}

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

	if ((pInput == nullptr) || (pInput->type != CN_CBOR_MAP)) {
		return 0;
	}
	pEncrypt = cn_cbor_mapget_string(pInput, "encrypted");
	if ((pEncrypt == nullptr) || (pEncrypt->type != CN_CBOR_MAP)) {
		return 0;
	}

	pRecipients = cn_cbor_mapget_string(pEncrypt, "recipients");
	if ((pRecipients == nullptr) || (pRecipients->type != CN_CBOR_ARRAY)) {
		return 0;
	}

	pRecipients = pRecipients->first_child;

	Safe_HCOSE_ENCRYPT hEnc;

	if (pcnEncoded == nullptr) {
		hEnc = (HCOSE_ENCRYPT)COSE_Decode(pbEncoded, cbEncoded, &type,
			COSE_encrypt_object, CBOR_CONTEXT_PARAM_COMMA nullptr);
		if (hEnc == nullptr) {
			if (fFailBody) {
				return 1;
			}
			return 0;
		}
	}
	else {
		hEnc = COSE_Encrypt_Init_From_Object(
			pcnEncoded, CBOR_CONTEXT_PARAM_COMMA nullptr);
		if (hEnc == nullptr) {
			if (fFailBody) {
				return 1;
			}
			return 0;
		}
	}

	if (!SetReceivingAttributes(hEnc, pEncrypt, Attributes_Encrypt_protected)) {
		return 0;
	}

	Safe_CN_CBOR pkey =
		BuildCborKey(cn_cbor_mapget_string(pRecipients, "key"), true);
	if (pkey == nullptr) {
		return 0;
	}

	cn_cbor *k = cn_cbor_mapget_int(pkey, -1);
	if (k == nullptr) {
		return 0;
	}

	pFail = cn_cbor_mapget_string(pRecipients, "fail");
	cose_errback coseError;
	if (COSE_Encrypt_decrypt(hEnc, k->v.bytes, k->length, &coseError)) {
		if ((pFail != nullptr) && (pFail->type != CN_CBOR_TRUE)) {
			returnValue = 0;
		}

		size_t cb;
		const byte *pb = COSE_Encrypt_GetContent(hEnc, &cb, nullptr);
		// M00TODO - compare content?
	}
	else {
		if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
			returnValue = COSE_MIN(1, returnValue);
		}
		else if (fFailBody) {
			returnValue = COSE_MIN(1, returnValue);
		}
		else if ((pFail != nullptr) && (pFail->type == CN_CBOR_FALSE)) {
			returnValue = COSE_MIN(1, returnValue);
		}
		else {
			returnValue = 0;
		}
	}

#if INCLUDE_COUNTERSIGNATURE
	{
		//  Countersign on Encrypt0 Body

		//  Validate counter signatures on signers
		cn_cbor *countersignList =
			cn_cbor_mapget_string(pEncrypt, "countersign");
		if (countersignList != nullptr) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == nullptr) {
				return 0;
			}
			const int count = (int)countersigners->length;
			bool forward = true;

			if (COSE_Encrypt_map_get_int(hEnc, COSE_Header_CounterSign,
					COSE_UNPROTECT_ONLY, nullptr) == nullptr) {
				goto returnError;
			}

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

				Safe_HCOSE_COUNTERSIGN h = COSE_Encrypt0_get_countersignature(
					hEnc, counterNo, nullptr);
				if (h == nullptr) {
					fFail = true;
					continue;
				}

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

				Safe_HCOSE_KEY hkeyCountersign = BuildKey(
					cn_cbor_mapget_string(counterSigner, "key"), false);
				if (hkeyCountersign == nullptr) {
					returnValue = 0;
					continue;
				}

				if (!COSE_CounterSign_SetKey2(h, hkeyCountersign, nullptr)) {
					fFail = true;
					continue;
				}

				if (COSE_Encrypt0_CounterSign_validate(hEnc, h, &coseError)) {
					//  I don't think we have any forced errors yet.
				}
				else {
					if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
						returnValue = COSE_MIN(1, returnValue);
					}
					else if (forward && counterNo == 0 && count > 1) {
						forward = false;
						counterNo -= 1;
					}
					else {
						returnValue = 0;
					}
				}
			}
		}
	}
#endif
#if INCLUDE_COUNTERSIGNATURE1
	{
		//  Countersign1 on Enveloped Body

		//  Validate counter signatures on signers
		const cn_cbor *countersignList =
			cn_cbor_mapget_string(pEncrypt, "countersign0");
		if (countersignList != nullptr) {
			cn_cbor *countersigners =
				cn_cbor_mapget_string(countersignList, "signers");
			if (countersigners == nullptr) {
				return 0;
			}

			if (COSE_Encrypt_map_get_int(hEnc, COSE_Header_CounterSign1,
					COSE_UNPROTECT_ONLY, nullptr) == nullptr) {
				return 0;
			}

			bool noSupportSign = false;
			Safe_HCOSE_COUNTERSIGN1 h =
				COSE_Encrypt0_get_countersignature1(hEnc, nullptr);
			if (h.IsNull()) {
				return 0;
			}

			cn_cbor *counterSigner = cn_cbor_index(countersigners, 0);

			Safe_HCOSE_KEY hkeyCountersign(
				BuildKey(cn_cbor_mapget_string(counterSigner, "key"), false));
			if (hkeyCountersign == nullptr) {
				return 0;
			}

			if (!COSE_CounterSign1_SetKey(h, hkeyCountersign, nullptr)) {
				return false;
			}

			if (!SetReceivingAttributes(
					h, counterSigner, Attributes_Countersign1_protected)) {
				return false;
			}

			if (COSE_Encrypt0_CounterSign1_validate(hEnc, h, &coseError)) {
				//  I don't think we have any forced errors yet.
			}
			else {
				if (coseError.err == COSE_ERR_UNKNOWN_ALGORITHM) {
					returnValue = COSE_MIN(1, returnValue);
				}
				else {
					returnValue = 0;
				}
			}
		}
	}
#endif

	return returnValue;
}

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

	int fRet = _ValidateEncrypt(pControl, pbEncoded, cbEncoded, nullptr);
	if (fRet == 0) {
		CFails += 1;
	}
	if (fRet != 2) {
		return false;
	}

	cn_cbor *cbor =
		cn_cbor_decode(pbEncoded, cbEncoded, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (cbor == nullptr) {
		return false;
	}

	fRet = _ValidateEncrypt(pControl, nullptr, 0, cbor);
	if (fRet == 0) {
		CFails += 1;
	}
	return fRet == 2;
}

bool BuildEncryptMessage(const cn_cbor *pControl)
{
	//
	//  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 != nullptr) && (pFail->type == CN_CBOR_TRUE)) {
		return false;
	}

	Safe_HCOSE_ENCRYPT hEncObj = COSE_Encrypt_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);

	const cn_cbor *pInputs = cn_cbor_mapget_string(pControl, "input");
	if (pInputs == nullptr) {
	returnError:
		CFails += 1;
		return false;
	}

	const cn_cbor *pEncrypt = cn_cbor_mapget_string(pInputs, "encrypted");
	if (pEncrypt == nullptr) {
		goto returnError;
	}

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

	if (!SetSendingAttributes(
			hEncObj, pEncrypt, Attributes_Encrypt_protected)) {
		goto returnError;
	}

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

	pRecipients = pRecipients->first_child;
	Safe_CN_CBOR pkey =
		BuildCborKey(cn_cbor_mapget_string(pRecipients, "key"), false);
	if (pkey == nullptr) {
		goto returnError;
	}

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

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

			for (; countersign != nullptr; countersign = countersign->next) {
				Safe_HCOSE_KEY hkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (hkeyCountersign == nullptr) {
					goto returnError;
				}

				Safe_HCOSE_COUNTERSIGN hCountersign =
					COSE_CounterSign_Init(CBOR_CONTEXT_PARAM_COMMA nullptr);
				if (hCountersign == nullptr) {
					goto returnError;
				}

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

				if (!COSE_CounterSign_SetKey2(
						hCountersign, hkeyCountersign, nullptr)) {
					goto returnError;
				}

				if (!COSE_Encrypt0_add_countersignature(
						hEncObj, hCountersign, nullptr)) {
					goto returnError;
				}
			}
		}
	}
#endif

#if INCLUDE_COUNTERSIGNATURE1
	{
		// On the Encrypt0 body
		cn_cbor *countersigns = cn_cbor_mapget_string(pEncrypt, "countersign0");
		if (countersigns != nullptr) {
			countersigns = cn_cbor_mapget_string(countersigns, "signers");
			cn_cbor *countersign = countersigns->first_child;

			for (; countersign != nullptr; countersign = countersign->next) {
				Safe_HCOSE_KEY hkeyCountersign =
					BuildKey(cn_cbor_mapget_string(countersign, "key"), false);
				if (hkeyCountersign == nullptr) {
					goto returnError;
				}

				Safe_HCOSE_COUNTERSIGN1 hCountersign =
					COSE_CounterSign1_Init(CBOR_CONTEXT_PARAM_COMMA nullptr);
				if (hCountersign == nullptr) {
					goto returnError;
				}

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

				if (!COSE_CounterSign1_SetKey(
						hCountersign, hkeyCountersign, nullptr)) {
					goto returnError;
				}

				if (!COSE_Encrypt0_add_countersignature1(
						hEncObj, hCountersign, nullptr)) {
					goto returnError;
				}
			}
		}
	}
#endif

	if (!COSE_Encrypt_encrypt(hEncObj, k->v.bytes, k->length, nullptr)) {
		goto returnError;
	}

	size_t cb = COSE_Encode(hEncObj.ToCOSE(), nullptr, 0, 0) + 1;
	std::unique_ptr<byte> rgb(new byte[cb]);
	cb = COSE_Encode(hEncObj.ToCOSE(), rgb.get(), 0, cb);

	COSE_Encrypt_Free(hEncObj);

	int f = _ValidateEncrypt(pControl, rgb.get(), cb, nullptr);

	return f == 1;
}
#endif

#if INCLUDE_ENCRYPT
void Enveloped_Corners()
{
	HCOSE_ENVELOPED hEncryptNULL = nullptr;
	HCOSE_ENVELOPED hEncrypt = nullptr;
	HCOSE_ENVELOPED hEncryptBad = nullptr;
	HCOSE_RECIPIENT hRecipientNULL = nullptr;
	HCOSE_RECIPIENT hRecipient = nullptr;
	HCOSE_RECIPIENT hRecipientBad = nullptr;
	byte rgb[10];
	cn_cbor *cn = cn_cbor_int_create(5, CBOR_CONTEXT_PARAM_COMMA nullptr);
	cose_errback cose_error;

	hEncrypt = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
#if INCLUDE_MAC
	hEncryptBad = (HCOSE_ENVELOPED)COSE_Mac_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
#else
	hEncryptBad = (HCOSE_ENVELOPED)COSE_CALLOC(1, sizeof(COSE), context);
#endif
	hRecipient = COSE_Recipient_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
#if INCLUDE_MAC
	hRecipientBad = (HCOSE_RECIPIENT)COSE_Mac_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
#else
	hRecipientBad = (HCOSE_RECIPIENT)COSE_CALLOC(1, sizeof(COSE), context);
#endif

	//  Missing case - addref then release on item

	//
	//  Do parameter checks
	//      - nullptr handle
	//      - Incorrect handle
	//      - nullptr pointer
	//

	CHECK_FAILURE(
		COSE_Enveloped_SetContent(hEncryptNULL, rgb, 10, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_SetContent(hEncryptBad, rgb, 10, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_SetContent(hEncrypt, nullptr, 10, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(COSE_Enveloped_map_put_int(
					  hEncryptNULL, 1, cn, COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_map_put_int(
					  hEncryptBad, 1, cn, COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_map_put_int(hEncrypt, 1, cn,
					  COSE_PROTECT_ONLY | COSE_UNPROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);
	CHECK_FAILURE(COSE_Enveloped_map_put_int(
					  hEncrypt, 1, nullptr, COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(
		COSE_Enveloped_map_get_int(hEncryptNULL, 1, COSE_BOTH, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Enveloped_map_get_int(hEncryptBad, 1, COSE_BOTH, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	CHECK_FAILURE(COSE_Enveloped_encrypt(hEncryptNULL, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_encrypt(hEncryptBad, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	CHECK_FAILURE(
		COSE_Enveloped_decrypt(hEncryptNULL, hRecipient, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_decrypt(hEncryptBad, hRecipient, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Enveloped_decrypt(hEncrypt, hRecipientNULL, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_decrypt(hEncrypt, hRecipientBad, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	CHECK_FAILURE(
		COSE_Enveloped_AddRecipient(hEncryptNULL, hRecipient, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Enveloped_AddRecipient(hEncryptBad, hRecipient, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Enveloped_AddRecipient(hEncrypt, hRecipientNULL, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Enveloped_AddRecipient(hEncrypt, hRecipientBad, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	CHECK_FAILURE_PTR(
		COSE_Enveloped_GetRecipient(hEncryptNULL, 0, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE_PTR(COSE_Enveloped_GetRecipient(hEncryptBad, 0, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	CHECK_FAILURE(
		COSE_Enveloped_SetExternal(hEncryptNULL, rgb, 10, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_SetExternal(hEncryptBad, rgb, 10, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_SetExternal(hEncrypt, nullptr, 10, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	if (!COSE_Enveloped_Free(hEncrypt)) {
		CFails++;
	}
	if (!COSE_Recipient_Free(hRecipient)) {
		CFails++;
	}

	//
	//  Unsupported algorithm

	//  Bad Int algorithm

	hEncrypt = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hEncrypt == nullptr) {
		CFails++;
	}
	CHECK_RETURN(
		COSE_Enveloped_SetContent(hEncrypt, (byte *)"Message", 7, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(COSE_Enveloped_map_put_int(hEncrypt, COSE_Header_Algorithm,
					 cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA nullptr),
					 COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_NONE, CFails++);
	hRecipient = COSE_Recipient_from_shared_secret(
		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hRecipient == nullptr) {
		CFails++;
	}
	CHECK_RETURN(COSE_Enveloped_AddRecipient(hEncrypt, hRecipient, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_encrypt(hEncrypt, &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Recipient_Free(hRecipient);
	COSE_Enveloped_Free(hEncrypt);

	hEncrypt = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hEncrypt == nullptr) {
		CFails++;
	}
	CHECK_RETURN(
		COSE_Enveloped_SetContent(hEncrypt, (byte *)"Message", 7, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(
		COSE_Enveloped_map_put_int(hEncrypt, COSE_Header_Algorithm,
			cn_cbor_string_create("hmac", CBOR_CONTEXT_PARAM_COMMA nullptr),
			COSE_PROTECT_ONLY, &cose_error),
		COE_ERR_NONE, CFails++);
	hRecipient = COSE_Recipient_from_shared_secret(
		rgb, sizeof(rgb), rgb, sizeof(rgb), CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hRecipient == nullptr) {
		CFails++;
	}
	CHECK_RETURN(COSE_Enveloped_AddRecipient(hEncrypt, hRecipient, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_encrypt(hEncrypt, &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);

	//
	//  Over shoot the recipients

	CHECK_FAILURE_PTR(COSE_Enveloped_GetRecipient(hEncrypt, -1, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);
	CHECK_FAILURE_PTR(COSE_Enveloped_GetRecipient(hEncrypt, 9, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	COSE_Enveloped_Free(hEncrypt);
	COSE_Recipient_Free(hRecipient);
}
#endif

#if INCLUDE_ENCRYPT0
void Encrypt_Corners()
{
	HCOSE_ENCRYPT hEncrypt = nullptr;
	byte rgb[10];
	cn_cbor *cn = cn_cbor_int_create(5, CBOR_CONTEXT_PARAM_COMMA nullptr);
	cose_errback cose_error;

	//  Missing case - addref then release on item

	//  nullptr Handle checks

	if (COSE_Encrypt_SetContent(hEncrypt, rgb, 10, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_map_get_int(hEncrypt, 1, COSE_BOTH, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_map_put_int(hEncrypt, 1, cn, COSE_PROTECT_ONLY, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_SetExternal(hEncrypt, rgb, 10, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_decrypt(hEncrypt, rgb, sizeof(rgb), nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_Free((HCOSE_ENCRYPT)hEncrypt)) {
		CFails++;
	}

	//  Wrong type of handle checks

#if INCLUDE_MAC
	hEncrypt = (HCOSE_ENCRYPT)COSE_Mac_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
#else
	hEncrypt = (HCOSE_ENCRYPT)COSE_CALLOC(1, sizeof(COSE), context);
#endif

	if (COSE_Encrypt_SetContent(hEncrypt, rgb, 10, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_map_get_int(hEncrypt, 1, COSE_BOTH, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_map_put_int(hEncrypt, 1, cn, COSE_PROTECT_ONLY, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_SetExternal(hEncrypt, rgb, 10, nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_decrypt(hEncrypt, rgb, sizeof(rgb), nullptr)) {
		CFails++;
	}
	if (COSE_Encrypt_Free(hEncrypt)) {
		CFails++;
	}

	//
	//  Unsupported algorithm

	hEncrypt =
		COSE_Encrypt_Init(COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hEncrypt == nullptr) {
		CFails++;
	}
	if (!COSE_Encrypt_SetContent(hEncrypt, (byte *)"Message", 7, nullptr)) {
		CFails++;
	}
	if (!COSE_Encrypt_map_put_int(hEncrypt, COSE_Header_Algorithm,
			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA nullptr),
			COSE_PROTECT_ONLY, nullptr)) {
		CFails++;
	}
	CHECK_FAILURE(COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Encrypt_Free(hEncrypt);

	hEncrypt =
		COSE_Encrypt_Init(COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	if (hEncrypt == nullptr) {
		CFails++;
	}
	if (!COSE_Encrypt_SetContent(hEncrypt, (byte *)"Message", 7, nullptr)) {
		CFails++;
	}
	if (!COSE_Encrypt_map_put_int(hEncrypt, COSE_Header_Algorithm,
			cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA nullptr),
			COSE_PROTECT_ONLY, nullptr)) {
		CFails++;
	}
	CHECK_FAILURE(COSE_Encrypt_encrypt(hEncrypt, rgb, sizeof(rgb), &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);
	COSE_Encrypt_Free(hEncrypt);
}
#endif

#if INCLUDE_ENCRYPT || INCLUDE_MAC
void Recipient_Corners()
{
	HCOSE_RECIPIENT hRecip;
	HCOSE_RECIPIENT hRecipNULL = nullptr;
	HCOSE_RECIPIENT hRecipBad;
	cose_errback cose_error;
	byte rgb[10];
	cn_cbor *cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);

	hRecip = COSE_Recipient_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA & cose_error);
#if INCLUDE_SIGN
	hRecipBad = (HCOSE_RECIPIENT)COSE_Signer_Init(
		CBOR_CONTEXT_PARAM_COMMA & cose_error);
#else
	hRecipBad = (HCOSE_RECIPIENT)COSE_CALLOC(1, sizeof(COSE), context);
#endif

	//  Check for invalid parameters

	CHECK_FAILURE_PTR(COSE_Recipient_from_shared_secret(nullptr, 0, nullptr, 0,
						  CBOR_CONTEXT_PARAM_COMMA & cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(COSE_Recipient_SetKey_secret(
					  hRecipNULL, rgb, sizeof(rgb), nullptr, 0, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Recipient_SetKey_secret(
					  hRecipBad, rgb, sizeof(rgb), nullptr, 0, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Recipient_SetKey_secret(
					  hRecip, nullptr, sizeof(rgb), nullptr, 0, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(COSE_Recipient_SetKey(hRecipNULL, cn, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_FAILURE(COSE_Recipient_SetKey(hRecipBad, cn, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_FAILURE(COSE_Recipient_SetKey(hRecip, nullptr, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(
		COSE_Recipient_SetSenderKey(hRecipNULL, cn, 0, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_FAILURE(COSE_Recipient_SetSenderKey(hRecipBad, cn, 0, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_FAILURE(COSE_Recipient_SetSenderKey(hRecip, nullptr, 0, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);
	CHECK_FAILURE(COSE_Recipient_SetSenderKey(hRecip, cn, 3, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_RETURN(COSE_Recipient_SetSenderKey(hRecip, cn, 0, &cose_error),
		COSE_ERR_NONE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);

	CHECK_FAILURE(
		COSE_Recipient_SetExternal(hRecipNULL, rgb, 10, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Recipient_SetExternal(hRecipBad, rgb, 10, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	CHECK_FAILURE(
		COSE_Recipient_map_get_int(hRecipNULL, 1, COSE_BOTH, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Recipient_map_get_int(hRecipBad, 1, COSE_BOTH, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Recipient_map_get_int(hRecip, 1, COSE_BOTH, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(COSE_Recipient_map_put_int(
					  hRecipNULL, 1, cn, COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_FAILURE(COSE_Recipient_map_put_int(
					  hRecipBad, 1, cn, COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	cn = cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA nullptr);
	CHECK_FAILURE(COSE_Recipient_map_put_int(
					  hRecip, 1, nullptr, COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);
	CHECK_FAILURE(COSE_Recipient_map_put_int(hRecip, 1, cn,
					  COSE_PROTECT_ONLY | COSE_UNPROTECT_ONLY, &cose_error),
		COSE_ERR_INVALID_PARAMETER, CFails++);

	CHECK_FAILURE(
		COSE_Recipient_AddRecipient(hRecipNULL, hRecip, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Recipient_AddRecipient(hRecipBad, hRecip, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(
		COSE_Recipient_AddRecipient(hRecip, hRecipNULL, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);
	CHECK_FAILURE(COSE_Recipient_AddRecipient(hRecip, hRecipBad, &cose_error),
		COSE_ERR_INVALID_HANDLE, CFails++);

	COSE_Recipient_Free(hRecip);

	//  Unknown algorithms
#if INCLUDE_ENCRYPT
	HCOSE_ENVELOPED hEnv = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	hRecip = COSE_Recipient_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);

	CHECK_RETURN(COSE_Enveloped_map_put_int(hEnv, COSE_Header_Algorithm,
					 cn_cbor_int_create(COSE_Algorithm_AES_GCM_128,
						 CBOR_CONTEXT_PARAM_COMMA nullptr),
					 COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(COSE_Enveloped_SetContent(
					 hEnv, (byte *)"This the body", 13, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(COSE_Recipient_map_put_int(hRecip, COSE_Header_Algorithm,
					 cn_cbor_int_create(-99, CBOR_CONTEXT_PARAM_COMMA nullptr),
					 COSE_UNPROTECT_ONLY, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(COSE_Enveloped_AddRecipient(hEnv, hRecip, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_encrypt(hEnv, &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);

	COSE_Enveloped_Free(hEnv);
	COSE_Recipient_Free(hRecip);

	hEnv = COSE_Enveloped_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);
	hRecip = COSE_Recipient_Init(
		COSE_INIT_FLAGS_NONE, CBOR_CONTEXT_PARAM_COMMA nullptr);

	CHECK_RETURN(COSE_Enveloped_map_put_int(hEnv, COSE_Header_Algorithm,
					 cn_cbor_int_create(COSE_Algorithm_AES_GCM_128,
						 CBOR_CONTEXT_PARAM_COMMA nullptr),
					 COSE_PROTECT_ONLY, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(COSE_Enveloped_SetContent(
					 hEnv, (byte *)"This the body", 13, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(
		COSE_Recipient_map_put_int(hRecip, COSE_Header_Algorithm,
			cn_cbor_string_create("Unknown", CBOR_CONTEXT_PARAM_COMMA nullptr),
			COSE_UNPROTECT_ONLY, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_RETURN(COSE_Enveloped_AddRecipient(hEnv, hRecip, &cose_error),
		COSE_ERR_NONE, CFails++);
	CHECK_FAILURE(COSE_Enveloped_encrypt(hEnv, &cose_error),
		COSE_ERR_UNKNOWN_ALGORITHM, CFails++);

	COSE_Enveloped_Free(hEnv);
	COSE_Recipient_Free(hRecip);
#endif
}
#endif
