diff --git a/llarp/service/endpoint.cpp b/llarp/service/endpoint.cpp index f14aec91b..7b624d3ef 100644 --- a/llarp/service/endpoint.cpp +++ b/llarp/service/endpoint.cpp @@ -978,12 +978,43 @@ namespace llarp return false; } + void + Endpoint::RemoveConvoTag(const ConvoTag& t) + { + m_Sessions.erase(t); + } + bool Endpoint::HandleHiddenServiceFrame(path::Path* p, const ProtocolFrame* frame) { - return frame->AsyncDecryptAndVerify(EndpointLogic(), Crypto(), p->RXID(), - Worker(), m_Identity, m_DataHandler); + if(frame->R) + { + // handle discard + ServiceInfo si; + if(!GetSenderFor(frame->T, si)) + return false; + // verify source + if(!frame->Verify(Crypto(), si)) + return false; + // remove convotag it doesn't exist + RemoveConvoTag(frame->T); + return true; + } + if(!frame->AsyncDecryptAndVerify(EndpointLogic(), Crypto(), p->RXID(), + Worker(), m_Identity, m_DataHandler)) + { + // send discard + ProtocolFrame f; + f.R = 1; + f.T = frame->T; + f.F = p->intro.pathID; + if(!f.Sign(Crypto(), m_Identity)) + return false; + const routing::PathTransferMessage d(f, frame->F); + return p->SendRoutingMessage(&d, router); + } + return true; } Endpoint::SendContext::SendContext(const ServiceInfo& ident, diff --git a/llarp/service/endpoint.hpp b/llarp/service/endpoint.hpp index f03443523..c2574c1f3 100644 --- a/llarp/service/endpoint.hpp +++ b/llarp/service/endpoint.hpp @@ -393,6 +393,9 @@ namespace llarp bool GetIntroFor(const ConvoTag& remote, Introduction& intro) const override; + void + RemoveConvoTag(const ConvoTag& remote) override; + void PutReplyIntroFor(const ConvoTag& remote, const Introduction& intro) override; diff --git a/llarp/service/handler.hpp b/llarp/service/handler.hpp index 25e3a28d9..e7503f1a7 100644 --- a/llarp/service/handler.hpp +++ b/llarp/service/handler.hpp @@ -25,6 +25,9 @@ namespace llarp PutCachedSessionKeyFor(const ConvoTag& remote, const SharedSecret& secret) = 0; + virtual void + RemoveConvoTag(const ConvoTag& remote) = 0; + virtual void PutSenderFor(const ConvoTag& remote, const ServiceInfo& si) = 0; diff --git a/llarp/service/protocol.cpp b/llarp/service/protocol.cpp index 3961f9b9e..a86d04eee 100644 --- a/llarp/service/protocol.cpp +++ b/llarp/service/protocol.cpp @@ -105,14 +105,23 @@ namespace llarp if(!BEncodeWriteDictEntry("C", C, buf)) return false; } - if(!BEncodeWriteDictEntry("D", D, buf)) - return false; - + if(D.size() > 0) + { + if(!BEncodeWriteDictEntry("D", D, buf)) + return false; + } if(!BEncodeWriteDictEntry("F", F, buf)) return false; - - if(!BEncodeWriteDictEntry("N", N, buf)) - return false; + if(!N.IsZero()) + { + if(!BEncodeWriteDictEntry("N", N, buf)) + return false; + } + if(R) + { + if(!BEncodeWriteDictInt("R", R, buf)) + return false; + } if(!T.IsZero()) { if(!BEncodeWriteDictEntry("T", T, buf)) @@ -148,6 +157,8 @@ namespace llarp return false; if(!BEncodeMaybeReadDictInt("S", S, read, key, val)) return false; + if(!BEncodeMaybeReadDictInt("R", R, read, key, val)) + return false; if(!BEncodeMaybeReadDictEntry("T", T, read, key, val)) return false; if(!BEncodeMaybeReadVersion("V", version, LLARP_PROTO_VERSION, read, key, @@ -169,6 +180,25 @@ namespace llarp return msg.BDecode(buf); } + bool + ProtocolFrame::Sign(llarp::Crypto* crypto, const Identity& localIdent) + { + Z.Zero(); + std::array< byte_t, MAX_PROTOCOL_MESSAGE_SIZE > tmp; + llarp_buffer_t buf(tmp); + // encode + if(!BEncode(&buf)) + { + llarp::LogError("message too big to encode"); + return false; + } + // rewind + buf.sz = buf.cur - buf.base; + buf.cur = buf.base; + // sign + return localIdent.Sign(crypto, Z, buf); + } + bool ProtocolFrame::EncryptAndSign(llarp::Crypto* crypto, const ProtocolMessage& msg, @@ -313,6 +343,7 @@ namespace llarp N = other.N; Z = other.Z; T = other.T; + R = other.R; S = other.S; version = other.version; return *this; diff --git a/llarp/service/protocol.hpp b/llarp/service/protocol.hpp index ccec7efe3..d4e0453d7 100644 --- a/llarp/service/protocol.hpp +++ b/llarp/service/protocol.hpp @@ -65,6 +65,7 @@ namespace llarp using Encrypted_t = Encrypted< 2048 >; PQCipherBlock C; Encrypted_t D; + uint64_t R; KeyExchangeNonce N; Signature Z; PathID_t F; @@ -74,6 +75,7 @@ namespace llarp : routing::IMessage() , C(other.C) , D(other.D) + , R(other.R) , N(other.N) , Z(other.Z) , F(other.F) @@ -106,6 +108,9 @@ namespace llarp EncryptAndSign(Crypto* c, const ProtocolMessage& msg, const SharedSecret& sharedkey, const Identity& localIdent); + bool + Sign(Crypto* c, const Identity& localIdent); + bool AsyncDecryptAndVerify(Logic* logic, Crypto* c, const PathID_t& srcpath, llarp_threadpool* worker, @@ -131,6 +136,7 @@ namespace llarp T.Zero(); N.Zero(); Z.Zero(); + R = 0; } bool