From 5d22f62e82cb161d1b888291eaf50a5b1dac4277 Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Wed, 30 Dec 2020 13:09:51 +0530 Subject: [PATCH 1/9] decrypting private key from keystore file --- relay/src/bsc_relay.cpp | 159 +++++++++++++++++++++++++++++++++++++++- 1 file changed, 158 insertions(+), 1 deletion(-) diff --git a/relay/src/bsc_relay.cpp b/relay/src/bsc_relay.cpp index 65bfe8c7..5064fb77 100644 --- a/relay/src/bsc_relay.cpp +++ b/relay/src/bsc_relay.cpp @@ -3,6 +3,10 @@ #include #include +#include +#include +#include +#include using namespace marlin::core; using namespace marlin::asyncio; @@ -14,13 +18,17 @@ struct CliOptions { std::string discovery_addrs; std::string heartbeat_addrs; std::string datadir; + std::string keystore_path; + std::string keystore_pass_path; std::optional pubsub_port; std::optional discovery_port; std::optional address; std::optional name; std::optional interface; }; -STRUCTOPT(CliOptions, discovery_addrs, heartbeat_addrs, datadir, pubsub_port, discovery_port, address, name, interface); +STRUCTOPT(CliOptions, discovery_addrs, heartbeat_addrs, datadir, keystore_path, keystore_pass_path, pubsub_port, discovery_port, address, name, interface); + +std::string get_key(std::string keystore_path, std::string keystore_pass_path); int main(int argc, char** argv) { try { @@ -29,6 +37,12 @@ int main(int argc, char** argv) { auto pubsub_port = options.pubsub_port.value_or(5000); auto discovery_port = options.discovery_port.value_or(5002); auto address = options.address.value_or("0x0000000000000000000000000000000000000000"); + + std::string key = get_key(options.keystore_path, options.keystore_pass_path); + if (key.empty()) { + SPDLOG_ERROR("keystore file error"); + return 1; + } if(address.size() != 42) { structopt::details::visitor visitor("bsc_relay", ""); CliOptions opt = CliOptions(); @@ -81,3 +95,146 @@ int main(int argc, char** argv) { return -1; } + +std::string string_to_hex(const std::string& input) +{ + std::string output; + CryptoPP::StringSource ss2( input, true, + new CryptoPP::HexEncoder( + new CryptoPP::StringSink( output ) + )); // HexEncoder + return output; +} + +std::string hex_to_string(const std::string& input) +{ + std::string output; + CryptoPP::StringSource ss2( input, true, + new CryptoPP::HexDecoder( + new CryptoPP::StringSink( output ) + )); // HexDecoder + return output; +} + +bool isvalid_cipherparams(const rapidjson::Value &cipherparams, const std::string &cipher) { + if(cipher == "aes-128-ctr") { + return cipherparams.HasMember("iv") && cipherparams["iv"].IsString(); + } + return false; +} + +bool isvalid_kdfparams(const rapidjson::Value &kdfparams, const std::string &kdf) { + if(kdf == "scrypt") { + return kdfparams.HasMember("dklen") && kdfparams["dklen"].IsUint64() + && kdfparams.HasMember("n") && kdfparams["n"].IsUint64() + && kdfparams.HasMember("p") && kdfparams["p"].IsUint64() + && kdfparams.HasMember("r") && kdfparams["r"].IsUint64() + && kdfparams.HasMember("salt") && kdfparams["salt"].IsString(); + } + return false; +} + +bool isvalid_keystore(rapidjson::Document &keystore) { + if (keystore.HasMember("crypto") && keystore["crypto"].IsObject() ) { + const rapidjson::Value &crypto = keystore["crypto"]; + const rapidjson::Value &cipherparams = crypto["cipherparams"]; + const rapidjson::Value &kdfparams = crypto["kdfparams"]; + return crypto.HasMember("cipher") && crypto["cipher"].IsString() + && crypto.HasMember("ciphertext") && crypto["ciphertext"].IsString() + && crypto.HasMember("kdf") && crypto["kdf"].IsString() + && crypto.HasMember("mac") && crypto["mac"].IsString() + && crypto.HasMember("cipherparams") && crypto["cipherparams"].IsObject() + && crypto.HasMember("kdfparams") && crypto["kdfparams"].IsObject() + && isvalid_cipherparams(cipherparams, crypto["cipher"].GetString()) + && isvalid_kdfparams(kdfparams, crypto["kdf"].GetString()); + } + return false; +} + +void derivekey_scrypt(CryptoPP::SecByteBlock &derived, const rapidjson::Value &kdfparams, const std::string &pass) { + + CryptoPP::Scrypt pbkdf; + derived = CryptoPP::SecByteBlock(kdfparams["dklen"].GetUint()); + std::string salt(hex_to_string(kdfparams["salt"].GetString())); + pbkdf.DeriveKey(derived, derived.size(), + CryptoPP::ConstBytePtr(pass), CryptoPP::BytePtrSize(pass), + CryptoPP::ConstBytePtr(salt), CryptoPP::BytePtrSize(salt), + CryptoPP::word64(kdfparams["n"].GetUint64()), + CryptoPP::word64(kdfparams["r"].GetUint64()), + CryptoPP::word64(kdfparams["p"].GetUint64())); +} + +std::string decrypt_aes128ctr(const rapidjson::Value &cipherparams, std::string &ciphertext, CryptoPP::SecByteBlock &derived) { + std::string iv = hex_to_string(cipherparams["iv"].GetString()); + + CryptoPP::CTR_Mode::Decryption d; + d.SetKeyWithIV(derived, 16, CryptoPP::ConstBytePtr(iv)); + + CryptoPP::SecByteBlock decrypted(ciphertext.size()); + d.ProcessData(decrypted, CryptoPP::ConstBytePtr(ciphertext), CryptoPP::BytePtrSize(ciphertext)); + return std::string((const char*)decrypted.data(), decrypted.size()); +} + +bool check_mac(const std::string &mac, CryptoPP::SecByteBlock &derived, std::string &ciphertext) { + CryptoPP::Keccak_256 hasher; + auto hashinput = CryptoPP::SecByteBlock((derived.data()+16), 16) + CryptoPP::SecByteBlock((const CryptoPP::byte*)ciphertext.data(), ciphertext.size()); + + CryptoPP::SecByteBlock hash(mac.size()); + return hasher.VerifyTruncatedDigest((const CryptoPP::byte*)mac.data(), mac.size(), hashinput, hashinput.size()); + //hasher.CalculateTruncatedDigest(receipthash, hash.size(), hashinput, hash_input.size()); +} + +std::string get_key(std::string keystore_path, std::string keystore_pass_path) { + using namespace CryptoPP; + std::string _pass; + rapidjson::Document _keystore; + + // read password file + if(boost::filesystem::exists(keystore_pass_path)) { + std::ifstream fin(keystore_pass_path); + std::getline(fin, _pass); + fin.close(); + } + if (_pass.empty()) { + SPDLOG_ERROR("Invalid password file"); + return ""; + } + + // read keystore file + if(boost::filesystem::exists(keystore_path)) { + std::string s; + boost::filesystem::load_string_file(keystore_path, s); + rapidjson::StringStream ss(s.c_str()); + _keystore.ParseStream(ss); + } + if (!isvalid_keystore(_keystore)){ + SPDLOG_ERROR("Invalid keystore file"); + return ""; + } + + const rapidjson::Value &crypto = _keystore["crypto"]; + std::string ciphertext = hex_to_string(crypto["ciphertext"].GetString()); + CryptoPP::SecByteBlock derived; + std::string decrypted; + + // get derived keycrypto + if (crypto["kdf"] == "scrypt") { + derivekey_scrypt(derived, crypto["kdfparams"], _pass); + } + if (derived.size() == 0) { + SPDLOG_ERROR("kdf error"); + return ""; + } + if (crypto["cipher"] == "aes-128-ctr") { + decrypted = decrypt_aes128ctr(crypto["cipherparams"], ciphertext, derived); + } + + //validate mac + if (!check_mac(hex_to_string(crypto["mac"].GetString()), derived, ciphertext)) { + SPDLOG_ERROR("Invalid mac"); + return ""; + } + SPDLOG_INFO("decrypted keystore"); + return decrypted; +} + From b570308ea01df41e7b884c8a1a1f9319b90dd211 Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Wed, 30 Dec 2020 13:35:11 +0530 Subject: [PATCH 2/9] removing unused --- relay/src/bsc_relay.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/relay/src/bsc_relay.cpp b/relay/src/bsc_relay.cpp index 5064fb77..97738c9e 100644 --- a/relay/src/bsc_relay.cpp +++ b/relay/src/bsc_relay.cpp @@ -181,11 +181,9 @@ bool check_mac(const std::string &mac, CryptoPP::SecByteBlock &derived, std::str CryptoPP::SecByteBlock hash(mac.size()); return hasher.VerifyTruncatedDigest((const CryptoPP::byte*)mac.data(), mac.size(), hashinput, hashinput.size()); - //hasher.CalculateTruncatedDigest(receipthash, hash.size(), hashinput, hash_input.size()); } std::string get_key(std::string keystore_path, std::string keystore_pass_path) { - using namespace CryptoPP; std::string _pass; rapidjson::Document _keystore; From eecdd6b8619c3f199320d32a0884668225d3f69f Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Wed, 30 Dec 2020 15:53:43 +0530 Subject: [PATCH 3/9] putting key in sigAttester --- .../include/marlin/pubsub/attestation/SigAttester.hpp | 9 ++------- relay/include/Relay.hpp | 10 +++++++--- relay/src/bsc_relay.cpp | 1 + 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp b/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp index 347331a8..6a5e139d 100644 --- a/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp +++ b/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp @@ -19,15 +19,10 @@ struct SigAttester { secp256k1_context* ctx_verifier = nullptr; uint8_t key[32]; - SigAttester() { + SigAttester(const char* priv_key) { + std::memcpy(key, priv_key, 32); ctx_signer = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); ctx_verifier = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - - do { - CryptoPP::OS_GenerateRandomBlock(false, key, 32); - } while( - secp256k1_ec_seckey_verify(ctx_verifier, key) != 1 - ); } ~SigAttester() { diff --git a/relay/include/Relay.hpp b/relay/include/Relay.hpp index e2053c73..13d91f4c 100644 --- a/relay/include/Relay.hpp +++ b/relay/include/Relay.hpp @@ -4,6 +4,8 @@ #include #include #include +#include + #include @@ -37,7 +39,7 @@ class Relay { enable_cut_through, accept_unsol_conn, enable_relay, - EmptyAttester, + SigAttester, BloomWitnesser, AbciTemplate >; @@ -58,8 +60,9 @@ class Relay { const core::SocketAddress &pubsub_addr, const core::SocketAddress &beacon_addr, const core::SocketAddress &beacon_server_addr, + const std::string &key, Args&&... args - ) : Relay(protocol, pubsub_port, pubsub_addr, beacon_addr, {beacon_server_addr}, {beacon_server_addr}, "", "", std::forward(args)...) {} + ) : Relay(protocol, pubsub_port, pubsub_addr, beacon_addr, key, {beacon_server_addr}, {beacon_server_addr}, "", "", std::forward(args)...) {} template Relay( @@ -67,6 +70,7 @@ class Relay { const uint32_t pubsub_port, const core::SocketAddress &pubsub_addr, const core::SocketAddress &beacon_addr, + const std::string &key, std::vector&& discovery_addrs, std::vector&& heartbeat_addrs, std::string address, @@ -99,7 +103,7 @@ class Relay { auto [max_sol_conns, max_unsol_conns] = protocol == MASTER_PUBSUB_PROTOCOL_NUMBER ? std::tuple(50, 30) : std::tuple(2, 16); - ps = new PubSubNodeType(pubsub_addr, max_sol_conns, max_unsol_conns, static_sk, {}, std::tie(static_pk), std::forward_as_tuple(args...)); + ps = new PubSubNodeType(pubsub_addr, max_sol_conns, max_unsol_conns, static_sk, std::forward_as_tuple(key.c_str()), std::tie(static_pk), std::forward_as_tuple(args...)); ps->delegate = this; b = new DiscoveryClient(beacon_addr, static_sk); b->address = address; diff --git a/relay/src/bsc_relay.cpp b/relay/src/bsc_relay.cpp index 97738c9e..6fc41ed2 100644 --- a/relay/src/bsc_relay.cpp +++ b/relay/src/bsc_relay.cpp @@ -80,6 +80,7 @@ int main(int argc, char** argv) { pubsub_port, SocketAddress::from_string(options.interface.value_or(std::string("0.0.0.0")).append(":").append(std::to_string(pubsub_port))), SocketAddress::from_string(options.interface.value_or(std::string("0.0.0.0")).append(":").append(std::to_string(discovery_port))), + key, std::move(discovery_addrs), std::move(heartbeat_addrs), address, From 8fcecd34ee138deb4f513950a4598d5ba926bc4c Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Thu, 31 Dec 2020 11:14:41 +0530 Subject: [PATCH 4/9] adding key extraction in beaconserver --- beacon/CMakeLists.txt | 6 ++ beacon/examples/server.cpp | 158 ++++++++++++++++++++++++++++++++++++- 2 files changed, 163 insertions(+), 1 deletion(-) diff --git a/beacon/CMakeLists.txt b/beacon/CMakeLists.txt index 799d7fee..d749e80a 100644 --- a/beacon/CMakeLists.txt +++ b/beacon/CMakeLists.txt @@ -41,6 +41,12 @@ target_link_libraries(beacon INTERFACE Boost::iterator) # Boost::filesystem target_link_libraries(beacon INTERFACE Boost::filesystem) +# cryptopp +target_link_libraries(beacon INTERFACE cryptopp::CryptoPP) + +# rapidjson +target_link_libraries(beacon INTERFACE rapidjson) + install(TARGETS beacon EXPORT marlin-beacon-export LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} diff --git a/beacon/examples/server.cpp b/beacon/examples/server.cpp index f81bfea9..058625ea 100644 --- a/beacon/examples/server.cpp +++ b/beacon/examples/server.cpp @@ -2,17 +2,28 @@ #include #include #include +#include +#include +#include +#include +#include +#include +#include using namespace marlin; class BeaconDelegate {}; struct CliOptions { + std::string keystore_path; + std::string keystore_pass_path; std::optional discovery_addr; std::optional heartbeat_addr; std::optional beacon_addr; }; -STRUCTOPT(CliOptions, discovery_addr, heartbeat_addr, beacon_addr); +STRUCTOPT(CliOptions, keystore_path, keystore_pass_path, discovery_addr, heartbeat_addr, beacon_addr); + +std::string get_key(std::string keystore_path, std::string keystore_pass_path); int main(int argc, char** argv) { try { @@ -31,6 +42,11 @@ int main(int argc, char** argv) { heartbeat_addr.to_string() ); + std::string key = get_key(options.keystore_path, options.keystore_pass_path); + if (key.empty()) { + SPDLOG_ERROR("keystore file error"); + return 1; + } BeaconDelegate del; beacon::DiscoveryServer b(discovery_addr, heartbeat_addr, beacon_addr); b.delegate = &del; @@ -43,3 +59,143 @@ int main(int argc, char** argv) { return -1; } + +std::string string_to_hex(const std::string& input) +{ + std::string output; + CryptoPP::StringSource ss2( input, true, + new CryptoPP::HexEncoder( + new CryptoPP::StringSink( output ) + )); // HexEncoder + return output; +} + +std::string hex_to_string(const std::string& input) +{ + std::string output; + CryptoPP::StringSource ss2( input, true, + new CryptoPP::HexDecoder( + new CryptoPP::StringSink( output ) + )); // HexDecoder + return output; +} + +bool isvalid_cipherparams(const rapidjson::Value &cipherparams, const std::string &cipher) { + if(cipher == "aes-128-ctr") { + return cipherparams.HasMember("iv") && cipherparams["iv"].IsString(); + } + return false; +} + +bool isvalid_kdfparams(const rapidjson::Value &kdfparams, const std::string &kdf) { + if(kdf == "scrypt") { + return kdfparams.HasMember("dklen") && kdfparams["dklen"].IsUint64() + && kdfparams.HasMember("n") && kdfparams["n"].IsUint64() + && kdfparams.HasMember("p") && kdfparams["p"].IsUint64() + && kdfparams.HasMember("r") && kdfparams["r"].IsUint64() + && kdfparams.HasMember("salt") && kdfparams["salt"].IsString(); + } + return false; +} + +bool isvalid_keystore(rapidjson::Document &keystore) { + if (keystore.HasMember("crypto") && keystore["crypto"].IsObject() ) { + const rapidjson::Value &crypto = keystore["crypto"]; + const rapidjson::Value &cipherparams = crypto["cipherparams"]; + const rapidjson::Value &kdfparams = crypto["kdfparams"]; + return crypto.HasMember("cipher") && crypto["cipher"].IsString() + && crypto.HasMember("ciphertext") && crypto["ciphertext"].IsString() + && crypto.HasMember("kdf") && crypto["kdf"].IsString() + && crypto.HasMember("mac") && crypto["mac"].IsString() + && crypto.HasMember("cipherparams") && crypto["cipherparams"].IsObject() + && crypto.HasMember("kdfparams") && crypto["kdfparams"].IsObject() + && isvalid_cipherparams(cipherparams, crypto["cipher"].GetString()) + && isvalid_kdfparams(kdfparams, crypto["kdf"].GetString()); + } + return false; +} + +void derivekey_scrypt(CryptoPP::SecByteBlock &derived, const rapidjson::Value &kdfparams, const std::string &pass) { + + CryptoPP::Scrypt pbkdf; + derived = CryptoPP::SecByteBlock(kdfparams["dklen"].GetUint()); + std::string salt(hex_to_string(kdfparams["salt"].GetString())); + pbkdf.DeriveKey(derived, derived.size(), + CryptoPP::ConstBytePtr(pass), CryptoPP::BytePtrSize(pass), + CryptoPP::ConstBytePtr(salt), CryptoPP::BytePtrSize(salt), + CryptoPP::word64(kdfparams["n"].GetUint64()), + CryptoPP::word64(kdfparams["r"].GetUint64()), + CryptoPP::word64(kdfparams["p"].GetUint64())); +} + +std::string decrypt_aes128ctr(const rapidjson::Value &cipherparams, std::string &ciphertext, CryptoPP::SecByteBlock &derived) { + std::string iv = hex_to_string(cipherparams["iv"].GetString()); + + CryptoPP::CTR_Mode::Decryption d; + d.SetKeyWithIV(derived, 16, CryptoPP::ConstBytePtr(iv)); + + CryptoPP::SecByteBlock decrypted(ciphertext.size()); + d.ProcessData(decrypted, CryptoPP::ConstBytePtr(ciphertext), CryptoPP::BytePtrSize(ciphertext)); + return std::string((const char*)decrypted.data(), decrypted.size()); +} + +bool check_mac(const std::string &mac, CryptoPP::SecByteBlock &derived, std::string &ciphertext) { + CryptoPP::Keccak_256 hasher; + auto hashinput = CryptoPP::SecByteBlock((derived.data()+16), 16) + CryptoPP::SecByteBlock((const CryptoPP::byte*)ciphertext.data(), ciphertext.size()); + + CryptoPP::SecByteBlock hash(mac.size()); + return hasher.VerifyTruncatedDigest((const CryptoPP::byte*)mac.data(), mac.size(), hashinput, hashinput.size()); +} + +std::string get_key(std::string keystore_path, std::string keystore_pass_path) { + std::string _pass; + rapidjson::Document _keystore; + + // read password file + if(boost::filesystem::exists(keystore_pass_path)) { + std::ifstream fin(keystore_pass_path); + std::getline(fin, _pass); + fin.close(); + } + if (_pass.empty()) { + SPDLOG_ERROR("Invalid password file"); + return ""; + } + + // read keystore file + if(boost::filesystem::exists(keystore_path)) { + std::string s; + boost::filesystem::load_string_file(keystore_path, s); + rapidjson::StringStream ss(s.c_str()); + _keystore.ParseStream(ss); + } + if (!isvalid_keystore(_keystore)){ + SPDLOG_ERROR("Invalid keystore file"); + return ""; + } + + const rapidjson::Value &crypto = _keystore["crypto"]; + std::string ciphertext = hex_to_string(crypto["ciphertext"].GetString()); + CryptoPP::SecByteBlock derived; + std::string decrypted; + + // get derived keycrypto + if (crypto["kdf"] == "scrypt") { + derivekey_scrypt(derived, crypto["kdfparams"], _pass); + } + if (derived.size() == 0) { + SPDLOG_ERROR("kdf error"); + return ""; + } + if (crypto["cipher"] == "aes-128-ctr") { + decrypted = decrypt_aes128ctr(crypto["cipherparams"], ciphertext, derived); + } + + //validate mac + if (!check_mac(hex_to_string(crypto["mac"].GetString()), derived, ciphertext)) { + SPDLOG_ERROR("Invalid mac"); + return ""; + } + SPDLOG_INFO("decrypted keystore"); + return decrypted; +} From e8d1b7ce76d30383b4506745f1c1d6451bc6781e Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Thu, 31 Dec 2020 11:29:20 +0530 Subject: [PATCH 5/9] removing key exctraction from relay --- relay/include/Relay.hpp | 10 +-- relay/src/bsc_relay.cpp | 159 +--------------------------------------- 2 files changed, 5 insertions(+), 164 deletions(-) diff --git a/relay/include/Relay.hpp b/relay/include/Relay.hpp index 13d91f4c..e2053c73 100644 --- a/relay/include/Relay.hpp +++ b/relay/include/Relay.hpp @@ -4,8 +4,6 @@ #include #include #include -#include - #include @@ -39,7 +37,7 @@ class Relay { enable_cut_through, accept_unsol_conn, enable_relay, - SigAttester, + EmptyAttester, BloomWitnesser, AbciTemplate >; @@ -60,9 +58,8 @@ class Relay { const core::SocketAddress &pubsub_addr, const core::SocketAddress &beacon_addr, const core::SocketAddress &beacon_server_addr, - const std::string &key, Args&&... args - ) : Relay(protocol, pubsub_port, pubsub_addr, beacon_addr, key, {beacon_server_addr}, {beacon_server_addr}, "", "", std::forward(args)...) {} + ) : Relay(protocol, pubsub_port, pubsub_addr, beacon_addr, {beacon_server_addr}, {beacon_server_addr}, "", "", std::forward(args)...) {} template Relay( @@ -70,7 +67,6 @@ class Relay { const uint32_t pubsub_port, const core::SocketAddress &pubsub_addr, const core::SocketAddress &beacon_addr, - const std::string &key, std::vector&& discovery_addrs, std::vector&& heartbeat_addrs, std::string address, @@ -103,7 +99,7 @@ class Relay { auto [max_sol_conns, max_unsol_conns] = protocol == MASTER_PUBSUB_PROTOCOL_NUMBER ? std::tuple(50, 30) : std::tuple(2, 16); - ps = new PubSubNodeType(pubsub_addr, max_sol_conns, max_unsol_conns, static_sk, std::forward_as_tuple(key.c_str()), std::tie(static_pk), std::forward_as_tuple(args...)); + ps = new PubSubNodeType(pubsub_addr, max_sol_conns, max_unsol_conns, static_sk, {}, std::tie(static_pk), std::forward_as_tuple(args...)); ps->delegate = this; b = new DiscoveryClient(beacon_addr, static_sk); b->address = address; diff --git a/relay/src/bsc_relay.cpp b/relay/src/bsc_relay.cpp index 6fc41ed2..36d4f8c1 100644 --- a/relay/src/bsc_relay.cpp +++ b/relay/src/bsc_relay.cpp @@ -3,10 +3,6 @@ #include #include -#include -#include -#include -#include using namespace marlin::core; using namespace marlin::asyncio; @@ -18,17 +14,13 @@ struct CliOptions { std::string discovery_addrs; std::string heartbeat_addrs; std::string datadir; - std::string keystore_path; - std::string keystore_pass_path; std::optional pubsub_port; std::optional discovery_port; std::optional address; std::optional name; std::optional interface; }; -STRUCTOPT(CliOptions, discovery_addrs, heartbeat_addrs, datadir, keystore_path, keystore_pass_path, pubsub_port, discovery_port, address, name, interface); - -std::string get_key(std::string keystore_path, std::string keystore_pass_path); +STRUCTOPT(CliOptions, discovery_addrs, heartbeat_addrs, datadir, pubsub_port, discovery_port, address, name, interface); int main(int argc, char** argv) { try { @@ -38,11 +30,6 @@ int main(int argc, char** argv) { auto discovery_port = options.discovery_port.value_or(5002); auto address = options.address.value_or("0x0000000000000000000000000000000000000000"); - std::string key = get_key(options.keystore_path, options.keystore_pass_path); - if (key.empty()) { - SPDLOG_ERROR("keystore file error"); - return 1; - } if(address.size() != 42) { structopt::details::visitor visitor("bsc_relay", ""); CliOptions opt = CliOptions(); @@ -80,7 +67,6 @@ int main(int argc, char** argv) { pubsub_port, SocketAddress::from_string(options.interface.value_or(std::string("0.0.0.0")).append(":").append(std::to_string(pubsub_port))), SocketAddress::from_string(options.interface.value_or(std::string("0.0.0.0")).append(":").append(std::to_string(discovery_port))), - key, std::move(discovery_addrs), std::move(heartbeat_addrs), address, @@ -95,145 +81,4 @@ int main(int argc, char** argv) { } return -1; -} - -std::string string_to_hex(const std::string& input) -{ - std::string output; - CryptoPP::StringSource ss2( input, true, - new CryptoPP::HexEncoder( - new CryptoPP::StringSink( output ) - )); // HexEncoder - return output; -} - -std::string hex_to_string(const std::string& input) -{ - std::string output; - CryptoPP::StringSource ss2( input, true, - new CryptoPP::HexDecoder( - new CryptoPP::StringSink( output ) - )); // HexDecoder - return output; -} - -bool isvalid_cipherparams(const rapidjson::Value &cipherparams, const std::string &cipher) { - if(cipher == "aes-128-ctr") { - return cipherparams.HasMember("iv") && cipherparams["iv"].IsString(); - } - return false; -} - -bool isvalid_kdfparams(const rapidjson::Value &kdfparams, const std::string &kdf) { - if(kdf == "scrypt") { - return kdfparams.HasMember("dklen") && kdfparams["dklen"].IsUint64() - && kdfparams.HasMember("n") && kdfparams["n"].IsUint64() - && kdfparams.HasMember("p") && kdfparams["p"].IsUint64() - && kdfparams.HasMember("r") && kdfparams["r"].IsUint64() - && kdfparams.HasMember("salt") && kdfparams["salt"].IsString(); - } - return false; -} - -bool isvalid_keystore(rapidjson::Document &keystore) { - if (keystore.HasMember("crypto") && keystore["crypto"].IsObject() ) { - const rapidjson::Value &crypto = keystore["crypto"]; - const rapidjson::Value &cipherparams = crypto["cipherparams"]; - const rapidjson::Value &kdfparams = crypto["kdfparams"]; - return crypto.HasMember("cipher") && crypto["cipher"].IsString() - && crypto.HasMember("ciphertext") && crypto["ciphertext"].IsString() - && crypto.HasMember("kdf") && crypto["kdf"].IsString() - && crypto.HasMember("mac") && crypto["mac"].IsString() - && crypto.HasMember("cipherparams") && crypto["cipherparams"].IsObject() - && crypto.HasMember("kdfparams") && crypto["kdfparams"].IsObject() - && isvalid_cipherparams(cipherparams, crypto["cipher"].GetString()) - && isvalid_kdfparams(kdfparams, crypto["kdf"].GetString()); - } - return false; -} - -void derivekey_scrypt(CryptoPP::SecByteBlock &derived, const rapidjson::Value &kdfparams, const std::string &pass) { - - CryptoPP::Scrypt pbkdf; - derived = CryptoPP::SecByteBlock(kdfparams["dklen"].GetUint()); - std::string salt(hex_to_string(kdfparams["salt"].GetString())); - pbkdf.DeriveKey(derived, derived.size(), - CryptoPP::ConstBytePtr(pass), CryptoPP::BytePtrSize(pass), - CryptoPP::ConstBytePtr(salt), CryptoPP::BytePtrSize(salt), - CryptoPP::word64(kdfparams["n"].GetUint64()), - CryptoPP::word64(kdfparams["r"].GetUint64()), - CryptoPP::word64(kdfparams["p"].GetUint64())); -} - -std::string decrypt_aes128ctr(const rapidjson::Value &cipherparams, std::string &ciphertext, CryptoPP::SecByteBlock &derived) { - std::string iv = hex_to_string(cipherparams["iv"].GetString()); - - CryptoPP::CTR_Mode::Decryption d; - d.SetKeyWithIV(derived, 16, CryptoPP::ConstBytePtr(iv)); - - CryptoPP::SecByteBlock decrypted(ciphertext.size()); - d.ProcessData(decrypted, CryptoPP::ConstBytePtr(ciphertext), CryptoPP::BytePtrSize(ciphertext)); - return std::string((const char*)decrypted.data(), decrypted.size()); -} - -bool check_mac(const std::string &mac, CryptoPP::SecByteBlock &derived, std::string &ciphertext) { - CryptoPP::Keccak_256 hasher; - auto hashinput = CryptoPP::SecByteBlock((derived.data()+16), 16) + CryptoPP::SecByteBlock((const CryptoPP::byte*)ciphertext.data(), ciphertext.size()); - - CryptoPP::SecByteBlock hash(mac.size()); - return hasher.VerifyTruncatedDigest((const CryptoPP::byte*)mac.data(), mac.size(), hashinput, hashinput.size()); -} - -std::string get_key(std::string keystore_path, std::string keystore_pass_path) { - std::string _pass; - rapidjson::Document _keystore; - - // read password file - if(boost::filesystem::exists(keystore_pass_path)) { - std::ifstream fin(keystore_pass_path); - std::getline(fin, _pass); - fin.close(); - } - if (_pass.empty()) { - SPDLOG_ERROR("Invalid password file"); - return ""; - } - - // read keystore file - if(boost::filesystem::exists(keystore_path)) { - std::string s; - boost::filesystem::load_string_file(keystore_path, s); - rapidjson::StringStream ss(s.c_str()); - _keystore.ParseStream(ss); - } - if (!isvalid_keystore(_keystore)){ - SPDLOG_ERROR("Invalid keystore file"); - return ""; - } - - const rapidjson::Value &crypto = _keystore["crypto"]; - std::string ciphertext = hex_to_string(crypto["ciphertext"].GetString()); - CryptoPP::SecByteBlock derived; - std::string decrypted; - - // get derived keycrypto - if (crypto["kdf"] == "scrypt") { - derivekey_scrypt(derived, crypto["kdfparams"], _pass); - } - if (derived.size() == 0) { - SPDLOG_ERROR("kdf error"); - return ""; - } - if (crypto["cipher"] == "aes-128-ctr") { - decrypted = decrypt_aes128ctr(crypto["cipherparams"], ciphertext, derived); - } - - //validate mac - if (!check_mac(hex_to_string(crypto["mac"].GetString()), derived, ciphertext)) { - SPDLOG_ERROR("Invalid mac"); - return ""; - } - SPDLOG_INFO("decrypted keystore"); - return decrypted; -} - +} \ No newline at end of file From cee28ffea38d29a6784a19ee29c24a795b8b85a6 Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Thu, 31 Dec 2020 11:32:04 +0530 Subject: [PATCH 6/9] removing blank lines --- relay/src/bsc_relay.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/relay/src/bsc_relay.cpp b/relay/src/bsc_relay.cpp index 36d4f8c1..65bfe8c7 100644 --- a/relay/src/bsc_relay.cpp +++ b/relay/src/bsc_relay.cpp @@ -29,7 +29,6 @@ int main(int argc, char** argv) { auto pubsub_port = options.pubsub_port.value_or(5000); auto discovery_port = options.discovery_port.value_or(5002); auto address = options.address.value_or("0x0000000000000000000000000000000000000000"); - if(address.size() != 42) { structopt::details::visitor visitor("bsc_relay", ""); CliOptions opt = CliOptions(); @@ -81,4 +80,4 @@ int main(int argc, char** argv) { } return -1; -} \ No newline at end of file +} From fda74811bccf314c33d62d89989526f3a07b07c6 Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Thu, 31 Dec 2020 15:54:53 +0530 Subject: [PATCH 7/9] reverting sigAttester --- pubsub/include/marlin/pubsub/attestation/SigAttester.hpp | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp b/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp index 6a5e139d..e6c0e279 100644 --- a/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp +++ b/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp @@ -19,10 +19,15 @@ struct SigAttester { secp256k1_context* ctx_verifier = nullptr; uint8_t key[32]; - SigAttester(const char* priv_key) { - std::memcpy(key, priv_key, 32); + SigAttester() { ctx_signer = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); ctx_verifier = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); + + do { + CryptoPP::OS_GenerateRandomBlock(false, key, 32); + } while( + secp256k1_ec_seckey_verify(ctx_verifier, key) != 1 + ); } ~SigAttester() { From 5fb821668a6d827ce92e71ffc02994862c5f2c56 Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Thu, 31 Dec 2020 15:56:03 +0530 Subject: [PATCH 8/9] making key params optional --- beacon/examples/server.cpp | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/beacon/examples/server.cpp b/beacon/examples/server.cpp index 058625ea..ced697fe 100644 --- a/beacon/examples/server.cpp +++ b/beacon/examples/server.cpp @@ -15,8 +15,8 @@ using namespace marlin; class BeaconDelegate {}; struct CliOptions { - std::string keystore_path; - std::string keystore_pass_path; + std::optional keystore_path; + std::optional keystore_pass_path; std::optional discovery_addr; std::optional heartbeat_addr; std::optional beacon_addr; @@ -28,6 +28,18 @@ std::string get_key(std::string keystore_path, std::string keystore_pass_path); int main(int argc, char** argv) { try { auto options = structopt::app("beacon").parse(argc, argv); + if(options.beacon_addr.has_value()) { + if(options.keystore_path.has_value() && options.keystore_pass_path.has_value()) { + std::string key = get_key(options.keystore_path.value(), options.keystore_pass_path.value()); + if (key.empty()) { + SPDLOG_ERROR("keystore file error"); + return 1; + } + } else { + SPDLOG_ERROR("require keystore and password file"); + return 1; + } + } auto discovery_addr = core::SocketAddress::from_string( options.discovery_addr.value_or("127.0.0.1:8002") ); @@ -42,11 +54,6 @@ int main(int argc, char** argv) { heartbeat_addr.to_string() ); - std::string key = get_key(options.keystore_path, options.keystore_pass_path); - if (key.empty()) { - SPDLOG_ERROR("keystore file error"); - return 1; - } BeaconDelegate del; beacon::DiscoveryServer b(discovery_addr, heartbeat_addr, beacon_addr); b.delegate = &del; From 576509663c766adeb39a7b5132c67f73ec89d7c8 Mon Sep 17 00:00:00 2001 From: whitewalker608 Date: Thu, 31 Dec 2020 15:57:22 +0530 Subject: [PATCH 9/9] removing blank spaces --- pubsub/include/marlin/pubsub/attestation/SigAttester.hpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp b/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp index e6c0e279..347331a8 100644 --- a/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp +++ b/pubsub/include/marlin/pubsub/attestation/SigAttester.hpp @@ -23,10 +23,10 @@ struct SigAttester { ctx_signer = secp256k1_context_create(SECP256K1_CONTEXT_SIGN); ctx_verifier = secp256k1_context_create(SECP256K1_CONTEXT_VERIFY); - do { - CryptoPP::OS_GenerateRandomBlock(false, key, 32); - } while( - secp256k1_ec_seckey_verify(ctx_verifier, key) != 1 + do { + CryptoPP::OS_GenerateRandomBlock(false, key, 32); + } while( + secp256k1_ec_seckey_verify(ctx_verifier, key) != 1 ); }