mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-07 15:20:31 +00:00
b39c46fc03
redo link protocol to use 2 session keys, add unit tests.
166 lines
3.6 KiB
C++
166 lines
3.6 KiB
C++
#include <bencode.h>
|
|
#include <logger.hpp>
|
|
#include <messages/link_intro.hpp>
|
|
#include <router.hpp>
|
|
#include <router_contact.hpp>
|
|
|
|
namespace llarp
|
|
{
|
|
LinkIntroMessage::~LinkIntroMessage()
|
|
{
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::DecodeKey(llarp_buffer_t key, llarp_buffer_t* buf)
|
|
{
|
|
if(llarp_buffer_eq(key, "a"))
|
|
{
|
|
llarp_buffer_t strbuf;
|
|
if(!bencode_read_string(buf, &strbuf))
|
|
return false;
|
|
if(strbuf.sz != 1)
|
|
return false;
|
|
return *strbuf.cur == 'i';
|
|
}
|
|
if(llarp_buffer_eq(key, "n"))
|
|
{
|
|
if(N.BDecode(buf))
|
|
return true;
|
|
llarp::LogWarn("failed to decode nonce in LIM");
|
|
return false;
|
|
}
|
|
if(llarp_buffer_eq(key, "p"))
|
|
{
|
|
return bencode_read_integer(buf, &P);
|
|
}
|
|
if(llarp_buffer_eq(key, "r"))
|
|
{
|
|
if(rc.BDecode(buf))
|
|
return true;
|
|
llarp::LogWarn("failed to decode RC in LIM");
|
|
llarp::DumpBuffer(*buf);
|
|
return false;
|
|
}
|
|
else if(llarp_buffer_eq(key, "v"))
|
|
{
|
|
if(!bencode_read_integer(buf, &version))
|
|
return false;
|
|
if(version != LLARP_PROTO_VERSION)
|
|
{
|
|
llarp::LogWarn("llarp protocol version missmatch ", version,
|
|
" != ", LLARP_PROTO_VERSION);
|
|
return false;
|
|
}
|
|
llarp::LogDebug("LIM version ", version);
|
|
return true;
|
|
}
|
|
else if(llarp_buffer_eq(key, "z"))
|
|
{
|
|
return Z.BDecode(buf);
|
|
}
|
|
else
|
|
{
|
|
llarp::LogWarn("invalid LIM key: ", *key.cur);
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::BEncode(llarp_buffer_t* buf) const
|
|
{
|
|
if(!bencode_start_dict(buf))
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, "a", 1))
|
|
return false;
|
|
if(!bencode_write_bytestring(buf, "i", 1))
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, "n", 1))
|
|
return false;
|
|
if(!N.BEncode(buf))
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, "p", 1))
|
|
return false;
|
|
if(!bencode_write_uint64(buf, P))
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, "r", 1))
|
|
return false;
|
|
if(!rc.BEncode(buf))
|
|
return false;
|
|
|
|
if(!bencode_write_version_entry(buf))
|
|
return false;
|
|
|
|
if(!bencode_write_bytestring(buf, "z", 1))
|
|
return false;
|
|
if(!Z.BEncode(buf))
|
|
return false;
|
|
|
|
return bencode_end(buf);
|
|
}
|
|
|
|
LinkIntroMessage&
|
|
LinkIntroMessage::operator=(const LinkIntroMessage& msg)
|
|
{
|
|
version = msg.version;
|
|
Z = msg.Z;
|
|
rc = msg.rc;
|
|
N = msg.N;
|
|
P = msg.P;
|
|
return *this;
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::HandleMessage(llarp::Router* router) const
|
|
{
|
|
if(!Verify(&router->crypto))
|
|
return false;
|
|
return session->GotLIM(this);
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::Sign(
|
|
std::function< bool(Signature&, llarp_buffer_t) > signer)
|
|
{
|
|
Z.Zero();
|
|
byte_t tmp[MaxSize] = {0};
|
|
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
if(!BEncode(&buf))
|
|
return false;
|
|
buf.sz = buf.cur - buf.base;
|
|
buf.cur = buf.base;
|
|
return signer(Z, buf);
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::Verify(llarp::Crypto* c) const
|
|
{
|
|
LinkIntroMessage copy;
|
|
copy = *this;
|
|
copy.Z.Zero();
|
|
byte_t tmp[MaxSize] = {0};
|
|
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
if(!copy.BEncode(&buf))
|
|
return false;
|
|
buf.sz = buf.cur - buf.base;
|
|
buf.cur = buf.base;
|
|
// outer signature
|
|
if(!c->verify(rc.pubkey, buf, Z))
|
|
{
|
|
llarp::LogError("outer signature failure");
|
|
return false;
|
|
}
|
|
// verify RC
|
|
if(!rc.Verify(c))
|
|
{
|
|
llarp::LogError("invalid RC in link intro");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace llarp
|