From 4153da3c16d184a1e6ffa15d2c504c6e3f6b0e1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Roman=20Smr=C5=BE?= Date: Sat, 19 Aug 2023 09:42:34 +0200 Subject: Network: move secure channel to protocol module --- src/channel.cpp | 200 -------------------------------------------------------- 1 file changed, 200 deletions(-) delete mode 100644 src/channel.cpp (limited to 'src/channel.cpp') diff --git a/src/channel.cpp b/src/channel.cpp deleted file mode 100644 index b317f3d..0000000 --- a/src/channel.cpp +++ /dev/null @@ -1,200 +0,0 @@ -#include "channel.h" - -#include -#include -#include - -#include - -using std::remove_const; -using std::runtime_error; - -using namespace erebos; - -Ref ChannelRequestData::store(const Storage & st) const -{ - vector items; - - for (const auto & p : peers) - items.emplace_back("peer", p); - items.emplace_back("enc", "aes-128-gcm"); - items.emplace_back("key", key); - - return st.storeObject(Record(std::move(items))); -} - -ChannelRequestData ChannelRequestData::load(const Ref & ref) -{ - if (auto rec = ref->asRecord()) { - if (rec->item("enc").asText() == "aes-128-gcm") - if (auto key = rec->item("key").as()) - return ChannelRequestData { - .peers = rec->items("peer").as>(), - .key = *key, - }; - } - - return ChannelRequestData { - .peers = {}, - .key = Stored::load(ref.storage().zref()), - }; -} - -Ref ChannelAcceptData::store(const Storage & st) const -{ - vector items; - - items.emplace_back("req", request); - items.emplace_back("enc", "aes-128-gcm"); - items.emplace_back("key", key); - - return st.storeObject(Record(std::move(items))); -} - -ChannelAcceptData ChannelAcceptData::load(const Ref & ref) -{ - if (auto rec = ref->asRecord()) - if (rec->item("enc").asText() == "aes-128-gcm") - return ChannelAcceptData { - .request = *rec->item("req").as(), - .key = *rec->item("key").as(), - }; - - return ChannelAcceptData { - .request = Stored::load(ref.storage().zref()), - .key = Stored::load(ref.storage().zref()), - }; -} - -unique_ptr ChannelAcceptData::channel() const -{ - if (auto secret = SecretKexKey::load(key)) - return make_unique( - request->data->peers, - secret->dh(*request->data->key), - false - ); - - if (auto secret = SecretKexKey::load(request->data->key)) - return make_unique( - request->data->peers, - secret->dh(*key), - true - ); - - throw runtime_error("failed to load secret DH key"); -} - - -Stored Channel::generateRequest(const Storage & st, - const Identity & self, const Identity & peer) -{ - auto signKey = SecretKey::load(self.keyMessage()); - if (!signKey) - throw runtime_error("failed to load own message key"); - - return signKey->sign(st.store(ChannelRequestData { - .peers = self.ref()->digest() < peer.ref()->digest() ? - vector>> { - Stored>::load(*self.ref()), - Stored>::load(*peer.ref()), - } : - vector>> { - Stored>::load(*peer.ref()), - Stored>::load(*self.ref()), - }, - .key = SecretKexKey::generate(st).pub(), - })); -} - -optional> Channel::acceptRequest(const Identity & self, - const Identity & peer, const Stored & request) -{ - if (!request->isSignedBy(peer.keyMessage())) - return nullopt; - - auto & peers = request->data->peers; - if (peers.size() != 2 || - std::none_of(peers.begin(), peers.end(), [&self](const auto & x) - { return x.ref().digest() == self.ref()->digest(); }) || - std::none_of(peers.begin(), peers.end(), [&peer](const auto & x) - { return x.ref().digest() == peer.ref()->digest(); })) - return nullopt; - - auto & st = request.ref().storage(); - - auto signKey = SecretKey::load(self.keyMessage()); - if (!signKey) - throw runtime_error("failed to load own message key"); - - return signKey->sign(st.store(ChannelAcceptData { - .request = request, - .key = SecretKexKey::generate(st).pub(), - })); -} - -vector Channel::encrypt(const vector & plain) -{ - vector res(plain.size() + 8 + 16 + 16); - array iv; - - uint64_t beCount = htobe64(nonceCounter++); - std::memcpy(res.data(), &beCount, 8); - std::copy_n(nonceFixedOur.begin(), 6, iv.begin()); - std::copy_n(res.begin() + 2, 6, iv.begin() + 6); - - const unique_ptr - ctx(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free); - EVP_EncryptInit_ex(ctx.get(), EVP_aes_128_gcm(), - nullptr, key.data(), iv.data()); - - int outl = 0; - uint8_t * cur = res.data() + 8; - - if (EVP_EncryptUpdate(ctx.get(), cur, &outl, plain.data(), plain.size()) != 1) - throw runtime_error("failed to encrypt data"); - cur += outl; - - if (EVP_EncryptFinal(ctx.get(), cur, &outl) != 1) - throw runtime_error("failed to encrypt data"); - cur += outl; - - EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_GET_TAG, 16, cur); - cur += 16; - - res.resize(cur - res.data()); - return res; -} - -optional> Channel::decrypt(const vector & ctext) -{ - vector res(ctext.size()); - array iv; - - std::copy_n(nonceFixedPeer.begin(), 6, iv.begin()); - std::copy_n(ctext.begin() + 2, 6, iv.begin() + 6); - - const unique_ptr - ctx(EVP_CIPHER_CTX_new(), EVP_CIPHER_CTX_free); - EVP_DecryptInit_ex(ctx.get(), EVP_aes_128_gcm(), - nullptr, key.data(), iv.data()); - - int outl = 0; - uint8_t * cur = res.data(); - - if (EVP_DecryptUpdate(ctx.get(), cur, &outl, - ctext.data() + 8, ctext.size() - 8 - 16) != 1) - return nullopt; - cur += outl; - - if (!EVP_CIPHER_CTX_ctrl(ctx.get(), EVP_CTRL_GCM_SET_TAG, 16, - (void *) (ctext.data() + ctext.size() - 16))) - return nullopt; - - if (EVP_DecryptFinal_ex(ctx.get(), cur, &outl) != 1) - return nullopt; - cur += outl; - - res.resize(cur - res.data()); - return res; -} -- cgit v1.2.3