diff --git a/include/cose/cose.h b/include/cose/cose.h index 0cc424c..c9a5783 100644 --- a/include/cose/cose.h +++ b/include/cose/cose.h @@ -222,9 +222,9 @@ typedef enum { * Functions dealing with keys */ -const int COSE_KEY_FL_OWN = 0x1; // Cede ownership of the key to the libraray - // Only neede for MBEDTLS as OpenSSL does reference counts - +const int COSE_KEY_FL_OWN = + 0x1; // Cede ownership of the key to the libraray + // Only neede for MBEDTLS as OpenSSL does reference counts HCOSE_KEY COSE_KEY_FromCbor(cn_cbor* pcborKey, CBOR_CONTEXT_COMMA cose_errback* perror); @@ -235,8 +235,8 @@ HCOSE_KEY COSE_KEY_FromEVP(EVP_PKEY* opensslKey, CBOR_CONTEXT_COMMA cose_errback* perror); #endif #ifdef COSE_C_USE_MBEDTLS -HCOSE_KEY COSE_KEY_FromMbedKeypair(mbedtls_ecp_keypair *, - cn_cbor * pcborKey, +HCOSE_KEY COSE_KEY_FromMbedKeypair(mbedtls_ecp_keypair*, + cn_cbor* pcborKey, int flags, CBOR_CONTEXT_COMMA cose_errback* perror); #endif diff --git a/src/Cose.cpp b/src/Cose.cpp index 1eec83b..b219abd 100644 --- a/src/Cose.cpp +++ b/src/Cose.cpp @@ -666,7 +666,7 @@ bool AreListsEmpty() #if INCLUDE_MAC0 fRet &= Mac0Root == nullptr; #endif - fRet &= KeysRoot == nullptr; + fRet &= COSE_KEY::KeysRoot == nullptr; return fRet; } diff --git a/src/CoseKey.cpp b/src/CoseKey.cpp index 236c05e..ad4444c 100644 --- a/src/CoseKey.cpp +++ b/src/CoseKey.cpp @@ -5,12 +5,12 @@ #include "cose_int.h" #include "cose_crypto.h" -COSE_KEY *KeysRoot = nullptr; +COSE_KEY *COSE_KEY::KeysRoot = nullptr; /*! \private - * @brief Test if a HCOSE_ENVELOPED handle is valid + * @brief Test if a HCOSE_KEY handle is valid * - * Internal function to test if a enveloped message handle is valid. + * Internal function to test if a key handle is valid. * This will start returning invalid results and cause the code to * crash if handles are not released before the memory that underlies them * is deallocated. This is an issue of a block allocator is used since @@ -21,9 +21,9 @@ COSE_KEY *KeysRoot = nullptr; * @returns result of check */ -bool IsValidKeyHandle(HCOSE_KEY h) +bool COSE_KEY::IsValidKeyHandle(HCOSE_KEY h) { - COSE_KEY *p = (COSE_KEY *)h; + COSE_KEY *p = reinterpret_cast(h); if (KeysRoot == nullptr) { return false; } @@ -45,8 +45,7 @@ HCOSE_KEY COSE_KEY_FromCbor(cn_cbor *pcborKey, { COSE_KEY *pkey = nullptr; - pkey = (COSE_KEY *)COSE_CALLOC(1, sizeof(COSE_KEY), context); - + pkey = new (std::nothrow, context) COSE_KEY(); if (pkey == nullptr) { if (perror != nullptr) { perror->err = COSE_ERR_OUT_OF_MEMORY; @@ -54,54 +53,45 @@ HCOSE_KEY COSE_KEY_FromCbor(cn_cbor *pcborKey, return nullptr; } -#ifdef USE_CBOR_CONTEXT - if (context != nullptr) { - pkey->m_allocContext = *context; - } -#endif - - pkey->m_refCount = 1; pkey->m_cborKey = pcborKey; - pkey->m_nextKey = KeysRoot; - KeysRoot = pkey; - - return (HCOSE_KEY)pkey; + return reinterpret_cast(pkey); } -bool COSE_KEY_Free(HCOSE_KEY h) -{ - COSE_KEY *p = (COSE_KEY *)h; - if (!IsValidKeyHandle(h)) { - return false; - } +COSE_KEY::~COSE_KEY() - if (p->m_refCount > 1) { - p->m_refCount--; - return true; +{ + if (m_cborKey != nullptr) { + CN_CBOR_FREE(m_cborKey, &m_allocContext); } - if (KeysRoot == p) { - KeysRoot = p->m_nextKey; - p->m_nextKey = nullptr; + if (KeysRoot == this) { + KeysRoot = this->m_nextKey; + this->m_nextKey = nullptr; ; } else { for (COSE_KEY *walk = KeysRoot; walk->m_nextKey != nullptr; walk = walk->m_nextKey) { - if (walk->m_nextKey == p) { - walk->m_nextKey = p->m_nextKey; - p->m_nextKey = nullptr; + if (walk->m_nextKey == this) { + walk->m_nextKey = this->m_nextKey; + this->m_nextKey = nullptr; break; } } } - if (p->m_cborKey != nullptr && p->m_cborKey->parent == nullptr) { - CN_CBOR_FREE(p->m_cborKey, &p->m_allocContext); + if (m_cborKey != nullptr && m_cborKey->parent == nullptr) { + CN_CBOR_FREE(m_cborKey, &m_allocContext); } +} - COSE_FREE(p, &p->m_allocContext); - +bool COSE_KEY_Free(HCOSE_KEY h) +{ + COSE_KEY *key = reinterpret_cast(h); + if (!COSE_KEY::IsValidKeyHandle(h)) { + return false; + } + key->Release(); return true; } @@ -110,63 +100,36 @@ HCOSE_KEY COSE_KEY_FromEVP(EVP_PKEY *opensslKey, cn_cbor *pcborKey, CBOR_CONTEXT_COMMA cose_errback *perror) { - COSE_KEY *pkey = nullptr; - - pkey = (COSE_KEY *)COSE_CALLOC(1, sizeof(COSE_KEY), context); - + COSE_KEY *pkey = new (std::nothrow, context) COSE_KEY(); if (pkey == nullptr) { perror->err = COSE_ERR_OUT_OF_MEMORY; return nullptr; } -#ifdef USE_CBOR_CONTEXT - if (context != nullptr) { - pkey->m_allocContext = *context; - } -#endif - - pkey->m_refCount = 1; - pkey->m_cborKey = pcborKey; pkey->m_opensslKey = opensslKey; + pkey->m_cborKey = pcborKey; EVP_PKEY_up_ref(opensslKey); - pkey->m_nextKey = KeysRoot; - KeysRoot = pkey; - - return (HCOSE_KEY)pkey; + return reinterpret_cast(pkey); } #endif #ifdef COSE_C_USE_MBEDTLS -HCOSE_KEY COSE_KEY_FromMbedKeypair(mbedtls_ecp_keypair * mbedtls_keypair, +HCOSE_KEY COSE_KEY_FromMbedKeypair(mbedtls_ecp_keypair *mbedtls_keypair, cn_cbor *pcborKey, int flags, CBOR_CONTEXT_COMMA cose_errback *perror) { - COSE_KEY *pkey = nullptr; - - pkey = (COSE_KEY *)COSE_CALLOC(1, sizeof(COSE_KEY), context); - + COSE_KEY *pkey = new (std::nothrow, context) COSE_KEY(); if (pkey == nullptr) { perror->err = COSE_ERR_OUT_OF_MEMORY; return nullptr; } -#ifdef USE_CBOR_CONTEXT - if (context != nullptr) { - pkey->m_allocContext = *context; - } -#endif - - pkey->m_refCount = 1; - pkey->m_cborKey = pcborKey; pkey->m_mbedtls_keypair = mbedtls_keypair; pkey->m_flags = flags; - pkey->m_nextKey = KeysRoot; - KeysRoot = pkey; - - return (HCOSE_KEY)pkey; + return reinterpret_cast(pkey); } #endif diff --git a/src/CounterSign.cpp b/src/CounterSign.cpp index 4270398..19583e8 100644 --- a/src/CounterSign.cpp +++ b/src/CounterSign.cpp @@ -257,7 +257,7 @@ bool COSE_CounterSign_SetKey2(HCOSE_COUNTERSIGN hSigner, COSE_KEY* pKey = (COSE_KEY*)hKey; CHECK_CONDITION(IsValidCounterSignHandle(hSigner), COSE_ERR_INVALID_HANDLE); - CHECK_CONDITION(IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); + CHECK_CONDITION(COSE_KEY::IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); if (pSigner->m_signer.m_pkey != nullptr) { COSE_KEY_Free((HCOSE_KEY)pSigner->m_signer.m_pkey); diff --git a/src/CounterSign1.cpp b/src/CounterSign1.cpp index a8eb5b3..dc6445e 100644 --- a/src/CounterSign1.cpp +++ b/src/CounterSign1.cpp @@ -294,7 +294,7 @@ bool COSE_CounterSign1_SetKey(HCOSE_COUNTERSIGN1 hSigner, CHECK_CONDITION( IsValidCounterSign1Handle(hSigner), COSE_ERR_INVALID_HANDLE); - CHECK_CONDITION(IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); + CHECK_CONDITION(COSE_KEY::IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); if (pSigner->m_signer.m_pkey != nullptr) { COSE_KEY_Free((HCOSE_KEY)pSigner->m_signer.m_pkey); diff --git a/src/Recipient.cpp b/src/Recipient.cpp index 2682079..2671327 100644 --- a/src/Recipient.cpp +++ b/src/Recipient.cpp @@ -1630,7 +1630,8 @@ bool COSE_Recipient_SetSenderKey2(HCOSE_RECIPIENT h, } CHECK_CONDITION(IsValidRecipientHandle(h), COSE_ERR_INVALID_HANDLE); - CHECK_CONDITION(IsValidKeyHandle(hKey), COSE_ERR_INVALID_PARAMETER); + CHECK_CONDITION( + COSE_KEY::IsValidKeyHandle(hKey), COSE_ERR_INVALID_PARAMETER); p = (COSE_RecipientInfo *)h; COSE_KEY *pKey = (COSE_KEY *)hKey; diff --git a/src/Sign1.cpp b/src/Sign1.cpp index efd7775..2594e44 100644 --- a/src/Sign1.cpp +++ b/src/Sign1.cpp @@ -262,7 +262,7 @@ bool COSE_Sign1_Sign2(HCOSE_SIGN1 h, HCOSE_KEY hKey, cose_errback *perr) errorReturn: return false; } - CHECK_CONDITION(IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); + CHECK_CONDITION(COSE_KEY::IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); #ifdef USE_CBOR_CONTEXT context = &pMessage->m_message.m_allocContext; @@ -311,7 +311,7 @@ bool COSE_Sign1_validate2(HCOSE_SIGN1 hSign, HCOSE_KEY hKey, cose_errback *perr) } CHECK_CONDITION(IsValidSign1Handle(hSign), COSE_ERR_INVALID_HANDLE); - CHECK_CONDITION(IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); + CHECK_CONDITION(COSE_KEY::IsValidKeyHandle(hKey), COSE_ERR_INVALID_HANDLE); COSE_Sign1Message *pSign = (COSE_Sign1Message *)hSign; diff --git a/src/SignerInfo.cpp b/src/SignerInfo.cpp index e1692a9..c509cd5 100644 --- a/src/SignerInfo.cpp +++ b/src/SignerInfo.cpp @@ -362,7 +362,7 @@ bool COSE_Signer_SetKey2(HCOSE_SIGNER h, HCOSE_KEY pKey, cose_errback *perr) } CHECK_CONDITION(IsValidSignerHandle(h), COSE_ERR_INVALID_HANDLE); - CHECK_CONDITION(IsValidKeyHandle(pKey), COSE_ERR_INVALID_HANDLE); + CHECK_CONDITION(COSE_KEY::IsValidKeyHandle(pKey), COSE_ERR_INVALID_HANDLE); p = (COSE_SignerInfo *)h; if (p->m_pkey != nullptr) { diff --git a/src/cose_int.h b/src/cose_int.h index 88d9907..ba260ae 100644 --- a/src/cose_int.h +++ b/src/cose_int.h @@ -1,6 +1,10 @@ #pragma once #include +#ifdef __cplusplus +#include +#endif + #include #include #include @@ -12,6 +16,57 @@ #include #endif +#ifdef USE_CBOR_CONTEXT +/** + * Allocate enough space for 1 `cn_cbor` structure. + * + * @param[in] ctx The allocation context, or nullptr for calloc. + * @return A pointer to a `cn_cbor` or nullptr on failure + */ +#define CN_CALLOC(ctx) \ + ((ctx) && (ctx)->calloc_func) \ + ? (ctx)->calloc_func(1, sizeof(cn_cbor), (ctx)->context) \ + : calloc(1, sizeof(cn_cbor)); + +/** + * Allocate space required + * + * @param[in] ctx The allocation context, or nullptr for normal calloc. + * @param[in] count Number of items to allocate + * @param[in] size Size of item to allocate + * @return A pointer to the object needed + */ +#define COSE_CALLOC(count, size, ctx) \ + ((((ctx)) && ((ctx)->calloc_func)) \ + ? ((ctx)->calloc_func(count, size, (ctx)->context)) \ + : calloc(count, size)) + +/** + * Free a + * @param free_func [description] + * @return [description] + */ +#define COSE_FREE(ptr, ctx) \ + ((((ctx) && (ctx)->free_func)) ? ((ctx)->free_func((ptr), (ctx)->context)) \ + : free((ptr))) + +#define CBOR_CONTEXT_PARAM , context +#define CBOR_CONTEXT_PARAM_COMMA context, +//#define CN_CALLOC_CONTEXT() CN_CALLOC(context) +#define CN_CBOR_FREE(p, context) cn_cbor_free(p, context) + +#else + +#define CBOR_CONTEXT_PARAM +#define CBOR_CONTEXT_PARAM_COMMA +#define CN_CALLOC_CONTEXT() CN_CALLOC +#define COSE_CALLOC(count, size, ctx) calloc(count, size) +#define CN_CBOR_FREE(p, context) cn_cbor_free(p) + +#define COSE_FREE(ptr, ctx) free(ptr) + +#endif // USE_CBOR_CONTEXT + // These definitions are here because they aren't required for the public // interface, and they were quite confusing in cn-cbor.h @@ -27,11 +82,13 @@ typedef struct CounterSign1 COSE_CounterSign1; #define _countof(x) (sizeof(x) / sizeof(x[0])) #endif -typedef struct _COSE_KEY { +#ifdef __cplusplus +class COSE_KEY { + public: int m_refCount; cn_cbor *m_cborKey; int m_flags; - struct _COSE_KEY *m_nextKey; + COSE_KEY *m_nextKey; #ifdef USE_CBOR_CONTEXT cn_cbor_context m_allocContext; #endif @@ -39,9 +96,66 @@ typedef struct _COSE_KEY { EVP_PKEY *m_opensslKey; #endif #ifdef COSE_C_USE_MBEDTLS - mbedtls_ecp_keypair * m_mbedtls_keypair; + mbedtls_ecp_keypair *m_mbedtls_keypair; +#endif + + public: + static COSE_KEY *KeysRoot; + + public: + COSE_KEY() + { + m_refCount = 1; + m_nextKey = KeysRoot; + KeysRoot = this; + } + + ~COSE_KEY(); + + int AddRef() { return m_refCount += 1; } + int Release() + { + if (m_refCount > 1) { + return m_refCount -= 1; + } +#ifdef USE_CBOR_CONTEXT + COSE_KEY::~COSE_KEY(); + COSE_FREE(this, &m_allocContext); +#else + delete this; +#endif + return 0; + } + + static bool IsValidKeyHandle(HCOSE_KEY h); + +#ifdef USE_CBOR_CONTEXT + __nothrow void *operator new(size_t size, + const std::nothrow_t &, + cn_cbor_context *context) + { + COSE_KEY *p = static_cast(COSE_CALLOC(size, 1, context)); + if (p == nullptr) { + return nullptr; + } + + if (context != nullptr) { + p->m_allocContext = *context; + } + return p; + } + + void operator delete(void *p, + const std::nothrow_t &, + cn_cbor_context *context) + { + COSE_FREE(p, context); + } +#endif +}; +#else +typedef void *COSE_KEY; #endif -} COSE_KEY; typedef struct _COSE { COSE_INIT_FLAGS m_flags; // Not sure what goes here yet @@ -123,57 +237,6 @@ struct CounterSign1 { COSE_CounterSign1 *m_next; }; -#ifdef USE_CBOR_CONTEXT -/** - * Allocate enough space for 1 `cn_cbor` structure. - * - * @param[in] ctx The allocation context, or nullptr for calloc. - * @return A pointer to a `cn_cbor` or nullptr on failure - */ -#define CN_CALLOC(ctx) \ - ((ctx) && (ctx)->calloc_func) \ - ? (ctx)->calloc_func(1, sizeof(cn_cbor), (ctx)->context) \ - : calloc(1, sizeof(cn_cbor)); - -/** - * Allocate space required - * - * @param[in] ctx The allocation context, or nullptr for normal calloc. - * @param[in] count Number of items to allocate - * @param[in] size Size of item to allocate - * @return A pointer to the object needed - */ -#define COSE_CALLOC(count, size, ctx) \ - ((((ctx)) && ((ctx)->calloc_func)) \ - ? ((ctx)->calloc_func(count, size, (ctx)->context)) \ - : calloc(count, size)) - -/** - * Free a - * @param free_func [description] - * @return [description] - */ -#define COSE_FREE(ptr, ctx) \ - ((((ctx) && (ctx)->free_func)) ? ((ctx)->free_func((ptr), (ctx)->context)) \ - : free((ptr))) - -#define CBOR_CONTEXT_PARAM , context -#define CBOR_CONTEXT_PARAM_COMMA context, -//#define CN_CALLOC_CONTEXT() CN_CALLOC(context) -#define CN_CBOR_FREE(p, context) cn_cbor_free(p, context) - -#else - -#define CBOR_CONTEXT_PARAM -#define CBOR_CONTEXT_PARAM_COMMA -#define CN_CALLOC_CONTEXT() CN_CALLOC -#define COSE_CALLOC(count, size, ctx) calloc(count, size) -#define CN_CBOR_FREE(p, context) cn_cbor_free(p) - -#define COSE_FREE(ptr, ctx) free(ptr) - -#endif // USE_CBOR_CONTEXT - cose_error _MapFromCBOR(cn_cbor_errback err); /* @@ -194,7 +257,6 @@ bool IsValidCounterSignHandle(HCOSE_COUNTERSIGN h); bool IsValidCounterSign1Handle(HCOSE_COUNTERSIGN1 h); bool IsValidMacHandle(HCOSE_MAC h); bool IsValidMac0Handle(HCOSE_MAC0 h); -bool IsValidKeyHandle(HCOSE_KEY h); bool _COSE_Init(COSE_INIT_FLAGS flags, COSE *pcose, @@ -476,13 +538,12 @@ enum { COSE_Int_Alg_AES_CBC_MAC_256_64 = -22 }; #define COSE_CounterSign_object 1000 #define COSE_CounterSign1_object 1001 - #if defined(COSE_C_USE_OPENSSL) && (OPENSSL_VERSION_NUMBER > 0x10100000L) EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr); #endif #ifdef COSE_C_USE_MBEDTLS -mbedtls_ecp_keypair * ECKey_From(COSE_KEY *pKey, +mbedtls_ecp_keypair *ECKey_From(COSE_KEY *pKey, mbedtls_ecp_keypair *keypair, cose_errback *perr); #endif diff --git a/src/mbedtls.cpp b/src/mbedtls.cpp index 5626192..593f116 100644 --- a/src/mbedtls.cpp +++ b/src/mbedtls.cpp @@ -666,14 +666,14 @@ bool HMAC_Validate(COSE_MacMessage *pcose, #define COSE_Key_EC_Y -3 #define COSE_Key_EC_d -4 -mbedtls_ecp_keypair * ECKey_From(COSE_KEY *pKey, +mbedtls_ecp_keypair *ECKey_From(COSE_KEY *pKey, mbedtls_ecp_keypair *keypair, cose_errback *perr) { if (pKey->m_mbedtls_keypair != nullptr) { return pKey->m_mbedtls_keypair; } - + byte rgbKey[MBEDTLS_ECP_MAX_PT_LEN]; int cbKey = 0; int cbGroup = 0; @@ -869,7 +869,7 @@ bool ECDSA_Verify(COSE *pSigner, cose_errback *perr) { mbedtls_ecp_keypair keypair; - mbedtls_ecp_keypair* useKey = nullptr; + mbedtls_ecp_keypair *useKey = nullptr; mbedtls_mpi r; mbedtls_mpi s; mbedtls_md_type_t mdType; diff --git a/src/openssl.cpp b/src/openssl.cpp index f376fb4..f1b93bd 100644 --- a/src/openssl.cpp +++ b/src/openssl.cpp @@ -1084,7 +1084,6 @@ bool HMAC_Validate(COSE_MacMessage *pcose, #define COSE_Key_EC_Y -3 #define COSE_Key_EC_d -4 - EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr) { EC_KEY *pNewKey = nullptr; @@ -1116,7 +1115,7 @@ EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr) default: FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER); - } + } return pKeyNew; } diff --git a/test/test.cpp b/test/test.cpp index f515018..e2c3e12 100644 --- a/test/test.cpp +++ b/test/test.cpp @@ -21,7 +21,6 @@ #include "json.h" #include "test.h" - #ifdef COSE_C_USE_OPENSSL #include #endif @@ -904,14 +903,14 @@ HCOSE_KEY BuildKey(const cn_cbor* pKeyIn, bool fPublicKey) #endif #ifdef COSE_C_USE_MBEDTLS { - keypair = - static_cast(COSE_CALLOC(sizeof(*keypair), 1, context) - ); + keypair = static_cast( + COSE_CALLOC(sizeof(*keypair), 1, context)); if (keypair == nullptr) { return nullptr; } mbedtls_ecp_keypair_init(keypair); - if (!ECKey_From((COSE_KEY *) (HCOSE_KEY) key, keypair, &coseError)) { + if (!ECKey_From( + (COSE_KEY*)(HCOSE_KEY)key, keypair, &coseError)) { mbedtls_ecp_keypair_free(keypair); COSE_FREE(keypair, context); return nullptr; @@ -1527,7 +1526,6 @@ void RunTestsInDirectory(const char* szDir) } #endif // _MSCVER - int main(int argc, char** argv) { int i;