From bfd6006dffdf750ffccddd8977feb3eacc33b14c Mon Sep 17 00:00:00 2001 From: dr7ana Date: Fri, 25 Oct 2024 07:22:22 -0700 Subject: [PATCH] path-build tweaking, DRYing out path messages generally --- llarp/crypto/crypto.cpp | 7 +++++-- llarp/crypto/crypto.hpp | 6 +++++- llarp/link/link_manager.cpp | 6 +++--- llarp/messages/common.hpp | 2 ++ llarp/messages/path.hpp | 16 ++++++++-------- llarp/messages/session.hpp | 3 ++- llarp/path/path_handler.cpp | 2 +- llarp/path/transit_hop.cpp | 7 ++++--- llarp/path/transit_hop.hpp | 12 ++++-------- 9 files changed, 34 insertions(+), 27 deletions(-) diff --git a/llarp/crypto/crypto.cpp b/llarp/crypto/crypto.cpp index 10bc5a09be..da583b2d1d 100644 --- a/llarp/crypto/crypto.cpp +++ b/llarp/crypto/crypto.cpp @@ -262,9 +262,12 @@ namespace llarp } void crypto::derive_decrypt_outer_wrapping( - const Ed25519SecretKey& local_sk, const PubKey& remote, const SymmNonce& nonce, uspan encrypted) + const Ed25519SecretKey& local_sk, + SharedSecret& shared, + const PubKey& remote, + const SymmNonce& nonce, + uspan encrypted) { - SharedSecret shared; // derive shared secret using ephemeral pubkey and our secret key (and nonce) if (!crypto::dh_server(shared, remote, local_sk, nonce)) { diff --git a/llarp/crypto/crypto.hpp b/llarp/crypto/crypto.hpp index efbcabbb16..e0faaf3776 100644 --- a/llarp/crypto/crypto.hpp +++ b/llarp/crypto/crypto.hpp @@ -73,7 +73,11 @@ namespace llarp /// pubkey and the provided nonce. The encrypted payload is mutated in-place. Will throw on failure of either /// the server DH derivation or the xchacha20 payload mutation void derive_decrypt_outer_wrapping( - const Ed25519SecretKey& local, const PubKey& remote, const SymmNonce& nonce, uspan encrypted); + const Ed25519SecretKey& local, + SharedSecret& shared, + const PubKey& remote, + const SymmNonce& nonce, + uspan encrypted); bool make_scalar(AlignedBuffer<32>& out, const PubKey& k, uint64_t i); diff --git a/llarp/link/link_manager.cpp b/llarp/link/link_manager.cpp index dbf831b73e..28e1283b38 100644 --- a/llarp/link/link_manager.cpp +++ b/llarp/link/link_manager.cpp @@ -1267,16 +1267,16 @@ namespace llarp log::trace(logcat, "Deserializing frame: {}", buffer_printer{frames.front()}); SymmNonce nonce; - PubKey remote_pk; ustring hop_payload; + SharedSecret shared; - std::tie(nonce, remote_pk, hop_payload) = + std::tie(nonce, shared, hop_payload) = PathBuildMessage::deserialize_hop(oxenc::bt_dict_consumer{frames.front()}, _router.identity()); log::trace(logcat, "Deserializing hop payload: {}", buffer_printer{hop_payload}); auto hop = path::TransitHop::deserialize_hop( - oxenc::bt_dict_consumer{hop_payload}, from, _router, remote_pk, nonce); + oxenc::bt_dict_consumer{hop_payload}, from, _router, std::move(shared)); hop->started = _router.now(); set_conn_persist(hop->downstream(), hop->expiry_time() + 10s); diff --git a/llarp/messages/common.hpp b/llarp/messages/common.hpp index 48f37d01a2..c70ccac66e 100644 --- a/llarp/messages/common.hpp +++ b/llarp/messages/common.hpp @@ -48,6 +48,8 @@ namespace llarp return std::move(btdp).str(); } + // inline static std::string serialize(const SymmNonce& nonce, std::string_view) + inline static std::string serialize(const SymmNonce& nonce, const HopID& hop_id, const ustring_view& payload) { return serialize( diff --git a/llarp/messages/path.hpp b/llarp/messages/path.hpp index 1b5efa2435..802958732b 100644 --- a/llarp/messages/path.hpp +++ b/llarp/messages/path.hpp @@ -122,8 +122,8 @@ namespace llarp - Generate the XOR nonce by hashing the symmetric key from DH (`hop.shared`) and truncating Bt-encoded contents: + - 'k' : shared pubkey used to derive symmetric key - 'n' : symmetric nonce used for DH key-exchange - - 's' : shared pubkey used to derive symmetric key - 'x' : encrypted payload - 'l' : path lifetime - 'r' : rxID (the path ID for messages going *to* the hop) @@ -171,26 +171,26 @@ namespace llarp buffer_printer{hop_payload}); oxenc::bt_dict_producer btdp; - + btdp.append("k", ephemeral_key.to_pubkey().to_view()); btdp.append("n", hop.nonce.to_view()); - btdp.append("s", ephemeral_key.to_pubkey().to_view()); btdp.append("x", hop_payload); return std::move(btdp).str(); } - inline static std::tuple deserialize_hop( + inline static std::tuple deserialize_hop( oxenc::bt_dict_consumer&& btdc, const Ed25519SecretKey& local_sk) { SymmNonce nonce; PubKey remote_pk; ustring hop_payload; + SharedSecret shared; try { + remote_pk.from_string(btdc.require("k")); nonce.from_string(btdc.require("n")); - remote_pk.from_string(btdc.require("s")); - hop_payload = btdc.require("x"); + hop_payload = btdc.require("x"); } catch (const std::exception& e) { @@ -207,7 +207,7 @@ namespace llarp try { - crypto::derive_decrypt_outer_wrapping(local_sk, remote_pk, nonce, to_uspan(hop_payload)); + crypto::derive_decrypt_outer_wrapping(local_sk, shared, remote_pk, nonce, to_uspan(hop_payload)); } catch (...) { @@ -222,7 +222,7 @@ namespace llarp remote_pk.to_string(), buffer_printer{hop_payload}); - return {std::move(nonce), std::move(remote_pk), std::move(hop_payload)}; + return {std::move(nonce), std::move(shared), std::move(hop_payload)}; } } // namespace PathBuildMessage } // namespace llarp diff --git a/llarp/messages/session.hpp b/llarp/messages/session.hpp index 60db08131f..11a0049191 100644 --- a/llarp/messages/session.hpp +++ b/llarp/messages/session.hpp @@ -82,6 +82,7 @@ namespace llarp SymmNonce nonce; RouterID shared_pubkey; ustring payload; + SharedSecret shared; try { @@ -89,7 +90,7 @@ namespace llarp shared_pubkey = RouterID{btdc.require("s")}; payload = btdc.require("x"); - crypto::derive_decrypt_outer_wrapping(local, shared_pubkey, nonce, to_uspan(payload)); + crypto::derive_decrypt_outer_wrapping(local, shared, shared_pubkey, nonce, to_uspan(payload)); { RouterID remote; diff --git a/llarp/path/path_handler.cpp b/llarp/path/path_handler.cpp index 48d4682304..ff3f03a368 100644 --- a/llarp/path/path_handler.cpp +++ b/llarp/path/path_handler.cpp @@ -555,7 +555,7 @@ namespace llarp::path // the same entity from knowing they are part of the same path // (unless they're adjacent in the path; nothing we can do about that obviously). - // i from n_hops downto 0 + // i from n_hops down to 0 for (int i = n_hops - 1; i >= 0; --i) { const auto& next_rid = i == n_hops - 1 ? path_hops[i].rc.router_id() : path_hops[i + 1].rc.router_id(); diff --git a/llarp/path/transit_hop.cpp b/llarp/path/transit_hop.cpp index dc46efd374..9867772e9a 100644 --- a/llarp/path/transit_hop.cpp +++ b/llarp/path/transit_hop.cpp @@ -10,7 +10,7 @@ namespace llarp::path static auto logcat = log::Cat("transit-hop"); std::shared_ptr TransitHop::deserialize_hop( - oxenc::bt_dict_consumer&& btdc, const RouterID& src, Router& r, const PubKey& remote_pk, const SymmNonce& nonce) + oxenc::bt_dict_consumer&& btdc, const RouterID& src, Router& r, SharedSecret secret) { auto hop = std::make_shared(); @@ -34,13 +34,14 @@ namespace llarp::path throw std::runtime_error{PathBuildMessage::BAD_LIFETIME}; hop->downstream() = src; + hop->shared = std::move(secret); if (r.path_context()->has_transit_hop(hop)) throw std::runtime_error{PathBuildMessage::BAD_PATHID}; // TODO: get this from the first dh - if (!crypto::dh_server(hop->shared, remote_pk, r.identity(), nonce)) - throw std::runtime_error{PathBuildMessage::BAD_CRYPTO}; + // if (!crypto::dh_server(hop->shared, remote_pk, r.identity(), nonce)) + // throw std::runtime_error{PathBuildMessage::BAD_CRYPTO}; // generate hash of hop key for nonce mutation ShortHash xor_hash; diff --git a/llarp/path/transit_hop.hpp b/llarp/path/transit_hop.hpp index 13da518f30..d651c0903d 100644 --- a/llarp/path/transit_hop.hpp +++ b/llarp/path/transit_hop.hpp @@ -27,19 +27,15 @@ namespace llarp // This static factory function is used in path-build logic. The exceptions thrown are the exact response // bodies passed to message::respond(...) function static std::shared_ptr deserialize_hop( - oxenc::bt_dict_consumer&& btdc, - const RouterID& src, - Router& r, - const PubKey& remote_pk, - const SymmNonce& nonce); + oxenc::bt_dict_consumer&& btdc, const RouterID& src, Router& r, SharedSecret secret); SharedSecret shared; SymmNonce nonceXOR; - std::chrono::milliseconds started = 0s; + std::chrono::milliseconds started{0s}; // 10 minutes default - std::chrono::milliseconds lifetime = DEFAULT_LIFETIME; + std::chrono::milliseconds lifetime{DEFAULT_LIFETIME}; uint8_t version; - std::chrono::milliseconds _last_activity = 0s; + std::chrono::milliseconds _last_activity{0s}; bool terminal_hop{false}; RouterID& upstream() { return _upstream; }