* Refactor: Mesh::onPeer ... methods added 'secret' param. (is whatever getPeerSharedSecret() returned)

This commit is contained in:
Scott Powell 2025-01-15 20:52:13 +11:00
parent cd92308c41
commit ec92bfa6b1
7 changed files with 54 additions and 42 deletions

View file

@ -18,7 +18,7 @@
#define LORA_BW 125 #define LORA_BW 125
#endif #endif
#ifndef LORA_SF #ifndef LORA_SF
#define LORA_SF 10 #define LORA_SF 9
#endif #endif
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
@ -42,13 +42,6 @@ class MyMesh : public mesh::Mesh {
bool got_adv = false; bool got_adv = false;
protected: protected:
int searchPeersByHash(const uint8_t* hash) override {
if (got_adv && server_id.isHashMatch(hash)) {
return 1;
}
return 0; // not found
}
void onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, uint32_t timestamp, const uint8_t* app_data, size_t app_data_len) override { void onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, uint32_t timestamp, const uint8_t* app_data, size_t app_data_len) override {
if (memcmp(app_data, "PING", 4) == 0) { if (memcmp(app_data, "PING", 4) == 0) {
Serial.println("Received advertisement from a PING server"); Serial.println("Received advertisement from a PING server");
@ -64,19 +57,31 @@ protected:
} }
} }
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, uint8_t* data, size_t len) override { int searchPeersByHash(const uint8_t* hash) override {
if (got_adv && server_id.isHashMatch(hash)) {
return 1;
}
return 0; // not found
}
void getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) override {
// lookup pre-calculated shared_secret
memcpy(dest_secret, server_secret, PUB_KEY_SIZE);
}
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override {
if (type == PAYLOAD_TYPE_RESPONSE) { if (type == PAYLOAD_TYPE_RESPONSE) {
Serial.println("Received PING Reply!"); Serial.println("Received PING Reply!");
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// let server know path TO here, so they can use sendDirect() for future ping responses // let server know path TO here, so they can use sendDirect() for future ping responses
mesh::Packet* path = createPathReturn(server_id, server_secret, packet->path, packet->path_len, 0, NULL, 0); mesh::Packet* path = createPathReturn(server_id, secret, packet->path, packet->path_len, 0, NULL, 0);
if (path) sendFlood(path); if (path) sendFlood(path);
} }
} }
} }
void onPeerPathRecv(mesh::Packet* packet, int sender_idx, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override { void onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override {
// must be from server_id // must be from server_id
Serial.printf("PATH to server, path_len=%d\n", (uint32_t) path_len); Serial.printf("PATH to server, path_len=%d\n", (uint32_t) path_len);
@ -84,7 +89,7 @@ protected:
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// send a reciprocal return path to sender, but send DIRECTLY! // send a reciprocal return path to sender, but send DIRECTLY!
mesh::Packet* rpath = createPathReturn(server_id, server_secret, packet->path, packet->path_len, 0, NULL, 0); mesh::Packet* rpath = createPathReturn(server_id, secret, packet->path, packet->path_len, 0, NULL, 0);
if (rpath) sendDirect(rpath, path, path_len); if (rpath) sendDirect(rpath, path, path_len);
} }

View file

@ -18,7 +18,7 @@
#define LORA_BW 125 #define LORA_BW 125
#endif #endif
#ifndef LORA_SF #ifndef LORA_SF
#define LORA_SF 10 #define LORA_SF 9
#endif #endif
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
@ -118,7 +118,7 @@ protected:
} }
} }
void onPeerPathRecv(mesh::Packet* packet, int sender_idx, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override { void onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override {
if (sender_idx >= 0 && sender_idx < MAX_CLIENTS) { if (sender_idx >= 0 && sender_idx < MAX_CLIENTS) {
Serial.printf("PATH to client, path_len=%d\n", (uint32_t) path_len); Serial.printf("PATH to client, path_len=%d\n", (uint32_t) path_len);

View file

@ -19,7 +19,7 @@
#define LORA_BW 125 #define LORA_BW 125
#endif #endif
#ifndef LORA_SF #ifndef LORA_SF
#define LORA_SF 10 #define LORA_SF 9
#endif #endif
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
@ -218,7 +218,7 @@ protected:
} }
} }
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, uint8_t* data, size_t len) override { void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override {
if (type == PAYLOAD_TYPE_REQ) { // request (from a Known admin client!) if (type == PAYLOAD_TYPE_REQ) { // request (from a Known admin client!)
int i = matching_peer_indexes[sender_idx]; int i = matching_peer_indexes[sender_idx];
@ -236,11 +236,11 @@ protected:
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response // let this sender know path TO here, so they can use sendDirect(), and ALSO encode the response
mesh::Packet* path = createPathReturn(client->id, client->secret, packet->path, packet->path_len, mesh::Packet* path = createPathReturn(client->id, secret, packet->path, packet->path_len,
PAYLOAD_TYPE_RESPONSE, reply_data, reply_len); PAYLOAD_TYPE_RESPONSE, reply_data, reply_len);
if (path) sendFlood(path); if (path) sendFlood(path);
} else { } else {
mesh::Packet* reply = createDatagram(PAYLOAD_TYPE_RESPONSE, client->id, client->secret, reply_data, reply_len); mesh::Packet* reply = createDatagram(PAYLOAD_TYPE_RESPONSE, client->id, secret, reply_data, reply_len);
if (reply) { if (reply) {
if (client->out_path_len >= 0) { // we have an out_path, so send DIRECT if (client->out_path_len >= 0) { // we have an out_path, so send DIRECT
sendDirect(reply, client->out_path, client->out_path_len); sendDirect(reply, client->out_path, client->out_path_len);
@ -256,7 +256,7 @@ protected:
} }
} }
void onPeerPathRecv(mesh::Packet* packet, int sender_idx, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override { void onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override {
// TODO: prevent replay attacks // TODO: prevent replay attacks
int i = matching_peer_indexes[sender_idx]; int i = matching_peer_indexes[sender_idx];

View file

@ -18,7 +18,7 @@
#define LORA_BW 125 #define LORA_BW 125
#endif #endif
#ifndef LORA_SF #ifndef LORA_SF
#define LORA_SF 10 #define LORA_SF 9
#endif #endif
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
@ -119,7 +119,7 @@ protected:
} }
} }
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, uint8_t* data, size_t len) override { void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override {
if (type == PAYLOAD_TYPE_TXT_MSG && len > 5) { if (type == PAYLOAD_TYPE_TXT_MSG && len > 5) {
int i = matching_peer_indexes[sender_idx]; int i = matching_peer_indexes[sender_idx];
if (i < 0 || i >= num_contacts) { if (i < 0 || i >= num_contacts) {
@ -146,7 +146,7 @@ protected:
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK // let this sender know path TO here, so they can use sendDirect(), and ALSO encode the ACK
mesh::Packet* path = createPathReturn(from.id, from.shared_secret, packet->path, packet->path_len, mesh::Packet* path = createPathReturn(from.id, secret, packet->path, packet->path_len,
PAYLOAD_TYPE_ACK, (uint8_t *) &ack_hash, 4); PAYLOAD_TYPE_ACK, (uint8_t *) &ack_hash, 4);
if (path) sendFlood(path); if (path) sendFlood(path);
} else { } else {
@ -162,7 +162,7 @@ protected:
} }
} }
void onPeerPathRecv(mesh::Packet* packet, int sender_idx, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override { void onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override {
int i = matching_peer_indexes[sender_idx]; int i = matching_peer_indexes[sender_idx];
if (i < 0 || i >= num_contacts) { if (i < 0 || i >= num_contacts) {
MESH_DEBUG_PRINTLN("onPeerPathRecv: Invalid sender idx: %d", i); MESH_DEBUG_PRINTLN("onPeerPathRecv: Invalid sender idx: %d", i);
@ -178,7 +178,7 @@ protected:
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// send a reciprocal return path to sender, but send DIRECTLY! // send a reciprocal return path to sender, but send DIRECTLY!
mesh::Packet* rpath = createPathReturn(from.id, from.shared_secret, packet->path, packet->path_len, 0, NULL, 0); mesh::Packet* rpath = createPathReturn(from.id, secret, packet->path, packet->path_len, 0, NULL, 0);
if (rpath) sendDirect(rpath, path, path_len); if (rpath) sendDirect(rpath, path, path_len);
} }

View file

@ -18,7 +18,7 @@
#define LORA_BW 125 #define LORA_BW 125
#endif #endif
#ifndef LORA_SF #ifndef LORA_SF
#define LORA_SF 10 #define LORA_SF 9
#endif #endif
#ifndef LORA_CR #ifndef LORA_CR
#define LORA_CR 5 #define LORA_CR 5
@ -62,13 +62,6 @@ class MyMesh : public mesh::Mesh {
bool got_adv = false; bool got_adv = false;
protected: protected:
int searchPeersByHash(const uint8_t* hash) override {
if (got_adv && server_id.isHashMatch(hash)) {
return 1;
}
return 0; // not found
}
void onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, uint32_t timestamp, const uint8_t* app_data, size_t app_data_len) override { void onAdvertRecv(mesh::Packet* packet, const mesh::Identity& id, uint32_t timestamp, const uint8_t* app_data, size_t app_data_len) override {
if (memcmp(app_data, "repeater:", 9) == 0) { if (memcmp(app_data, "repeater:", 9) == 0) {
Serial.println("Received advertisement from a repeater!"); Serial.println("Received advertisement from a repeater!");
@ -115,19 +108,31 @@ protected:
} }
} }
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, uint8_t* data, size_t len) override { int searchPeersByHash(const uint8_t* hash) override {
if (got_adv && server_id.isHashMatch(hash)) {
return 1;
}
return 0; // not found
}
void getPeerSharedSecret(uint8_t* dest_secret, int peer_idx) override {
// lookup pre-calculated shared_secret
memcpy(dest_secret, server_secret, PUB_KEY_SIZE);
}
void onPeerDataRecv(mesh::Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) override {
if (type == PAYLOAD_TYPE_RESPONSE) { if (type == PAYLOAD_TYPE_RESPONSE) {
handleResponse(data, len); handleResponse(data, len);
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// let server know path TO here, so they can use sendDirect() for future ping responses // let server know path TO here, so they can use sendDirect() for future ping responses
mesh::Packet* path = createPathReturn(server_id, server_secret, packet->path, packet->path_len, 0, NULL, 0); mesh::Packet* path = createPathReturn(server_id, secret, packet->path, packet->path_len, 0, NULL, 0);
if (path) sendFlood(path); if (path) sendFlood(path);
} }
} }
} }
void onPeerPathRecv(mesh::Packet* packet, int sender_idx, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override { void onPeerPathRecv(mesh::Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) override {
// must be from server_id // must be from server_id
Serial.printf("PATH to repeater, path_len=%d\n", (uint32_t) path_len); Serial.printf("PATH to repeater, path_len=%d\n", (uint32_t) path_len);
@ -135,7 +140,7 @@ protected:
if (packet->isRouteFlood()) { if (packet->isRouteFlood()) {
// send a reciprocal return path to sender, but send DIRECTLY! // send a reciprocal return path to sender, but send DIRECTLY!
mesh::Packet* rpath = createPathReturn(server_id, server_secret, packet->path, packet->path_len, 0, NULL, 0); mesh::Packet* rpath = createPathReturn(server_id, secret, packet->path, packet->path_len, 0, NULL, 0);
if (rpath) sendDirect(rpath, path, path_len); if (rpath) sendDirect(rpath, path, path_len);
} }

View file

@ -97,9 +97,9 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
uint8_t extra_type = data[k++]; uint8_t extra_type = data[k++];
uint8_t* extra = &data[k]; uint8_t* extra = &data[k];
uint8_t extra_len = len - k; // remainder of packet (may be padded with zeroes!) uint8_t extra_len = len - k; // remainder of packet (may be padded with zeroes!)
onPeerPathRecv(pkt, j, path, path_len, extra_type, extra, extra_len); onPeerPathRecv(pkt, j, secret, path, path_len, extra_type, extra, extra_len);
} else { } else {
onPeerDataRecv(pkt, pkt->getPayloadType(), j, data, len); onPeerDataRecv(pkt, pkt->getPayloadType(), j, secret, data, len);
} }
found = true; found = true;
break; break;
@ -172,7 +172,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
uint32_t timestamp; uint32_t timestamp;
memcpy(&timestamp, &pkt->payload[i], 4); i += 4; memcpy(&timestamp, &pkt->payload[i], 4); i += 4;
uint8_t* signature = &pkt->payload[i]; i += SIGNATURE_SIZE; const uint8_t* signature = &pkt->payload[i]; i += SIGNATURE_SIZE;
if (i > pkt->payload_len) { if (i > pkt->payload_len) {
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete advertisement packet"); MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): incomplete advertisement packet");
@ -197,7 +197,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
onAdvertRecv(pkt, id, timestamp, app_data, app_data_len); onAdvertRecv(pkt, id, timestamp, app_data, app_data_len);
action = routeRecvPacket(pkt); action = routeRecvPacket(pkt);
} else { } else {
MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): received advertisement with forged signature!"); MESH_DEBUG_PRINTLN("Mesh::onRecvPacket(): received advertisement with forged signature! (app_data_len=%d)", app_data_len);
} }
} }
break; break;

View file

@ -80,15 +80,17 @@ protected:
* NOTE: these can be received multiple times (per sender/msg-id), via different routes * NOTE: these can be received multiple times (per sender/msg-id), via different routes
* \param type one of: PAYLOAD_TYPE_TXT_MSG, PAYLOAD_TYPE_REQ, PAYLOAD_TYPE_RESPONSE * \param type one of: PAYLOAD_TYPE_TXT_MSG, PAYLOAD_TYPE_REQ, PAYLOAD_TYPE_RESPONSE
* \param sender_idx index of peer, [0..n) where n is what searchPeersByHash() returned * \param sender_idx index of peer, [0..n) where n is what searchPeersByHash() returned
* \param secret the pre-calculated shared-secret (handy for sending response packet)
*/ */
virtual void onPeerDataRecv(Packet* packet, uint8_t type, int sender_idx, uint8_t* data, size_t len) { } virtual void onPeerDataRecv(Packet* packet, uint8_t type, int sender_idx, const uint8_t* secret, uint8_t* data, size_t len) { }
/** /**
* \brief A path TO peer (sender_idx) has been received. (also with optional 'extra' data encoded) * \brief A path TO peer (sender_idx) has been received. (also with optional 'extra' data encoded)
* NOTE: these can be received multiple times (per sender), via differen routes * NOTE: these can be received multiple times (per sender), via differen routes
* \param sender_idx index of peer, [0..n) where n is what searchPeersByHash() returned * \param sender_idx index of peer, [0..n) where n is what searchPeersByHash() returned
* \param secret the pre-calculated shared-secret (handy for sending response packet)
*/ */
virtual void onPeerPathRecv(Packet* packet, int sender_idx, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) { } virtual void onPeerPathRecv(Packet* packet, int sender_idx, const uint8_t* secret, uint8_t* path, uint8_t path_len, uint8_t extra_type, uint8_t* extra, uint8_t extra_len) { }
virtual int searchChannelsByHash(const uint8_t* hash, GroupChannel channels[], int max_matches); virtual int searchChannelsByHash(const uint8_t* hash, GroupChannel channels[], int max_matches);