lokinet/llarp/router_contact.cpp

220 lines
4.7 KiB
C++
Raw Normal View History

2018-05-10 23:32:46 +00:00
#include <llarp/bencode.h>
#include <llarp/router_contact.h>
#include <llarp/version.h>
#include <llarp/crypto.hpp>
#include "buffer.hpp"
#include "logger.hpp"
extern "C" {
void
llarp_rc_free(struct llarp_rc *rc)
{
if(rc->exits)
llarp_xi_list_free(rc->exits);
if(rc->addrs)
llarp_ai_list_free(rc->addrs);
rc->exits = 0;
rc->addrs = 0;
2018-05-10 23:32:46 +00:00
}
2018-05-16 18:13:18 +00:00
struct llarp_rc_decoder
{
struct llarp_rc *rc;
struct llarp_alloc *mem;
2018-05-16 18:13:18 +00:00
};
2018-05-13 18:07:36 +00:00
static bool
llarp_rc_decode_dict(struct dict_reader *r, llarp_buffer_t *key)
2018-05-13 18:07:36 +00:00
{
uint64_t v;
2018-05-13 18:07:36 +00:00
llarp_buffer_t strbuf;
llarp_rc *rc = static_cast< llarp_rc * >(r->user);
2018-05-13 18:07:36 +00:00
if(!key)
return true;
2018-05-13 18:07:36 +00:00
if(llarp_buffer_eq(*key, "a"))
{
if(rc->addrs)
{
llarp_ai_list_free(rc->addrs);
}
rc->addrs = llarp_ai_list_new();
2018-05-13 18:07:36 +00:00
return llarp_ai_list_bdecode(rc->addrs, r->buffer);
}
2018-06-12 12:49:23 +00:00
if(llarp_buffer_eq(*key, "k"))
2018-06-10 14:05:48 +00:00
{
if(!bencode_read_string(r->buffer, &strbuf))
return false;
if(strbuf.sz != PUBKEYSIZE)
2018-06-10 14:05:48 +00:00
return false;
2018-06-12 12:49:23 +00:00
memcpy(rc->pubkey, strbuf.base, PUBKEYSIZE);
2018-06-10 14:05:48 +00:00
return true;
}
2018-06-12 12:49:23 +00:00
if(llarp_buffer_eq(*key, "p"))
2018-05-13 18:07:36 +00:00
{
if(!bencode_read_string(r->buffer, &strbuf))
2018-05-13 18:07:36 +00:00
return false;
if(strbuf.sz != PUBKEYSIZE)
2018-05-13 18:07:36 +00:00
return false;
2018-06-12 12:49:23 +00:00
memcpy(rc->enckey, strbuf.base, PUBKEYSIZE);
2018-05-13 18:07:36 +00:00
return true;
}
2018-05-13 18:07:36 +00:00
2018-05-21 12:44:50 +00:00
if(llarp_buffer_eq(*key, "u"))
{
if(!bencode_read_integer(r->buffer, &rc->last_updated))
return false;
return true;
2018-05-21 12:44:50 +00:00
}
2018-05-13 18:07:36 +00:00
if(llarp_buffer_eq(*key, "v"))
{
if(!bencode_read_integer(r->buffer, &v))
2018-05-13 18:07:36 +00:00
return false;
return v == LLARP_PROTO_VERSION;
}
if(llarp_buffer_eq(*key, "x"))
{
if(rc->exits)
{
llarp_xi_list_free(rc->exits);
}
rc->exits = llarp_xi_list_new();
2018-05-13 18:07:36 +00:00
return llarp_xi_list_bdecode(rc->exits, r->buffer);
}
if(llarp_buffer_eq(*key, "z"))
{
if(!bencode_read_string(r->buffer, &strbuf))
2018-05-13 18:07:36 +00:00
return false;
if(strbuf.sz != SIGSIZE)
2018-05-13 18:07:36 +00:00
return false;
memcpy(rc->signature, strbuf.base, SIGSIZE);
2018-05-13 18:07:36 +00:00
return true;
}
return false;
}
2018-05-30 20:56:47 +00:00
void
2018-06-01 21:35:17 +00:00
llarp_rc_copy(struct llarp_rc *dst, const struct llarp_rc *src)
2018-05-30 20:56:47 +00:00
{
llarp_rc_free(dst);
llarp_rc_clear(dst);
memcpy(dst->pubkey, src->pubkey, PUBKEYSIZE);
memcpy(dst->enckey, src->enckey, PUBKEYSIZE);
memcpy(dst->signature, src->signature, SIGSIZE);
2018-05-30 20:56:47 +00:00
dst->last_updated = src->last_updated;
if(src->addrs)
{
dst->addrs = llarp_ai_list_new();
llarp_ai_list_copy(dst->addrs, src->addrs);
}
if(src->exits)
{
dst->exits = llarp_xi_list_new();
llarp_xi_list_copy(dst->exits, src->exits);
}
}
bool
llarp_rc_bdecode(struct llarp_rc *rc, llarp_buffer_t *buff)
{
dict_reader r = {buff, rc, &llarp_rc_decode_dict};
return bencode_read_dict(buff, &r);
2018-05-13 18:07:36 +00:00
}
bool
llarp_rc_verify_sig(struct llarp_crypto *crypto, struct llarp_rc *rc)
2018-05-13 18:07:36 +00:00
{
2018-05-31 13:07:52 +00:00
// maybe we should copy rc before modifying it
// would that make it more thread safe?
// jeff agrees
2018-05-20 17:45:47 +00:00
bool result = false;
llarp::Signature sig;
byte_t tmp[MAX_RC_SIZE];
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
2018-05-20 17:45:47 +00:00
// copy sig
memcpy(sig, rc->signature, SIGSIZE);
// zero sig
size_t sz = 0;
while(sz < SIGSIZE)
rc->signature[sz++] = 0;
2018-05-20 17:45:47 +00:00
// bencode
if(llarp_rc_bencode(rc, &buf))
{
buf.sz = buf.cur - buf.base;
2018-05-20 17:45:47 +00:00
buf.cur = buf.base;
result = crypto->verify(rc->pubkey, buf, sig);
2018-05-20 17:45:47 +00:00
}
else
2018-06-21 12:55:02 +00:00
llarp::Warn("RC encode failed");
// restore sig
memcpy(rc->signature, sig, SIGSIZE);
2018-05-20 17:45:47 +00:00
return result;
2018-05-13 18:07:36 +00:00
}
bool
2018-06-13 16:32:34 +00:00
llarp_rc_bencode(const struct llarp_rc *rc, llarp_buffer_t *buff)
{
2018-05-10 23:32:46 +00:00
/* write dict begin */
if(!bencode_start_dict(buff))
return false;
if(rc->addrs)
{
2018-05-10 23:32:46 +00:00
/* write ai if they exist */
if(!bencode_write_bytestring(buff, "a", 1))
return false;
if(!llarp_ai_list_bencode(rc->addrs, buff))
return false;
2018-05-10 23:32:46 +00:00
}
2018-06-10 14:05:48 +00:00
/* write signing pubkey */
if(!bencode_write_bytestring(buff, "k", 1))
return false;
if(!bencode_write_bytestring(buff, rc->pubkey, PUBKEYSIZE))
2018-05-10 23:32:46 +00:00
return false;
2018-06-12 12:49:23 +00:00
/* write encryption pubkey */
if(!bencode_write_bytestring(buff, "p", 1))
return false;
if(!bencode_write_bytestring(buff, rc->enckey, PUBKEYSIZE))
return false;
2018-05-21 12:44:50 +00:00
/* write last updated */
if(!bencode_write_bytestring(buff, "u", 1))
return false;
if(!bencode_write_uint64(buff, rc->last_updated))
2018-05-21 12:44:50 +00:00
return false;
2018-05-10 23:32:46 +00:00
/* write version */
if(!bencode_write_version_entry(buff))
return false;
2018-05-10 23:32:46 +00:00
if(rc->exits)
{
2018-05-10 23:32:46 +00:00
/* write ai if they exist */
if(!bencode_write_bytestring(buff, "x", 1))
return false;
if(!llarp_xi_list_bencode(rc->exits, buff))
return false;
2018-05-10 23:32:46 +00:00
}
/* write signature */
if(!bencode_write_bytestring(buff, "z", 1))
return false;
if(!bencode_write_bytestring(buff, rc->signature, SIGSIZE))
2018-05-10 23:32:46 +00:00
return false;
return bencode_end(buff);
}
}