aboutsummaryrefslogtreecommitdiff
path: root/contrib/epee
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/epee')
-rw-r--r--contrib/epee/include/math_helper.h2
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.h2
-rw-r--r--contrib/epee/include/net/abstract_tcp_server2.inl9
-rw-r--r--contrib/epee/include/net/levin_protocol_handler_async.h2
-rw-r--r--contrib/epee/include/net/net_fwd.h38
-rw-r--r--contrib/epee/include/net/net_helper.h11
-rw-r--r--contrib/epee/include/net/net_ssl.h5
-rw-r--r--contrib/epee/include/net/net_utils_base.h54
-rw-r--r--contrib/epee/include/rolling_median.h236
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization.h3
-rw-r--r--contrib/epee/include/serialization/keyvalue_serialization_overloads.h3
-rw-r--r--contrib/epee/include/storages/portable_storage_from_bin.h1
-rw-r--r--contrib/epee/src/buffer.cpp3
-rw-r--r--contrib/epee/src/mlog.cpp2
-rw-r--r--contrib/epee/src/net_ssl.cpp133
-rw-r--r--contrib/epee/src/net_utils_base.cpp18
-rw-r--r--contrib/epee/src/wipeable_string.cpp17
17 files changed, 512 insertions, 27 deletions
diff --git a/contrib/epee/include/math_helper.h b/contrib/epee/include/math_helper.h
index 35b649972..ddc1f7f4b 100644
--- a/contrib/epee/include/math_helper.h
+++ b/contrib/epee/include/math_helper.h
@@ -32,7 +32,7 @@
#include <list>
#include <numeric>
-#include <boost/timer.hpp>
+#include <boost/timer/timer.hpp>
#include <boost/uuid/uuid.hpp>
#include <boost/uuid/random_generator.hpp>
diff --git a/contrib/epee/include/net/abstract_tcp_server2.h b/contrib/epee/include/net/abstract_tcp_server2.h
index 374a28a2e..c1aa0fe5f 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.h
+++ b/contrib/epee/include/net/abstract_tcp_server2.h
@@ -70,7 +70,7 @@ namespace net_utils
struct i_connection_filter
{
- virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address)=0;
+ virtual bool is_remote_host_allowed(const epee::net_utils::network_address &address, time_t *t = NULL)=0;
protected:
virtual ~i_connection_filter(){}
};
diff --git a/contrib/epee/include/net/abstract_tcp_server2.inl b/contrib/epee/include/net/abstract_tcp_server2.inl
index 821594355..fa5858b9f 100644
--- a/contrib/epee/include/net/abstract_tcp_server2.inl
+++ b/contrib/epee/include/net/abstract_tcp_server2.inl
@@ -54,6 +54,9 @@
#undef MONERO_DEFAULT_LOG_CATEGORY
#define MONERO_DEFAULT_LOG_CATEGORY "net"
+#define AGGRESSIVE_TIMEOUT_THRESHOLD 120 // sockets
+#define NEW_CONNECTION_TIMEOUT_LOCAL 1200000 // 2 minutes
+#define NEW_CONNECTION_TIMEOUT_REMOTE 10000 // 10 seconds
#define DEFAULT_TIMEOUT_MS_LOCAL 1800000 // 30 minutes
#define DEFAULT_TIMEOUT_MS_REMOTE 300000 // 5 minutes
#define TIMEOUT_EXTRA_MS_PER_BYTE 0.2
@@ -189,7 +192,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
m_protocol_handler.after_init_connection();
- reset_timer(get_default_timeout(), false);
+ reset_timer(boost::posix_time::milliseconds(m_local ? NEW_CONNECTION_TIMEOUT_LOCAL : NEW_CONNECTION_TIMEOUT_REMOTE), false);
// first read on the raw socket to detect SSL for the server
buffer_ssl_init_fill = 0;
@@ -691,7 +694,7 @@ PRAGMA_WARNING_DISABLE_VS(4355)
{
unsigned count;
try { count = host_count(m_host); } catch (...) { count = 0; }
- const unsigned shift = std::min(std::max(count, 1u) - 1, 8u);
+ const unsigned shift = get_state().sock_count > AGGRESSIVE_TIMEOUT_THRESHOLD ? std::min(std::max(count, 1u) - 1, 8u) : 0;
boost::posix_time::milliseconds timeout(0);
if (m_local)
timeout = boost::posix_time::milliseconds(DEFAULT_TIMEOUT_MS_LOCAL >> shift);
@@ -730,8 +733,6 @@ PRAGMA_WARNING_DISABLE_VS(4355)
template<class t_protocol_handler>
void connection<t_protocol_handler>::reset_timer(boost::posix_time::milliseconds ms, bool add)
{
- if (m_connection_type != e_connection_type_RPC)
- return;
MTRACE("Setting " << ms << " expiry");
auto self = safe_shared_from_this();
if(!self)
diff --git a/contrib/epee/include/net/levin_protocol_handler_async.h b/contrib/epee/include/net/levin_protocol_handler_async.h
index a1ea3e680..116b3ace1 100644
--- a/contrib/epee/include/net/levin_protocol_handler_async.h
+++ b/contrib/epee/include/net/levin_protocol_handler_async.h
@@ -266,7 +266,7 @@ public:
m_pservice_endpoint(psnd_hndlr),
m_config(config),
m_connection_context(conn_context),
- m_cache_in_buffer(256 * 1024),
+ m_cache_in_buffer(4 * 1024),
m_state(stream_state_head)
{
m_close_called = 0;
diff --git a/contrib/epee/include/net/net_fwd.h b/contrib/epee/include/net/net_fwd.h
new file mode 100644
index 000000000..ba4fe6259
--- /dev/null
+++ b/contrib/epee/include/net/net_fwd.h
@@ -0,0 +1,38 @@
+// Copyright (c) 2019, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+#pragma once
+
+namespace epee
+{
+ namespace net_utils
+ {
+ struct ssl_authentication_t;
+ class ssl_options_t;
+ }
+}
diff --git a/contrib/epee/include/net/net_helper.h b/contrib/epee/include/net/net_helper.h
index 89cef8134..e315555fc 100644
--- a/contrib/epee/include/net/net_helper.h
+++ b/contrib/epee/include/net/net_helper.h
@@ -193,7 +193,6 @@ namespace net_utils
return CONNECT_FAILURE;
}
}
- m_ssl_options.support = ssl_support_t::e_ssl_support_enabled;
}
return CONNECT_SUCCESS;
}else
@@ -223,7 +222,6 @@ namespace net_utils
return false;
if (m_ssl_options.support == epee::net_utils::ssl_support_t::e_ssl_support_autodetect)
{
- m_ssl_options.support = epee::net_utils::ssl_support_t::e_ssl_support_enabled;
if (try_connect_result == CONNECT_NO_SSL)
{
MERROR("SSL handshake failed on an autodetect connection, reconnecting without SSL");
@@ -396,7 +394,7 @@ namespace net_utils
if (!m_connected || !m_ssl_socket->next_layer().is_open())
return false;
if (ssl)
- *ssl = m_ssl_options.support == ssl_support_t::e_ssl_support_enabled;
+ *ssl = m_ssl_options.support != ssl_support_t::e_ssl_support_disabled;
return true;
}
@@ -448,6 +446,7 @@ namespace net_utils
{
MTRACE("Connection err_code eof.");
//connection closed there, empty
+ buff.clear();
return true;
}
@@ -650,7 +649,7 @@ namespace net_utils
bool write(const void* data, size_t sz, boost::system::error_code& ec)
{
bool success;
- if(m_ssl_options.support == ssl_support_t::e_ssl_support_enabled)
+ if(m_ssl_options.support != ssl_support_t::e_ssl_support_disabled)
success = boost::asio::write(*m_ssl_socket, boost::asio::buffer(data, sz), ec);
else
success = boost::asio::write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), ec);
@@ -659,7 +658,7 @@ namespace net_utils
void async_write(const void* data, size_t sz, boost::system::error_code& ec)
{
- if(m_ssl_options.support == ssl_support_t::e_ssl_support_enabled)
+ if(m_ssl_options.support != ssl_support_t::e_ssl_support_disabled)
boost::asio::async_write(*m_ssl_socket, boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
else
boost::asio::async_write(m_ssl_socket->next_layer(), boost::asio::buffer(data, sz), boost::lambda::var(ec) = boost::lambda::_1);
@@ -667,7 +666,7 @@ namespace net_utils
void async_read(char* buff, size_t sz, boost::asio::detail::transfer_at_least_t transfer_at_least, handler_obj& hndlr)
{
- if(m_ssl_options.support != ssl_support_t::e_ssl_support_enabled)
+ if(m_ssl_options.support == ssl_support_t::e_ssl_support_disabled)
boost::asio::async_read(m_ssl_socket->next_layer(), boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
else
boost::asio::async_read(*m_ssl_socket, boost::asio::buffer(buff, sz), transfer_at_least, hndlr);
diff --git a/contrib/epee/include/net/net_ssl.h b/contrib/epee/include/net/net_ssl.h
index 957903ff8..3a97dfdaf 100644
--- a/contrib/epee/include/net/net_ssl.h
+++ b/contrib/epee/include/net/net_ssl.h
@@ -37,6 +37,8 @@
#include <boost/asio/ssl.hpp>
#include <boost/system/error_code.hpp>
+#define SSL_FINGERPRINT_SIZE 32
+
namespace epee
{
namespace net_utils
@@ -133,6 +135,9 @@ namespace net_utils
constexpr size_t get_ssl_magic_size() { return 9; }
bool is_ssl(const unsigned char *data, size_t len);
bool ssl_support_from_string(ssl_support_t &ssl, boost::string_ref s);
+
+ bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
+ bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert);
}
}
diff --git a/contrib/epee/include/net/net_utils_base.h b/contrib/epee/include/net/net_utils_base.h
index 50536f63b..62618537f 100644
--- a/contrib/epee/include/net/net_utils_base.h
+++ b/contrib/epee/include/net/net_utils_base.h
@@ -41,7 +41,7 @@
#define MONERO_DEFAULT_LOG_CATEGORY "net"
#ifndef MAKE_IP
-#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(a4<<24))
+#define MAKE_IP( a1, a2, a3, a4 ) (a1|(a2<<8)|(a3<<16)|(((uint32_t)a4)<<24))
#endif
#if BOOST_VERSION >= 107000
@@ -107,6 +107,53 @@ namespace net_utils
inline bool operator>=(const ipv4_network_address& lhs, const ipv4_network_address& rhs) noexcept
{ return !lhs.less(rhs); }
+ class ipv4_network_subnet
+ {
+ uint32_t m_ip;
+ uint8_t m_mask;
+
+ public:
+ constexpr ipv4_network_subnet() noexcept
+ : ipv4_network_subnet(0, 0)
+ {}
+
+ constexpr ipv4_network_subnet(uint32_t ip, uint8_t mask) noexcept
+ : m_ip(ip), m_mask(mask) {}
+
+ bool equal(const ipv4_network_subnet& other) const noexcept;
+ bool less(const ipv4_network_subnet& other) const noexcept;
+ constexpr bool is_same_host(const ipv4_network_subnet& other) const noexcept
+ { return subnet() == other.subnet(); }
+ bool matches(const ipv4_network_address &address) const;
+
+ constexpr uint32_t subnet() const noexcept { return m_ip & ~(0xffffffffull << m_mask); }
+ std::string str() const;
+ std::string host_str() const;
+ bool is_loopback() const;
+ bool is_local() const;
+ static constexpr address_type get_type_id() noexcept { return address_type::invalid; }
+ static constexpr zone get_zone() noexcept { return zone::public_; }
+ static constexpr bool is_blockable() noexcept { return true; }
+
+ BEGIN_KV_SERIALIZE_MAP()
+ KV_SERIALIZE(m_ip)
+ KV_SERIALIZE(m_mask)
+ END_KV_SERIALIZE_MAP()
+ };
+
+ inline bool operator==(const ipv4_network_subnet& lhs, const ipv4_network_subnet& rhs) noexcept
+ { return lhs.equal(rhs); }
+ inline bool operator!=(const ipv4_network_subnet& lhs, const ipv4_network_subnet& rhs) noexcept
+ { return !lhs.equal(rhs); }
+ inline bool operator<(const ipv4_network_subnet& lhs, const ipv4_network_subnet& rhs) noexcept
+ { return lhs.less(rhs); }
+ inline bool operator<=(const ipv4_network_subnet& lhs, const ipv4_network_subnet& rhs) noexcept
+ { return !rhs.less(lhs); }
+ inline bool operator>(const ipv4_network_subnet& lhs, const ipv4_network_subnet& rhs) noexcept
+ { return rhs.less(lhs); }
+ inline bool operator>=(const ipv4_network_subnet& lhs, const ipv4_network_subnet& rhs) noexcept
+ { return !lhs.less(rhs); }
+
class network_address
{
struct interface
@@ -294,6 +341,11 @@ namespace net_utils
m_max_speed_up(0)
{}
+ connection_context_base(const connection_context_base& a): connection_context_base()
+ {
+ set_details(a.m_connection_id, a.m_remote_address, a.m_is_income, a.m_ssl);
+ }
+
connection_context_base& operator=(const connection_context_base& a)
{
set_details(a.m_connection_id, a.m_remote_address, a.m_is_income, a.m_ssl);
diff --git a/contrib/epee/include/rolling_median.h b/contrib/epee/include/rolling_median.h
new file mode 100644
index 000000000..8b5a82a84
--- /dev/null
+++ b/contrib/epee/include/rolling_median.h
@@ -0,0 +1,236 @@
+// Copyright (c) 2019, The Monero Project
+//
+// All rights reserved.
+//
+// Redistribution and use in source and binary forms, with or without modification, are
+// permitted provided that the following conditions are met:
+//
+// 1. Redistributions of source code must retain the above copyright notice, this list of
+// conditions and the following disclaimer.
+//
+// 2. Redistributions in binary form must reproduce the above copyright notice, this list
+// of conditions and the following disclaimer in the documentation and/or other
+// materials provided with the distribution.
+//
+// 3. Neither the name of the copyright holder nor the names of its contributors may be
+// used to endorse or promote products derived from this software without specific
+// prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
+// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+// MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
+// THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+// PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+// STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
+// THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+//
+// Adapted from source by AShelly:
+// Copyright (c) 2011 ashelly.myopenid.com, licenced under the MIT licence
+// https://stackoverflow.com/questions/5527437/rolling-median-in-c-turlach-implementation
+// https://stackoverflow.com/questions/1309263/rolling-median-algorithm-in-c
+// https://ideone.com/XPbl6
+
+#pragma once
+
+#include <stdlib.h>
+#include <stdint.h>
+
+namespace epee
+{
+namespace misc_utils
+{
+
+template<typename Item>
+struct rolling_median_t
+{
+private:
+ Item* data; //circular queue of values
+ int* pos; //index into `heap` for each value
+ int* heap; //max/median/min heap holding indexes into `data`.
+ int N; //allocated size.
+ int idx; //position in circular queue
+ int minCt; //count of items in min heap
+ int maxCt; //count of items in max heap
+ int sz; //count of items in heap
+
+private:
+
+ //returns true if heap[i] < heap[j]
+ bool mmless(int i, int j) const
+ {
+ return data[heap[i]] < data[heap[j]];
+ }
+
+ //swaps items i&j in heap, maintains indexes
+ bool mmexchange(int i, int j)
+ {
+ const int t = heap[i];
+ heap[i] = heap[j];
+ heap[j] = t;
+ pos[heap[i]] = i;
+ pos[heap[j]] = j;
+ return 1;
+ }
+
+ //swaps items i&j if i<j; returns true if swapped
+ bool mmCmpExch(int i, int j)
+ {
+ return mmless(i, j) && mmexchange(i, j);
+ }
+
+ //maintains minheap property for all items below i.
+ void minSortDown(int i)
+ {
+ for (i *= 2; i <= minCt; i *= 2)
+ {
+ if (i < minCt && mmless(i + 1, i))
+ ++i;
+ if (!mmCmpExch(i, i / 2))
+ break;
+ }
+ }
+
+ //maintains maxheap property for all items below i. (negative indexes)
+ void maxSortDown(int i)
+ {
+ for (i *= 2; i >= -maxCt; i *= 2)
+ {
+ if (i > -maxCt && mmless(i, i - 1))
+ --i;
+ if (!mmCmpExch(i / 2, i))
+ break;
+ }
+ }
+
+ //maintains minheap property for all items above i, including median
+ //returns true if median changed
+ bool minSortUp(int i)
+ {
+ while (i > 0 && mmCmpExch(i, i / 2))
+ i /= 2;
+ return i == 0;
+ }
+
+ //maintains maxheap property for all items above i, including median
+ //returns true if median changed
+ bool maxSortUp(int i)
+ {
+ while (i < 0 && mmCmpExch(i / 2, i))
+ i /= 2;
+ return i == 0;
+ }
+
+protected:
+ rolling_median_t &operator=(const rolling_median_t&) = delete;
+ rolling_median_t(const rolling_median_t&) = delete;
+
+public:
+ //creates new rolling_median_t: to calculate `nItems` running median.
+ rolling_median_t(size_t N): N(N)
+ {
+ int size = N * (sizeof(Item) + sizeof(int) * 2);
+ data = (Item*)malloc(size);
+ pos = (int*) (data + N);
+ heap = pos + N + (N / 2); //points to middle of storage.
+ clear();
+ }
+
+ rolling_median_t(rolling_median_t &&m)
+ {
+ free(data);
+ memcpy(this, &m, sizeof(rolling_median_t));
+ m.data = NULL;
+ }
+ rolling_median_t &operator=(rolling_median_t &&m)
+ {
+ free(data);
+ memcpy(this, &m, sizeof(rolling_median_t));
+ m.data = NULL;
+ return *this;
+ }
+
+ ~rolling_median_t()
+ {
+ free(data);
+ }
+
+ void clear()
+ {
+ idx = 0;
+ minCt = 0;
+ maxCt = 0;
+ sz = 0;
+ int nItems = N;
+ while (nItems--) //set up initial heap fill pattern: median,max,min,max,...
+ {
+ pos[nItems] = ((nItems + 1) / 2) * ((nItems & 1) ? -1 : 1);
+ heap[pos[nItems]] = nItems;
+ }
+ }
+
+ int size() const
+ {
+ return sz;
+ }
+
+ //Inserts item, maintains median in O(lg nItems)
+ void insert(Item v)
+ {
+ int p = pos[idx];
+ Item old = data[idx];
+ data[idx] = v;
+ idx = (idx + 1) % N;
+ sz = std::min<int>(sz + 1, N);
+ if (p > 0) //new item is in minHeap
+ {
+ if (minCt < (N - 1) / 2)
+ {
+ ++minCt;
+ }
+ else if (v > old)
+ {
+ minSortDown(p);
+ return;
+ }
+ if (minSortUp(p) && mmCmpExch(0, -1))
+ maxSortDown(-1);
+ }
+ else if (p < 0) //new item is in maxheap
+ {
+ if (maxCt < N / 2)
+ {
+ ++maxCt;
+ }
+ else if (v < old)
+ {
+ maxSortDown(p);
+ return;
+ }
+ if (maxSortUp(p) && minCt && mmCmpExch(1, 0))
+ minSortDown(1);
+ }
+ else //new item is at median
+ {
+ if (maxCt && maxSortUp(-1))
+ maxSortDown(-1);
+ if (minCt && minSortUp(1))
+ minSortDown(1);
+ }
+ }
+
+ //returns median item (or average of 2 when item count is even)
+ Item median() const
+ {
+ Item v = data[heap[0]];
+ if (minCt < maxCt)
+ {
+ v = (v + data[heap[-1]]) / 2;
+ }
+ return v;
+ }
+};
+
+}
+}
diff --git a/contrib/epee/include/serialization/keyvalue_serialization.h b/contrib/epee/include/serialization/keyvalue_serialization.h
index fc5a21851..5459c8409 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization.h
@@ -32,6 +32,9 @@
#include "enableable.h"
#include "keyvalue_serialization_overloads.h"
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
+
namespace epee
{
/************************************************************************/
diff --git a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
index 15c95f07a..fc8b90a2c 100644
--- a/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
+++ b/contrib/epee/include/serialization/keyvalue_serialization_overloads.h
@@ -33,6 +33,9 @@
#include <boost/mpl/vector.hpp>
#include <boost/mpl/contains_fwd.hpp>
+#undef MONERO_DEFAULT_LOG_CATEGORY
+#define MONERO_DEFAULT_LOG_CATEGORY "serialization"
+
namespace epee
{
namespace
diff --git a/contrib/epee/include/storages/portable_storage_from_bin.h b/contrib/epee/include/storages/portable_storage_from_bin.h
index 2884f8c5e..e0a32b3ca 100644
--- a/contrib/epee/include/storages/portable_storage_from_bin.h
+++ b/contrib/epee/include/storages/portable_storage_from_bin.h
@@ -136,6 +136,7 @@ namespace epee
//for pod types
array_entry_t<type_name> sa;
size_t size = read_varint();
+ CHECK_AND_ASSERT_THROW_MES(size <= m_count, "Size sanity check failed");
sa.reserve(size);
//TODO: add some optimization here later
while(size--)
diff --git a/contrib/epee/src/buffer.cpp b/contrib/epee/src/buffer.cpp
index d637b905e..10ea6de56 100644
--- a/contrib/epee/src/buffer.cpp
+++ b/contrib/epee/src/buffer.cpp
@@ -64,7 +64,8 @@ void buffer::append(const void *data, size_t sz)
size_t reserve = (((size() + sz) * 3 / 2) + 4095) & ~4095;
new_storage.reserve(reserve);
new_storage.resize(size());
- memcpy(new_storage.data(), storage.data() + offset, storage.size() - offset);
+ if (size() > 0)
+ memcpy(new_storage.data(), storage.data() + offset, storage.size() - offset);
offset = 0;
std::swap(storage, new_storage);
}
diff --git a/contrib/epee/src/mlog.cpp b/contrib/epee/src/mlog.cpp
index 9b6b832d1..4c6ad5516 100644
--- a/contrib/epee/src/mlog.cpp
+++ b/contrib/epee/src/mlog.cpp
@@ -100,7 +100,7 @@ static const char *get_default_categories(int level)
switch (level)
{
case 0:
- categories = "*:WARNING,net:FATAL,net.http:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO";
+ categories = "*:WARNING,net:FATAL,net.http:FATAL,net.ssl:FATAL,net.p2p:FATAL,net.cn:FATAL,global:INFO,verify:FATAL,serialization:FATAL,stacktrace:INFO,logging:INFO,msgwriter:INFO";
break;
case 1:
categories = "*:INFO,global:INFO,stacktrace:INFO,logging:INFO,msgwriter:INFO,perf.*:DEBUG";
diff --git a/contrib/epee/src/net_ssl.cpp b/contrib/epee/src/net_ssl.cpp
index 7bedb18ac..7d48d2a64 100644
--- a/contrib/epee/src/net_ssl.cpp
+++ b/contrib/epee/src/net_ssl.cpp
@@ -78,6 +78,24 @@ namespace
};
using openssl_bignum = std::unique_ptr<BIGNUM, openssl_bignum_free>;
+ struct openssl_ec_key_free
+ {
+ void operator()(EC_KEY* ptr) const noexcept
+ {
+ EC_KEY_free(ptr);
+ }
+ };
+ using openssl_ec_key = std::unique_ptr<EC_KEY, openssl_ec_key_free>;
+
+ struct openssl_group_free
+ {
+ void operator()(EC_GROUP* ptr) const noexcept
+ {
+ EC_GROUP_free(ptr);
+ }
+ };
+ using openssl_group = std::unique_ptr<EC_GROUP, openssl_group_free>;
+
boost::system::error_code load_ca_file(boost::asio::ssl::context& ctx, const std::string& path)
{
SSL_CTX* const ssl_ctx = ctx.native_handle(); // could be moved from context
@@ -101,7 +119,7 @@ namespace net_utils
// https://stackoverflow.com/questions/256405/programmatically-create-x509-certificate-using-openssl
-bool create_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
+bool create_rsa_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
{
MGINFO("Generating SSL certificate");
pkey = EVP_PKEY_new();
@@ -171,6 +189,87 @@ bool create_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert)
return true;
}
+bool create_ec_ssl_certificate(EVP_PKEY *&pkey, X509 *&cert, int type)
+{
+ MGINFO("Generating SSL certificate");
+ pkey = EVP_PKEY_new();
+ if (!pkey)
+ {
+ MERROR("Failed to create new private key");
+ return false;
+ }
+
+ openssl_pkey pkey_deleter{pkey};
+ openssl_ec_key ec_key{EC_KEY_new()};
+ if (!ec_key)
+ {
+ MERROR("Error allocating EC private key");
+ return false;
+ }
+
+ EC_GROUP *group = EC_GROUP_new_by_curve_name(type);
+ if (!group)
+ {
+ MERROR("Error getting EC group " << type);
+ return false;
+ }
+ openssl_group group_deleter{group};
+
+ EC_GROUP_set_asn1_flag(group, OPENSSL_EC_NAMED_CURVE);
+ EC_GROUP_set_point_conversion_form(group, POINT_CONVERSION_UNCOMPRESSED);
+
+ if (!EC_GROUP_check(group, NULL))
+ {
+ MERROR("Group failed check: " << ERR_reason_error_string(ERR_get_error()));
+ return false;
+ }
+ if (EC_KEY_set_group(ec_key.get(), group) != 1)
+ {
+ MERROR("Error setting EC group");
+ return false;
+ }
+ if (EC_KEY_generate_key(ec_key.get()) != 1)
+ {
+ MERROR("Error generating EC private key");
+ return false;
+ }
+ if (EVP_PKEY_assign_EC_KEY(pkey, ec_key.get()) <= 0)
+ {
+ MERROR("Error assigning EC private key");
+ return false;
+ }
+
+ // the key is now managed by the EVP_PKEY structure
+ (void)ec_key.release();
+
+ cert = X509_new();
+ if (!cert)
+ {
+ MERROR("Failed to create new X509 certificate");
+ return false;
+ }
+ ASN1_INTEGER_set(X509_get_serialNumber(cert), 1);
+ X509_gmtime_adj(X509_get_notBefore(cert), 0);
+ X509_gmtime_adj(X509_get_notAfter(cert), 3600 * 24 * 182); // half a year
+ if (!X509_set_pubkey(cert, pkey))
+ {
+ MERROR("Error setting pubkey on certificate");
+ X509_free(cert);
+ return false;
+ }
+ X509_NAME *name = X509_get_subject_name(cert);
+ X509_set_issuer_name(cert, name);
+
+ if (X509_sign(cert, pkey, EVP_sha256()) == 0)
+ {
+ MERROR("Error signing certificate");
+ X509_free(cert);
+ return false;
+ }
+ (void)pkey_deleter.release();
+ return true;
+}
+
ssl_options_t::ssl_options_t(std::vector<std::vector<std::uint8_t>> fingerprints, std::string ca_path)
: fingerprints_(std::move(fingerprints)),
ca_path(std::move(ca_path)),
@@ -195,7 +294,7 @@ boost::asio::ssl::context ssl_options_t::create_context() const
ssl_context.set_options(boost::asio::ssl::context::no_tlsv1_1);
// only allow a select handful of tls v1.3 and v1.2 ciphers to be used
- SSL_CTX_set_cipher_list(ssl_context.native_handle(), "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-CHACHA20-POLY1305");
+ SSL_CTX_set_cipher_list(ssl_context.native_handle(), "ECDHE-ECDSA-CHACHA20-POLY1305-SHA256:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-GCM-SHA256");
// set options on the SSL context for added security
SSL_CTX *ctx = ssl_context.native_handle();
@@ -214,6 +313,10 @@ boost::asio::ssl::context ssl_options_t::create_context() const
#ifdef SSL_OP_NO_COMPRESSION
SSL_CTX_set_options(ctx, SSL_OP_NO_COMPRESSION);
#endif
+#ifdef SSL_OP_CIPHER_SERVER_PREFERENCE
+ SSL_CTX_set_options(ctx, SSL_OP_CIPHER_SERVER_PREFERENCE);
+#endif
+ SSL_CTX_set_ecdh_auto(ctx, 1);
switch (verification)
{
@@ -240,11 +343,29 @@ boost::asio::ssl::context ssl_options_t::create_context() const
{
EVP_PKEY *pkey;
X509 *cert;
- CHECK_AND_ASSERT_THROW_MES(create_ssl_certificate(pkey, cert), "Failed to create certificate");
+ bool ok = false;
+
+#ifdef USE_EXTRA_EC_CERT
+ CHECK_AND_ASSERT_THROW_MES(create_ec_ssl_certificate(pkey, cert, NID_secp256k1), "Failed to create certificate");
+ CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
+ if (!SSL_CTX_use_PrivateKey(ctx, pkey))
+ MERROR("Failed to use generated EC private key for " << NID_secp256k1);
+ else
+ ok = true;
+ X509_free(cert);
+ EVP_PKEY_free(pkey);
+#endif
+
+ CHECK_AND_ASSERT_THROW_MES(create_rsa_ssl_certificate(pkey, cert), "Failed to create certificate");
CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_certificate(ctx, cert), "Failed to use generated certificate");
- // don't free the cert, the CTX owns it now
- CHECK_AND_ASSERT_THROW_MES(SSL_CTX_use_PrivateKey(ctx, pkey), "Failed to use generated private key");
+ if (!SSL_CTX_use_PrivateKey(ctx, pkey))
+ MERROR("Failed to use generated RSA private key for RSA");
+ else
+ ok = true;
+ X509_free(cert);
EVP_PKEY_free(pkey);
+
+ CHECK_AND_ASSERT_THROW_MES(ok, "Failed to use any generated certificate");
}
else
auth.use_ssl_certificate(ssl_context);
@@ -321,7 +442,7 @@ bool ssl_options_t::has_fingerprint(boost::asio::ssl::verify_context &ctx) const
unsigned int size{ 0 };
// create the digest from the certificate
- if (!X509_digest(cert, EVP_sha1(), digest.data(), &size)) {
+ if (!X509_digest(cert, EVP_sha256(), digest.data(), &size)) {
MERROR("Failed to create certificate fingerprint");
return false;
}
diff --git a/contrib/epee/src/net_utils_base.cpp b/contrib/epee/src/net_utils_base.cpp
index 9b781027e..b7f07a23b 100644
--- a/contrib/epee/src/net_utils_base.cpp
+++ b/contrib/epee/src/net_utils_base.cpp
@@ -22,6 +22,24 @@ namespace epee { namespace net_utils
bool ipv4_network_address::is_local() const { return net_utils::is_ip_local(ip()); }
+ bool ipv4_network_subnet::equal(const ipv4_network_subnet& other) const noexcept
+ { return is_same_host(other) && m_mask == other.m_mask; }
+
+ bool ipv4_network_subnet::less(const ipv4_network_subnet& other) const noexcept
+ { return subnet() < other.subnet() ? true : (other.subnet() < subnet() ? false : (m_mask < other.m_mask)); }
+
+ std::string ipv4_network_subnet::str() const
+ { return string_tools::get_ip_string_from_int32(subnet()) + "/" + std::to_string(m_mask); }
+
+ std::string ipv4_network_subnet::host_str() const { return string_tools::get_ip_string_from_int32(subnet()) + "/" + std::to_string(m_mask); }
+ bool ipv4_network_subnet::is_loopback() const { return net_utils::is_ip_loopback(subnet()); }
+ bool ipv4_network_subnet::is_local() const { return net_utils::is_ip_local(subnet()); }
+ bool ipv4_network_subnet::matches(const ipv4_network_address &address) const
+ {
+ return (address.ip() & ~(0xffffffffull << m_mask)) == subnet();
+ }
+
+
bool network_address::equal(const network_address& other) const
{
// clang typeid workaround
diff --git a/contrib/epee/src/wipeable_string.cpp b/contrib/epee/src/wipeable_string.cpp
index 3a6ee5dac..4209b71bf 100644
--- a/contrib/epee/src/wipeable_string.cpp
+++ b/contrib/epee/src/wipeable_string.cpp
@@ -62,13 +62,15 @@ wipeable_string::wipeable_string(wipeable_string &&other)
wipeable_string::wipeable_string(const std::string &other)
{
grow(other.size());
- memcpy(buffer.data(), other.c_str(), size());
+ if (size() > 0)
+ memcpy(buffer.data(), other.c_str(), size());
}
wipeable_string::wipeable_string(std::string &&other)
{
grow(other.size());
- memcpy(buffer.data(), other.c_str(), size());
+ if (size() > 0)
+ memcpy(buffer.data(), other.c_str(), size());
if (!other.empty())
{
memwipe(&other[0], other.size()); // we're kinda left with this again aren't we
@@ -79,7 +81,8 @@ wipeable_string::wipeable_string(std::string &&other)
wipeable_string::wipeable_string(const char *s)
{
grow(strlen(s));
- memcpy(buffer.data(), s, size());
+ if (size() > 0)
+ memcpy(buffer.data(), s, size());
}
wipeable_string::wipeable_string(const char *s, size_t len)
@@ -112,14 +115,18 @@ void wipeable_string::grow(size_t sz, size_t reserved)
}
size_t old_sz = buffer.size();
std::unique_ptr<char[]> tmp{new char[old_sz]};
- memcpy(tmp.get(), buffer.data(), old_sz * sizeof(char));
if (old_sz > 0)
+ {
+ memcpy(tmp.get(), buffer.data(), old_sz * sizeof(char));
memwipe(buffer.data(), old_sz * sizeof(char));
+ }
buffer.reserve(reserved);
buffer.resize(sz);
- memcpy(buffer.data(), tmp.get(), old_sz * sizeof(char));
if (old_sz > 0)
+ {
+ memcpy(buffer.data(), tmp.get(), old_sz * sizeof(char));
memwipe(tmp.get(), old_sz * sizeof(char));
+ }
}
void wipeable_string::push_back(char c)