Compare commits

..
26 changed files with 210 additions and 224 deletions

No files matched your search

+3
View File
@@ -19,6 +19,9 @@
*.exe
*.out
*.app
**/dhtnode
**/dhtchat
**/dhtscanner
# Autotools
/ac
-4
View File
@@ -1,4 +0,0 @@
[submodule "argon2"]
path = argon2
url = https://github.com/P-H-C/phc-winner-argon2
ignore = dirty
+8 -48
View File
@@ -7,7 +7,7 @@ include(FindPkgConfig)
include(cmake/CheckAtomic.cmake)
set (opendht_VERSION_MAJOR 2)
set (opendht_VERSION_MINOR 2.0)
set (opendht_VERSION_MINOR 3.0)
set (opendht_VERSION ${opendht_VERSION_MAJOR}.${opendht_VERSION_MINOR})
set (PACKAGE_VERSION ${opendht_VERSION})
set (VERSION "${opendht_VERSION}")
@@ -20,7 +20,6 @@ option (OPENDHT_PYTHON "Build Python bindings" OFF)
option (OPENDHT_TOOLS "Build DHT tools" ON)
option (OPENDHT_SYSTEMD "Install systemd module" OFF)
option (OPENDHT_SYSTEMD_UNIT_FILE_LOCATION "Where to install systemd unit file")
option (OPENDHT_ARGON2 "Use included argon2 sources" OFF)
option (OPENDHT_LTO "Build with LTO" OFF)
option (OPENDHT_SANITIZE "Build with address sanitizer and stack protector" OFF)
option (OPENDHT_PROXY_SERVER "Enable DHT proxy server, use Restinio and jsoncpp" OFF)
@@ -28,7 +27,6 @@ option (OPENDHT_PUSH_NOTIFICATIONS "Enable push notifications support" OFF)
option (OPENDHT_PROXY_SERVER_IDENTITY "Allow clients to use the node identity" OFF)
option (OPENDHT_PROXY_CLIENT "Enable DHT proxy client, use Restinio and jsoncpp" OFF)
option (OPENDHT_PROXY_OPENSSL "Build DHT proxy with OpenSSL" ON)
option (OPENDHT_PROXY_HTTP_PARSER_FORK "Build DHT proxy with custom http_parser to support old API" OFF)
CMAKE_DEPENDENT_OPTION(OPENDHT_HTTP "Build embedded http(s) client" OFF "NOT OPENDHT_PROXY_SERVER;NOT OPENDHT_PROXY_CLIENT" ON)
option (OPENDHT_PEER_DISCOVERY "Enable multicast peer discovery" ON)
option (OPENDHT_INDEX "Build DHT indexation feature" OFF)
@@ -46,22 +44,12 @@ if (NOT MSVC)
find_package (Threads)
find_package (PkgConfig REQUIRED)
find_package (GnuTLS 3.3 REQUIRED)
pkg_search_module (Nettle nettle)
pkg_search_module (Nettle REQUIRED nettle)
find_package (Msgpack 1.2 REQUIRED)
if (OPENDHT_TOOLS)
find_package (Readline 6 REQUIRED)
endif ()
if (NOT OPENDHT_ARGON2)
pkg_search_module(argon2 libargon2)
if (argon2_FOUND)
message("-- Found Argon2: " ${argon2_LIBRARY_DIRS} " (found version \"" ${argon2_VERSION} "\")")
link_directories (${argon2_LIBRARY_DIRS})
else ()
message("Argon2 not found, using included version.")
set(OPENDHT_ARGON2 ON)
endif()
endif ()
pkg_search_module(argon2 REQUIRED libargon2)
pkg_search_module(Jsoncpp jsoncpp)
if (Jsoncpp_FOUND)
add_definitions(-DOPENDHT_JSONCPP)
@@ -95,9 +83,6 @@ if (NOT MSVC)
message(SEND_ERROR "OpenSSL is required for DHT proxy as specified")
endif()
endif()
if (OPENDHT_PROXY_HTTP_PARSER_FORK)
add_definitions(-DOPENDHT_PROXY_HTTP_PARSER_FORK)
endif()
else ()
set(OPENDHT_PROXY_OPENSSL OFF)
endif ()
@@ -187,6 +172,7 @@ if (Jsoncpp_INCLUDE_DIRS)
endif ()
link_directories (${Nettle_LIBRARY_DIRS})
link_directories (${Jsoncpp_LIBRARY_DIRS})
link_directories (${argon2_LIBRARY_DIRS})
include_directories (
./
include/
@@ -314,23 +300,6 @@ if (OPENDHT_HTTP)
)
endif ()
if(OPENDHT_ARGON2)
# make sure argon2 submodule is up to date and initialized
message("Initializing Argon2 submodule")
execute_process(COMMAND git submodule update --init)
# add local argon2 files to build
list (APPEND opendht_SOURCES
argon2/src/argon2.c
argon2/src/core.c
argon2/src/blake2/blake2b.c
argon2/src/thread.c
argon2/src/ref.c
argon2/src/encoding.c
)
include_directories(argon2/include/)
endif()
if (MSVC)
list (APPEND opendht_HEADERS src/compat/msvc/unistd.h)
endif ()
@@ -343,11 +312,7 @@ if (OPENDHT_STATIC)
${opendht_HEADERS}
)
set_target_properties (opendht-static PROPERTIES OUTPUT_NAME "opendht")
if (OPENDHT_ARGON2)
target_include_directories(opendht-static SYSTEM PRIVATE argon2)
else ()
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_include_directories(opendht-static SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
target_link_libraries(opendht-static
PRIVATE ${argon2_LIBRARIES}
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${GNUTLS_LIBRARIES} ${Nettle_STATIC_LIBRARIES}
@@ -412,25 +377,20 @@ if (OPENDHT_SHARED)
set_target_properties (opendht PROPERTIES IMPORT_SUFFIX "_import.lib")
set_target_properties (opendht PROPERTIES SOVERSION ${opendht_VERSION_MAJOR} VERSION ${opendht_VERSION})
target_compile_definitions(opendht PRIVATE OPENDHT_BUILD)
if (OPENDHT_ARGON2)
target_include_directories(opendht SYSTEM PRIVATE argon2)
else ()
target_link_libraries(opendht PRIVATE ${argon2_LIBRARIES})
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
endif ()
target_include_directories(opendht SYSTEM PRIVATE ${argon2_INCLUDE_DIRS})
if (APPLE)
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${argon2_LIBRARIES}
SYSTEM "-framework CoreFoundation" "-framework Security")
else ()
target_link_libraries(opendht
PUBLIC ${CMAKE_THREAD_LIBS_INIT} ${OPENSSL_LIBRARIES}
PRIVATE ${GNUTLS_LIBRARIES} ${Nettle_LIBRARIES}
${Jsoncpp_LIBRARIES}
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY})
${FMT_LIBRARY} ${HTTP_PARSER_LIBRARY} ${argon2_LIBRARIES})
endif ()
install (TARGETS opendht DESTINATION ${CMAKE_INSTALL_LIBDIR} EXPORT opendht)
Submodule argon2 deleted from 62358ba212.
-1
View File
@@ -1,2 +1 @@
git submodule update --init
autoreconf --install --verbose -Wall
+3 -30
View File
@@ -1,6 +1,6 @@
dnl define macros
m4_define([opendht_major_version], 2)
m4_define([opendht_minor_version], 2)
m4_define([opendht_minor_version], 3)
m4_define([opendht_patch_version], 0)
m4_define([opendht_version],
[opendht_major_version.opendht_minor_version.opendht_patch_version])
@@ -132,6 +132,8 @@ AM_CONDITIONAL(PROXY_CLIENT_OR_SERVER, test x$proxy_client == xyes || test x$pro
PKG_CHECK_MODULES([Nettle], [nettle >= 2.4])
PKG_CHECK_MODULES([GnuTLS], [gnutls >= 3.3])
PKG_CHECK_MODULES([MsgPack], [msgpack >= 1.2])
PKG_CHECK_MODULES([Argon2], [libargon2])
AC_SUBST(argon2_lib, [", libargon2"])
AC_ARG_WITH([jsoncpp], AS_HELP_STRING([--without-jsoncpp], [Build without JsonCpp support]))
AS_IF([test "x$with_jsoncpp" != "xno"],
@@ -157,14 +159,6 @@ AS_IF([test "x$have_openssl" = "xyes"], [
AC_MSG_NOTICE([Not using OpenSSL])
])
AC_ARG_WITH([http_parser_fork], AS_HELP_STRING([--with-http-parser-fork], [Build with http_parser fork to support old API]))
AS_IF([test "x$with_http_parser_fork" = "xyes"],[
AC_MSG_NOTICE([Using http_parser fork])
AC_DEFINE([OPENDHT_PROXY_HTTP_PARSER_FORK], [], [Define if using http parser fork])
], [
AC_MSG_NOTICE([Not using http_parser fork])
])
AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
AC_CHECK_HEADERS([asio.hpp], exit,, AC_MSG_ERROR([Missing Asio headers files]))
CXXFLAGS="${CXXFLAGS} -DASIO_STANDALONE"
@@ -183,27 +177,6 @@ AM_COND_IF([PROXY_CLIENT_OR_SERVER], [
CXXFLAGS="${CXXFLAGS} -DMSGPACK_DISABLE_LEGACY_NIL -DMSGPACK_DISABLE_LEGACY_CONVERT"
dnl Check for Argon2
AC_ARG_WITH([argon2], AS_HELP_STRING([--without-argon2], [Use included Argon2]))
AS_IF([test "x$with_argon2" != "xno"],
[PKG_CHECK_MODULES([Argon2], [libargon2], [have_argon2=yes], [have_argon2=no])],
[have_argon2=no])
AS_IF([test "x$have_argon2" = "xyes"], [
AC_MSG_NOTICE([Using system Argon2])
AC_SUBST(argon2_lib, [", libargon2"])
], [
AS_IF([test "x$with_argon2" = "xyes"], [
AC_MSG_ERROR([Argon2 requested but not found])
],[
AC_MSG_NOTICE([Using included Argon2])
AC_SUBST(Argon2_CFLAGS, "-I\${top_srcdir}/argon2/src -I\${top_srcdir}/argon2/include")
AC_SUBST(Argon2_LIBS, "libargon2.la")
AC_SUBST(Argon2_LDFLAGS, "-L\${abs_top_srcdir}/argon2/src/.libs")
])
])
AM_CONDITIONAL([WITH_INCLUDED_ARGON2], [test "x$have_argon2" = "xno"])
AC_ARG_ENABLE([tools], AS_HELP_STRING([--disable-tools],[Disable tools (CLI DHT node)]),,build_tools=yes)
AM_CONDITIONAL(ENABLE_TOOLS, test x$build_tools == xyes)
AM_COND_IF([ENABLE_TOOLS], [
+4 -2
View File
@@ -164,7 +164,9 @@ struct OPENDHT_PUBLIC PrivateKey
~PrivateKey();
explicit operator bool() const { return key; }
PublicKey getPublicKey() const;
const PublicKey& getPublicKey() const;
const std::shared_ptr<PublicKey>& getSharedPublicKey() const;
int serialize(uint8_t* out, size_t* out_len, const std::string& password = {}) const;
Blob serialize(const std::string& password = {}) const;
@@ -199,7 +201,7 @@ private:
PrivateKey& operator=(const PrivateKey&) = delete;
Blob decryptBloc(const uint8_t* src, size_t src_size) const;
//friend dht::crypto::Identity dht::crypto::generateIdentity(const std::string&, dht::crypto::Identity, unsigned key_length);
mutable std::shared_ptr<PublicKey> publicKey_ {};
};
class OPENDHT_PUBLIC RevocationList
+4 -1
View File
@@ -66,8 +66,10 @@ private:
public:
virtual void unpackValue(const Value& v) override {
if (v.owner)
if (v.owner) {
owner = v.owner;
from = v.owner->getId();
}
BaseClass::unpackValue(v);
}
@@ -75,6 +77,7 @@ public:
return [](const Value& v){ return v.isSigned(); };
}
Sp<crypto::PublicKey> owner;
dht::InfoHash from;
};
+12
View File
@@ -257,6 +257,17 @@ public:
}
void putEncrypted(const std::string& key, InfoHash to, Value&& value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, value, bindDoneCb(cb), permanent);
}
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb={}, bool permanent = false);
void putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallbackSimple cb, bool permanent = false) {
putEncrypted(hash, to, std::forward<Value>(value), bindDoneCb(cb), permanent);
}
/**
* Insert known nodes to the routing table, without necessarly ping them.
* Usefull to restart a node and get things running fast without putting load on the network.
@@ -303,6 +314,7 @@ public:
* Get the public key fingerprint if an identity is used with this node, 0 otherwise.
*/
InfoHash getId() const;
std::shared_ptr<crypto::PublicKey> getPublicKey() const;
/**
* Get the ID of the DHT node.
-12
View File
@@ -375,15 +375,3 @@ private:
} // namespace http
} // namespace dht
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
namespace restinio
{
/* Custom HTTP-methods for RESTinio > 0.5.0.
* https://github.com/Stiffstream/restinio/issues/26
*/
constexpr const restinio::http_method_id_t method_listen {HTTP_LISTEN, "LISTEN"};
constexpr const restinio::http_method_id_t method_stats {HTTP_STATS, "STATS"};
constexpr const restinio::http_method_id_t method_sign {HTTP_SIGN, "SIGN"};
constexpr const restinio::http_method_id_t method_encrypt {HTTP_ENCRYPT, "ENCRYPT"};
} // namespace restinio
#endif
+12 -5
View File
@@ -61,6 +61,9 @@ public:
PkId getLongId() const {
return key_ ? key_->getPublicKey().getLongId() : PkId();
}
Sp<crypto::PublicKey> getPublicKey() const {
return key_ ? key_->getSharedPublicKey() : Sp<crypto::PublicKey>{};
}
ValueType secureType(ValueType&& type);
@@ -115,6 +118,10 @@ public:
void putEncrypted(const InfoHash& hash, const InfoHash& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Sp<Value> val, DoneCallback callback, bool permanent = false);
void putEncrypted(const InfoHash& hash, const crypto::PublicKey& to, Value&& v, DoneCallback callback, bool permanent = false) {
putEncrypted(hash, to, std::make_shared<Value>(std::move(v)), callback, permanent);
}
/**
* Take ownership of the value and sign it using our private key.
@@ -126,13 +133,13 @@ public:
Value decrypt(const Value& v);
void findCertificate(const InfoHash& node, const std::function<void(const Sp<crypto::Certificate>)>& cb);
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<const crypto::PublicKey>)>& cb);
void findPublicKey(const InfoHash& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb);
const Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
Sp<crypto::Certificate> registerCertificate(const InfoHash& node, const Blob& cert);
void registerCertificate(Sp<crypto::Certificate>& cert);
const Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
const Sp<const crypto::PublicKey> getPublicKey(const InfoHash& node) const;
Sp<crypto::Certificate> getCertificate(const InfoHash& node) const;
Sp<crypto::PublicKey> getPublicKey(const InfoHash& node) const;
/**
* Allows to set a custom callback called by the library to find a locally-stored certificate.
@@ -354,7 +361,7 @@ private:
// our certificate cache
std::map<InfoHash, Sp<crypto::Certificate>> nodesCertificates_ {};
std::map<InfoHash, Sp<const crypto::PublicKey>> nodesPubKeys_ {};
std::map<InfoHash, Sp<crypto::PublicKey>> nodesPubKeys_ {};
std::atomic_bool forward_all_ {false};
bool enableCache_ {false};
+4 -4
View File
@@ -356,7 +356,7 @@ struct OPENDHT_PUBLIC Value
void sign(const crypto::PrivateKey& key) {
if (isEncrypted())
throw DhtException("Can't sign encrypted data.");
owner = std::make_shared<const crypto::PublicKey>(key.getPublicKey());
owner = key.getSharedPublicKey();
signature = key.sign(getToSign());
}
@@ -368,8 +368,8 @@ struct OPENDHT_PUBLIC Value
return isSigned() and owner->checkSignature(getToSign(), signature);
}
std::shared_ptr<const crypto::PublicKey> getOwner() const {
return std::static_pointer_cast<const crypto::PublicKey>(owner);
std::shared_ptr<crypto::PublicKey> getOwner() const {
return std::static_pointer_cast<crypto::PublicKey>(owner);
}
/**
@@ -594,7 +594,7 @@ struct OPENDHT_PUBLIC Value
/**
* Public key of the signer.
*/
std::shared_ptr<const crypto::PublicKey> owner {};
std::shared_ptr<crypto::PublicKey> owner {};
/**
* Hash of the recipient (optional).
+6 -6
View File
@@ -329,11 +329,11 @@ cdef class PrivateKey(_WithID):
cdef shared_ptr[cpp.PrivateKey] _key
def getId(self):
h = InfoHash()
h._infohash = self._key.get().getPublicKey().getId()
h._infohash = self._key.get().getSharedPublicKey().get().getId()
return h
def getPublicKey(self):
pk = PublicKey()
pk._key = self._key.get().getPublicKey()
pk._key = self._key.get().getSharedPublicKey()
return pk
def decrypt(self, bytes dat):
cdef size_t d_len = len(dat)
@@ -358,17 +358,17 @@ cdef class PrivateKey(_WithID):
return k
cdef class PublicKey(_WithID):
cdef cpp.PublicKey _key
cdef cpp.shared_ptr[cpp.PublicKey] _key
def getId(self):
h = InfoHash()
h._infohash = self._key.getId()
h._infohash = self._key.get().getId()
return h
def encrypt(self, bytes dat):
cdef size_t d_len = len(dat)
cdef cpp.uint8_t* d_ptr = <cpp.uint8_t*>dat
cdef cpp.Blob indat
indat.assign(d_ptr, <cpp.uint8_t*>(d_ptr + d_len))
cdef cpp.Blob encrypted = self._key.encrypt(indat)
cdef cpp.Blob encrypted = self._key.get().encrypt(indat)
cdef char* encrypted_c_str = <char *>encrypted.data()
cdef Py_ssize_t length = encrypted.size()
return encrypted_c_str[:length]
@@ -440,7 +440,7 @@ cdef class Identity(object):
property publickey:
def __get__(self):
k = PublicKey()
k._key = self._id.first.get().getPublicKey()
k._key = self._id.first.get().getSharedPublicKey()
return k
property certificate:
def __get__(self):
+1 -1
View File
@@ -97,7 +97,7 @@ cdef extern from "opendht/crypto.h" namespace "dht::crypto":
cdef cppclass PrivateKey:
PrivateKey()
PublicKey getPublicKey() const
shared_ptr[PublicKey] getSharedPublicKey() const
Blob decrypt(Blob data) const
@staticmethod
PrivateKey generate()
+1 -28
View File
@@ -2,7 +2,7 @@ lib_LTLIBRARIES = libopendht.la
libopendht_la_CPPFLAGS = @CPPFLAGS@ -I$(top_srcdir)/include/opendht @Argon2_CFLAGS@ @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@ @OpenSSL_CFLAGS@ @Fmt_CFLAGS@
libopendht_la_LIBADD = @Argon2_LIBS@ @JsonCpp_LIBS@ @GnuTLS_LIBS@ @Nettle_LIBS@ @OpenSSL_LIBS@ @Fmt_LIBS@
libopendht_la_LDFLAGS = @LDFLAGS@ @Argon2_LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
libopendht_la_LDFLAGS = @LDFLAGS@ -version-number @OPENDHT_MAJOR_VERSION@:@OPENDHT_MINOR_VERSION@:@OPENDHT_PATCH_VERSION@
libopendht_la_SOURCES = \
dht.cpp \
storage.h \
@@ -87,30 +87,3 @@ endif
clean-local:
rm -rf libargon2.la
######################
# ARGON2 submodule #
######################
if WITH_INCLUDED_ARGON2
noinst_LTLIBRARIES = libargon2.la
libopendht_la_DEPENDENCIES = libargon2.la
libargon2_la_CFLAGS = -std=c89 -fPIC -pthread -O3 -Wall -I@top_builddir@/argon2/include -I@top_builddir@/argon2/src
libargon2_la_SOURCES = \
@top_builddir@/argon2/src/argon2.c \
@top_builddir@/argon2/src/core.c \
@top_builddir@/argon2/src/blake2/blake2b.c \
@top_builddir@/argon2/src/thread.c \
@top_builddir@/argon2/src/ref.c \
@top_builddir@/argon2/src/encoding.c
noinst_HEADERS = \
@top_builddir@/argon2/include/argon2.h \
@top_builddir@/argon2/src/blake2/blake2.h \
@top_builddir@/argon2/src/blake2/blake2-impl.h \
@top_builddir@/argon2/src/blake2/blamka-round-ref.h \
@top_builddir@/argon2/src/core.h \
@top_builddir@/argon2/src/encoding.h \
@top_builddir@/argon2/src/thread.h
endif
+15 -11
View File
@@ -368,13 +368,22 @@ PrivateKey::serialize(uint8_t* out, size_t* out_len, const std::string& password
: gnutls_x509_privkey_export_pkcs8(x509_key, GNUTLS_X509_FMT_PEM, password.c_str(), GNUTLS_PKCS_PBES2_AES_256, out, out_len);
}
PublicKey
const PublicKey&
PrivateKey::getPublicKey() const
{
PublicKey pk;
if (auto err = gnutls_pubkey_import_privkey(pk.pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
return *getSharedPublicKey();
}
const std::shared_ptr<PublicKey>&
PrivateKey::getSharedPublicKey() const
{
if (publicKey_)
return publicKey_;
auto pk = std::make_shared<PublicKey>();
if (auto err = gnutls_pubkey_import_privkey(pk->pk, key, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN, 0))
throw CryptoException(std::string("Can't retreive public key: ") + gnutls_strerror(err));
return pk;
publicKey_ = pk;
return publicKey_;
}
PublicKey::PublicKey()
@@ -540,12 +549,7 @@ PublicKey::getId() const
return {};
InfoHash id;
size_t sz = id.size();
#if GNUTLS_VERSION_NUMBER < 0x030401
const int flags = 0;
#else
const int flags = (id.size() == 32) ? GNUTLS_KEYID_USE_SHA256 : 0;
#endif
if (auto err = gnutls_pubkey_get_key_id(pk, flags, id.data(), &sz))
if (auto err = gnutls_pubkey_get_key_id(pk, 0, id.data(), &sz))
throw CryptoException(std::string("Can't get public key ID: ") + gnutls_strerror(err));
if (sz != id.size())
throw CryptoException("Can't get public key ID: wrong output length.");
@@ -1169,7 +1173,7 @@ Certificate::generate(const PrivateKey& key, const std::string& name, const Iden
}
// TODO: compute the subject key using the recommended RFC method
auto pk = key.getPublicKey();
const auto& pk = key.getPublicKey();
auto pk_id = pk.getId();
const std::string uid_str = pk_id.toString();
+22 -1
View File
@@ -873,6 +873,11 @@ Dht::listenTo(const InfoHash& id, sa_family_t af, ValueCallback cb, Value::Filte
size_t
Dht::listen(const InfoHash& id, ValueCallback cb, Value::Filter f, Where where)
{
if (not id) {
if (logger_)
logger_->w(id, "Listen called with invalid key");
return 0;
}
scheduler.syncTime();
auto token = ++listener_token;
@@ -955,7 +960,9 @@ struct GetStatus : public OpStatus {
void
Dht::put(const InfoHash& id, Sp<Value> val, DoneCallback callback, time_point created, bool permanent)
{
if (not val) {
if (not id or not val) {
if (logger_)
logger_->w(id, "Put called with invalid key or value");
if (callback)
callback(false, {});
return;
@@ -1025,6 +1032,13 @@ bool callbackWrapper(Cb get_cb, DoneCallback done_cb, const std::vector<Sp<T>>&
void
Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filter&& filter, Where&& where)
{
if (not id) {
if (logger_)
logger_->w(id, "Get called with invalid key");
if (donecb)
donecb(false, {});
return;
}
scheduler.syncTime();
auto op = std::make_shared<GetStatus<std::map<Value::Id, Sp<Value>>>>();
@@ -1065,6 +1079,13 @@ Dht::get(const InfoHash& id, GetCallback getcb, DoneCallback donecb, Value::Filt
void Dht::query(const InfoHash& id, QueryCallback cb, DoneCallback done_cb, Query&& q)
{
if (not id) {
if (logger_)
logger_->w(id, "Query called with invalid key");
if (done_cb)
done_cb(false, {});
return;
}
scheduler.syncTime();
auto op = std::make_shared<GetStatus<std::vector<Sp<FieldValueIndex>>>>();
auto f = q.where.getFilter();
-10
View File
@@ -829,13 +829,8 @@ DhtProxyClient::listen(const InfoHash& key, ValueCallback cb, Value::Filter filt
restinio::http_request_header_t header;
if (deviceKey_.empty()){ // listen
method = ListenMethod::LISTEN;
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
header.method(restinio::method_listen);
header.request_target("/" + key.toString());
#else
header.method(restinio::http_method_get());
header.request_target("/key/" + key.toString() + "/listen");
#endif
}
else {
method = ListenMethod::SUBSCRIBE;
@@ -1151,13 +1146,8 @@ DhtProxyClient::restartListeners(const asio::error_code &ec)
auto cb = listener.cb;
// define header
restinio::http_request_header_t header;
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
header.method(restinio::method_listen);
header.request_target("/" + search.first.toString());
#else
header.method(restinio::http_method_get());
header.request_target("/key/" + search.first.toString() + "/listen");
#endif
sendListen(header, cb, opstate, listener, ListenMethod::LISTEN);
}
}
-44
View File
@@ -39,26 +39,6 @@
using namespace std::placeholders;
using namespace std::chrono_literals;
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
namespace restinio {
struct custom_http_methods_t
{
static constexpr restinio::http_method_id_t from_nodejs(int m) noexcept {
if(m == method_listen.raw_id())
return method_listen;
else if(m == method_stats.raw_id())
return method_stats;
else if(m == method_sign.raw_id())
return method_sign;
else if(m == method_encrypt.raw_id())
return method_encrypt;
else
return restinio::default_http_methods_t::from_nodejs(m);
}
};
}
#endif
namespace dht {
constexpr char RESP_MSG_JSON_INCORRECT[] = "{\"err:\":\"Incorrect JSON\"}";
constexpr char RESP_MSG_SERVICE_UNAVAILABLE[] = "{\"err\":\"Incorrect DhtRunner\"}";
@@ -156,9 +136,6 @@ DhtProxyServer::onConnectionClosed(restinio::connection_id_t id)
struct DhtProxyServer::RestRouterTraitsTls : public restinio::default_tls_traits_t
{
using timer_manager_t = restinio::asio_timer_manager_t;
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
using http_methods_mapper_t = restinio::custom_http_methods_t;
#endif
using logger_t = opendht_logger_t;
using request_handler_t = RestRouter;
using connection_state_listener_t = ConnectionListener;
@@ -166,9 +143,6 @@ struct DhtProxyServer::RestRouterTraitsTls : public restinio::default_tls_traits
struct DhtProxyServer::RestRouterTraits : public restinio::default_traits_t
{
using timer_manager_t = restinio::asio_timer_manager_t;
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
using http_methods_mapper_t = restinio::custom_http_methods_t;
#endif
using logger_t = opendht_logger_t;
using request_handler_t = RestRouter;
using connection_state_listener_t = ConnectionListener;
@@ -613,11 +587,6 @@ DhtProxyServer::createRestRouter()
// **************************** LEGACY ROUTES ****************************
// node.info
router->http_get("/", std::bind(&DhtProxyServer::getNodeInfo, this, _1, _2));
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
// node.stats
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_stats.raw_id()),
"/", std::bind(&DhtProxyServer::getStats, this, _1, _2));
#endif
// key.options
router->add_handler(restinio::http_method_options(),
"/:hash", std::bind(&DhtProxyServer::options, this, _1, _2));
@@ -625,11 +594,6 @@ DhtProxyServer::createRestRouter()
router->http_get("/:hash", std::bind(&DhtProxyServer::get, this, _1, _2));
// key.post
router->http_post("/:hash", std::bind(&DhtProxyServer::put, this, _1, _2));
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
// key.listen
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_listen.raw_id()),
"/:hash", std::bind(&DhtProxyServer::listen, this, _1, _2));
#endif
#ifdef OPENDHT_PUSH_NOTIFICATIONS
// key.subscribe
router->add_handler(restinio::http_method_subscribe(),
@@ -639,14 +603,6 @@ DhtProxyServer::createRestRouter()
"/:hash", std::bind(&DhtProxyServer::unsubscribe, this, _1, _2));
#endif //OPENDHT_PUSH_NOTIFICATIONS
#ifdef OPENDHT_PROXY_SERVER_IDENTITY
#ifdef OPENDHT_PROXY_HTTP_PARSER_FORK
// key.sign
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_sign.raw_id()),
"/:hash", std::bind(&DhtProxyServer::putSigned, this, _1, _2));
// key.encrypt
router->add_handler(restinio::custom_http_methods_t::from_nodejs(restinio::method_encrypt.raw_id()),
"/:hash", std::bind(&DhtProxyServer::putEncrypted, this, _1, _2));
#endif
#endif // OPENDHT_PROXY_SERVER_IDENTITY
// **************************** NEW ROUTES ****************************
+33
View File
@@ -406,6 +406,14 @@ DhtRunner::getId() const
return {};
}
std::shared_ptr<crypto::PublicKey>
DhtRunner::getPublicKey() const
{
if (auto dht = activeDht())
return dht->getPublicKey();
return {};
}
InfoHash
DhtRunner::getNodeId() const
{
@@ -958,6 +966,31 @@ DhtRunner::putEncrypted(const std::string& key, InfoHash to, Value&& value, Done
putEncrypted(InfoHash::get(key), to, std::forward<Value>(value), std::move(cb), permanent);
}
void
DhtRunner::putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, std::shared_ptr<Value> value, DoneCallback cb, bool permanent)
{
std::unique_lock<std::mutex> lck(storage_mtx);
if (running != State::Running) {
lck.unlock();
if (cb) cb(false, {});
return;
}
ongoing_ops++;
pending_ops.emplace([=,
cb = std::move(cb),
value = std::move(value)
] (SecureDht& dht) mutable {
dht.putEncrypted(hash, *to, value, bindOpDoneCallback(std::move(cb)), permanent);
});
cv.notify_all();
}
void
DhtRunner::putEncrypted(InfoHash hash, const std::shared_ptr<crypto::PublicKey>& to, Value&& value, DoneCallback cb, bool permanent)
{
putEncrypted(hash, to, std::make_shared<Value>(std::move(value)), std::move(cb), permanent);
}
void
DhtRunner::bootstrap(const std::string& host, const std::string& service)
{
+27 -9
View File
@@ -118,7 +118,7 @@ SecureDht::secureType(ValueType&& type)
return type;
}
const Sp<crypto::Certificate>
Sp<crypto::Certificate>
SecureDht::getCertificate(const InfoHash& node) const
{
if (node == getId())
@@ -130,7 +130,7 @@ SecureDht::getCertificate(const InfoHash& node) const
return it->second;
}
const Sp<const crypto::PublicKey>
Sp<crypto::PublicKey>
SecureDht::getPublicKey(const InfoHash& node) const
{
if (node == getId())
@@ -142,7 +142,7 @@ SecureDht::getPublicKey(const InfoHash& node) const
return it->second;
}
const Sp<crypto::Certificate>
Sp<crypto::Certificate>
SecureDht::registerCertificate(const InfoHash& node, const Blob& data)
{
Sp<crypto::Certificate> crt;
@@ -200,8 +200,6 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
auto found = std::make_shared<bool>(false);
dht_->get(node, [cb,node,found,this](const std::vector<Sp<Value>>& vals) {
if (*found)
return false;
for (const auto& v : vals) {
if (auto cert = registerCertificate(node, v->data)) {
*found = true;
@@ -212,7 +210,7 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
return false;
}
}
return true;
return !*found;
}, [cb,found](bool) {
if (!*found and cb)
cb(nullptr);
@@ -220,7 +218,7 @@ SecureDht::findCertificate(const InfoHash& node, const std::function<void(const
}
void
SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp<const crypto::PublicKey>)>& cb)
SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp<crypto::PublicKey>)>& cb)
{
auto pk = getPublicKey(node);
if (pk && *pk) {
@@ -230,7 +228,7 @@ SecureDht::findPublicKey(const InfoHash& node, const std::function<void(const Sp
cb(pk);
return;
}
findCertificate(node, [=](const Sp<crypto::Certificate> crt) {
findCertificate(node, [=](const Sp<crypto::Certificate>& crt) {
if (crt && *crt) {
auto pk = std::make_shared<crypto::PublicKey>(crt->getPublicKey());
if (*pk) {
@@ -405,7 +403,7 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val,
callback(false, {});
return;
}
findPublicKey(to, [=](const Sp<const crypto::PublicKey>& pk) {
findPublicKey(to, [this, hash, val = std::move(val), callback = std::move(callback), permanent](const Sp<crypto::PublicKey>& pk) {
if(!pk || !*pk) {
if (callback)
callback(false, {});
@@ -424,6 +422,26 @@ SecureDht::putEncrypted(const InfoHash& hash, const InfoHash& to, Sp<Value> val,
});
}
void
SecureDht::putEncrypted(const InfoHash& hash, const crypto::PublicKey& pk, Sp<Value> val, DoneCallback callback, bool permanent)
{
if (not key_) {
if (callback)
callback(false, {});
return;
}
if (logger_)
logger_->w("Encrypting data for PK: %s", pk.getLongId().to_c_str());
try {
dht_->put(hash, encrypt(*val, pk), callback, time_point::max(), permanent);
} catch (const std::exception& e) {
if (logger_)
logger_->e("Error putting encrypted data: %s", e.what());
if (callback)
callback(false, {});
}
}
void
SecureDht::sign(Value& v) const
{
+2 -2
View File
@@ -163,7 +163,7 @@ Value::msgpack_unpack_body(const msgpack::object& o)
throw msgpack::type_error();
crypto::PublicKey new_owner;
new_owner.msgpack_unpack(*rowner);
owner = std::make_shared<const crypto::PublicKey>(std::move(new_owner));
owner = std::make_shared<crypto::PublicKey>(std::move(new_owner));
if (auto rrecipient = findMapValue(*rbody, VALUE_KEY_TO)) {
recipient = rrecipient->as<InfoHash>();
}
@@ -193,7 +193,7 @@ Value::Value(const Json::Value& json)
if (jowner.isString()) {
auto ownerStr = jowner.asString();
auto ownerBlob = std::vector<unsigned char>(ownerStr.begin(), ownerStr.end());
owner = std::make_shared<const crypto::PublicKey>(ownerBlob);
owner = std::make_shared<crypto::PublicKey>(ownerBlob);
}
const auto& jto = json[VALUE_KEY_TO];
if (jto.isString())
+1 -1
View File
@@ -33,7 +33,7 @@ CryptoTester::setUp() {
void
CryptoTester::testSignatureEncryption() {
auto key = dht::crypto::PrivateKey::generate();
auto public_key = key.getPublicKey();
const auto& public_key = key.getPublicKey();
std::vector<uint8_t> data1 {5, 10};
std::vector<uint8_t> data2(64 * 1024, 10);
+44
View File
@@ -19,6 +19,8 @@
#include "dhtrunnertester.h"
#include <opendht/thread_pool.h>
#include <chrono>
#include <mutex>
#include <condition_variable>
@@ -230,6 +232,13 @@ DhtRunnerTester::testIdOps() {
cv.notify_all();
});
node1.putEncrypted(key, node2.getPublicKey(), dht::Value("yo"), [&](bool ok){
CPPUNIT_ASSERT(ok);
std::lock_guard<std::mutex> lk(mutex);
valueCount++;
cv.notify_all();
});
node2.listen<std::string>(key, [&](std::string&& value){
CPPUNIT_ASSERT_EQUAL("yo"s, value);
std::lock_guard<std::mutex> lk(mutex);
@@ -291,4 +300,39 @@ DhtRunnerTester::testListenLotOfBytes() {
node3.cancelListen(foo, ftokenfoo.get());
}
void
DhtRunnerTester::testMultithread() {
std::mutex mutex;
std::condition_variable cv;
unsigned putCount(0);
unsigned putOkCount(0);
constexpr unsigned N = 2048;
for (unsigned i=0; i<N; i++) {
dht::ThreadPool::computation().run([&]{
node2.put(dht::InfoHash::get("123" + std::to_string(i)), "hehe", [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
putCount++;
if (ok) putOkCount++;
cv.notify_all();
});
node2.get(dht::InfoHash::get("123" + std::to_string(N-i-1)), [](const std::shared_ptr<dht::Value>&){
return true;
}, [&](bool ok) {
std::lock_guard<std::mutex> lock(mutex);
putCount++;
if (ok) putOkCount++;
cv.notify_all();
});
});
}
std::unique_lock<std::mutex> lk(mutex);
CPPUNIT_ASSERT(cv.wait_for(lk, 30s, [&]{ return putCount == 2*N; }));
CPPUNIT_ASSERT_EQUAL(2*N, putOkCount);
}
} // namespace test
+5
View File
@@ -67,6 +67,11 @@ class DhtRunnerTester : public CppUnit::TestFixture {
* Test listen method with lot of datas
*/
void testListenLotOfBytes();
/**
* Test multithread
*/
void testMultithread();
};
} // namespace test
+3 -3
View File
@@ -4,10 +4,10 @@ noinst_HEADERS = tools_common.h
AM_CPPFLAGS = -isystem @top_srcdir@/include @JsonCpp_CFLAGS@ @MsgPack_CFLAGS@
dhtnode_SOURCES = dhtnode.cpp
dhtnode_LDFLAGS = -lopendht -lreadline -L@top_builddir@/src/.libs @Argon2_LDFLAGS@ @GnuTLS_LIBS@
dhtnode_LDFLAGS = -lopendht -lreadline -L@top_builddir@/src/.libs @GnuTLS_LIBS@
dhtchat_SOURCES = dhtchat.cpp
dhtchat_LDFLAGS = -lopendht -lreadline -L@top_builddir@/src/.libs @Argon2_LDFLAGS@ @GnuTLS_LIBS@
dhtchat_LDFLAGS = -lopendht -lreadline -L@top_builddir@/src/.libs @GnuTLS_LIBS@
dhtscanner_SOURCES = dhtscanner.cpp
dhtscanner_LDFLAGS = -lopendht -lreadline -L@top_builddir@/src/.libs @Argon2_LDFLAGS@ @GnuTLS_LIBS@
dhtscanner_LDFLAGS = -lopendht -lreadline -L@top_builddir@/src/.libs @GnuTLS_LIBS@