mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-10-31 09:20:21 +00:00
f168b7cf72
It didn't do equality, it did "does the remaining space start with the argument" (and so the replacement in the previous commit was broken). This renames it to avoid the confusion and restores to what it was doing on dev.
160 lines
3.5 KiB
C++
160 lines
3.5 KiB
C++
#include "link_intro.hpp"
|
|
|
|
#include <llarp/crypto/crypto.hpp>
|
|
#include <llarp/router_contact.hpp>
|
|
#include <llarp/router/abstractrouter.hpp>
|
|
#include <llarp/util/bencode.h>
|
|
#include <llarp/util/logging.hpp>
|
|
|
|
namespace llarp
|
|
{
|
|
bool
|
|
LinkIntroMessage::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf)
|
|
{
|
|
if (key.startswith("a"))
|
|
{
|
|
llarp_buffer_t strbuf;
|
|
if (!bencode_read_string(buf, &strbuf))
|
|
return false;
|
|
if (strbuf.sz != 1)
|
|
return false;
|
|
return *strbuf.cur == 'i';
|
|
}
|
|
if (key.startswith("n"))
|
|
{
|
|
if (N.BDecode(buf))
|
|
return true;
|
|
llarp::LogWarn("failed to decode nonce in LIM");
|
|
return false;
|
|
}
|
|
if (key.startswith("p"))
|
|
{
|
|
return bencode_read_integer(buf, &P);
|
|
}
|
|
if (key.startswith("r"))
|
|
{
|
|
if (rc.BDecode(buf))
|
|
return true;
|
|
llarp::LogWarn("failed to decode RC in LIM");
|
|
llarp::DumpBuffer(*buf);
|
|
return false;
|
|
}
|
|
if (key.startswith("v"))
|
|
{
|
|
if (!bencode_read_integer(buf, &version))
|
|
return false;
|
|
if (version != llarp::constants::proto_version)
|
|
{
|
|
llarp::LogWarn(
|
|
"llarp protocol version mismatch ", version, " != ", llarp::constants::proto_version);
|
|
return false;
|
|
}
|
|
llarp::LogDebug("LIM version ", version);
|
|
return true;
|
|
}
|
|
if (key.startswith("z"))
|
|
{
|
|
return Z.BDecode(buf);
|
|
}
|
|
|
|
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_uint64_entry(buf, "v", 1, llarp::constants::proto_version))
|
|
return false;
|
|
|
|
if (!bencode_write_bytestring(buf, "z", 1))
|
|
return false;
|
|
if (!Z.BEncode(buf))
|
|
return false;
|
|
|
|
return bencode_end(buf);
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::HandleMessage(AbstractRouter* /*router*/) const
|
|
{
|
|
if (!Verify())
|
|
return false;
|
|
return session->GotLIM(this);
|
|
}
|
|
|
|
void
|
|
LinkIntroMessage::Clear()
|
|
{
|
|
P = 0;
|
|
N.Zero();
|
|
rc.Clear();
|
|
Z.Zero();
|
|
version = 0;
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::Sign(std::function<bool(Signature&, const llarp_buffer_t&)> signer)
|
|
{
|
|
Z.Zero();
|
|
std::array<byte_t, MaxSize> tmp;
|
|
llarp_buffer_t buf(tmp);
|
|
if (!BEncode(&buf))
|
|
return false;
|
|
buf.sz = buf.cur - buf.base;
|
|
buf.cur = buf.base;
|
|
return signer(Z, buf);
|
|
}
|
|
|
|
bool
|
|
LinkIntroMessage::Verify() const
|
|
{
|
|
LinkIntroMessage copy;
|
|
copy = *this;
|
|
copy.Z.Zero();
|
|
std::array<byte_t, MaxSize> tmp;
|
|
llarp_buffer_t buf(tmp);
|
|
if (!copy.BEncode(&buf))
|
|
return false;
|
|
buf.sz = buf.cur - buf.base;
|
|
buf.cur = buf.base;
|
|
// outer signature
|
|
if (!CryptoManager::instance()->verify(rc.pubkey, buf, Z))
|
|
{
|
|
llarp::LogError("outer signature failure");
|
|
return false;
|
|
}
|
|
// verify RC
|
|
if (!rc.Verify(llarp::time_now_ms()))
|
|
{
|
|
llarp::LogError("invalid RC in link intro");
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
} // namespace llarp
|