lokinet/llarp/messages/link_intro.cpp

163 lines
3.6 KiB
C++
Raw Normal View History

#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>
2023-08-29 14:26:59 +00:00
#include <oxenc/bt_producer.h>
namespace llarp
{
bool
2023-08-29 14:26:59 +00:00
LinkIntroMessage::decode_key(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"))
{
2023-08-29 14:26:59 +00:00
if (nonce.BDecode(buf))
return true;
llarp::LogWarn("failed to decode nonce in LIM");
return false;
}
if (key.startswith("p"))
{
2023-08-29 14:26:59 +00:00
return bencode_read_integer(buf, &session_period);
}
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;
2022-05-26 15:59:44 +00:00
if (version != llarp::constants::proto_version)
{
2022-05-26 15:59:44 +00:00
llarp::LogWarn(
"llarp protocol version mismatch ", version, " != ", llarp::constants::proto_version);
return false;
}
llarp::LogDebug("LIM version ", version);
return true;
}
if (key.startswith("z"))
{
2023-08-29 14:26:59 +00:00
return sig.BDecode(buf);
}
2019-07-30 23:42:13 +00:00
llarp::LogWarn("invalid LIM key: ", *key.cur);
return false;
}
2023-08-29 14:26:59 +00:00
std::string
LinkIntroMessage::bt_encode() const
{
2023-08-29 14:26:59 +00:00
oxenc::bt_dict_producer btdp;
2023-08-29 14:26:59 +00:00
try
{
btdp.append("a", "i");
btdp.append("n", nonce.ToView());
btdp.append("p", session_period);
2023-08-29 14:26:59 +00:00
{
auto subdict = btdp.append_list("r");
rc.bt_encode_subdict(subdict);
}
2023-08-29 14:26:59 +00:00
btdp.append("v", llarp::constants::proto_version);
btdp.append("z", sig.ToView());
}
catch (...)
{
log::critical(link_cat, "Error: LinkIntroMessage failed to bt encode contents!");
}
2023-08-29 14:26:59 +00:00
return std::move(btdp).str();
}
bool
2023-08-29 14:26:59 +00:00
LinkIntroMessage::handle_message(AbstractRouter* /*router*/) const
{
2023-08-29 14:26:59 +00:00
if (!verify())
return false;
return session->GotLIM(this);
}
void
2023-08-29 14:26:59 +00:00
LinkIntroMessage::clear()
{
2023-08-29 14:26:59 +00:00
session_period = 0;
nonce.Zero();
rc.Clear();
2023-08-29 14:26:59 +00:00
sig.Zero();
version = 0;
}
bool
2023-08-29 14:26:59 +00:00
LinkIntroMessage::sign(std::function<bool(Signature&, const llarp_buffer_t&)> signer)
{
2023-08-29 14:26:59 +00:00
sig.Zero();
// need to keep this as a llarp_buffer_t for now, as all the crypto code expects
// byte_t types -- fix this later
std::array<byte_t, MAX_MSG_SIZE> tmp;
2019-02-02 23:12:42 +00:00
llarp_buffer_t buf(tmp);
2023-08-29 14:26:59 +00:00
auto bte = bt_encode();
buf.write(bte.begin(), bte.end());
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
2023-08-29 14:26:59 +00:00
return signer(sig, buf);
}
bool
2023-08-29 14:26:59 +00:00
LinkIntroMessage::verify() const
{
LinkIntroMessage copy;
copy = *this;
2023-08-29 14:26:59 +00:00
copy.sig.Zero();
// need to keep this as a llarp_buffer_t for now, as all the crypto code expects
// byte_t types -- fix this later
std::array<byte_t, MAX_MSG_SIZE> tmp;
2019-02-02 23:12:42 +00:00
llarp_buffer_t buf(tmp);
2023-08-29 14:26:59 +00:00
auto bte = copy.bt_encode();
buf.write(bte.begin(), bte.end());
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
2023-08-29 14:26:59 +00:00
// outer signature
2023-08-29 14:26:59 +00:00
if (!CryptoManager::instance()->verify(rc.pubkey, buf, sig))
{
2023-08-29 14:26:59 +00:00
log::error(link_cat, "Error: outer signature failed!");
return false;
}
// verify RC
if (!rc.Verify(llarp::time_now_ms()))
{
2023-08-29 14:26:59 +00:00
log::error(link_cat, "Error: invalid RC in link intro!");
return false;
}
return true;
}
} // namespace llarp