more send stuff, more refactoring

This commit is contained in:
Green Sky 2024-08-05 22:03:03 +02:00
parent 7399956a06
commit 0a0fb18527
No known key found for this signature in database
2 changed files with 238 additions and 70 deletions

View File

@ -1,8 +1,11 @@
#include "./tox_p2prng.hpp" #include "./tox_p2prng.hpp"
#include <solanaceae/contact/components.hpp>
#include <solanaceae/tox_contacts/components.hpp> #include <solanaceae/tox_contacts/components.hpp>
#include <solanaceae/toxcore/tox_interface.hpp>
#include <iostream> #include <iostream>
#include <vector>
// packets: // packets:
// //
@ -25,6 +28,8 @@
// secret_request // secret_request
// - id // - id
#define TOX_PKG_ID_FRIEND 0xB1
#define TOX_PKG_ID_GROUP 0xa6
void ToxP2PRNG::RngState::fillInitalStatePreamble(const ByteSpan id) { void ToxP2PRNG::RngState::fillInitalStatePreamble(const ByteSpan id) {
// id // id
@ -105,6 +110,30 @@ void ToxP2PRNG::RngState::genFinalResult(void) {
// we done // we done
} }
P2PRNG::State ToxP2PRNG::RngState::getState(void) const {
//DONE, // rng is done, event contains full rng
if (!final_result.empty()) {
return P2PRNG::DONE;
}
//SECRET, // got a secret (phase start will be denoted by own, secrets received before we have all hmacs get queued up)
if (hmacs.size() == contacts.size()) {
return P2PRNG::SECRET;
}
//HMAC, // got a hmac (phase start will be denoted by the initiators hmac)
if (!hmacs.empty()) {
return P2PRNG::HMAC;
}
//INIT, // inital params (incoming or outgoing?)
if (!inital_state.empty() && !inital_state_preamble.empty()) {
return P2PRNG::INIT;
}
return P2PRNG::UNKNOWN;
}
ToxP2PRNG::ToxP2PRNG( ToxP2PRNG::ToxP2PRNG(
ToxI& t, ToxI& t,
ToxEventProviderI& tep, ToxEventProviderI& tep,
@ -137,32 +166,31 @@ ByteSpan ToxP2PRNG::getResult(const ByteSpan id) {
bool ToxP2PRNG::handlePacket( bool ToxP2PRNG::handlePacket(
Contact3Handle c, Contact3Handle c,
PKG pkg_type, PKG pkg_type,
const uint8_t* data, ByteSpan data
const size_t data_size
) { ) {
if (data_size < 1) { if (data.size < 1) {
return false; // waht return false; // waht
} }
// rn all are prefixed with ID, so here we go // rn all are prefixed with ID, so here we go
if (data_size < 32) { if (data.size < 32) {
std::cerr << "TP2PRNG error: packet without id\n"; std::cerr << "TP2PRNG error: packet without id\n";
return false; return false;
} }
ByteSpan id{data, 32}; ByteSpan id{data.ptr, 32};
switch (pkg_type) { switch (pkg_type) {
case PKG::INIT_WITH_HMAC: case PKG::INIT_WITH_HMAC:
return handle_init_with_hmac(c, id, data+32, data_size-(32)); return handle_init_with_hmac(c, id, {data.ptr+32, data.size-(32)});
case PKG::HMAC: case PKG::HMAC:
return handle_hmac(c, id, data+32, data_size-(32)); return handle_hmac(c, id, {data.ptr+32, data.size-(32)});
case PKG::HMAC_REQUEST: case PKG::HMAC_REQUEST:
return handle_hmac_request(c, id, data+32, data_size-(32)); return handle_hmac_request(c, id, {data.ptr+32, data.size-(32)});
case PKG::SECRET: case PKG::SECRET:
return handle_secret(c, id, data+32, data_size-(32)); return handle_secret(c, id, {data.ptr+32, data.size-(32)});
case PKG::SECRET_REQUEST: case PKG::SECRET_REQUEST:
return handle_secret_request(c, id, data+32, data_size-(32)); return handle_secret_request(c, id, {data.ptr+32, data.size-(32)});
default: default:
return false; return false;
} }
@ -172,15 +200,14 @@ bool ToxP2PRNG::handlePacket(
bool ToxP2PRNG::handleFriendPacket( bool ToxP2PRNG::handleFriendPacket(
const uint32_t friend_number, const uint32_t friend_number,
const uint8_t* data, ByteSpan data
const size_t data_size
) { ) {
// packet id + packet id + id // packet id + packet id + id
if (data_size < 1+1+32) { if (data.size < 1+1+32) {
return false; return false;
} }
if (data[0] != 0xB1) { // 177 if (data[0] != TOX_PKG_ID_FRIEND) {
return false; return false;
} }
@ -191,22 +218,21 @@ bool ToxP2PRNG::handleFriendPacket(
return false; return false;
} }
return handlePacket(c, tpr_pkg_type, data+2, data_size-2); return handlePacket(c, tpr_pkg_type, {data.ptr+2, data.size-2});
} }
bool ToxP2PRNG::handleGroupPacket( bool ToxP2PRNG::handleGroupPacket(
const uint32_t group_number, const uint32_t group_number,
const uint32_t peer_number, const uint32_t peer_number,
const uint8_t* data, ByteSpan data,
const size_t data_size,
const bool /*_private*/ const bool /*_private*/
) { ) {
// packet id + packet id + id // packet id + packet id + id
if (data_size < 1+1+32) { if (data.size < 1+1+32) {
return false; return false;
} }
if (data[0] != (0x80 | 38u)) { // 0xa6 / 166 if (data[0] != TOX_PKG_ID_GROUP) {
return false; return false;
} }
@ -217,50 +243,185 @@ bool ToxP2PRNG::handleGroupPacket(
return false; return false;
} }
return handlePacket(c, tpr_pkg_type, data+2, data_size-2); return handlePacket(c, tpr_pkg_type, {data.ptr+2, data.size-2});
} }
bool ToxP2PRNG::handle_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_init_with_hmac(Contact3Handle c, ByteSpan id, ByteSpan data) {
std::cerr << "TP2PRNG: got packet INIT_WITH_HMAC\n"; std::cerr << "TP2PRNG: got packet INIT_WITH_HMAC\n";
size_t curser = 0; size_t curser = 0;
return false; return false;
} }
bool ToxP2PRNG::handle_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_hmac(Contact3Handle c, ByteSpan id, ByteSpan data) {
std::cerr << "TP2PRNG: got packet HMAC\n"; std::cerr << "TP2PRNG: got packet HMAC\n";
size_t curser = 0; size_t curser = 0;
return false; return false;
} }
bool ToxP2PRNG::handle_hmac_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_hmac_request(Contact3Handle c, ByteSpan id, ByteSpan data) {
std::cerr << "TP2PRNG: got packet HMAC_REQUEST\n"; std::cerr << "TP2PRNG: got packet HMAC_REQUEST\n";
if (data_size > 0) { if (!data.empty()) {
std::cerr << "TP2PRNG warning: HMAC_REQUEST pkg has extra data!\n"; std::cerr << "TP2PRNG warning: HMAC_REQUEST pkg has extra data!\n";
} }
const auto* rng_state = getRngSate(c, id);
if (rng_state == nullptr) {
return false;
}
return false; return false;
} }
bool ToxP2PRNG::handle_secret(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_secret(Contact3Handle c, ByteSpan id, ByteSpan data) {
std::cerr << "TP2PRNG: got packet SECRET\n"; std::cerr << "TP2PRNG: got packet SECRET\n";
size_t curser = 0; size_t curser = 0;
return false; return false;
} }
bool ToxP2PRNG::handle_secret_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size) { bool ToxP2PRNG::handle_secret_request(Contact3Handle c, ByteSpan id, ByteSpan data) {
std::cerr << "TP2PRNG: got packet SECRET_REQUEST\n"; std::cerr << "TP2PRNG: got packet SECRET_REQUEST\n";
if (data_size > 0) { if (!data.empty()) {
std::cerr << "TP2PRNG warning: SECRET_REQUEST pkg has extra data!\n"; std::cerr << "TP2PRNG warning: SECRET_REQUEST pkg has extra data!\n";
} }
const auto* rng_state = getRngSate(c, id);
if (rng_state == nullptr) {
return false;
}
// can only request secret if secret or done state
if (const auto current_state = rng_state->getState(); !(current_state == P2PRNG::SECRET || current_state == P2PRNG::DONE)) {
return false;
}
// find self contact
// TODO: accel
// TODO: do TagSelfStrong over contacts instead?? probably. maybe additionally
Contact3Handle self;
if (c.all_of<Contact::Components::Self>()) {
self = Contact3Handle{*c.registry(), c.get<Contact::Components::Self>().self};
} else if (c.all_of<Contact::Components::Parent>()) {
Contact3Handle parent = {*c.registry(), c.get<Contact::Components::Parent>().parent};
if (static_cast<bool>(parent) && parent.all_of<Contact::Components::Self>()) {
self = Contact3Handle{*c.registry(), parent.get<Contact::Components::Self>().self};
}
}
if (!static_cast<bool>(self)) {
std::cerr << "TP2PRNG error: failed to look up self\n";
return false;
}
auto self_secret_it = rng_state->secrets.find(self);
if (self_secret_it == rng_state->secrets.cend()) {
// hmmmmmmmmmm this bad
std::cerr << "hmmmmmmmmmm this bad\n";
return false;
}
// TODO: queue these instead
// SEND secret to c
send_secret(c, id, ByteSpan{self_secret_it->second});
return true;
}
static std::tuple<std::vector<uint8_t>, const Contact::Components::ToxFriendEphemeral*, const Contact::Components::ToxGroupPeerEphemeral*> prepSendPkgWithID(Contact3Handle c, ToxP2PRNG::PKG pkg_type, ByteSpan id) {
std::vector<uint8_t> pkg;
// determine friend or group (meh)
const auto* tfe = c.try_get<Contact::Components::ToxFriendEphemeral>();
const auto* tgpe = c.try_get<Contact::Components::ToxGroupPeerEphemeral>();
if (tfe != nullptr) {
pkg.push_back(TOX_PKG_ID_FRIEND);
} else if (tgpe != nullptr) {
pkg.push_back(TOX_PKG_ID_GROUP);
} else {
return {};
}
pkg.push_back(static_cast<uint8_t>(pkg_type));
// pack packet
// - id
pkg.insert(pkg.cend(), id.cbegin(), id.cend());
return {pkg, tfe, tgpe};
}
static bool sendToxPrivatePacket(
ToxI& t,
const Contact::Components::ToxFriendEphemeral* tfe,
const Contact::Components::ToxGroupPeerEphemeral* tgpe,
const std::vector<uint8_t>& pkg
) {
// send to friend or group peer
if (tfe != nullptr) {
return
t.toxFriendSendLosslessPacket(
tfe->friend_number,
pkg
) == TOX_ERR_FRIEND_CUSTOM_PACKET_OK
;
} else if (tgpe != nullptr) {
return
t.toxGroupSendCustomPrivatePacket(
tgpe->group_number, tgpe->peer_number,
true,
pkg
) == TOX_ERR_GROUP_SEND_CUSTOM_PRIVATE_PACKET_OK
;
}
return false; return false;
} }
bool ToxP2PRNG::send_hmac(Contact3Handle c, ByteSpan id, const ByteSpan hmac) {
auto [pkg, tfe, tgpe] = prepSendPkgWithID(c, PKG::HMAC, id);
if (pkg.empty()) {
return false;
}
// - hmac
pkg.insert(pkg.cend(), hmac.cbegin(), hmac.cend());
return false;
}
bool ToxP2PRNG::send_hmac_request(Contact3Handle c, ByteSpan id) {
auto [pkg, tfe, tgpe] = prepSendPkgWithID(c, PKG::HMAC_REQUEST, id);
if (pkg.empty()) {
return false;
}
return sendToxPrivatePacket(_t, tfe, tgpe, pkg);
}
bool ToxP2PRNG::send_secret(Contact3Handle c, ByteSpan id, const ByteSpan secret) {
auto [pkg, tfe, tgpe] = prepSendPkgWithID(c, PKG::SECRET, id);
if (pkg.empty()) {
return false;
}
// - secret (msg+k)
pkg.insert(pkg.cend(), secret.cbegin(), secret.cend());
return sendToxPrivatePacket(_t, tfe, tgpe, pkg);
}
bool ToxP2PRNG::send_secret_request(Contact3Handle c, ByteSpan id) {
auto [pkg, tfe, tgpe] = prepSendPkgWithID(c, PKG::SECRET_REQUEST, id);
if (pkg.empty()) {
return false;
}
return sendToxPrivatePacket(_t, tfe, tgpe, pkg);
}
ToxP2PRNG::RngState* ToxP2PRNG::getRngSate(Contact3Handle c, ByteSpan id_bytes) { ToxP2PRNG::RngState* ToxP2PRNG::getRngSate(Contact3Handle c, ByteSpan id_bytes) {
if (id_bytes.size != ID{}.size()) { if (id_bytes.size != ID{}.size()) {
return nullptr; return nullptr;
@ -268,7 +429,7 @@ ToxP2PRNG::RngState* ToxP2PRNG::getRngSate(Contact3Handle c, ByteSpan id_bytes)
ID r_id{}; ID r_id{};
{ // building the id is very annoying, should have not used array? { // building the id is very annoying, should have not used array?
// TODO: provide custom comperator ? // TODO: provide custom comperator ?
for (size_t i = 0; i < r_id.size(); i++) { for (size_t i = 0; i < r_id.size(); i++) {
r_id[i] = id_bytes[i]; r_id[i] = id_bytes[i];
} }
@ -293,7 +454,7 @@ bool ToxP2PRNG::onToxEvent(const Tox_Event_Friend_Lossless_Packet* e) {
const uint8_t* data = tox_event_friend_lossless_packet_get_data(e); const uint8_t* data = tox_event_friend_lossless_packet_get_data(e);
const auto data_length = tox_event_friend_lossless_packet_get_data_length(e); const auto data_length = tox_event_friend_lossless_packet_get_data_length(e);
return handleFriendPacket(friend_number, data, data_length); return handleFriendPacket(friend_number, {data, data_length});
} }
bool ToxP2PRNG::onToxEvent(const Tox_Event_Group_Custom_Packet* e) { bool ToxP2PRNG::onToxEvent(const Tox_Event_Group_Custom_Packet* e) {
@ -302,7 +463,7 @@ bool ToxP2PRNG::onToxEvent(const Tox_Event_Group_Custom_Packet* e) {
const uint8_t* data = tox_event_group_custom_packet_get_data(e); const uint8_t* data = tox_event_group_custom_packet_get_data(e);
const auto data_length = tox_event_group_custom_packet_get_data_length(e); const auto data_length = tox_event_group_custom_packet_get_data_length(e);
return handleGroupPacket(group_number, peer_number, data, data_length, false); return handleGroupPacket(group_number, peer_number, {data, data_length}, false);
} }
bool ToxP2PRNG::onToxEvent(const Tox_Event_Group_Custom_Private_Packet* e) { bool ToxP2PRNG::onToxEvent(const Tox_Event_Group_Custom_Private_Packet* e) {
@ -311,6 +472,6 @@ bool ToxP2PRNG::onToxEvent(const Tox_Event_Group_Custom_Private_Packet* e) {
const uint8_t* data = tox_event_group_custom_private_packet_get_data(e); const uint8_t* data = tox_event_group_custom_private_packet_get_data(e);
const auto data_length = tox_event_group_custom_private_packet_get_data_length(e); const auto data_length = tox_event_group_custom_private_packet_get_data_length(e);
return handleGroupPacket(group_number, peer_number, data, data_length, true); return handleGroupPacket(group_number, peer_number, {data, data_length}, true);
} }

View File

@ -19,42 +19,46 @@ class ToxP2PRNG : public P2PRNGI, public ToxEventI {
ToxEventProviderI& _tep; ToxEventProviderI& _tep;
ToxContactModel2& _tcm; ToxContactModel2& _tcm;
enum class PKG : uint8_t { public:
INVALID = 0u, enum class PKG : uint8_t {
INVALID = 0u,
INIT_WITH_HMAC, INIT_WITH_HMAC,
HMAC, HMAC,
HMAC_REQUEST, HMAC_REQUEST,
SECRET, SECRET,
SECRET_REQUEST, SECRET_REQUEST,
}; };
using ID = std::array<uint8_t, 32>; using ID = std::array<uint8_t, 32>;
struct IDHash {size_t operator()(const ID& a) const {return (a[0] | a[1] << 1*8 | a[2] << 1*16 | a[3] << 1*24) ^ (a[31] | a[30] << 1*8);}}; struct IDHash {size_t operator()(const ID& a) const {return (a[0] | a[1] << 1*8 | a[2] << 1*16 | a[3] << 1*24) ^ (a[31] | a[30] << 1*8);}};
struct RngState { private:
// all contacts participating, including self struct RngState {
std::vector<Contact3Handle> contacts; // all contacts participating, including self
std::vector<Contact3Handle> contacts;
// app given // app given
std::vector<uint8_t> inital_state; std::vector<uint8_t> inital_state;
// the other stuff needed for full IS (preamble+IS) // the other stuff needed for full IS (preamble+IS)
// - ID // - ID
// - list of public keys of contacts (same order as later used to calc res) // - list of public keys of contacts (same order as later used to calc res)
std::vector<uint8_t> inital_state_preamble; std::vector<uint8_t> inital_state_preamble;
void fillInitalStatePreamble(const ByteSpan id); void fillInitalStatePreamble(const ByteSpan id);
// use contacts instead? // use contacts instead?
entt::dense_map<Contact3, std::array<uint8_t, P2PRNG_MAC_LEN>> hmacs; entt::dense_map<Contact3, std::array<uint8_t, P2PRNG_MAC_LEN>> hmacs;
entt::dense_map<Contact3, std::array<uint8_t, P2PRNG_LEN + P2PRNG_MAC_KEY_LEN>> secrets; entt::dense_map<Contact3, std::array<uint8_t, P2PRNG_LEN + P2PRNG_MAC_KEY_LEN>> secrets;
entt::dense_map<Contact3, bool> secrets_valid; entt::dense_map<Contact3, bool> secrets_valid;
void genFinalResult(void); void genFinalResult(void);
std::vector<uint8_t> final_result; // cached std::vector<uint8_t> final_result; // cached
};
entt::dense_map<ID, RngState, IDHash> _global_map; P2PRNG::State getState(void) const;
};
entt::dense_map<ID, RngState, IDHash> _global_map;
public: public:
ToxP2PRNG( ToxP2PRNG(
@ -75,28 +79,31 @@ class ToxP2PRNG : public P2PRNGI, public ToxEventI {
bool handlePacket( bool handlePacket(
Contact3Handle c, Contact3Handle c,
PKG pkg_type, PKG pkg_type,
const uint8_t* data, ByteSpan data
const size_t data_size
); );
bool handleFriendPacket( bool handleFriendPacket(
const uint32_t friend_number, const uint32_t friend_number,
const uint8_t* data, ByteSpan data
const size_t data_size
); );
bool handleGroupPacket( bool handleGroupPacket(
const uint32_t group_number, const uint32_t group_number,
const uint32_t peer_number, const uint32_t peer_number,
const uint8_t* data, ByteSpan data,
const size_t data_size,
const bool _private const bool _private
); );
bool handle_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_init_with_hmac(Contact3Handle c, ByteSpan id, ByteSpan data);
bool handle_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_hmac(Contact3Handle c, ByteSpan id, ByteSpan data);
bool handle_hmac_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_hmac_request(Contact3Handle c, ByteSpan id, ByteSpan data);
bool handle_secret(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_secret(Contact3Handle c, ByteSpan id, ByteSpan data);
bool handle_secret_request(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size); bool handle_secret_request(Contact3Handle c, ByteSpan id, ByteSpan data);
//bool send_init_with_hmac(Contact3Handle c, ByteSpan id, const uint8_t* data, size_t data_size);
bool send_hmac(Contact3Handle c, ByteSpan id, const ByteSpan hmac);
bool send_hmac_request(Contact3Handle c, ByteSpan id);
bool send_secret(Contact3Handle c, ByteSpan id, const ByteSpan secret);
bool send_secret_request(Contact3Handle c, ByteSpan id);
RngState* getRngSate(Contact3Handle c, ByteSpan id); RngState* getRngSate(Contact3Handle c, ByteSpan id);