From 5fb08c213956472ace2b634aad6bb735bcb81c67 Mon Sep 17 00:00:00 2001 From: Jeff Becker Date: Thu, 20 Sep 2018 07:27:18 -0400 Subject: [PATCH] check introset timestamps --- include/llarp/service/IntroSet.hpp | 2 +- llarp/dht/context.cpp | 9 ++++----- llarp/dht/got_intro.cpp | 4 ++-- llarp/dht/publish_intro.cpp | 4 ++-- llarp/service.cpp | 22 ++++++++++++++++++++-- llarp/service/endpoint.cpp | 8 +++++--- test/hiddenservice_unittest.cpp | 5 +++-- 7 files changed, 37 insertions(+), 17 deletions(-) diff --git a/include/llarp/service/IntroSet.hpp b/include/llarp/service/IntroSet.hpp index 82e428a09..1dc0162de 100644 --- a/include/llarp/service/IntroSet.hpp +++ b/include/llarp/service/IntroSet.hpp @@ -129,7 +129,7 @@ namespace llarp DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf); bool - VerifySignature(llarp_crypto* crypto) const; + Verify(llarp_crypto* crypto) const; }; } // namespace service } // namespace llarp diff --git a/llarp/dht/context.cpp b/llarp/dht/context.cpp index 94092a4e3..5d550021f 100644 --- a/llarp/dht/context.cpp +++ b/llarp/dht/context.cpp @@ -327,10 +327,9 @@ namespace llarp bool Validate(const service::IntroSet &value) const { - if(!value.VerifySignature(parent->Crypto())) + if(!value.Verify(parent->Crypto())) { - llarp::LogWarn( - "Got introset with invalid signature from service lookup"); + llarp::LogWarn("Got invalid introset from service lookup"); return false; } if(value.A.Addr() != target) @@ -552,9 +551,9 @@ namespace llarp bool Validate(const service::IntroSet &introset) const { - if(!introset.VerifySignature(parent->Crypto())) + if(!introset.Verify(parent->Crypto())) { - llarp::LogWarn("got introset from tag lookup with invalid signature"); + llarp::LogWarn("got invalid introset from tag lookup"); return false; } if(introset.topic != target) diff --git a/llarp/dht/got_intro.cpp b/llarp/dht/got_intro.cpp index df6855be6..8d0d63db9 100644 --- a/llarp/dht/got_intro.cpp +++ b/llarp/dht/got_intro.cpp @@ -28,10 +28,10 @@ namespace llarp for(const auto &introset : I) { - if(!introset.VerifySignature(crypto)) + if(!introset.Verify(crypto)) { llarp::LogWarn( - "Invalid introset signature while handling direct GotIntro " + "Invalid introset while handling direct GotIntro " "from ", From); return false; diff --git a/llarp/dht/publish_intro.cpp b/llarp/dht/publish_intro.cpp index 93adbd751..b4e2ee024 100644 --- a/llarp/dht/publish_intro.cpp +++ b/llarp/dht/publish_intro.cpp @@ -50,9 +50,9 @@ namespace llarp return false; } auto &dht = ctx->impl; - if(!I.VerifySignature(&dht.router->crypto)) + if(!I.Verify(&dht.router->crypto)) { - llarp::LogWarn("invalid introset signature, ", I); + llarp::LogWarn("invalid introset: ", I); return false; } if(I.W && !I.W->IsValid(dht.router->crypto.shorthash)) diff --git a/llarp/service.cpp b/llarp/service.cpp index 8934bbd5e..58d3e49de 100644 --- a/llarp/service.cpp +++ b/llarp/service.cpp @@ -290,7 +290,7 @@ namespace llarp } bool - IntroSet::VerifySignature(llarp_crypto* crypto) const + IntroSet::Verify(llarp_crypto* crypto) const { byte_t tmp[MAX_INTROSET_SIZE]; auto buf = llarp::StackBuffer< decltype(tmp) >(tmp); @@ -302,7 +302,25 @@ namespace llarp // rewind and resize buffer buf.sz = buf.cur - buf.base; buf.cur = buf.base; - return A.Verify(crypto, buf, Z); + if(!A.Verify(crypto, buf, Z)) + return false; + // validate PoW + if(W && !W->IsValid(crypto->shorthash)) + return false; + // valid timestamps + auto now = llarp_time_now_ms(); + for(const auto& intro : I) + { + if(intro.expiresAt >= now + && intro.expiresAt - now > DEFAULT_PATH_LIFETIME) + { + if(W && intro.expiresAt - W->extendedLifetime > DEFAULT_PATH_LIFETIME) + return false; + else if(W == nullptr) + return false; + } + } + return !IsExpired(now); } bool diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index ff5da2841..db97b0133 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -271,10 +271,10 @@ namespace llarp std::set< IntroSet > remote; for(const auto& introset : msg->I) { - if(!introset.VerifySignature(crypto)) + if(!introset.Verify(crypto)) { - llarp::LogInfo("invalid introset signature for ", introset, - " on endpoint ", Name()); + llarp::LogInfo("invalid introset ", introset, " on endpoint ", + Name()); if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T) { IntroSetPublishFail(); @@ -1204,6 +1204,8 @@ namespace llarp const RouterContact& prev, RouterContact& cur, size_t hop) { + if(remoteIntro.router.IsZero()) + return false; if(hop == numHops - 1) { if(llarp_nodedb_get_rc(db, remoteIntro.router, cur)) diff --git a/test/hiddenservice_unittest.cpp b/test/hiddenservice_unittest.cpp index 000c6a38c..bb9f672c0 100644 --- a/test/hiddenservice_unittest.cpp +++ b/test/hiddenservice_unittest.cpp @@ -31,16 +31,17 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet) llarp::service::Address addr; ASSERT_TRUE(ident.pub.CalculateAddress(addr.data())); llarp::service::IntroSet I; + auto now = llarp_time_now_ms(); while(I.I.size() < 10) { llarp::service::Introduction intro; - intro.expiresAt = 1000; + intro.expiresAt = now + (DEFAULT_PATH_LIFETIME / 2); intro.router.Randomize(); intro.pathID.Randomize(); I.I.push_back(intro); } ASSERT_TRUE(ident.SignIntroSet(I, Crypto())); - ASSERT_TRUE(I.VerifySignature(Crypto())); + ASSERT_TRUE(I.Verify(Crypto())); }; TEST_F(HiddenServiceTest, TestAddressToFromString)