Skip to content

Commit

Permalink
Remove support for Openssl pre 1.1
Browse files Browse the repository at this point in the history
* Deal with flag for doing compressed vs uncompressed points
* Use EVP everywhere but ECDSA signing - should do that too
  • Loading branch information
jimsch committed Jun 3, 2020
1 parent bb3010a commit 7583bcb
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 166 deletions.
2 changes: 1 addition & 1 deletion src/Recipient.cpp
Expand Up @@ -1658,7 +1658,7 @@ bool COSE_Recipient_SetSenderKey2(HCOSE_RECIPIENT h,
case COSE_UNPROTECT_ONLY:
if (pKey->m_cborKey == nullptr) {
#ifdef COSE_C_USE_OPENSSL
pKey->m_cborKey = EVP_ToCBOR(pKey->m_opensslKey,
pKey->m_cborKey = EVP_ToCBOR(pKey->m_opensslKey, true,
#ifdef USE_CBOR_CONTEXT
&pKey->m_allocContext,
#endif
Expand Down
3 changes: 2 additions & 1 deletion src/cose_int.h
Expand Up @@ -479,7 +479,8 @@ enum { COSE_Int_Alg_AES_CBC_MAC_256_64 = -22 };

#if defined(COSE_C_USE_OPENSSL) && (OPENSSL_VERSION_NUMBER > 0x10100000L)
EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr);
cn_cbor * EVP_ToCBOR(EVP_PKEY * pKey, CBOR_CONTEXT_COMMA cose_errback *perr);
cn_cbor * EVP_ToCBOR(EVP_PKEY * pKey, bool fCompressPoints, CBOR_CONTEXT_COMMA cose_errback *perr);
EVP_PKEY *EVP_FromKey(COSE_KEY *pKey, CBOR_CONTEXT_COMMA cose_errback *perr);
#endif

#ifdef COSE_C_USE_MBEDTLS
Expand Down
199 changes: 51 additions & 148 deletions src/openssl.cpp
Expand Up @@ -22,45 +22,6 @@
#include <openssl/rand.h>
#include <openssl/bn.h>

static bool FUseCompressed = true;

#if (OPENSSL_VERSION_NUMBER < 0x10100000)

HMAC_CTX *HMAC_CTX_new()
{
HMAC_CTX *foo = (HMAC_CTX *)malloc(sizeof(HMAC_CTX));
if (foo != nullptr) {
HMAC_CTX_init(foo);
}
return foo;
}

void HMAC_CTX_free(HMAC_CTX *foo)
{
if (foo != nullptr)
free(foo);
}

void ECDSA_SIG_get0(const ECDSA_SIG *sig, const BIGNUM **pr, const BIGNUM **ps)
{
if (pr != nullptr)
*pr = sig->r;
if (ps != nullptr)
*ps = sig->s;
}

int ECDSA_SIG_set0(ECDSA_SIG *sig, BIGNUM *r, BIGNUM *s)
{
if (r == nullptr || s == nullptr)
return 0;
BN_clear_free(sig->r);
BN_clear_free(sig->s);
sig->r = r;
sig->s = s;
return 1;
}
#endif

/*******************************************/

#define Safe_OPENSSL(handleName, freeFunction) \
Expand Down Expand Up @@ -115,7 +76,6 @@ Safe_OPENSSL(EC_KEY, EC_KEY_free);
Safe_OPENSSL(EVP_PKEY, EVP_PKEY_free);



/**********************************************/

bool AES_CCM_Decrypt(COSE_Enveloped *pcose,
Expand Down Expand Up @@ -1125,10 +1085,12 @@ bool HMAC_Validate(COSE_MacMessage *pcose,
CHECK_CONDITION(cn != nullptr, COSE_ERR_CBOR);

if (cn->length > cbOut) {
return false;
f = false;
}
for (unsigned int i = 0; i < (unsigned int)TSize / 8; i++) {
f |= (cn->v.bytes[i] != rgbOut[i]);
else {
for (unsigned int i = 0; i < (unsigned int)TSize / 8; i++) {
f |= (cn->v.bytes[i] != rgbOut[i]);
}
}

COSE_FREE(rgbOut, context);
Expand Down Expand Up @@ -1313,8 +1275,9 @@ EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr)
cbKey = (*cbGroup) + 1;
rgbKey[0] = POINT_CONVERSION_COMPRESSED;
}
else
else {
FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
}

pPoint = EC_POINT_new(ecgroup);
CHECK_CONDITION(pPoint != nullptr, COSE_ERR_CRYPTO_FAIL);
Expand All @@ -1341,7 +1304,7 @@ EC_KEY *ECKey_From(COSE_KEY *pKey, int *cbGroup, cose_errback *perr)
return pNewKey.Release();
}

cn_cbor *EC_ToCBOR(const EC_KEY * pKey, CBOR_CONTEXT_COMMA cose_errback * perr)
cn_cbor *EC_ToCBOR(const EC_KEY * pKey, bool fUseCompressed, CBOR_CONTEXT_COMMA cose_errback * perr)
{
cn_cbor *pkey = nullptr;
int cose_group;
Expand Down Expand Up @@ -1384,7 +1347,7 @@ cn_cbor *EC_ToCBOR(const EC_KEY * pKey, CBOR_CONTEXT_COMMA cose_errback * perr)
pPoint = EC_KEY_get0_public_key(pKey);
CHECK_CONDITION(pPoint != nullptr, COSE_ERR_INVALID_PARAMETER);

if (FUseCompressed) {
if (fUseCompressed) {
cbSize = EC_POINT_point2oct(
pgroup, pPoint, POINT_CONVERSION_COMPRESSED, nullptr, 0, nullptr);
CHECK_CONDITION(cbSize > 0, COSE_ERR_CRYPTO_FAIL);
Expand Down Expand Up @@ -1421,7 +1384,7 @@ cn_cbor *EC_ToCBOR(const EC_KEY * pKey, CBOR_CONTEXT_COMMA cose_errback * perr)
cbor_error);
p = nullptr;

if (FUseCompressed) {
if (fUseCompressed) {
p = cn_cbor_bool_create(
pbPoint[0] & 1, CBOR_CONTEXT_PARAM_COMMA & cbor_error);
CHECK_CONDITION_CBOR(p != nullptr, cbor_error);
Expand Down Expand Up @@ -1471,16 +1434,16 @@ cn_cbor *EC_ToCBOR(const EC_KEY * pKey, CBOR_CONTEXT_COMMA cose_errback * perr)
}


cn_cbor *EVP_ToCBOR(EVP_PKEY *pKey,
cn_cbor *EVP_ToCBOR(EVP_PKEY *pKey, bool fCompressPoints,
CBOR_CONTEXT_COMMA cose_errback *perr)
{
cn_cbor_errback cborErr;
int type = EVP_PKEY_base_id(pKey);

switch (type) {
case EVP_PKEY_EC:
return EC_ToCBOR(
EVP_PKEY_get1_EC_KEY(pKey), CBOR_CONTEXT_PARAM_COMMA perr);
return EC_ToCBOR(EVP_PKEY_get1_EC_KEY(pKey), fCompressPoints,
CBOR_CONTEXT_PARAM_COMMA perr);

case EVP_PKEY_X25519:
case EVP_PKEY_X448: {
Expand Down Expand Up @@ -1545,12 +1508,13 @@ cn_cbor *EVP_ToCBOR(EVP_PKEY *pKey,

}

#if false

COSE_KEY *EC_FromKey(EC_KEY *pKey, CBOR_CONTEXT_COMMA cose_errback *perr)
COSE_KEY *EC_FromKey(EC_KEY *pKey, bool fUseCompressed, CBOR_CONTEXT_COMMA cose_errback *perr)
{
COSE_KEY *coseKey = nullptr;
cn_cbor *pkey =
EC_ToCBOR(pKey, CBOR_CONTEXT_PARAM_COMMA perr);
EC_ToCBOR(pKey, fUseCompressed, CBOR_CONTEXT_PARAM_COMMA perr);
if (pkey == nullptr) {
return nullptr;
}
Expand All @@ -1574,6 +1538,7 @@ COSE_KEY *EC_FromKey(EC_KEY *pKey, CBOR_CONTEXT_COMMA cose_errback *perr)
errorReturn:
goto returnHere;
}
#endif

bool ECDSA_Sign(COSE *pSigner,
int index,
Expand Down Expand Up @@ -1760,7 +1725,7 @@ bool EdDSA_Sign(COSE *pSigner,
cn_cbor_errback cbor_error;
EVP_PKEY_CTX *keyCtx = nullptr;
EVP_MD_CTX *mdCtx = nullptr;
EVP_PKEY *pkey = nullptr;
Safe_EVP_PKEY pkey;
byte *pbSig = nullptr;
int cbSig;

Expand All @@ -1773,9 +1738,6 @@ bool EdDSA_Sign(COSE *pSigner,
if (keyCtx != nullptr) {
EVP_PKEY_CTX_free(keyCtx);
}
if (pkey != nullptr) {
EVP_PKEY_free(pkey);
}
if (pbSig != nullptr) {
COSE_FREE(pbSig, context);
}
Expand All @@ -1799,12 +1761,11 @@ bool EdDSA_Sign(COSE *pSigner,
FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
}

p = cn_cbor_mapget_int(pKeyIn->m_cborKey, COSE_Key_EC_d);
CHECK_CONDITION(p != nullptr, COSE_ERR_INVALID_PARAMETER);

pkey = EVP_PKEY_new_raw_private_key(type, nullptr, p->v.bytes, p->length);
CHECK_CONDITION(pkey != nullptr, COSE_ERR_CRYPTO_FAIL);

pkey = EVP_FromKey(pKeyIn, CBOR_CONTEXT_PARAM_COMMA perr);
if (pkey == nullptr) {
goto errorReturn;
}

keyCtx = EVP_PKEY_CTX_new_id(type, nullptr);
CHECK_CONDITION(keyCtx != nullptr, COSE_ERR_OUT_OF_MEMORY);

Expand Down Expand Up @@ -1839,9 +1800,6 @@ bool EdDSA_Sign(COSE *pSigner,
if (keyCtx != nullptr) {
EVP_PKEY_CTX_free(keyCtx);
}
if (pkey != nullptr) {
EVP_PKEY_free(pkey);
}
if (pbSig != nullptr) {
COSE_FREE(pbSig, context);
}
Expand All @@ -1856,14 +1814,18 @@ bool EdDSA_Verify(COSE *pSigner,
size_t cbToSign,
cose_errback *perr)
{
#ifdef USE_CBOR_CONTEXT
cn_cbor_context *context = &pSigner->m_allocContext;
#endif
cn_cbor *pSig;
EVP_PKEY *pkey = nullptr;
Safe_EVP_PKEY pkey = nullptr;
EVP_MD_CTX *pmdCtx = nullptr;

cn_cbor *p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_OPK_Curve);
if (p == nullptr) {
errorReturn:
if (pkey != nullptr) {
EVP_PKEY_free(pkey);
if (pmdCtx != nullptr) {
EVP_MD_CTX_free(pmdCtx);
}
return false;
}
Expand All @@ -1883,16 +1845,15 @@ bool EdDSA_Verify(COSE *pSigner,
FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
}

p = cn_cbor_mapget_int(pKey->m_cborKey, COSE_Key_OPK_X);
CHECK_CONDITION(p != nullptr, COSE_ERR_INVALID_PARAMETER);

pkey = EVP_PKEY_new_raw_public_key(type, nullptr, p->v.bytes, p->length);
CHECK_CONDITION(pkey != nullptr, COSE_ERR_CBOR);
pkey = EVP_FromKey(pKey, CBOR_CONTEXT_PARAM_COMMA perr);
if (pkey == nullptr) {
goto errorReturn;
}

pSig = _COSE_arrayget_int(pSigner, index);
CHECK_CONDITION(pSig != nullptr, COSE_ERR_INVALID_PARAMETER);

EVP_MD_CTX *pmdCtx = EVP_MD_CTX_new();
pmdCtx = EVP_MD_CTX_new();
EVP_PKEY_CTX *keyCtx = EVP_PKEY_CTX_new_id(type, nullptr);

CHECK_CONDITION(
Expand All @@ -1906,9 +1867,6 @@ bool EdDSA_Verify(COSE *pSigner,
if (pmdCtx != nullptr) {
EVP_MD_CTX_free(pmdCtx);
}
if (pkey != nullptr) {
EVP_PKEY_free(pkey);
}

return true;
}
Expand Down Expand Up @@ -2009,7 +1967,6 @@ bool ECDH_ComputeSecret(COSE *pRecipient,
size_t *pcbSecret,
CBOR_CONTEXT_COMMA cose_errback *perr)
{
#if OPENSSL_VERSION_NUMBER > 0x10100000L
EVP_PKEY *evpPublic = nullptr;
EVP_PKEY *evpPrivate = nullptr;
EVP_PKEY_CTX *ctx = nullptr;
Expand All @@ -2030,8 +1987,20 @@ bool ECDH_ComputeSecret(COSE *pRecipient,
goto errorReturn;
}

bool fCompressPoints = true;

if (*ppKeyPrivate == nullptr) {
// Generate an ephemeral key for the key agreement.

int type = EVP_PKEY_base_id(evpPublic);
cn_cbor *pCompress = _COSE_map_get_int(
pRecipient, COSE_Header_UseCompressedECDH, COSE_DONT_SEND, perr);
if (pCompress == nullptr) {
fCompressPoints = true;
}
else {
fCompressPoints = (pCompress->type == CN_CBOR_TRUE);
}

switch (type) {
case EVP_PKEY_EC: {
Expand Down Expand Up @@ -2063,18 +2032,20 @@ bool ECDH_ComputeSecret(COSE *pRecipient,
FAIL_CONDITION(COSE_ERR_INVALID_PARAMETER);
}

cn_cbor *pcborPrivate =
EVP_ToCBOR(evpPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
cn_cbor *pcborPrivate = EVP_ToCBOR(
evpPrivate, fCompressPoints, CBOR_CONTEXT_PARAM_COMMA perr);
if (pcborPrivate == nullptr) {
goto errorReturn;
}
COSE_KEY *pPrivateKey = (COSE_KEY *) COSE_KEY_FromEVP(evpPrivate, pcborPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
if (pPrivateKey == nullptr) {
CN_CBOR_FREE(pcborPrivate, context);
goto errorReturn;
}
*ppKeyPrivate = pPrivateKey;
}
else {
// Use the passed in sender key
evpPrivate = EVP_FromKey(*ppKeyPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
if (evpPrivate == nullptr) {
goto errorReturn;
Expand Down Expand Up @@ -2103,74 +2074,6 @@ bool ECDH_ComputeSecret(COSE *pRecipient,
*pcbSecret = skeylen;

return true;

#else
EC_KEY *peckeyPrivate = nullptr;
EC_KEY *peckeyPublic = nullptr;
int cbGroup;
int cbsecret;
byte *pbsecret = nullptr;
bool fRet = false;

peckeyPublic = ECKey_From(pKeyPublic, &cbGroup, perr);
if (peckeyPublic == nullptr) {
goto errorReturn;
}

if (*ppKeyPrivate == nullptr) {
{
cn_cbor *pCompress = _COSE_map_get_int(
pRecipient, COSE_Header_UseCompressedECDH, COSE_BOTH, perr);
if (pCompress == nullptr) {
FUseCompressed = false;
}
else {
FUseCompressed = (pCompress->type == CN_CBOR_TRUE);
}
}
peckeyPrivate = EC_KEY_new();
EC_KEY_set_group(peckeyPrivate, EC_KEY_get0_group(peckeyPublic));
CHECK_CONDITION(
EC_KEY_generate_key(peckeyPrivate) == 1, COSE_ERR_CRYPTO_FAIL);
*ppKeyPrivate =
EC_FromKey(peckeyPrivate, CBOR_CONTEXT_PARAM_COMMA perr);
if (*ppKeyPrivate == nullptr) {
goto errorReturn;
}
}
else {
peckeyPrivate = ECKey_From(*ppKeyPrivate, &cbGroup, perr);
if (peckeyPrivate == nullptr) {
goto errorReturn;
}
}

pbsecret = (byte *)COSE_CALLOC(cbGroup, 1, context);
CHECK_CONDITION(pbsecret != nullptr, COSE_ERR_OUT_OF_MEMORY);

cbsecret = ECDH_compute_key(pbsecret, cbGroup,
EC_KEY_get0_public_key(peckeyPublic), peckeyPrivate, nullptr);
CHECK_CONDITION(cbsecret > 0, COSE_ERR_CRYPTO_FAIL);

*ppbSecret = pbsecret;
*pcbSecret = cbsecret;
pbsecret = nullptr;

fRet = true;

errorReturn:
if (pbsecret != nullptr) {
COSE_FREE(pbsecret, context);
}
if (peckeyPublic != nullptr) {
EC_KEY_free(peckeyPublic);
}
if (peckeyPrivate != nullptr) {
EC_KEY_free(peckeyPrivate);
}

return fRet;
#endif
}

#endif // COSE_C_USE_OPENSSL

0 comments on commit 7583bcb

Please sign in to comment.