Skip to content

Commit

Permalink
Merge pull request #12 from pkthapa/sign-verify-with-eddsa
Browse files Browse the repository at this point in the history
Sign/verify implementation using OpenSSL library.
  • Loading branch information
pkthapa authored Aug 23, 2022
2 parents 5f8a3d4 + 46e96a6 commit 60f690d
Show file tree
Hide file tree
Showing 139 changed files with 3,644 additions and 1,886 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
CONCORD_BFT_DOCKER_REPO?=concordbft/
CONCORD_BFT_DOCKER_IMAGE?=concord-bft
CONCORD_BFT_DOCKER_IMAGE_VERSION?=0.42
CONCORD_BFT_DOCKER_IMAGE_VERSION?=0.45
CONCORD_BFT_DOCKER_CONTAINER?=concord-bft

CONCORD_BFT_DOCKERFILE?=Dockerfile
Expand Down
9 changes: 4 additions & 5 deletions bftengine/include/bcstatetransfer/SimpleBCStateTransfer.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,6 @@
#include "kvstream.h"
#include "digest.hpp"

using concord::util::digest::Digest;
using concord::util::digest::BlockDigest;

namespace concord {
namespace storage {
class IDBClient;
Expand All @@ -48,7 +45,7 @@ namespace bcst {
// blocks.
// Blocks are numbered. The first block should be block number 1.

// represnts a digest
// represents a digest
#pragma pack(push, 1)
struct StateTransferDigest {
char content[DIGEST_SIZE];
Expand All @@ -61,7 +58,9 @@ void computeBlockDigest(const uint64_t blockId,
const uint32_t blockSize,
StateTransferDigest *outDigest);

BlockDigest computeBlockDigest(const uint64_t blockId, const char *block, const uint32_t blockSize);
concord::util::digest::BlockDigest computeBlockDigest(const uint64_t blockId,
const char *block,
const uint32_t blockSize);

// This interface should be implemented by the application/storage layer.
// It is used by the state transfer module.
Expand Down
4 changes: 2 additions & 2 deletions bftengine/include/bftengine/IKeyExchanger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
// file.

#pragma once
#include "crypto_utils.hpp"
#include "crypto.hpp"
#include <string>
#include <cstdint>

Expand All @@ -31,5 +31,5 @@ class IMultiSigKeyGenerator {
class IClientPublicKeyStore {
public:
virtual ~IClientPublicKeyStore() = default;
virtual void setClientPublicKey(uint16_t clientId, const std::string& key, concord::util::crypto::KeyFormat) = 0;
virtual void setClientPublicKey(uint16_t clientId, const std::string& key, concord::crypto::KeyFormat) = 0;
};
6 changes: 3 additions & 3 deletions bftengine/include/bftengine/KeyExchangeManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
#include "Metrics.hpp"
#include "secrets_manager_impl.h"
#include "SysConsts.hpp"
#include "crypto_utils.hpp"
#include "crypto.hpp"
#include <future>
namespace bftEngine::impl {

Expand Down Expand Up @@ -64,10 +64,10 @@ class KeyExchangeManager {
void sendInitialClientsKeys(const std::string&);
void onPublishClientsKeys(const std::string& keys, std::optional<std::string> bootstrap_keys);
// called on a new client key
void onClientPublicKeyExchange(const std::string& key, concord::util::crypto::KeyFormat, NodeIdType clientId);
void onClientPublicKeyExchange(const std::string& key, concord::crypto::KeyFormat, NodeIdType clientId);
// called when client keys are loaded
void loadClientPublicKey(const std::string& key,
concord::util::crypto::KeyFormat,
concord::crypto::KeyFormat,
NodeIdType clientId,
bool saveToReservedPages);
///////// end - Clients public keys interface///////////////
Expand Down
25 changes: 22 additions & 3 deletions bftengine/include/bftengine/ReplicaConfig.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@
#include <chrono>
#include "string.hpp"
#include "kvstream.h"

#include "Serializable.h"
#include "crypto/factory.hpp"

namespace bftEngine {

Expand Down Expand Up @@ -281,6 +280,16 @@ class ReplicaConfig : public concord::serialize::SerializableFactory<ReplicaConf
"the concord-ctl script");
CONFIG_PARAM(kvBlockchainVersion, std::uint32_t, 1u, "Default version of KV blockchain for this replica");

CONFIG_PARAM(replicaMsgSigningAlgo,
concord::crypto::SIGN_VERIFY_ALGO,
concord::crypto::SIGN_VERIFY_ALGO::EDDSA,
"A flag to specify the replica message signing algorithm. It is defaulted to use EDDSA algo.");

CONFIG_PARAM(operatorMsgSigningAlgo,
concord::crypto::SIGN_VERIFY_ALGO,
concord::crypto::SIGN_VERIFY_ALGO::EDDSA,
"A flag to specify the operator message signing algorithm. It is defaulted to use EDDSA algo.");

// Parameter to enable/disable waiting for transaction data to be persisted.
// Not predefined configuration parameters
// Example of usage:
Expand Down Expand Up @@ -406,6 +415,8 @@ class ReplicaConfig : public concord::serialize::SerializableFactory<ReplicaConf
serialize(outStream, diagnosticsServerPort);
serialize(outStream, useUnifiedCertificates);
serialize(outStream, kvBlockchainVersion);
serialize(outStream, operatorMsgSigningAlgo);
serialize(outStream, replicaMsgSigningAlgo);
}
void deserializeDataMembers(std::istream& inStream) {
deserialize(inStream, isReadOnly);
Expand Down Expand Up @@ -506,6 +517,8 @@ class ReplicaConfig : public concord::serialize::SerializableFactory<ReplicaConf
deserialize(inStream, diagnosticsServerPort);
deserialize(inStream, useUnifiedCertificates);
deserialize(inStream, kvBlockchainVersion);
deserialize(inStream, operatorMsgSigningAlgo);
deserialize(inStream, replicaMsgSigningAlgo);
}

private:
Expand Down Expand Up @@ -591,6 +604,10 @@ inline std::ostream& operator<<(std::ostream& os, const ReplicaConfig& rc) {
rc.adaptivePruningIntervalPeriod,
rc.dbSnapshotIntervalSeconds.count());
os << ",";
const auto replicaMsgSignAlgo =
(concord::crypto::SIGN_VERIFY_ALGO::RSA == rc.replicaMsgSigningAlgo) ? "rsa" : "eddsa";
const auto operatorMsgSignAlgo =
(concord::crypto::SIGN_VERIFY_ALGO::ECDSA == rc.operatorMsgSigningAlgo) ? "ecdsa" : "eddsa";
os << KVLOG(rc.dbCheckpointMonitorIntervalSeconds.count(),
rc.dbCheckpointDiskSpaceThreshold,
rc.enableMultiplexChannel,
Expand All @@ -599,7 +616,9 @@ inline std::ostream& operator<<(std::ostream& os, const ReplicaConfig& rc) {
rc.enablePreProcessorMemoryPool,
rc.diagnosticsServerPort,
rc.useUnifiedCertificates,
rc.kvBlockchainVersion);
rc.kvBlockchainVersion,
replicaMsgSignAlgo,
operatorMsgSignAlgo);
os << ", ";
for (auto& [param, value] : rc.config_params_) os << param << ": " << value << "\n";
return os;
Expand Down
4 changes: 2 additions & 2 deletions bftengine/src/bcstatetransfer/AsyncStateTransferCRE.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ class Communication : public ICommunication {
uint16_t repId_;
};

class InternalSigner : public concord::util::crypto::ISigner {
class InternalSigner : public concord::crypto::ISigner {
public:
std::string sign(const std::string& data) override {
std::string out;
out.resize(bftEngine::impl::SigManager::instance()->getMySigLength());
bftEngine::impl::SigManager::instance()->sign(data.data(), data.size(), out.data(), signatureLength());
bftEngine::impl::SigManager::instance()->sign(data.data(), data.size(), out.data());
return out;
}
uint32_t signatureLength() const override { return bftEngine::impl::SigManager::instance()->getMySigLength(); }
Expand Down
2 changes: 1 addition & 1 deletion bftengine/src/bcstatetransfer/BCStateTran.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
#include "assertUtils.hpp"
#include "hex_tools.h"
#include "BCStateTran.hpp"
#include "digest.hpp"
#include "InMemoryDataStore.hpp"
#include "json_output.hpp"
#include "ReservedPagesClient.hpp"
Expand Down Expand Up @@ -52,6 +51,7 @@ using concord::util::digest::DigestGenerator;

namespace bftEngine {
namespace bcst {
using concord::util::digest::BlockDigest;

void computeBlockDigest(const uint64_t blockId,
const char *block,
Expand Down
4 changes: 3 additions & 1 deletion bftengine/src/bcstatetransfer/BCStateTran.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -518,7 +518,9 @@ class BCStateTran : public IStateTransfer {
const uint32_t blockSize,
Digest* outDigest);

static BlockDigest computeDigestOfBlock(const uint64_t blockNum, const char* block, const uint32_t blockSize);
static concord::util::digest::BlockDigest computeDigestOfBlock(const uint64_t blockNum,
const char* block,
const uint32_t blockSize);

protected:
// A wrapper function to get a block from the IAppState and compute its digest.
Expand Down
11 changes: 1 addition & 10 deletions bftengine/src/bftengine/BFTEngine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,22 +25,13 @@
#include "ReservedPagesClient.hpp"
#include "bftengine/EpochManager.hpp"
#include "bcstatetransfer/AsyncStateTransferCRE.hpp"
#include "util/filesystem.hpp"
#include <condition_variable>
#include <memory>
#include <mutex>
#include <cstdio>
#include <utility>

#if __has_include(<filesystem>)
#include <filesystem>
namespace fs = std::filesystem;
#elif __has_include(<experimental/filesystem>)
#include <experimental/filesystem>
namespace fs = std::experimental::filesystem;
#else
#error "Missing filesystem support"
#endif

#include <ccron/ticks_generator.hpp>

bftEngine::IReservedPages *bftEngine::ReservedPagesClientBase::res_pages_ = nullptr;
Expand Down
4 changes: 1 addition & 3 deletions bftengine/src/bftengine/ClientsManager.cpp
100755 → 100644
Original file line number Diff line number Diff line change
Expand Up @@ -417,9 +417,7 @@ std::unique_ptr<ClientReplyMsg> ClientsManager::allocateReplyFromSavedOne(NodeId
return r;
}

void ClientsManager::setClientPublicKey(NodeIdType clientId,
const std::string& key,
concord::util::crypto::KeyFormat fmt) {
void ClientsManager::setClientPublicKey(NodeIdType clientId, const std::string& key, concord::crypto::KeyFormat fmt) {
LOG_INFO(CL_MNGR, "key: " << key << " fmt: " << (uint16_t)fmt << " client: " << clientId);
ClientInfo& info = clientsInfo_[clientId];
info.pubKey = std::make_pair(key, fmt);
Expand Down
4 changes: 2 additions & 2 deletions bftengine/src/bftengine/ClientsManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ class ClientsManager : public ResPagesClient<ClientsManager>, public IPendingReq
// cases:
// - The given NodeIdType parameter is not the ID of a valid client.
// - The given public key does not fit in a single reserved page under ClientsManager's implementation.
void setClientPublicKey(NodeIdType, const std::string& key, concord::util::crypto::KeyFormat) override;
void setClientPublicKey(NodeIdType, const std::string& key, concord::crypto::KeyFormat) override;

// General
static uint32_t reservedPagesPerClient(const uint32_t& sizeOfReservedPage, const uint32_t& maxReplySize);
Expand Down Expand Up @@ -258,7 +258,7 @@ class ClientsManager : public ResPagesClient<ClientsManager>, public IPendingReq
struct ClientInfo {
std::shared_ptr<RequestsInfo> requestsInfo;
std::shared_ptr<RepliesInfo> repliesInfo;
std::pair<std::string, concord::util::crypto::KeyFormat> pubKey;
std::pair<std::string, concord::crypto::KeyFormat> pubKey;
};

std::set<NodeIdType> proxyClients_;
Expand Down
3 changes: 1 addition & 2 deletions bftengine/src/bftengine/DbCheckpointManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -334,8 +334,7 @@ void DbCheckpointManager::sendInternalCreateDbCheckpointMsg(const SeqNum& seqNum
std::vector<uint8_t> data_vec;
concord::messages::db_checkpoint_msg::serialize(data_vec, req);
std::string sig(SigManager::instance()->getMySigLength(), '\0');
uint16_t sig_length{0};
SigManager::instance()->sign(reinterpret_cast<char*>(data_vec.data()), data_vec.size(), sig.data(), sig_length);
SigManager::instance()->sign(reinterpret_cast<char*>(data_vec.data()), data_vec.size(), sig.data());
req.signature = std::vector<uint8_t>(sig.begin(), sig.end());
data_vec.clear();
concord::messages::db_checkpoint_msg::serialize(data_vec, req);
Expand Down
40 changes: 25 additions & 15 deletions bftengine/src/bftengine/KeyExchangeManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,19 @@
#include "bftengine/EpochManager.hpp"
#include "concord.cmf.hpp"
#include "communication/StateControl.hpp"
#include "crypto/factory.hpp"
#include "crypto.hpp"
#include "openssl/utils.hpp"

namespace bftEngine::impl {

using concord::crypto::KeyFormat;
using concord::crypto::SIGN_VERIFY_ALGO;
using concord::crypto::EdDSAHexToPem;
using concord::crypto::RsaHexToPem;
using concord::crypto::generateECDSAKeyPair;
using concord::crypto::generateSelfSignedCert;

KeyExchangeManager::KeyExchangeManager(InitData* id)
: repID_{ReplicaConfig::instance().getreplicaId()},
clusterSize_{ReplicaConfig::instance().getnumReplicas()},
Expand Down Expand Up @@ -146,18 +156,22 @@ void KeyExchangeManager::loadClientPublicKeys() {
}

void KeyExchangeManager::exchangeTlsKeys(const std::string& type, const SeqNum& bft_sn) {
auto keys = concord::util::crypto::Crypto::instance().generateECDSAKeyPair(
concord::util::crypto::KeyFormat::PemFormat, concord::util::crypto::CurveType::secp384r1);
auto keys = generateECDSAKeyPair(concord::crypto::KeyFormat::PemFormat, concord::crypto::CurveType::secp384r1);
bool use_unified_certs = bftEngine::ReplicaConfig::instance().useUnifiedCertificates;
const std::string base_path =
bftEngine::ReplicaConfig::instance().certificatesRootPath + "/" + std::to_string(repID_);
std::string root_path = (use_unified_certs) ? base_path : base_path + "/" + type;

std::string cert_path = (use_unified_certs) ? root_path + "/node.cert" : root_path + "/" + type + ".cert";
std::string prev_key_pem = concord::util::crypto::Crypto::instance()
.RsaHexToPem(std::make_pair(SigManager::instance()->getSelfPrivKey(), ""))
.first;
auto cert = concord::util::crypto::CertificateUtils::generateSelfSignedCert(cert_path, keys.second, prev_key_pem);

std::string prev_key_pem;
if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::RSA) {
prev_key_pem = RsaHexToPem(std::make_pair(SigManager::instance()->getSelfPrivKey(), "")).first;
} else if (ReplicaConfig::instance().replicaMsgSigningAlgo == SIGN_VERIFY_ALGO::EDDSA) {
prev_key_pem = EdDSAHexToPem(std::make_pair(SigManager::instance()->getSelfPrivKey(), "")).first;
}

auto cert =
generateSelfSignedCert(cert_path, keys.second, prev_key_pem, ReplicaConfig::instance().replicaMsgSigningAlgo);
// Now that we have generated new key pair and certificate, lets do the actual exchange on this replica
std::string pk_path = root_path + "/pk.pem";
std::fstream nec_f(pk_path);
Expand Down Expand Up @@ -186,8 +200,7 @@ void KeyExchangeManager::exchangeTlsKeys(const std::string& type, const SeqNum&
std::vector<uint8_t> data_vec;
concord::messages::serialize(data_vec, req);
std::string sig(SigManager::instance()->getMySigLength(), '\0');
uint16_t sig_length{0};
SigManager::instance()->sign(reinterpret_cast<char*>(data_vec.data()), data_vec.size(), sig.data(), sig_length);
SigManager::instance()->sign(reinterpret_cast<char*>(data_vec.data()), data_vec.size(), sig.data());
req.signature = std::vector<uint8_t>(sig.begin(), sig.end());
data_vec.clear();
concord::messages::serialize(data_vec, req);
Expand All @@ -212,8 +225,7 @@ void KeyExchangeManager::sendMainPublicKey() {
std::vector<uint8_t> data_vec;
concord::messages::serialize(data_vec, req);
std::string sig(SigManager::instance()->getMySigLength(), '\0');
uint16_t sig_length{0};
SigManager::instance()->sign(reinterpret_cast<char*>(data_vec.data()), data_vec.size(), sig.data(), sig_length);
SigManager::instance()->sign(reinterpret_cast<char*>(data_vec.data()), data_vec.size(), sig.data());
req.signature = std::vector<uint8_t>(sig.begin(), sig.end());
data_vec.clear();
concord::messages::serialize(data_vec, req);
Expand Down Expand Up @@ -294,9 +306,7 @@ void KeyExchangeManager::onPublishClientsKeys(const std::string& keys, std::opti
if (save) saveClientsPublicKeys(keys);
}

void KeyExchangeManager::onClientPublicKeyExchange(const std::string& key,
concord::util::crypto::KeyFormat fmt,
NodeIdType clientId) {
void KeyExchangeManager::onClientPublicKeyExchange(const std::string& key, KeyFormat fmt, NodeIdType clientId) {
LOG_INFO(KEY_EX_LOG, "key: " << key << " fmt: " << (uint16_t)fmt << " client: " << clientId);
// persist a new key
clientPublicKeyStore_->setClientPublicKey(clientId, key, fmt);
Expand All @@ -305,7 +315,7 @@ void KeyExchangeManager::onClientPublicKeyExchange(const std::string& key,
}

void KeyExchangeManager::loadClientPublicKey(const std::string& key,
concord::util::crypto::KeyFormat fmt,
KeyFormat fmt,
NodeIdType clientId,
bool saveToReservedPages) {
LOG_INFO(KEY_EX_LOG, "key: " << key << " fmt: " << (uint16_t)fmt << " client: " << clientId);
Expand Down
4 changes: 2 additions & 2 deletions bftengine/src/bftengine/ReadOnlyReplica.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,9 +62,9 @@ ReadOnlyReplica::ReadOnlyReplica(const ReplicaConfig &config,
SigManager::init(config_.replicaId,
config_.replicaPrivateKey,
config_.publicKeysOfReplicas,
concord::util::crypto::KeyFormat::HexaDecimalStrippedFormat,
concord::crypto::KeyFormat::HexaDecimalStrippedFormat,
ReplicaConfig::instance().getPublicKeysOfClients(),
concord::util::crypto::KeyFormat::PemFormat,
concord::crypto::KeyFormat::PemFormat,
*repsInfo);

// Register status handler for Read-Only replica
Expand Down
Loading

0 comments on commit 60f690d

Please sign in to comment.