Make MAC handle freeing correct.
diff --git a/README.md b/README.md
index e47b422..b133c58 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,5 @@
-# COSE-C Implementation [](https://travis-ci.org/cose-wg/COSE-C)[](https://coveralls.io/github/cose-wg/COSE-C?branch=master)
+# COSE-C Implementation [](https://travis-ci.org/cose-wg/COSE-C) [](https://coveralls.io/github/cose-wg/COSE-C?branch=master)
This project is a C implementation of the IETF CBOR Encoded Mesage Syntax (COSE).
There are currently two versions of the COSE document that can be read.
diff --git a/src/MacMessage.c b/src/MacMessage.c
index e5bfad1..6f49454 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -79,9 +79,15 @@
#ifdef USE_CBOR_CONTEXT
cn_cbor_context context;
#endif
+ COSE_MacMessage * p = (COSE_MacMessage *)h;
if (!IsValidMacHandle(h)) return false;
+ if (p->m_message.m_refCount > 1) {
+ p->m_message.m_refCount--;
+ return true;
+ }
+
#ifdef USE_CBOR_CONTEXT
context = ((COSE_MacMessage *)h)->m_message.m_allocContext;
#endif
@@ -93,11 +99,21 @@
return true;
}
-void _COSE_Mac_Release(COSE_MacMessage * p)
+bool _COSE_Mac_Release(COSE_MacMessage * p)
{
+ COSE_RecipientInfo * pRecipient;
+ COSE_RecipientInfo * pRecipient2;
+
if (p->pbKey != NULL) COSE_FREE(p->pbKey, &p->m_message.m_allocContext);
+ for (pRecipient = p->m_recipientFirst; pRecipient != NULL; pRecipient = pRecipient2) {
+ pRecipient2 = pRecipient->m_recipientNext;
+ _COSE_Recipient_Free(pRecipient);
+ }
+
_COSE_Release(&p->m_message);
+
+ return true;
}
@@ -423,12 +439,11 @@
cn_cbor_errback cbor_error;
byte * pbAuthData = NULL;
int cbitKey = 0;
- byte * pbKeyIn = NULL;
int alg;
const cn_cbor * cn = NULL;
- byte * pbKey = pbKeyIn;
+ byte * pbKey = NULL;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = NULL;
#endif
@@ -485,8 +500,6 @@
if (pbKey == NULL) {
pbKey = COSE_CALLOC(cbitKey / 8, 1, context);
CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
- pcose->pbKey = pbKey;
- pcose->cbKey = cbitKey / 8;
}
// If there is a recipient - ask it for the key
@@ -532,35 +545,29 @@
switch (alg) {
case COSE_Algorithm_HMAC_256_256:
- if (!HMAC_Validate(pcose, 256, 256, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Validate(pcose, 256, 256, pbKey, cbitKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_256_64:
- if (!HMAC_Validate(pcose, 256, 64, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Validate(pcose, 256, 64, pbKey, cbitKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_384_384:
- if (!HMAC_Validate(pcose, 384, 384, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Validate(pcose, 384, 384, pbKey, cbitKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_512_512:
- if (!HMAC_Validate(pcose, 512, 512, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Validate(pcose, 512, 512, pbKey, cbitKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_CBC_MAC_128_64:
- if (!AES_CBC_MAC_Validate(pcose, 128, 64, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ case COSE_Algorithm_CBC_MAC_256_64:
+ if (!AES_CBC_MAC_Validate(pcose, 64, pbKey, cbitKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_CBC_MAC_128_128:
- if (!AES_CBC_MAC_Validate(pcose, 128, 128, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-
- case COSE_Algorithm_CBC_MAC_256_64:
- if (!AES_CBC_MAC_Validate(pcose, 256, 64, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-
case COSE_Algorithm_CBC_MAC_256_128:
- if (!AES_CBC_MAC_Validate(pcose, 256, 128, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!AES_CBC_MAC_Validate(pcose, 128, pbKey, cbitKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
default:
@@ -570,7 +577,7 @@
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
- if ((pbKey != NULL) && (pbKeyIn == NULL)) {
+ if ((pbKey != NULL)) {
memset(pbKey, 0xff, cbitKey / 8);
COSE_FREE(pbKey, context);
}
@@ -580,7 +587,7 @@
errorReturn:
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
- if ((pbKey != NULL) && (pbKeyIn == NULL)) {
+ if ((pbKey != NULL)) {
memset(pbKey, 0xff, cbitKey / 8);
COSE_FREE(pbKey, context);
}
@@ -623,7 +630,7 @@
}
CHECK_CONDITION_CBOR(cn_cbor_array_append(pRecipients, pRecip->m_encrypt.m_message.m_cbor, &cbor_error), cbor_error);
-
+ pRecip->m_encrypt.m_message.m_refCount++;
return true;
@@ -645,6 +652,7 @@
CHECK_CONDITION(p != NULL, COSE_ERR_NO_RECIPIENT_FOUND);
p = p->m_recipientNext;
}
+ p->m_encrypt.m_message.m_refCount++;
return (HCOSE_RECIPIENT)p;
errorReturn:
diff --git a/src/Recipient.c b/src/Recipient.c
index 573d870..4cee65a 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -91,6 +91,11 @@
void _COSE_Recipient_Free(COSE_RecipientInfo * pRecipient)
{
+ if (pRecipient->m_encrypt.m_message.m_refCount > 1) {
+ pRecipient->m_encrypt.m_message.m_refCount--;
+ return;
+ }
+
COSE_FREE(pRecipient, &pRecipient->m_encrypt.m_message.m_allocContext);
return;
diff --git a/src/SignerInfo.c b/src/SignerInfo.c
index 8bbf317..a2ed0b6 100644
--- a/src/SignerInfo.c
+++ b/src/SignerInfo.c
@@ -211,13 +211,8 @@
{
cn_cbor_errback cbor_error;
byte * pbAuthData = NULL;
- int cbitKey = 0;
- byte * pbKeyIn = NULL;
-
int alg;
const cn_cbor * cn = NULL;
-
- byte * pbKey = pbKeyIn;
#ifdef USE_CBOR_CONTEXT
cn_cbor_context * context = NULL;
#endif
@@ -299,20 +294,12 @@
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
- if ((pbKey != NULL) && (pbKeyIn == NULL)) {
- memset(pbKey, 0xff, cbitKey / 8);
- COSE_FREE(pbKey, context);
- }
return true;
errorReturn:
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
- if ((pbKey != NULL) && (pbKeyIn == NULL)) {
- memset(pbKey, 0xff, cbitKey / 8);
- COSE_FREE(pbKey, context);
- }
return false;
}
diff --git a/src/cose_int.h b/src/cose_int.h
index d6906f0..4f6ad8b 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -152,7 +152,7 @@
// Mac-ed items
extern HCOSE_MAC _COSE_Mac_Init_From_Object(cn_cbor *, COSE_MacMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
-extern void _COSE_Mac_Release(COSE_MacMessage * p);
+extern bool _COSE_Mac_Release(COSE_MacMessage * p);
#define CHECK_CONDITION(condition, error) { if (!(condition)) { assert(false); perr->err = error; goto errorReturn;}}
diff --git a/src/crypto.h b/src/crypto.h
index 5eb16d9..d788f27 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -27,10 +27,10 @@
bool AES_KW_Encrypt(COSE_RecipientInfo * pcose, const byte * pbKeyIn, int cbitKey, const byte * pbContent, int cbContent, cose_errback * perr);
-extern bool AES_CMAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
+extern bool AES_CMAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
extern bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
-extern bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int KeySize, int TagSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
+extern bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int TagSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
/**
* Perform an HMAC Creation operation
@@ -44,7 +44,7 @@
* @return Did the function succeed?
*/
bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
-bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
+bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
/**
* Perform a signature operation
diff --git a/src/openssl.c b/src/openssl.c
index 7de84f1..c3c08a4 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -436,7 +436,7 @@
return false;
}
-bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int KeySize, int TSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
+bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int TSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
{
const EVP_CIPHER * pcipher = NULL;
EVP_CIPHER_CTX ctx;
@@ -446,7 +446,7 @@
bool f = false;
unsigned int i;
- switch (KeySize) {
+ switch (cbitKey) {
case 128:
pcipher = EVP_aes_128_cbc();
break;
@@ -462,7 +462,7 @@
// Setup and run the OpenSSL code
EVP_CIPHER_CTX_init(&ctx);
- CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pcose->pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION(EVP_EncryptInit_ex(&ctx, pcipher, NULL, pbKey, rgbIV), COSE_ERR_CRYPTO_FAIL);
TSize /= 8;
@@ -575,7 +575,7 @@
return true;
}
-bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
+bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
{
HMAC_CTX ctx;
const EVP_MD * pmd = NULL;
@@ -599,7 +599,7 @@
rgbOut = COSE_CALLOC(EVP_MAX_MD_SIZE, 1, context);
CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
- CHECK_CONDITION(HMAC_Init(&ctx, pcose->pbKey, (int) pcose->cbKey, pmd), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION(HMAC_Init(&ctx, pbKey, cbitKey/8, pmd), COSE_ERR_CRYPTO_FAIL);
CHECK_CONDITION(HMAC_Update(&ctx, pbAuthData, cbAuthData), COSE_ERR_CRYPTO_FAIL);
CHECK_CONDITION(HMAC_Final(&ctx, rgbOut, &cbOut), COSE_ERR_CRYPTO_FAIL);
@@ -616,7 +616,6 @@
COSE_FREE(rgbOut, context);
HMAC_cleanup(&ctx);
return false;
-
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 83f5c4d..99a8ec5 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -8,7 +8,7 @@
set (CMAKE_RUNTIME_OUTPUT_DIRECTORY ${dist_dir}/test )
-add_executable ( cose_test test.c json.c encrypt.c sign.c context.c )
+add_executable ( cose_test test.c json.c encrypt.c sign.c context.c mac_test.c)
target_link_libraries (cose_test PRIVATE cose-c )
diff --git a/test/mac_test.c b/test/mac_test.c
new file mode 100644
index 0000000..edec5f6
--- /dev/null
+++ b/test/mac_test.c
@@ -0,0 +1,220 @@
+#define _CRT_SECURE_NO_WARNINGS
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <cose.h>
+#include <cn-cbor/cn-cbor.h>
+
+#include "json.h"
+#include "test.h"
+#include "context.h"
+
+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;
+
+ 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, NULL, NULL);
+ if (hMAC == NULL) exit(1);
+
+ if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) exit(1);
+ pMac = cn_cbor_mapget_string(pInput, "mac");
+ if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP)) exit(1);
+
+ pRecipients = cn_cbor_mapget_string(pMac, "recipients");
+ if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) exit(1);
+
+ iRecipient = (int) pRecipients->length - 1;
+ pRecipients = pRecipients->first_child;
+ for (; pRecipients != NULL; iRecipient--, pRecipients=pRecipients->next) {
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"));
+ if (pkey == NULL) {
+ fFail = true;
+ continue;
+ }
+
+ HCOSE_RECIPIENT hRecip = COSE_Mac_GetRecipient(hMAC, iRecipient, NULL);
+ if (hRecip == NULL) {
+ fFail = true;
+ continue;
+ }
+
+ if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
+ fFail = true;
+ continue;
+ }
+
+ pFail = cn_cbor_mapget_string(pRecipients, "fail");
+ if (COSE_Mac_validate(hMAC, hRecip, NULL)) {
+ if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) fFail = true;
+ }
+ else {
+ if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) fFail = true;
+ }
+
+ COSE_Recipient_Free(hRecip);
+ }
+
+ COSE_Mac_Free(hMAC);
+
+ if (fFailBody) {
+ if (!fFail) fFail = true;
+ else fFail = false;
+ }
+
+ if (fFail) CFails += 1;
+ return 0;
+}
+
+int ValidateMAC(const cn_cbor * pControl)
+{
+ int cbEncoded;
+ byte * pbEncoded = GetCBOREncoding(pControl, &cbEncoded);
+
+ return _ValidateMAC(pControl, pbEncoded, cbEncoded);
+}
+
+int BuildMacMessage(const cn_cbor * pControl)
+{
+ int iRecipient;
+
+ //
+ // 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(CBOR_CONTEXT_PARAM_COMMA NULL);
+
+ const cn_cbor * pInputs = cn_cbor_mapget_string(pControl, "input");
+ if (pInputs == NULL) exit(1);
+ const cn_cbor * pMac = cn_cbor_mapget_string(pInputs, "mac");
+ if (pMac == NULL) exit(1);
+
+ const cn_cbor * pContent = cn_cbor_mapget_string(pInputs, "plaintext");
+ if (!COSE_Mac_SetContent(hMacObj, pContent->v.bytes, pContent->length, NULL)) goto returnError;
+
+ if (!SetAttributes((HCOSE) hMacObj, cn_cbor_mapget_string(pMac, "protected"), Attributes_MAC_protected)) goto returnError;
+ if (!SetAttributes((HCOSE) hMacObj, cn_cbor_mapget_string(pMac, "unprotected"), Attributes_MAC_unprotected)) goto returnError;
+
+ const cn_cbor * pAlg = COSE_Mac_map_get_int(hMacObj, 1, COSE_BOTH, NULL);
+
+ const cn_cbor * pRecipients = cn_cbor_mapget_string(pMac, "recipients");
+ if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) exit(1);
+
+ pRecipients = pRecipients->first_child;
+ for (iRecipient = 0; pRecipients != NULL; iRecipient++, pRecipients = pRecipients->next) {
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"));
+ if (pkey == NULL) exit(1);
+
+ HCOSE_RECIPIENT hRecip = COSE_Recipient_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (hRecip == NULL) exit(1);
+
+ if (!SetAttributes((HCOSE) hRecip, cn_cbor_mapget_string(pRecipients, "protected"), Attributes_Recipient_protected)) goto returnError;
+ if (!SetAttributes((HCOSE) hRecip, cn_cbor_mapget_string(pRecipients, "unprotected"), Attributes_Recipient_unprotected)) goto returnError;
+
+ if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) exit(1);
+
+ if (!COSE_Mac_AddRecipient(hMacObj, hRecip, NULL)) exit(1);
+
+ COSE_Recipient_Free(hRecip);
+ }
+
+ if (!COSE_Mac_encrypt(hMacObj, NULL)) exit(1);
+
+ 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:
+ CFails += 1;
+ return 1;
+}
+
+int MacMessage()
+{
+ HCOSE_MAC hEncObj = COSE_Mac_Init(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;
+ byte * rgb;
+
+ COSE_Mac_map_put(hEncObj, COSE_Header_Algorithm, cn_cbor_int_create(COSE_Algorithm_HMAC_256_256, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_PROTECT_ONLY, NULL);
+ COSE_Mac_SetContent(hEncObj, (byte *) sz, strlen(sz), NULL);
+
+ COSE_Mac_add_shared_secret(hEncObj, COSE_Algorithm_Direct, rgbSecret, sizeof(rgbSecret), rgbKid, cbKid, NULL);
+
+ COSE_Mac_encrypt(hEncObj, NULL);
+
+ cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0) + 1;
+ rgb = (byte *)malloc(cb);
+ cb = COSE_Encode((HCOSE)hEncObj, rgb, 0, cb);
+
+ 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
+
+ COSE_Mac_Free(hEncObj);
+
+ /* */
+
+ int typ;
+ hEncObj = (HCOSE_MAC) COSE_Decode(rgb, (int) cb, &typ, COSE_mac_object, NULL, NULL);
+
+ int iRecipient = 0;
+ do {
+ HCOSE_RECIPIENT hRecip;
+
+ hRecip = COSE_Mac_GetRecipient(hEncObj, iRecipient, NULL);
+ if (hRecip == NULL) break;
+
+ COSE_Recipient_SetKey_secret(hRecip, rgbSecret, sizeof(rgbSecret), NULL);
+
+ COSE_Mac_validate(hEncObj, hRecip, NULL);
+
+ iRecipient += 1;
+
+ COSE_Recipient_Free(hRecip);
+
+ } while (true);
+
+ COSE_Mac_Free(hEncObj);
+
+ return 1;
+}
diff --git a/test/test.c b/test/test.c
index 2d56925..e37146e 100644
--- a/test/test.c
+++ b/test/test.c
@@ -15,8 +15,6 @@
#include "test.h"
-
-extern int EncryptMessage();
int CFails = 0;
@@ -300,201 +298,6 @@
return pKeyOut;
}
-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;
-
- 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, NULL, NULL);
- if (hMAC == NULL) exit(1);
-
- if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) exit(1);
- pMac = cn_cbor_mapget_string(pInput, "mac");
- if ((pMac == NULL) || (pMac->type != CN_CBOR_MAP)) exit(1);
-
- pRecipients = cn_cbor_mapget_string(pMac, "recipients");
- if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) exit(1);
-
- iRecipient = (int) pRecipients->length - 1;
- pRecipients = pRecipients->first_child;
- for (; pRecipients != NULL; iRecipient--, pRecipients=pRecipients->next) {
- cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"));
- if (pkey == NULL) {
- fFail = true;
- continue;
- }
-
- HCOSE_RECIPIENT hRecip = COSE_Mac_GetRecipient(hMAC, iRecipient, NULL);
- if (hRecip == NULL) {
- fFail = true;
- continue;
- }
-
- if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) {
- fFail = true;
- continue;
- }
-
- pFail = cn_cbor_mapget_string(pRecipients, "fail");
- if (COSE_Mac_validate(hMAC, hRecip, NULL)) {
- if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) fFail = true;
- }
- else {
- if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) fFail = true;
- }
- }
-
- if (fFailBody) {
- if (!fFail) fFail = true;
- else fFail = false;
- }
-
- if (fFail) CFails += 1;
- return 0;
-}
-
-int ValidateMAC(const cn_cbor * pControl)
-{
- int cbEncoded;
- byte * pbEncoded = GetCBOREncoding(pControl, &cbEncoded);
-
- return _ValidateMAC(pControl, pbEncoded, cbEncoded);
-}
-
-int BuildMacMessage(const cn_cbor * pControl)
-{
- int iRecipient;
-
- //
- // 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(CBOR_CONTEXT_PARAM_COMMA NULL);
-
- const cn_cbor * pInputs = cn_cbor_mapget_string(pControl, "input");
- if (pInputs == NULL) exit(1);
- const cn_cbor * pMac = cn_cbor_mapget_string(pInputs, "mac");
- if (pMac == NULL) exit(1);
-
- const cn_cbor * pContent = cn_cbor_mapget_string(pInputs, "plaintext");
- if (!COSE_Mac_SetContent(hMacObj, pContent->v.bytes, pContent->length, NULL)) goto returnError;
-
- if (!SetAttributes((HCOSE) hMacObj, cn_cbor_mapget_string(pMac, "protected"), Attributes_MAC_protected)) goto returnError;
- if (!SetAttributes((HCOSE) hMacObj, cn_cbor_mapget_string(pMac, "unprotected"), Attributes_MAC_unprotected)) goto returnError;
-
- const cn_cbor * pAlg = COSE_Mac_map_get_int(hMacObj, 1, COSE_BOTH, NULL);
-
- const cn_cbor * pRecipients = cn_cbor_mapget_string(pMac, "recipients");
- if ((pRecipients == NULL) || (pRecipients->type != CN_CBOR_ARRAY)) exit(1);
-
- pRecipients = pRecipients->first_child;
- for (iRecipient = 0; pRecipients != NULL; iRecipient++, pRecipients = pRecipients->next) {
- cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"));
- if (pkey == NULL) exit(1);
-
- HCOSE_RECIPIENT hRecip = COSE_Recipient_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
- if (hRecip == NULL) exit(1);
-
- if (!SetAttributes((HCOSE) hRecip, cn_cbor_mapget_string(pRecipients, "protected"), Attributes_Recipient_protected)) goto returnError;
- if (!SetAttributes((HCOSE) hRecip, cn_cbor_mapget_string(pRecipients, "unprotected"), Attributes_Recipient_unprotected)) goto returnError;
-
- if (!COSE_Recipient_SetKey(hRecip, pkey, NULL)) exit(1);
-
- if (!COSE_Mac_AddRecipient(hMacObj, hRecip, NULL)) exit(1);
- }
-
- if (!COSE_Mac_encrypt(hMacObj, NULL)) exit(1);
-
- size_t cb = COSE_Encode((HCOSE)hMacObj, NULL, 0, 0) + 1;
- byte * rgb = (byte *)malloc(cb);
- cb = COSE_Encode((HCOSE)hMacObj, rgb, 0, cb);
-
- int f = _ValidateMAC(pControl, rgb, cb);
-
- free(rgb);
- return f;
-
-returnError:
- CFails += 1;
- return 1;
-}
-
-int MacMessage()
-{
- HCOSE_MAC hEncObj = COSE_Mac_Init(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;
- byte * rgb;
-
- COSE_Mac_map_put(hEncObj, COSE_Header_Algorithm, cn_cbor_int_create(COSE_Algorithm_HMAC_256_256, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_PROTECT_ONLY, NULL);
- COSE_Mac_SetContent(hEncObj, (byte *) sz, strlen(sz), NULL);
-
- COSE_Mac_add_shared_secret(hEncObj, COSE_Algorithm_Direct, rgbSecret, sizeof(rgbSecret), rgbKid, cbKid, NULL);
-
- COSE_Mac_encrypt(hEncObj, NULL);
-
- cb = COSE_Encode((HCOSE)hEncObj, NULL, 0, 0) + 1;
- rgb = (byte *)malloc(cb);
- cb = COSE_Encode((HCOSE)hEncObj, rgb, 0, cb);
-
-
- 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
-
- COSE_Mac_Free(hEncObj);
-
- /* */
-
- int typ;
- hEncObj = (HCOSE_MAC) COSE_Decode(rgb, (int) cb, &typ, COSE_mac_object, NULL, NULL);
-
- int iRecipient = 0;
- do {
- HCOSE_RECIPIENT hRecip;
-
- hRecip = COSE_Mac_GetRecipient(hEncObj, iRecipient, NULL);
- if (hRecip == NULL) break;
-
- COSE_Recipient_SetKey_secret(hRecip, rgbSecret, sizeof(rgbSecret), NULL);
-
- COSE_Mac_validate(hEncObj, hRecip, NULL);
-
- iRecipient += 1;
-
- } while (true);
-
- return 1;
-}
bool cn_cbor_array_replace(cn_cbor * cb_array, cn_cbor * cb_value, int index, CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
diff --git a/test/test.h b/test/test.h
index 0a4ecd4..d5ab6b4 100644
--- a/test/test.h
+++ b/test/test.h
@@ -23,6 +23,11 @@
int SignMessage();
int BuildSignedMessage(const cn_cbor * pControl);
+// mac_testc
+
+int ValidateMac(const cn_cbor * pControl);
+int MacMessage();
+int BuildMacMessage(const cn_cbor * pControl);
// test.c
enum {