From c794bbd16d2f39c656478608eb1314055e877370 Mon Sep 17 00:00:00 2001 From: Eneas U de Queiroz Date: Sat, 26 May 2018 23:44:54 -0300 Subject: [PATCH] ibrdtnd: added openssl compatibility This patch adds compatibility with openssl 1.1.0 to ibrdtnd. Signed-off-by: Eneas U de Queiroz --- .../src/security/exchange/DHProtocol.cpp | 36 +++++++++-- .../daemon/src/security/exchange/Makefile.am | 2 + .../src/security/exchange/openssl_compat.cpp | 62 +++++++++++++++++++ .../src/security/exchange/openssl_compat.h | 13 ++++ 4 files changed, 107 insertions(+), 6 deletions(-) create mode 100644 ibrdtn/daemon/src/security/exchange/openssl_compat.cpp create mode 100644 ibrdtn/daemon/src/security/exchange/openssl_compat.h diff --git a/ibrdtn/daemon/src/security/exchange/DHProtocol.cpp b/ibrdtn/daemon/src/security/exchange/DHProtocol.cpp index e94c50260..3e0ad7173 100644 --- a/ibrdtn/daemon/src/security/exchange/DHProtocol.cpp +++ b/ibrdtn/daemon/src/security/exchange/DHProtocol.cpp @@ -30,6 +30,7 @@ #include #include +#include "openssl_compat.h" #define DH_KEY_LENGTH 1024 @@ -132,6 +133,7 @@ namespace dtn void DHProtocol::begin(KeyExchangeSession &session, KeyExchangeData &data) { + const BIGNUM *pub_key, *p, *g; // get session state DHState &state = session.getState(); @@ -159,9 +161,12 @@ namespace dtn // prepare request KeyExchangeData request(KeyExchangeData::REQUEST, session); - write(request, state.dh->pub_key); - write(request, state.dh->p); - write(request, state.dh->g); + DH_get0_pqg(state.dh, &p, NULL, &g); + DH_get0_key(state.dh, &pub_key, NULL); + + write(request, pub_key); + write(request, p); + write(request, g); manager.submit(session, request); } @@ -177,6 +182,15 @@ namespace dtn { if (data.getAction() == KeyExchangeData::REQUEST) { + BIGNUM *p = BN_new(); + BIGNUM *g = BN_new(); + if (p == NULL || g == NULL) + { + BN_free(p); + BN_free(g); + throw ibrcommon::Exception("Error while allocating space for DH parameters"); + } + BIGNUM* pub_key = BN_new(); read(data, &pub_key); @@ -184,8 +198,16 @@ namespace dtn state.dh = DH_new(); // read p and g paramter from message - read(data, &state.dh->p); - read(data, &state.dh->g); + read(data, &p); + read(data, &g); + + if (DH_set0_pqg(state.dh, p, NULL, g)) + { + BN_free(p); + BN_free(g); + BN_free(pub_key); + throw ibrcommon::Exception("Error while setting DH parameters"); + } int codes; if (!DH_check(state.dh, &codes)) @@ -213,7 +235,9 @@ namespace dtn state.secret.assign((const char*)secret, length); KeyExchangeData response(KeyExchangeData::RESPONSE, session); - write(response, state.dh->pub_key); + const BIGNUM *state_dh_pub_key; + DH_get0_key(state.dh, &state_dh_pub_key, NULL); + write(response, state_dh_pub_key); manager.submit(session, response); diff --git a/ibrdtn/daemon/src/security/exchange/Makefile.am b/ibrdtn/daemon/src/security/exchange/Makefile.am index a6b2f8322..71ed8365e 100644 --- a/ibrdtn/daemon/src/security/exchange/Makefile.am +++ b/ibrdtn/daemon/src/security/exchange/Makefile.am @@ -22,6 +22,8 @@ exchange_SOURCES += \ NFCProtocol.cpp \ NoneProtocol.h \ NoneProtocol.cpp \ + openssl_compat.h \ + openssl_compat.cpp \ QRCodeProtocol.h \ QRCodeProtocol.cpp diff --git a/ibrdtn/daemon/src/security/exchange/openssl_compat.cpp b/ibrdtn/daemon/src/security/exchange/openssl_compat.cpp new file mode 100644 index 000000000..e3baba0f2 --- /dev/null +++ b/ibrdtn/daemon/src/security/exchange/openssl_compat.cpp @@ -0,0 +1,62 @@ +/* + * Copyright 2016 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the OpenSSL license (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include "openssl_compat.h" + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +void DH_get0_pqg(const DH *dh, + const BIGNUM **p, const BIGNUM **q, const BIGNUM **g) +{ + if (p != NULL) + *p = dh->p; + if (q != NULL) + *q = dh->q; + if (g != NULL) + *g = dh->g; +} + +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g) +{ + /* If the fields p and g in d are NULL, the corresponding input + * parameters MUST be non-NULL. q may remain NULL. + */ + if ((dh->p == NULL && p == NULL) + || (dh->g == NULL && g == NULL)) + return 0; + + if (p != NULL) { + BN_free(dh->p); + dh->p = p; + } + if (q != NULL) { + BN_free(dh->q); + dh->q = q; + } + if (g != NULL) { + BN_free(dh->g); + dh->g = g; + } + + if (q != NULL) { + dh->length = BN_num_bits(q); + } + + return 1; +} + +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key) +{ + if (pub_key != NULL) + *pub_key = dh->pub_key; + if (priv_key != NULL) + *priv_key = dh->priv_key; +} + +#endif /* OPENSSL_VERSION_NUMBER */ diff --git a/ibrdtn/daemon/src/security/exchange/openssl_compat.h b/ibrdtn/daemon/src/security/exchange/openssl_compat.h new file mode 100644 index 000000000..29e7d4155 --- /dev/null +++ b/ibrdtn/daemon/src/security/exchange/openssl_compat.h @@ -0,0 +1,13 @@ +#ifndef LIBCRYPTO_COMPAT_H +#define LIBCRYPTO_COMPAT_H + +#if OPENSSL_VERSION_NUMBER < 0x10100000L + +#include + +void DH_get0_pqg(const DH *dh, const BIGNUM **p, const BIGNUM **q, const BIGNUM **g); +int DH_set0_pqg(DH *dh, BIGNUM *p, BIGNUM *q, BIGNUM *g); +void DH_get0_key(const DH *dh, const BIGNUM **pub_key, const BIGNUM **priv_key); + +#endif /* OPENSSL_VERSION_NUMBER */ +#endif /* LIBCRYPTO_COMPAT_H */