Merge remote-tracking branch 'origin/master'

pull/631/head
Jeff Becker 5 years ago
commit 762a0c534f
No known key found for this signature in database
GPG Key ID: F357B3B42F6F9B05

@ -0,0 +1,60 @@
sudo: required
dist: xenial
os: linux
language: minimal
cache:
directories:
- contrib/depends/built
- contrib/depends/sdk-sources
- $HOME/.ccache
env:
global:
- MAKEJOBS=-j2
- CCACHE_SIZE=100M
- CCACHE_TEMPDIR=/tmp/.ccache-temp
- CCACHE_COMPRESS=1
- CCACHE_DIR=$HOME/.ccache
- BASE_OUTDIR=$TRAVIS_BUILD_DIR/out
- SDK_URL=https://bitcoincore.org/depends-sources/sdks
- DOCKER_PACKAGES="build-essential cmake git libcap-dev bsdmainutils curl git ca-certificates ccache"
matrix:
#- HOST=x86_64-w64-mingw32
- HOST=x86_64-unknown-linux-gnu
#- HOST=x86_64-apple-darwin11 OSX_SDK=10.12
install:
- env | grep -E '^(CCACHE_|DISPLAY|CONFIG_SHELL)' | tee /tmp/env
- if [[ $HOST = *-mingw32 ]]; then DOCKER_ADMIN="--cap-add SYS_ADMIN"; fi
- DOCKER_ID=$(docker run $DOCKER_ADMIN -idt --mount type=bind,src=$TRAVIS_BUILD_DIR,dst=$TRAVIS_BUILD_DIR --mount type=bind,src=$CCACHE_DIR,dst=$CCACHE_DIR -w $TRAVIS_BUILD_DIR --env-file /tmp/env ubuntu:18.04)
- DOCKER_EXEC="docker exec $DOCKER_ID"
- if [ -n "$DPKG_ADD_ARCH" ]; then $DOCKER_EXEC dpkg --add-architecture "$DPKG_ADD_ARCH" ; fi
- travis_retry $DOCKER_EXEC apt-get update
- travis_retry $DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade software-properties-common -qq $PACKAGES $DOCKER_PACKAGES
# - travis_retry $DOCKER_EXEC add-apt-repository ppa:ubuntu-toolchain-r/test
# - travis_retry $DOCKER_EXEC apt-get update
# - travis_retry $DOCKER_EXEC apt-get install --no-install-recommends --no-upgrade -qq gcc-6 g++-6
script:
- export TRAVIS_COMMIT_LOG=`git log --format=fuller -1`
- OUTDIR=$BASE_OUTDIR/$TRAVIS_PULL_REQUEST/$TRAVIS_JOB_NUMBER-$HOST
- if [ -z "$NO_DEPENDS" ]; then $DOCKER_EXEC ccache --max-size=$CCACHE_SIZE; fi
#- $DOCKER_EXEC bash -c "update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-6 60 --slave /usr/bin/g++ g++ /usr/bin/g++-6"
- $DOCKER_EXEC bash -c "mkdir build && cd build && cmake .. && make $MAKEJOBS && make test"
after_script:
- echo $TRAVIS_COMMIT_RANGE
- echo $TRAVIS_COMMIT_LOG
after_success:
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
- chmod +x send.sh
- ./send.sh success $WEBHOOK_URL
after_failure:
- wget https://raw.githubusercontent.com/DiscordHooks/travis-ci-discord-webhook/master/send.sh
- chmod +x send.sh
- ./send.sh failure $WEBHOOK_URL
notifications:
irc:
on_success: change
on_failure: change
channels:
- "chat.freenode.net#llarp"
nick: lokinet-ci
template:
- "%{result} | %{repository}#%{build_number} (%{commit} : %{author}) | Build details : %{build_url}"

@ -12,23 +12,23 @@ import os
import sys
import requests
from pylokinet import rc
from pylokinet import rc
lib_file = os.path.join(os.path.realpath('.'), 'liblokinet-shared.so')
def log(msg):
sys.stderr.write("lokinet: {}\n".format(msg))
sys.stderr.flush()
class LokiNET(threading.Thread):
lib = None
ctx = 0
failed = False
up = False
asRouter = True
def configure(self, lib, conf, ip=None, port=None, ifname=None, seedfile=None, lokid_host=None, lokid_port=None):
@ -43,7 +43,8 @@ class LokiNET(threading.Thread):
if self.lib.llarp_ensure_config(conf.encode('utf-8'), os.path.dirname(conf).encode('utf-8'), True, self.asRouter):
config = configparser.ConfigParser()
config.read(conf)
log('overwrite ip="{}" port="{}" ifname="{}" seedfile="{}" lokid=("{}", "{}")'.format(ip, port, ifname, seedfile, lokid_host, lokid_port))
log('overwrite ip="{}" port="{}" ifname="{}" seedfile="{}" lokid=("{}", "{}")'.format(
ip, port, ifname, seedfile, lokid_host, lokid_port))
if seedfile and lokid_host and lokid_port:
if not os.path.exists(seedfile):
log('cannot access service node seed at "{}"'.format(seedfile))
@ -66,8 +67,7 @@ class LokiNET(threading.Thread):
self.ctx = self.lib.llarp_main_init(conf.encode('utf-8'))
else:
return False
return self.lib.llarp_main_setup(self.ctx) == 0
return self.lib.llarp_main_setup(self.ctx, False) == 0
def inform_fail(self):
"""
@ -79,7 +79,7 @@ class LokiNET(threading.Thread):
def inform_up(self):
self.up = True
self._inform()
def _inform(self):
"""
inform waiter
@ -105,14 +105,16 @@ class LokiNET(threading.Thread):
self.inform_fail()
self.up = False
# self._up.release()
def close(self):
if self.lib and self.ctx:
self.lib.llarp_main_free(self.ctx)
def getconf(name, fallback=None):
return name in os.environ and os.environ[name] or fallback
def run_main(args):
seedfile = getconf("LOKI_SEED_FILE")
if seedfile is None:
@ -126,12 +128,12 @@ def run_main(args):
if root is None:
print("LOKINET_ROOT was not set")
return
rc_callback = getconf("LOKINET_SUBMIT_URL")
if rc_callback is None:
print("LOKINET_SUBMIT_URL was not set")
return
bootstrap = getconf("LOKINET_BOOTSTRAP_URL")
if bootstrap is None:
print("LOKINET_BOOTSTRAP_URL was not set")
@ -172,7 +174,7 @@ def run_main(args):
return
if loki.configure(lib, conf, ip, port, ifname, seedfile, lokid_host, lokid_port):
log("configured")
loki.start()
try:
log("waiting for spawn")
@ -187,7 +189,8 @@ def run_main(args):
log("submitting rc")
try:
with open(os.path.join(root, 'self.signed'), 'rb') as f:
r = requests.put(rc_callback, data=f.read(), headers={"content-type": "application/octect-stream"})
r = requests.put(rc_callback, data=f.read(), headers={
"content-type": "application/octect-stream"})
log('submit rc reply: HTTP {}'.format(r.status_code))
except Exception as ex:
log("failed to submit rc: {}".format(ex))
@ -212,8 +215,10 @@ def run_main(args):
else:
loki.close()
def main():
run_main(sys.argv[1:])
if __name__ == "__main__":
main()
main()

@ -107,6 +107,7 @@ main(int argc, char *argv[])
("g,generate", "generate client config", cxxopts::value<bool>())
("r,router", "generate router config", cxxopts::value<bool>())
("f,force", "overwrite", cxxopts::value<bool>())
("d,debug", "debug mode - UNENCRYPTED TRAFFIC", cxxopts::value<bool>())
("config","path to configuration file", cxxopts::value<std::string>());
options.parse_positional("config");
@ -115,6 +116,7 @@ main(int argc, char *argv[])
bool genconfigOnly = false;
bool asRouter = false;
bool overWrite = false;
bool debugMode = false;
std::string conffname; // suggestions: confFName? conf_fname?
try
@ -138,6 +140,11 @@ main(int argc, char *argv[])
genconfigOnly = true;
}
if(result.count("debug") > 0)
{
debugMode = true;
}
if(result.count("force") > 0)
{
overWrite = true;
@ -279,7 +286,7 @@ main(int argc, char *argv[])
signal(SIGHUP, handle_signal);
#endif
code = llarp_main_setup(ctx);
code = llarp_main_setup(ctx, debugMode);
if(code == 0)
code = llarp_main_run(ctx);
llarp_main_free(ctx);

@ -42,7 +42,7 @@ LLARP - Low Latency Anon Routing Protocol
network level (IPv4/IPv6) tunnel broker for both "hidden services" and
communication back to "the clearnet" (the normal internet). Both hidden service
and clearnet communication MUST permit both outbound and inbound traffic on the
network level without any NAT (expect for IPv4 in which NAT is permitted due to
network level without any NAT (except for IPv4 in which NAT is permitted due to
lack of address availability).

@ -41,7 +41,7 @@ extern "C"
/// setup main context, returns 0 on success
int
llarp_main_setup(struct llarp_main *ptr);
llarp_main_setup(struct llarp_main *ptr, bool debugMode);
/// run main context, returns 0 on success, blocks until program end
int

@ -20,6 +20,7 @@ namespace llarp
{
struct Config;
struct Crypto;
struct CryptoManager;
class Logic;
struct AbstractRouter;
struct RouterContact;
@ -55,6 +56,7 @@ namespace llarp
std::map< std::string, std::string > metricTags;
std::unique_ptr< Crypto > crypto;
std::unique_ptr< CryptoManager > cryptoManager;
std::unique_ptr< AbstractRouter > router;
std::unique_ptr< llarp_threadpool > worker;
std::shared_ptr< Logic > logic;
@ -82,7 +84,7 @@ namespace llarp
GetDatabase(const byte_t *pk);
int
Setup();
Setup(bool debug=false);
int
Run();

@ -126,6 +126,7 @@ set(LIB_SRC
context.cpp
crypto/constants.cpp
crypto/crypto_libsodium.cpp
crypto/crypto_noop.cpp
crypto/crypto.cpp
crypto/ec.cpp
crypto/encrypted_frame.cpp

@ -3,6 +3,7 @@
#include <config.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <crypto/crypto_noop.hpp>
#include <dht/context.hpp>
#include <dnsd.hpp>
#include <ev/ev.hpp>
@ -162,9 +163,9 @@ __ ___ ____ _ _ ___ _ _ ____
\ V V / ___ \| _ <| |\ || || |\ | |_| |
\_/\_/_/ \_\_| \_\_| \_|___|_| \_|\____|
This Lokinet session is not private
This Lokinet session is not private!!
Sending connection metrics to metrictank
Sending connection metrics to metrictank!!
__ ___ ____ _ _ ___ _ _ ____
\ \ / / \ | _ \| \ | |_ _| \ | |/ ___|
\ \ /\ / / _ \ | |_) | \| || || \| | | _
@ -203,9 +204,7 @@ __ ___ ____ _ _ ___ _ _ ____
int
Context::LoadDatabase()
{
crypto = std::make_unique< sodium::CryptoLibSodium >();
nodedb =
std::make_unique< llarp_nodedb >(crypto.get(), router->diskworker());
nodedb = std::make_unique< llarp_nodedb >(router->diskworker());
if(!llarp_nodedb::ensure_dir(nodedb_dir.c_str()))
{
@ -248,7 +247,7 @@ __ ___ ____ _ _ ___ _ _ ____
}
int
Context::Setup()
Context::Setup(bool debug)
{
llarp::LogInfo(LLARP_VERSION, " ", LLARP_RELEASE_MOTTO);
llarp::LogInfo("starting up");
@ -270,6 +269,35 @@ __ ___ ____ _ _ ___ _ _ ____
else
logic = std::make_shared< Logic >();
if(debug)
{
static std::string WARNING = R"(
__ ___ ____ _ _ ___ _ _ ____
\ \ / / \ | _ \| \ | |_ _| \ | |/ ___|
\ \ /\ / / _ \ | |_) | \| || || \| | | _
\ V V / ___ \| _ <| |\ || || |\ | |_| |
\_/\_/_/ \_\_| \_\_| \_|___|_| \_|\____|
This Lokinet session is not private!!
Sending traffic unencrypted!!
__ ___ ____ _ _ ___ _ _ ____
\ \ / / \ | _ \| \ | |_ _| \ | |/ ___|
\ \ /\ / / _ \ | |_) | \| || || \| | | _
\ V V / ___ \| _ <| |\ || || |\ | |_| |
\_/\_/_/ \_\_| \_\_| \_|___|_| \_|\____|
)";
std::cerr << WARNING << '\n';
crypto = std::make_unique< NoOpCrypto >();
}
else
{
crypto = std::make_unique< sodium::CryptoLibSodium >();
}
cryptoManager = std::make_unique< CryptoManager >(crypto.get());
router = std::make_unique< Router >(worker.get(), mainloop, logic);
if(!router->Configure(config.get()))
{
@ -472,9 +500,9 @@ extern "C"
}
int
llarp_main_setup(struct llarp_main *ptr)
llarp_main_setup(struct llarp_main *ptr, bool debug)
{
return ptr->ctx->Setup();
return ptr->ctx->Setup(debug);
}
int
@ -533,104 +561,6 @@ extern "C"
return ptr->ctx->LoadDatabase();
}
/*
int
llarp_main_iterateDatabase(struct llarp_main *ptr, struct llarp_nodedb_iter i)
{
return ptr->ctx->IterateDatabase(i);
}
bool
llarp_main_putDatabase(struct llarp_main *ptr, llarp::RouterContact &rc)
{
return ptr->ctx->PutDatabase(rc);
}
llarp::RouterContact *
llarp_main_getDatabase(struct llarp_main *ptr, byte_t *pk)
{
return ptr->ctx->GetDatabase(pk);
}
llarp::RouterContact *
llarp_main_getLocalRC(__attribute__((unused)) struct llarp_main *ptr)
{
return nullptr;
}
void
llarp_main_checkOnline(void *u, __attribute__((unused)) uint64_t orig,
uint64_t left)
{
// llarp::Info("checkOnline - check ", left);
if(left)
return;
struct check_online_request *request =
static_cast< struct check_online_request * >(u);
// llarp::Debug("checkOnline - running");
// llarp::Info("checkOnline - DHT nodes ",
// request->ptr->ctx->router->dht->impl.nodes->nodes.size());
request->online = false;
request->nodes =
request->ptr->ctx->router->dht()->impl->Nodes()->nodes.size();
if(request->ptr->ctx->router->dht()->impl->Nodes()->nodes.size())
{
// llarp::Info("checkOnline - Going to say we're online");
request->online = true;
}
request->hook(request);
// reschedue our self
llarp_main_queryDHT(request);
}
void
llarp_main_queryDHT_online(struct check_online_request *request)
{
// Info("llarp_main_queryDHT_online: ", request->online ? "online" :
// "offline");
if(request->online && !request->first)
{
request->first = true;
llarp::LogInfo("llarp_main_queryDHT_online - We're online");
llarp::LogInfo("llarp_main_queryDHT_online - Querying DHT");
llarp_dht_lookup_router(request->ptr->ctx->router->dht(), request->job);
}
}
void
llarp_main_queryDHT(struct check_online_request *request)
{
// llarp::Info("llarp_main_queryDHT - setting up timer");
request->hook = &llarp_main_queryDHT_online;
request->ptr->ctx->router->logic()->call_later(
{1000, request, &llarp_main_checkOnline});
// llarp_dht_lookup_router(ptr->ctx->router->dht, job);
}
llarp::handlers::TunEndpoint *
main_router_getFirstTunEndpoint(struct llarp_main *ptr)
{
if(ptr && ptr->ctx && ptr->ctx->router)
return ptr->ctx->router->hiddenServiceContext().getFirstTun();
return nullptr;
}
bool
main_router_endpoint_iterator(
struct llarp_main *ptr, struct llarp::service::Context::endpoint_iter &i)
{
return ptr->ctx->router->hiddenServiceContext().iterate(i);
}
llarp_tun_io *
main_router_getRange(struct llarp_main *ptr)
{
return ptr->ctx->router->hiddenServiceContext().getRange();
}
*/
const char *
handleBaseCmdLineArgs(int argc, char *argv[])
{

@ -1 +1,6 @@
#include <crypto/crypto.hpp>
namespace llarp
{
Crypto* CryptoManager::m_crypto = nullptr;
}

@ -6,6 +6,7 @@
#include <util/buffer.hpp>
#include <absl/base/optimization.h>
#include <functional>
#include <stdbool.h>
#include <stdint.h>
@ -19,18 +20,6 @@
namespace llarp
{
/// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function< bool(
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >;
/// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function< bool(
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >;
/// SH(result, body)
using shorthash_func =
std::function< bool(ShortHash &, const llarp_buffer_t &) >;
/// library crypto configuration
struct Crypto
{
@ -62,9 +51,6 @@ namespace llarp
virtual bool
transport_dh_server(SharedSecret &, const PubKey &, const SecretKey &,
const TunnelNonce &) = 0;
/// blake2b 512 bit
virtual bool
hash(byte_t *, const llarp_buffer_t &) = 0;
/// blake2b 256 bit
virtual bool
shorthash(ShortHash &, const llarp_buffer_t &) = 0;
@ -85,7 +71,7 @@ namespace llarp
randomize(const llarp_buffer_t &) = 0;
/// randomizer memory
virtual void
randbytes(void *, size_t) = 0;
randbytes(byte_t *, size_t) = 0;
/// generate signing keypair
virtual void
identity_keygen(SecretKey &) = 0;
@ -120,6 +106,36 @@ namespace llarp
const byte_t *
pq_keypair_to_secret(const PQKeyPair &keypair);
struct CryptoManager
{
private:
static Crypto *m_crypto;
Crypto *m_prevCrypto;
public:
CryptoManager(Crypto *crypto) : m_prevCrypto(m_crypto)
{
m_crypto = crypto;
}
~CryptoManager()
{
m_crypto = m_prevCrypto;
}
static Crypto *
instance() ABSL_ATTRIBUTE_RETURNS_NONNULL
{
if(ABSL_PREDICT_TRUE(m_crypto))
{
return m_crypto;
}
throw std::logic_error("Cryptomanager::instance() was undefined");
}
};
} // namespace llarp
#endif

@ -85,7 +85,7 @@ namespace llarp
ntru_init(0);
}
int seed = 0;
this->randbytes(&seed, sizeof(seed));
randombytes(reinterpret_cast< unsigned char * >(&seed), sizeof(seed));
srand(seed);
}
@ -139,14 +139,6 @@ namespace llarp
return dh_server_priv(shared, pk, sk, n);
}
bool
CryptoLibSodium::hash(uint8_t *result, const llarp_buffer_t &buff)
{
return crypto_generichash_blake2b(result, HASHSIZE, buff.base, buff.sz,
nullptr, 0)
!= -1;
}
bool
CryptoLibSodium::shorthash(ShortHash &result, const llarp_buffer_t &buff)
{
@ -249,6 +241,14 @@ namespace llarp
return true;
}
static bool
hash(uint8_t *result, const llarp_buffer_t &buff)
{
return crypto_generichash_blake2b(result, HASHSIZE, buff.base, buff.sz,
nullptr, 0)
!= -1;
}
bool
CryptoLibSodium::sign(Signature &sig, const SecretKey &secret,
const llarp_buffer_t &buf)
@ -327,7 +327,7 @@ namespace llarp
}
void
CryptoLibSodium::randbytes(void *ptr, size_t sz)
CryptoLibSodium::randbytes(byte_t *ptr, size_t sz)
{
randombytes((unsigned char *)ptr, sz);
}

@ -41,9 +41,6 @@ namespace llarp
bool
transport_dh_server(SharedSecret &, const PubKey &, const SecretKey &,
const TunnelNonce &) override;
/// blake2b 512 bit
bool
hash(byte_t *, const llarp_buffer_t &) override;
/// blake2b 256 bit
bool
shorthash(ShortHash &, const llarp_buffer_t &) override;
@ -66,7 +63,7 @@ namespace llarp
randomize(const llarp_buffer_t &) override;
/// randomizer memory
void
randbytes(void *, size_t) override;
randbytes(byte_t *, size_t) override;
/// generate signing keypair
void
identity_keygen(SecretKey &) override;

@ -0,0 +1 @@
#include <crypto/crypto_noop.hpp>

@ -0,0 +1,186 @@
#ifndef LLARP_CRYPTO_NOOP_HPP
#define LLARP_CRYPTO_NOOP_HPP
#include <crypto/crypto.hpp>
#include <atomic>
#include <numeric>
namespace llarp
{
struct NoOpCrypto final : public Crypto
{
private:
std::atomic_uint64_t m_value;
static constexpr byte_t MAX_BYTE = std::numeric_limits< byte_t >::max();
public:
NoOpCrypto() : m_value(0)
{
}
~NoOpCrypto() = default;
bool
xchacha20(const llarp_buffer_t &, const SharedSecret &,
const TunnelNonce &) override
{
return true;
}
bool
xchacha20_alt(const llarp_buffer_t &out, const llarp_buffer_t &in,
const SharedSecret &, const byte_t *) override
{
if(in.sz > out.sz)
{
return false;
}
std::copy_n(in.begin(), in.sz, out.begin());
return true;
}
bool
dh_client(SharedSecret &shared, const PubKey &pk, const SecretKey &,
const TunnelNonce &) override
{
std::copy_n(pk.begin(), pk.size(), shared.begin());
return true;
}
bool
dh_server(SharedSecret &shared, const PubKey &pk, const SecretKey &,
const TunnelNonce &) override
{
std::copy_n(pk.begin(), pk.size(), shared.begin());
return true;
}
bool
transport_dh_client(SharedSecret &shared, const PubKey &pk,
const SecretKey &, const TunnelNonce &) override
{
std::copy_n(pk.begin(), pk.size(), shared.begin());
return true;
}
bool
transport_dh_server(SharedSecret &shared, const PubKey &pk,
const SecretKey &, const TunnelNonce &) override
{
std::copy_n(pk.begin(), pk.size(), shared.begin());
return true;
}
bool
shorthash(ShortHash &out, const llarp_buffer_t &buff) override
{
// copy the first 32 bytes of the buffer
if(buff.sz < out.size())
{
std::copy_n(buff.begin(), buff.sz, out.begin());
std::fill(out.begin() + buff.sz, out.end(), 0);
}
else
{
std::copy_n(buff.begin(), out.size(), out.begin());
}
return true;
}
bool
hmac(byte_t *out, const llarp_buffer_t &buff, const SharedSecret &) override
{
if(buff.sz < HMACSIZE)
{
std::copy_n(buff.begin(), buff.sz, out);
std::fill(out + buff.sz, out + (HMACSIZE - buff.sz), 0);
}
else
{
std::copy_n(buff.begin(), HMACSIZE, out);
}
return true;
}
bool
sign(Signature &sig, const SecretKey &key, const llarp_buffer_t &) override
{
static_assert(Signature::SIZE == SecretKey::SIZE, "");
std::copy(key.begin(), key.end(), sig.begin());
return true;
}
bool
verify(const PubKey &, const llarp_buffer_t &, const Signature &) override
{
return true;
}
bool
seed_to_secretkey(SecretKey &key, const IdentitySecret &secret) override
{
static_assert(SecretKey::SIZE == (2 * IdentitySecret::SIZE), "");
std::copy(secret.begin(), secret.end(), key.begin());
std::copy(secret.begin(), secret.end(),
key.begin() + IdentitySecret::SIZE);
return true;
}
void
randomize(const llarp_buffer_t &buff) override
{
std::iota(buff.begin(), buff.end(), m_value.load() % MAX_BYTE);
m_value += buff.sz;
}
void
randbytes(byte_t *ptr, size_t sz) override
{
std::iota(ptr, ptr + sz, m_value.load() % MAX_BYTE);
m_value += sz;
}
void
identity_keygen(SecretKey &key) override
{
std::iota(key.begin(), key.end(), m_value.load() % MAX_BYTE);
m_value += key.size();
}
void
encryption_keygen(SecretKey &key) override
{
std::iota(key.begin(), key.end(), m_value.load() % MAX_BYTE);
m_value += key.size();
}
void
pqe_keygen(PQKeyPair &pair) override
{
std::iota(pair.begin(), pair.end(), m_value.load() % MAX_BYTE);
m_value += pair.size();
}
bool
pqe_decrypt(const PQCipherBlock &block, SharedSecret &secret,
const byte_t *) override
{
std::copy_n(block.begin(), SharedSecret::SIZE, secret.begin());
return true;
}
bool
pqe_encrypt(PQCipherBlock &block, SharedSecret &secret,
const PQPubKey &) override
{
std::copy_n(secret.begin(), SharedSecret::SIZE, block.begin());
return true;
}
};
} // namespace llarp
#endif

@ -8,8 +8,7 @@ namespace llarp
{
bool
EncryptedFrame::EncryptInPlace(const SecretKey& ourSecretKey,
const PubKey& otherPubkey,
llarp::Crypto* crypto)
const PubKey& otherPubkey)
{
// format of frame is
// <32 bytes keyed hash of following data>
@ -29,6 +28,8 @@ namespace llarp
buf.cur = buf.base;
buf.sz = size() - EncryptedFrameOverheadSize;
auto crypto = CryptoManager::instance();
// set our pubkey
memcpy(pubkey, ourSecretKey.toPublic().data(), PUBKEYSIZE);
// randomize nonce
@ -63,8 +64,7 @@ namespace llarp
}
bool
EncryptedFrame::DecryptInPlace(const SecretKey& ourSecretKey,
llarp::Crypto* crypto)
EncryptedFrame::DecryptInPlace(const SecretKey& ourSecretKey)
{
// format of frame is
// <32 bytes keyed hash of following data>
@ -80,6 +80,8 @@ namespace llarp
SharedSecret shared;
auto crypto = CryptoManager::instance();
// use dh_server because we are not the creator of this message
if(!crypto->dh_server(shared, otherPubkey, ourSecretKey, nonce))
{

@ -9,8 +9,6 @@
namespace llarp
{
struct Crypto;
static constexpr size_t EncryptedFrameOverheadSize =
PUBKEYSIZE + TUNNONCESIZE + SHORTHASHSIZE;
static constexpr size_t EncryptedFrameBodySize = 128 * 6;
@ -40,57 +38,10 @@ namespace llarp
}
bool
DecryptInPlace(const SecretKey& seckey, llarp::Crypto* crypto);
DecryptInPlace(const SecretKey& seckey);
bool
EncryptInPlace(const SecretKey& seckey, const PubKey& other,
llarp::Crypto* crypto);
};
/// TODO: can only handle 1 frame at a time
template < typename User >
struct AsyncFrameEncrypter
{
using EncryptHandler = std::function< void(EncryptedFrame*, User*) >;
static void
Encrypt(void* user)
{
AsyncFrameEncrypter< User >* ctx =
static_cast< AsyncFrameEncrypter< User >* >(user);
if(ctx->frame.EncryptInPlace(ctx->seckey, ctx->otherKey, ctx->crypto))
ctx->handler(&ctx->frame, ctx->user);
else
{
ctx->handler(nullptr, ctx->user);
}
}
llarp::Crypto* crypto;
byte_t* secretkey;
EncryptHandler handler;
EncryptedFrame frame;
User* user;
byte_t* otherKey;
AsyncFrameEncrypter(llarp::Crypto* c, byte_t* seckey, EncryptHandler h)
: crypto(c), secretkey(seckey), handler(h)
{
}
void
AsyncEncrypt(llarp_threadpool* worker, llarp_buffer_t buf, byte_t* other,
User* u)
{
// TODO: should we own otherKey?
otherKey = other;
if(buf.sz > EncryptedFrameBodySize)
return;
memcpy(frame.data() + EncryptedFrameOverheadSize, buf.base, buf.sz);
user = u;
llarp_threadpool_queue_job(worker, {this, &Encrypt});
}
EncryptInPlace(const SecretKey& seckey, const PubKey& other);
};
/// TODO: can only handle 1 frame at a time
@ -106,7 +57,7 @@ namespace llarp
AsyncFrameDecrypter< User >* ctx =
static_cast< AsyncFrameDecrypter< User >* >(user);
if(ctx->target.DecryptInPlace(ctx->seckey, ctx->crypto))
if(ctx->target.DecryptInPlace(ctx->seckey))
{
auto buf = ctx->target.Buffer();
buf->cur = buf->base + EncryptedFrameOverheadSize;
@ -117,15 +68,13 @@ namespace llarp
ctx->user = nullptr;
}
AsyncFrameDecrypter(llarp::Crypto* c, const SecretKey& secretkey,
DecryptHandler h)
: result(h), crypto(c), seckey(secretkey)
AsyncFrameDecrypter(const SecretKey& secretkey, DecryptHandler h)
: result(h), seckey(secretkey)
{
}
DecryptHandler result;
User_ptr user;
llarp::Crypto* crypto;
const SecretKey& seckey;
EncryptedFrame target;

@ -164,6 +164,18 @@ namespace llarp
using PQCipherBlock = AlignedBuffer< PQ_CIPHERTEXTSIZE + 1 >;
using PQPubKey = AlignedBuffer< PQ_PUBKEYSIZE >;
using PQKeyPair = AlignedBuffer< PQ_KEYPAIRSIZE >;
/// PKE(result, publickey, secretkey, nonce)
using path_dh_func = std::function< bool(
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >;
/// TKE(result, publickey, secretkey, nonce)
using transport_dh_func = std::function< bool(
SharedSecret &, const PubKey &, const SecretKey &, const TunnelNonce &) >;
/// SH(result, body)
using shorthash_func =
std::function< bool(ShortHash &, const llarp_buffer_t &) >;
} // namespace llarp
#endif

@ -41,9 +41,6 @@ namespace llarp
util::StatusObject
ExtractStatus() const override;
llarp::Crypto*
Crypto() const override;
/// on behalf of whoasked request introset for target from dht router with
/// key askpeer
void
@ -696,12 +693,6 @@ namespace llarp
}
}
llarp::Crypto*
Context::Crypto() const
{
return router->crypto();
}
llarp_time_t
Context::Now() const
{

@ -129,9 +129,6 @@ namespace llarp
virtual void
ExploreNetworkVia(const Key_t& peer) = 0;
virtual llarp::Crypto*
Crypto() const = 0;
virtual llarp::AbstractRouter*
GetRouter() const = 0;

@ -25,12 +25,11 @@ namespace llarp
__attribute__((unused))
std::vector< std::unique_ptr< IMessage > > &replies) const
{
auto &dht = *ctx->impl;
auto crypto = dht.GetRouter()->crypto();
auto &dht = *ctx->impl;
for(const auto &introset : I)
{
if(!introset.Verify(crypto, dht.Now()))
if(!introset.Verify(dht.Now()))
{
llarp::LogWarn(
"Invalid introset while handling direct GotIntro "

@ -53,7 +53,7 @@ namespace llarp
return false;
}
auto &dht = *ctx->impl;
if(!I.Verify(dht.Crypto(), now))
if(!I.Verify(now))
{
llarp::LogWarn("invalid introset: ", I);
// don't propogate or store
@ -61,10 +61,7 @@ namespace llarp
return true;
}
using namespace std::placeholders;
shorthash_func shorthash =
std::bind(&Crypto::shorthash, dht.Crypto(), _1, _2);
if(I.W && !I.W->IsValid(shorthash, now))
if(I.W && !I.W->IsValid(now))
{
llarp::LogWarn("proof of work not good enough for IntroSet");
// don't propogate or store

@ -22,7 +22,7 @@ namespace llarp
bool
RecursiveRouterLookup::Validate(const RouterContact &rc) const
{
if(!rc.Verify(parent->Crypto(), parent->Now()))
if(!rc.Verify(parent->Now()))
{
llarp::LogWarn("rc from lookup result is invalid");
return false;

@ -22,7 +22,7 @@ namespace llarp
bool
ServiceAddressLookup::Validate(const service::IntroSet &value) const
{
if(!value.Verify(parent->Crypto(), parent->Now()))
if(!value.Verify(parent->Now()))
{
llarp::LogWarn("Got invalid introset from service lookup");
return false;

@ -10,7 +10,7 @@ namespace llarp
bool
TagLookup::Validate(const service::IntroSet &introset) const
{
if(!introset.Verify(parent->Crypto(), parent->Now()))
if(!introset.Verify(parent->Now()))
{
llarp::LogWarn("got invalid introset from tag lookup");
return false;

@ -40,7 +40,7 @@ namespace llarp
}
bool
CloseExitMessage::Verify(llarp::Crypto* c, const llarp::PubKey& pk) const
CloseExitMessage::Verify(const llarp::PubKey& pk) const
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -50,11 +50,11 @@ namespace llarp
if(!copy.BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->verify(pk, buf, Z);
return CryptoManager::instance()->verify(pk, buf, Z);
}
bool
CloseExitMessage::Sign(llarp::Crypto* c, const llarp::SecretKey& sk)
CloseExitMessage::Sign(const llarp::SecretKey& sk)
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -63,7 +63,7 @@ namespace llarp
if(!BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->sign(Z, sk, buf);
return CryptoManager::instance()->sign(Z, sk, buf);
}
bool

@ -45,7 +45,7 @@ namespace llarp
}
bool
GrantExitMessage::Verify(llarp::Crypto* c, const llarp::PubKey& pk) const
GrantExitMessage::Verify(const llarp::PubKey& pk) const
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -55,11 +55,11 @@ namespace llarp
if(!copy.BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->verify(pk, buf, Z);
return CryptoManager::instance()->verify(pk, buf, Z);
}
bool
GrantExitMessage::Sign(llarp::Crypto* c, const llarp::SecretKey& sk)
GrantExitMessage::Sign(const llarp::SecretKey& sk)
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -68,7 +68,7 @@ namespace llarp
if(!BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->sign(Z, sk, buf);
return CryptoManager::instance()->sign(Z, sk, buf);
}
bool

@ -8,7 +8,7 @@ namespace llarp
namespace routing
{
bool
ObtainExitMessage::Sign(llarp::Crypto* c, const llarp::SecretKey& sk)
ObtainExitMessage::Sign(const llarp::SecretKey& sk)
{
std::array< byte_t, 1024 > tmp;
llarp_buffer_t buf(tmp);
@ -19,11 +19,11 @@ namespace llarp
return false;
}
buf.sz = buf.cur - buf.base;
return c->sign(Z, sk, buf);
return CryptoManager::instance()->sign(Z, sk, buf);
}
bool
ObtainExitMessage::Verify(llarp::Crypto* c) const
ObtainExitMessage::Verify() const
{
std::array< byte_t, 1024 > tmp;
llarp_buffer_t buf(tmp);
@ -36,7 +36,7 @@ namespace llarp
}
// rewind buffer
buf.sz = buf.cur - buf.base;
return c->verify(I, buf, Z);
return CryptoManager::instance()->verify(I, buf, Z);
}
bool

@ -53,7 +53,7 @@ namespace llarp
}
bool
RejectExitMessage::Sign(llarp::Crypto* c, const llarp::SecretKey& sk)
RejectExitMessage::Sign(const llarp::SecretKey& sk)
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -62,11 +62,11 @@ namespace llarp
if(!BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->sign(Z, sk, buf);
return CryptoManager::instance()->sign(Z, sk, buf);
}
bool
RejectExitMessage::Verify(llarp::Crypto* c, const llarp::PubKey& pk) const
RejectExitMessage::Verify(const llarp::PubKey& pk) const
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -76,7 +76,7 @@ namespace llarp
if(!copy.BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->verify(pk, buf, Z);
return CryptoManager::instance()->verify(pk, buf, Z);
}
bool

@ -1,5 +1,6 @@
#include <exit/session.hpp>
#include <crypto/crypto.hpp>
#include <nodedb.hpp>
#include <path/path.hpp>
#include <router/abstractrouter.hpp>
@ -19,7 +20,7 @@ namespace llarp
, m_LastUse(0)
, m_BundleRC(bundleRC)
{
r->crypto()->identity_keygen(m_ExitIdentity);
CryptoManager::instance()->identity_keygen(m_ExitIdentity);
}
BaseSession::~BaseSession()
@ -109,11 +110,11 @@ namespace llarp
p->AddObtainExitHandler(std::bind(&BaseSession::HandleGotExit, this,
std::placeholders::_1,
std::placeholders::_2));
llarp::routing::ObtainExitMessage obtain;
routing::ObtainExitMessage obtain;
obtain.S = p->NextSeqNo();
obtain.T = llarp::randint();
PopulateRequest(obtain);
if(!obtain.Sign(router->crypto(), m_ExitIdentity))
if(!obtain.Sign(m_ExitIdentity))
{
llarp::LogError("Failed to sign exit request");
return;
@ -168,9 +169,8 @@ namespace llarp
if(p->SupportsAnyRoles(roles))
{
llarp::LogInfo(p->Name(), " closing exit path");
llarp::routing::CloseExitMessage msg;
if(msg.Sign(router->crypto(), m_ExitIdentity)
&& p->SendExitClose(msg, router))
routing::CloseExitMessage msg;
if(msg.Sign(m_ExitIdentity) && p->SendExitClose(msg, router))
{
p->ClearRoles(roles);
}
@ -186,19 +186,18 @@ namespace llarp
BaseSession::Stop()
{
CallPendingCallbacks(false);
auto sendExitClose = [&](const llarp::path::Path_ptr p) {
if(p->SupportsAnyRoles(llarp::path::ePathRoleExit))
auto sendExitClose = [&](const path::Path_ptr p) {
if(p->SupportsAnyRoles(path::ePathRoleExit))
{
llarp::LogInfo(p->Name(), " closing exit path");
llarp::routing::CloseExitMessage msg;
if(!(msg.Sign(router->crypto(), m_ExitIdentity)
&& p->SendExitClose(msg, router)))
llarp::LogWarn(p->Name(), " failed to send exit close message");
LogInfo(p->Name(), " closing exit path");
routing::CloseExitMessage msg;
if(!(msg.Sign(m_ExitIdentity) && p->SendExitClose(msg, router)))
LogWarn(p->Name(), " failed to send exit close message");
}
};
ForEachPath(sendExitClose);
router->pathContext().RemovePathSet(shared_from_this());
return llarp::path::Builder::Stop();
return path::Builder::Stop();
}
bool

@ -45,7 +45,7 @@ namespace llarp
}
bool
UpdateExitMessage::Verify(llarp::Crypto* c, const llarp::PubKey& pk) const
UpdateExitMessage::Verify(const llarp::PubKey& pk) const
{
std::array< byte_t, 512 > tmp;
@ -56,11 +56,11 @@ namespace llarp
if(!copy.BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->verify(pk, buf, Z);
return CryptoManager::instance()->verify(pk, buf, Z);
}
bool
UpdateExitMessage::Sign(llarp::Crypto* c, const llarp::SecretKey& sk)
UpdateExitMessage::Sign(const llarp::SecretKey& sk)
{
std::array< byte_t, 512 > tmp;
llarp_buffer_t buf(tmp);
@ -68,7 +68,7 @@ namespace llarp
if(!BEncode(&buf))
return false;
buf.sz = buf.cur - buf.base;
return c->sign(Z, sk, buf);
return CryptoManager::instance()->sign(Z, sk, buf);
}
bool

@ -304,12 +304,6 @@ namespace llarp
return m_Router;
}
Crypto *
ExitEndpoint::GetCrypto()
{
return m_Router->crypto();
}
huint32_t
ExitEndpoint::GetIfAddr() const
{

@ -62,9 +62,6 @@ namespace llarp
llarp_time_t
Now() const;
Crypto*
GetCrypto();
template < typename Stats >
void
CalculateTrafficStats(Stats& stats)

@ -11,7 +11,7 @@ namespace llarp
{
using namespace std::placeholders;
return NewServer(
r->crypto(), r->encryption(), std::bind(&AbstractRouter::rc, r),
r->encryption(), std::bind(&AbstractRouter::rc, r),
std::bind(&AbstractRouter::HandleRecvLinkMessageBuffer, r, _1, _2),
std::bind(&AbstractRouter::OnSessionEstablished, r, _1),
std::bind(&AbstractRouter::CheckRenegotiateValid, r, _1, _2),
@ -21,12 +21,11 @@ namespace llarp
}
std::unique_ptr< ILinkLayer >
NewServer(Crypto* c, const SecretKey& enckey, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler t, SessionClosedHandler closed)
NewServer(const SecretKey& enckey, GetRCFunc getrc, LinkMessageHandler h,
SessionEstablishedHandler est, SessionRenegotiateHandler reneg,
SignBufferFunc sign, TimeoutHandler t,
SessionClosedHandler closed)
{
(void)c;
(void)enckey;
(void)getrc;
(void)h;

@ -12,9 +12,8 @@ namespace llarp
namespace iwp
{
std::unique_ptr< ILinkLayer >
NewServer(llarp::Crypto* crypto, const SecretKey& routerEncSecret,
llarp::GetRCFunc getrc, llarp::LinkMessageHandler h,
llarp::SessionEstablishedHandler est,
NewServer(const SecretKey& routerEncSecret, llarp::GetRCFunc getrc,
llarp::LinkMessageHandler h, llarp::SessionEstablishedHandler est,
llarp::SessionRenegotiateHandler reneg,
llarp::SignBufferFunc sign, llarp::TimeoutHandler timeout,
llarp::SessionClosedHandler closed);

@ -4,11 +4,11 @@ namespace llarp
{
namespace iwp
{
LinkLayer::LinkLayer(Crypto* c, const SecretKey& enckey, GetRCFunc getrc,
LinkLayer::LinkLayer(const SecretKey& enckey, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler t, SessionClosedHandler closed)
: ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed), crypto(c)
: ILinkLayer(enckey, getrc, h, sign, est, reneg, t, closed)
{
m_FlowCookie.Randomize();
}
@ -33,7 +33,7 @@ namespace llarp
LinkLayer::KeyGen(SecretKey& k)
{
k.Zero();
crypto->encryption_keygen(k);
CryptoManager::instance()->encryption_keygen(k);
return !k.IsZero();
}
@ -67,7 +67,8 @@ namespace llarp
{
case eOCMD_ObtainFlowID:
sigbuf.sz -= m_OuterMsg.Zsig.size();
if(!crypto->verify(m_OuterMsg.pubkey, sigbuf, m_OuterMsg.Zsig))
if(!CryptoManager::instance()->verify(m_OuterMsg.pubkey, sigbuf,
m_OuterMsg.Zsig))
{
LogError("failed to verify signature on '",
(char)m_OuterMsg.command, "' message from ", from);
@ -131,7 +132,7 @@ namespace llarp
tmp.begin() + 64 + pk.size());
llarp_buffer_t buf(tmp);
ShortHash h;
if(!crypto->shorthash(h, buf))
if(!CryptoManager::instance()->shorthash(h, buf))
return false;
std::copy_n(h.begin(), flow.size(), flow.begin());
return true;

@ -14,22 +14,13 @@ namespace llarp
{
struct LinkLayer final : public ILinkLayer
{
LinkLayer(Crypto *crypto, const SecretKey &encryptionSecretKey,
GetRCFunc getrc, LinkMessageHandler h,
SessionEstablishedHandler established,
LinkLayer(const SecretKey &encryptionSecretKey, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler established,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed);
~LinkLayer();
Crypto *const crypto;
Crypto *
OurCrypto() override
{
return crypto;
}
bool
Start(std::shared_ptr< Logic > l) override;

@ -61,9 +61,6 @@ namespace llarp
return llarp_ev_loop_time_now_ms(m_Loop);
}
virtual Crypto*
OurCrypto() = 0;
bool
HasSessionTo(const RouterID& pk);

@ -9,7 +9,6 @@
namespace llarp
{
struct Crypto;
namespace routing
{
struct ObtainExitMessage final : public IMessage
@ -44,10 +43,10 @@ namespace llarp
/// populates I and signs
bool
Sign(llarp::Crypto* c, const llarp::SecretKey& sk);
Sign(const llarp::SecretKey& sk);
bool
Verify(llarp::Crypto* c) const;
Verify() const;
bool
BEncode(llarp_buffer_t* buf) const override;
@ -71,10 +70,10 @@ namespace llarp
BEncode(llarp_buffer_t* buf) const override;
bool
Sign(llarp::Crypto* c, const llarp::SecretKey& sk);
Sign(const llarp::SecretKey& sk);
bool
Verify(llarp::Crypto* c, const llarp::PubKey& pk) const;
Verify(const llarp::PubKey& pk) const;
bool
DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf) override;
@ -111,10 +110,10 @@ namespace llarp
}
bool
Sign(llarp::Crypto* c, const llarp::SecretKey& sk);
Sign(const llarp::SecretKey& sk);
bool
Verify(llarp::Crypto* c, const llarp::PubKey& pk) const;
Verify(const llarp::PubKey& pk) const;
bool
BEncode(llarp_buffer_t* buf) const override;
@ -133,13 +132,7 @@ namespace llarp
Nonce_t Y;
llarp::Signature Z;
UpdateExitVerifyMessage() : IMessage()
{
}
~UpdateExitVerifyMessage()
{
}
~UpdateExitVerifyMessage() = default;
void
Clear() override
@ -149,15 +142,6 @@ namespace llarp
Z.Zero();
}
UpdateExitVerifyMessage&
operator=(const UpdateExitVerifyMessage& other);
bool
Sign(llarp::Crypto* c, const llarp::SecretKey& sk);
bool
Verify(llarp::Crypto* c, const llarp::PubKey& pk) const;
bool
BEncode(llarp_buffer_t* buf) const override;
@ -177,10 +161,10 @@ namespace llarp
llarp::Signature Z;
bool
Sign(llarp::Crypto* c, const llarp::SecretKey& sk);
Sign(const llarp::SecretKey& sk);
bool
Verify(llarp::Crypto* c, const llarp::PubKey& pk) const;
Verify(const llarp::PubKey& pk) const;
bool
BEncode(llarp_buffer_t* buf) const override;
@ -218,10 +202,10 @@ namespace llarp
HandleMessage(IMessageHandler* h, AbstractRouter* r) const override;
bool
Sign(llarp::Crypto* c, const llarp::SecretKey& sk);
Sign(const llarp::SecretKey& sk);
bool
Verify(llarp::Crypto* c, const llarp::PubKey& pk) const;
Verify(const llarp::PubKey& pk) const;
void
Clear() override

@ -101,9 +101,10 @@ namespace llarp
}
bool
LinkIntroMessage::HandleMessage(AbstractRouter* router) const
LinkIntroMessage::HandleMessage(
ABSL_ATTRIBUTE_UNUSED AbstractRouter* router) const
{
if(!Verify(router->crypto()))
if(!Verify())
return false;
return session->GotLIM(this);
}
@ -132,7 +133,7 @@ namespace llarp
}
bool
LinkIntroMessage::Verify(llarp::Crypto* c) const
LinkIntroMessage::Verify() const
{
LinkIntroMessage copy;
copy = *this;
@ -144,13 +145,13 @@ namespace llarp
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// outer signature
if(!c->verify(rc.pubkey, buf, Z))
if(!CryptoManager::instance()->verify(rc.pubkey, buf, Z))
{
llarp::LogError("outer signature failure");
return false;
}
// verify RC
if(!rc.Verify(c, llarp::time_now_ms()))
if(!rc.Verify(llarp::time_now_ms()))
{
llarp::LogError("invalid RC in link intro");
return false;

@ -35,7 +35,7 @@ namespace llarp
Sign(std::function< bool(Signature&, const llarp_buffer_t&) > signer);
bool
Verify(llarp::Crypto* c) const;
Verify() const;
void
Clear() override;

@ -1,5 +1,6 @@
#include <messages/relay_commit.hpp>
#include <crypto/crypto.hpp>
#include <messages/path_confirm.hpp>
#include <path/path.hpp>
#include <router/abstractrouter.hpp>
@ -235,7 +236,7 @@ namespace llarp
// ... and it's valid
const auto now = self->context->Router()->Now();
if(self->record.nextRC->IsPublicRouter()
&& self->record.nextRC->Verify(self->context->crypto(), now))
&& self->record.nextRC->Verify(now))
{
llarp_nodedb* n = self->context->Router()->nodedb();
const RouterContact rc = *self->record.nextRC;
@ -309,7 +310,7 @@ namespace llarp
return;
}
// generate path key as we are in a worker thread
auto crypto = self->context->crypto();
auto crypto = CryptoManager::instance();
if(!crypto->dh_server(self->hop->pathKey, self->record.commkey,
self->context->EncryptionSecretKey(),
self->record.tunnelNonce))
@ -321,10 +322,7 @@ namespace llarp
// generate hash of hop key for nonce mutation
crypto->shorthash(self->hop->nonceXOR,
llarp_buffer_t(self->hop->pathKey));
using namespace std::placeholders;
if(self->record.work
&& self->record.work->IsValid(
std::bind(&Crypto::shorthash, crypto, _1, _2), now))
if(self->record.work && self->record.work->IsValid(now))
{
llarp::LogDebug("LRCM extended lifetime by ",
self->record.work->extendedLifetime, " seconds for ",
@ -382,8 +380,7 @@ namespace llarp
LR_CommitMessage::AsyncDecrypt(llarp::path::PathContext* context) const
{
auto decrypter = std::make_unique< LRCMFrameDecrypt::Decrypter >(
context->crypto(), context->EncryptionSecretKey(),
&LRCMFrameDecrypt::HandleDecrypted);
context->EncryptionSecretKey(), &LRCMFrameDecrypt::HandleDecrypted);
// copy frames so we own them
auto frameDecrypt = std::make_shared< LRCMFrameDecrypt >(
context, std::move(decrypter), this);

@ -209,7 +209,7 @@ llarp_nodedb::loadfile(const fs::path &fpath)
llarp::LogError("failed to read file ", fpath);
return false;
}
if(!rc.Verify(crypto, llarp::time_now_ms()))
if(!rc.Verify(llarp::time_now_ms()))
{
llarp::LogError(fpath, " contains invalid RC");
return false;
@ -295,8 +295,7 @@ crypto_threadworker_verifyrc(void *user)
llarp_async_verify_rc *verify_request =
static_cast< llarp_async_verify_rc * >(user);
llarp::RouterContact rc = verify_request->rc;
verify_request->valid =
rc.Verify(verify_request->nodedb->crypto, llarp::time_now_ms());
verify_request->valid = rc.Verify(llarp::time_now_ms());
// if it's valid we need to set it
if(verify_request->valid && rc.IsPublicRouter())
{

@ -26,7 +26,6 @@ struct llarp_threadpool;
namespace llarp
{
struct Crypto;
class Logic;
namespace thread
@ -45,8 +44,8 @@ struct llarp_nodedb_iter
struct llarp_nodedb
{
llarp_nodedb(llarp::Crypto *c, llarp::thread::ThreadPool *diskworker)
: crypto(c), disk(diskworker)
explicit llarp_nodedb(llarp::thread::ThreadPool *diskworker)
: disk(diskworker)
{
}
@ -55,7 +54,6 @@ struct llarp_nodedb
Clear();
}
llarp::Crypto *crypto;
llarp::thread::ThreadPool *disk;
mutable llarp::util::Mutex access; // protects entries
std::unordered_map< llarp::RouterID, llarp::RouterContact,

@ -57,12 +57,6 @@ namespace llarp
return m_Router->threadpool();
}
Crypto*
PathContext::crypto()
{
return m_Router->crypto();
}
std::shared_ptr< Logic >
PathContext::logic()
{
@ -617,7 +611,7 @@ namespace llarp
TunnelNonce n = Y;
for(const auto& hop : hops)
{
r->crypto()->xchacha20(buf, hop.shared, n);
CryptoManager::instance()->xchacha20(buf, hop.shared, n);
n ^= hop.nonceXOR;
}
RelayUpstreamMessage msg;
@ -659,7 +653,7 @@ namespace llarp
for(const auto& hop : hops)
{
n ^= hop.nonceXOR;
r->crypto()->xchacha20(buf, hop.shared, n);
CryptoManager::instance()->xchacha20(buf, hop.shared, n);
}
if(!HandleRoutingMessage(buf, r))
return false;
@ -719,7 +713,7 @@ namespace llarp
if(buf.sz < pad_size)
{
// randomize padding
r->crypto()->randbytes(buf.cur, pad_size - buf.sz);
CryptoManager::instance()->randbytes(buf.cur, pad_size - buf.sz);
buf.sz = pad_size;
}
buf.cur = buf.base;
@ -819,12 +813,12 @@ namespace llarp
bool
Path::HandleCloseExitMessage(const routing::CloseExitMessage& msg,
AbstractRouter* r)
ABSL_ATTRIBUTE_UNUSED AbstractRouter* r)
{
/// allows exits to close from their end
if(SupportsAnyRoles(ePathRoleExit | ePathRoleSVC))
{
if(msg.Verify(r->crypto(), EndpointPubKey()))
if(msg.Verify(EndpointPubKey()))
{
LogInfo(Name(), " had its exit closed");
_role &= ~ePathRoleExit;
@ -882,7 +876,7 @@ namespace llarp
{
if(m_ExitObtainTX && msg.T == m_ExitObtainTX)
{
if(!msg.Verify(r->crypto(), EndpointPubKey()))
if(!msg.Verify(EndpointPubKey()))
{
LogError(Name(), "RXM invalid signature");
return false;
@ -901,7 +895,7 @@ namespace llarp
{
if(m_ExitObtainTX && msg.T == m_ExitObtainTX)
{
if(!msg.Verify(r->crypto(), EndpointPubKey()))
if(!msg.Verify(EndpointPubKey()))
{
LogError(Name(), " GXM signature failed");
return false;

@ -27,7 +27,6 @@ namespace llarp
{
class Logic;
struct AbstractRouter;
struct Crypto;
struct LR_CommitMessage;
struct LR_CommitRecord;
@ -705,9 +704,6 @@ namespace llarp
llarp_threadpool*
Worker();
llarp::Crypto*
crypto();
std::shared_ptr< Logic >
logic();

@ -1,5 +1,6 @@
#include <path/pathbuilder.hpp>
#include <crypto/crypto.hpp>
#include <messages/relay_commit.hpp>
#include <nodedb.hpp>
#include <path/path.hpp>
@ -27,7 +28,6 @@ namespace llarp
AbstractRouter* router = nullptr;
llarp_threadpool* worker = nullptr;
std::shared_ptr< Logic > logic = nullptr;
Crypto* crypto = nullptr;
LR_CommitMessage LRCM;
~AsyncPathKeyExchangeContext()
@ -53,12 +53,13 @@ namespace llarp
auto& hop = ctx->path->hops[ctx->idx];
auto& frame = ctx->LRCM.frames[ctx->idx];
auto crypto = CryptoManager::instance();
// generate key
ctx->crypto->encryption_keygen(hop.commkey);
crypto->encryption_keygen(hop.commkey);
hop.nonce.Randomize();
// do key exchange
if(!ctx->crypto->dh_client(hop.shared, hop.rc.enckey, hop.commkey,
hop.nonce))
if(!crypto->dh_client(hop.shared, hop.rc.enckey, hop.commkey, hop.nonce))
{
LogError(ctx->pathset->Name(),
" Failed to generate shared key for path build");
@ -66,7 +67,7 @@ namespace llarp
return;
}
// generate nonceXOR valueself->hop->pathKey
ctx->crypto->shorthash(hop.nonceXOR, llarp_buffer_t(hop.shared));
crypto->shorthash(hop.nonceXOR, llarp_buffer_t(hop.shared));
++ctx->idx;
bool isFarthestHop = ctx->idx == ctx->path->hops.size();
@ -104,8 +105,8 @@ namespace llarp
}
// use ephemeral keypair for frame
SecretKey framekey;
ctx->crypto->encryption_keygen(framekey);
if(!frame.EncryptInPlace(framekey, hop.rc.enckey, ctx->crypto))
crypto->encryption_keygen(framekey);
if(!frame.EncryptInPlace(framekey, hop.rc.enckey))
{
LogError(ctx->pathset->Name(), " Failed to encrypt LRCR");
delete ctx;
@ -125,10 +126,6 @@ namespace llarp
}
}
AsyncPathKeyExchangeContext(Crypto* c) : crypto(c)
{
}
/// Generate all keys asynchronously and call handler when done
void
AsyncGenerateKeys(Path_t p, std::shared_ptr< Logic > l,
@ -173,7 +170,7 @@ namespace llarp
size_t pathNum, size_t hops)
: path::PathSet(pathNum), router(p_router), dht(p_dht), numHops(hops)
{
p_router->crypto()->encryption_keygen(enckey);
CryptoManager::instance()->encryption_keygen(enckey);
_run.store(true);
}
@ -319,7 +316,7 @@ namespace llarp
const auto aligned =
router->pathContext().FindOwnedPathsWithEndpoint(remote);
/// pick the lowest latency path that aligns to remote
/// note: peer exuastion is made worse happen here
/// note: peer exhaustion is made worse happen here
Path_ptr p;
llarp_time_t min = std::numeric_limits< llarp_time_t >::max();
for(const auto& path : aligned)
@ -409,7 +406,7 @@ namespace llarp
lastBuild = Now();
// async generate keys
AsyncPathKeyExchangeContext< Builder >* ctx =
new AsyncPathKeyExchangeContext< Builder >(router->crypto());
new AsyncPathKeyExchangeContext< Builder >();
ctx->router = router;
ctx->pathset = GetSelf();
auto path = std::make_shared< path::Path >(hops, this, roles);

@ -64,7 +64,7 @@ namespace llarp
{
dlt = pad_size - dlt;
// randomize padding
r->crypto()->randbytes(buf.cur, dlt);
CryptoManager::instance()->randbytes(buf.cur, dlt);
buf.sz += dlt;
}
buf.cur = buf.base;
@ -78,7 +78,7 @@ namespace llarp
RelayDownstreamMessage msg;
msg.pathid = info.rxID;
msg.Y = Y ^ nonceXOR;
r->crypto()->xchacha20(buf, pathKey, Y);
CryptoManager::instance()->xchacha20(buf, pathKey, Y);
msg.X = buf;
llarp::LogDebug("relay ", msg.X.size(), " bytes downstream from ",
info.upstream, " to ", info.downstream);
@ -89,7 +89,7 @@ namespace llarp
TransitHop::HandleUpstream(const llarp_buffer_t& buf, const TunnelNonce& Y,
AbstractRouter* r)
{
r->crypto()->xchacha20(buf, pathKey, Y);
CryptoManager::instance()->xchacha20(buf, pathKey, Y);
if(IsEndpoint(r->pubkey()))
{
m_LastActivity = r->Now();
@ -146,13 +146,13 @@ namespace llarp
TransitHop::HandleObtainExitMessage(
const llarp::routing::ObtainExitMessage& msg, AbstractRouter* r)
{
if(msg.Verify(r->crypto())
if(msg.Verify()
&& r->exitContext().ObtainNewExit(msg.I, info.rxID, msg.E != 0))
{
llarp::routing::GrantExitMessage grant;
grant.S = NextSeqNo();
grant.T = msg.T;
if(!grant.Sign(r->crypto(), r->identity()))
if(!grant.Sign(r->identity()))
{
llarp::LogError("Failed to sign grant exit message");
return false;
@ -164,7 +164,7 @@ namespace llarp
llarp::routing::RejectExitMessage reject;
reject.S = NextSeqNo();
reject.T = msg.T;
if(!reject.Sign(r->crypto(), r->identity()))
if(!reject.Sign(r->identity()))
{
llarp::LogError("Failed to sign reject exit message");
return false;
@ -178,12 +178,12 @@ namespace llarp
{
const llarp::routing::DataDiscardMessage discard(info.rxID, msg.S);
auto ep = r->exitContext().FindEndpointForPath(info.rxID);
if(ep && msg.Verify(r->crypto(), ep->PubKey()))
if(ep && msg.Verify(ep->PubKey()))
{
llarp::routing::CloseExitMessage reply;
reply.Y = msg.Y;
reply.S = NextSeqNo();
if(reply.Sign(r->crypto(), r->identity()))
if(reply.Sign(r->identity()))
{
if(SendRoutingMessage(reply, r))
{
@ -213,7 +213,7 @@ namespace llarp
auto ep = r->exitContext().FindEndpointForPath(msg.P);
if(ep)
{
if(!msg.Verify(r->crypto(), ep->PubKey()))
if(!msg.Verify(ep->PubKey()))
return false;
if(ep->UpdateLocalPath(info.rxID))

@ -1,5 +1,6 @@
#include <pow.hpp>
#include <crypto/crypto.hpp>
#include <util/buffer.hpp>
#include <cmath>
@ -28,7 +29,7 @@ namespace llarp
}
bool
PoW::IsValid(shorthash_func hashfunc, llarp_time_t now) const
PoW::IsValid(llarp_time_t now) const
{
if(now - timestamp > (uint64_t(extendedLifetime) * 1000))
return false;
@ -43,7 +44,7 @@ namespace llarp
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// hash
if(!hashfunc(digest, buf))
if(!CryptoManager::instance()->shorthash(digest, buf))
return false;
// check bytes required
uint32_t required = std::floor(std::log(extendedLifetime));

@ -1,7 +1,6 @@
#ifndef LLARP_POW_HPP
#define LLARP_POW_HPP
#include <crypto/crypto.hpp>
#include <router_id.hpp>
#include <util/buffer.hpp>
@ -19,7 +18,7 @@ namespace llarp
~PoW();
bool
IsValid(shorthash_func hashfunc, llarp_time_t now) const;
IsValid(llarp_time_t now) const;
bool
DecodeKey(const llarp_buffer_t& k, llarp_buffer_t* val);

@ -17,7 +17,6 @@ namespace llarp
{
class Logic;
struct Config;
struct Crypto;
struct RouterID;
struct ILinkMessage;
struct ILinkSession;
@ -68,9 +67,6 @@ namespace llarp
virtual llarp_dht_context *
dht() const = 0;
virtual Crypto *
crypto() const = 0;
virtual llarp_nodedb *
nodedb() const = 0;

@ -115,7 +115,7 @@ on_try_connecting(std::shared_ptr< TryConnectJob > j)
}
bool
llarp_loadServiceNodeIdentityKey(llarp::Crypto *crypto, const fs::path &fpath,
llarp_loadServiceNodeIdentityKey(const fs::path &fpath,
llarp::SecretKey &secret)
{
std::string path = fpath.string();
@ -124,12 +124,11 @@ llarp_loadServiceNodeIdentityKey(llarp::Crypto *crypto, const fs::path &fpath,
if(!ident.LoadFromFile(path.c_str()))
return false;
return crypto->seed_to_secretkey(secret, ident);
return llarp::CryptoManager::instance()->seed_to_secretkey(secret, ident);
}
bool
llarp_findOrCreateIdentity(llarp::Crypto *crypto, const fs::path &path,
llarp::SecretKey &secretkey)
llarp_findOrCreateIdentity(const fs::path &path, llarp::SecretKey &secretkey)
{
std::string fpath = path.string();
llarp::LogDebug("find or create ", fpath);
@ -137,7 +136,7 @@ llarp_findOrCreateIdentity(llarp::Crypto *crypto, const fs::path &path,
if(!fs::exists(path, ec))
{
llarp::LogInfo("generating new identity key");
crypto->identity_keygen(secretkey);
llarp::CryptoManager::instance()->identity_keygen(secretkey);
if(!secretkey.SaveToFile(fpath.c_str()))
return false;
}
@ -146,8 +145,7 @@ llarp_findOrCreateIdentity(llarp::Crypto *crypto, const fs::path &path,
// C++ ...
bool
llarp_findOrCreateEncryption(llarp::Crypto *crypto, const fs::path &path,
llarp::SecretKey &encryption)
llarp_findOrCreateEncryption(const fs::path &path, llarp::SecretKey &encryption)
{
std::string fpath = path.string();
llarp::LogDebug("find or create ", fpath);
@ -155,7 +153,7 @@ llarp_findOrCreateEncryption(llarp::Crypto *crypto, const fs::path &path,
if(!fs::exists(path, ec))
{
llarp::LogInfo("generating new encryption key");
crypto->encryption_keygen(encryption);
llarp::CryptoManager::instance()->encryption_keygen(encryption);
if(!encryption.SaveToFile(fpath.c_str()))
return false;
}
@ -212,7 +210,6 @@ namespace llarp
, _netloop(__netloop)
, tp(_tp)
, _logic(l)
, _crypto(std::make_unique< sodium::CryptoLibSodium >())
, paths(this)
, _exitContext(this)
, disk(1, 1000)
@ -376,7 +373,7 @@ namespace llarp
{
return;
}
if(results[0].Verify(crypto(), Now()))
if(results[0].Verify(Now()))
{
TryConnectAsync(results[0], 10);
return;
@ -423,7 +420,7 @@ namespace llarp
LogError("failure to decode or verify of remote RC");
return;
}
if(remote.Verify(crypto(), Now()))
if(remote.Verify(Now()))
{
LogDebug("verified signature");
if(!TryConnectAsync(remote, 10))
@ -442,17 +439,15 @@ namespace llarp
if(!EnsureEncryptionKey())
return false;
if(usingSNSeed)
return llarp_loadServiceNodeIdentityKey(crypto(), ident_keyfile,
_identity);
return llarp_loadServiceNodeIdentityKey(ident_keyfile, _identity);
else
return llarp_findOrCreateIdentity(crypto(), ident_keyfile, _identity);
return llarp_findOrCreateIdentity(ident_keyfile, _identity);
}
bool
Router::EnsureEncryptionKey()
{
return llarp_findOrCreateEncryption(crypto(), encryption_keyfile,
_encryption);
return llarp_findOrCreateEncryption(encryption_keyfile, _encryption);
}
void
@ -496,7 +491,7 @@ namespace llarp
Router::SaveRC()
{
LogDebug("verify RC signature");
if(!_rc.Verify(crypto(), Now()))
if(!_rc.Verify(Now()))
{
Dump< MAX_RC_SIZE >(rc());
LogError("RC is invalid, not saving");
@ -617,7 +612,7 @@ namespace llarp
const auto numConnected = NumberOfConnectedRouters();
for(const auto &rc : results)
{
if(!rc.Verify(crypto(), Now()))
if(!rc.Verify(Now()))
continue;
nodedb()->InsertAsync(rc);
@ -745,7 +740,7 @@ namespace llarp
RouterContact nextRC = _rc;
if(rotateKeys)
{
crypto()->encryption_keygen(nextOnionKey);
CryptoManager::instance()->encryption_keygen(nextOnionKey);
std::string f = encryption_keyfile.string();
// TODO: use disk worker
if(nextOnionKey.SaveToFile(f.c_str()))
@ -755,7 +750,7 @@ namespace llarp
}
}
nextRC.last_updated = Now();
if(!nextRC.Sign(crypto(), identity()))
if(!nextRC.Sign(identity()))
return false;
_rc = nextRC;
// propagate RC by renegotiating sessions
@ -1010,7 +1005,7 @@ namespace llarp
;
return;
}
if(rc.Verify(crypto(), Now()))
if(rc.Verify(Now()))
{
const auto result = bootstrapRCList.insert(rc);
if(result.second)
@ -1331,7 +1326,7 @@ namespace llarp
Router::Sign(Signature &sig, const llarp_buffer_t &buf) const
{
METRICS_TIME_BLOCK("Router", "Sign");
return crypto()->sign(sig, identity(), buf);
return CryptoManager::instance()->sign(sig, identity(), buf);
}
void
@ -1626,7 +1621,7 @@ namespace llarp
_rc.enckey = seckey_topublic(encryption());
LogInfo("Signing rc...");
if(!_rc.Sign(crypto(), identity()))
if(!_rc.Sign(identity()))
{
LogError("failed to sign rc");
return false;
@ -1684,11 +1679,11 @@ namespace llarp
maxConnectedRouters = minConnectedRouters + 1;
// we are a client
// regenerate keys and resign rc before everything else
crypto()->identity_keygen(_identity);
crypto()->encryption_keygen(_encryption);
CryptoManager::instance()->identity_keygen(_identity);
CryptoManager::instance()->encryption_keygen(_encryption);
_rc.pubkey = seckey_topublic(identity());
_rc.enckey = seckey_topublic(encryption());
if(!_rc.Sign(crypto(), identity()))
if(!_rc.Sign(identity()))
{
LogError("failed to regenerate keys and sign RC");
return false;

@ -37,19 +37,17 @@
namespace llarp
{
struct Config;
struct Crypto;
} // namespace llarp
bool
llarp_findOrCreateEncryption(llarp::Crypto *crypto, const fs::path &fpath,
llarp_findOrCreateEncryption(const fs::path &fpath,
llarp::SecretKey &encryption);
bool
llarp_findOrCreateIdentity(llarp::Crypto *crypto, const fs::path &path,
llarp::SecretKey &secretkey);
llarp_findOrCreateIdentity(const fs::path &path, llarp::SecretKey &secretkey);
bool
llarp_loadServiceNodeIdentityKey(llarp::Crypto *crypto, const fs::path &fpath,
llarp_loadServiceNodeIdentityKey(const fs::path &fpath,
llarp::SecretKey &secretkey);
struct TryConnectJob;
@ -101,12 +99,6 @@ namespace llarp
util::StatusObject
ExtractStatus() const override;
Crypto *
crypto() const override
{
return _crypto.get();
}
llarp_nodedb *
nodedb() const override
{
@ -184,7 +176,6 @@ namespace llarp
llarp_ev_loop_ptr _netloop;
llarp_threadpool *tp;
std::shared_ptr< Logic > _logic;
std::unique_ptr< Crypto > _crypto;
path::PathContext paths;
exit::Context _exitContext;
SecretKey _identity;

@ -263,7 +263,7 @@ namespace llarp
}
bool
RouterContact::Sign(llarp::Crypto *crypto, const SecretKey &secretkey)
RouterContact::Sign(const SecretKey &secretkey)
{
pubkey = llarp::seckey_topublic(secretkey);
std::array< byte_t, MAX_RC_SIZE > tmp;
@ -274,11 +274,11 @@ namespace llarp
return false;
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return crypto->sign(signature, secretkey, buf);
return CryptoManager::instance()->sign(signature, secretkey, buf);
}
bool
RouterContact::Verify(llarp::Crypto *crypto, llarp_time_t now) const
RouterContact::Verify(llarp_time_t now) const
{
if(netID != NetID::DefaultValue())
{
@ -307,7 +307,7 @@ namespace llarp
return false;
}
}
if(!VerifySignature(crypto))
if(!VerifySignature())
{
llarp::LogError("invalid signature");
return false;
@ -316,7 +316,7 @@ namespace llarp
}
bool
RouterContact::VerifySignature(llarp::Crypto *crypto) const
RouterContact::VerifySignature() const
{
RouterContact copy;
copy = *this;
@ -330,7 +330,7 @@ namespace llarp
}
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return crypto->verify(pubkey, buf, signature);
return CryptoManager::instance()->verify(pubkey, buf, signature);
}
bool

@ -17,8 +17,6 @@
namespace llarp
{
struct Crypto;
/// NetID
struct NetID final : public AlignedBuffer< 8 >
{
@ -166,10 +164,10 @@ namespace llarp
SetNick(const std::string &nick);
bool
Verify(llarp::Crypto *crypto, llarp_time_t now) const;
Verify(llarp_time_t now) const;
bool
Sign(llarp::Crypto *crypto, const llarp::SecretKey &secret);
Sign(const llarp::SecretKey &secret);
/// does this RC expire soon? default delta is 1 minute
bool
@ -195,7 +193,7 @@ namespace llarp
private:
bool
VerifySignature(llarp::Crypto *crypto) const;
VerifySignature() const;
};
inline std::ostream &

@ -8,14 +8,13 @@ namespace llarp
{
namespace service
{
AsyncKeyExchange::AsyncKeyExchange(std::shared_ptr< Logic > l, Crypto* c,
AsyncKeyExchange::AsyncKeyExchange(std::shared_ptr< Logic > l,
const ServiceInfo& r,
const Identity& localident,
const PQPubKey& introsetPubKey,
const Introduction& remote,
IDataHandler* h, const ConvoTag& t)
: logic(l)
, crypto(c)
, remote(r)
, m_LocalIdentity(localident)
, introPubKey(introsetPubKey)
@ -44,7 +43,8 @@ namespace llarp
AsyncKeyExchange* self = static_cast< AsyncKeyExchange* >(user);
// derive ntru session key component
SharedSecret K;
self->crypto->pqe_encrypt(self->frame.C, K, self->introPubKey);
auto crypto = CryptoManager::instance();
crypto->pqe_encrypt(self->frame.C, K, self->introPubKey);
// randomize Nonce
self->frame.N.Randomize();
// compure post handshake session key
@ -52,7 +52,7 @@ namespace llarp
SharedSecret sharedSecret;
using namespace std::placeholders;
path_dh_func dh_client =
std::bind(&Crypto::dh_client, self->crypto, _1, _2, _3, _4);
std::bind(&Crypto::dh_client, crypto, _1, _2, _3, _4);
if(!self->m_LocalIdentity.KeyExchange(dh_client, sharedSecret,
self->remote, self->frame.N))
{
@ -63,7 +63,7 @@ namespace llarp
std::copy(K.begin(), K.end(), tmp.begin());
// H (K + PKE(A, B, N))
std::copy(sharedSecret.begin(), sharedSecret.end(), tmp.begin() + 32);
self->crypto->shorthash(self->sharedKey, llarp_buffer_t(tmp));
crypto->shorthash(self->sharedKey, llarp_buffer_t(tmp));
// set tag
self->msg.tag = self->tag;
// set sender
@ -73,8 +73,7 @@ namespace llarp
// set protocol
self->msg.proto = eProtocolTraffic;
// encrypt and sign
if(self->frame.EncryptAndSign(self->crypto, self->msg, K,
self->m_LocalIdentity))
if(self->frame.EncryptAndSign(self->msg, K, self->m_LocalIdentity))
self->logic->queue_job({self, &Result});
else
{

@ -8,14 +8,12 @@
namespace llarp
{
class Logic;
struct Crypto;
namespace service
{
struct AsyncKeyExchange
{
std::shared_ptr< Logic > logic;
Crypto* crypto;
SharedSecret sharedKey;
ServiceInfo remote;
const Identity& m_LocalIdentity;
@ -28,8 +26,8 @@ namespace llarp
IDataHandler* handler;
ConvoTag tag;
AsyncKeyExchange(std::shared_ptr< Logic > l, Crypto* c,
const ServiceInfo& r, const Identity& localident,
AsyncKeyExchange(std::shared_ptr< Logic > l, const ServiceInfo& r,
const Identity& localident,
const PQPubKey& introsetPubKey,
const Introduction& remote, IDataHandler* h,
const ConvoTag& t);

@ -159,7 +159,7 @@ namespace llarp
return;
}
m_IntroSet.topic = m_Tag;
if(!m_Identity.SignIntroSet(m_IntroSet, m_Router->crypto(), now))
if(!m_Identity.SignIntroSet(m_IntroSet, now))
{
LogWarn("failed to sign introset for endpoint ", Name());
return;
@ -347,11 +347,10 @@ namespace llarp
bool
Endpoint::HandleGotIntroMessage(dht::GotIntroMessage_constptr msg)
{
auto crypto = m_Router->crypto();
std::set< IntroSet > remote;
for(const auto& introset : msg->I)
{
if(!introset.Verify(crypto, Now()))
if(!introset.Verify(Now()))
{
if(m_Identity.pub == introset.A && m_CurrentPublishTX == msg->T)
IntroSetPublishFail();
@ -482,10 +481,9 @@ namespace llarp
bool
Endpoint::LoadKeyFile()
{
auto crypto = m_Router->crypto();
if(!m_Keyfile.empty())
{
if(!m_Identity.EnsureKeys(m_Keyfile, crypto))
if(!m_Identity.EnsureKeys(m_Keyfile))
{
LogError("Can't ensure keyfile [", m_Keyfile, "]");
return false;
@ -493,7 +491,7 @@ namespace llarp
}
else
{
m_Identity.RegenerateKeys(crypto);
m_Identity.RegenerateKeys();
}
return true;
}
@ -884,16 +882,15 @@ namespace llarp
if(!GetSenderFor(frame.T, si))
return false;
// verify source
if(!frame.Verify(crypto(), si))
if(!frame.Verify(si))
return false;
// remove convotag it doesn't exist
LogWarn("remove convotag T=", frame.T);
RemoveConvoTag(frame.T);
return true;
}
if(!frame.AsyncDecryptAndVerify(EndpointLogic(), crypto(), p,
CryptoWorker(), m_Identity,
m_DataHandler))
if(!frame.AsyncDecryptAndVerify(EndpointLogic(), p, CryptoWorker(),
m_Identity, m_DataHandler))
{
// send discard
ProtocolFrame f;
@ -901,7 +898,7 @@ namespace llarp
f.T = frame.T;
f.F = p->intro.pathID;
if(!f.Sign(crypto(), m_Identity))
if(!f.Sign(m_Identity))
return false;
{
util::Lock lock(&m_SendQueueMutex);
@ -1047,7 +1044,7 @@ namespace llarp
// send downstream packets to user for snode
for(const auto& item : m_SNodeSessions)
item.second->FlushDownstream();
// send downstrream traffic to user for hidden service
// send downstream traffic to user for hidden service
util::Lock lock(&m_InboundTrafficQueueMutex);
while(m_InboundTrafficQueue.size())
{
@ -1128,7 +1125,7 @@ namespace llarp
f.F = m.introReply.pathID;
f.S = GetSeqNoForConvo(f.T);
transfer->P = remoteIntro.pathID;
if(!f.EncryptAndSign(Router()->crypto(), m, K, m_Identity))
if(!f.EncryptAndSign(m, K, m_Identity))
{
LogError("failed to encrypt and sign");
return false;
@ -1225,12 +1222,6 @@ namespace llarp
return m_IsolatedLogic ? m_IsolatedLogic : m_Router->logic();
}
Crypto*
Endpoint::crypto()
{
return m_Router->crypto();
}
llarp_threadpool*
Endpoint::CryptoWorker()
{

@ -105,9 +105,6 @@ namespace llarp
llarp_ev_loop_ptr
EndpointNetLoop();
Crypto*
crypto();
/// crypto worker threadpool
llarp_threadpool*
CryptoWorker();

@ -1,5 +1,6 @@
#include <service/identity.hpp>
#include <crypto/crypto.hpp>
#include <util/fs.hpp>
namespace llarp
@ -53,8 +54,9 @@ namespace llarp
}
void
Identity::RegenerateKeys(Crypto* crypto)
Identity::RegenerateKeys()
{
auto crypto = CryptoManager::instance();
crypto->encryption_keygen(enckey);
crypto->identity_keygen(signkey);
pub.Update(seckey_topublic(enckey), seckey_topublic(signkey));
@ -70,13 +72,13 @@ namespace llarp
}
bool
Identity::Sign(Crypto* c, Signature& sig, const llarp_buffer_t& buf) const
Identity::Sign(Signature& sig, const llarp_buffer_t& buf) const
{
return c->sign(sig, signkey, buf);
return CryptoManager::instance()->sign(sig, signkey, buf);
}
bool
Identity::EnsureKeys(const std::string& fname, Crypto* c)
Identity::EnsureKeys(const std::string& fname)
{
std::array< byte_t, 4096 > tmp;
llarp_buffer_t buf(tmp);
@ -90,7 +92,7 @@ namespace llarp
return false;
}
// regen and encode
RegenerateKeys(c);
RegenerateKeys();
if(!BEncode(&buf))
return false;
// rewind
@ -132,7 +134,7 @@ namespace llarp
}
bool
Identity::SignIntroSet(IntroSet& i, Crypto* crypto, llarp_time_t now) const
Identity::SignIntroSet(IntroSet& i, llarp_time_t now) const
{
if(i.I.size() == 0)
return false;
@ -152,7 +154,7 @@ namespace llarp
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
return Sign(crypto, i.Z, buf);
return Sign(i.Z, buf);
}
} // namespace service
} // namespace llarp

@ -12,8 +12,6 @@
namespace llarp
{
struct Crypto;
namespace service
{
// private keys
@ -30,13 +28,13 @@ namespace llarp
// regenerate secret keys
void
RegenerateKeys(Crypto* c);
RegenerateKeys();
bool
BEncode(llarp_buffer_t* buf) const;
bool
EnsureKeys(const std::string& fpath, Crypto* c);
EnsureKeys(const std::string& fpath);
bool
KeyExchange(path_dh_func dh, SharedSecret& sharedkey,
@ -46,10 +44,10 @@ namespace llarp
DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf);
bool
SignIntroSet(IntroSet& i, Crypto* c, llarp_time_t now) const;
SignIntroSet(IntroSet& i, llarp_time_t now) const;
bool
Sign(Crypto*, Signature& sig, const llarp_buffer_t& buf) const;
Sign(Signature& sig, const llarp_buffer_t& buf) const;
};
inline bool

@ -13,10 +13,10 @@ namespace llarp
namespace service
{
bool
ServiceInfo::Verify(Crypto* crypto, const llarp_buffer_t& payload,
ServiceInfo::Verify(const llarp_buffer_t& payload,
const Signature& sig) const
{
return crypto->verify(signkey, payload, sig);
return CryptoManager::instance()->verify(signkey, payload, sig);
}
bool

@ -10,8 +10,6 @@
namespace llarp
{
struct Crypto;
namespace service
{
struct ServiceInfo
@ -34,8 +32,7 @@ namespace llarp
}
bool
Verify(Crypto* crypto, const llarp_buffer_t& payload,
const Signature& sig) const;
Verify(const llarp_buffer_t& payload, const Signature& sig) const;
const PubKey&
EncryptionPublicKey() const

@ -114,7 +114,7 @@ namespace llarp
}
bool
IntroSet::Verify(Crypto* crypto, llarp_time_t now) const
IntroSet::Verify(llarp_time_t now) const
{
std::array< byte_t, MAX_INTROSET_SIZE > tmp;
llarp_buffer_t buf(tmp);
@ -128,13 +128,12 @@ namespace llarp
// rewind and resize buffer
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
if(!A.Verify(crypto, buf, Z))
if(!A.Verify(buf, Z))
{
return false;
}
// validate PoW
using namespace std::placeholders;
if(W && !W->IsValid(std::bind(&Crypto::shorthash, crypto, _1, _2), now))
if(W && !W->IsValid(now))
{
return false;
}

@ -18,8 +18,6 @@
namespace llarp
{
struct Crypto;
namespace service
{
constexpr std::size_t MAX_INTROSET_SIZE = 4096;
@ -70,7 +68,7 @@ namespace llarp
DecodeKey(const llarp_buffer_t& key, llarp_buffer_t* buf);
bool
Verify(Crypto* crypto, llarp_time_t now) const;
Verify(llarp_time_t now) const;
util::StatusObject
ExtractStatus() const;

@ -161,9 +161,8 @@ namespace llarp
}
currentConvoTag.Randomize();
AsyncKeyExchange* ex = new AsyncKeyExchange(
m_Endpoint->RouterLogic(), m_Endpoint->crypto(), remoteIdent,
m_Endpoint->GetIdentity(), currentIntroSet.K, remoteIntro,
m_DataHandler, currentConvoTag);
m_Endpoint->RouterLogic(), remoteIdent, m_Endpoint->GetIdentity(),
currentIntroSet.K, remoteIntro, m_DataHandler, currentConvoTag);
ex->hook =
std::bind(&OutboundContext::Send, this, std::placeholders::_1, path);

@ -172,18 +172,17 @@ namespace llarp
}
bool
ProtocolFrame::DecryptPayloadInto(Crypto* crypto,
const SharedSecret& sharedkey,
ProtocolFrame::DecryptPayloadInto(const SharedSecret& sharedkey,
ProtocolMessage& msg) const
{
Encrypted_t tmp = D;
auto buf = tmp.Buffer();
crypto->xchacha20(*buf, sharedkey, N);
CryptoManager::instance()->xchacha20(*buf, sharedkey, N);
return bencode_decode_dict(msg, buf);
}
bool
ProtocolFrame::Sign(Crypto* crypto, const Identity& localIdent)
ProtocolFrame::Sign(const Identity& localIdent)
{
Z.Zero();
std::array< byte_t, MAX_PROTOCOL_MESSAGE_SIZE > tmp;
@ -198,11 +197,11 @@ namespace llarp
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// sign
return localIdent.Sign(crypto, Z, buf);
return localIdent.Sign(Z, buf);
}
bool
ProtocolFrame::EncryptAndSign(Crypto* crypto, const ProtocolMessage& msg,
ProtocolFrame::EncryptAndSign(const ProtocolMessage& msg,
const SharedSecret& sessionKey,
const Identity& localIdent)
{
@ -218,7 +217,7 @@ namespace llarp
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// encrypt
crypto->xchacha20(buf, sessionKey, N);
CryptoManager::instance()->xchacha20(buf, sessionKey, N);
// put encrypted buffer
D = buf;
// zero out signature
@ -235,7 +234,7 @@ namespace llarp
buf2.sz = buf2.cur - buf2.base;
buf2.cur = buf2.base;
// sign
if(!localIdent.Sign(crypto, Z, buf2))
if(!localIdent.Sign(Z, buf2))
{
LogError("failed to sign? wtf?!");
return false;
@ -245,7 +244,6 @@ namespace llarp
struct AsyncFrameDecrypt
{
Crypto* crypto;
std::shared_ptr< Logic > logic;
std::shared_ptr< ProtocolMessage > msg;
const Identity& m_LocalIdentity;
@ -253,12 +251,11 @@ namespace llarp
const ProtocolFrame frame;
const Introduction fromIntro;
AsyncFrameDecrypt(std::shared_ptr< Logic > l, Crypto* c,
const Identity& localIdent, IDataHandler* h,
AsyncFrameDecrypt(std::shared_ptr< Logic > l, const Identity& localIdent,
IDataHandler* h,
const std::shared_ptr< ProtocolMessage >& m,
const ProtocolFrame& f, const Introduction& recvIntro)
: crypto(c)
, logic(l)
: logic(l)
, msg(m)
, m_LocalIdentity(localIdent)
, handler(h)
@ -271,7 +268,7 @@ namespace llarp
Work(void* user)
{
AsyncFrameDecrypt* self = static_cast< AsyncFrameDecrypt* >(user);
auto crypto = self->crypto;
auto crypto = CryptoManager::instance();
SharedSecret K;
SharedSecret sharedKey;
// copy
@ -296,7 +293,7 @@ namespace llarp
return;
}
// verify signature of outer message after we parsed the inner message
if(!self->frame.Verify(crypto, self->msg->sender))
if(!self->frame.Verify(self->msg->sender))
{
LogError("intro frame has invalid signature Z=", self->frame.Z,
" from ", self->msg->sender.Addr());
@ -319,8 +316,8 @@ namespace llarp
// PKE (A, B, N)
SharedSecret sharedSecret;
using namespace std::placeholders;
path_dh_func dh_server =
std::bind(&Crypto::dh_server, self->crypto, _1, _2, _3, _4);
path_dh_func dh_server = std::bind(
&Crypto::dh_server, CryptoManager::instance(), _1, _2, _3, _4);
if(!self->m_LocalIdentity.KeyExchange(dh_server, sharedSecret,
self->msg->sender, self->frame.N))
@ -367,7 +364,7 @@ namespace llarp
bool
ProtocolFrame::AsyncDecryptAndVerify(std::shared_ptr< Logic > logic,
Crypto* c, path::Path_ptr recvPath,
path::Path_ptr recvPath,
llarp_threadpool* worker,
const Identity& localIdent,
IDataHandler* handler) const
@ -378,8 +375,8 @@ namespace llarp
LogInfo("Got protocol frame with new convo");
msg->srcPath = recvPath->RXID();
// we need to dh
auto dh = new AsyncFrameDecrypt(logic, c, localIdent, handler, msg,
*this, recvPath->intro);
auto dh = new AsyncFrameDecrypt(logic, localIdent, handler, msg, *this,
recvPath->intro);
llarp_threadpool_queue_job(worker, {dh, &AsyncFrameDecrypt::Work});
return true;
}
@ -395,12 +392,12 @@ namespace llarp
LogError("No sender for T=", T);
return false;
}
if(!Verify(c, si))
if(!Verify(si))
{
LogError("Signature failure from ", si.Addr());
return false;
}
if(!DecryptPayloadInto(c, shared, *msg))
if(!DecryptPayloadInto(shared, *msg))
{
LogError("failed to decrypt message");
return false;
@ -419,7 +416,7 @@ namespace llarp
}
bool
ProtocolFrame::Verify(Crypto* crypto, const ServiceInfo& from) const
ProtocolFrame::Verify(const ServiceInfo& from) const
{
ProtocolFrame copy(*this);
// save signature
@ -438,7 +435,7 @@ namespace llarp
buf.sz = buf.cur - buf.base;
buf.cur = buf.base;
// verify
return from.Verify(crypto, buf, Z);
return from.Verify(buf, Z);
}
bool

@ -19,7 +19,6 @@ struct llarp_threadpool;
namespace llarp
{
struct Crypto;
class Logic;
namespace path
@ -120,20 +119,20 @@ namespace llarp
operator=(const ProtocolFrame& other);
bool
EncryptAndSign(Crypto* c, const ProtocolMessage& msg,
const SharedSecret& sharedkey, const Identity& localIdent);
EncryptAndSign(const ProtocolMessage& msg, const SharedSecret& sharedkey,
const Identity& localIdent);
bool
Sign(Crypto* c, const Identity& localIdent);
Sign(const Identity& localIdent);
bool
AsyncDecryptAndVerify(std::shared_ptr< Logic > logic, Crypto* c,
AsyncDecryptAndVerify(std::shared_ptr< Logic > logic,
path::Path_ptr fromPath, llarp_threadpool* worker,
const Identity& localIdent,
IDataHandler* handler) const;
bool
DecryptPayloadInto(Crypto* c, const SharedSecret& sharedkey,
DecryptPayloadInto(const SharedSecret& sharedkey,
ProtocolMessage& into) const;
bool
@ -161,7 +160,7 @@ namespace llarp
}
bool
Verify(Crypto* c, const ServiceInfo& from) const;
Verify(const ServiceInfo& from) const;
bool
HandleMessage(routing::IMessageHandler* h,

@ -55,7 +55,6 @@ namespace llarp
void
SendContext::EncryptAndSendTo(const llarp_buffer_t& payload, ProtocolType t)
{
auto crypto = m_Endpoint->Router()->crypto();
SharedSecret shared;
ProtocolFrame f;
f.N.Randomize();
@ -94,7 +93,7 @@ namespace llarp
m.sender = m_Endpoint->GetIdentity().pub;
m.tag = f.T;
m.PutBuffer(payload);
if(!f.EncryptAndSign(crypto, m, shared, m_Endpoint->GetIdentity()))
if(!f.EncryptAndSign(m, shared, m_Endpoint->GetIdentity()))
{
LogError("failed to sign");
return;

@ -114,6 +114,13 @@ struct llarp_buffer_t
{
}
// clang-format off
byte_t * begin() { return base; }
byte_t * begin() const { return base; }
byte_t * end() { return base + sz; }
byte_t * end() const { return base + sz; }
// clang-format on
size_t
size_left() const;

@ -138,16 +138,14 @@ namespace llarp
return 0;
}
LinkLayer::LinkLayer(Crypto* crypto, const SecretKey& routerEncSecret,
GetRCFunc getrc, LinkMessageHandler h,
SignBufferFunc sign,
LinkLayer::LinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler established,
SessionRenegotiateHandler reneg,
TimeoutHandler timeout, SessionClosedHandler closed)
: ILinkLayer(routerEncSecret, getrc, h, sign, established, reneg,
timeout, closed)
{
_crypto = crypto;
_utp_ctx = utp_init(2);
utp_context_set_userdata(_utp_ctx, this);
utp_set_callback(_utp_ctx, UTP_SENDTO, &LinkLayer::SendTo);
@ -302,7 +300,7 @@ namespace llarp
bool
LinkLayer::KeyGen(SecretKey& k)
{
OurCrypto()->encryption_keygen(k);
CryptoManager::instance()->encryption_keygen(k);
return true;
}

@ -17,7 +17,6 @@ namespace llarp
struct LinkLayer final : public ILinkLayer
{
utp_context* _utp_ctx = nullptr;
Crypto* _crypto = nullptr;
// low level read callback
static uint64
@ -47,8 +46,8 @@ namespace llarp
OnLog(utp_callback_arguments* arg);
/// construct
LinkLayer(Crypto* crypto, const SecretKey& routerEncSecret,
GetRCFunc getrc, LinkMessageHandler h, SignBufferFunc sign,
LinkLayer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SignBufferFunc sign,
SessionEstablishedHandler established,
SessionRenegotiateHandler reneg, TimeoutHandler timeout,
SessionClosedHandler closed);
@ -70,12 +69,6 @@ namespace llarp
ProcessICMP();
#endif
Crypto*
OurCrypto() override
{
return _crypto;
}
/// pump sessions
void
Pump() override;

@ -19,12 +19,6 @@ namespace llarp
LogDebug("link established with ", remoteAddr);
}
Crypto*
Session::OurCrypto()
{
return parent->OurCrypto();
}
/// pump tx queue
void
Session::PumpWrite()
@ -91,10 +85,11 @@ namespace llarp
OutboundHandshake();
}
template < bool (Crypto::*dh_func)(SharedSecret&, const PubKey&,
const SecretKey&, const TunnelNonce&) >
bool
Session::DoKeyExchange(transport_dh_func dh, SharedSecret& K,
const KeyExchangeNonce& n, const PubKey& other,
const SecretKey& secret)
Session::DoKeyExchange(SharedSecret& K, const KeyExchangeNonce& n,
const PubKey& other, const SecretKey& secret)
{
ShortHash t_h;
static constexpr size_t TMP_SIZE = 64;
@ -105,14 +100,14 @@ namespace llarp
std::copy(K.begin(), K.end(), tmp.begin());
std::copy(n.begin(), n.end(), tmp.begin() + K.size());
// t_h = HS(K + L.n)
if(!OurCrypto()->shorthash(t_h, llarp_buffer_t(tmp)))
if(!CryptoManager::instance()->shorthash(t_h, llarp_buffer_t(tmp)))
{
LogError("failed to mix key to ", remoteAddr);
return false;
}
// K = TKE(a.p, B_a.e, sk, t_h)
if(!dh(K, other, secret, t_h))
if(!(CryptoManager::instance()->*dh_func)(K, other, secret, t_h))
{
LogError("key exchange with ", other, " failed");
return false;
@ -130,7 +125,7 @@ namespace llarp
buf.cur += K.size();
std::copy(A.begin(), A.end(), buf.cur);
buf.cur = buf.base;
return OurCrypto()->shorthash(K, buf);
return CryptoManager::instance()->shorthash(K, buf);
}
void
@ -314,7 +309,7 @@ namespace llarp
// build our RC
LinkIntroMessage msg;
msg.rc = parent->GetOurRC();
if(!msg.rc.Verify(OurCrypto(), parent->Now()))
if(!msg.rc.Verify(parent->Now()))
{
LogError("our RC is invalid? closing session to", remoteAddr);
Close();
@ -346,10 +341,8 @@ namespace llarp
return;
}
if(!DoKeyExchange(std::bind(&Crypto::transport_dh_client, OurCrypto(), _1,
_2, _3, _4),
txKey, msg.N, remoteTransportPubKey,
parent->RouterEncryptionSecret()))
if(!DoClientKeyExchange(txKey, msg.N, remoteTransportPubKey,
parent->RouterEncryptionSecret()))
{
LogError("failed to mix keys for outbound session to ", remoteAddr);
Close();
@ -402,14 +395,14 @@ namespace llarp
TunnelNonce nonce(noncePtr);
// encrypt
if(!OurCrypto()->xchacha20(payload, txKey, nonce))
if(!CryptoManager::instance()->xchacha20(payload, txKey, nonce))
return false;
payload.base = noncePtr;
payload.cur = payload.base;
payload.sz = FragmentBufferSize - FragmentHashSize;
// key'd hash
if(!OurCrypto()->hmac(buf.data(), payload, txKey))
if(!CryptoManager::instance()->hmac(buf.data(), payload, txKey))
return false;
return MutateKey(txKey, A);
}
@ -451,9 +444,8 @@ namespace llarp
// set remote rc
remoteRC = msg->rc;
// recalculate rx key
return DoKeyExchange(
std::bind(&Crypto::transport_dh_server, OurCrypto(), _1, _2, _3, _4),
rxKey, msg->N, remoteRC.enckey, parent->RouterEncryptionSecret());
return DoServerKeyExchange(rxKey, msg->N, remoteRC.enckey,
parent->RouterEncryptionSecret());
}
bool
@ -477,9 +469,8 @@ namespace llarp
if(!SendMessageBuffer(buf))
return false;
// regen our tx Key
return DoKeyExchange(
std::bind(&Crypto::transport_dh_client, OurCrypto(), _1, _2, _3, _4),
txKey, lim.N, remoteRC.enckey, parent->RouterEncryptionSecret());
return DoClientKeyExchange(txKey, lim.N, remoteRC.enckey,
parent->RouterEncryptionSecret());
}
bool
@ -490,7 +481,7 @@ namespace llarp
llarp_buffer_t hbuf(ptr + FragmentHashSize,
FragmentBufferSize - FragmentHashSize);
if(!OurCrypto()->hmac(digest.data(), hbuf, rxKey))
if(!CryptoManager::instance()->hmac(digest.data(), hbuf, rxKey))
{
LogError("keyed hash failed");
return false;
@ -510,7 +501,8 @@ namespace llarp
llarp_buffer_t out(rxFragBody);
// decrypt
if(!OurCrypto()->xchacha20_alt(out, in, rxKey, ptr + FragmentHashSize))
if(!CryptoManager::instance()->xchacha20_alt(out, in, rxKey,
ptr + FragmentHashSize))
{
LogError("failed to decrypt message from ", remoteAddr);
return false;
@ -615,7 +607,7 @@ namespace llarp
sock = s;
remoteAddr = addr;
RouterID rid = p->GetOurRC().pubkey;
OurCrypto()->shorthash(rxKey, llarp_buffer_t(rid));
CryptoManager::instance()->shorthash(rxKey, llarp_buffer_t(rid));
remoteRC.Clear();
ABSL_ATTRIBUTE_UNUSED void* res = utp_set_userdata(sock, this);
@ -635,19 +627,18 @@ namespace llarp
if(!gotLIM)
{
remoteRC = msg->rc;
OurCrypto()->shorthash(txKey, llarp_buffer_t(remoteRC.pubkey));
CryptoManager::instance()->shorthash(txKey,
llarp_buffer_t(remoteRC.pubkey));
if(!DoKeyExchange(std::bind(&Crypto::transport_dh_server, OurCrypto(),
_1, _2, _3, _4),
rxKey, msg->N, remoteRC.enckey,
parent->TransportSecretKey()))
if(!DoServerKeyExchange(rxKey, msg->N, remoteRC.enckey,
parent->TransportSecretKey()))
return false;
std::array< byte_t, LinkIntroMessage::MaxSize > tmp;
llarp_buffer_t buf(tmp);
LinkIntroMessage replymsg;
replymsg.rc = parent->GetOurRC();
if(!replymsg.rc.Verify(OurCrypto(), parent->Now()))
if(!replymsg.rc.Verify(parent->Now()))
{
LogError("our RC is invalid? closing session to", remoteAddr);
Close();
@ -679,10 +670,8 @@ namespace llarp
Close();
return false;
}
if(!DoKeyExchange(std::bind(&Crypto::transport_dh_client, OurCrypto(),
_1, _2, _3, _4),
txKey, replymsg.N, remoteRC.enckey,
parent->RouterEncryptionSecret()))
if(!DoClientKeyExchange(txKey, replymsg.N, remoteRC.enckey,
parent->RouterEncryptionSecret()))
return false;
LogDebug("Sent reply LIM");
@ -705,9 +694,9 @@ namespace llarp
remoteAddr = addr;
RouterID rid = remoteRC.pubkey;
OurCrypto()->shorthash(txKey, llarp_buffer_t(rid));
CryptoManager::instance()->shorthash(txKey, llarp_buffer_t(rid));
rid = p->GetOurRC().pubkey;
OurCrypto()->shorthash(rxKey, llarp_buffer_t(rid));
CryptoManager::instance()->shorthash(rxKey, llarp_buffer_t(rid));
ABSL_ATTRIBUTE_UNUSED void* res = utp_set_userdata(sock, this);
assert(res == this);
@ -733,10 +722,8 @@ namespace llarp
remoteRC = msg->rc;
gotLIM = true;
if(!DoKeyExchange(std::bind(&Crypto::transport_dh_server, OurCrypto(), _1,
_2, _3, _4),
rxKey, msg->N, remoteRC.enckey,
parent->RouterEncryptionSecret()))
if(!DoServerKeyExchange(rxKey, msg->N, remoteRC.enckey,
parent->RouterEncryptionSecret()))
{
Close();
return false;

@ -91,9 +91,6 @@ namespace llarp
void
OnLinkEstablished(ILinkLayer* p) override;
Crypto*
OurCrypto();
/// switch states
void
EnterState(State st);
@ -159,10 +156,27 @@ namespace llarp
OutboundHandshake();
// do key exchange for handshake
template < bool (Crypto::*dh_func)(SharedSecret&, const PubKey&,
const SecretKey&, const TunnelNonce&) >
bool
DoKeyExchange(SharedSecret& K, const KeyExchangeNonce& n,
const PubKey& other, const SecretKey& secret);
bool
DoKeyExchange(transport_dh_func dh, SharedSecret& K,
const KeyExchangeNonce& n, const PubKey& other,
const SecretKey& secret);
DoClientKeyExchange(SharedSecret& K, const KeyExchangeNonce& n,
const PubKey& other, const SecretKey& secret)
{
return DoKeyExchange< &Crypto::transport_dh_client >(K, n, other,
secret);
}
bool
DoServerKeyExchange(SharedSecret& K, const KeyExchangeNonce& n,
const PubKey& other, const SecretKey& secret)
{
return DoKeyExchange< &Crypto::transport_dh_server >(K, n, other,
secret);
}
/// does K = HS(K + A)
bool

@ -10,13 +10,13 @@ namespace llarp
using namespace std::placeholders;
LinkLayer_ptr
NewServer(Crypto* crypto, const SecretKey& routerEncSecret, GetRCFunc getrc,
NewServer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed)
{
return std::make_shared< LinkLayer >(crypto, routerEncSecret, getrc, h,
sign, est, reneg, timeout, closed);
return std::make_shared< LinkLayer >(routerEncSecret, getrc, h, sign, est,
reneg, timeout, closed);
}
LinkLayer_ptr
@ -24,7 +24,7 @@ namespace llarp
{
using namespace std::placeholders;
return NewServer(
r->crypto(), r->encryption(), std::bind(&AbstractRouter::rc, r),
r->encryption(), std::bind(&AbstractRouter::rc, r),
std::bind(&AbstractRouter::HandleRecvLinkMessageBuffer, r, _1, _2),
std::bind(&AbstractRouter::OnSessionEstablished, r, _1),
std::bind(&AbstractRouter::CheckRenegotiateValid, r, _1, _2),

@ -11,7 +11,7 @@ namespace llarp
namespace utp
{
LinkLayer_ptr
NewServer(Crypto* crypto, const SecretKey& routerEncSecret, GetRCFunc getrc,
NewServer(const SecretKey& routerEncSecret, GetRCFunc getrc,
LinkMessageHandler h, SessionEstablishedHandler est,
SessionRenegotiateHandler reneg, SignBufferFunc sign,
TimeoutHandler timeout, SessionClosedHandler closed);

@ -9,6 +9,7 @@ And you can read the LLARP protocol specification [here](docs/proto_v0.txt)
You can view documentation on how to get started [here](https://loki-project.github.io/loki-docs/Lokinet/LokinetOverview/) .
![build status](https://gitlab.com/lokiproject/loki-network/badges/master/pipeline.svg "build status")
![travis-ci](https://travis-ci.org/loki-project/loki-network.svg?branch=master "ci status")
## Usage

@ -18,6 +18,7 @@ list(APPEND TEST_SRC
ev/test_ev_loop.cpp
exit/test_llarp_exit_context.cpp
link/test_llarp_link.cpp
llarp_test.cpp
metrics/test_llarp_metrics_metricktank.cpp
metrics/test_llarp_metrics_publisher.cpp
net/test_llarp_net_inaddr.cpp

@ -56,7 +56,7 @@ namespace llarp
MOCK_METHOD1(randomize, void(const llarp_buffer_t &));
MOCK_METHOD2(randbytes, void(void *, size_t));
MOCK_METHOD2(randbytes, void(byte_t *, size_t));
MOCK_METHOD1(identity_keygen, void(SecretKey &));

@ -13,12 +13,6 @@ namespace llarp
IdentityKeyTest()
{
}
llarp::Crypto*
Crypto()
{
return &crypto;
}
};
TEST_F(IdentityKeyTest, TestSignVerify)
@ -46,12 +40,6 @@ namespace llarp
{
}
llarp::Crypto*
Crypto()
{
return &crypto;
}
void
SetUp()
{
@ -63,7 +51,7 @@ namespace llarp
{
PQCipherBlock block;
SharedSecret shared, otherShared;
auto c = Crypto();
auto c = &crypto;
ASSERT_TRUE(keys.size() == PQ_KEYPAIRSIZE);
ASSERT_TRUE(

@ -88,8 +88,6 @@ namespace llarp
MOCK_METHOD1(ExploreNetworkVia, void(const dht::Key_t& peer));
MOCK_CONST_METHOD0(Crypto, llarp::Crypto*());
MOCK_CONST_METHOD0(GetRouter, llarp::AbstractRouter*());
MOCK_CONST_METHOD0(OurKey, const dht::Key_t&());

@ -3,6 +3,7 @@
#include <crypto/mock_crypto.hpp>
#include <dht/mock_context.hpp>
#include <dht/messages/gotintro.hpp>
#include <llarp_test.hpp>
#include <service/intro_set.hpp>
#include <test_util.hpp>
@ -21,9 +22,8 @@ struct MockIntroSetHandler
static constexpr uint64_t EXPIRY = 1548503831ull;
struct TestDhtServiceAddressLookup : public ::testing::Test
struct TestDhtServiceAddressLookup : public test::LlarpTest<>
{
test::MockCrypto crypto;
MockIntroSetHandler introsetHandler;
dht::Key_t ourKey;
@ -62,9 +62,8 @@ TEST_F(TestDhtServiceAddressLookup, validate)
{
service::IntroSet introset;
EXPECT_CALL(context, Crypto()).WillOnce(Return(&crypto));
EXPECT_CALL(context, Now()).WillOnce(Return(EXPIRY));
EXPECT_CALL(crypto, verify(_, _, _)).WillOnce(Return(false));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(false));
ASSERT_FALSE(serviceAddressLookup->Validate(introset));
}
@ -78,9 +77,8 @@ TEST_F(TestDhtServiceAddressLookup, validate)
EXPIRY + service::MAX_INTROSET_TIME_DELTA + 1;
// Set expectations
EXPECT_CALL(context, Crypto()).WillOnce(Return(&crypto));
EXPECT_CALL(context, Now()).WillOnce(Return(EXPIRY));
EXPECT_CALL(crypto, verify(_, _, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ASSERT_FALSE(serviceAddressLookup->Validate(introset));
}
@ -97,9 +95,8 @@ TEST_F(TestDhtServiceAddressLookup, validate)
EXPIRY + service::MAX_INTROSET_TIME_DELTA + 1;
// Set expectations
EXPECT_CALL(context, Crypto()).WillOnce(Return(&crypto));
EXPECT_CALL(context, Now()).WillOnce(Return(EXPIRY));
EXPECT_CALL(crypto, verify(_, _, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ASSERT_TRUE(serviceAddressLookup->Validate(introset));
}

@ -3,6 +3,7 @@
#include <crypto/mock_crypto.hpp>
#include <dht/mock_context.hpp>
#include <dht/messages/gotintro.hpp>
#include <llarp_test.hpp>
#include <service/intro_set.hpp>
#include <test_util.hpp>
@ -15,9 +16,8 @@ using test::makeBuf;
static constexpr uint64_t EXPIRY = 1548503831ull;
struct TestDhtTagLookup : public ::testing::Test
struct TestDhtTagLookup : public test::LlarpTest<>
{
test::MockCrypto crypto;
dht::Key_t txKey;
uint64_t txId;
dht::TXOwner txOwner;
@ -47,9 +47,8 @@ TEST_F(TestDhtTagLookup, validate)
{
service::IntroSet introset;
EXPECT_CALL(context, Crypto()).WillOnce(Return(&crypto));
EXPECT_CALL(context, Now()).WillOnce(Return(EXPIRY));
EXPECT_CALL(crypto, verify(_, _, _)).WillOnce(Return(false));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(false));
ASSERT_FALSE(tagLookup.Validate(introset));
}
@ -65,9 +64,8 @@ TEST_F(TestDhtTagLookup, validate)
EXPIRY + service::MAX_INTROSET_TIME_DELTA + 1;
// Set expectations
EXPECT_CALL(context, Crypto()).WillOnce(Return(&crypto));
EXPECT_CALL(context, Now()).WillOnce(Return(EXPIRY));
EXPECT_CALL(crypto, verify(_, _, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ASSERT_FALSE(tagLookup.Validate(introset));
}
@ -83,9 +81,8 @@ TEST_F(TestDhtTagLookup, validate)
EXPIRY + service::MAX_INTROSET_TIME_DELTA + 1;
// Set expectations
EXPECT_CALL(context, Crypto()).WillOnce(Return(&crypto));
EXPECT_CALL(context, Now()).WillOnce(Return(EXPIRY));
EXPECT_CALL(crypto, verify(_, _, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ASSERT_TRUE(tagLookup.Validate(introset));
}

@ -1,45 +1,47 @@
#include <crypto/crypto_noop.hpp>
#include <ev/ev.h>
#include <iwp/iwp.hpp>
#include <llarp_test.hpp>
#include <messages/link_intro.hpp>
#include <messages/discard.hpp>
#include <utp/utp.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <test_util.hpp>
#include <gtest/gtest.h>
struct LinkLayerTest : public ::testing::Test
using namespace ::llarp;
using namespace ::testing;
struct LinkLayerTest : public test::LlarpTest< NoOpCrypto >
{
static constexpr uint16_t AlicePort = 5000;
static constexpr uint16_t BobPort = 6000;
struct Context
{
Context(llarp::Crypto& c)
Context()
{
crypto = &c;
crypto->identity_keygen(signingKey);
crypto->encryption_keygen(encryptionKey);
CryptoManager::instance()->identity_keygen(signingKey);
CryptoManager::instance()->encryption_keygen(encryptionKey);
rc.pubkey = signingKey.toPublic();
rc.enckey = encryptionKey.toPublic();
}
llarp::SecretKey signingKey;
llarp::SecretKey encryptionKey;
llarp::RouterContact rc;
SecretKey signingKey;
SecretKey encryptionKey;
llarp::Crypto* crypto;
RouterContact rc;
bool gotLIM = false;
const llarp::RouterContact&
const RouterContact&
GetRC() const
{
return rc;
}
llarp::RouterID
RouterID
GetRouterID() const
{
return rc.pubkey;
@ -49,12 +51,12 @@ struct LinkLayerTest : public ::testing::Test
bool
Regen()
{
crypto->encryption_keygen(encryptionKey);
rc.enckey = llarp::seckey_topublic(encryptionKey);
return rc.Sign(crypto, signingKey);
CryptoManager::instance()->encryption_keygen(encryptionKey);
rc.enckey = seckey_topublic(encryptionKey);
return rc.Sign(signingKey);
}
std::shared_ptr< llarp::ILinkLayer > link;
std::shared_ptr< ILinkLayer > link;
static std::string
localLoopBack()
@ -68,7 +70,7 @@ struct LinkLayerTest : public ::testing::Test
}
bool
Start(std::shared_ptr<llarp::Logic> logic, llarp_ev_loop_ptr loop, uint16_t port)
Start(std::shared_ptr< Logic > logic, llarp_ev_loop_ptr loop, uint16_t port)
{
if(!link)
return false;
@ -79,7 +81,7 @@ struct LinkLayerTest : public ::testing::Test
rc.addrs.emplace_back();
if(!link->GetOurAddressInfo(rc.addrs[0]))
return false;
if(!rc.Sign(crypto, signingKey))
if(!rc.Sign(signingKey))
return false;
return link->Start(logic);
}
@ -99,30 +101,28 @@ struct LinkLayerTest : public ::testing::Test
}
};
llarp::sodium::CryptoLibSodium crypto;
Context Alice;
Context Bob;
bool success = false;
llarp_ev_loop_ptr netLoop;
std::shared_ptr< llarp::Logic > m_logic;
std::shared_ptr< Logic > m_logic;
llarp_time_t oldRCLifetime;
LinkLayerTest() : Alice(crypto), Bob(crypto), netLoop(nullptr)
LinkLayerTest() : netLoop(nullptr)
{
}
void
SetUp()
{
oldRCLifetime = llarp::RouterContact::Lifetime;
llarp::RouterContact::IgnoreBogons = true;
llarp::RouterContact::Lifetime = 500;
netLoop = llarp_make_ev_loop();
m_logic.reset(new llarp::Logic());
oldRCLifetime = RouterContact::Lifetime;
RouterContact::IgnoreBogons = true;
RouterContact::Lifetime = 500;
netLoop = llarp_make_ev_loop();
m_logic.reset(new Logic());
}
void
@ -132,8 +132,8 @@ struct LinkLayerTest : public ::testing::Test
Bob.TearDown();
m_logic.reset();
netLoop.reset();
llarp::RouterContact::IgnoreBogons = false;
llarp::RouterContact::Lifetime = oldRCLifetime;
RouterContact::IgnoreBogons = false;
RouterContact::Lifetime = oldRCLifetime;
}
static void
@ -168,10 +168,10 @@ struct LinkLayerTest : public ::testing::Test
TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
{
Alice.link = llarp::utp::NewServer(
&crypto, Alice.encryptionKey,
[&]() -> const llarp::RouterContact& { return Alice.GetRC(); },
[&](llarp::ILinkSession* s, const llarp_buffer_t& buf) -> bool {
Alice.link = utp::NewServer(
Alice.encryptionKey,
[&]() -> const RouterContact& { return Alice.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
if(Alice.gotLIM)
{
Alice.Regen();
@ -179,7 +179,7 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
}
else
{
llarp::LinkIntroMessage msg;
LinkIntroMessage msg;
ManagedBuffer copy{buf};
if(!msg.BDecode(&copy.underlying))
return false;
@ -189,25 +189,25 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
return true;
}
},
[&](llarp::ILinkSession* s) -> bool {
[&](ILinkSession* s) -> bool {
const auto rc = s->GetRemoteRC();
return rc.pubkey == Bob.GetRC().pubkey;
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::Signature& sig, const llarp_buffer_t& buf) -> bool {
return crypto.sign(sig, Alice.signingKey, buf);
[&](RouterContact, RouterContact) -> bool { return true; },
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
[&](ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
[&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
auto sendDiscardMessage = [](llarp::ILinkSession* s) -> bool {
auto sendDiscardMessage = [](ILinkSession* s) -> bool {
// send discard message in reply to complete unit test
std::array< byte_t, 32 > tmp;
llarp_buffer_t otherBuf(tmp);
llarp::DiscardMessage discard;
DiscardMessage discard;
if(!discard.BEncode(&otherBuf))
return false;
otherBuf.sz = otherBuf.cur - otherBuf.base;
@ -215,11 +215,10 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
return s->SendMessageBuffer(otherBuf);
};
Bob.link = llarp::utp::NewServer(
&crypto, Bob.encryptionKey,
[&]() -> const llarp::RouterContact& { return Bob.GetRC(); },
[&](llarp::ILinkSession* s, const llarp_buffer_t& buf) -> bool {
llarp::LinkIntroMessage msg;
Bob.link = utp::NewServer(
Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage msg;
ManagedBuffer copy{buf};
if(!msg.BDecode(&copy.underlying))
return false;
@ -228,24 +227,22 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
Bob.gotLIM = true;
return sendDiscardMessage(s);
},
[&](llarp::ILinkSession* s) -> bool {
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
return false;
llarp::LogInfo("bob established with alice");
LogInfo("bob established with alice");
return Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](llarp::RouterContact newrc, llarp::RouterContact oldrc) -> bool {
[&](RouterContact newrc, RouterContact oldrc) -> bool {
success = newrc.pubkey == oldrc.pubkey;
return true;
},
[&](llarp::Signature& sig, const llarp_buffer_t& buf) -> bool {
return crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort));
@ -259,11 +256,11 @@ TEST_F(LinkLayerTest, TestUTPAliceRenegWithBob)
TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
{
Alice.link = llarp::utp::NewServer(
&crypto, Alice.encryptionKey,
[&]() -> const llarp::RouterContact& { return Alice.GetRC(); },
[&](llarp::ILinkSession* s, const llarp_buffer_t& buf) -> bool {
llarp::LinkIntroMessage lim;
Alice.link = utp::NewServer(
Alice.encryptionKey,
[&]() -> const RouterContact& { return Alice.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage lim;
llarp_buffer_t copy(buf.base, buf.sz);
if(lim.BDecode(&copy))
{
@ -276,27 +273,26 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
}
return AliceGotMessage(buf);
},
[&](llarp::ILinkSession* s) -> bool {
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Bob.GetRC().pubkey)
return false;
llarp::LogInfo("alice established with bob");
LogInfo("alice established with bob");
return true;
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::Signature& sig, const llarp_buffer_t& buf) -> bool {
return crypto.sign(sig, Alice.signingKey, buf);
[&](RouterContact, RouterContact) -> bool { return true; },
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Alice.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
[&](ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
[&](RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
Bob.link = llarp::utp::NewServer(
&crypto, Bob.encryptionKey,
[&]() -> const llarp::RouterContact& { return Bob.GetRC(); },
[&](llarp::ILinkSession* s, const llarp_buffer_t& buf) -> bool {
llarp::LinkIntroMessage lim;
Bob.link = utp::NewServer(
Bob.encryptionKey, [&]() -> const RouterContact& { return Bob.GetRC(); },
[&](ILinkSession* s, const llarp_buffer_t& buf) -> bool {
LinkIntroMessage lim;
llarp_buffer_t copy(buf.base, buf.sz);
if(lim.BDecode(&copy))
{
@ -309,16 +305,16 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
}
return true;
},
[&](llarp::ILinkSession* s) -> bool {
[&](ILinkSession* s) -> bool {
if(s->GetRemoteRC().pubkey != Alice.GetRC().pubkey)
return false;
llarp::LogInfo("bob established with alice");
LogInfo("bob established with alice");
m_logic->queue_job({s, [](void* u) {
llarp::ILinkSession* self =
static_cast< llarp::ILinkSession* >(u);
ILinkSession* self =
static_cast< ILinkSession* >(u);
std::array< byte_t, 32 > tmp;
llarp_buffer_t otherBuf(tmp);
llarp::DiscardMessage discard;
DiscardMessage discard;
if(!discard.BEncode(&otherBuf))
return;
otherBuf.sz = otherBuf.cur - otherBuf.base;
@ -327,14 +323,12 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
}});
return true;
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::Signature& sig, const llarp_buffer_t& buf) -> bool {
return crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
[&](RouterContact, RouterContact) -> bool { return true; },
[&](Signature& sig, const llarp_buffer_t& buf) -> bool {
return m_crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
[&](ILinkSession* session) { ASSERT_FALSE(session->IsEstablished()); },
[&](RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
ASSERT_TRUE(Alice.Start(m_logic, netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(m_logic, netLoop, BobPort));
@ -345,93 +339,3 @@ TEST_F(LinkLayerTest, TestUTPAliceConnectToBob)
ASSERT_TRUE(Bob.gotLIM);
ASSERT_TRUE(success);
}
/*
TEST_F(LinkLayerTest, TestIWPAliceConnectToBob)
{
Alice.link = llarp::iwp::NewServer(
&crypto, Alice.encryptionKey,
[&]() -> const llarp::RouterContact& { return Alice.GetRC(); },
[&](llarp::ILinkSession* s, const llarp_buffer_t& buf) -> bool {
if(Alice.gotLIM)
{
return AliceGotMessage(buf);
}
else
{
llarp::LinkIntroMessage msg;
ManagedBuffer copy{buf};
if(!msg.BDecode(&copy.underlying))
return false;
if(!s->GotLIM(&msg))
return false;
Alice.gotLIM = true;
return true;
}
},
[&](llarp::RouterContact rc) {
ASSERT_EQ(rc, Bob.GetRC());
llarp::LogInfo("alice established with bob");
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::Signature& sig, const llarp_buffer_t& buf) -> bool {
return crypto.sign(sig, Alice.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
Stop();
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Bob.GetRouterID()); });
auto sendDiscardMessage = [](llarp::ILinkSession* s) -> bool {
// send discard message in reply to complete unit test
std::array< byte_t, 32 > tmp;
llarp_buffer_t otherBuf(tmp);
llarp::DiscardMessage discard;
if(!discard.BEncode(&otherBuf))
return false;
otherBuf.sz = otherBuf.cur - otherBuf.base;
otherBuf.cur = otherBuf.base;
return s->SendMessageBuffer(otherBuf);
};
Bob.link = llarp::iwp::NewServer(
&crypto, Bob.encryptionKey,
[&]() -> const llarp::RouterContact& { return Bob.GetRC(); },
[&](llarp::ILinkSession* s, const llarp_buffer_t& buf) -> bool {
llarp::LinkIntroMessage msg;
ManagedBuffer copy{buf};
if(!msg.BDecode(&copy.underlying))
return false;
if(!s->GotLIM(&msg))
return false;
Bob.gotLIM = true;
return true;
},
[&](llarp::RouterContact rc) {
ASSERT_EQ(rc, Alice.GetRC());
llarp::LogInfo("bob established with alice");
Bob.link->VisitSessionByPubkey(Alice.GetRC().pubkey.as_array(),
sendDiscardMessage);
},
[&](llarp::RouterContact, llarp::RouterContact) -> bool { return true; },
[&](llarp::Signature& sig, const llarp_buffer_t& buf) -> bool {
return crypto.sign(sig, Bob.signingKey, buf);
},
[&](llarp::ILinkSession* session) {
ASSERT_FALSE(session->IsEstablished());
},
[&](llarp::RouterID router) { ASSERT_EQ(router, Alice.GetRouterID()); });
ASSERT_TRUE(Alice.Start(m_logic.get(), netLoop, AlicePort));
ASSERT_TRUE(Bob.Start(m_logic.get(), netLoop, BobPort));
ASSERT_TRUE(Alice.link->TryEstablishTo(Bob.GetRC()));
RunMainloop();
ASSERT_TRUE(Alice.gotLIM);
ASSERT_TRUE(Bob.gotLIM);
ASSERT_TRUE(success);
};
*/

@ -0,0 +1 @@
#include <llarp_test.hpp>

@ -0,0 +1,26 @@
#ifndef LLARP_TEST
#define LLARP_TEST
#include <gtest/gtest.h>
#include <crypto/mock_crypto.hpp>
namespace llarp
{
namespace test
{
template < typename CryptoImpl = MockCrypto >
class LlarpTest : public ::testing::Test
{
protected:
CryptoImpl m_crypto;
CryptoManager cm;
LlarpTest() : cm(&m_crypto)
{
static_assert(std::is_base_of< Crypto, CryptoImpl >::value, "");
}
};
} // namespace test
} // namespace llarp
#endif

@ -2,41 +2,45 @@
#include <crypto/crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <llarp_test.hpp>
#include <gtest/gtest.h>
#include <gmock/gmock.h>
using ObtainExitMessage = llarp::routing::ObtainExitMessage;
using namespace ::testing;
using namespace ::llarp;
class ObtainExitTest : public ::testing::Test
using ObtainExitMessage = routing::ObtainExitMessage;
class ObtainExitTest : public test::LlarpTest<>
{
public:
llarp::sodium::CryptoLibSodium crypto;
llarp::SecretKey alice;
SecretKey alice;
ObtainExitTest()
{
}
~ObtainExitTest()
{
}
void
SetUp()
{
crypto.identity_keygen(alice);
// m_crypto.identity_keygen(alice);
}
};
void
fill(Signature& s)
{
s.Fill(0xFF);
}
TEST_F(ObtainExitTest, TestSignVerify)
{
EXPECT_CALL(m_crypto, sign(_, alice, _))
.WillOnce(DoAll(WithArg< 0 >(Invoke(&fill)), Return(true)));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ObtainExitMessage msg;
msg.Z.Zero();
msg.S = llarp::randint();
msg.T = llarp::randint();
EXPECT_TRUE(msg.Sign(&crypto, alice));
EXPECT_TRUE(msg.Verify(&crypto));
EXPECT_TRUE(msg.I == llarp::PubKey(llarp::seckey_topublic(alice)));
msg.S = randint();
msg.T = randint();
EXPECT_TRUE(msg.Sign(alice));
EXPECT_TRUE(msg.Verify());
EXPECT_TRUE(msg.I == PubKey(seckey_topublic(alice)));
EXPECT_FALSE(msg.version != LLARP_PROTO_VERSION);
EXPECT_FALSE(msg.Z.IsZero());
}

@ -1,5 +1,6 @@
#include <crypto/crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <llarp_test.hpp>
#include <path/path.hpp>
#include <service/address.hpp>
#include <service/identity.hpp>
@ -15,28 +16,9 @@
using namespace llarp;
using namespace testing;
struct HiddenServiceTest : public ::testing::Test
struct HiddenServiceTest : public test::LlarpTest<>
{
sodium::CryptoLibSodium crypto;
service::Identity ident;
HiddenServiceTest()
{
}
llarp::Crypto*
Crypto()
{
return &crypto;
}
void
SetUp()
{
ident.RegenerateKeys(Crypto());
ident.pub.RandomizeVanity();
ident.pub.UpdateAddr();
}
};
TEST_F(HiddenServiceTest, TestGenerateIntroSet)
@ -54,8 +36,12 @@ TEST_F(HiddenServiceTest, TestGenerateIntroSet)
intro.pathID.Randomize();
I.I.emplace_back(std::move(intro));
}
ASSERT_TRUE(ident.SignIntroSet(I, Crypto(), now));
ASSERT_TRUE(I.Verify(Crypto(), now));
EXPECT_CALL(m_crypto, sign(I.Z, _, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, I.Z)).WillOnce(Return(true));
ASSERT_TRUE(ident.SignIntroSet(I, now));
ASSERT_TRUE(I.Verify(now));
}
TEST_F(HiddenServiceTest, TestAddressToFromString)
@ -66,9 +52,11 @@ TEST_F(HiddenServiceTest, TestAddressToFromString)
ASSERT_TRUE(addr == ident.pub.Addr());
}
struct ServiceIdentityTest : public ::testing::Test
struct ServiceIdentityTest : public test::LlarpTest<>
{
test::MockCrypto crypto;
ServiceIdentityTest()
{
}
};
template < typename Arg >
@ -85,23 +73,23 @@ TEST_F(ServiceIdentityTest, EnsureKeys)
test::FileGuard guard(p);
EXPECT_CALL(crypto, encryption_keygen(_))
EXPECT_CALL(m_crypto, encryption_keygen(_))
.WillOnce(WithArg< 0 >(FillArg< SecretKey >(0x01)));
EXPECT_CALL(crypto, identity_keygen(_))
EXPECT_CALL(m_crypto, identity_keygen(_))
.WillOnce(WithArg< 0 >(FillArg< SecretKey >(0x02)));
EXPECT_CALL(crypto, pqe_keygen(_))
EXPECT_CALL(m_crypto, pqe_keygen(_))
.WillOnce(WithArg< 0 >(FillArg< PQKeyPair >(0x03)));
service::Identity identity;
ASSERT_TRUE(identity.EnsureKeys(p.string(), &crypto));
ASSERT_TRUE(identity.EnsureKeys(p.string()));
ASSERT_TRUE(fs::exists(fs::status(p)));
// Verify what is on disk is what is what was generated
service::Identity other;
// No need to set more mocks, as we shouldn't need to re-keygen
ASSERT_TRUE(other.EnsureKeys(p.string(), &crypto));
ASSERT_TRUE(other.EnsureKeys(p.string()));
ASSERT_EQ(identity, other);
}
@ -115,7 +103,7 @@ TEST_F(ServiceIdentityTest, EnsureKeysDir)
ASSERT_TRUE(fs::create_directory(p, code)) << code;
service::Identity identity;
ASSERT_FALSE(identity.EnsureKeys(p.string(), &crypto));
ASSERT_FALSE(identity.EnsureKeys(p.string()));
}
TEST_F(ServiceIdentityTest, EnsureKeysBrokenFile)
@ -132,5 +120,5 @@ TEST_F(ServiceIdentityTest, EnsureKeysBrokenFile)
file.close();
service::Identity identity;
ASSERT_FALSE(identity.EnsureKeys(p.string(), &crypto));
ASSERT_FALSE(identity.EnsureKeys(p.string()));
}

@ -2,40 +2,25 @@
#include <crypto/crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <llarp_test.hpp>
#include <messages/relay_commit.hpp>
#include <test_util.hpp>
#include <gtest/gtest.h>
using EncryptedFrame = llarp::EncryptedFrame;
using SecretKey = llarp::SecretKey;
using PubKey = llarp::PubKey;
using LRCR = llarp::LR_CommitRecord;
using namespace ::llarp;
using namespace ::testing;
using EncryptedFrame = EncryptedFrame;
using SecretKey = SecretKey;
using PubKey = PubKey;
using LRCR = LR_CommitRecord;
class FrameTest : public ::testing::Test
class FrameTest : public test::LlarpTest<>
{
public:
llarp::sodium::CryptoLibSodium crypto;
SecretKey alice, bob;
FrameTest()
{
}
~FrameTest()
{
}
void
SetUp()
{
crypto.encryption_keygen(alice);
crypto.encryption_keygen(bob);
}
void
TearDown()
{
}
};
TEST_F(FrameTest, TestFrameCrypto)
@ -49,16 +34,28 @@ TEST_F(FrameTest, TestFrameCrypto)
record.txid.Fill(4);
auto buf = f.Buffer();
buf->cur = buf->base + llarp::EncryptedFrameOverheadSize;
buf->cur = buf->base + EncryptedFrameOverheadSize;
ASSERT_TRUE(record.BEncode(buf));
EXPECT_CALL(m_crypto, randbytes(_, _))
.WillOnce(Invoke(&test::randbytes_impl));
EXPECT_CALL(m_crypto, dh_client(_, _, alice, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, xchacha20(_, _, _))
.Times(2)
.WillRepeatedly(Return(true));
EXPECT_CALL(m_crypto, hmac(_, _, _)).Times(2).WillRepeatedly(Return(true));
// rewind buffer
buf->cur = buf->base + llarp::EncryptedFrameOverheadSize;
buf->cur = buf->base + EncryptedFrameOverheadSize;
// encrypt to alice
ASSERT_TRUE(f.EncryptInPlace(alice, bob.toPublic(), &crypto));
ASSERT_TRUE(f.EncryptInPlace(alice, bob.toPublic()));
EXPECT_CALL(m_crypto, dh_server(_, _, _, _)).WillOnce(Return(true));
// decrypt from alice
ASSERT_TRUE(f.DecryptInPlace(bob, &crypto));
ASSERT_TRUE(f.DecryptInPlace(bob));
LRCR otherRecord;
ASSERT_TRUE(otherRecord.BDecode(buf));

@ -2,6 +2,7 @@
#include <crypto/crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <llarp_test.hpp>
#include <functional>
#include <random>
@ -9,16 +10,14 @@
#include <test_util.hpp>
#include <gtest/gtest.h>
using FindOrCreateFunc = std::function< bool(llarp::Crypto *, const fs::path &,
llarp::SecretKey &) >;
using namespace ::llarp;
using namespace ::testing;
struct FindOrCreate : public ::testing::TestWithParam< FindOrCreateFunc >
{
FindOrCreate()
{
}
using FindOrCreateFunc = std::function< bool(const fs::path &, SecretKey &) >;
llarp::sodium::CryptoLibSodium crypto;
struct FindOrCreate : public test::LlarpTest<>,
public WithParamInterface< FindOrCreateFunc >
{
};
// Concerns
@ -29,13 +28,21 @@ struct FindOrCreate : public ::testing::TestWithParam< FindOrCreateFunc >
TEST_P(FindOrCreate, find_file_missing)
{
// File missing. Should create a new file
llarp::SecretKey key;
fs::path p = llarp::test::randFilename();
SecretKey key;
fs::path p = test::randFilename();
ASSERT_FALSE(fs::exists(fs::status(p)));
llarp::test::FileGuard guard(p);
test::FileGuard guard(p);
EXPECT_CALL(m_crypto, encryption_keygen(_))
.Times(AtMost(1))
.WillRepeatedly(Invoke(&test::keygen< SecretKey >));
EXPECT_CALL(m_crypto, identity_keygen(_))
.Times(AtMost(1))
.WillRepeatedly(Invoke(&test::keygen< SecretKey >));
ASSERT_TRUE(GetParam()(&crypto, p, key));
ASSERT_TRUE(GetParam()(p, key));
ASSERT_TRUE(fs::exists(fs::status(p)));
ASSERT_FALSE(key.IsZero());
}
@ -43,17 +50,17 @@ TEST_P(FindOrCreate, find_file_missing)
TEST_P(FindOrCreate, find_file_empty)
{
// File empty.
llarp::SecretKey key;
fs::path p = llarp::test::randFilename();
SecretKey key;
fs::path p = test::randFilename();
ASSERT_FALSE(fs::exists(fs::status(p)));
std::fstream f;
f.open(p.string(), std::ios::out);
f.close();
llarp::test::FileGuard guard(p);
test::FileGuard guard(p);
ASSERT_FALSE(GetParam()(&crypto, p, key));
ASSERT_FALSE(GetParam()(p, key));
// Verify we didn't delete an invalid file
ASSERT_TRUE(fs::exists(fs::status(p)));
}
@ -61,8 +68,8 @@ TEST_P(FindOrCreate, find_file_empty)
TEST_P(FindOrCreate, happy_path)
{
// happy path.
llarp::SecretKey key;
fs::path p = llarp::test::randFilename();
SecretKey key;
fs::path p = test::randFilename();
ASSERT_FALSE(fs::exists(fs::status(p)));
std::ofstream f;
@ -70,9 +77,9 @@ TEST_P(FindOrCreate, happy_path)
std::fill_n(std::ostream_iterator< byte_t >(f), key.size(), 0x20);
f.close();
llarp::test::FileGuard guard(p);
test::FileGuard guard(p);
ASSERT_TRUE(GetParam()(&crypto, p, key));
ASSERT_TRUE(GetParam()(p, key));
// Verify we didn't delete the file
ASSERT_TRUE(fs::exists(fs::status(p)));
}

@ -2,43 +2,48 @@
#include <crypto/crypto.hpp>
#include <crypto/crypto_libsodium.hpp>
#include <llarp_test.hpp>
#include <router_contact.hpp>
using namespace ::llarp;
using namespace ::testing;
static const byte_t DEF_VALUE[] = "unittest";
struct RCTest : public ::testing::Test
struct RCTest : public test::LlarpTest<>
{
using RC_t = llarp::RouterContact;
using SecKey_t = llarp::SecretKey;
using RC_t = RouterContact;
using SecKey_t = SecretKey;
RCTest() : oldval(llarp::NetID::DefaultValue())
RCTest() : oldval(NetID::DefaultValue())
{
llarp::NetID::DefaultValue() = llarp::NetID(DEF_VALUE);
NetID::DefaultValue() = NetID(DEF_VALUE);
}
~RCTest()
{
llarp::NetID::DefaultValue() = oldval;
NetID::DefaultValue() = oldval;
}
llarp::sodium::CryptoLibSodium crypto;
const llarp::NetID oldval;
const NetID oldval;
};
TEST_F(RCTest, TestSignVerify)
{
llarp::NetID netid(DEF_VALUE);
NetID netid(DEF_VALUE);
RC_t rc;
SecKey_t encr;
SecKey_t sign;
crypto.encryption_keygen(encr);
crypto.identity_keygen(sign);
rc.enckey = encr.toPublic();
rc.pubkey = sign.toPublic();
rc.exits.emplace_back(rc.pubkey, llarp::nuint32_t{50000});
rc.exits.emplace_back(rc.pubkey, nuint32_t{50000});
ASSERT_TRUE(rc.netID == netid);
ASSERT_TRUE(rc.netID == llarp::NetID::DefaultValue());
ASSERT_TRUE(rc.Sign(&crypto, sign));
ASSERT_TRUE(rc.Verify(&crypto, llarp::time_now_ms()));
ASSERT_TRUE(rc.netID == NetID::DefaultValue());
EXPECT_CALL(m_crypto, sign(_, sign, _)).WillOnce(Return(true));
EXPECT_CALL(m_crypto, verify(_, _, _)).WillOnce(Return(true));
ASSERT_TRUE(rc.Sign(sign));
ASSERT_TRUE(rc.Verify(time_now_ms()));
}

@ -40,6 +40,26 @@ namespace llarp
}
};
inline void
randbytes_impl(byte_t *ptr, size_t sz)
{
std::fill_n(ptr, sz, 0xAA);
}
template < typename T >
inline void
keygen_val(T &val, byte_t x)
{
val.Fill(x);
}
template < typename T >
inline void
keygen(T &val)
{
keygen_val(val, 0xAA);
}
template < typename T >
struct CombinationIterator
{

Loading…
Cancel
Save