mirror of
https://github.com/oxen-io/lokinet.git
synced 2024-11-11 07:10:36 +00:00
Merge branch 'master' of ssh://github.com/loki-project/loki-network
This commit is contained in:
commit
6b9900de4f
@ -227,6 +227,8 @@ if(${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(LIB_PLATFORM_SRC
|
set(LIB_PLATFORM_SRC
|
||||||
|
# string stuff
|
||||||
|
llarp/str.cpp
|
||||||
# for outpug
|
# for outpug
|
||||||
llarp/logger.cpp
|
llarp/logger.cpp
|
||||||
# needed for threading
|
# needed for threading
|
||||||
@ -320,7 +322,6 @@ set(LIB_SRC
|
|||||||
llarp/buffer.cpp
|
llarp/buffer.cpp
|
||||||
llarp/config.cpp
|
llarp/config.cpp
|
||||||
llarp/context.cpp
|
llarp/context.cpp
|
||||||
llarp/crypto_async.cpp
|
|
||||||
llarp/crypto_libsodium.cpp
|
llarp/crypto_libsodium.cpp
|
||||||
llarp/dht.cpp
|
llarp/dht.cpp
|
||||||
llarp/dns.cpp
|
llarp/dns.cpp
|
||||||
|
@ -1,229 +0,0 @@
|
|||||||
#ifndef LLARP_CRYPTO_ASYNC_H_
|
|
||||||
#define LLARP_CRYPTO_ASYNC_H_
|
|
||||||
#include <llarp/crypto.h>
|
|
||||||
#include <llarp/ev.h>
|
|
||||||
#include <llarp/logic.h>
|
|
||||||
#include <llarp/threadpool.h>
|
|
||||||
#include <llarp/time.h>
|
|
||||||
|
|
||||||
/**
|
|
||||||
* crypto_async.h
|
|
||||||
*
|
|
||||||
* asynchronous crypto functions
|
|
||||||
*/
|
|
||||||
|
|
||||||
/// context for doing asynchronous cryptography for iwp
|
|
||||||
/// with a worker threadpool
|
|
||||||
/// defined in crypto_async.cpp
|
|
||||||
struct llarp_async_iwp;
|
|
||||||
|
|
||||||
/// allocator
|
|
||||||
/// use crypto as cryptograph implementation
|
|
||||||
/// use logic as the callback handler thread
|
|
||||||
/// use worker as threadpool that does the heavy lifting
|
|
||||||
struct llarp_async_iwp *
|
|
||||||
llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic,
|
|
||||||
struct llarp_threadpool *worker);
|
|
||||||
|
|
||||||
/// deallocator
|
|
||||||
void
|
|
||||||
llarp_async_iwp_free(struct llarp_async_iwp *iwp);
|
|
||||||
|
|
||||||
struct iwp_async_keygen;
|
|
||||||
|
|
||||||
/// define functor for keygen
|
|
||||||
typedef void (*iwp_keygen_hook)(struct iwp_async_keygen *);
|
|
||||||
|
|
||||||
/// key generation request
|
|
||||||
struct iwp_async_keygen
|
|
||||||
{
|
|
||||||
/// internal wire protocol async configuration
|
|
||||||
struct llarp_async_iwp *iwp;
|
|
||||||
/// a pointer to pass ourself to thread worker
|
|
||||||
void *user;
|
|
||||||
/// destination key buffer
|
|
||||||
uint8_t *keybuf;
|
|
||||||
/// result handler callback
|
|
||||||
iwp_keygen_hook hook;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// generate an encryption keypair asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_keygen(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_keygen *keygen);
|
|
||||||
|
|
||||||
struct iwp_async_intro;
|
|
||||||
|
|
||||||
/// iwp_async_intro functor
|
|
||||||
typedef void (*iwp_intro_hook)(struct iwp_async_intro *);
|
|
||||||
|
|
||||||
/// iwp_async_intro request
|
|
||||||
struct iwp_async_intro
|
|
||||||
{
|
|
||||||
struct llarp_async_iwp *iwp;
|
|
||||||
void *user;
|
|
||||||
uint8_t *buf;
|
|
||||||
size_t sz;
|
|
||||||
/// nonce paramter
|
|
||||||
uint8_t nonce[32];
|
|
||||||
/// remote public key
|
|
||||||
uint8_t remote_pubkey[32];
|
|
||||||
/// local private key
|
|
||||||
uint8_t secretkey[64];
|
|
||||||
/// callback
|
|
||||||
iwp_intro_hook hook;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// asynchronously generate an intro packet
|
|
||||||
void
|
|
||||||
iwp_call_async_gen_intro(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_intro *intro);
|
|
||||||
|
|
||||||
/// asynchronously verify an intro packet
|
|
||||||
void
|
|
||||||
iwp_call_async_verify_intro(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_intro *info);
|
|
||||||
|
|
||||||
struct iwp_async_introack;
|
|
||||||
|
|
||||||
/// introduction acknowledgement functor
|
|
||||||
typedef void (*iwp_introack_hook)(struct iwp_async_introack *);
|
|
||||||
|
|
||||||
/// introduction acknowledgement request
|
|
||||||
struct iwp_async_introack
|
|
||||||
{
|
|
||||||
struct llarp_async_iwp *iwp;
|
|
||||||
void *user;
|
|
||||||
uint8_t *buf;
|
|
||||||
size_t sz;
|
|
||||||
/// nonce paramter
|
|
||||||
uint8_t *nonce;
|
|
||||||
/// token paramter
|
|
||||||
uint8_t *token;
|
|
||||||
/// remote public key
|
|
||||||
uint8_t *remote_pubkey;
|
|
||||||
/// local private key
|
|
||||||
uint8_t *secretkey;
|
|
||||||
/// callback
|
|
||||||
iwp_introack_hook hook;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// generate introduction acknowledgement packet asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_gen_introack(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_introack *introack);
|
|
||||||
|
|
||||||
/// verify introduction acknowledgement packet asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_verify_introack(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_introack *introack);
|
|
||||||
|
|
||||||
struct iwp_async_session_start;
|
|
||||||
|
|
||||||
/// start session functor
|
|
||||||
typedef void (*iwp_session_start_hook)(struct iwp_async_session_start *);
|
|
||||||
|
|
||||||
/// start session request
|
|
||||||
struct iwp_async_session_start
|
|
||||||
{
|
|
||||||
struct llarp_async_iwp *iwp;
|
|
||||||
void *user;
|
|
||||||
uint8_t *buf;
|
|
||||||
size_t sz;
|
|
||||||
/// nonce parameter
|
|
||||||
uint8_t *nonce;
|
|
||||||
/// token parameter
|
|
||||||
uint8_t *token;
|
|
||||||
/// memory to write session key to
|
|
||||||
uint8_t *sessionkey;
|
|
||||||
/// local secrkey key
|
|
||||||
uint8_t *secretkey;
|
|
||||||
/// remote public encryption key
|
|
||||||
uint8_t *remote_pubkey;
|
|
||||||
/// result callback handler
|
|
||||||
iwp_session_start_hook hook;
|
|
||||||
};
|
|
||||||
|
|
||||||
/// generate session start packet asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_gen_session_start(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_session_start *start);
|
|
||||||
|
|
||||||
/// verify session start packet asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_session_start *start);
|
|
||||||
|
|
||||||
struct iwp_async_frame;
|
|
||||||
|
|
||||||
/// internal wire protocol frame request
|
|
||||||
typedef void (*iwp_async_frame_hook)(struct iwp_async_frame *);
|
|
||||||
|
|
||||||
struct iwp_async_frame
|
|
||||||
{
|
|
||||||
/// true if decryption succeded
|
|
||||||
bool success;
|
|
||||||
/// timestamp for CoDel
|
|
||||||
llarp_time_t created;
|
|
||||||
struct llarp_async_iwp *iwp;
|
|
||||||
/// a pointer to pass ourself
|
|
||||||
void *user;
|
|
||||||
/// current session key
|
|
||||||
byte_t *sessionkey;
|
|
||||||
/// size of the frame
|
|
||||||
size_t sz;
|
|
||||||
/// result handler
|
|
||||||
iwp_async_frame_hook hook;
|
|
||||||
/// memory holding the entire frame
|
|
||||||
byte_t buf[1500];
|
|
||||||
};
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
struct FramePutTime
|
|
||||||
{
|
|
||||||
void
|
|
||||||
operator()(iwp_async_frame &frame) const
|
|
||||||
{
|
|
||||||
frame.created = llarp_time_now_ms();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
struct FrameGetTime
|
|
||||||
{
|
|
||||||
llarp_time_t
|
|
||||||
operator()(const iwp_async_frame &frame) const
|
|
||||||
{
|
|
||||||
return frame.created;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
struct FrameCompareTime
|
|
||||||
{
|
|
||||||
bool
|
|
||||||
operator()(const iwp_async_frame &left, const iwp_async_frame &right) const
|
|
||||||
{
|
|
||||||
return left.created < right.created;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/// synchronously decrypt a frame
|
|
||||||
bool
|
|
||||||
iwp_decrypt_frame(struct iwp_async_frame *frame);
|
|
||||||
|
|
||||||
/// synchronosuly encrypt a frame
|
|
||||||
bool
|
|
||||||
iwp_encrypt_frame(struct iwp_async_frame *frame);
|
|
||||||
|
|
||||||
/// decrypt iwp frame asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_frame_decrypt(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_frame *frame);
|
|
||||||
|
|
||||||
/// encrypt iwp frame asynchronously
|
|
||||||
void
|
|
||||||
iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_frame *frame);
|
|
||||||
|
|
||||||
#endif
|
|
@ -323,7 +323,7 @@ namespace llarp
|
|||||||
|
|
||||||
/// inform all watches for key of values found
|
/// inform all watches for key of values found
|
||||||
void
|
void
|
||||||
Inform(const TXOwner& from, const K& key, std::vector< V > values,
|
Inform(TXOwner from, K key, std::vector< V > values,
|
||||||
bool sendreply = false, bool removeTimeouts = true)
|
bool sendreply = false, bool removeTimeouts = true)
|
||||||
{
|
{
|
||||||
auto range = waiting.equal_range(key);
|
auto range = waiting.equal_range(key);
|
||||||
@ -339,14 +339,13 @@ namespace llarp
|
|||||||
{
|
{
|
||||||
txitr->second->SendReply();
|
txitr->second->SendReply();
|
||||||
tx.erase(txitr);
|
tx.erase(txitr);
|
||||||
|
itr = waiting.erase(itr);
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
++itr;
|
++itr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sendreply)
|
|
||||||
waiting.erase(key);
|
|
||||||
|
|
||||||
if(removeTimeouts)
|
if(removeTimeouts)
|
||||||
timeouts.erase(key);
|
timeouts.erase(key);
|
||||||
}
|
}
|
||||||
|
17
include/llarp/str.hpp
Normal file
17
include/llarp/str.hpp
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
#ifndef LLARP_STR_HPP
|
||||||
|
#define LLARP_STR_HPP
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
StrEq(const char *s1, const char *s2);
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsFalseValue(const char *str);
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsTrueValue(const char *str);
|
||||||
|
|
||||||
|
} // namespace llarp
|
||||||
|
|
||||||
|
#endif
|
@ -165,6 +165,7 @@ extern "C"
|
|||||||
#endif
|
#endif
|
||||||
f << "ifname=lokitun0" << std::endl;
|
f << "ifname=lokitun0" << std::endl;
|
||||||
f << "ifaddr=10.200.0.1/16" << std::endl;
|
f << "ifaddr=10.200.0.1/16" << std::endl;
|
||||||
|
f << "enabled=true" << std::endl;
|
||||||
f << std::endl << std::endl;
|
f << std::endl << std::endl;
|
||||||
|
|
||||||
f << "# dns provider configuration section" << std::endl;
|
f << "# dns provider configuration section" << std::endl;
|
||||||
|
@ -1,574 +0,0 @@
|
|||||||
#include <llarp/crypto_async.h>
|
|
||||||
#include <llarp/mem.h>
|
|
||||||
#include <llarp/router_contact.hpp>
|
|
||||||
#include <string.h>
|
|
||||||
#include <llarp/crypto.hpp>
|
|
||||||
#include <llarp/router_id.hpp>
|
|
||||||
#include "buffer.hpp"
|
|
||||||
#include "logger.hpp"
|
|
||||||
#include "mem.hpp"
|
|
||||||
|
|
||||||
struct llarp_async_iwp
|
|
||||||
{
|
|
||||||
struct llarp_crypto *crypto;
|
|
||||||
struct llarp_logic *logic;
|
|
||||||
struct llarp_threadpool *worker;
|
|
||||||
};
|
|
||||||
|
|
||||||
namespace iwp
|
|
||||||
{
|
|
||||||
void
|
|
||||||
inform_intro(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_intro *intro = static_cast< iwp_async_intro * >(user);
|
|
||||||
intro->hook(intro);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gen_intro(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_intro *intro = static_cast< iwp_async_intro * >(user);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmp[68] = {0};
|
|
||||||
const char *hexname = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
|
|
||||||
intro->remote_pubkey, ftmp);
|
|
||||||
llarp::LogDebug("gen_intro remote_pubkey: ", hexname);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
llarp::SharedSecret sharedkey;
|
|
||||||
llarp_crypto *crypto = intro->iwp->crypto;
|
|
||||||
|
|
||||||
// S = TKE(a.k, b.k, n)
|
|
||||||
crypto->transport_dh_client(sharedkey, intro->remote_pubkey,
|
|
||||||
intro->secretkey, intro->nonce);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmpShared[68] = {0};
|
|
||||||
const char *hexShared =
|
|
||||||
llarp::HexEncode< llarp::SharedSecret, decltype(ftmpShared) >(
|
|
||||||
sharedkey, ftmpShared);
|
|
||||||
llarp::LogDebug("gen_intro sharedkey ", hexShared);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
byte_t tmp[64];
|
|
||||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
||||||
|
|
||||||
llarp::SymmNonce n;
|
|
||||||
// copy nonce
|
|
||||||
memcpy(n, intro->nonce, 32); // was 24 bytes
|
|
||||||
|
|
||||||
/*
|
|
||||||
char ftmpN[68] = {0};
|
|
||||||
const char *hexN =
|
|
||||||
llarp::HexEncode< llarp::SymmNonce, decltype(ftmpN) >(n, ftmpN);
|
|
||||||
llarp::LogDebug("gen_intro nonce ", hexN);
|
|
||||||
*/
|
|
||||||
|
|
||||||
// e_k = HS(b.k + n)
|
|
||||||
|
|
||||||
llarp::ShortHash e_k;
|
|
||||||
memcpy(tmp, intro->remote_pubkey, 32);
|
|
||||||
memcpy(tmp + 32, intro->nonce, 32);
|
|
||||||
crypto->shorthash(e_k, buf);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmpEk[68] = {0};
|
|
||||||
const char *hexEk =
|
|
||||||
llarp::HexEncode< llarp::ShortHash, decltype(ftmpEk) >(e_k, ftmpEk);
|
|
||||||
llarp::LogDebug("gen_intro e_k ", hexEk, " used ", strlen(hexEk));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// put nonce
|
|
||||||
memcpy(intro->buf + 32, intro->nonce, 32);
|
|
||||||
|
|
||||||
// e = SE(a.k, e_k, n[0:24])
|
|
||||||
memcpy(intro->buf + 64, llarp::seckey_topublic(intro->secretkey), 32);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmpSk[68] = {0};
|
|
||||||
const char *hexSk = llarp::HexEncode< llarp::PubKey, decltype(ftmpSk) >(
|
|
||||||
intro->secretkey, ftmpSk);
|
|
||||||
llarp::LogDebug("gen_intro SK ", hexSk);
|
|
||||||
|
|
||||||
char ftmpSkPub[68] = {0};
|
|
||||||
const char *hexSkPub =
|
|
||||||
llarp::HexEncode< llarp::PubKey, decltype(ftmpSkPub) >(
|
|
||||||
llarp::seckey_topublic(intro->secretkey), ftmpSkPub);
|
|
||||||
llarp::LogDebug("gen_intro SK pub ", hexSkPub);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
buf.base = intro->buf + 64;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = 32;
|
|
||||||
crypto->xchacha20(buf, e_k, intro->nonce);
|
|
||||||
|
|
||||||
// h = MDS( n + e + w0, S)
|
|
||||||
buf.base = intro->buf + 32;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = intro->sz - 32;
|
|
||||||
crypto->hmac(intro->buf, buf, sharedkey);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmpHmac[68] = {0}; // probably could be 65
|
|
||||||
const char *hexHmac = llarp::HexEncode< llarp::PubKey, decltype(ftmpHmac) >(
|
|
||||||
intro->buf, ftmpHmac);
|
|
||||||
llarp::LogDebug("gen_intro Hmac ", hexHmac);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// inform result
|
|
||||||
// intro->hook(intro);
|
|
||||||
llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
verify_intro(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_intro *intro = static_cast< iwp_async_intro * >(user);
|
|
||||||
auto crypto = intro->iwp->crypto;
|
|
||||||
llarp::SharedSecret sharedkey;
|
|
||||||
llarp::ShortHash e_K;
|
|
||||||
llarp::SharedSecret h;
|
|
||||||
byte_t tmp[64];
|
|
||||||
const auto OurPK = llarp::seckey_topublic(intro->secretkey);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmp[68] = {0};
|
|
||||||
const char *hexPk =
|
|
||||||
llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(OurPK, ftmp);
|
|
||||||
llarp::LogDebug("intro OurPK ", hexPk);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// e_k = HS(b.k + n)
|
|
||||||
memcpy(tmp, OurPK, 32);
|
|
||||||
memcpy(tmp + 32, intro->nonce, 32);
|
|
||||||
auto buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
||||||
crypto->shorthash(e_K, buf);
|
|
||||||
|
|
||||||
buf.base = intro->remote_pubkey;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = 32;
|
|
||||||
|
|
||||||
// was using remote_pubkey directly (use buffer wrapper? directly?)
|
|
||||||
// memcpy(intro->remote_pubkey, intro->buf + 64, 32);
|
|
||||||
memcpy(buf.base, intro->buf + 64, 32);
|
|
||||||
|
|
||||||
crypto->xchacha20(buf, e_K, intro->nonce);
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
llarp::LogInfo("handshake from ", llarp::RouterID(intro->remote_pubkey));
|
|
||||||
|
|
||||||
char ftmp2[68] = {0};
|
|
||||||
const char *hexRemotePK = llarp::HexEncode< llarp::PubKey, decltype(ftmp) >(
|
|
||||||
intro->remote_pubkey, ftmp2);
|
|
||||||
llarp::LogDebug("intro remote_pubkey ", hexRemotePK);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// S = TKE(a.k, b.k, n)
|
|
||||||
crypto->transport_dh_server(sharedkey, intro->remote_pubkey,
|
|
||||||
intro->secretkey, intro->nonce);
|
|
||||||
|
|
||||||
#ifdef neuroCryptoDebug
|
|
||||||
char ftmpShared[68] = {0};
|
|
||||||
const char *hexShared =
|
|
||||||
llarp::HexEncode< llarp::PubKey, decltype(ftmpShared) >(sharedkey,
|
|
||||||
ftmpShared);
|
|
||||||
llarp::LogDebug("intro sharedkey ", hexShared);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// h = MDS( n + e + w2, S)
|
|
||||||
buf.base = intro->buf + 32;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = intro->sz - 32;
|
|
||||||
crypto->hmac(h, buf, sharedkey);
|
|
||||||
if(memcmp(h, intro->buf, 32))
|
|
||||||
{
|
|
||||||
llarp::LogWarn("intro HMAC failure");
|
|
||||||
// hmac fail
|
|
||||||
delete[] intro->buf;
|
|
||||||
intro->buf = nullptr;
|
|
||||||
}
|
|
||||||
// inform result
|
|
||||||
llarp_logic_queue_job(intro->iwp->logic, {intro, &inform_intro});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
inform_introack(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
|
|
||||||
introack->hook(introack);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
verify_introack(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
|
|
||||||
auto crypto = introack->iwp->crypto;
|
|
||||||
auto logic = introack->iwp->logic;
|
|
||||||
|
|
||||||
llarp::ShortHash digest;
|
|
||||||
llarp::SharedSecret sharedkey;
|
|
||||||
|
|
||||||
auto hmac = introack->buf;
|
|
||||||
auto body = introack->buf + 32;
|
|
||||||
const auto pubkey = introack->remote_pubkey;
|
|
||||||
auto secretkey = introack->secretkey;
|
|
||||||
auto nonce = introack->buf + 32;
|
|
||||||
auto token = introack->buf + 64;
|
|
||||||
size_t bodysz = introack->sz - 32;
|
|
||||||
llarp_buffer_t buf;
|
|
||||||
buf.base = body;
|
|
||||||
buf.cur = body;
|
|
||||||
buf.sz = bodysz;
|
|
||||||
|
|
||||||
// S = TKE(a.k, b.k, n)
|
|
||||||
crypto->transport_dh_client(sharedkey, pubkey, secretkey, nonce);
|
|
||||||
|
|
||||||
// h = MDS(n + x + w1, S)
|
|
||||||
crypto->hmac(digest, buf, sharedkey);
|
|
||||||
|
|
||||||
if(!llarp_eq(digest, hmac, 32))
|
|
||||||
{
|
|
||||||
// fail to verify hmac
|
|
||||||
introack->buf = nullptr;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
buf.base = token;
|
|
||||||
buf.sz = 32;
|
|
||||||
// token = SD(S, x, n[0:24])
|
|
||||||
crypto->xchacha20(buf, sharedkey, nonce);
|
|
||||||
// copy token
|
|
||||||
memcpy(introack->token, token, 32);
|
|
||||||
}
|
|
||||||
// introack->hook(introack);
|
|
||||||
llarp_logic_queue_job(logic, {introack, &inform_introack});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gen_introack(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_introack *introack = static_cast< iwp_async_introack * >(user);
|
|
||||||
llarp::SharedSecret sharedkey;
|
|
||||||
auto crypto = introack->iwp->crypto;
|
|
||||||
const auto pubkey = introack->remote_pubkey;
|
|
||||||
auto secretkey = introack->secretkey;
|
|
||||||
auto nonce = introack->nonce;
|
|
||||||
// S = TKE(a.k, b.k, n)
|
|
||||||
crypto->transport_dh_server(sharedkey, pubkey, secretkey, nonce);
|
|
||||||
|
|
||||||
// x = SE(S, token, n[0:24])
|
|
||||||
llarp_buffer_t buf;
|
|
||||||
buf.base = introack->buf + 64;
|
|
||||||
buf.sz = 32;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
memcpy(buf.base, introack->token, 32);
|
|
||||||
crypto->xchacha20(buf, sharedkey, nonce);
|
|
||||||
|
|
||||||
// h = MDS(n + x + w1, S)
|
|
||||||
buf.base = introack->buf + 32;
|
|
||||||
buf.sz = introack->sz - 32;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
crypto->hmac(introack->buf, buf, sharedkey);
|
|
||||||
// introack->hook(introack);
|
|
||||||
llarp_logic_queue_job(introack->iwp->logic, {introack, &inform_introack});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
inform_session_start(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_session_start *session =
|
|
||||||
static_cast< iwp_async_session_start * >(user);
|
|
||||||
session->hook(session);
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
gen_session_start(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_session_start *session =
|
|
||||||
static_cast< iwp_async_session_start * >(user);
|
|
||||||
auto crypto = session->iwp->crypto;
|
|
||||||
auto logic = session->iwp->logic;
|
|
||||||
|
|
||||||
auto dh = crypto->transport_dh_client;
|
|
||||||
auto shorthash = crypto->shorthash;
|
|
||||||
auto hmac = crypto->hmac;
|
|
||||||
auto encrypt = crypto->xchacha20;
|
|
||||||
|
|
||||||
// auto logic = session->iwp->logic;
|
|
||||||
auto a_sK = session->secretkey;
|
|
||||||
const auto b_K = session->remote_pubkey;
|
|
||||||
auto N = session->nonce;
|
|
||||||
auto token = session->token;
|
|
||||||
auto K = session->sessionkey;
|
|
||||||
|
|
||||||
llarp::SharedSecret e_K;
|
|
||||||
llarp::ShortHash T;
|
|
||||||
|
|
||||||
byte_t tmp[64];
|
|
||||||
llarp_buffer_t buf = llarp::StackBuffer< decltype(tmp) >(tmp);
|
|
||||||
|
|
||||||
// T = HS(token + n)
|
|
||||||
memcpy(tmp, token, 32);
|
|
||||||
memcpy(tmp + 32, N, 32);
|
|
||||||
shorthash(T, buf);
|
|
||||||
|
|
||||||
// e_K = TKE(a.k, b.k, n)
|
|
||||||
dh(e_K, b_K, a_sK, N);
|
|
||||||
// K = TKE(a.k, b.k, T)
|
|
||||||
dh(K, b_K, a_sK, T);
|
|
||||||
|
|
||||||
// x = SE(e_K, token, n[0:24])
|
|
||||||
buf.base = (session->buf + 64);
|
|
||||||
buf.sz = 32;
|
|
||||||
memcpy(buf.base, token, 32);
|
|
||||||
encrypt(buf, e_K, N);
|
|
||||||
|
|
||||||
// h = MDS(n + x + w2, e_K)
|
|
||||||
buf.base = (session->buf + 32);
|
|
||||||
buf.sz = session->sz - 32;
|
|
||||||
hmac(session->buf, buf, e_K);
|
|
||||||
// session->hook(session);
|
|
||||||
llarp_logic_queue_job(logic, {session, &inform_session_start});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
verify_session_start(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_session_start *session =
|
|
||||||
static_cast< iwp_async_session_start * >(user);
|
|
||||||
// possible repeat job
|
|
||||||
if(session->buf == nullptr)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto crypto = session->iwp->crypto;
|
|
||||||
auto logic = session->iwp->logic;
|
|
||||||
|
|
||||||
auto dh = crypto->transport_dh_server;
|
|
||||||
auto shorthash = crypto->shorthash;
|
|
||||||
auto hmac = crypto->hmac;
|
|
||||||
auto decrypt = crypto->xchacha20;
|
|
||||||
|
|
||||||
auto b_sK = session->secretkey;
|
|
||||||
auto a_K = session->remote_pubkey;
|
|
||||||
auto N = session->nonce;
|
|
||||||
auto token = session->token;
|
|
||||||
auto K = session->sessionkey;
|
|
||||||
|
|
||||||
llarp::SharedSecret e_K;
|
|
||||||
llarp::ShortHash T;
|
|
||||||
|
|
||||||
byte_t tmp[64];
|
|
||||||
|
|
||||||
llarp_buffer_t buf;
|
|
||||||
|
|
||||||
// e_K = TKE(a.k, b.k, N)
|
|
||||||
dh(e_K, a_K, b_sK, N);
|
|
||||||
// h = MDS( n + x + w2, e_K)
|
|
||||||
buf.base = session->buf + 32;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = session->sz - 32;
|
|
||||||
hmac(tmp, buf, e_K);
|
|
||||||
if(memcmp(tmp, session->buf, 32) == 0)
|
|
||||||
{
|
|
||||||
// hmac good
|
|
||||||
buf.base = session->buf + 64;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = 32;
|
|
||||||
// token = SD(e_K, x, n[0:24])
|
|
||||||
decrypt(buf, e_K, N);
|
|
||||||
// ensure it's the same token
|
|
||||||
if(memcmp(buf.base, token, 32) == 0)
|
|
||||||
{
|
|
||||||
// T = HS(token + n)
|
|
||||||
memcpy(tmp, token, 32);
|
|
||||||
memcpy(tmp + 32, N, 32);
|
|
||||||
buf.base = tmp;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = sizeof(tmp);
|
|
||||||
shorthash(T, buf);
|
|
||||||
// K = TKE(a.k, b.k, T)
|
|
||||||
dh(K, a_K, b_sK, T);
|
|
||||||
}
|
|
||||||
else // token missmatch
|
|
||||||
{
|
|
||||||
session->buf = nullptr;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else // hmac fail
|
|
||||||
session->buf = nullptr;
|
|
||||||
// session->hook(session);
|
|
||||||
llarp_logic_queue_job(logic, {session, &inform_session_start});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
inform_frame_done(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_frame *frame = static_cast< iwp_async_frame * >(user);
|
|
||||||
frame->hook(frame);
|
|
||||||
delete frame;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
hmac_then_decrypt(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_frame *frame = static_cast< iwp_async_frame * >(user);
|
|
||||||
iwp_decrypt_frame(frame);
|
|
||||||
// inform result
|
|
||||||
llarp_logic_queue_job(frame->iwp->logic, {frame, &inform_frame_done});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
encrypt_then_hmac(void *user)
|
|
||||||
{
|
|
||||||
iwp_async_frame *frame = static_cast< iwp_async_frame * >(user);
|
|
||||||
iwp_encrypt_frame(frame);
|
|
||||||
// call result RIGHT HERE
|
|
||||||
frame->hook(frame);
|
|
||||||
delete frame;
|
|
||||||
}
|
|
||||||
} // namespace iwp
|
|
||||||
|
|
||||||
bool
|
|
||||||
iwp_decrypt_frame(struct iwp_async_frame *frame)
|
|
||||||
{
|
|
||||||
auto crypto = frame->iwp->crypto;
|
|
||||||
byte_t *hmac = frame->buf;
|
|
||||||
byte_t *nonce = frame->buf + 32;
|
|
||||||
byte_t *body = frame->buf + 64;
|
|
||||||
|
|
||||||
llarp::ShortHash digest;
|
|
||||||
|
|
||||||
llarp_buffer_t buf;
|
|
||||||
buf.base = nonce;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = frame->sz - 32;
|
|
||||||
|
|
||||||
// h = MDS(n + x, S)
|
|
||||||
crypto->hmac(digest, buf, frame->sessionkey);
|
|
||||||
// check hmac
|
|
||||||
frame->success = memcmp(digest, hmac, 32) == 0;
|
|
||||||
if(!frame->success)
|
|
||||||
{
|
|
||||||
// [", digest, "] vs [", hmac, "]
|
|
||||||
llarp::LogWarn("crypto_async::iwp_decrypt_frame failed to decrypt");
|
|
||||||
//} else {
|
|
||||||
// llarp::Debug("crypto_async::iwp_decrypt_frame decrypted");
|
|
||||||
}
|
|
||||||
// x = SE(S, p, n[0:24])
|
|
||||||
buf.base = body;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = frame->sz - 64;
|
|
||||||
crypto->xchacha20(buf, frame->sessionkey, nonce);
|
|
||||||
|
|
||||||
return frame->success;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool
|
|
||||||
iwp_encrypt_frame(struct iwp_async_frame *frame)
|
|
||||||
{
|
|
||||||
auto crypto = frame->iwp->crypto;
|
|
||||||
byte_t *hmac = frame->buf;
|
|
||||||
byte_t *nonce = frame->buf + 32;
|
|
||||||
byte_t *body = frame->buf + 64;
|
|
||||||
|
|
||||||
llarp_buffer_t buf;
|
|
||||||
buf.base = body;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = frame->sz - 64;
|
|
||||||
|
|
||||||
// randomize N
|
|
||||||
crypto->randbytes(nonce, 32);
|
|
||||||
// x = SE(S, p, n[0:24])
|
|
||||||
crypto->xchacha20(buf, frame->sessionkey, nonce);
|
|
||||||
// h = MDS(n + x, S)
|
|
||||||
buf.base = nonce;
|
|
||||||
buf.cur = buf.base;
|
|
||||||
buf.sz = frame->sz - 32;
|
|
||||||
crypto->hmac(hmac, buf, frame->sessionkey);
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_gen_intro(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_intro *intro)
|
|
||||||
{
|
|
||||||
intro->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {intro, &iwp::gen_intro});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_verify_introack(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_introack *introack)
|
|
||||||
{
|
|
||||||
introack->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {introack, &iwp::verify_introack});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_gen_session_start(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_session_start *session)
|
|
||||||
{
|
|
||||||
session->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {session, &iwp::gen_session_start});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_verify_intro(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_intro *intro)
|
|
||||||
{
|
|
||||||
intro->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {intro, &iwp::verify_intro});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_gen_introack(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_introack *introack)
|
|
||||||
{
|
|
||||||
introack->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {introack, &iwp::gen_introack});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_frame_decrypt(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_frame *frame)
|
|
||||||
{
|
|
||||||
frame->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {frame, &iwp::hmac_then_decrypt});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_frame_encrypt(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_frame *frame)
|
|
||||||
{
|
|
||||||
frame->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker, {frame, &iwp::encrypt_then_hmac});
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
iwp_call_async_verify_session_start(struct llarp_async_iwp *iwp,
|
|
||||||
struct iwp_async_session_start *session)
|
|
||||||
{
|
|
||||||
session->iwp = iwp;
|
|
||||||
llarp_threadpool_queue_job(iwp->worker,
|
|
||||||
{session, &iwp::verify_session_start});
|
|
||||||
}
|
|
||||||
|
|
||||||
struct llarp_async_iwp *
|
|
||||||
llarp_async_iwp_new(struct llarp_crypto *crypto, struct llarp_logic *logic,
|
|
||||||
struct llarp_threadpool *worker)
|
|
||||||
{
|
|
||||||
llarp_async_iwp *iwp = new llarp_async_iwp;
|
|
||||||
if(iwp)
|
|
||||||
{
|
|
||||||
iwp->crypto = crypto;
|
|
||||||
iwp->logic = logic;
|
|
||||||
iwp->worker = worker;
|
|
||||||
}
|
|
||||||
return iwp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
llarp_async_iwp_free(struct llarp_async_iwp *iwp)
|
|
||||||
{
|
|
||||||
delete iwp;
|
|
||||||
}
|
|
@ -1,4 +1,4 @@
|
|||||||
#include <llarp/crypto_async.h>
|
#include <llarp/logic.h>
|
||||||
#include <llarp/nodedb.hpp>
|
#include <llarp/nodedb.hpp>
|
||||||
#include <llarp/router_contact.hpp>
|
#include <llarp/router_contact.hpp>
|
||||||
|
|
||||||
|
@ -861,7 +861,8 @@ llarp_router::InitOutboundLink()
|
|||||||
bool
|
bool
|
||||||
llarp_router::CreateDefaultHiddenService()
|
llarp_router::CreateDefaultHiddenService()
|
||||||
{
|
{
|
||||||
return hiddenServiceContext.AddDefaultEndpoint(defaultIfAddr, defaultIfName);
|
return disableDefaultEndpoint
|
||||||
|
|| hiddenServiceContext.AddDefaultEndpoint(defaultIfAddr, defaultIfName);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@ -1073,6 +1074,10 @@ namespace llarp
|
|||||||
{
|
{
|
||||||
self->defaultIfAddr = val;
|
self->defaultIfAddr = val;
|
||||||
}
|
}
|
||||||
|
if(StrEq(key, "enabled"))
|
||||||
|
{
|
||||||
|
self->disableDefaultEndpoint = IsFalseValue(val);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if(StrEq(section, "services"))
|
else if(StrEq(section, "services"))
|
||||||
{
|
{
|
||||||
|
@ -95,11 +95,11 @@ struct llarp_router
|
|||||||
|
|
||||||
std::string defaultIfAddr = "10.200.0.1/24";
|
std::string defaultIfAddr = "10.200.0.1/24";
|
||||||
std::string defaultIfName = "lokitun0";
|
std::string defaultIfName = "lokitun0";
|
||||||
|
bool disableDefaultEndpoint = false;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
CreateDefaultHiddenService();
|
CreateDefaultHiddenService();
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr< llarp::ILinkLayer > outboundLink;
|
std::unique_ptr< llarp::ILinkLayer > outboundLink;
|
||||||
std::vector< std::unique_ptr< llarp::ILinkLayer > > inboundLinks;
|
std::vector< std::unique_ptr< llarp::ILinkLayer > > inboundLinks;
|
||||||
|
|
||||||
|
39
llarp/str.cpp
Normal file
39
llarp/str.cpp
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
#include "str.hpp"
|
||||||
|
|
||||||
|
#include <cstring>
|
||||||
|
#include <string>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
|
namespace llarp
|
||||||
|
{
|
||||||
|
bool
|
||||||
|
IsFalseValue(const char* str)
|
||||||
|
{
|
||||||
|
std::string value = str;
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(),
|
||||||
|
[](char ch) -> char { return std::tolower(ch); });
|
||||||
|
return value == "no" || value == "false" || value == "0";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
IsTrueValue(const char* str)
|
||||||
|
{
|
||||||
|
std::string value = str;
|
||||||
|
std::transform(value.begin(), value.end(), value.begin(),
|
||||||
|
[](char ch) -> char { return std::tolower(ch); });
|
||||||
|
return value == "yes" || value == "true" || value == "1";
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
StrEq(const char* s1, const char* s2)
|
||||||
|
{
|
||||||
|
size_t sz1 = strlen(s1);
|
||||||
|
size_t sz2 = strlen(s2);
|
||||||
|
if(sz1 == sz2)
|
||||||
|
{
|
||||||
|
return strncmp(s1, s2, sz1) == 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
} // namespace llarp
|
@ -1,22 +1 @@
|
|||||||
#ifndef LIBLLARP_STR_HPP
|
#include <llarp/str.hpp>
|
||||||
#define LIBLLARP_STR_HPP
|
|
||||||
#include <cstring>
|
|
||||||
|
|
||||||
namespace llarp
|
|
||||||
{
|
|
||||||
static bool
|
|
||||||
StrEq(const char *s1, const char *s2)
|
|
||||||
{
|
|
||||||
size_t sz1 = strlen(s1);
|
|
||||||
size_t sz2 = strlen(s2);
|
|
||||||
if(sz1 == sz2)
|
|
||||||
{
|
|
||||||
return strncmp(s1, s2, sz1) == 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace llarp
|
|
||||||
|
|
||||||
#endif
|
|
||||||
|
Loading…
Reference in New Issue
Block a user