2019-01-10 19:41:51 +00:00
|
|
|
#include <service/protocol.hpp>
|
2019-04-10 13:19:32 +00:00
|
|
|
#include <path/path.hpp>
|
2018-12-12 02:04:32 +00:00
|
|
|
#include <routing/handler.hpp>
|
2019-01-10 19:41:51 +00:00
|
|
|
#include <util/buffer.hpp>
|
|
|
|
#include <util/mem.hpp>
|
2019-09-01 12:38:03 +00:00
|
|
|
#include <util/meta/memfn.hpp>
|
2019-09-01 13:26:16 +00:00
|
|
|
#include <util/thread/logic.hpp>
|
2020-05-28 11:21:47 +00:00
|
|
|
#include <service/endpoint.hpp>
|
2020-06-11 11:44:02 +00:00
|
|
|
#include <router/abstractrouter.hpp>
|
2019-07-30 23:42:13 +00:00
|
|
|
#include <utility>
|
2018-07-19 04:58:39 +00:00
|
|
|
|
|
|
|
namespace llarp
|
|
|
|
{
|
|
|
|
namespace service
|
|
|
|
{
|
2018-07-22 23:14:29 +00:00
|
|
|
ProtocolMessage::ProtocolMessage()
|
2018-07-19 04:58:39 +00:00
|
|
|
{
|
2018-08-09 19:02:17 +00:00
|
|
|
tag.Zero();
|
2018-07-19 04:58:39 +00:00
|
|
|
}
|
|
|
|
|
2018-08-09 19:02:17 +00:00
|
|
|
ProtocolMessage::ProtocolMessage(const ConvoTag& t) : tag(t)
|
2018-07-19 04:58:39 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
ProtocolMessage::~ProtocolMessage() = default;
|
2018-07-19 04:58:39 +00:00
|
|
|
|
|
|
|
void
|
2019-02-01 01:58:06 +00:00
|
|
|
ProtocolMessage::PutBuffer(const llarp_buffer_t& buf)
|
2018-07-19 04:58:39 +00:00
|
|
|
{
|
|
|
|
payload.resize(buf.sz);
|
|
|
|
memcpy(payload.data(), buf.base, buf.sz);
|
|
|
|
}
|
2018-07-22 23:14:29 +00:00
|
|
|
|
2018-08-09 19:02:17 +00:00
|
|
|
void
|
2020-04-07 18:38:56 +00:00
|
|
|
ProtocolMessage::ProcessAsync(
|
|
|
|
path::Path_ptr path, PathID_t from, std::shared_ptr<ProtocolMessage> self)
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!self->handler->HandleDataMessage(path, from, self))
|
2019-06-14 13:13:06 +00:00
|
|
|
LogWarn("failed to handle data message from ", path->Name());
|
2018-08-09 19:02:17 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
ProtocolMessage::DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* buf)
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
|
|
|
bool read = false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictInt("a", proto, read, k, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (k == "d")
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
|
|
|
llarp_buffer_t strbuf;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_read_string(buf, &strbuf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
|
|
|
PutBuffer(strbuf);
|
|
|
|
return true;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("i", introReply, read, k, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictInt("n", seqno, read, k, buf))
|
2019-05-22 16:20:03 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("s", sender, read, k, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("t", tag, read, k, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictInt("v", version, read, k, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
|
|
|
return read;
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
|
|
|
ProtocolMessage::BEncode(llarp_buffer_t* buf) const
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_start_dict(buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictInt("a", proto, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-06-17 13:07:05 +00:00
|
|
|
if (not payload.empty())
|
|
|
|
{
|
|
|
|
if (!bencode_write_bytestring(buf, "d", 1))
|
|
|
|
return false;
|
|
|
|
if (!bencode_write_bytestring(buf, payload.data(), payload.size()))
|
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("i", introReply, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictInt("n", seqno, buf))
|
2019-05-22 16:20:03 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("s", sender, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!tag.IsZero())
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("t", tag, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictInt("v", version, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
|
|
|
return bencode_end(buf);
|
|
|
|
}
|
|
|
|
|
2020-06-17 13:07:05 +00:00
|
|
|
std::optional<std::vector<byte_t>>
|
|
|
|
ProtocolMessage::MaybeEncodeAuthInfo() const
|
|
|
|
{
|
|
|
|
std::array<byte_t, 1024> info;
|
|
|
|
llarp_buffer_t buf{info};
|
|
|
|
if (not bencode_start_dict(&buf))
|
|
|
|
return std::nullopt;
|
|
|
|
if (not BEncodeWriteDictInt("a", proto, &buf))
|
|
|
|
return std::nullopt;
|
|
|
|
if (not BEncodeWriteDictEntry("i", introReply, &buf))
|
|
|
|
return std::nullopt;
|
|
|
|
if (not BEncodeWriteDictEntry("s", sender, &buf))
|
|
|
|
return std::nullopt;
|
|
|
|
if (not BEncodeWriteDictEntry("t", tag, &buf))
|
|
|
|
return std::nullopt;
|
|
|
|
if (not BEncodeWriteDictInt("v", version, &buf))
|
|
|
|
return std::nullopt;
|
|
|
|
if (not bencode_end(&buf))
|
|
|
|
return std::nullopt;
|
|
|
|
const std::size_t encodedSize = buf.cur - buf.base;
|
|
|
|
std::vector<byte_t> data;
|
|
|
|
data.resize(encodedSize);
|
|
|
|
std::copy_n(buf.base, encodedSize, data.data());
|
|
|
|
return data;
|
|
|
|
}
|
|
|
|
|
2019-07-30 23:42:13 +00:00
|
|
|
ProtocolFrame::~ProtocolFrame() = default;
|
2018-07-22 23:14:29 +00:00
|
|
|
|
|
|
|
bool
|
|
|
|
ProtocolFrame::BEncode(llarp_buffer_t* buf) const
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_start_dict(buf))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2018-08-13 23:22:31 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictMsgType(buf, "A", "H"))
|
2018-08-12 17:22:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!C.IsZero())
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("C", C, buf))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (D.size() > 0)
|
2019-03-08 16:00:45 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("D", D, buf))
|
2019-03-08 16:00:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("F", F, buf))
|
2019-03-08 15:33:49 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!N.IsZero())
|
2019-03-08 16:00:45 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("N", N, buf))
|
2019-03-08 16:00:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (R)
|
2019-03-08 16:00:45 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictInt("R", R, buf))
|
2019-03-08 16:00:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!T.IsZero())
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("T", T, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictInt("V", version, buf))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeWriteDictEntry("Z", Z, buf))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
|
|
|
return bencode_end(buf);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool
|
2019-02-01 01:58:06 +00:00
|
|
|
ProtocolFrame::DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* val)
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
|
|
|
bool read = false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (key == "A")
|
2018-08-12 17:22:29 +00:00
|
|
|
{
|
|
|
|
llarp_buffer_t strbuf;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_read_string(val, &strbuf))
|
2018-08-12 17:22:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (strbuf.sz != 1)
|
2018-08-12 17:22:29 +00:00
|
|
|
return false;
|
|
|
|
return *strbuf.cur == 'H';
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("D", D, read, key, val))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("F", F, read, key, val))
|
2019-03-08 15:33:49 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("C", C, read, key, val))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("N", N, read, key, val))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictInt("S", S, read, key, val))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictInt("R", R, read, key, val))
|
2019-03-08 16:00:45 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("T", T, read, key, val))
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeVerifyVersion("V", version, LLARP_PROTO_VERSION, read, key, val))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncodeMaybeReadDictEntry("Z", Z, read, key, val))
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
|
|
|
return read;
|
|
|
|
}
|
|
|
|
|
2018-08-09 19:02:17 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
ProtocolFrame::DecryptPayloadInto(const SharedSecret& sharedkey, ProtocolMessage& msg) const
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2018-12-20 16:49:05 +00:00
|
|
|
Encrypted_t tmp = D;
|
2020-04-07 18:38:56 +00:00
|
|
|
auto buf = tmp.Buffer();
|
2019-05-28 19:45:08 +00:00
|
|
|
CryptoManager::instance()->xchacha20(*buf, sharedkey, N);
|
2019-05-24 02:01:36 +00:00
|
|
|
return bencode_decode_dict(msg, buf);
|
2018-08-09 19:02:17 +00:00
|
|
|
}
|
|
|
|
|
2019-03-08 16:00:45 +00:00
|
|
|
bool
|
2019-05-28 19:45:08 +00:00
|
|
|
ProtocolFrame::Sign(const Identity& localIdent)
|
2019-03-08 16:00:45 +00:00
|
|
|
{
|
|
|
|
Z.Zero();
|
2020-04-07 18:38:56 +00:00
|
|
|
std::array<byte_t, MAX_PROTOCOL_MESSAGE_SIZE> tmp;
|
2019-03-08 16:00:45 +00:00
|
|
|
llarp_buffer_t buf(tmp);
|
|
|
|
// encode
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncode(&buf))
|
2019-03-08 16:00:45 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("message too big to encode");
|
2019-03-08 16:00:45 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
// rewind
|
2020-04-07 18:38:56 +00:00
|
|
|
buf.sz = buf.cur - buf.base;
|
2019-03-08 16:00:45 +00:00
|
|
|
buf.cur = buf.base;
|
|
|
|
// sign
|
2019-05-28 19:45:08 +00:00
|
|
|
return localIdent.Sign(Z, buf);
|
2019-03-08 16:00:45 +00:00
|
|
|
}
|
|
|
|
|
2018-07-22 23:14:29 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
ProtocolFrame::EncryptAndSign(
|
|
|
|
const ProtocolMessage& msg, const SharedSecret& sessionKey, const Identity& localIdent)
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
std::array<byte_t, MAX_PROTOCOL_MESSAGE_SIZE> tmp;
|
2019-02-02 23:12:42 +00:00
|
|
|
llarp_buffer_t buf(tmp);
|
2018-08-14 21:17:18 +00:00
|
|
|
// encode message
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!msg.BEncode(&buf))
|
2018-09-19 17:04:55 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("message too big to encode");
|
2018-08-14 21:17:18 +00:00
|
|
|
return false;
|
2018-09-19 17:04:55 +00:00
|
|
|
}
|
2018-08-14 21:17:18 +00:00
|
|
|
// rewind
|
2020-04-07 18:38:56 +00:00
|
|
|
buf.sz = buf.cur - buf.base;
|
2018-08-14 21:17:18 +00:00
|
|
|
buf.cur = buf.base;
|
|
|
|
// encrypt
|
2019-05-28 19:45:08 +00:00
|
|
|
CryptoManager::instance()->xchacha20(buf, sessionKey, N);
|
2018-08-14 21:17:18 +00:00
|
|
|
// put encrypted buffer
|
|
|
|
D = buf;
|
|
|
|
// zero out signature
|
|
|
|
Z.Zero();
|
2019-02-02 23:12:42 +00:00
|
|
|
llarp_buffer_t buf2(tmp);
|
2018-08-14 21:17:18 +00:00
|
|
|
// encode frame
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!BEncode(&buf2))
|
2018-09-19 17:04:55 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("frame too big to encode");
|
|
|
|
DumpBuffer(buf2);
|
2018-07-22 23:14:29 +00:00
|
|
|
return false;
|
2018-09-19 17:04:55 +00:00
|
|
|
}
|
2018-07-22 23:14:29 +00:00
|
|
|
// rewind
|
2020-04-07 18:38:56 +00:00
|
|
|
buf2.sz = buf2.cur - buf2.base;
|
2018-09-21 12:47:07 +00:00
|
|
|
buf2.cur = buf2.base;
|
2018-07-22 23:14:29 +00:00
|
|
|
// sign
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!localIdent.Sign(Z, buf2))
|
2018-09-19 17:04:55 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("failed to sign? wtf?!");
|
2018-09-19 17:04:55 +00:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2018-07-22 23:14:29 +00:00
|
|
|
}
|
|
|
|
|
2018-08-14 21:17:18 +00:00
|
|
|
struct AsyncFrameDecrypt
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-06-14 13:13:06 +00:00
|
|
|
path::Path_ptr path;
|
2020-04-07 18:38:56 +00:00
|
|
|
std::shared_ptr<Logic> logic;
|
|
|
|
std::shared_ptr<ProtocolMessage> msg;
|
2018-08-13 23:22:31 +00:00
|
|
|
const Identity& m_LocalIdentity;
|
2020-05-28 11:07:32 +00:00
|
|
|
Endpoint* handler;
|
2018-09-17 16:12:42 +00:00
|
|
|
const ProtocolFrame frame;
|
2019-04-10 13:19:32 +00:00
|
|
|
const Introduction fromIntro;
|
2018-08-09 19:02:17 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
AsyncFrameDecrypt(
|
|
|
|
std::shared_ptr<Logic> l,
|
|
|
|
const Identity& localIdent,
|
2020-05-28 11:07:32 +00:00
|
|
|
Endpoint* h,
|
2020-04-07 18:38:56 +00:00
|
|
|
std::shared_ptr<ProtocolMessage> m,
|
|
|
|
const ProtocolFrame& f,
|
|
|
|
const Introduction& recvIntro)
|
2019-07-30 23:42:13 +00:00
|
|
|
: logic(std::move(l))
|
|
|
|
, msg(std::move(m))
|
2018-08-13 23:22:31 +00:00
|
|
|
, m_LocalIdentity(localIdent)
|
2018-08-09 19:02:17 +00:00
|
|
|
, handler(h)
|
2018-08-13 23:22:31 +00:00
|
|
|
, frame(f)
|
2019-04-10 13:19:32 +00:00
|
|
|
, fromIntro(recvIntro)
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2020-05-28 11:07:32 +00:00
|
|
|
Work(std::shared_ptr<AsyncFrameDecrypt> self)
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-07-30 23:42:13 +00:00
|
|
|
auto crypto = CryptoManager::instance();
|
2018-08-13 23:22:31 +00:00
|
|
|
SharedSecret K;
|
|
|
|
SharedSecret sharedKey;
|
|
|
|
// copy
|
2018-09-17 16:12:42 +00:00
|
|
|
ProtocolFrame frame(self->frame);
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!crypto->pqe_decrypt(self->frame.C, K, pq_keypair_to_secret(self->m_LocalIdentity.pq)))
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("pqke failed C=", self->frame.C);
|
2019-05-03 13:15:03 +00:00
|
|
|
self->msg.reset();
|
2018-08-09 19:02:17 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-08-14 21:17:18 +00:00
|
|
|
// decrypt
|
|
|
|
auto buf = frame.D.Buffer();
|
2018-09-17 16:12:42 +00:00
|
|
|
crypto->xchacha20(*buf, K, self->frame.N);
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!bencode_decode_dict(*self->msg, buf))
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("failed to decode inner protocol message");
|
|
|
|
DumpBuffer(*buf);
|
2019-05-03 13:15:03 +00:00
|
|
|
self->msg.reset();
|
2018-08-09 19:02:17 +00:00
|
|
|
return;
|
|
|
|
}
|
2018-08-13 23:22:31 +00:00
|
|
|
// verify signature of outer message after we parsed the inner message
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!self->frame.Verify(self->msg->sender))
|
2018-08-13 23:22:31 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
LogError(
|
|
|
|
"intro frame has invalid signature Z=",
|
|
|
|
self->frame.Z,
|
|
|
|
" from ",
|
|
|
|
self->msg->sender.Addr());
|
|
|
|
Dump<MAX_PROTOCOL_MESSAGE_SIZE>(self->frame);
|
|
|
|
Dump<MAX_PROTOCOL_MESSAGE_SIZE>(*self->msg);
|
2019-05-03 13:15:03 +00:00
|
|
|
self->msg.reset();
|
2018-08-13 23:22:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2019-04-12 18:37:43 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
if (self->handler->HasConvoTag(self->msg->tag))
|
2019-04-12 18:37:43 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("dropping duplicate convo tag T=", self->msg->tag);
|
2019-04-12 18:37:43 +00:00
|
|
|
// TODO: send convotag reset
|
2019-05-03 13:15:03 +00:00
|
|
|
self->msg.reset();
|
2019-04-12 18:37:43 +00:00
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2018-08-13 23:22:31 +00:00
|
|
|
// PKE (A, B, N)
|
2019-01-02 01:04:03 +00:00
|
|
|
SharedSecret sharedSecret;
|
2020-04-07 18:38:56 +00:00
|
|
|
path_dh_func dh_server = util::memFn(&Crypto::dh_server, CryptoManager::instance());
|
2019-01-26 15:40:58 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!self->m_LocalIdentity.KeyExchange(
|
|
|
|
dh_server, sharedSecret, self->msg->sender, self->frame.N))
|
2018-08-13 23:22:31 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("x25519 key exchange failed");
|
2020-04-07 18:38:56 +00:00
|
|
|
Dump<MAX_PROTOCOL_MESSAGE_SIZE>(self->frame);
|
2019-05-03 13:15:03 +00:00
|
|
|
self->msg.reset();
|
2018-08-13 23:22:31 +00:00
|
|
|
return;
|
|
|
|
}
|
2020-04-07 18:38:56 +00:00
|
|
|
std::array<byte_t, 64> tmp;
|
2019-01-02 01:04:03 +00:00
|
|
|
// K
|
|
|
|
std::copy(K.begin(), K.end(), tmp.begin());
|
2018-08-13 23:22:31 +00:00
|
|
|
// S = HS( K + PKE( A, B, N))
|
2019-01-02 01:04:03 +00:00
|
|
|
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
|
2019-02-02 23:12:42 +00:00
|
|
|
crypto->shorthash(sharedKey, llarp_buffer_t(tmp));
|
2018-08-13 23:22:31 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
std::shared_ptr<ProtocolMessage> msg = std::move(self->msg);
|
|
|
|
path::Path_ptr path = std::move(self->path);
|
|
|
|
const PathID_t from = self->frame.F;
|
2020-05-28 11:07:32 +00:00
|
|
|
msg->handler = self->handler;
|
2020-06-17 13:07:05 +00:00
|
|
|
self->handler->AsyncProcessAuthMessage(
|
|
|
|
msg,
|
2020-05-28 11:07:32 +00:00
|
|
|
[path, msg, from, handler = self->handler, fromIntro = self->fromIntro, sharedKey](
|
2020-05-28 11:21:47 +00:00
|
|
|
AuthResult result) {
|
|
|
|
if (result == AuthResult::eAuthAccepted)
|
2020-05-28 11:07:32 +00:00
|
|
|
{
|
2020-06-02 21:10:42 +00:00
|
|
|
LogInfo("Accepted Convo T=", msg->tag);
|
2020-05-28 11:07:32 +00:00
|
|
|
handler->PutIntroFor(msg->tag, msg->introReply);
|
|
|
|
handler->PutReplyIntroFor(msg->tag, fromIntro);
|
|
|
|
handler->PutSenderFor(msg->tag, msg->sender, true);
|
|
|
|
handler->PutCachedSessionKeyFor(msg->tag, sharedKey);
|
|
|
|
ProtocolMessage::ProcessAsync(path, from, msg);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2020-06-02 21:10:42 +00:00
|
|
|
LogInfo("Rejected Convo T=", msg->tag);
|
2020-05-28 11:21:47 +00:00
|
|
|
handler->SendAuthReject(path, from, msg->tag, result);
|
2020-05-28 11:07:32 +00:00
|
|
|
}
|
|
|
|
});
|
2018-08-09 19:02:17 +00:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2018-08-14 21:17:18 +00:00
|
|
|
ProtocolFrame&
|
|
|
|
ProtocolFrame::operator=(const ProtocolFrame& other)
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
C = other.C;
|
|
|
|
D = other.D;
|
|
|
|
F = other.F;
|
|
|
|
N = other.N;
|
|
|
|
Z = other.Z;
|
|
|
|
T = other.T;
|
|
|
|
R = other.R;
|
|
|
|
S = other.S;
|
2018-09-14 13:43:42 +00:00
|
|
|
version = other.version;
|
2018-08-14 21:17:18 +00:00
|
|
|
return *this;
|
|
|
|
}
|
|
|
|
|
2019-11-28 23:08:02 +00:00
|
|
|
struct AsyncDecrypt
|
|
|
|
{
|
|
|
|
ServiceInfo si;
|
|
|
|
SharedSecret shared;
|
|
|
|
ProtocolFrame frame;
|
|
|
|
};
|
|
|
|
|
2018-08-09 19:02:17 +00:00
|
|
|
bool
|
2019-07-09 13:47:24 +00:00
|
|
|
ProtocolFrame::AsyncDecryptAndVerify(
|
2020-04-07 18:38:56 +00:00
|
|
|
std::shared_ptr<Logic> logic,
|
|
|
|
path::Path_ptr recvPath,
|
|
|
|
const Identity& localIdent,
|
2020-05-28 11:07:32 +00:00
|
|
|
Endpoint* handler) const
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
auto msg = std::make_shared<ProtocolMessage>();
|
2019-11-28 23:08:02 +00:00
|
|
|
msg->handler = handler;
|
2020-04-07 18:38:56 +00:00
|
|
|
if (T.IsZero())
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogInfo("Got protocol frame with new convo");
|
2018-08-09 19:02:17 +00:00
|
|
|
// we need to dh
|
2020-05-28 11:07:32 +00:00
|
|
|
auto dh = std::make_shared<AsyncFrameDecrypt>(
|
|
|
|
logic, localIdent, handler, msg, *this, recvPath->intro);
|
2019-06-14 13:13:06 +00:00
|
|
|
dh->path = recvPath;
|
2020-06-11 11:44:02 +00:00
|
|
|
handler->Router()->QueueWork(std::bind(&AsyncFrameDecrypt::Work, dh));
|
2020-05-20 11:41:42 +00:00
|
|
|
return true;
|
2018-08-09 19:02:17 +00:00
|
|
|
}
|
2019-11-28 23:08:02 +00:00
|
|
|
|
2020-05-28 11:07:32 +00:00
|
|
|
auto v = std::make_shared<AsyncDecrypt>();
|
2019-11-28 23:08:02 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!handler->GetCachedSessionKeyFor(T, v->shared))
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("No cached session for T=", T);
|
2020-05-28 11:07:32 +00:00
|
|
|
return true;
|
2018-08-09 19:02:17 +00:00
|
|
|
}
|
2019-11-28 23:08:02 +00:00
|
|
|
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!handler->GetSenderFor(T, v->si))
|
2018-08-09 19:02:17 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("No sender for T=", T);
|
2018-08-09 19:02:17 +00:00
|
|
|
return false;
|
|
|
|
}
|
2019-11-28 23:08:02 +00:00
|
|
|
v->frame = *this;
|
2020-06-11 11:44:02 +00:00
|
|
|
handler->Router()->QueueWork([v, msg = std::move(msg), recvPath = std::move(recvPath)]() {
|
2020-04-07 18:38:56 +00:00
|
|
|
if (not v->frame.Verify(v->si))
|
|
|
|
{
|
|
|
|
LogError("Signature failure from ", v->si.Addr());
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (not v->frame.DecryptPayloadInto(v->shared, *msg))
|
|
|
|
{
|
|
|
|
LogError("failed to decrypt message");
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
RecvDataEvent ev;
|
|
|
|
ev.fromPath = std::move(recvPath);
|
|
|
|
ev.pathid = v->frame.F;
|
|
|
|
ev.msg = std::move(msg);
|
|
|
|
msg->handler->QueueRecvData(std::move(ev));
|
|
|
|
});
|
2020-05-20 11:41:42 +00:00
|
|
|
return true;
|
2018-08-09 19:02:17 +00:00
|
|
|
}
|
|
|
|
|
2018-09-17 15:32:37 +00:00
|
|
|
bool
|
|
|
|
ProtocolFrame::operator==(const ProtocolFrame& other) const
|
|
|
|
{
|
2020-04-07 18:38:56 +00:00
|
|
|
return C == other.C && D == other.D && N == other.N && Z == other.Z && T == other.T
|
|
|
|
&& S == other.S && version == other.version;
|
2018-09-17 15:32:37 +00:00
|
|
|
}
|
|
|
|
|
2018-07-22 23:14:29 +00:00
|
|
|
bool
|
2019-08-02 09:27:27 +00:00
|
|
|
ProtocolFrame::Verify(const ServiceInfo& svc) const
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
2018-09-17 13:28:26 +00:00
|
|
|
ProtocolFrame copy(*this);
|
2018-07-22 23:14:29 +00:00
|
|
|
// save signature
|
|
|
|
// zero out signature for verify
|
2018-08-09 19:02:17 +00:00
|
|
|
copy.Z.Zero();
|
2018-07-22 23:14:29 +00:00
|
|
|
// serialize
|
2020-04-07 18:38:56 +00:00
|
|
|
std::array<byte_t, MAX_PROTOCOL_MESSAGE_SIZE> tmp;
|
2019-02-02 23:12:42 +00:00
|
|
|
llarp_buffer_t buf(tmp);
|
2020-04-07 18:38:56 +00:00
|
|
|
if (!copy.BEncode(&buf))
|
2018-07-22 23:14:29 +00:00
|
|
|
{
|
2019-04-22 18:35:19 +00:00
|
|
|
LogError("bencode fail");
|
2018-09-17 15:32:37 +00:00
|
|
|
return false;
|
2018-07-22 23:14:29 +00:00
|
|
|
}
|
2018-09-17 15:32:37 +00:00
|
|
|
|
|
|
|
// rewind buffer
|
2020-04-07 18:38:56 +00:00
|
|
|
buf.sz = buf.cur - buf.base;
|
2018-09-17 15:32:37 +00:00
|
|
|
buf.cur = buf.base;
|
|
|
|
// verify
|
2019-08-02 09:27:27 +00:00
|
|
|
return svc.Verify(buf, Z);
|
2018-07-22 23:14:29 +00:00
|
|
|
}
|
|
|
|
|
2018-07-23 07:38:29 +00:00
|
|
|
bool
|
2020-04-07 18:38:56 +00:00
|
|
|
ProtocolFrame::HandleMessage(routing::IMessageHandler* h, AbstractRouter* /*r*/) const
|
2018-07-23 07:38:29 +00:00
|
|
|
{
|
2019-04-22 17:38:29 +00:00
|
|
|
return h->HandleHiddenServiceFrame(*this);
|
2018-07-23 07:38:29 +00:00
|
|
|
}
|
|
|
|
|
2018-07-19 04:58:39 +00:00
|
|
|
} // namespace service
|
2018-09-14 13:43:42 +00:00
|
|
|
} // namespace llarp
|