Coverity & ECDSA
Fix one pass of issues discovered by Coverity
Add the support for Direct ECDSA w/ HKDF SHA-256
diff --git a/dumper/dumper.c b/dumper/dumper.c
index 6128856..2f822dd 100644
--- a/dumper/dumper.c
+++ b/dumper/dumper.c
@@ -269,8 +269,14 @@
fprintf(fp, "%s", t);
fprintf(fp, "\n");
+ if (strlen(OutputBuffer) + strlen(iRet + 1) >= sizeof(OutputBuffer)-1) {
+ fprintf(stderr, "Internal buffer too small for dumpping");
+ exit(1);
+ }
strcpy(OutputBuffer, iRet + 1);
}
+
+ va_end(args);
}
diff --git a/src/Encrypt.c b/src/Encrypt.c
index e74c077..6e37da6 100644
--- a/src/Encrypt.c
+++ b/src/Encrypt.c
@@ -232,7 +232,6 @@
#endif
byte * pbAuthData = NULL;
size_t cbAuthData;
- cn_cbor * pAuthData = NULL;
byte * pbProtected = NULL;
ssize_t cbProtected;
@@ -246,7 +245,6 @@
errorReturn:
if (pbProtected != NULL) COSE_FREE(pbProtected, context);
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);
@@ -360,7 +358,6 @@
if (pbProtected != NULL) COSE_FREE(pbProtected, context);
if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
if ((pbKey != NULL) && (pbKeyIn == NULL)) COSE_FREE(pbKey, context);
if (perr != NULL) perr->err = COSE_ERR_NONE;
@@ -374,13 +371,13 @@
COSE_RecipientInfo * pri;
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_Enveloped * pcose = (COSE_Enveloped *) h;
+ bool fRet = false;
CHECK_CONDITION(IsValidEnvelopedHandle(h), COSE_ERR_INVALID_PARAMETER);
@@ -495,16 +492,12 @@
// Figure out the clean up
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
-
- return true;
+ fRet = 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;
+ return fRet;
}
bool COSE_Enveloped_SetContent(HCOSE_ENVELOPED h, const byte * rgb, size_t cb, cose_errback * perror)
diff --git a/src/MacMessage.c b/src/MacMessage.c
index b00f6df..30c9199 100644
--- a/src/MacMessage.c
+++ b/src/MacMessage.c
@@ -277,6 +277,7 @@
#endif
COSE_MacMessage * pcose = (COSE_MacMessage *)h;
cn_cbor_errback cbor_error;
+ bool fRet = false;
CHECK_CONDITION(IsValidMacHandle(h), COSE_ERR_INVALID_PARAMETER);
@@ -426,16 +427,13 @@
// 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;
+ fRet = 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;
+ return fRet;
}
byte RgbDontUseMac[1024];
diff --git a/src/Recipient.c b/src/Recipient.c
index ddbdf9a..9ce9f05 100644
--- a/src/Recipient.c
+++ b/src/Recipient.c
@@ -133,6 +133,9 @@
size_t cbContext;
byte rgbDigest[512 / 8];
size_t cbDigest;
+ cn_cbor * pkey = NULL;
+ byte * pbSecret = NULL;
+ size_t cbSecret;
#ifdef USE_CBOR_CONTEXT
context = &pcose->m_message.m_allocContext;
@@ -145,10 +148,7 @@
if (pbProtected != NULL) COSE_FREE(pbProtected, context);
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);
- }
+ if (pbSecret != NULL) COSE_FREE(pbSecret, context);
return false;
}
CHECK_CONDITION((cn->type == CN_CBOR_UINT) || (cn->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
@@ -182,18 +182,14 @@
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
break;
+ case COSE_Algorithm_ECDH_ES_HKDF_256:
+ break;
+
default:
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
break;
}
- // Allocate the key if we have not already done so
-
- if (pbKey == NULL) {
- pbKey = COSE_CALLOC(cbitKey / 8, 1, context);
- CHECK_CONDITION(pbKey != NULL, COSE_ERR_OUT_OF_MEMORY);
- }
-
// If there is a recipient - ask it for the key
for (pRecip2 = pcose->m_recipientFirst; pRecip2 != NULL; pRecip2 = pRecip->m_recipientNext) {
@@ -263,6 +259,21 @@
if (!HKDF_AES_Expand(&pcose->m_message, 256, cn->v.bytes, cn->length, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
break;
+ case COSE_Algorithm_ECDH_ES_HKDF_256:
+ if (!BuildContextBytes(&pcose->m_message, algIn, cbitKey, &pbContext, &cbContext, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ pkey = _COSE_map_get_int(&pcose->m_message, COSE_Header_ECDH_EPHEMERAL, COSE_BOTH, perr);
+ if (pkey == NULL) goto errorReturn;
+
+ CHECK_CONDITION(pRecip->m_pkey != NULL, COSE_ERR_INVALID_PARAMETER);
+ if (!ECDH_ComputeSecret(&pcose->m_message, (cn_cbor **) &pRecip->m_pkey, pkey, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ if (!HKDF_Extract(&pcose->m_message, pbSecret, cbSecret, 256, rgbDigest, &cbDigest, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ if (!HKDF_Expand(&pcose->m_message, 256, rgbDigest, cbDigest, pbContext, cbContext, pbKey, cbitKey / 8, perr)) goto errorReturn;
+
+ break;
+
default:
FAIL_CONDITION(COSE_ERR_UNKNOWN_ALGORITHM);
break;
@@ -278,13 +289,13 @@
COSE_RecipientInfo * pri;
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
cn_cbor_errback cbor_error;
+ bool fRet = false;
#ifdef USE_CBOR_CONTEXT
context = &pRecipient->m_encrypt.m_message.m_allocContext;
@@ -304,6 +315,8 @@
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
case COSE_Algorithm_Direct_HKDF_AES_128:
case COSE_Algorithm_Direct_HKDF_AES_256:
+ case COSE_Algorithm_ECDH_ES_HKDF_256:
+ case COSE_Algorithm_ECDH_ES_HKDF_512:
// This is a NOOP
cbitKey = 0;
CHECK_CONDITION(pRecipient->m_encrypt.m_recipientFirst == NULL, COSE_ERR_INVALID_PARAMETER);
@@ -369,9 +382,12 @@
case COSE_Algorithm_Direct_HKDF_HMAC_SHA_512:
case COSE_Algorithm_Direct_HKDF_AES_128:
case COSE_Algorithm_Direct_HKDF_AES_256:
+ case COSE_Algorithm_ECDH_ES_HKDF_256:
+ case COSE_Algorithm_ECDH_ES_HKDF_512:
ptmp = cn_cbor_data_create(NULL, 0, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
CHECK_CONDITION_CBOR(ptmp != NULL, cbor_error);
CHECK_CONDITION_CBOR(_COSE_array_replace(&pRecipient->m_encrypt.m_message, ptmp, INDEX_BODY, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ ptmp = NULL;
break;
@@ -398,16 +414,12 @@
// Figure out the clean up
- if (pbAuthData != NULL) COSE_FREE(pbAuthData, context);
- if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
-
- return true;
+ fRet = 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;
+ return fRet;
}
byte * _COSE_RecipientInfo_generateKey(COSE_RecipientInfo * pRecipient, int algIn, size_t cbitKeySize, cose_errback * perr)
@@ -423,6 +435,9 @@
const cn_cbor * pK;
byte rgbDigest[512 / 8];
size_t cbDigest;
+ cn_cbor * pkey;
+ byte *pbSecret = NULL;
+ size_t cbSecret;
CHECK_CONDITION(cn_Alg != NULL, COSE_ERR_INVALID_PARAMETER);
CHECK_CONDITION((cn_Alg->type == CN_CBOR_UINT) || (cn_Alg->type == CN_CBOR_INT), COSE_ERR_INVALID_PARAMETER);
@@ -504,6 +519,26 @@
break;
+ case COSE_Algorithm_ECDH_ES_HKDF_256:
+ if (!BuildContextBytes(&pRecipient->m_encrypt.m_message, algIn, cbitKeySize, &pbContext, &cbContext, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ pkey = _COSE_map_get_int(&pRecipient->m_encrypt.m_message, COSE_Header_ECDH_EPHEMERAL, COSE_BOTH, perr);
+
+ if (!ECDH_ComputeSecret(&pRecipient->m_encrypt.m_message, &pkey, pRecipient->m_pkey, &pbSecret, &cbSecret, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ if (pkey->parent == NULL) {
+ if (!_COSE_map_put(&pRecipient->m_encrypt.m_message, COSE_Header_ECDH_EPHEMERAL, pkey, COSE_UNPROTECT_ONLY, perr)) goto errorReturn;
+ }
+
+ pb = COSE_CALLOC(cbitKeySize / 8, 1, context);
+ CHECK_CONDITION(pb != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ if (!HKDF_Extract(&pRecipient->m_encrypt.m_message, pbSecret, cbSecret, 256, rgbDigest, &cbDigest, CBOR_CONTEXT_PARAM_COMMA perr)) goto errorReturn;
+
+ if (!HKDF_Expand(&pRecipient->m_encrypt.m_message, 256, rgbDigest, cbDigest, pbContext, cbContext, pb, cbitKeySize / 8, perr)) goto errorReturn;
+
+ break;
+
case COSE_Algorithm_ECDH_SS_HKDF_256: {
// Need to have a key and it needs to be the correct type of key.
if ((pRecipient->m_pkey == NULL) || (cn_cbor_mapget_int(pRecipient->m_pkey, 1)->v.uint != 2)) return NULL;
@@ -511,14 +546,16 @@
}
default:
- return NULL;
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
}
+ if (pbSecret != NULL) COSE_FREE(pbSecret, context);
if (pbContext != NULL) COSE_FREE(pbContext, context);
return pb;
errorReturn:
+ if (pbSecret != NULL) COSE_FREE(pbSecret, context);
if (pbContext != NULL) COSE_FREE(pbContext, context);
if (pb != NULL) COSE_FREE(pb, context);
return NULL;
diff --git a/src/Sign.c b/src/Sign.c
index 450a17a..d2c3d98 100644
--- a/src/Sign.c
+++ b/src/Sign.c
@@ -242,7 +242,7 @@
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);
+ CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
f = _COSE_Signer_validate(pSign, pSigner, cnContent, cnProtected, perr);
diff --git a/src/Sign0.c b/src/Sign0.c
index 6749ef4..109fd25 100644
--- a/src/Sign0.c
+++ b/src/Sign0.c
@@ -164,7 +164,7 @@
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);
+ CHECK_CONDITION(cnProtected != NULL && cnProtected->type == CN_CBOR_BYTES, COSE_ERR_INVALID_PARAMETER);
f = _COSE_Signer0_validate(pSign, pKey, perr);
@@ -331,8 +331,8 @@
cn_cbor_context * context = NULL;
#endif
size_t cbToSign;
- cn_cbor * pAuthData = NULL;
cn_cbor * cnSignature = NULL;
+ bool fRet = false;
#ifdef USE_CBOR_CONTEXT
context = &pSign->m_message.m_allocContext;
@@ -374,14 +374,10 @@
break;
}
- if (pbToSign != NULL) COSE_FREE(pbToSign, context);
- if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
-
- return true;
+ fRet = true;
errorReturn:
if (pbToSign != NULL) COSE_FREE(pbToSign, context);
- if (pAuthData != NULL) cn_cbor_free(pAuthData CBOR_CONTEXT_PARAM);
- return false;
+ return fRet;
}
diff --git a/src/cose.h b/src/cose.h
index d3aa969..d7c814e 100644
--- a/src/cose.h
+++ b/src/cose.h
@@ -147,6 +147,10 @@
COSE_Header_KDF_PUB_other = -999,
COSE_Header_KDF_PRIV = -998,
+
+ COSE_Header_ECDH_EPHEMERAL = -1,
+ COSE_Header_ECDH_STATIC = -2
+
} COSE_Header;
typedef enum {
diff --git a/src/crypto.h b/src/crypto.h
index d5a8f46..232a927 100644
--- a/src/crypto.h
+++ b/src/crypto.h
@@ -63,6 +63,8 @@
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);
+bool ECDH_ComputeSecret(COSE * pReciient, cn_cbor ** ppKeyMe, const cn_cbor * pKeyYou, byte ** ppbSecret, size_t * pcbSecret, CBOR_CONTEXT_COMMA cose_errback *perr);
+
/**
* Generate random bytes in a buffer
*
diff --git a/src/openssl.c b/src/openssl.c
index 351b76e..d441d2c 100644
--- a/src/openssl.c
+++ b/src/openssl.c
@@ -13,6 +13,7 @@
#include <openssl/cmac.h>
#include <openssl/hmac.h>
#include <openssl/ecdsa.h>
+#include <openssl/ecdh.h>
#include <openssl/rand.h>
#define MIN(A, B) ((A) < (B) ? (A) : (B))
@@ -825,6 +826,67 @@
return NULL;
}
+cn_cbor * EC_FromKey(const EC_KEY * pKey, CBOR_CONTEXT_COMMA cose_errback * perr)
+{
+ cn_cbor * pkey = NULL;
+ const EC_GROUP * pgroup;
+ int cose_group;
+ cn_cbor * p = NULL;
+ cn_cbor_errback cbor_error;
+ const EC_POINT * pPoint;
+ size_t cbSize;
+ byte * pbOut = NULL;
+
+ pgroup = EC_KEY_get0_group(pKey);
+
+ switch (EC_GROUP_get_curve_name(pgroup)) {
+ case NID_X9_62_prime256v1:
+ cose_group = 1;
+ break;
+
+ default:
+ FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
+ }
+
+ pkey = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(pkey != NULL, cbor_error);
+
+ p = cn_cbor_int_create(cose_group, CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Curve, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ p = NULL;
+
+ pPoint = EC_KEY_get0_public_key(pKey);
+ CHECK_CONDITION(pPoint != NULL, COSE_ERR_INVALID_PARAMETER);
+
+ cbSize = EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED, NULL, 0, NULL);
+ CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
+ pbOut = COSE_CALLOC(cbSize, 1, context);
+ CHECK_CONDITION(pbOut != NULL, COSE_ERR_OUT_OF_MEMORY);
+ CHECK_CONDITION(EC_POINT_point2oct(pgroup, pPoint, POINT_CONVERSION_UNCOMPRESSED, pbOut, cbSize, NULL) == cbSize, COSE_ERR_CRYPTO_FAIL);
+
+ p = cn_cbor_data_create(pbOut+1, (int) (cbSize / 2), CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_X, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ p = NULL;
+
+ p = cn_cbor_data_create(pbOut + cbSize / 2+1, (int) (cbSize / 2), CBOR_CONTEXT_PARAM_COMMA &cbor_error);
+ pbOut = NULL; // It is already part of the other one.
+ CHECK_CONDITION_CBOR(p != NULL, cbor_error);
+ CHECK_CONDITION_CBOR(cn_cbor_mapput_int(pkey, COSE_Key_EC_Y, p, CBOR_CONTEXT_PARAM_COMMA &cbor_error), cbor_error);
+ p = NULL;
+
+returnHere:
+ if (pbOut != NULL) COSE_FREE(pbOut, context);
+ if (p != NULL) CN_CBOR_FREE(p, context);
+ return pkey;
+
+errorReturn:
+ CN_CBOR_FREE(pkey, context);
+ pkey = NULL;
+ goto returnHere;
+}
+
/*
bool ECDSA_Sign(const cn_cbor * pKey)
{
@@ -860,6 +922,7 @@
eckey = ECKey_From(pKey, &cbR, perr);
if (eckey == NULL) {
errorReturn:
+ if (pbSig != NULL) COSE_FREE(pbSig, context);
if (p != NULL) CN_CBOR_FREE(p, context);
if (eckey != NULL) EC_KEY_free(eckey);
return false;
@@ -894,6 +957,10 @@
CHECK_CONDITION(_COSE_array_replace(pSigner, p, index, CBOR_CONTEXT_PARAM_COMMA NULL), COSE_ERR_CBOR);
+ pbSig = NULL;
+
+ if (eckey != NULL) EC_KEY_free(eckey);
+
return true;
}
@@ -1000,4 +1067,51 @@
RAND_bytes(pb, (int) cb);
}
+bool ECDH_ComputeSecret(COSE * pRecipient, cn_cbor ** ppKeyMe, const cn_cbor * pKeyYou, byte ** ppbSecret, size_t * pcbSecret, CBOR_CONTEXT_COMMA cose_errback *perr)
+{
+ EC_KEY * pkeyMe = NULL;
+ EC_KEY * pkeyYou = NULL;
+ int cbGroup;
+ int cbsecret;
+ byte * pbsecret = NULL;
+
+ pkeyYou = ECKey_From(pKeyYou, &cbGroup, perr);
+ if (pkeyYou == NULL) goto errorReturn;
+
+ if (*ppKeyMe == NULL) {
+ pkeyMe = EC_KEY_new();
+ EC_KEY_set_group(pkeyMe, EC_KEY_get0_group(pkeyYou));
+ CHECK_CONDITION(EC_KEY_generate_key(pkeyMe) == 1, COSE_ERR_CRYPTO_FAIL);
+ *ppKeyMe = EC_FromKey(pkeyMe, CBOR_CONTEXT_PARAM_COMMA perr);
+ if (*ppKeyMe == NULL) goto errorReturn;
+ }
+ else {
+ pkeyMe = ECKey_From(*ppKeyMe, &cbGroup, perr);
+ if (pkeyMe == NULL) goto errorReturn;
+ }
+
+ pbsecret = COSE_CALLOC(cbGroup, 1, context);
+ CHECK_CONDITION(pbsecret != NULL, COSE_ERR_OUT_OF_MEMORY);
+
+ cbsecret = ECDH_compute_key(pbsecret, cbGroup, EC_KEY_get0_public_key(pkeyYou), pkeyMe, NULL);
+ CHECK_CONDITION(cbsecret != 0, COSE_ERR_CRYPTO_FAIL);
+
+ *ppbSecret = pbsecret;
+ *pcbSecret = cbsecret;
+ pbsecret = NULL;
+
+ if (pkeyMe != NULL) EC_KEY_free(pkeyMe);
+ if (pkeyYou != NULL) EC_KEY_free(pkeyYou);
+
+ return true;
+
+errorReturn:
+ if (pbsecret != NULL) COSE_FREE(pbsecret, context);
+ if (pkeyMe != NULL) EC_KEY_free(pkeyMe);
+ if (pkeyYou != NULL) EC_KEY_free(pkeyYou);
+
+ return false;
+
+}
+
#endif // USE_OPEN_SSL
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index ecd4054..1a4c22f 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -38,6 +38,7 @@
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 enc-01 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-01.json )
add_test ( NAME enc-02 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-02.json )
add_test ( NAME enc-04 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-04.json )
add_test ( NAME enc-05 WORKING_DIRECTORY ${CMAKE_SOURCE_DIR} COMMAND cose_test Examples/spec-examples/Enc-05.json )
diff --git a/test/json.c b/test/json.c
index 184614e..975b2d7 100644
--- a/test/json.c
+++ b/test/json.c
@@ -34,15 +34,16 @@
node = cn_cbor_map_create(CBOR_CONTEXT_PARAM_COMMA NULL);
break;
- case '}':
- parent = parent->parent;
- break;
-
case '[':
node = cn_cbor_array_create(CBOR_CONTEXT_PARAM_COMMA NULL);
break;
+ case '}':
case ']':
+ if (parent == NULL) {
+ fprintf(stderr, "Parse failure @ '%s'\n", &rgch[ib]);
+ return NULL;
+ }
parent = parent->parent;
break;
@@ -93,7 +94,7 @@
default:
error:
fprintf(stderr, "Parse failure @ '%s'\n", &rgch[ib]);
- break;
+ return NULL;
}
if ((node != NULL) && (parent != NULL)) {
@@ -124,14 +125,16 @@
const cn_cbor * ParseJson(const char * fileName)
{
int cch;
- char * rgch = malloc(8 * 1024);
+ char * rgch;
FILE * fp = fopen(fileName, "r");
if (fp == NULL) {
fprintf(stderr, "Cannot open file '%s'\n", fileName);
+
return NULL;
}
+ rgch = malloc(8 * 1024);
cch = (int) fread(rgch, 1, 8*1024, fp);
fclose(fp);
@@ -205,7 +208,10 @@
if (data[input_length - 2] == '=') (*output_length)--;
unsigned char *decoded_data = malloc(*output_length);
- if (decoded_data == NULL) return NULL;
+ if (decoded_data == NULL) {
+ if (p != NULL) free(p);
+ return NULL;
+ }
for (unsigned int i = 0, j = 0; i < input_length;) {
diff --git a/test/test.c b/test/test.c
index 2395be7..d706217 100644
--- a/test/test.c
+++ b/test/test.c
@@ -28,7 +28,7 @@
int i;
} NameMap;
-NameMap RgAlgorithmNames[30] = {
+NameMap RgAlgorithmNames[31] = {
{"HS256", COSE_Algorithm_HMAC_256_256},
{"HS256/64", COSE_Algorithm_HMAC_256_64},
{"HS384", COSE_Algorithm_HMAC_384_384},
@@ -59,6 +59,7 @@
{"HKDF-HMAC-SHA-512", COSE_Algorithm_Direct_HKDF_HMAC_SHA_512},
{"HKDF-AES-128", COSE_Algorithm_Direct_HKDF_AES_128},
{"HKDF-AES-256", COSE_Algorithm_Direct_HKDF_AES_256},
+ {"ECDH-ES", COSE_Algorithm_ECDH_ES_HKDF_256}
};
@@ -609,6 +610,10 @@
HANDLE hFind;
char rgchFullName[2 * 1024];
+ if (strlen(szDir) + 7 >= sizeof(rgchFullName)) {
+ fprintf(stderr, "Buffer overflow error\n");
+ exit(1);
+ }
strcpy(rgchFullName, szDir);
strcat(rgchFullName, "\\");
size_t ich = strlen(rgchFullName);
@@ -623,6 +628,10 @@
do {
rgchFullName[ich] = 0;
+ if (ich + strlen(FindFileData.cFileName) >= sizeof(rgchFullName)) {
+ fprintf(stderr, "Buffer overflow problem\n");
+ exit(1);
+ }
strcat(rgchFullName, FindFileData.cFileName);
printf("Run test '%s'", rgchFullName);
@@ -645,7 +654,6 @@
DIR * dirp = opendir(szDir);
struct dirent * dp;
char rgchFullName[2 * 1024];
- strcpy(rgchFullName, szDir);
int ich;
int cFailTotal = 0;
@@ -653,6 +661,11 @@
fprintf(stderr, "Cannot open directory '%s'\n", szDir);
exit(1);
}
+ if (strlen(szDir) >= sizeof(rgchFullName) - 3) {
+ fprintf(stderr, "Buffer overflow problem\n");
+ exit(1);
+ }
+ strcpy(rgchFullName, szDir);
strcat(rgchFullName, "/");
ich = strlen(rgchFullName);
@@ -660,6 +673,10 @@
int cch = strlen(dp->d_name);
if (cch < 4) continue;
rgchFullName[ich] = 0;
+ if (ich + strlen(dp->d_name) >= sizeof(rgchFullName) - 2) {
+ fprintf(stderr, "Buffer overflow problem\n");
+ exit(1);
+ }
strcat(rgchFullName, dp->d_name);
printf("Run test '%s'", rgchFullName);
CFails = 0;