From c1bb07e65f550e043d9a387d3978e651a1b7a15d Mon Sep 17 00:00:00 2001 From: Determinant Date: Tue, 2 Jul 2019 03:00:31 -0400 Subject: enable TLS for replica-replica connections --- src/hotstuff.cpp | 18 +++++++++++++++--- src/hotstuff_app.cpp | 41 ++++++++++++++++++++++++++++++---------- src/hotstuff_client.cpp | 8 ++++---- src/hotstuff_tls_keygen.cpp | 46 +++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 96 insertions(+), 17 deletions(-) create mode 100644 src/hotstuff_tls_keygen.cpp (limited to 'src') diff --git a/src/hotstuff.cpp b/src/hotstuff.cpp index 54b80e4..a59aa82 100644 --- a/src/hotstuff.cpp +++ b/src/hotstuff.cpp @@ -246,6 +246,16 @@ void HotStuffBase::resp_blk_handler(MsgRespBlock &&msg, const Net::conn_t &) { if (blk) on_fetch_blk(blk); } +bool HotStuffBase::conn_handler(const salticidae::ConnPool::conn_t &conn, bool connected) { + if (connected) + { + auto cert = conn->get_peer_cert(); + SALTICIDAE_LOG_INFO("%s", salticidae::get_hash(cert->get_der()).to_hex().c_str()); + return (!cert) || valid_tls_certs.count(salticidae::get_hash(cert->get_der())); + } + return true; +} + void HotStuffBase::print_stat() const { LOG_INFO("===== begin stats ====="); LOG_INFO("-------- queues -------"); @@ -339,6 +349,7 @@ HotStuffBase::HotStuffBase(uint32_t blk_size, pn.reg_handler(salticidae::generic_bind(&HotStuffBase::vote_handler, this, _1, _2)); pn.reg_handler(salticidae::generic_bind(&HotStuffBase::req_blk_handler, this, _1, _2)); pn.reg_handler(salticidae::generic_bind(&HotStuffBase::resp_blk_handler, this, _1, _2)); + pn.reg_conn_handler(salticidae::generic_bind(&HotStuffBase::conn_handler, this, _1, _2)); pn.start(); pn.listen(listen_addr); } @@ -377,12 +388,13 @@ void HotStuffBase::do_decide(Finality &&fin) { HotStuffBase::~HotStuffBase() {} void HotStuffBase::start( - std::vector> &&replicas, + std::vector> &&replicas, bool ec_loop) { for (size_t i = 0; i < replicas.size(); i++) { - auto &addr = replicas[i].first; - HotStuffCore::add_replica(i, addr, std::move(replicas[i].second)); + auto &addr = std::get<0>(replicas[i]); + HotStuffCore::add_replica(i, addr, std::move(std::get<1>(replicas[i]))); + valid_tls_certs.insert(std::move(std::get<2>(replicas[i]))); if (addr != listen_addr) { peers.push_back(addr); diff --git a/src/hotstuff_app.cpp b/src/hotstuff_app.cpp index 25b5698..7aa9e1d 100644 --- a/src/hotstuff_app.cpp +++ b/src/hotstuff_app.cpp @@ -142,7 +142,7 @@ class HotStuffApp: public HotStuff { const Net::Config &repnet_config, const ClientNetwork::Config &clinet_config); - void start(const std::vector> &reps); + void start(const std::vector> &reps); void stop(); }; @@ -168,6 +168,8 @@ int main(int argc, char **argv) { auto opt_idx = Config::OptValInt::create(0); auto opt_client_port = Config::OptValInt::create(-1); auto opt_privkey = Config::OptValStr::create(); + auto opt_tls_privkey = Config::OptValStr::create(); + auto opt_tls_cert = Config::OptValStr::create(); auto opt_help = Config::OptValFlag::create(false); auto opt_pace_maker = Config::OptValStr::create("dummy"); auto opt_fixed_proposer = Config::OptValInt::create(1); @@ -178,6 +180,7 @@ int main(int argc, char **argv) { auto opt_repburst = Config::OptValInt::create(100); auto opt_clinworker = Config::OptValInt::create(8); auto opt_cliburst = Config::OptValInt::create(1000); + auto opt_notls = Config::OptValFlag::create(false); config.add_opt("block-size", opt_blk_size, Config::SET_VAL); config.add_opt("parent-limit", opt_parent_limit, Config::SET_VAL); @@ -186,6 +189,8 @@ int main(int argc, char **argv) { config.add_opt("idx", opt_idx, Config::SET_VAL, 'i', "specify the index in the replica list"); config.add_opt("cport", opt_client_port, Config::SET_VAL, 'c', "specify the port listening for clients"); config.add_opt("privkey", opt_privkey, Config::SET_VAL); + config.add_opt("tls-privkey", opt_tls_privkey, Config::SET_VAL); + config.add_opt("tls-cert", opt_tls_cert, Config::SET_VAL); config.add_opt("pace-maker", opt_pace_maker, Config::SET_VAL, 'p', "specify pace maker (sticky, dummy)"); config.add_opt("proposer", opt_fixed_proposer, Config::SET_VAL, 'l', "set the fixed proposer (for dummy)"); config.add_opt("qc-timeout", opt_qc_timeout, Config::SET_VAL, 't', "set QC timeout (for sticky)"); @@ -195,6 +200,7 @@ int main(int argc, char **argv) { config.add_opt("repburst", opt_repburst, Config::SET_VAL, 'b', ""); config.add_opt("clinworker", opt_clinworker, Config::SET_VAL, 'M', "the number of threads for client network"); config.add_opt("cliburst", opt_cliburst, Config::SET_VAL, 'B', ""); + config.add_opt("notls", opt_notls, Config::SWITCH_ON, 's', "disable TLS"); config.add_opt("help", opt_help, Config::SWITCH_ON, 'h', "show this help info"); EventContext ec; @@ -206,18 +212,18 @@ int main(int argc, char **argv) { } auto idx = opt_idx->get(); auto client_port = opt_client_port->get(); - std::vector> replicas; + std::vector> replicas; for (const auto &s: opt_replicas->get()) { auto res = trim_all(split(s, ",")); - if (res.size() != 2) + if (res.size() != 3) throw HotStuffError("invalid replica info"); - replicas.push_back(std::make_pair(res[0], res[1])); + replicas.push_back(std::make_tuple(res[0], res[1], res[2])); } if (!(0 <= idx && (size_t)idx < replicas.size())) throw HotStuffError("replica idx out of range"); - std::string binding_addr = replicas[idx].first; + std::string binding_addr = std::get<0>(replicas[idx]); if (client_port == -1) { auto p = split_ip_port_cport(binding_addr); @@ -242,6 +248,19 @@ int main(int argc, char **argv) { HotStuffApp::Net::Config repnet_config; ClientNetwork::Config clinet_config; + if (!opt_tls_privkey->get().empty() && !opt_notls->get()) + { + auto tls_priv_key = new salticidae::PKey( + salticidae::PKey::create_privkey_from_der( + hotstuff::from_hex(opt_tls_privkey->get()))); + auto tls_cert = new salticidae::X509( + salticidae::X509::create_from_der( + hotstuff::from_hex(opt_tls_cert->get()))); + repnet_config + .enable_tls(true) + .tls_key(tls_priv_key) + .tls_cert(tls_cert); + } repnet_config .burst_size(opt_repburst->get()) .nworker(opt_repnworker->get()); @@ -260,12 +279,14 @@ int main(int argc, char **argv) { opt_nworker->get(), repnet_config, clinet_config); - std::vector> reps; + std::vector> reps; for (auto &r: replicas) { - auto p = split_ip_port_cport(r.first); - reps.push_back(std::make_pair( - NetAddr(p.first), hotstuff::from_hex(r.second))); + auto p = split_ip_port_cport(std::get<0>(r)); + reps.push_back(std::make_tuple( + NetAddr(p.first), + hotstuff::from_hex(std::get<1>(r)), + hotstuff::from_hex(std::get<2>(r)))); } auto shutdown = [&](int) { papp->stop(); }; salticidae::SigEvent ev_sigint(ec, shutdown); @@ -344,7 +365,7 @@ void HotStuffApp::client_request_cmd_handler(MsgReqCmd &&msg, const conn_t &conn }); } -void HotStuffApp::start(const std::vector> &reps) { +void HotStuffApp::start(const std::vector> &reps) { ev_stat_timer = TimerEvent(ec, [this](TimerEvent &) { HotStuff::print_stat(); HotStuffApp::print_stat(); diff --git a/src/hotstuff_client.cpp b/src/hotstuff_client.cpp index 08f2a2e..9f7423d 100644 --- a/src/hotstuff_client.cpp +++ b/src/hotstuff_client.cpp @@ -156,13 +156,13 @@ int main(int argc, char **argv) { auto idx = opt_idx->get(); max_iter_num = opt_max_iter_num->get(); max_async_num = opt_max_async_num->get(); - std::vector> raw; + std::vector raw; for (const auto &s: opt_replicas->get()) { auto res = salticidae::trim_all(salticidae::split(s, ",")); - if (res.size() != 2) + if (res.size() < 1) throw HotStuffError("format error"); - raw.push_back(std::make_pair(res[0], res[1])); + raw.push_back(res[0]); } if (!(0 <= idx && (size_t)idx < raw.size() && raw.size() > 0)) @@ -170,7 +170,7 @@ int main(int argc, char **argv) { cid = opt_cid->get() != -1 ? opt_cid->get() : idx; for (const auto &p: raw) { - auto _p = split_ip_port_cport(p.first); + auto _p = split_ip_port_cport(p); size_t _; replicas.push_back(NetAddr(NetAddr(_p.first).ip, htons(stoi(_p.second, &_)))); } diff --git a/src/hotstuff_tls_keygen.cpp b/src/hotstuff_tls_keygen.cpp new file mode 100644 index 0000000..1ce80f2 --- /dev/null +++ b/src/hotstuff_tls_keygen.cpp @@ -0,0 +1,46 @@ +/** + * Copyright 2018 VMware + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +#include +#include "salticidae/util.h" +#include "salticidae/crypto.h" +#include "hotstuff/type.h" + +using salticidae::Config; +using hotstuff::tls_pkey_bt; +using hotstuff::tls_x509_bt; + +int main(int argc, char **argv) { + Config config("hotstuff.conf"); + tls_pkey_bt priv_key; + tls_x509_bt pub_key; + auto opt_n = Config::OptValInt::create(1); + config.add_opt("num", opt_n, Config::SET_VAL); + config.parse(argc, argv); + int n = opt_n->get(); + if (n < 1) + error(1, 0, "n must be >0"); + while (n--) + { + priv_key = new salticidae::PKey(salticidae::PKey::create_privkey_rsa()); + pub_key = new salticidae::X509(salticidae::X509::create_self_signed_from_pubkey(*priv_key)); + printf("crt:%s sec:%s cid:%s\n", + salticidae::get_hex(pub_key->get_der()).c_str(), + salticidae::get_hex(priv_key->get_privkey_der()).c_str(), + salticidae::get_hex(salticidae::get_hash(pub_key->get_der())).c_str()); + } + return 0; +} -- cgit v1.2.3