First pass Sign0 and Mac0 implement
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1f5166d..44c09fe 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -5,8 +5,10 @@
set ( cose_sources
Cose.c
MacMessage.c
+ MacMessage0.c
openssl.c
Sign.c
+ Sign0.c
cbor.c
Encrypt.c
Encrypt0.c
diff --git a/src/Cose.c b/src/Cose.c
index 23b40e3..a26d139 100644
--- a/src/Cose.c
+++ b/src/Cose.c
@@ -183,6 +183,13 @@
}
break;
+ case COSE_sign0_object:
+ h = (HCOSE)_COSE_Sign0_Init_From_Object(cborRoot, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
+ if (h == NULL) {
+ goto errorReturn;
+ }
+ break;
+
case COSE_mac_object:
h = (HCOSE)_COSE_Mac_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
if (h == NULL) {
@@ -190,6 +197,13 @@
}
break;
+ case COSE_mac0_object:
+ h = (HCOSE)_COSE_Mac0_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
+ if (h == NULL) {
+ goto errorReturn;
+ }
+ break;
+
case COSE_encrypt_object:
h = (HCOSE)_COSE_Encrypt_Init_From_Object(cbor, NULL, CBOR_CONTEXT_PARAM_COMMA perr);
if (h == NULL) {
diff --git a/src/Encrypt.c b/src/Encrypt.c
index 26b0223..2440e14 100644
--- a/src/Encrypt.c
+++ b/src/Encrypt.c
@@ -15,7 +15,7 @@
bool IsValidEnvelopedHandle(HCOSE_ENVELOPED h)
{
COSE_Enveloped * p = (COSE_Enveloped *)h;
- return _COSE_IsInList(EnvelopedRoot, p);
+ return _COSE_IsInList(EnvelopedRoot, &p->m_message);
}
@@ -38,7 +38,7 @@
return NULL;
}
- _COSE_InsertInList(&EnvelopedRoot, pobj);
+ _COSE_InsertInList(&EnvelopedRoot, &pobj->m_message);
return (HCOSE_ENVELOPED) pobj;
}
@@ -77,7 +77,7 @@
}
}
- if (pIn == NULL) _COSE_InsertInList(&EnvelopedRoot, pobj);
+ if (pIn == NULL) _COSE_InsertInList(&EnvelopedRoot, &pobj->m_message);
return(HCOSE_ENVELOPED) pobj;
}
@@ -87,6 +87,7 @@
#ifdef USE_CBOR_CONTEXT
cn_cbor_context context;
#endif
+ COSE_Enveloped * p = (COSE_Enveloped *)h;
if (!IsValidEnvelopedHandle(h)) return false;
@@ -94,7 +95,7 @@
context = ((COSE_Enveloped *)h)->m_message.m_allocContext;
#endif
- _COSE_RemoveFromList(&EnvelopedRoot, (COSE_Enveloped *)h);
+ _COSE_RemoveFromList(&EnvelopedRoot, &p->m_message);
_COSE_Enveloped_Release((COSE_Enveloped *)h);
diff --git a/src/MacMessage.c b/src/MacMessage.c
index c1c3da2..ed287d9 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -237,7 +237,7 @@
}
-bool COSE_Mac_map_put(HCOSE_MAC h, int key, cn_cbor * value, int flags, cose_errback * perror)
+bool COSE_Mac_map_put_int(HCOSE_MAC h, int key, cn_cbor * value, int flags, cose_errback * perror)
{
if (!IsValidMacHandle(h) || (value == NULL)) {
if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
@@ -377,35 +377,29 @@
switch (alg) {
case COSE_Algorithm_CBC_MAC_128_64:
- if (!AES_CBC_MAC_Create(pcose, 128, 64, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ case COSE_Algorithm_CBC_MAC_256_64:
+ if (!AES_CBC_MAC_Create(pcose, 64, pcose->pbKey, pcose->cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_CBC_MAC_128_128:
- if (!AES_CBC_MAC_Create(pcose, 128, 128, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-
- case COSE_Algorithm_CBC_MAC_256_64:
- if (!AES_CBC_MAC_Create(pcose, 256, 64, pbAuthData, cbAuthData, perr)) goto errorReturn;
- break;
-
case COSE_Algorithm_CBC_MAC_256_128:
- if (!AES_CBC_MAC_Create(pcose, 256, 128, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!AES_CBC_MAC_Create(pcose, 128, pcose->pbKey, pcose->cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_256_64:
- if (!HMAC_Create(pcose, 256, 64, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Create(pcose, 256, 64, pcose->pbKey, pcose->cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_256_256:
- if (!HMAC_Create(pcose, 256, 256, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Create(pcose, 256, 256, pcose->pbKey, pcose->cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_384_384:
- if (!HMAC_Create(pcose, 384, 384, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Create(pcose, 384, 384, pcose->pbKey, pcose->cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_HMAC_512_512:
- if (!HMAC_Create(pcose, 512, 512, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ if (!HMAC_Create(pcose, 512, 512, pcose->pbKey, pcose->cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
default:
diff --git a/src/MacMessage0.c b/src/MacMessage0.c
new file mode 100644
index 0000000..78f804a
--- /dev/null
+++ b/src/MacMessage0.c
@@ -0,0 +1,426 @@
+#include <stdlib.h>
+#include <memory.h>
+#include <stdio.h>
+#include <assert.h>
+#include <string.h>
+
+#include "cose.h"
+#include "cose_int.h"
+#include "configure.h"
+#include "crypto.h"
+
+byte RgbDontUse2[8 * 1024]; // Remove this array when we can compute the size of a cbor serialization without this hack.
+
+
+bool IsValidMac0Handle(HCOSE_MAC0 h)
+{
+ COSE_Mac0Message * p = (COSE_Mac0Message *)h;
+ if (p == NULL) return false;
+ return true;
+}
+
+
+HCOSE_MAC0 COSE_Mac0_Init(CBOR_CONTEXT_COMMA cose_errback * perr)
+{
+ COSE_Mac0Message * pobj = (COSE_Mac0Message *)COSE_CALLOC(1, sizeof(COSE_Mac0Message), context);
+ CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ if (!_COSE_Init(&pobj->m_message, COSE_mac0_object, CBOR_CONTEXT_PARAM_COMMA perr)) {
+ goto errorReturn;
+ }
+
+ return (HCOSE_MAC0)pobj;
+
+errorReturn:
+ if (pobj != NULL) COSE_Mac0_Free((HCOSE_MAC0)pobj);
+ return NULL;
+}
+
+HCOSE_MAC0 _COSE_Mac0_Init_From_Object(cn_cbor * cbor, COSE_Mac0Message * pIn, CBOR_CONTEXT_COMMA cose_errback * perr)
+{
+ COSE_Mac0Message * pobj = pIn;
+ cn_cbor * pRecipients = NULL;
+ // cn_cbor * tmp;
+ cose_errback error = { COSE_ERR_NONE };
+ if (perr == NULL) perr = &error;
+
+ if (pobj == NULL) pobj = (COSE_Mac0Message *)COSE_CALLOC(1, sizeof(COSE_Mac0Message), context);
+ if (pobj == NULL) {
+ perr->err = COSE_ERR_OUT_OF_MEMORY;
+ errorReturn:
+ if ((pIn == NULL) && (pobj != NULL)) COSE_FREE(pobj, context);
+ return NULL;
+ }
+
+ if (!_COSE_Init_From_Object(&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
+ goto errorReturn;
+ }
+
+ pRecipients = _COSE_arrayget_int(&pobj->m_message, INDEX_MAC_RECIPIENTS);
+ CHECK_CONDITION(pRecipients == NULL, COSE_ERR_INVALID_PARAMETER);
+
+ return(HCOSE_MAC0)pobj;
+}
+
+bool COSE_Mac0_Free(HCOSE_MAC0 h)
+{
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context context;
+#endif
+ COSE_Mac0Message * p = (COSE_Mac0Message *)h;
+
+ if (!IsValidMac0Handle(h)) return false;
+
+ if (p->m_message.m_refCount > 1) {
+ p->m_message.m_refCount--;
+ return true;
+ }
+
+#ifdef USE_CBOR_CONTEXT
+ context = ((COSE_Mac0Message *)h)->m_message.m_allocContext;
+#endif
+
+ _COSE_Mac0_Release((COSE_Mac0Message *)h);
+
+ COSE_FREE((COSE_Mac0Message *)h, &context);
+
+ return true;
+}
+
+bool _COSE_Mac0_Release(COSE_Mac0Message * p)
+{
+ _COSE_Release(&p->m_message);
+
+ return true;
+}
+
+bool COSE_Mac0_SetContent(HCOSE_MAC0 cose, const byte * rgbContent, size_t cbContent, cose_errback * perr)
+{
+ COSE_Mac0Message * p = (COSE_Mac0Message *)cose;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = &p->m_message.m_allocContext;
+#endif
+ cn_cbor * ptmp = NULL;
+ cn_cbor_errback cbor_error;
+
+ CHECK_CONDITION(IsValidMac0Handle(cose), COSE_ERR_INVALID_PARAMETER);
+
+ ptmp = cn_cbor_data_create(rgbContent, (int) cbContent, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+
+ CHECK_CONDITION_CBOR(_COSE_array_replace(&p->m_message, ptmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ ptmp = NULL;
+
+ return true;
+
+errorReturn:
+ if (ptmp != NULL) CN_CBOR_FREE(ptmp, context);
+ return false;
+}
+
+
+cn_cbor * COSE_Mac0_map_get_int(HCOSE_MAC0 h, int key, int flags, cose_errback * perror)
+{
+ if (!IsValidMac0Handle(h)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ return _COSE_map_get_int(&((COSE_Mac0Message *)h)->m_message, key, flags, perror);
+}
+
+
+bool COSE_Mac0_map_put_int(HCOSE_MAC0 h, int key, cn_cbor * value, int flags, cose_errback * perror)
+{
+ if (!IsValidMac0Handle(h) || (value == NULL)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return false;
+ }
+
+ return _COSE_map_put(&((COSE_Mac0Message *)h)->m_message, key, value, flags, perror);
+}
+
+
+bool COSE_Mac0_encrypt(HCOSE_MAC0 h, const byte * pbKey, size_t cbKey, cose_errback * perr)
+{
+ int alg;
+ const cn_cbor * cn_Alg = NULL;
+ byte * pbAuthData = NULL;
+ cn_cbor * pAuthData = NULL;
+ cn_cbor * ptmp = NULL;
+ size_t cbitKey;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = NULL;
+#endif
+ COSE_Mac0Message * pcose = (COSE_Mac0Message *)h;
+ cn_cbor_errback cbor_error;
+
+ CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_PARAMETER);
+
+#ifdef USE_CBOR_CONTEXT
+ context = &pcose->m_message.m_allocContext;
+#endif // USE_CBOR_CONTEXT
+
+ cn_Alg = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ if (cn_Alg == NULL) goto errorReturn;
+ CHECK_CONDITION(((cn_Alg->type == CN_CBOR_UINT || cn_Alg->type == CN_CBOR_INT)), COSE_ERR_INVALID_PARAMETER);
+
+ alg = (int) cn_Alg->v.uint;
+
+ // Get the key size
+
+ switch (alg) {
+ case COSE_Algorithm_CBC_MAC_128_64:
+ case COSE_Algorithm_CBC_MAC_128_128:
+ cbitKey = 128;
+ break;
+
+ case COSE_Algorithm_CBC_MAC_256_64:
+ case COSE_Algorithm_CBC_MAC_256_128:
+ case COSE_Algorithm_HMAC_256_64:
+ case COSE_Algorithm_HMAC_256_256:
+ cbitKey = 256;
+ break;
+
+ case COSE_Algorithm_HMAC_384_384:
+ cbitKey = 384;
+ break;
+
+ case COSE_Algorithm_HMAC_512_512:
+ cbitKey = 512;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+
+ // Build protected headers
+
+ const cn_cbor * cbProtected = _COSE_encode_protected(&pcose->m_message, perr);
+ if (cbProtected == NULL) goto errorReturn;
+
+ // Get the body
+ const cn_cbor * cbBody = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
+ CHECK_CONDITION(cbBody != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ // Build authenticated data
+ // Protected headers
+ // external data
+ // body
+
+ size_t cbAuthData = 0;
+ pAuthData = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
+ CHECK_CONDITION(pAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ ptmp = cn_cbor_string_create("MAC0", CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+ ptmp = NULL;
+
+ ptmp = cn_cbor_data_create(cbProtected->v.bytes, (int) cbProtected->length, CBOR_CONTEXT_PARAM_COMMA NULL);
+ CHECK_CONDITION(ptmp != NULL, COSE_ERR_CBOR);
+
+ CHECK_CONDITION(cn_cbor_array_append(pAuthData, ptmp, NULL), COSE_ERR_CBOR);
+ ptmp = NULL;
+
+ ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+ ptmp = NULL;
+
+ ptmp = cn_cbor_data_create(cbBody->v.bytes, (int) cbBody->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+ ptmp = NULL;
+
+ cbAuthData = cn_cbor_encoder_write(RgbDontUse2, 0, sizeof(RgbDontUse2), pAuthData);
+ CHECK_CONDITION(cbAuthData > 0, COSE_ERR_CBOR);
+ pbAuthData = (byte *)COSE_CALLOC(cbAuthData, 1, context);
+ CHECK_CONDITION(pbAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);
+ CHECK_CONDITION(cn_cbor_encoder_write(pbAuthData, 0, cbAuthData, pAuthData) == cbAuthData, COSE_ERR_CBOR);
+
+ switch (alg) {
+ case COSE_Algorithm_CBC_MAC_128_64:
+ case COSE_Algorithm_CBC_MAC_256_64:
+ if (!AES_CBC_MAC_Create((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_CBC_MAC_128_128:
+ case COSE_Algorithm_CBC_MAC_256_128:
+ if (!AES_CBC_MAC_Create((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_256_64:
+ if (!HMAC_Create((COSE_MacMessage *)pcose, 256, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_256_256:
+ if (!HMAC_Create((COSE_MacMessage *)pcose, 256, 256, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_384_384:
+ if (!HMAC_Create((COSE_MacMessage *)pcose, 384, 384, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_512_512:
+ if (!HMAC_Create((COSE_MacMessage *)pcose, 512, 512, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+
+ // Figure out the clean up
+
+ if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
+ if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
+ if (ptmp != NULL) cn_cbor_free(ptmp CBOR_CONTEXT_PARAM);
+ return true;
+
+errorReturn:
+ if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
+ if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
+ if (ptmp != NULL) cn_cbor_free(ptmp CBOR_CONTEXT_PARAM);
+ return false;
+}
+
+byte RgbDontUseMac[1024];
+
+bool COSE_Mac0_validate(HCOSE_MAC0 h, const byte * pbKey, size_t cbKey, cose_errback * perr)
+{
+ COSE_Mac0Message * pcose = (COSE_Mac0Message *)h;
+ cn_cbor_errback cbor_error;
+ byte * pbAuthData = NULL;
+ int cbitKey = 0;
+
+ int alg;
+ const cn_cbor * cn = NULL;
+
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = NULL;
+#endif
+ ssize_t cbAuthData;
+ cn_cbor * pAuthData = NULL;
+ cn_cbor * ptmp = NULL;
+
+ CHECK_CONDITION(IsValidMac0Handle(h), COSE_ERR_INVALID_PARAMETER);
+
+#ifdef USE_CBOR_CONTEXT
+ context = &pcose->m_message.m_allocContext;
+#endif
+
+ cn = _COSE_map_get_int(&pcose->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ if (cn == NULL) goto errorReturn;
+
+ if (cn->type == CN_CBOR_TEXT) {
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ }
+ else {
+ CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
+
+ alg = (int)cn->v.uint;
+
+ switch (alg) {
+ case COSE_Algorithm_CBC_MAC_128_64:
+ case COSE_Algorithm_CBC_MAC_128_128:
+ cbitKey = 128;
+ break;
+
+ case COSE_Algorithm_CBC_MAC_256_64:
+ case COSE_Algorithm_CBC_MAC_256_128:
+ case COSE_Algorithm_HMAC_256_64:
+ case COSE_Algorithm_HMAC_256_256:
+ cbitKey = 256;
+ break;
+
+ case COSE_Algorithm_HMAC_384_384:
+ cbitKey = 384;
+ break;
+
+ case COSE_Algorithm_HMAC_512_512:
+ cbitKey = 512;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ break;
+ }
+ }
+
+ // Build protected headers
+
+ cn_cbor * cnProtected = _COSE_arrayget_int(&pcose->m_message, INDEX_PROTECTED);
+ CHECK_CONDITION((cnProtected != NULL) && (cnProtected->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
+
+ cn_cbor * cnContent = _COSE_arrayget_int(&pcose->m_message, INDEX_BODY);
+ CHECK_CONDITION((cnContent != NULL) && (cnContent->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
+
+ // Build authenticated data
+ pbAuthData = NULL;
+ pAuthData = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pAuthData != NULL, cbor_error);
+
+ ptmp = cn_cbor_string_create("MAC0", CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+
+ ptmp = cn_cbor_data_create(cnProtected->v.bytes, (int) cnProtected->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+
+ ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+
+ ptmp = cn_cbor_data_create(cnContent->v.bytes, (int) cnContent->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
+
+ cbAuthData = cn_cbor_encoder_write(RgbDontUseMac, 0, sizeof(RgbDontUseMac), pAuthData);
+ pbAuthData = (byte *)COSE_CALLOC(cbAuthData, 1, context);
+ CHECK_CONDITION(pbAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);
+ CHECK_CONDITION((cn_cbor_encoder_write(pbAuthData, 0, cbAuthData+1, pAuthData) == cbAuthData), COSE_ERR_CBOR); // M00HACK
+
+ switch (alg) {
+ case COSE_Algorithm_HMAC_256_256:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 256, 256, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_256_64:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 256, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_384_384:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 384, 384, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_HMAC_512_512:
+ if (!HMAC_Validate((COSE_MacMessage *)pcose, 512, 512, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_CBC_MAC_128_64:
+ case COSE_Algorithm_CBC_MAC_256_64:
+ if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 64, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_CBC_MAC_128_128:
+ case COSE_Algorithm_CBC_MAC_256_128:
+ if (!AES_CBC_MAC_Validate((COSE_MacMessage *)pcose, 128, pbKey, cbKey, pbAuthData, cbAuthData, perr)) goto errorReturn;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ break;
+ }
+
+ if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
+ if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
+
+ return true;
+
+errorReturn:
+ if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
+ if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
+
+ return false;
+}
diff --git a/src/Recipient.c b/src/Recipient.c
index 93cf834..cb1dc80 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -6,10 +6,14 @@
#include "configure.h"
#include "crypto.h"
+COSE* RecipientRoot = NULL;
+
bool IsValidRecipientHandle(HCOSE_RECIPIENT h)
{
- if (h == NULL) return false;
- return true;
+ COSE_RecipientInfo * p = (COSE_RecipientInfo *)h;
+
+ if (p == NULL) return false;
+ return _COSE_IsInList(RecipientRoot, &p->m_encrypt.m_message);
}
HCOSE_RECIPIENT COSE_Recipient_Init(CBOR_CONTEXT_COMMA cose_errback * perror)
@@ -25,17 +29,21 @@
return NULL;
}
+ _COSE_InsertInList(&RecipientRoot, &pobj->m_encrypt.m_message);
return (HCOSE_RECIPIENT)pobj;
}
bool COSE_Recipient_Free(HCOSE_RECIPIENT hRecipient)
{
if (IsValidRecipientHandle(hRecipient)) {
+ COSE_RecipientInfo * p = (COSE_RecipientInfo *)hRecipient;
+ _COSE_RemoveFromList(&RecipientRoot, &p->m_encrypt.m_message);
- _COSE_Recipient_Free((COSE_RecipientInfo *)hRecipient);
+ _COSE_Recipient_Free(p);
return true;
}
+
return false;
}
@@ -82,6 +90,8 @@
goto errorReturn;
}
+ _COSE_InsertInList(&RecipientRoot, &pRecipient->m_encrypt.m_message);
+
return pRecipient;
errorReturn:
@@ -204,8 +214,6 @@
return true;
}
-byte RgbDontUse9[8 * 1024];
-
bool _COSE_Recipient_encrypt(COSE_RecipientInfo * pRecipient, const byte * pbContent, size_t cbContent, cose_errback * perr)
{
int alg;
@@ -290,25 +298,8 @@
if (cbProtected == NULL) goto errorReturn;
// Build authenticated data
- ssize_t cbAuthData = 0;
- pbAuthData = NULL;
- pAuthData = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
- CHECK_CONDITION_CBOR(pAuthData != NULL, cbor_error);
-
- ptmp = cn_cbor_data_create(cbProtected->v.bytes, (int)cbProtected->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
- CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
- CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
- ptmp = NULL;
-
- ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
- CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
- CHECK_CONDITION_CBOR(cn_cbor_array_append(pAuthData, ptmp, &cbor_error), cbor_error);
- ptmp = NULL;
-
- cbAuthData = cn_cbor_encoder_write(RgbDontUse9, 0, sizeof(RgbDontUse9), pAuthData);
- pbAuthData = (byte *)COSE_CALLOC(cbAuthData, 1, context);
- CHECK_CONDITION(pbAuthData != NULL, COSE_ERR_OUT_OF_MEMORY);
- CHECK_CONDITION(cn_cbor_encoder_write(pbAuthData, 0, cbAuthData, pAuthData) == cbAuthData, COSE_ERR_CBOR);
+ size_t cbAuthData = 0;
+ if (!_COSE_Encrypt_Build_AAD(&pRecipient->m_encrypt.m_message, &pbAuthData, &cbAuthData, "Recipient", perr)) goto errorReturn;
switch (alg) {
diff --git a/src/Sign0.c b/src/Sign0.c
new file mode 100644
index 0000000..5b7201a
--- /dev/null
+++ b/src/Sign0.c
@@ -0,0 +1,378 @@
+#include <stdlib.h>
+
+#include "cose.h"
+#include "cose_int.h"
+#include "crypto.h"
+
+bool _COSE_Signer0_sign(COSE_Sign0Message * pSigner, const cn_cbor * pKey, cose_errback * perr);
+bool _COSE_Signer0_validate(COSE_Sign0Message * pSign, const cn_cbor * pKey, cose_errback * perr);
+void _COSE_Sign0_Release(COSE_Sign0Message * p);
+
+
+
+bool IsValidSign0Handle(HCOSE_SIGN0 h)
+{
+ COSE_Sign0Message * p = (COSE_Sign0Message *)h;
+ if (p == NULL) return false;
+ return true;
+}
+
+
+HCOSE_SIGN0 COSE_Sign0_Init(CBOR_CONTEXT_COMMA cose_errback * perror)
+{
+ COSE_Sign0Message * pobj = (COSE_Sign0Message *)COSE_CALLOC(1, sizeof(COSE_Sign0Message), context);
+ if (pobj == NULL) {
+ if (perror != NULL) perror->err = COSE_ERR_OUT_OF_MEMORY;
+ return NULL;
+ }
+
+ if (!_COSE_Init(&pobj->m_message, COSE_sign_object, CBOR_CONTEXT_PARAM_COMMA perror)) {
+ COSE_Sign0_Free((HCOSE_SIGN0)pobj);
+ return NULL;
+ }
+
+ return (HCOSE_SIGN0)pobj;
+}
+
+HCOSE_SIGN0 _COSE_Sign0_Init_From_Object(cn_cbor * cbor, COSE_Sign0Message * pIn, CBOR_CONTEXT_COMMA cose_errback * perr)
+{
+ COSE_Sign0Message * pobj = pIn;
+ cn_cbor * pSigners = NULL;
+ // cn_cbor * tmp;
+ cose_errback error = { 0 };
+ if (perr == NULL) perr = &error;
+
+ if (pobj == NULL) pobj = (COSE_Sign0Message *)COSE_CALLOC(1, sizeof(COSE_Sign0Message), context);
+ CHECK_CONDITION(pobj != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ if (!_COSE_Init_From_Object(&pobj->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
+ goto errorReturn;
+ }
+
+ return(HCOSE_SIGN0)pobj;
+
+errorReturn:
+ if ((pIn == NULL) && (pobj != NULL)) COSE_FREE(pobj, context);
+ return NULL;
+}
+
+bool COSE_Sign0_Free(HCOSE_SIGN0 h)
+{
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context context;
+#endif
+ COSE_Sign0Message * pMessage = (COSE_Sign0Message *)h;
+
+ if (!IsValidSign0Handle(h)) return false;
+
+ // Check reference counting
+ if (pMessage->m_message.m_refCount > 1) {
+ pMessage->m_message.m_refCount--;
+ return true;
+ }
+
+#ifdef USE_CBOR_CONTEXT
+ context = pMessage->m_message.m_allocContext;
+#endif
+
+ _COSE_Sign0_Release(pMessage);
+
+ COSE_FREE(pMessage, &context);
+
+ return true;
+}
+
+void _COSE_Sign0_Release(COSE_Sign0Message * p)
+{
+ _COSE_Release(&p->m_message);
+}
+
+bool COSE_Sign0_SetContent(HCOSE_SIGN0 h, const byte * rgb, size_t cb, cose_errback * perr)
+{
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = NULL;
+#endif
+ cn_cbor * p = NULL;
+ COSE_Sign0Message * pMessage = (COSE_Sign0Message *)h;
+
+ if (!IsValidSign0Handle(h) || (rgb == NULL)) {
+ if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
+ errorReturn:
+ if (p != NULL) CN_CBOR_FREE(p, context);
+ return false;
+ }
+
+#ifdef USE_CBOR_CONTEXT
+ context = &pMessage->m_message.m_allocContext;
+#endif
+
+ p = cn_cbor_data_create(rgb, (int) cb, CBOR_CONTEXT_PARAM_COMMA NULL);
+ CHECK_CONDITION(p != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ CHECK_CONDITION(_COSE_array_replace(&pMessage->m_message, p, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_OUT_OF_MEMORY);
+
+ return true;
+}
+
+bool COSE_Sign0_Sign(HCOSE_SIGN0 h, const cn_cbor * pKey, cose_errback * perr)
+{
+#ifdef USE_CBOR_CONTEXT
+ // cn_cbor_context * context = NULL;
+#endif
+ COSE_Sign0Message * pMessage = (COSE_Sign0Message *)h;
+ const cn_cbor * pcborProtected;
+
+ if (!IsValidSign0Handle(h)) {
+ CHECK_CONDITION(false, COSE_ERR_INVALID_PARAMETER);
+ errorReturn:
+ return false;
+ }
+#ifdef USE_CBOR_CONTEXT
+ // context = &pMessage->m_message.m_allocContext;
+#endif
+
+ pcborProtected = _COSE_encode_protected(&pMessage->m_message, perr);
+ if (pcborProtected == NULL) goto errorReturn;
+
+ if (!_COSE_Signer0_sign(pMessage, pKey, perr)) goto errorReturn;
+
+ return true;
+}
+
+bool COSE_Sign0_validate(HCOSE_SIGN0 hSign, const cn_cbor * pKey, cose_errback * perr)
+{
+ bool f;
+ COSE_Sign0Message * pSign;
+ const cn_cbor * cnContent;
+ const cn_cbor * cnProtected;
+
+ CHECK_CONDITION(IsValidSign0Handle(hSign), COSE_ERR_INVALID_PARAMETER);
+
+ pSign = (COSE_Sign0Message *)hSign;
+
+ cnContent = _COSE_arrayget_int(&pSign->m_message, INDEX_BODY);
+ CHECK_CONDITION(cnContent != NULL && cnContent->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
+
+ cnProtected = _COSE_arrayget_int(&pSign->m_message, INDEX_PROTECTED);
+ CHECK_CONDITION(cnProtected != NULL && cnContent->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
+
+ f = _COSE_Signer0_validate(pSign, pKey, perr);
+
+ return f;
+
+errorReturn:
+ return false;
+}
+
+
+cn_cbor * COSE_Sign0_map_get_int(HCOSE_SIGN0 h, int key, int flags, cose_errback * perror)
+{
+ if (!IsValidSign0Handle(h)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return NULL;
+ }
+
+ return _COSE_map_get_int(&((COSE_Sign0Message *)h)->m_message, key, flags, perror);
+}
+
+bool COSE_Sign0_map_put_int(HCOSE_SIGN0 h, int key, cn_cbor * value, int flags, cose_errback * perror)
+{
+ if (!IsValidSign0Handle(h) || (value == NULL)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return false;
+ }
+
+ return _COSE_map_put(&((COSE_Sign0Message *)h)->m_message, key, value, flags, perror);
+}
+
+
+byte RgbDontUse4[8 * 1024];
+byte RgbDontUseSign[8 * 1024];
+
+static bool CreateSign0AAD(COSE_Sign0Message * pMessage, byte ** ppbToSign, size_t * pcbToSign, char * szContext, cose_errback * perr)
+{
+ cn_cbor * pArray = NULL;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = &pMessage->m_message.m_allocContext;
+#endif
+ cn_cbor_errback cbor_error;
+ cn_cbor * cn = NULL;
+ cn_cbor * cn2;
+ size_t cbToSign;
+ byte * pbToSign = NULL;
+
+ pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pArray != NULL, cbor_error);
+
+ cn = cn_cbor_string_create(szContext, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
+
+ cn2 = _COSE_arrayget_int(&pMessage->m_message, INDEX_PROTECTED);
+
+ cn = cn_cbor_data_create(cn2->v.bytes, (int)cn2->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
+
+ cn = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
+
+ cn2 = _COSE_arrayget_int(&pMessage->m_message, INDEX_BODY);
+ cn = cn_cbor_data_create(cn2->v.bytes, (int)cn2->length, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(cn != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_array_append(pArray, cn, &cbor_error), cbor_error);
+ cn = NULL;
+
+
+ cbToSign = cn_cbor_encoder_write(RgbDontUse4, 0, sizeof(RgbDontUse4), pArray);
+ CHECK_CONDITION(cbToSign > 0, COSE_ERR_CBOR);
+ pbToSign = (byte *)COSE_CALLOC(cbToSign, 1, context);
+ CHECK_CONDITION(pbToSign != NULL, COSE_ERR_OUT_OF_MEMORY);
+ CHECK_CONDITION(cn_cbor_encoder_write(pbToSign, 0, cbToSign, pArray), COSE_ERR_CBOR);
+
+ *ppbToSign = pbToSign;
+ *pcbToSign = cbToSign;
+ pbToSign = NULL;
+
+ if (cn != NULL) CN_CBOR_FREE(cn, context);
+ if (pArray != NULL) COSE_FREE(pArray, context);
+ return true;
+
+errorReturn:
+ if (pbToSign != NULL) COSE_FREE(pbToSign, context);
+ if (cn != NULL) CN_CBOR_FREE(cn, context);
+ if (pArray != NULL) COSE_FREE(pArray, context);
+ return false;
+}
+
+bool _COSE_Signer0_sign(COSE_Sign0Message * pSigner, const cn_cbor * pKey, cose_errback * perr)
+{
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = &pSigner->m_message.m_allocContext;
+#endif
+ cn_cbor * pcborBody2 = NULL;
+ cn_cbor * pcborProtected2 = NULL;
+ cn_cbor * pArray = NULL;
+ cn_cbor * cn = NULL;
+ size_t cbToSign;
+ byte * pbToSign = NULL;
+ bool f;
+ int alg;
+
+ pArray = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (pArray == NULL) {
+ if (perr != NULL) perr->err = COSE_ERR_OUT_OF_MEMORY;
+ errorReturn:
+ if (cn != NULL) CN_CBOR_FREE(cn, context);
+ if (pcborBody2 != NULL) CN_CBOR_FREE(pcborBody2, context);
+ if (pcborProtected2 != NULL) CN_CBOR_FREE(pcborProtected2, context);
+ if (pArray != NULL) COSE_FREE(pArray, context);
+ if (pbToSign != NULL) COSE_FREE(pbToSign, context);
+ return false;
+ }
+
+ cn = _COSE_map_get_int(&pSigner->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ if (cn == NULL) goto errorReturn;
+
+ if (cn->type == CN_CBOR_TEXT) {
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ }
+ else {
+ CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
+
+ alg = (int)cn->v.uint;
+ }
+
+
+ if (!CreateSign0AAD(pSigner, &pbToSign, &cbToSign, "Signature1", perr)) goto errorReturn;
+
+ switch (alg) {
+ case COSE_Algorithm_ECDSA_SHA_256:
+ f = ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE+1, pKey, 256, pbToSign, cbToSign, perr);
+ break;
+
+ case COSE_Algorithm_ECDSA_SHA_384:
+ f = ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE+1, pKey, 384, pbToSign, cbToSign, perr);
+ break;
+
+ case COSE_Algorithm_ECDSA_SHA_512:
+ f = ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE+1, pKey, 512, pbToSign, cbToSign, perr);
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+
+ COSE_FREE(pbToSign, context);
+ CN_CBOR_FREE(pArray, context);
+
+ return f;
+}
+
+bool _COSE_Signer0_validate(COSE_Sign0Message * pSign, const cn_cbor * pKey, cose_errback * perr)
+{
+ byte * pbToSign = NULL;
+ int alg;
+ const cn_cbor * cn = NULL;
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = NULL;
+#endif
+ size_t cbToSign;
+ cn_cbor * pAuthData = NULL;
+ cn_cbor * cnSignature = NULL;
+
+#ifdef USE_CBOR_CONTEXT
+ context = &pSign->m_message.m_allocContext;
+#endif
+
+ cn = _COSE_map_get_int(&pSign->m_message, COSE_Header_Algorithm, COSE_BOTH, perr);
+ if (cn == NULL) goto errorReturn;
+
+ if (cn->type == CN_CBOR_TEXT) {
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ }
+ else {
+ CHECK_CONDITION((cn->type == CN_CBOR_UINT || cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
+
+ alg = (int)cn->v.uint;
+ }
+
+ // Build protected headers
+
+ if (!CreateSign0AAD(pSign, &pbToSign, &cbToSign, "Signature1", perr)) goto errorReturn;
+
+ cnSignature = _COSE_arrayget_int(&pSign->m_message, INDEX_SIGNATURE);
+
+ switch (alg) {
+ case COSE_Algorithm_ECDSA_SHA_256:
+ if (!ECDSA_Verify(&pSign->m_message, INDEX_SIGNATURE+1, pKey, 256, pbToSign, cbToSign, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_ECDSA_SHA_384:
+ if (!ECDSA_Verify(&pSign->m_message, INDEX_SIGNATURE+1, pKey, 384, pbToSign, cbToSign, perr)) goto errorReturn;
+ break;
+
+ case COSE_Algorithm_ECDSA_SHA_512:
+ if (!ECDSA_Verify(&pSign->m_message, INDEX_SIGNATURE+1, pKey, 512, pbToSign, cbToSign, perr)) goto errorReturn;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
+ break;
+ }
+
+ if (pbToSign != NULL) COSE_FREE(pbToSign, context);
+ if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
+
+ return true;
+
+errorReturn:
+ if (pbToSign != NULL) COSE_FREE(pbToSign, context);
+ if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
+
+ return false;
+}
diff --git a/src/SignerInfo.c b/src/SignerInfo.c
index a2ed0b6..8165bbd 100644
--- a/src/SignerInfo.c
+++ b/src/SignerInfo.c
@@ -169,15 +169,15 @@
switch (alg) {
case COSE_Algorithm_ECDSA_SHA_256:
- f = ECDSA_Sign(pSigner, 256, pbToSign, cbToSign, perr);
+ f = ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE, pSigner->m_pkey, 256, pbToSign, cbToSign, perr);
break;
case COSE_Algorithm_ECDSA_SHA_384:
- f = ECDSA_Sign(pSigner, 384, pbToSign, cbToSign, perr);
+ f = ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE, pSigner->m_pkey, 384, pbToSign, cbToSign, perr);
break;
case COSE_Algorithm_ECDSA_SHA_512:
- f = ECDSA_Sign(pSigner, 512, pbToSign, cbToSign, perr);
+ f = ECDSA_Sign(&pSigner->m_message, INDEX_SIGNATURE, pSigner->m_pkey, 512, pbToSign, cbToSign, perr);
break;
default:
@@ -276,15 +276,15 @@
switch (alg) {
case COSE_Algorithm_ECDSA_SHA_256:
- if (!ECDSA_Verify(pSigner, 256, pbAuthData, cbAuthData, cnSignature->v.bytes, cnSignature->length, perr)) goto errorReturn;
+ if (!ECDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE, pSigner->m_pkey, 256, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDSA_SHA_384:
- if (!ECDSA_Verify(pSigner, 384, pbAuthData, cbAuthData, cnSignature->v.bytes, cnSignature->length, perr)) goto errorReturn;
+ if (!ECDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE, pSigner->m_pkey, 384, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
case COSE_Algorithm_ECDSA_SHA_512:
- if (!ECDSA_Verify(pSigner, 512, pbAuthData, cbAuthData, cnSignature->v.bytes, cnSignature->length, perr)) goto errorReturn;
+ if (!ECDSA_Verify(&pSigner->m_message, INDEX_SIGNATURE, pSigner->m_pkey, 512, pbAuthData, cbAuthData, perr)) goto errorReturn;
break;
default:
diff --git a/src/cose.h b/src/cose.h
index 99e47ae..7f7c0a0 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -5,10 +5,12 @@
typedef struct _cose * HCOSE;
typedef struct _cose_sign * HCOSE_SIGN;
typedef struct _cose_signer * HCOSE_SIGNER;
+typedef struct _cose_sign0 * HCOSE_SIGN0;
typedef struct _cose_encrypt * HCOSE_ENCRYPT;
typedef struct _cose_enveloped * HCOSE_ENVELOPED;
typedef struct _cose_recipient * HCOSE_RECIPIENT;
typedef struct _cose_mac * HCOSE_MAC;
+typedef struct _cose_mac0 * HCOSE_MAC0;
/**
* All of the different kinds of errors
@@ -43,7 +45,7 @@
typedef enum {
COSE_unknown_object = 0,
COSE_sign_object = 991,
- COSE_sign1_object = 997,
+ COSE_sign0_object = 997,
COSE_enveloped_object = 992,
COSE_encrypt_object = 993,
COSE_mac_object = 994,
@@ -206,7 +208,7 @@
bool COSE_Mac_SetContent(HCOSE_MAC cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
cn_cbor * COSE_Mac_map_get_int(HCOSE_MAC h, int key, int flags, cose_errback * perror);
-bool COSE_Mac_map_put(HCOSE_MAC cose, int key, cn_cbor * value, int flags, cose_errback * errp);
+bool COSE_Mac_map_put_int(HCOSE_MAC cose, int key, cn_cbor * value, int flags, cose_errback * errp);
bool COSE_Mac_encrypt(HCOSE_MAC cose, cose_errback * perror);
bool COSE_Mac_validate(HCOSE_MAC, HCOSE_RECIPIENT, cose_errback * perr);
@@ -216,6 +218,19 @@
extern bool COSE_Mac_AddRecipient(HCOSE_MAC hMac, HCOSE_RECIPIENT hRecip, cose_errback * perr);
HCOSE_RECIPIENT COSE_Mac_GetRecipient(HCOSE_MAC cose, int iRecipient, cose_errback * perr);
+// MAC0 calls
+
+HCOSE_MAC0 COSE_Mac0_Init(CBOR_CONTEXT_COMMA cose_errback * perr);
+bool COSE_Mac0_Free(HCOSE_MAC0 cose);
+
+bool COSE_Mac0_SetContent(HCOSE_MAC0 cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
+
+cn_cbor * COSE_Mac0_map_get_int(HCOSE_MAC0 h, int key, int flags, cose_errback * perror);
+bool COSE_Mac0_map_put_int(HCOSE_MAC0 cose, int key, cn_cbor * value, int flags, cose_errback * errp);
+
+bool COSE_Mac0_encrypt(HCOSE_MAC0 cose, const byte * pbKey, size_t cbKey, cose_errback * perror);
+bool COSE_Mac0_validate(HCOSE_MAC0, const byte * pbKey, size_t cbKey, cose_errback * perr);
+
//
//
@@ -233,3 +248,15 @@
bool COSE_Signer_Free(HCOSE_SIGNER cose);
bool COSE_Signer_SetKey(HCOSE_SIGNER hSigner, const cn_cbor * pkey, cose_errback * perr);
bool COSE_Signer_map_put(HCOSE_SIGNER cose, int key, cn_cbor * value, int flags, cose_errback * errp);
+
+/*
+ * Sign routines
+ */
+
+HCOSE_SIGN0 COSE_Sign0_Init(CBOR_CONTEXT_COMMA cose_errback * perr);
+bool COSE_Sign0_Free(HCOSE_SIGN0 cose);
+bool COSE_Sign0_SetContent(HCOSE_SIGN0 cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
+bool COSE_Sign0_Sign(HCOSE_SIGN0 h, const cn_cbor * pkey, cose_errback * perr);
+bool COSE_Sign0_validate(HCOSE_SIGN0 hSign, const cn_cbor * pkey, cose_errback * perr);
+cn_cbor * COSE_Sign0_map_get_int(HCOSE_SIGN0 h, int key, int flags, cose_errback * perror);
+bool COSE_Sign0_map_put_int(HCOSE_SIGN0 cose, int key, cn_cbor * value, int flags, cose_errback * errp);
diff --git a/src/cose_int.h b/src/cose_int.h
index 5640946..65317f4 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -28,6 +28,10 @@
COSE_SignerInfo * m_signerFirst;
} COSE_SignMessage;
+typedef struct {
+ COSE m_message; // The message object
+} COSE_Sign0Message;
+
struct _SignerInfo {
COSE m_message;
byte * pbKey;
@@ -64,11 +68,15 @@
typedef struct {
COSE m_message; // The message object
- COSE_RecipientInfo * m_recipientFirst;
byte * pbKey;
size_t cbKey;
+ COSE_RecipientInfo * m_recipientFirst;
} COSE_MacMessage;
+typedef struct {
+ COSE m_message; // The message object
+} COSE_Mac0Message;
+
#ifdef USE_CBOR_CONTEXT
/**
* Allocate enough space for 1 `cn_cbor` structure.
@@ -179,8 +187,14 @@
extern HCOSE_MAC _COSE_Mac_Init_From_Object(cn_cbor *, COSE_MacMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
extern bool _COSE_Mac_Release(COSE_MacMessage * p);
+// MAC0 Items
+extern HCOSE_MAC0 _COSE_Mac0_Init_From_Object(cn_cbor *, COSE_Mac0Message * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
+extern bool _COSE_Mac0_Release(COSE_Mac0Message * p);
-#define CHECK_CONDITION(condition, error) { if (!(condition)) { /*assert(false);*/ perr->err = error; goto errorReturn;}}
+//
+// Debugging Items
+
+#define CHECK_CONDITION(condition, error) { if (!(condition)) { assert(false); perr->err = error; goto errorReturn;}}
#define FAIL_CONDITION(error) { assert(false); perr->err = error; goto errorReturn;}
#define CHECK_CONDITION_CBOR(condition, error) { if (!(condition)) { assert(false); perr->err = _MapFromCBOR(error); goto errorReturn;}}
diff --git a/src/crypto.h b/src/crypto.h
index c8728ca..8f7c8df 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 * pbKey, int cbitKey, 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, size_t 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 TagSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
+extern bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int TagSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr);
+extern bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int TagSize, const byte * pbKey, size_t cbitKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr);
/**
* Perform an HMAC Creation operation
@@ -43,8 +43,8 @@
* @param[in] cose_errback * Error return location
* @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 * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr);
+bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr);
+bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbitKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr);
/**
* Perform a signature operation
@@ -55,8 +55,8 @@
* @param[in] cose_errback * Error return location
* @return Did the function succeed?
*/
-bool ECDSA_Sign(COSE_SignerInfo * pSigner, int cbitsDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr);
-bool ECDSA_Verify(COSE_SignerInfo * pSigner, int cbitsDigest, const byte * rgbToSign, size_t cbToSign, const byte * rgbSig, size_t cbSig, cose_errback * perr);
+bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitsDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr);
+bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitsDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr);
/**
* Generate random bytes in a buffer
diff --git a/src/openssl.c b/src/openssl.c
index 90d8db3..4ddfe97 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -376,7 +376,7 @@
}
-bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int KeySize, int TSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
+bool AES_CBC_MAC_Create(COSE_MacMessage * pcose, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
const EVP_CIPHER * pcipher = NULL;
EVP_CIPHER_CTX ctx;
@@ -393,7 +393,7 @@
rgbOut = COSE_CALLOC(16, 1, context);
CHECK_CONDITION(rgbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
- switch (KeySize) {
+ switch (cbKey*8) {
case 128:
pcipher = EVP_aes_128_cbc();
break;
@@ -409,7 +409,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);
for (i = 0; i < (unsigned int)cbAuthData / 16; i++) {
CHECK_CONDITION(EVP_EncryptUpdate(&ctx, rgbOut, &cbOut, pbAuthData + (i * 16), 16), COSE_ERR_CRYPTO_FAIL);
@@ -436,7 +436,7 @@
return false;
}
-bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int TSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
+bool AES_CBC_MAC_Validate(COSE_MacMessage * pcose, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
const EVP_CIPHER * pcipher = NULL;
EVP_CIPHER_CTX ctx;
@@ -446,7 +446,7 @@
bool f = false;
unsigned int i;
- switch (cbitKey) {
+ switch (cbKey*8) {
case 128:
pcipher = EVP_aes_128_cbc();
break;
@@ -536,7 +536,7 @@
}
#endif
-bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
+bool HMAC_Create(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t cbAuthData, cose_errback * perr)
{
HMAC_CTX ctx;
const EVP_MD * pmd = NULL;
@@ -565,7 +565,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, (int) cbKey, 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);
@@ -575,7 +575,7 @@
return true;
}
-bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, int cbitKey, const byte * pbAuthData, int cbAuthData, cose_errback * perr)
+bool HMAC_Validate(COSE_MacMessage * pcose, int HSize, int TSize, const byte * pbKey, size_t cbKey, const byte * pbAuthData, size_t 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, pbKey, cbitKey/8, pmd), COSE_ERR_CRYPTO_FAIL);
+ CHECK_CONDITION(HMAC_Init(&ctx, pbKey, (int) cbKey, 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);
@@ -702,7 +702,7 @@
}
*/
-bool ECDSA_Sign(COSE_SignerInfo * pSigner, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
+bool ECDSA_Sign(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
EC_KEY * eckey = NULL;
byte rgbDigest[EVP_MAX_MD_SIZE];
@@ -710,7 +710,7 @@
byte * pbSig = NULL;
const EVP_MD * digest;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = &pSigner->m_message.m_allocContext;
+ cn_cbor_context * context = &pSigner->m_allocContext;
#endif
cn_cbor * p = NULL;
ECDSA_SIG * psig = NULL;
@@ -719,7 +719,7 @@
byte rgbSig[66];
int cb;
- eckey = ECKey_From(pSigner->m_pkey, &cbR, perr);
+ eckey = ECKey_From(pKey, &cbR, perr);
if (eckey == NULL) {
errorReturn:
if (p != NULL) CN_CBOR_FREE(p, context);
@@ -743,8 +743,6 @@
pbSig = COSE_CALLOC(cbR, 2, context);
CHECK_CONDITION(pbSig != NULL, COSE_ERR_OUT_OF_MEMORY);
-
-
cb = BN_bn2bin(psig->r, rgbSig);
CHECK_CONDITION(cb <= cbR, COSE_ERR_INVALID_PARAMETER);
memcpy(pbSig + cbR - cb, rgbSig, cb);
@@ -756,25 +754,27 @@
p = cn_cbor_data_create(pbSig, cbR*2, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
CHECK_CONDITION_CBOR(p != NULL, cbor_error);
- CHECK_CONDITION(_COSE_array_replace(&pSigner->m_message, p, INDEX_SIGNATURE, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
+ CHECK_CONDITION(_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
return true;
}
-bool ECDSA_Verify(COSE_SignerInfo * pSigner, int cbitDigest, const byte * rgbToSign, size_t cbToSign, const byte * rgbSignature, size_t cbSignature, cose_errback * perr)
+bool ECDSA_Verify(COSE * pSigner, int index, const cn_cbor * pKey, int cbitDigest, const byte * rgbToSign, size_t cbToSign, cose_errback * perr)
{
EC_KEY * eckey = NULL;
byte rgbDigest[EVP_MAX_MD_SIZE];
unsigned int cbDigest = sizeof(rgbDigest);
const EVP_MD * digest;
#ifdef USE_CBOR_CONTEXT
- cn_cbor_context * context = &pSigner->m_message.m_allocContext;
+ cn_cbor_context * context = &pSigner->m_allocContext;
#endif
cn_cbor * p = NULL;
ECDSA_SIG sig = { NULL, NULL };
int cbR;
+ cn_cbor * pSig;
+ size_t cbSignature;
- eckey = ECKey_From(pSigner->m_pkey, &cbR, perr);
+ eckey = ECKey_From(pKey, &cbR, perr);
if (eckey == NULL) {
errorReturn:
if (sig.r != NULL) BN_free(sig.r);
@@ -793,14 +793,19 @@
}
EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, digest, NULL);
+ pSig = _COSE_arrayget_int(pSigner, index);
+ CHECK_CONDITION(pSig != NULL, CN_CBOR_ERR_INVALID_PARAMETER);
+ cbSignature = pSig->length;
+
CHECK_CONDITION(cbSignature / 2 == cbR, COSE_ERR_INVALID_PARAMETER);
- sig.r = BN_bin2bn(rgbSignature,(int) cbSignature/2, NULL);
- sig.s = BN_bin2bn(rgbSignature+cbSignature/2, (int) cbSignature/2, NULL);
+ sig.r = BN_bin2bn(pSig->v.bytes,(int) cbSignature/2, NULL);
+ sig.s = BN_bin2bn(pSig->v.bytes+cbSignature/2, (int) cbSignature/2, NULL);
CHECK_CONDITION(ECDSA_do_verify(rgbDigest, cbDigest, &sig, eckey) == 1, COSE_ERR_CRYPTO_FAIL);
BN_free(sig.r);
BN_free(sig.s);
+ if (eckey != NULL) EC_KEY_free(eckey);
return true;
}
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 65ba3c0..03690ae 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -51,6 +51,17 @@
add_test ( NAME cbc-mac-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-03.json )
add_test ( NAME cbc-mac-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-04.json )
+add_test ( NAME hmac-enc01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/Hmac-Enc01.json )
+add_test ( NAME hmac-enc02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/Hmac-Enc02.json )
+add_test ( NAME hmac-enc03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/Hmac-Enc03.json )
+add_test ( NAME hmac-enc04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/Hmac-Enc04.json )
+add_test ( NAME hmac-enc05 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/Hmac-Enc05.json )
+
+add_test ( NAME cbc-mac-enc-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-01.json )
+add_test ( NAME cbc-mac-enc-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-02.json )
+add_test ( NAME cbc-mac-enc-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-03.json )
+add_test ( NAME cbc-mac-enc-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/cbc-mac-examples/cbc-mac-enc-04.json )
+
add_test ( NAME aes-gcm-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-01.json )
add_test ( NAME aes-gcm-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-02.json )
add_test ( NAME aes-gcm-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/aes-gcm-examples/aes-gcm-03.json )
diff --git a/test/mac_test.c b/test/mac_test.c
index 725c389..113f254 100644
--- a/test/mac_test.c
+++ b/test/mac_test.c
@@ -162,7 +162,7 @@
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_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);
COSE_Mac_SetContent(hEncObj, (byte *) sz, strlen(sz), NULL);
COSE_Mac_add_shared_secret(hEncObj, COSE_Algorithm_Direct, rgbSecret, sizeof(rgbSecret), rgbKid, cbKid, NULL);
@@ -216,3 +216,121 @@
return 1;
}
+
+
+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;
+ const cn_cbor * pMac;
+ const cn_cbor * pRecipients;
+ HCOSE_MAC0 hMAC;
+ int type;
+ 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_MAC0)COSE_Decode(pbEncoded, cbEncoded, &type, COSE_mac0_object, CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (hMAC == NULL) exit(1);
+
+ if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) exit(1);
+ pMac = cn_cbor_mapget_string(pInput, "mac0");
+ 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);
+
+ pRecipients = pRecipients->first_child;
+
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"));
+ if (pkey == NULL) {
+ fFail = true;
+ goto exitHere;
+ }
+
+ cn_cbor *k = cn_cbor_mapget_int(pkey, -1);
+
+ pFail = cn_cbor_mapget_string(pRecipients, "fail");
+ if (COSE_Mac0_validate(hMAC, k->v.bytes, k->length, NULL)) {
+ if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) fFail = true;
+ }
+ else {
+ if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) fFail = true;
+ }
+
+
+ COSE_Mac0_Free(hMAC);
+
+ if (fFailBody) {
+ if (!fFail) fFail = true;
+ else fFail = false;
+ }
+ exitHere:
+ if (fFail) CFails += 1;
+ return 0;
+}
+
+int ValidateMac0(const cn_cbor * pControl)
+{
+ int cbEncoded;
+ byte * pbEncoded = GetCBOREncoding(pControl, &cbEncoded);
+
+ return _ValidateMac0(pControl, pbEncoded, cbEncoded);
+}
+
+int BuildMac0Message(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 != NULL) && (pFail->type == CN_CBOR_TRUE)) return 0;
+
+ HCOSE_MAC0 hMacObj = COSE_Mac0_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, "mac0");
+ if (pMac == NULL) exit(1);
+
+ const cn_cbor * pContent = cn_cbor_mapget_string(pInputs, "plaintext");
+ if (!COSE_Mac0_SetContent(hMacObj, pContent->v.bytes, pContent->length, NULL)) goto returnError;
+
+ if (!SetAttributes((HCOSE)hMacObj, cn_cbor_mapget_string(pMac, "protected"), Attributes_MAC0_protected)) goto returnError;
+ if (!SetAttributes((HCOSE)hMacObj, cn_cbor_mapget_string(pMac, "unprotected"), Attributes_MAC0_unprotected)) goto returnError;
+
+ const cn_cbor * pAlg = COSE_Mac0_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;
+
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pRecipients, "key"));
+ if (pkey == NULL) exit(1);
+
+ cn_cbor * k = cn_cbor_mapget_int(pkey, -1);
+
+ if (!COSE_Mac0_encrypt(hMacObj, k->v.bytes, k->length, 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_Mac0_Free(hMacObj);
+
+ int f = _ValidateMac0(pControl, rgb, cb);
+
+ free(rgb);
+ return f;
+
+returnError:
+ CFails += 1;
+ return 1;
+}
diff --git a/test/sign.c b/test/sign.c
index 136cf47..28734b2 100644
--- a/test/sign.c
+++ b/test/sign.c
@@ -239,3 +239,119 @@
return 1;
}
+
+
+int _ValidateSign0(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 * pSign;
+ HCOSE_SIGN0 hSig;
+ int type;
+ bool fFail = false;
+ bool fFailBody = false;
+
+#ifdef USE_CBOR_CONTEXT
+ allocator = CreateContext();
+#endif
+
+ pFail = cn_cbor_mapget_string(pControl, "fail");
+ if ((pFail != NULL) && (pFail->type == CN_CBOR_TRUE)) {
+ fFailBody = true;
+ }
+
+ if ((pInput == NULL) || (pInput->type != CN_CBOR_MAP)) exit(1);
+ pSign = cn_cbor_mapget_string(pInput, "sign0");
+ if ((pSign == NULL) || (pSign->type != CN_CBOR_MAP)) exit(1);
+
+ hSig = (HCOSE_SIGN0)COSE_Decode(pbEncoded, cbEncoded, &type, COSE_sign0_object, CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (hSig == NULL) exit(1);
+
+
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pSign, "key"));
+ if (pkey == NULL) {
+ fFail = true;
+ goto exitHere;
+ }
+
+
+ pFail = cn_cbor_mapget_string(pInput, "fail");
+ if (COSE_Sign0_validate(hSig, pkey, NULL)) {
+ if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) fFail = true;
+ }
+ else {
+ if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) fFail = true;
+ }
+
+ COSE_Sign0_Free(hSig);
+
+ if (fFailBody) {
+ if (!fFail) fFail = true;
+ else fFail = false;
+ }
+
+exitHere:
+#ifdef USE_CBOR_CONTEXT
+ FreeContext(allocator);
+ allocator = NULL;
+#endif
+
+ if (fFail) CFails += 1;
+ return 0;
+}
+
+int ValidateSign0(const cn_cbor * pControl)
+{
+ int cbEncoded;
+ byte * pbEncoded = GetCBOREncoding(pControl, &cbEncoded);
+
+ return _ValidateSign0(pControl, pbEncoded, cbEncoded);
+}
+
+int BuildSign0Message(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 != NULL) && (pFail->type == CN_CBOR_TRUE)) return 0;
+
+ HCOSE_SIGN0 hSignObj = COSE_Sign0_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+
+ const cn_cbor * pInputs = cn_cbor_mapget_string(pControl, "input");
+ if (pInputs == NULL) exit(1);
+ const cn_cbor * pSign = cn_cbor_mapget_string(pInputs, "sign0");
+ if (pSign == NULL) exit(1);
+
+ const cn_cbor * pContent = cn_cbor_mapget_string(pInputs, "plaintext");
+ if (!COSE_Sign0_SetContent(hSignObj, pContent->v.bytes, pContent->length, NULL)) goto returnError;
+
+ if (!SetAttributes((HCOSE)hSignObj, cn_cbor_mapget_string(pSign, "protected"), Attributes_Sign0_protected)) goto returnError;
+ if (!SetAttributes((HCOSE)hSignObj, cn_cbor_mapget_string(pSign, "unprotected"), Attributes_Sign0_unprotected)) goto returnError;
+ if (!SetAttributes((HCOSE)hSignObj, cn_cbor_mapget_string(pSign, "unsent"), Attributes_Sign0_unsent)) goto returnError;
+
+ const cn_cbor * pAlg = COSE_Sign0_map_get_int(hSignObj, 1, COSE_BOTH, NULL);
+
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pSign, "key"));
+ if (pkey == NULL) exit(1);
+
+
+ if (!COSE_Sign0_Sign(hSignObj, pkey, NULL)) exit(1);
+
+ size_t cb = COSE_Encode((HCOSE)hSignObj, NULL, 0, 0) + 1;
+ byte * rgb = (byte *)malloc(cb);
+ cb = COSE_Encode((HCOSE)hSignObj, rgb, 0, cb);
+
+ COSE_Sign0_Free(hSignObj);
+
+ int f = _ValidateSign0(pControl, rgb, cb);
+
+ free(rgb);
+ return f;
+
+returnError:
+ CFails += 1;
+ return 1;
+}
+
diff --git a/test/test.c b/test/test.c
index 0774d6a..7098c6b 100644
--- a/test/test.c
+++ b/test/test.c
@@ -197,7 +197,7 @@
}
else if (strcmp(pKey->v.str, "IV_hex") == 0) {
keyNew = COSE_Header_IV;
- pValueNew = cn_cbor_data_create(FromHex(pValue->v.str, pValue->length), (int) pValue->length / 2, CBOR_CONTEXT_PARAM_COMMA NULL);
+ pValueNew = cn_cbor_data_create(FromHex(pValue->v.str, (int) pValue->length), (int) pValue->length / 2, CBOR_CONTEXT_PARAM_COMMA NULL);
}
else {
continue;
@@ -205,11 +205,27 @@
switch (which) {
case Attributes_MAC_protected:
- COSE_Mac_map_put((HCOSE_MAC)hHandle, keyNew, pValueNew, COSE_PROTECT_ONLY, NULL);
+ COSE_Mac_map_put_int((HCOSE_MAC)hHandle, keyNew, pValueNew, COSE_PROTECT_ONLY, NULL);
break;
case Attributes_MAC_unprotected:
- COSE_Mac_map_put((HCOSE_MAC)hHandle, keyNew, pValueNew, COSE_UNPROTECT_ONLY, NULL);
+ COSE_Mac_map_put_int((HCOSE_MAC)hHandle, keyNew, pValueNew, COSE_UNPROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_MAC_unsent:
+ COSE_Mac_map_put_int((HCOSE_MAC)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
+ break;
+
+ case Attributes_MAC0_protected:
+ COSE_Mac0_map_put_int((HCOSE_MAC0)hHandle, keyNew, pValueNew, COSE_PROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_MAC0_unprotected:
+ COSE_Mac0_map_put_int((HCOSE_MAC0)hHandle, keyNew, pValueNew, COSE_UNPROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_MAC0_unsent:
+ COSE_Mac0_map_put_int((HCOSE_MAC0)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
break;
case Attributes_Recipient_protected:
@@ -271,6 +287,19 @@
case Attributes_Signer_unsent:
COSE_Signer_map_put((HCOSE_SIGNER)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
break;
+
+ case Attributes_Sign0_protected:
+ COSE_Sign0_map_put_int((HCOSE_SIGN0)hHandle, keyNew, pValueNew, COSE_PROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_Sign0_unprotected:
+ COSE_Sign0_map_put_int((HCOSE_SIGN0)hHandle, keyNew, pValueNew, COSE_UNPROTECT_ONLY, NULL);
+ break;
+
+ case Attributes_Sign0_unsent:
+ COSE_Sign0_map_put_int((HCOSE_SIGN0)hHandle, keyNew, pValueNew, COSE_DONT_SEND, NULL);
+ break;
+
}
}
@@ -398,6 +427,10 @@
ValidateMAC(pControl);
BuildMacMessage(pControl);
}
+ else if (cn_cbor_mapget_string(pInput, "mac0") != NULL) {
+ ValidateMac0(pControl);
+ BuildMac0Message(pControl);
+ }
else if (cn_cbor_mapget_string(pInput, "enveloped") != NULL) {
ValidateEnveloped(pControl);
BuildEnvelopedMessage(pControl);
@@ -406,6 +439,10 @@
ValidateSigned(pControl);
BuildSignedMessage(pControl);
}
+ else if (cn_cbor_mapget_string(pInput, "sign0") != NULL) {
+ ValidateSign0(pControl);
+ BuildSign0Message(pControl);
+ }
else if (cn_cbor_mapget_string(pInput, "encrypted") != NULL) {
ValidateEncrypt(pControl);
BuildEncryptMessage(pControl);
diff --git a/test/test.h b/test/test.h
index e9f9178..b4629b1 100644
--- a/test/test.h
+++ b/test/test.h
@@ -24,17 +24,25 @@
int ValidateSigned(const cn_cbor * pControl);
int SignMessage();
int BuildSignedMessage(const cn_cbor * pControl);
+int ValidateSign0(const cn_cbor * pControl);
+int BuildSign0Message(const cn_cbor * pControl);
// mac_testc
int ValidateMAC(const cn_cbor * pControl);
int MacMessage();
int BuildMacMessage(const cn_cbor * pControl);
+int ValidateMac0(const cn_cbor * pControl);
+int BuildMac0Message(const cn_cbor * pControl);
// test.c
enum {
Attributes_MAC_protected=1,
Attributes_MAC_unprotected,
+ Attributes_MAC_unsent,
+ Attributes_MAC0_protected,
+ Attributes_MAC0_unprotected,
+ Attributes_MAC0_unsent,
Attributes_Recipient_protected,
Attributes_Recipient_unprotected,
Attributes_Recipient_unsent,
@@ -50,6 +58,9 @@
Attributes_Signer_protected,
Attributes_Signer_unprotected,
Attributes_Signer_unsent,
+ Attributes_Sign0_protected,
+ Attributes_Sign0_unprotected,
+ Attributes_Sign0_unsent,
} whichSet;
extern int CFails;