Add validate of signatures
diff --git a/src/MacMessage.c b/src/MacMessage.c
index f9abde3..7a36d0c 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -599,6 +599,10 @@
#endif
cn_cbor_errback cbor_error;
+#ifdef USE_CBOR_CONTEXT
+ context = &pMac->m_message.m_allocContext;
+#endif // USE_CBOR_CONTEXT
+
CHECK_CONDITION(IsValidMacHandle(hMac), COSE_ERR_INVALID_PARAMETER);
CHECK_CONDITION(IsValidRecipientHandle(hRecip), COSE_ERR_INVALID_PARAMETER);
@@ -607,9 +611,6 @@
pRecip->m_recipientNext = pMac->m_recipientFirst;
pMac->m_recipientFirst = pRecip;
-#ifdef USE_CBOR_CONTEXT
- context = &pMac->m_message.m_allocContext;
-#endif // USE_CBOR_CONTEXT
pRecipients = _COSE_arrayget_int(&pMac->m_message, INDEX_MAC_RECIPIENTS);
diff --git a/src/Sign.c b/src/Sign.c
index 5a1f280..8417ee8 100644
--- a/src/Sign.c
+++ b/src/Sign.c
@@ -47,20 +47,21 @@
goto errorReturn;
}
- pSigners = (cn_cbor *)cn_cbor_mapget_int(cbor, COSE_Header_Recipients);
- if (pSigners != NULL) {
- CHECK_CONDITION(pSigners->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
+ pSigners = _COSE_arrayget_int(&pobj->m_message, INDEX_SIGNATURES);
+ CHECK_CONDITION(pSigners != NULL, COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(pSigners->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
- pSigners = pSigners->first_child;
- while (pSigners != NULL) {
- COSE_SignerInfo * pInfo = _COSE_SignerInfo_Init_From_Object(pSigners, CBOR_CONTEXT_PARAM_COMMA perr);
- CHECK_CONDITION(pInfo != NULL, COSE_ERR_OUT_OF_MEMORY);
+ pSigners = pSigners->first_child;
+ CHECK_CONDITION(pSigners != NULL, COSE_ERR_INVALID_PARAMETER); // Must be at least one signer
- pInfo->m_signerNext = pobj->m_signerFirst;
- pobj->m_signerFirst = pInfo;
- pSigners = pSigners->next;
- }
- }
+ do {
+ COSE_SignerInfo * pInfo = _COSE_SignerInfo_Init_From_Object(pSigners, CBOR_CONTEXT_PARAM_COMMA perr);
+ if (pInfo == NULL) goto errorReturn;
+
+ pInfo->m_signerNext = pobj->m_signerFirst;
+ pobj->m_signerFirst = pInfo;
+ pSigners = pSigners->next;
+ } while (pSigners != NULL);
return(HCOSE_SIGN)pobj;
}
@@ -112,7 +113,7 @@
context = &pMessage->m_message.m_allocContext;
#endif
- p = cn_cbor_data_create(rgb, cb, CBOR_CONTEXT_PARAM_COMMA NULL);
+ p = cn_cbor_data_create(rgb, (int) cb, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(p != NULL, COSE_ERR_OUT_OF_MEMORY);
#ifdef USE_ARRAY
@@ -165,7 +166,7 @@
cbor = cn_cbor_mapget_int(pkey, COSE_Key_ID);
if (cbor != NULL) {
CHECK_CONDITION(cbor->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
- cbor2 = cn_cbor_data_create(cbor->v.bytes, cbor->length, CBOR_CONTEXT_PARAM_COMMA NULL);
+ cbor2 = cn_cbor_data_create(cbor->v.bytes, (int) cbor->length, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(cbor2 != NULL, COSE_ERR_CBOR);
CHECK_CONDITION(cn_cbor_mapput_int(pSigner->m_message.m_unprotectMap, COSE_Parameter_KID, cbor2, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
cbor2 = NULL;
@@ -239,3 +240,31 @@
return true;
}
+
+bool COSE_Sign_validate(HCOSE_SIGN hSign, HCOSE_SIGNER hSigner, cose_errback * perr)
+{
+ bool f;
+ COSE_SignMessage * pSign;
+ COSE_SignerInfo * pSigner;
+ const cn_cbor * cnContent;
+ const cn_cbor * cnProtected;
+
+ CHECK_CONDITION(IsValidSignHandle(hSign), COSE_ERR_INVALID_PARAMETER);
+ CHECK_CONDITION(IsValidSignerHandle(hSigner), COSE_ERR_INVALID_PARAMETER);
+
+ pSign = (COSE_SignMessage *)hSign;
+ pSigner = (COSE_SignerInfo *)hSigner;
+
+ 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_Signer_validate(pSign, pSigner, cnContent->v.bytes, cnContent->length, cnProtected->v.bytes, cnProtected->length, perr);
+
+ return f;
+
+errorReturn:
+ return false;
+}
diff --git a/src/SignerInfo.c b/src/SignerInfo.c
index 687a783..e8d2e39 100644
--- a/src/SignerInfo.c
+++ b/src/SignerInfo.c
@@ -48,22 +48,20 @@
COSE_SignerInfo * pSigner = NULL;
pSigner = (COSE_SignerInfo *)COSE_CALLOC(1, sizeof(COSE_SignerInfo), context);
- if (pSigner == NULL) {
- if (perr != NULL) perr->err = COSE_ERR_OUT_OF_MEMORY;
- return NULL;
- }
+ CHECK_CONDITION(pSigner != NULL, COSE_ERR_OUT_OF_MEMORY);
- if (cbor->type != CN_CBOR_MAP) {
- if (perr != NULL) perr->err = COSE_ERR_INVALID_PARAMETER;
- COSE_FREE(pSigner, context);
- return NULL;
- }
+ CHECK_CONDITION(cbor->type == CN_CBOR_ARRAY, COSE_ERR_INVALID_PARAMETER);
+
if (!_COSE_Init_From_Object(&pSigner->m_message, cbor, CBOR_CONTEXT_PARAM_COMMA perr)) {
_COSE_Signer_Free(pSigner);
return NULL;
}
return pSigner;
+
+errorReturn:
+ if (pSigner != NULL) COSE_FREE(pSigner, context);
+ return NULL;
}
byte RgbDontUse4[1024];
@@ -96,13 +94,13 @@
pcborProtectedSign = _COSE_encode_protected(&pSigner->m_message, perr);
if (pcborProtectedSign == NULL) goto errorReturn;
- pcborBody2 = cn_cbor_data_create(pcborBody->v.bytes, pcborBody->length, CBOR_CONTEXT_PARAM_COMMA NULL);
+ pcborBody2 = cn_cbor_data_create(pcborBody->v.bytes, (int) pcborBody->length, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(pcborBody2 != NULL, COSE_ERR_OUT_OF_MEMORY);
- pcborProtected2 = cn_cbor_data_create(pcborProtected->v.bytes, pcborProtected->length, CBOR_CONTEXT_PARAM_COMMA NULL);
+ pcborProtected2 = cn_cbor_data_create(pcborProtected->v.bytes, (int) pcborProtected->length, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(pcborProtected2 != NULL, COSE_ERR_OUT_OF_MEMORY);
- pcborProtectedSign2 = cn_cbor_data_create(pcborProtectedSign->v.bytes, pcborProtectedSign->length, CBOR_CONTEXT_PARAM_COMMA NULL);
+ pcborProtectedSign2 = cn_cbor_data_create(pcborProtectedSign->v.bytes, (int) pcborProtectedSign->length, CBOR_CONTEXT_PARAM_COMMA NULL);
CHECK_CONDITION(pcborProtectedSign2 != NULL, COSE_ERR_OUT_OF_MEMORY);
CHECK_CONDITION(cn_cbor_array_append(pArray, pcborProtected2, NULL), COSE_ERR_CBOR);
@@ -123,3 +121,122 @@
return f;
}
+
+bool COSE_Signer_SetKey(HCOSE_SIGNER h, const cn_cbor * pKey, cose_errback * perror)
+{
+ COSE_SignerInfo * p;
+
+ if (!IsValidSignerHandle(h) || (pKey == NULL)) {
+ if (perror != NULL) perror->err = COSE_ERR_INVALID_PARAMETER;
+ return false;
+ }
+
+ p = (COSE_SignerInfo *)h;
+ p->m_pkey = pKey;
+
+ return true;
+}
+
+byte RgbDontUseSign[8 * 1024];
+
+bool _COSE_Signer_validate(COSE_SignMessage * pSign, COSE_SignerInfo * pSigner, const byte * pbContent, size_t cbContent, const byte * pbProtected, size_t cbProtected, cose_errback * perr)
+{
+ 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
+ ssize_t cbAuthData;
+ cn_cbor * pAuthData = NULL;
+ cn_cbor * ptmp = NULL;
+
+#ifdef USE_CBOR_CONTEXT
+ context = &pSign->m_message.m_allocContext;
+#endif
+
+ 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;
+ }
+
+ // Build protected headers
+
+ cn_cbor * cnProtected = _COSE_arrayget_int(&pSigner->m_message, INDEX_PROTECTED);
+ CHECK_CONDITION((cnProtected != NULL) && (cnProtected->type == CN_CBOR_BYTES), COSE_ERR_INVALID_PARAMETER);
+
+ cn_cbor * cnSignature = _COSE_arrayget_int(&pSigner->m_message, INDEX_SIGNATURE);
+ CHECK_CONDITION((cnSignature != NULL) && (cnSignature->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("Signature", 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(pbProtected, (int) cbProtected, 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(pbContent, (int) cbContent, 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(RgbDontUseSign, 0, sizeof(RgbDontUseSign), 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_ECDSA_SHA_256:
+ if (!ECDSA_Verify(pSigner, pbAuthData, cbAuthData, cnSignature->v.bytes, cnSignature->length, 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);
+ 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.h b/src/cose.h
index 8cd2f6d..aafe457 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -185,3 +185,6 @@
bool COSE_Sign_SetContent(HCOSE_SIGN cose, const byte * rgbContent, size_t cbContent, cose_errback * errp);
HCOSE_SIGNER COSE_Sign_add_signer(HCOSE_SIGN cose, const cn_cbor * pkey, int algId, cose_errback * perr);
bool COSE_Sign_Sign(HCOSE_SIGN h, cose_errback * perr);
+HCOSE_SIGNER COSE_Sign_GetSigner(HCOSE_SIGN cose, int iSigner, cose_errback * perr);
+bool COSE_Sign_validate(HCOSE_SIGN hSign, HCOSE_SIGNER hSigner, cose_errback * perr);
+bool COSE_Signer_SetKey(HCOSE_SIGNER hSigner, const cn_cbor * pkey, cose_errback * perr);
diff --git a/src/cose_int.h b/src/cose_int.h
index 922be3a..1ca34fe 100644
--- a/src/cose_int.h
+++ b/src/cose_int.h
@@ -117,6 +117,7 @@
extern bool IsValidEncryptHandle(HCOSE_ENCRYPT h);
extern bool IsValidRecipientHandle(HCOSE_RECIPIENT h);
+extern bool IsValidSignerHandle(HCOSE_SIGNER h);
extern bool _COSE_Init(COSE * pcose, int msgType, CBOR_CONTEXT_COMMA cose_errback * errp);
extern bool _COSE_Init_From_Object(COSE* pobj, cn_cbor * pcbor, CBOR_CONTEXT_COMMA cose_errback * perror);
@@ -145,6 +146,7 @@
extern bool _COSE_Signer_sign(COSE_SignerInfo * pSigner, const cn_cbor * pcborBody, const cn_cbor * pcborProtected, cose_errback * perr);
extern COSE_SignerInfo * _COSE_SignerInfo_Init_From_Object(cn_cbor * cbor, CBOR_CONTEXT_COMMA cose_errback * perr);
extern void _COSE_Signer_Free(COSE_SignerInfo * pSigner);
+extern bool _COSE_Signer_validate(COSE_SignMessage * pSign, COSE_SignerInfo * pSigner, const byte * pbContent, size_t cbContent, const byte * pbProtected, size_t cbProtected, cose_errback * perr);
// Mac-ed items
extern HCOSE_MAC _COSE_Mac_Init_From_Object(cn_cbor *, COSE_MacMessage * pIn, CBOR_CONTEXT_COMMA cose_errback * errp);
diff --git a/src/crypto.h b/src/crypto.h
index 9180d62..af46cdc 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -56,6 +56,7 @@
* @return Did the function succeed?
*/
bool ECDSA_Sign(COSE_SignerInfo * pSigner, const byte * rgbToSign, size_t cbToSign, cose_errback * perr);
+bool ECDSA_Verify(COSE_SignerInfo * pSigner, const byte * rgbToSign, size_t cbToSign, const byte * rgbSig, size_t cbSig, cose_errback * perr);
/**
* Generate random bytes in a buffer
diff --git a/src/openssl.c b/src/openssl.c
index 7916cef..0bd5ae6 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -650,7 +650,7 @@
break;
default:
- return NULL;
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
}
EC_GROUP * ecgroup = EC_GROUP_new_by_curve_name(nidGroup);
@@ -736,6 +736,37 @@
return true;
}
+bool ECDSA_Verify(COSE_SignerInfo * pSigner, const byte * rgbToSign, size_t cbToSign, const byte * rgbSignature, size_t cbSignature, cose_errback * perr)
+{
+ EC_KEY * eckey = NULL;
+ byte rgbDigest[EVP_MAX_MD_SIZE];
+ unsigned int cbDigest = sizeof(rgbDigest);
+#ifdef USE_CBOR_CONTEXT
+ cn_cbor_context * context = &pSigner->m_message.m_allocContext;
+#endif
+ cn_cbor * p = NULL;
+
+ eckey = ECKey_From(pSigner->m_pkey, perr);
+ if (eckey == NULL) {
+ errorReturn:
+ if (p != NULL) CN_CBOR_FREE(p, context);
+ if (eckey != NULL) EC_KEY_free(eckey);
+ return false;
+ }
+
+ EVP_Digest(rgbToSign, cbToSign, rgbDigest, &cbDigest, EVP_sha256(), NULL);
+
+ ECDSA_SIG sig;
+ sig.r = BN_bin2bn(rgbSignature,(int) cbSignature/2, NULL);
+ sig.s = BN_bin2bn(rgbSignature+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);
+
+ return true;
+}
bool AES_KW_Decrypt(COSE_Encrypt * pcose, const byte * pbKeyIn, size_t cbitKey, byte * pbKeyOut, int * pcbKeyOut, cose_errback * perr)
{
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index a6523b9..05496f0 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 context.c )
+add_executable ( cose_test test.c json.c encrypt.c sign.c context.c )
target_link_libraries (cose_test PRIVATE cose-c )
@@ -31,6 +31,9 @@
add_test ( NAME cose_test COMMAND cose_test )
add_test ( NAME mac-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Mac-02.json )
add_test ( NAME mac-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Mac-04.json )
+add_test ( NAME sig-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Sig-01.json )
+add_test ( NAME sig-03 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Sig-03.json )
+add_test ( NAME sig-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Sig-04.json )
add_test ( NAME hmac-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/HMac-01.json )
add_test ( NAME hmac-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/hmac-examples/HMac-02.json )
diff --git a/test/sign.c b/test/sign.c
new file mode 100644
index 0000000..34412d3
--- /dev/null
+++ b/test/sign.c
@@ -0,0 +1,173 @@
+// encrypt.c
+
+#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 _ValidateSigned(const cn_cbor * pControl, const byte * pbEncoded, int cbEncoded)
+{
+ const cn_cbor * pInput = cn_cbor_mapget_string(pControl, "input");
+ const cn_cbor * pFail;
+ const cn_cbor * pSign;
+ const cn_cbor * pSigners;
+ HCOSE_SIGN hSig;
+ int type;
+ int iSigner;
+ 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, "sign");
+ if ((pSign == NULL) || (pSign->type != CN_CBOR_MAP)) exit(1);
+
+ pSigners = cn_cbor_mapget_string(pSign, "signers");
+ if ((pSigners == NULL) || (pSigners->type != CN_CBOR_ARRAY)) exit(1);
+
+ pSigners = pSigners->first_child;
+ for (iSigner = 0; pSigners != NULL; iSigner++, pSigners = pSigners->next) {
+
+ hSig = (HCOSE_SIGN)COSE_Decode(pbEncoded, cbEncoded, &type, COSE_sign_object, CBOR_CONTEXT_PARAM_COMMA NULL);
+ if (hSig == NULL) exit(1);
+
+
+ cn_cbor * pkey = BuildKey(cn_cbor_mapget_string(pSigners, "key"));
+ if (pkey == NULL) {
+ fFail = true;
+ continue;
+ }
+
+ HCOSE_SIGNER hSigner = COSE_Sign_GetSigner(hSig, iSigner, NULL);
+ if (hSigner == NULL) {
+ fFail = true;
+ continue;
+ }
+
+ if (!COSE_Signer_SetKey(hSigner, pkey, NULL)) {
+ fFail = true;
+ continue;
+ }
+
+ pFail = cn_cbor_mapget_string(pSigners, "fail");
+ if (COSE_Sign_validate(hSig, hSigner, NULL)) {
+ if ((pFail != NULL) && (pFail->type != CN_CBOR_TRUE)) fFail = true;
+ }
+ else {
+ if ((pFail == NULL) || (pFail->type == CN_CBOR_FALSE)) fFail = true;
+ }
+
+ // COSE_Encrypt_Free(hSig);
+ }
+
+ if (fFailBody) {
+ if (!fFail) fFail = true;
+ else fFail = false;
+ }
+
+#ifdef USE_CBOR_CONTEXT
+ FreeContext(allocator);
+ allocator = NULL;
+#endif
+
+ if (fFail) CFails += 1;
+ return 0;
+}
+
+int ValidateSigned(const cn_cbor * pControl)
+{
+ int cbEncoded;
+ byte * pbEncoded = GetCBOREncoding(pControl, &cbEncoded);
+
+ return _ValidateSigned(pControl, pbEncoded, cbEncoded);
+}
+
+
+int SignMessage()
+{
+ HCOSE_SIGN hEncObj = COSE_Sign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
+ char * sz = "This is the content to be used";
+ size_t cb;
+ byte * rgb;
+
+ byte rgbX[] = { 0x65, 0xed, 0xa5, 0xa1, 0x25, 0x77, 0xc2, 0xba, 0xe8, 0x29, 0x43, 0x7f, 0xe3, 0x38, 0x70, 0x1a, 0x10, 0xaa, 0xa3, 0x75, 0xe1, 0xbb, 0x5b, 0x5d, 0xe1, 0x08, 0xde, 0x43, 0x9c, 0x08, 0x55, 0x1d };
+ byte rgbY[] = { 0x1e, 0x52, 0xed, 0x75, 0x70, 0x11, 0x63, 0xf7, 0xf9, 0xe4, 0x0d, 0xdf, 0x9f, 0x34, 0x1b, 0x3d, 0xc9, 0xba, 0x86, 0x0a, 0xf7, 0xe0, 0xca, 0x7c, 0xa7, 0xe9, 0xee, 0xcd, 0x00, 0x84, 0xd1, 0x9c };
+ byte kid[] = { 0x6d, 0x65, 0x72, 0x69, 0x61, 0x64, 0x6f, 0x63, 0x2e, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x79, 0x62, 0x75, 0x63, 0x6, 0xb4, 0x06, 0x27, 0x56, 0x36, 0xb6, 0xc6, 0x16, 0xe6, 0x42, 0xe6, 0x57, 0x86, 0x16, 0xd7, 0x06, 0x65};
+ byte rgbD[] = {0xaf, 0xf9, 0x07, 0xc9, 0x9f, 0x9a, 0xd3, 0xaa, 0xe6, 0xc4, 0xcd, 0xf2, 0x11, 0x22, 0xbc, 0xe2, 0xbd, 0x68, 0xb5, 0x28, 0x3e, 0x69, 0x07, 0x15, 0x4a, 0xd9, 0x11, 0x84, 0x0f, 0xa2, 0x08, 0xcf};
+
+ cn_cbor * pkey = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pkey, COSE_Key_Type, cn_cbor_int_create(COSE_Key_Type_EC2, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pkey, -1, cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pkey, -2, cn_cbor_data_create(rgbX, sizeof(rgbX), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pkey, -3, cn_cbor_data_create(rgbY, sizeof(rgbY), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pkey, COSE_Key_ID, cn_cbor_data_create(kid, sizeof(kid), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+ cn_cbor_mapput_int(pkey, -4, cn_cbor_data_create(rgbD, sizeof(rgbD), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+
+ COSE_Sign_SetContent(hEncObj, (byte *) sz, strlen(sz), NULL);
+ COSE_Sign_add_signer(hEncObj, pkey, COSE_Algorithm_ECDSA_SHA_256, NULL);
+
+ COSE_Sign_Sign(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_Sign_Free(hEncObj);
+
+ /* */
+
+ int typ;
+ hEncObj = (HCOSE_SIGN)COSE_Decode(rgb, (int)cb, &typ, COSE_sign_object, NULL, NULL);
+
+#if 0
+ int iSigner = 0;
+ do {
+ HCOSE_RECIPIENT hSigner;
+
+ hSigner = COSE_Encrypt_GetRecipient(hEncObj, iSigner, NULL);
+ if (hSigner == NULL) break;
+
+ COSE_Recipient_SetKey(hSigner, rgbSecret, cbSecret, NULL);
+
+ COSE_Encrypt_decrypt(hEncObj, hSigner, NULL);
+
+ iSigner += 1;
+
+ } while (true);
+#endif
+
+ COSE_Sign_Free(hEncObj);
+
+ return 1;
+}
diff --git a/test/test.c b/test/test.c
index e898733..4f11f60 100644
--- a/test/test.c
+++ b/test/test.c
@@ -20,10 +20,12 @@
int CFails = 0;
-struct {
+typedef struct _NameMap {
char * sz;
int i;
-} RgAlgorithmNames[23] = {
+} NameMap;
+
+NameMap RgAlgorithmNames[23] = {
{"HS256", COSE_Algorithm_HMAC_256_256},
{"HS256/64", COSE_Algorithm_HMAC_256_64},
{"HS384", COSE_Algorithm_HMAC_384_384},
@@ -49,12 +51,19 @@
{"AES-CCM-64-256/128", COSE_Algorithm_AES_CCM_64_128_256}
};
-int MapAlgorithmName(const cn_cbor * p)
+
+NameMap RgCurveNames[3] = {
+ {"P-256", 1},
+ {"P-384", 2},
+ {"P-512", 3}
+};
+
+int MapName(const cn_cbor * p, NameMap * rgMap, int cMap)
{
unsigned int i;
- for (i = 0; i < _countof(RgAlgorithmNames); i++) {
- if (strcmp(RgAlgorithmNames[i].sz, p->v.str) == 0) return RgAlgorithmNames[i].i;
+ for (i = 0; i < cMap; i++) {
+ if (strcmp(rgMap[i].sz, p->v.str) == 0) return rgMap[i].i;
}
assert(false);
@@ -62,6 +71,11 @@
return 0;
}
+int MapAlgorithmName(const cn_cbor * p)
+{
+ return MapName(p, RgAlgorithmNames, _countof(RgAlgorithmNames));
+}
+
cn_cbor * cn_cbor_clone(const cn_cbor * pIn)
{
cn_cbor * pOut = NULL;
@@ -123,6 +137,7 @@
#define OPERATION_NONE 0
#define OPERATION_BASE64 1
#define OPERATION_IGNORE 2
+#define OPERATION_STRING 3
struct {
char * szKey;
@@ -132,7 +147,7 @@
} RgStringKeys[7] = {
{ "kty", 0, OPERATION_IGNORE, 0},
{ "kid", 0, OPERATION_NONE, 1},
- { "crv", 2, OPERATION_NONE, -1},
+ { "crv", 2, OPERATION_STRING, -1},
{ "x", 2, OPERATION_BASE64, -2},
{ "y", 2, OPERATION_BASE64, -3},
{ "d", 2, OPERATION_BASE64, -4},
@@ -244,6 +259,10 @@
pb = base64_decode(pValue->v.str, pValue->length, &cb);
cn_cbor_mapput_int(pKeyOut, RgStringKeys[i].keyNew, cn_cbor_data_create(pb, (int) cb, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
break;
+
+ case OPERATION_STRING:
+ cn_cbor_mapput_int(pKeyOut, RgStringKeys[i].keyNew, cn_cbor_int_create(MapName(pValue, RgCurveNames, _countof(RgCurveNames)), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
+ break;
}
i = 99;
}
@@ -449,79 +468,6 @@
return 1;
}
-int SignMessage()
-{
- HCOSE_SIGN hEncObj = COSE_Sign_Init(CBOR_CONTEXT_PARAM_COMMA NULL);
- char * sz = "This is the content to be used";
- size_t cb;
- byte * rgb;
-
- byte rgbX[] = { 0x65, 0xed, 0xa5, 0xa1, 0x25, 0x77, 0xc2, 0xba, 0xe8, 0x29, 0x43, 0x7f, 0xe3, 0x38, 0x70, 0x1a, 0x10, 0xaa, 0xa3, 0x75, 0xe1, 0xbb, 0x5b, 0x5d, 0xe1, 0x08, 0xde, 0x43, 0x9c, 0x08, 0x55, 0x1d };
- byte rgbY[] = { 0x1e, 0x52, 0xed, 0x75, 0x70, 0x11, 0x63, 0xf7, 0xf9, 0xe4, 0x0d, 0xdf, 0x9f, 0x34, 0x1b, 0x3d, 0xc9, 0xba, 0x86, 0x0a, 0xf7, 0xe0, 0xca, 0x7c, 0xa7, 0xe9, 0xee, 0xcd, 0x00, 0x84, 0xd1, 0x9c };
- byte kid[] = { 0x6d, 0x65, 0x72, 0x69, 0x61, 0x64, 0x6f, 0x63, 0x2e, 0x62, 0x72, 0x61, 0x6e, 0x64, 0x79, 0x62, 0x75, 0x63, 0x6, 0xb4, 0x06, 0x27, 0x56, 0x36, 0xb6, 0xc6, 0x16, 0xe6, 0x42, 0xe6, 0x57, 0x86, 0x16, 0xd7, 0x06, 0x65};
- byte rgbD[] = {0xaf, 0xf9, 0x07, 0xc9, 0x9f, 0x9a, 0xd3, 0xaa, 0xe6, 0xc4, 0xcd, 0xf2, 0x11, 0x22, 0xbc, 0xe2, 0xbd, 0x68, 0xb5, 0x28, 0x3e, 0x69, 0x07, 0x15, 0x4a, 0xd9, 0x11, 0x84, 0x0f, 0xa2, 0x08, 0xcf};
-
- cn_cbor * pkey = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA NULL);
- cn_cbor_mapput_int(pkey, COSE_Key_Type, cn_cbor_int_create(COSE_Key_Type_EC2, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
- cn_cbor_mapput_int(pkey, -1, cn_cbor_int_create(1, CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
- cn_cbor_mapput_int(pkey, -2, cn_cbor_data_create(rgbX, sizeof(rgbX), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
- cn_cbor_mapput_int(pkey, -3, cn_cbor_data_create(rgbY, sizeof(rgbY), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
- cn_cbor_mapput_int(pkey, COSE_Key_ID, cn_cbor_data_create(kid, sizeof(kid), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
- cn_cbor_mapput_int(pkey, -4, cn_cbor_data_create(rgbD, sizeof(rgbD), CBOR_CONTEXT_PARAM_COMMA NULL), CBOR_CONTEXT_PARAM_COMMA NULL);
-
- COSE_Sign_SetContent(hEncObj, (byte *) sz, strlen(sz), NULL);
- COSE_Sign_add_signer(hEncObj, pkey, COSE_Algorithm_ECDSA_SHA_256, NULL);
-
- COSE_Sign_Sign(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_Sign_Free(hEncObj);
-
- /* */
-
- int typ;
- hEncObj = (HCOSE_SIGN)COSE_Decode(rgb, (int)cb, &typ, COSE_sign_object, NULL, NULL);
-
-#if 0
- int iRecipient = 0;
- do {
- HCOSE_RECIPIENT hRecip;
-
- hRecip = COSE_Encrypt_GetRecipient(hEncObj, iRecipient, NULL);
- if (hRecip == NULL) break;
-
- COSE_Recipient_SetKey(hRecip, rgbSecret, cbSecret, NULL);
-
- COSE_Encrypt_decrypt(hEncObj, hRecip, NULL);
-
- iRecipient += 1;
-
- } while (true);
-#endif
-
- COSE_Sign_Free(hEncObj);
-
- return 1;
-}
bool cn_cbor_array_replace(cn_cbor * cb_array, cn_cbor * cb_value, int index, CBOR_CONTEXT_COMMA cn_cbor_errback *errp);
@@ -588,6 +534,9 @@
ValidateEnveloped(pControl);
BuildEncryptMessage(pControl);
}
+ else if (cn_cbor_mapget_string(pInput, "sign") != NULL) {
+ ValidateSigned(pControl);
+ }
}
else {
MacMessage();
diff --git a/test/test.h b/test/test.h
index fc48d29..5150c75 100644
--- a/test/test.h
+++ b/test/test.h
@@ -17,6 +17,12 @@
int EncryptMessage();
int BuildEncryptMessage(const cn_cbor * pControl);
+// sign.c
+
+int ValidateSigned(const cn_cbor * pControl);
+int SignMessage();
+int BuildSignedMessage(const cn_cbor * pControl);
+
// test.c
enum {