Skip to content
This repository has been archived by the owner on Mar 3, 2020. It is now read-only.

Commit

Permalink
Merge branch 'devel' into task/amastracci/issue-102
Browse files Browse the repository at this point in the history
  • Loading branch information
amastracci committed Nov 13, 2018
2 parents b470eb0 + 86f14e3 commit e2facca
Show file tree
Hide file tree
Showing 51 changed files with 587 additions and 305 deletions.
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -8,5 +8,6 @@ scripts/bluzelle_pb2.py
scripts/database_pb2.py
scripts/audit_pb2.py
scripts/pbft_pb2.py
scripts/status_pb2.py
*.pyc
*.pem
1 change: 0 additions & 1 deletion audit/audit.hpp
Expand Up @@ -16,7 +16,6 @@

#include <audit/audit_base.hpp>
#include <node/node_base.hpp>
#include <proto/bluzelle.pb.h>
#include <include/boost_asio_beast.hpp>
#include <boost/asio/ip/udp.hpp>
#include <mutex>
Expand Down
2 changes: 1 addition & 1 deletion audit/audit_base.hpp
Expand Up @@ -21,7 +21,7 @@
#include <include/bluzelle.hpp>
#include <node/node_base.hpp>
#include <node/session_base.hpp>
#include <proto/bluzelle.pb.h>
#include <proto/audit.pb.h>

namespace bzn
{
Expand Down
46 changes: 42 additions & 4 deletions crypto/crypto.cpp
Expand Up @@ -35,8 +35,45 @@ crypto::crypto(std::shared_ptr<bzn::options_base> options)
}
}

const std::string&
crypto::extract_payload(const bzn_envelope& msg)
{
switch (msg.payload_case())
{
case bzn_envelope::kPbftRequest :
{
return msg.pbft_request();
}
case bzn_envelope::kDatabaseResponse :
{
return msg.database_response();
}
case bzn_envelope::kJson :
{
return msg.json();
}
case bzn_envelope::kAudit :
{
return msg.audit();
}
case bzn_envelope::kPbft :
{
return msg.pbft();
}
case bzn_envelope::kPbftMembership :
{
return msg.pbft_membership();
}
default :
{
throw std::runtime_error(
"Crypto does not know how to handle a message with type " + std::to_string(msg.payload_case()));
}
}
}

bool
crypto::verify(const wrapped_bzn_msg& msg)
crypto::verify(const bzn_envelope& msg)
{
BIO_ptr_t bio(BIO_new(BIO_s_mem()), &BIO_free);
EC_KEY_ptr_t pubkey(nullptr, &EC_KEY_free);
Expand All @@ -54,6 +91,7 @@ crypto::verify(const wrapped_bzn_msg& msg)
std::string signature = msg.signature();
char* sig_ptr = signature.data();


bool result =
// Reconstruct the PEM file in memory (this is awkward, but it avoids dealing with EC specifics)
(0 < BIO_write(bio.get(), PEM_PREFIX.c_str(), PEM_PREFIX.length()))
Expand All @@ -67,7 +105,7 @@ crypto::verify(const wrapped_bzn_msg& msg)

// Perform the signature validation
&& (1 == EVP_DigestVerifyInit(context.get(), NULL, EVP_sha512(), NULL, key.get()))
&& (1 == EVP_DigestVerifyUpdate(context.get(), msg.payload().c_str(), msg.payload().length()))
&& (1 == EVP_DigestVerifyUpdate(context.get(), this->extract_payload(msg).c_str(), this->extract_payload(msg).length()))
&& (1 == EVP_DigestVerifyFinal(context.get(), reinterpret_cast<unsigned char*>(sig_ptr), msg.signature().length()));

/* Any errors here can be attributed to a bad (potentially malicious) incoming message, and we we should not
Expand All @@ -79,7 +117,7 @@ crypto::verify(const wrapped_bzn_msg& msg)
}

bool
crypto::sign(wrapped_bzn_msg& msg)
crypto::sign(bzn_envelope& msg)
{
if (msg.sender().empty())
{
Expand All @@ -98,7 +136,7 @@ crypto::sign(wrapped_bzn_msg& msg)
bool result =
(bool) (context)
&& (1 == EVP_DigestSignInit(context.get(), NULL, EVP_sha512(), NULL, this->private_key_EVP.get()))
&& (1 == EVP_DigestSignUpdate(context.get(), msg.payload().c_str(), msg.payload().size()))
&& (1 == EVP_DigestSignUpdate(context.get(), this->extract_payload(msg).c_str(), this->extract_payload(msg).length()))
&& (1 == EVP_DigestSignFinal(context.get(), NULL, &signature_length));

auto deleter = [](unsigned char* ptr){OPENSSL_free(ptr);};
Expand Down
6 changes: 4 additions & 2 deletions crypto/crypto.hpp
Expand Up @@ -29,9 +29,9 @@ namespace bzn

crypto(std::shared_ptr<bzn::options_base> options);

bool sign(wrapped_bzn_msg& msg) override;
bool sign(bzn_envelope& msg) override;

bool verify(const wrapped_bzn_msg& msg) override;
bool verify(const bzn_envelope& msg) override;

std::string hash(const std::string& msg) override;

Expand All @@ -46,6 +46,8 @@ namespace bzn

void log_openssl_errors();

const std::string& extract_payload(const bzn_envelope& msg);

std::shared_ptr<bzn::options_base> options;

EVP_PKEY_ptr_t private_key_EVP = EVP_PKEY_ptr_t(nullptr, &EVP_PKEY_free);
Expand Down
4 changes: 2 additions & 2 deletions crypto/crypto_base.hpp
Expand Up @@ -26,14 +26,14 @@ namespace bzn
* @msg message to sign
* @return if signature was successful
*/
virtual bool sign(wrapped_bzn_msg& msg) = 0;
virtual bool sign(bzn_envelope& msg) = 0;

/*
* verify that the signature on a message is correct and matches its sender
* @msg message to verify
* @return signature is present, valid and matches sender
*/
virtual bool verify(const wrapped_bzn_msg& msg) = 0;
virtual bool verify(const bzn_envelope& msg) = 0;

/*
* Compute the hash of some message
Expand Down
12 changes: 6 additions & 6 deletions crypto/test/crypto_test.cpp
Expand Up @@ -44,11 +44,11 @@ class crypto_test : public Test
"8Mcwr7lq+Hi7/xx7A37wZBHVtCRpaXbJNqRhIErf6FnOZI3m71sQoA==\n"
"-----END PUBLIC KEY-----\n";

wrapped_bzn_msg msg;
bzn_envelope msg;

crypto_test()
{
this->msg.set_payload("pretend this is a serialized protobuf message");
this->msg.set_pbft("pretend this is a serialized protobuf message");

std::ofstream ofile(private_key_file.c_str());
ofile << test_private_key_pem;
Expand Down Expand Up @@ -81,16 +81,16 @@ TEST_F(crypto_test, messages_use_my_public_key)

TEST_F(crypto_test, messages_signed_and_verified)
{
wrapped_bzn_msg msg2 = msg;
wrapped_bzn_msg msg3 = msg;
bzn_envelope msg2 = msg;
bzn_envelope msg3 = msg;

EXPECT_TRUE(crypto->sign(msg));
EXPECT_TRUE(crypto->verify(msg));
}

TEST_F(crypto_test, bad_signature_caught)
{
wrapped_bzn_msg msg2 = msg;
bzn_envelope msg2 = msg;

EXPECT_TRUE(crypto->sign(msg));

Expand All @@ -100,7 +100,7 @@ TEST_F(crypto_test, bad_signature_caught)

TEST_F(crypto_test, bad_sender_caught)
{
wrapped_bzn_msg msg3 = msg;
bzn_envelope msg3 = msg;

EXPECT_TRUE(crypto->sign(msg));

Expand Down
2 changes: 2 additions & 0 deletions include/bluzelle.hpp
Expand Up @@ -33,6 +33,8 @@ namespace bzn

using session_id = uint64_t;

using hash_t = std::string;

} // bzn


Expand Down
2 changes: 1 addition & 1 deletion mocks/mock_node_base.hpp
Expand Up @@ -27,7 +27,7 @@ class Mocknode_base : public node_base {
MOCK_METHOD2(register_for_message,
bool(const std::string& msg_type, bzn::message_handler message_handler));
MOCK_METHOD2(register_for_message,
bool(const bzn_msg_type msg_type, bzn::protobuf_handler message_handler));
bool(const bzn_envelope::PayloadCase msg_type, bzn::protobuf_handler message_handler));
MOCK_METHOD0(start,
void());
MOCK_METHOD2(send_message,
Expand Down
4 changes: 2 additions & 2 deletions mocks/mock_pbft_failure_detector.hpp
Expand Up @@ -23,9 +23,9 @@ namespace bzn
class Mockpbft_failure_detector_base : public pbft_failure_detector_base
{
public:
MOCK_METHOD1(request_seen, void(const pbft_request& req));
MOCK_METHOD1(request_seen, void(const bzn::hash_t& req));

MOCK_METHOD1(request_executed, void(const pbft_request& req));
MOCK_METHOD1(request_executed, void(const bzn::hash_t& req));

MOCK_METHOD1(register_failure_handler, void(std::function<void()> handler));
};
Expand Down
6 changes: 3 additions & 3 deletions mocks/mock_pbft_service_base.hpp
Expand Up @@ -22,16 +22,16 @@ namespace bzn {

class mock_pbft_service_base : public pbft_service_base {
public:
MOCK_METHOD2(apply_operation,
void(const pbft_request& request, uint64_t sequence_number));
MOCK_METHOD1(apply_operation,
void(std::shared_ptr<bzn::pbft_operation>));
MOCK_CONST_METHOD2(query,
void(const pbft_request& request, uint64_t sequence_number));
MOCK_CONST_METHOD1(service_state_hash,
bzn::hash_t(uint64_t sequence_number));
MOCK_METHOD1(consolidate_log,
void(uint64_t sequence_number));
MOCK_METHOD1(register_execute_handler,
void(std::function<void(const pbft_request&, uint64_t)> handler));
void(bzn::execute_handler_t handler));
MOCK_METHOD1(apply_operation,
void(const std::shared_ptr<pbft_operation>&));
};
Expand Down
12 changes: 6 additions & 6 deletions node/node.cpp
Expand Up @@ -69,7 +69,7 @@ node::register_for_message(const std::string& msg_type, bzn::message_handler msg


bool
node::register_for_message(const bzn_msg_type type, bzn::protobuf_handler msg_handler)
node::register_for_message(const bzn_envelope::PayloadCase type, bzn::protobuf_handler msg_handler)
{
std::lock_guard<std::mutex> lock(this->message_map_mutex);

Expand All @@ -81,7 +81,7 @@ node::register_for_message(const bzn_msg_type type, bzn::protobuf_handler msg_ha

if (this->protobuf_map.find(type) != this->protobuf_map.end())
{
LOG(debug) << bzn_msg_type_Name(type) << " message type already registered";
LOG(debug) << type << " message type already registered";

return false;
}
Expand Down Expand Up @@ -143,7 +143,7 @@ node::priv_msg_handler(const Json::Value& msg, std::shared_ptr<bzn::session_base
}

void
node::priv_protobuf_handler(const wrapped_bzn_msg& msg, std::shared_ptr<bzn::session_base> session)
node::priv_protobuf_handler(const bzn_envelope& msg, std::shared_ptr<bzn::session_base> session)
{
std::lock_guard<std::mutex> lock(this->message_map_mutex);

Expand All @@ -156,13 +156,13 @@ node::priv_protobuf_handler(const wrapped_bzn_msg& msg, std::shared_ptr<bzn::ses
return;
}

if (auto it = this->protobuf_map.find(msg.type()); it != this->protobuf_map.end())
if (auto it = this->protobuf_map.find(msg.payload_case()); it != this->protobuf_map.end())
{
it->second(msg, std::move(session));
}
else
{
LOG(debug) << "no handler for message type " << bzn_msg_type_Name(msg.type());
LOG(debug) << "no handler for message type " << msg.payload_case();
}

}
Expand Down Expand Up @@ -224,7 +224,7 @@ node::send_message(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<bzn
}

void
node::send_message(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<wrapped_bzn_msg> msg)
node::send_message(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<bzn_envelope> msg)
{
if(msg->sender().empty())
{
Expand Down
8 changes: 4 additions & 4 deletions node/node.hpp
Expand Up @@ -36,13 +36,13 @@ namespace bzn

bool register_for_message(const std::string& msg_type, bzn::message_handler msg_handler) override;

bool register_for_message(const bzn_msg_type type, bzn::protobuf_handler msg_handler) override;
bool register_for_message(const bzn_envelope::PayloadCase type, bzn::protobuf_handler msg_handler) override;

void start() override;

void send_message(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<bzn::json_message> msg) override;

void send_message(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<wrapped_bzn_msg> msg);
void send_message(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<bzn_envelope> msg);

void send_message_str(const boost::asio::ip::tcp::endpoint& ep, std::shared_ptr<bzn::encoded_message> msg) override;

Expand All @@ -53,7 +53,7 @@ namespace bzn
void do_accept();

void priv_msg_handler(const bzn::json_message& msg, std::shared_ptr<bzn::session_base> session);
void priv_protobuf_handler(const wrapped_bzn_msg& msg, std::shared_ptr<bzn::session_base> session);
void priv_protobuf_handler(const bzn_envelope& msg, std::shared_ptr<bzn::session_base> session);

std::unique_ptr<bzn::asio::tcp_acceptor_base> tcp_acceptor;
std::shared_ptr<bzn::asio::io_context_base> io_context;
Expand All @@ -63,7 +63,7 @@ namespace bzn
const std::chrono::milliseconds ws_idle_timeout;

std::unordered_map<std::string, bzn::message_handler> message_map;
std::unordered_map<bzn_msg_type, bzn::protobuf_handler> protobuf_map;
std::unordered_map<bzn_envelope::PayloadCase, bzn::protobuf_handler> protobuf_map;
std::mutex message_map_mutex;

std::once_flag start_once;
Expand Down
2 changes: 1 addition & 1 deletion node/node_base.hpp
Expand Up @@ -41,7 +41,7 @@ namespace bzn
* @param msg_handler callback
* @return true if registration succeeded
*/
virtual bool register_for_message(const bzn_msg_type type, bzn::protobuf_handler msg_handler) = 0;
virtual bool register_for_message(const bzn_envelope::PayloadCase type, bzn::protobuf_handler msg_handler) = 0;

/**
* Start server's listener etc.
Expand Down
2 changes: 1 addition & 1 deletion node/session.cpp
Expand Up @@ -92,7 +92,7 @@ session::do_read()
Json::Value msg;
Json::Reader reader;

wrapped_bzn_msg proto_msg;
bzn_envelope proto_msg;

if (reader.parse(ss.str(), msg))
{
Expand Down
2 changes: 1 addition & 1 deletion node/session_base.hpp
Expand Up @@ -24,7 +24,7 @@ namespace bzn
class session_base;

using message_handler = std::function<void(const bzn::json_message& msg, std::shared_ptr<bzn::session_base> session)>;
using protobuf_handler = std::function<void(const wrapped_bzn_msg& msg, std::shared_ptr<bzn::session_base> session)>;
using protobuf_handler = std::function<void(const bzn_envelope& msg, std::shared_ptr<bzn::session_base> session)>;

class session_base
{
Expand Down
12 changes: 5 additions & 7 deletions node/test/node_test.cpp
Expand Up @@ -183,22 +183,20 @@ namespace bzn

// Add our test callback...
unsigned int callback_execute = 0u;
node->register_for_message(BZN_MSG_PBFT, [&](const auto& /*msg*/, auto)
node->register_for_message(bzn_envelope::kPbft, [&](const auto& /*msg*/, auto)
{
callback_execute++;
});

wrapped_bzn_msg bad_msg;
bad_msg.set_payload("some stuff");
bzn_envelope bad_msg;
bad_msg.set_pbft("some stuff");
bad_msg.set_sender("Elizabeth the Second, by the Grace of God of the United Kingdom, Canada and Her other Realms and Territories Queen, Head of the Commonwealth, Defender of the Faith");
bad_msg.set_signature("probably not a valid signature");
bad_msg.set_type(BZN_MSG_PBFT);

wrapped_bzn_msg anon_msg;
anon_msg.set_payload("some stuff");
bzn_envelope anon_msg;
anon_msg.set_pbft("some stuff");
anon_msg.set_sender("");
anon_msg.set_signature("");
anon_msg.set_type(BZN_MSG_PBFT);

node->priv_protobuf_handler(bad_msg, mock_session);
EXPECT_EQ(callback_execute, 0u);
Expand Down
2 changes: 1 addition & 1 deletion node/test/session_test.cpp
Expand Up @@ -179,7 +179,7 @@ namespace bzn

ASSERT_FALSE(proto_handler_called);

wrapped_bzn_msg proto_msg;
bzn_envelope proto_msg;
write_to_buffer(proto_msg.SerializeAsString());
read_handler(boost::system::error_code(), 0);

Expand Down

0 comments on commit e2facca

Please sign in to comment.