implement rc signing

pull/1/head
Jeff Becker 6 years ago
parent 0f6c0d8a56
commit 6cc469775f
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -6,7 +6,7 @@ contact-file=router-contact.signed
dir=./tmp-nodes
[iwp-connect]
#named-node0=/path/to/routercontact0
named-node0=remote-rc.signed
#named-node1=/path/to/routercontact1
[iwp-links]

@ -12,6 +12,7 @@ static void progress() {
struct llarp_main
{
struct llarp_alloc mem;
struct llarp_crypto crypto;
struct llarp_router *router = nullptr;
struct llarp_threadpool *worker = nullptr;
struct llarp_threadpool *thread = nullptr;
@ -111,17 +112,18 @@ int main(int argc, char *argv[]) {
const char *conffname = "daemon.ini";
if (argc > 1) conffname = argv[1];
llarp_mem_jemalloc(&llarp.mem);
struct llarp_alloc * mem = &llarp.mem;
auto mem = &llarp.mem;
llarp_new_config(&llarp.config);
llarp_ev_loop_alloc(&llarp.mainloop);
llarp_crypto_libsodium_init(&llarp.crypto);
printf("%s loading config file %s\n", LLARP_VERSION, conffname);
if (!llarp_load_config(llarp.config, conffname)) {
struct llarp_config_iterator iter;
llarp_config_iterator iter;
iter.user = &llarp;
iter.visit = iter_main_config;
llarp_config_iter(llarp.config, &iter);
llarp.nodedb = llarp_nodedb_new(mem);
llarp.nodedb = llarp_nodedb_new(mem, &llarp.crypto);
if (llarp.nodedb_dir[0]) {
llarp.nodedb_dir[sizeof(llarp.nodedb_dir) - 1] = 0;
@ -129,7 +131,7 @@ int main(int argc, char *argv[]) {
if (llarp_nodedb_ensure_dir(dir)) {
// ensure worker thread pool
if (!llarp.worker) llarp.worker = llarp_init_threadpool(2);
// ensure thread
// ensure logic thread
llarp.thread = llarp_init_threadpool(1);
llarp.logic = llarp_init_logic(mem);
@ -140,11 +142,7 @@ int main(int argc, char *argv[]) {
printf("starting router\n");
llarp_run_router(llarp.router);
// run mainloop
struct llarp_thread_job job = {
.user = llarp.mainloop,
.work = &run_net
};
llarp_threadpool_queue_job(llarp.thread, job);
llarp_threadpool_queue_job(llarp.thread, {llarp.mainloop, &run_net});
printf("running\n");
llarp.exitcode = 0;
llarp_logic_mainloop(llarp.logic);

@ -27,11 +27,13 @@ struct llarp_ai_list;
struct llarp_ai_list *llarp_ai_list_new(struct llarp_alloc * mem);
void llarp_ai_list_free(struct llarp_ai_list **l);
void llarp_ai_copy(struct llarp_ai * dst, struct llarp_ai * src);
bool llarp_ai_list_bencode(struct llarp_ai_list *l, llarp_buffer_t *buff);
bool llarp_ai_list_bdecode(struct llarp_ai_list *l, llarp_buffer_t *buff);
struct llarp_ai llarp_ai_list_popfront(struct llarp_ai_list *l);
void llarp_ai_list_pushback(struct llarp_ai_list *l, struct llarp_ai *ai);
void llarp_ai_list_pushback(struct llarp_ai_list *l, struct llarp_ai ai);
size_t llarp_ai_list_size(struct llarp_ai_list *l);
struct llarp_ai *llarp_ai_list_index(struct llarp_ai_list *l, ssize_t idx);

@ -51,7 +51,7 @@ typedef bool (*llarp_shorthash_func)(llarp_shorthash_t *, llarp_buffer_t);
typedef bool (*llarp_hmac_func)(uint8_t *, llarp_buffer_t,
const uint8_t *);
typedef bool (*llarp_sign_func)(uint8_t *, llarp_seckey_t, llarp_buffer_t);
typedef bool (*llarp_sign_func)(uint8_t *, const uint8_t *, llarp_buffer_t);
typedef bool (*llarp_verify_func)(const uint8_t *, llarp_buffer_t, const uint8_t *);

@ -64,6 +64,7 @@ struct llarp_link_ev_listener {
struct llarp_link {
void *impl;
const char *(*name)(void);
void (*get_our_address)(struct llarp_link *, struct llarp_ai *);
/*
int (*register_listener)(struct llarp_link *, struct llarp_link_ev_listener);
void (*deregister_listener)(struct llarp_link *, int);

@ -9,7 +9,7 @@ extern "C" {
struct llarp_nodedb;
/** create an empty nodedb */
struct llarp_nodedb *llarp_nodedb_new(struct llarp_alloc * mem);
struct llarp_nodedb *llarp_nodedb_new(struct llarp_alloc * mem, struct llarp_crypto * crypto);
/** free a nodedb and all loaded rc */
void llarp_nodedb_free(struct llarp_nodedb **n);

@ -7,6 +7,8 @@
extern "C" {
#endif
const size_t MAX_RC_SIZE = 1024;
struct llarp_rc {
struct llarp_ai_list *addrs;
llarp_pubkey_t pubkey;
@ -17,7 +19,7 @@ struct llarp_rc {
bool llarp_rc_bdecode(struct llarp_alloc * mem, struct llarp_rc *rc, llarp_buffer_t *buf);
bool llarp_rc_bencode(struct llarp_rc *rc, llarp_buffer_t *buf);
void llarp_rc_free(struct llarp_rc *rc);
bool llarp_rc_verify_sig(struct llarp_rc *rc);
bool llarp_rc_verify_sig(struct llarp_crypto * crypto, struct llarp_rc *rc);
#ifdef __cplusplus
}

@ -87,6 +87,30 @@ void llarp_ai_list_free(struct llarp_ai_list **l) {
}
}
void llarp_ai_copy(struct llarp_ai * dst, struct llarp_ai * src)
{
memcpy(dst, src, sizeof(struct llarp_ai));
}
void llarp_ai_list_pushback(struct llarp_ai_list * l, struct llarp_ai a)
{
struct llarp_ai_list_node *cur = l->root;
if(cur)
{
// go to the end of the list
while(cur->next)
cur = cur->next;
cur->next = l->mem->alloc(l->mem, sizeof(struct llarp_ai_list_node), 16);
cur = cur->next;
}
else
cur = l->mem->alloc(l->mem, sizeof(struct llarp_ai_list_node), 16);
llarp_ai_copy(&cur->data, &a);
cur->next = 0;
}
void llarp_ai_list_iterate(struct llarp_ai_list *l,
struct llarp_ai_list_iter *itr) {
struct llarp_ai_list_node *cur = l->root;

@ -17,10 +17,10 @@ bool llarp_buffer_writef(llarp_buffer_t* buff, const char* fmt, ...) {
size_t sz = llarp_buffer_size_left(buff);
va_list args;
va_start(args, fmt);
written = snprintf(buff->cur, sz, fmt, args);
written = vsnprintf(buff->cur, sz, fmt, args);
va_end(args);
if (written == -1) return false;
buff->sz += written;
buff->cur += written;
return true;
}

@ -77,7 +77,7 @@ static bool hmac(uint8_t *result, llarp_buffer_t buff,
secret, HMACSECSIZE) != -1;
}
static bool sign(uint8_t *result, llarp_seckey_t secret,
static bool sign(uint8_t *result, const uint8_t * secret,
llarp_buffer_t buff) {
const uint8_t *base = (const uint8_t *)buff.base;
return crypto_sign_detached(result, nullptr, base, buff.sz, secret) != -1;

@ -569,6 +569,11 @@ struct server
printf("cleanup dead\n");
}
uint8_t * pubkey()
{
return llarp_seckey_topublic(seckey);
}
bool ensure_privkey()
{
std::error_code ec;
@ -662,10 +667,21 @@ server * link_alloc(struct llarp_alloc * mem, struct llarp_msg_muxer * muxer, co
const char * link_name()
{
return "iwp";
return "IWP";
}
void link_get_addr(struct llarp_link * l, struct llarp_ai * addr)
{
server * link = static_cast<server *>(l->impl);
llarp::Addr linkaddr(link->udp.addr);
addr->rank = 1;
strncpy(addr->dialect, link_name(), sizeof(addr->dialect));
memcpy(addr->enc_key, link->pubkey(), 32);
memcpy(addr->ip.s6_addr, linkaddr.addr.s6_addr, 16);
addr->port = linkaddr.port;
}
bool link_configure(struct llarp_link * l, struct llarp_ev_loop * netloop, const char * ifname, int af, uint16_t port)
{
server * link = static_cast<server*>(l->impl);
@ -768,6 +784,7 @@ void iwp_link_init(struct llarp_link * link, struct llarp_iwp_args args, struct
{
link->impl = iwp::link_alloc(args.mem, muxer, args.keyfile, args.crypto, args.logic, args.cryptoworker);
link->name = iwp::link_name;
link->get_our_address = iwp::link_get_addr;
link->configure = iwp::link_configure;
link->start_link = iwp::link_start;
link->stop_link = iwp::link_stop;

@ -2,7 +2,7 @@
bool llarp_link_initialized(struct llarp_link * link)
{
return link && link->impl && link->name && link->configure && link->start_link && link->stop_link && link->iter_sessions && link->try_establish && link->acquire_session_for_addr && link->mark_session_active && link->free_impl;
return link && link->impl && link->name && link->get_our_address && link->configure && link->start_link && link->stop_link && link->iter_sessions && link->try_establish && link->acquire_session_for_addr && link->mark_session_active && link->free_impl;
}
bool llarp_link_session_initialized(struct llarp_link_session * s)

@ -9,9 +9,10 @@ static const char skiplist_subdirs[] = "0123456789ABCDEF";
struct llarp_nodedb {
llarp_nodedb(struct llarp_alloc * m) : mem(m) {}
llarp_nodedb(llarp_alloc * m, llarp_crypto * c) : mem(m), crypto(c) {}
llarp_alloc * mem;
llarp_crypto * crypto;
std::map<llarp::pubkey, llarp_rc *> entries;
void Clear()
@ -51,8 +52,9 @@ struct llarp_nodedb {
}
fclose(f);
llarp_rc *rc = llarp::Alloc<llarp_rc>(mem);
llarp::Zero(rc, sizeof(llarp_rc));
if (llarp_rc_bdecode(mem, rc, &buff)) {
if (llarp_rc_verify_sig(rc)) {
if (llarp_rc_verify_sig(crypto, rc)) {
llarp::pubkey pk;
memcpy(pk.data(), rc->pubkey, pk.size());
entries[pk] = rc;
@ -75,10 +77,10 @@ struct llarp_nodedb {
extern "C" {
struct llarp_nodedb *llarp_nodedb_new(struct llarp_alloc * mem) {
struct llarp_nodedb *llarp_nodedb_new(struct llarp_alloc * mem, struct llarp_crypto * crypto) {
void * ptr = mem->alloc(mem, sizeof(llarp_nodedb), llarp::alignment<llarp_nodedb>());
if(!ptr) return nullptr;
return new (ptr) llarp_nodedb(mem);
return new (ptr) llarp_nodedb(mem, crypto);
}
void llarp_nodedb_free(struct llarp_nodedb **n) {

@ -7,6 +7,8 @@
#include <llarp/router.h>
#include "str.hpp"
#include <fstream>
namespace llarp {
void router_iter_config(llarp_config_iterator *iter, const char *section,
const char *key, const char *val);
@ -33,6 +35,54 @@ void llarp_router::AddLink(struct llarp_link *link) {
bool llarp_router::Ready() { return ready; }
bool llarp_router::EnsureIdentity()
{
std::error_code ec;
if(!fs::exists(ident_keyfile, ec))
{
crypto.keygen(identity);
std::ofstream f(ident_keyfile, std::ios::binary);
if(f.is_open())
{
f.write((char*)identity, sizeof(identity));
}
}
std::ifstream f(ident_keyfile, std::ios::binary);
if(f.is_open())
{
f.read((char*)identity, sizeof(identity));
return true;
}
return false;
}
bool llarp_router::SaveRC()
{
printf("verify rc signature... ");
if(!llarp_rc_verify_sig(&crypto, &rc))
{
printf(" BAD!\n");
return false;
}
printf(" OK.\n");
uint8_t tmp[MAX_RC_SIZE];
llarp_buffer_t buf;
buf.base = (char*)tmp;
buf.cur = (char*) tmp;
buf.sz = sizeof(tmp);
if(llarp_rc_bencode(&rc, &buf))
{
std::ofstream f(our_rc_file, std::ios::binary);
if(f.is_open())
{
f.write(buf.base, buf.cur - buf.base);
return true;
}
}
return false;
}
void llarp_router::ForEachLink(std::function<void(llarp_link *)> visitor) {
llarp::router_links *cur = &links;
do {
@ -66,15 +116,48 @@ bool llarp_configure_router(struct llarp_router *router,
iter.user = router;
iter.visit = llarp::router_iter_config;
llarp_config_iter(conf, &iter);
return router->Ready();
if(!router->Ready()) return false;
return router->EnsureIdentity();
}
void llarp_run_router(struct llarp_router *router) {
llarp_logic * logic = router->logic;
router->ForEachLink([logic](llarp_link *link) {
int result = link->start_link(link, logic);
if (result == -1) printf("link %s failed to start\n", link->name());
// zero out router contact
llarp::Zero(&router->rc, sizeof(llarp_rc));
// fill our address list
router->rc.addrs = llarp_ai_list_new(router->mem);
router->ForEachLink([router](llarp_link *link) {
llarp_ai addr;
link->get_our_address(link, &addr);
llarp_ai_list_pushback(router->rc.addrs, addr);
});
// set public key
memcpy(router->rc.pubkey, router->pubkey(), 32);
// sign router contact
llarp_buffer_t signbuf;
char buf[MAX_RC_SIZE];
signbuf.base = buf;
signbuf.cur = buf;
signbuf.sz = sizeof(buf);
// encode
if(llarp_rc_bencode(&router->rc, &signbuf))
{
// sign
signbuf.sz = signbuf.cur - signbuf.base;
router->crypto.sign(router->rc.signature, router->identity, signbuf);
if(router->SaveRC())
{
printf("saved router contact\n");
llarp_logic * logic = router->logic;
router->ForEachLink([logic](llarp_link *link) {
int result = link->start_link(link, logic);
if (result == -1) printf("link %s failed to start\n", link->name());
});
return;
}
}
printf("failed to generate rc\n");
}
void llarp_stop_router(struct llarp_router *router) {
@ -113,7 +196,7 @@ void router_iter_config(llarp_config_iterator *iter, const char *section,
proto = std::atoi(val);
}
struct llarp_link *link;
struct llarp_link *link = nullptr;
if (StrEq(section, "iwp-links"))
{
link = llarp::Alloc<llarp_link>(self->mem);
@ -124,10 +207,28 @@ void router_iter_config(llarp_config_iterator *iter, const char *section,
.crypto = &self->crypto,
.logic = self->logic,
.cryptoworker = self->tp,
.keyfile=self->transport_keyfile,
.keyfile = self->transport_keyfile.c_str(),
};
iwp_link_init(link, args, &self->muxer);
}
else if (StrEq(section, "iwp-connect"))
{
std::error_code ec;
if(fs::exists(val, ec))
self->connect.try_emplace(key, val);
else
printf("cannot read %s\n", val);
return;
}
else if (StrEq(section, "router"))
{
if(StrEq(key, "contact-file"))
{
self->our_rc_file = val;
printf("storing signed rc at %s\n", self->our_rc_file.c_str());
}
return;
}
else
return;

@ -2,9 +2,12 @@
#define LLARP_ROUTER_HPP
#include <llarp/link.h>
#include <llarp/router.h>
#include <llarp/router_contact.h>
#include <functional>
#include <map>
#include "mem.hpp"
#include "fs.hpp"
namespace llarp {
struct router_links {
@ -16,8 +19,21 @@ struct router_links {
struct llarp_router {
bool ready;
const char * transport_keyfile = "transport.key";
const char * transport_certfile = "transport.pem";
// transient iwp encryption key
fs::path transport_keyfile = "transport.key";
// nodes to connect to on startup
std::map<std::string, fs::path> connect;
// long term identity key
fs::path ident_keyfile = "identity.key";
// path to write our self signed rc to
fs::path our_rc_file = "rc.signed";
llarp_rc rc;
llarp_ev_loop * netloop;
llarp_threadpool *tp;
llarp_logic * logic;
@ -26,6 +42,7 @@ struct llarp_router {
llarp_msg_muxer muxer;
llarp_path_context *paths;
llarp_alloc * mem;
llarp_seckey_t identity;
llarp_router(llarp_alloc * mem);
~llarp_router();
@ -37,6 +54,11 @@ struct llarp_router {
void Close();
bool Ready();
bool EnsureIdentity();
bool SaveRC();
uint8_t * pubkey() { return llarp_seckey_topublic(identity); }
};
#endif

@ -77,9 +77,32 @@ bool llarp_rc_bdecode(struct llarp_alloc * mem, struct llarp_rc * rc, llarp_buff
return bdecode_read_dict(buff, &r);
}
bool llarp_rc_verify_sig(struct llarp_rc * rc)
bool llarp_rc_verify_sig(struct llarp_crypto * crypto, struct llarp_rc * rc)
{
return false;
bool result = false;
llarp_sig_t sig;
char tmp[MAX_RC_SIZE];
llarp_buffer_t buf;
buf.base = tmp;
buf.cur = tmp;
buf.sz = sizeof(tmp);
// copy sig
memcpy(sig, rc->signature, sizeof(llarp_sig_t));
// zero sig
memset(rc->signature, 0, sizeof(llarp_sig_t));
// bencode
if(llarp_rc_bencode(rc, &buf))
{
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// verify
result = crypto->verify(rc->pubkey, buf, sig);
// restore sig
memcpy(rc->signature, sig, sizeof(llarp_sig_t));
}
return result;
}
bool llarp_rc_bencode(struct llarp_rc *rc, llarp_buffer_t *buff) {

Loading…
Cancel
Save