2023-10-31 20:49:01 +00:00
|
|
|
#include "constants/version.hpp"
|
|
|
|
#include "crypto/crypto.hpp"
|
|
|
|
#include "net/net.hpp"
|
|
|
|
#include "router_contact.hpp"
|
|
|
|
#include "util/bencode.hpp"
|
|
|
|
#include "util/buffer.hpp"
|
|
|
|
#include "util/file.hpp"
|
|
|
|
#include "util/time.hpp"
|
|
|
|
|
|
|
|
#include <oxenc/bt_serialize.h>
|
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
2023-11-02 12:30:38 +00:00
|
|
|
RemoteRC::RemoteRC(oxenc::bt_dict_consumer btdc)
|
2023-10-31 20:49:01 +00:00
|
|
|
{
|
|
|
|
try
|
|
|
|
{
|
|
|
|
bt_load(btdc);
|
2023-11-02 12:30:38 +00:00
|
|
|
|
|
|
|
btdc.require_signature("~", [this](ustring_view msg, ustring_view sig) {
|
|
|
|
if (sig.size() != 64)
|
|
|
|
throw std::runtime_error{"Invalid signature: not 64 bytes"};
|
|
|
|
|
|
|
|
if (is_expired(time_now_ms()))
|
|
|
|
throw std::runtime_error{"Unable to verify expired RemoteRC!"};
|
|
|
|
|
|
|
|
// TODO: revisit if this is needed; detail from previous implementation
|
|
|
|
const auto* net = net::Platform::Default_ptr();
|
|
|
|
|
|
|
|
if (net->IsBogon(addr().in4()) and BLOCK_BOGONS)
|
|
|
|
{
|
|
|
|
auto err = "Unable to verify expired RemoteRC!";
|
|
|
|
log::info(logcat, err);
|
|
|
|
throw std::runtime_error{err};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not crypto::verify(router_id(), msg, sig))
|
|
|
|
throw std::runtime_error{"Failed to verify RemoteRC"};
|
|
|
|
});
|
2023-10-31 20:49:01 +00:00
|
|
|
}
|
|
|
|
catch (const std::exception& e)
|
|
|
|
{
|
2023-11-28 12:55:01 +00:00
|
|
|
auto err = "Exception caught parsing RemoteRC: {}"_format(e.what());
|
|
|
|
log::warning(logcat, err);
|
|
|
|
throw std::runtime_error{err};
|
2023-10-31 20:49:01 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
2023-11-02 12:30:38 +00:00
|
|
|
RemoteRC::bt_verify(oxenc::bt_dict_consumer& data, bool reject_expired) const
|
2023-10-31 20:49:01 +00:00
|
|
|
{
|
|
|
|
data.require_signature("~", [this, reject_expired](ustring_view msg, ustring_view sig) {
|
|
|
|
if (sig.size() != 64)
|
|
|
|
throw std::runtime_error{"Invalid signature: not 64 bytes"};
|
|
|
|
|
2023-11-27 16:31:43 +00:00
|
|
|
if (reject_expired and is_expired(time_now_ms()))
|
|
|
|
throw std::runtime_error{"Rejecting expired RemoteRC!"};
|
2023-10-31 20:49:01 +00:00
|
|
|
|
|
|
|
// TODO: revisit if this is needed; detail from previous implementation
|
|
|
|
const auto* net = net::Platform::Default_ptr();
|
|
|
|
|
|
|
|
if (net->IsBogon(addr().in4()) and BLOCK_BOGONS)
|
|
|
|
{
|
|
|
|
auto err = "Unable to verify expired RemoteRC!";
|
|
|
|
log::info(logcat, err);
|
|
|
|
throw std::runtime_error{err};
|
|
|
|
}
|
|
|
|
|
|
|
|
if (not crypto::verify(router_id(), msg, sig))
|
|
|
|
throw std::runtime_error{"Failed to verify RemoteRC"};
|
|
|
|
});
|
|
|
|
}
|
2023-11-02 12:30:38 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
RemoteRC::read(const fs::path& fname)
|
|
|
|
{
|
|
|
|
ustring buf;
|
|
|
|
buf.reserve(MAX_RC_SIZE);
|
|
|
|
|
|
|
|
try
|
|
|
|
{
|
|
|
|
util::file_to_buffer(fname, buf.data(), MAX_RC_SIZE);
|
2023-11-27 16:31:43 +00:00
|
|
|
|
|
|
|
oxenc::bt_dict_consumer btdc{buf};
|
|
|
|
bt_load(btdc);
|
|
|
|
bt_verify(btdc);
|
|
|
|
|
|
|
|
_payload = buf;
|
2023-11-02 12:30:38 +00:00
|
|
|
}
|
|
|
|
catch (const std::exception& e)
|
|
|
|
{
|
2023-12-06 21:54:51 +00:00
|
|
|
log::warning(logcat, "Failed to read or validate RC from {}: {}", fname, e.what());
|
2023-11-02 12:30:38 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
RemoteRC::verify() const
|
|
|
|
{
|
|
|
|
oxenc::bt_dict_consumer btdc{_payload};
|
|
|
|
bt_verify(btdc);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2023-10-31 20:49:01 +00:00
|
|
|
} // namespace llarp
|