Sfoglia il codice sorgente

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

Scott Powell 1 anno fa
parent
commit
ec92bfa6b1

+ 17 - 12
examples/ping_client/main.cpp

@@ -18,7 +18,7 @@
   #define LORA_BW     125
 #endif
 #ifndef LORA_SF
-  #define LORA_SF     10
+  #define LORA_SF     9
 #endif
 #ifndef LORA_CR
   #define LORA_CR      5
@@ -42,13 +42,6 @@ class MyMesh : public mesh::Mesh {
   bool got_adv = false;
 
 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 {
     if (memcmp(app_data, "PING", 4) == 0) {
       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) {
       Serial.println("Received PING Reply!");
 
       if (packet->isRouteFlood()) {
         // 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);
       }
     }
   }
 
-  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 
     Serial.printf("PATH to server, path_len=%d\n", (uint32_t) path_len);
 
@@ -84,7 +89,7 @@ protected:
 
     if (packet->isRouteFlood()) {
       // 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);
     }
 

+ 2 - 2
examples/ping_server/main.cpp

@@ -18,7 +18,7 @@
   #define LORA_BW     125
 #endif
 #ifndef LORA_SF
-  #define LORA_SF     10
+  #define LORA_SF     9
 #endif
 #ifndef LORA_CR
   #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) {
       Serial.printf("PATH to client, path_len=%d\n", (uint32_t) path_len);
 

+ 5 - 5
examples/simple_repeater/main.cpp

@@ -19,7 +19,7 @@
   #define LORA_BW     125
 #endif
 #ifndef LORA_SF
-  #define LORA_SF     10
+  #define LORA_SF     9
 #endif
 #ifndef LORA_CR
   #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!)
       int i = matching_peer_indexes[sender_idx];
 
@@ -236,11 +236,11 @@ protected:
 
           if (packet->isRouteFlood()) {
             // 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);
             if (path) sendFlood(path);
           } 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 (client->out_path_len >= 0) {  // we have an out_path, so send DIRECT
                 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
     int i = matching_peer_indexes[sender_idx];
 

+ 5 - 5
examples/simple_secure_chat/main.cpp

@@ -18,7 +18,7 @@
   #define LORA_BW     125
 #endif
 #ifndef LORA_SF
-  #define LORA_SF     10
+  #define LORA_SF     9
 #endif
 #ifndef LORA_CR
   #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) {
       int i = matching_peer_indexes[sender_idx];
       if (i < 0 || i >= num_contacts) {
@@ -146,7 +146,7 @@ protected:
 
       if (packet->isRouteFlood()) {
         // 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);
         if (path) sendFlood(path);
       } 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];
     if (i < 0 || i >= num_contacts) {
       MESH_DEBUG_PRINTLN("onPeerPathRecv: Invalid sender idx: %d", i);
@@ -178,7 +178,7 @@ protected:
 
     if (packet->isRouteFlood()) {
       // 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);
     }
 

+ 17 - 12
examples/test_admin/main.cpp

@@ -18,7 +18,7 @@
   #define LORA_BW     125
 #endif
 #ifndef LORA_SF
-  #define LORA_SF     10
+  #define LORA_SF     9
 #endif
 #ifndef LORA_CR
   #define LORA_CR      5
@@ -62,13 +62,6 @@ class MyMesh : public mesh::Mesh {
   bool got_adv = false;
 
 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 {
     if (memcmp(app_data, "repeater:", 9) == 0) {
       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) {
       handleResponse(data, len);
 
       if (packet->isRouteFlood()) {
         // 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);
       }
     }
   }
 
-  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 
     Serial.printf("PATH to repeater, path_len=%d\n", (uint32_t) path_len);
 
@@ -135,7 +140,7 @@ protected:
 
     if (packet->isRouteFlood()) {
       // 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);
     }
 

+ 4 - 4
src/Mesh.cpp

@@ -97,9 +97,9 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
                 uint8_t extra_type = data[k++];
                 uint8_t* extra = &data[k];
                 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 {
-                onPeerDataRecv(pkt, pkt->getPayloadType(), j, data, len);
+                onPeerDataRecv(pkt, pkt->getPayloadType(), j, secret, data, len);
               }
               found = true;
               break;
@@ -172,7 +172,7 @@ DispatcherAction Mesh::onRecvPacket(Packet* pkt) {
 
       uint32_t timestamp;
       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) {
         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);
           action = routeRecvPacket(pkt);
         } 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;

+ 4 - 2
src/Mesh.h

@@ -80,15 +80,17 @@ protected:
    *         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  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)
    *         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  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);