Skip to content

Commit 76fa805

Browse files
author
Igor Egorov
authored
Refactor Crypto Provider Implementation (#50)
* Enable RSA crypto provider * Make secure use of user's input buffers in crypto providers * Enable ECDSA crypto provider * Enable Secp256k1 crypto provider * Remove all the legacy and redundant code from the crypto provider * Use boost::optional in Kademlia and apply clang-format * Refactor keygen test Signed-off-by: Igor Egorov <[email protected]>
1 parent d81e3f7 commit 76fa805

33 files changed

+867
-621
lines changed

example/02-kad/factory.cpp

Lines changed: 20 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,13 @@
88

99
// implementations
1010
#include <libp2p/crypto/crypto_provider/crypto_provider_impl.hpp>
11+
#include <libp2p/crypto/ecdsa_provider/ecdsa_provider_impl.hpp>
1112
#include <libp2p/crypto/ed25519_provider/ed25519_provider_impl.hpp>
1213
#include <libp2p/crypto/key_marshaller/key_marshaller_impl.hpp>
1314
#include <libp2p/crypto/key_validator/key_validator_impl.hpp>
1415
#include <libp2p/crypto/random_generator/boost_generator.hpp>
16+
#include <libp2p/crypto/rsa_provider/rsa_provider_impl.hpp>
17+
#include <libp2p/crypto/secp256k1_provider/secp256k1_provider_impl.hpp>
1518
#include <libp2p/host/basic_host.hpp>
1619
#include <libp2p/muxer/mplex.hpp>
1720
#include <libp2p/muxer/yamux.hpp>
@@ -40,8 +43,8 @@
4043

4144
namespace libp2p::protocol::kademlia::example {
4245

43-
std::optional<libp2p::peer::PeerInfo> str2peerInfo(const std::string &str) {
44-
using R = std::optional<libp2p::peer::PeerInfo>;
46+
boost::optional<libp2p::peer::PeerInfo> str2peerInfo(const std::string &str) {
47+
using R = boost::optional<libp2p::peer::PeerInfo>;
4548

4649
auto server_ma_res = libp2p::multi::Multiaddress::create(str);
4750
if (!server_ma_res) {
@@ -76,8 +79,15 @@ namespace libp2p::protocol::kademlia::example {
7679
auto csprng = std::make_shared<crypto::random::BoostRandomGenerator>();
7780
auto ed25519_provider =
7881
std::make_shared<crypto::ed25519::Ed25519ProviderImpl>();
79-
auto crypto_provider = std::make_shared<crypto::CryptoProviderImpl>(
80-
csprng, ed25519_provider);
82+
auto rsa_provider = std::make_shared<crypto::rsa::RsaProviderImpl>();
83+
auto ecdsa_provider =
84+
std::make_shared<crypto::ecdsa::EcdsaProviderImpl>();
85+
auto secp256k1_provider =
86+
std::make_shared<crypto::secp256k1::Secp256k1ProviderImpl>();
87+
std::shared_ptr<crypto::CryptoProvider> crypto_provider =
88+
std::make_shared<crypto::CryptoProviderImpl>(
89+
csprng, ed25519_provider, rsa_provider, ecdsa_provider,
90+
secp256k1_provider);
8191
auto validator = std::make_shared<crypto::validator::KeyValidatorImpl>(
8292
crypto_provider);
8393

@@ -128,7 +138,8 @@ namespace libp2p::protocol::kademlia::example {
128138
}
129139
} // namespace
130140

131-
void createPerHostObjects(PerHostObjects &objects, const KademliaConfig& conf) {
141+
void createPerHostObjects(PerHostObjects &objects,
142+
const KademliaConfig &conf) {
132143
auto injector = makeInjector(boost::di::bind<boost::asio::io_context>.to(
133144
createIOContext())[boost::di::override]);
134145

@@ -137,12 +148,9 @@ namespace libp2p::protocol::kademlia::example {
137148
injector.create<std::shared_ptr<libp2p::crypto::CryptoProvider>>();
138149
objects.key_marshaller = injector.create<
139150
std::shared_ptr<libp2p::crypto::marshaller::KeyMarshaller>>();
140-
objects.routing_table =
141-
std::make_shared<RoutingTableImpl>(
142-
injector.create<std::shared_ptr<peer::IdentityManager>>(),
143-
injector.create<std::shared_ptr<event::Bus>>(),
144-
conf
145-
);
151+
objects.routing_table = std::make_shared<RoutingTableImpl>(
152+
injector.create<std::shared_ptr<peer::IdentityManager>>(),
153+
injector.create<std::shared_ptr<event::Bus>>(), conf);
146154
}
147155

148156
std::shared_ptr<boost::asio::io_context> createIOContext() {
@@ -151,4 +159,4 @@ namespace libp2p::protocol::kademlia::example {
151159
return c;
152160
}
153161

154-
} // namespace libp2p::kad_example
162+
} // namespace libp2p::protocol::kademlia::example

example/02-kad/factory.hpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,10 @@ namespace libp2p::protocol::kademlia::example {
2121
std::shared_ptr<crypto::marshaller::KeyMarshaller> key_marshaller;
2222
};
2323

24-
void createPerHostObjects(PerHostObjects &objects, const KademliaConfig& conf);
24+
void createPerHostObjects(PerHostObjects &objects,
25+
const KademliaConfig &conf);
2526

26-
std::optional<libp2p::peer::PeerInfo> str2peerInfo(const std::string &str);
27+
boost::optional<libp2p::peer::PeerInfo> str2peerInfo(const std::string &str);
2728

2829
} // namespace libp2p::protocol::kademlia::example
2930

example/02-kad/kad_peer_discovery_example.cpp

Lines changed: 18 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ namespace libp2p::protocol::kademlia::example {
2929
.value();
3030
}
3131

32-
const KademliaConfig& getConfig() {
32+
const KademliaConfig &getConfig() {
3333
static KademliaConfig config = ([] {
3434
KademliaConfig c;
3535
c.randomWalk.delay = 5s;
@@ -45,21 +45,21 @@ namespace libp2p::protocol::kademlia::example {
4545
std::shared_ptr<KadImpl> kad;
4646
std::string listen_to;
4747
std::string connect_to;
48-
std::optional<libp2p::peer::PeerId> find_id;
48+
boost::optional<libp2p::peer::PeerId> find_id;
4949
Scheduler::Handle htimer;
5050
Scheduler::Handle hbootstrap;
5151
bool found = false;
5252
bool verbose = true;
5353
bool request_sent = false;
5454

5555
Host(size_t i, std::shared_ptr<Scheduler> sch, PerHostObjects obj)
56-
: index(i), o(std::move(obj))
56+
: index(i),
57+
o(std::move(obj))
5758

5859
{
59-
kad = std::make_shared<KadImpl>(
60-
o.host, std::move(sch), o.routing_table,
61-
createDefaultValueStoreBackend(), getConfig()
62-
);
60+
kad = std::make_shared<KadImpl>(o.host, std::move(sch), o.routing_table,
61+
createDefaultValueStoreBackend(),
62+
getConfig());
6363
}
6464

6565
void checkPeers() {
@@ -90,7 +90,6 @@ namespace libp2p::protocol::kademlia::example {
9090
kad->start(true);
9191
}
9292

93-
9493
void connect() {
9594
if (connect_to.empty())
9695
return;
@@ -100,8 +99,10 @@ namespace libp2p::protocol::kademlia::example {
10099

101100
void findPeer(const libp2p::peer::PeerId &id) {
102101
find_id = id;
103-
htimer = kad->scheduler().schedule(20000, [this] { onFindPeerTimer(); });
104-
hbootstrap = kad->scheduler().schedule(100, [this] { onBootstrapTimer(); });
102+
htimer =
103+
kad->scheduler().schedule(20000, [this] { onFindPeerTimer(); });
104+
hbootstrap =
105+
kad->scheduler().schedule(100, [this] { onBootstrapTimer(); });
105106
}
106107

107108
void onBootstrapTimer() {
@@ -110,7 +111,7 @@ namespace libp2p::protocol::kademlia::example {
110111
request_sent =
111112
kad->findPeer(genRandomPeerId(*o.key_gen, *o.key_marshaller),
112113
[this](const libp2p::peer::PeerId &peer,
113-
Kad::FindPeerQueryResult res) { //NOLINT
114+
Kad::FindPeerQueryResult res) { // NOLINT
114115
logger->info(
115116
"bootstrap return from findPeer, i={}, "
116117
"peer={} peers={} ({})",
@@ -151,8 +152,8 @@ namespace libp2p::protocol::kademlia::example {
151152
logger->info("onFindPeer: i={}, res: success={}, peers={}", index,
152153
res.success, res.closer_peers.size());
153154

154-
htimer =
155-
kad->scheduler().schedule(1000, [this, peers = std::move(res.closer_peers)] {
155+
htimer = kad->scheduler().schedule(
156+
1000, [this, peers = std::move(res.closer_peers)] {
156157
kad->findPeer(find_id.value(),
157158
[this](const libp2p::peer::PeerId &peer,
158159
Kad::FindPeerQueryResult res) {
@@ -172,7 +173,7 @@ namespace libp2p::protocol::kademlia::example {
172173

173174
std::vector<Host> hosts;
174175

175-
Hosts(size_t n, const std::shared_ptr<Scheduler>& sch) {
176+
Hosts(size_t n, const std::shared_ptr<Scheduler> &sch) {
176177
hosts.reserve(n);
177178

178179
for (size_t i = 0; i < n; ++i) {
@@ -182,7 +183,7 @@ namespace libp2p::protocol::kademlia::example {
182183
makeConnectTopologyCircle();
183184
}
184185

185-
void newHost(const std::shared_ptr<Scheduler>& sch) {
186+
void newHost(const std::shared_ptr<Scheduler> &sch) {
186187
size_t index = hosts.size();
187188
PerHostObjects o;
188189
createPerHostObjects(o, getConfig());
@@ -264,9 +265,9 @@ int main(int argc, char *argv[]) {
264265
size_t hosts_count = 6;
265266
bool kad_log_debug = false;
266267
if (argc > 1)
267-
hosts_count = atoi(argv[1]); //NOLINT
268+
hosts_count = atoi(argv[1]); // NOLINT
268269
if (argc > 2)
269-
kad_log_debug = (atoi(argv[2]) != 0); //NOLINT
270+
kad_log_debug = (atoi(argv[2]) != 0); // NOLINT
270271

271272
x::setupLoggers(kad_log_debug);
272273

include/libp2p/crypto/crypto_provider.hpp

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,12 +6,13 @@
66
#ifndef LIBP2P_CRYPTO_PROVIDER_HPP
77
#define LIBP2P_CRYPTO_PROVIDER_HPP
88

9+
#include <vector>
10+
911
#include <boost/filesystem.hpp>
1012
#include <gsl/span>
1113
#include <libp2p/crypto/common.hpp>
1214
#include <libp2p/crypto/key.hpp>
1315
#include <libp2p/outcome/outcome.hpp>
14-
#include <vector>
1516

1617
namespace libp2p::crypto {
1718
/**
@@ -27,9 +28,12 @@ namespace libp2p::crypto {
2728
/**
2829
* @brief generates new key pair of specified type
2930
* @param key_type key type
31+
* @param rsa_bitness specifies the length of RSA key
3032
* @return new generated key pair of public and private key or error
3133
*/
32-
virtual outcome::result<KeyPair> generateKeys(Key::Type key_type) const = 0;
34+
virtual outcome::result<KeyPair> generateKeys(
35+
Key::Type key_type,
36+
common::RSAKeyType rsa_bitness = common::RSAKeyType::RSA2048) const = 0;
3337

3438
/**
3539
* @brief derives public key from private key
@@ -46,7 +50,8 @@ namespace libp2p::crypto {
4650
* @return signature bytes
4751
*/
4852
virtual outcome::result<Buffer> sign(
49-
gsl::span<uint8_t> message, const PrivateKey &private_key) const = 0;
53+
gsl::span<const uint8_t> message,
54+
const PrivateKey &private_key) const = 0;
5055

5156
/**
5257
* @brief verifies validness of the signature for a given message and public
@@ -56,8 +61,8 @@ namespace libp2p::crypto {
5661
* @param public_key to validate against
5762
* @return true - if the signature matches the message and the public key
5863
*/
59-
virtual outcome::result<bool> verify(gsl::span<uint8_t> message,
60-
gsl::span<uint8_t> signature,
64+
virtual outcome::result<bool> verify(gsl::span<const uint8_t> message,
65+
gsl::span<const uint8_t> signature,
6166
const PublicKey &public_key) const = 0;
6267
/**
6368
* Generate an ephemeral public key and return a function that will

include/libp2p/crypto/crypto_provider/crypto_provider_impl.hpp

Lines changed: 51 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -15,25 +15,38 @@ namespace libp2p::crypto {
1515
namespace ed25519 {
1616
class Ed25519Provider;
1717
}
18+
namespace rsa {
19+
class RsaProvider;
20+
}
21+
namespace ecdsa {
22+
class EcdsaProvider;
23+
}
24+
namespace secp256k1 {
25+
class Secp256k1Provider;
26+
}
1827

1928
class CryptoProviderImpl : public CryptoProvider {
2029
public:
2130
~CryptoProviderImpl() override = default;
2231

2332
explicit CryptoProviderImpl(
2433
std::shared_ptr<random::CSPRNG> random_provider,
25-
std::shared_ptr<ed25519::Ed25519Provider> ed25519_provider);
34+
std::shared_ptr<ed25519::Ed25519Provider> ed25519_provider,
35+
std::shared_ptr<rsa::RsaProvider> rsa_provider,
36+
std::shared_ptr<ecdsa::EcdsaProvider> ecdsa_provider,
37+
std::shared_ptr<secp256k1::Secp256k1Provider> secp256k1_provider);
2638

27-
outcome::result<KeyPair> generateKeys(Key::Type key_type) const override;
39+
outcome::result<KeyPair> generateKeys(
40+
Key::Type key_type, common::RSAKeyType rsa_bitness) const override;
2841

2942
outcome::result<PublicKey> derivePublicKey(
3043
const PrivateKey &private_key) const override;
3144

32-
outcome::result<Buffer> sign(gsl::span<uint8_t> message,
45+
outcome::result<Buffer> sign(gsl::span<const uint8_t> message,
3346
const PrivateKey &private_key) const override;
3447

35-
outcome::result<bool> verify(gsl::span<uint8_t> message,
36-
gsl::span<uint8_t> signature,
48+
outcome::result<bool> verify(gsl::span<const uint8_t> message,
49+
gsl::span<const uint8_t> signature,
3750
const PublicKey &public_key) const override;
3851

3952
outcome::result<EphemeralKeyPair> generateEphemeralKeyPair(
@@ -46,24 +59,47 @@ namespace libp2p::crypto {
4659
private:
4760
void initialize();
4861

49-
// outcome::result<KeyPair> generateRsa(common::RSAKeyType key_type)
50-
// const;
51-
outcome::result<KeyPair> generateEd25519() const;
52-
outcome::result<KeyPair> generateSecp256k1() const;
53-
outcome::result<KeyPair> generateEcdsa() const;
62+
// RSA
63+
outcome::result<KeyPair> generateRsa(common::RSAKeyType rsa_bitness) const;
64+
outcome::result<PublicKey> deriveRsa(const PrivateKey &key) const;
65+
outcome::result<Buffer> signRsa(gsl::span<const uint8_t> message,
66+
const PrivateKey &private_key) const;
67+
outcome::result<bool> verifyRsa(gsl::span<const uint8_t> message,
68+
gsl::span<const uint8_t> signature,
69+
const PublicKey &public_key) const;
5470

71+
// Ed25519
72+
outcome::result<KeyPair> generateEd25519() const;
5573
outcome::result<PublicKey> deriveEd25519(const PrivateKey &key) const;
56-
outcome::result<Buffer> signEd25519(gsl::span<uint8_t> message,
74+
outcome::result<Buffer> signEd25519(gsl::span<const uint8_t> message,
5775
const PrivateKey &private_key) const;
58-
outcome::result<bool> verifyEd25519(gsl::span<uint8_t> message,
59-
gsl::span<uint8_t> signature,
76+
outcome::result<bool> verifyEd25519(gsl::span<const uint8_t> message,
77+
gsl::span<const uint8_t> signature,
6078
const PublicKey &public_key) const;
6179

62-
outcome::result<KeyPair> generateEcdsa256WithCurve(Key::Type key_type,
63-
int curve_nid) const;
80+
// Secp256k1
81+
outcome::result<KeyPair> generateSecp256k1() const;
82+
outcome::result<PublicKey> deriveSecp256k1(const PrivateKey &key) const;
83+
outcome::result<Buffer> signSecp256k1(gsl::span<const uint8_t> message,
84+
const PrivateKey &private_key) const;
85+
outcome::result<bool> verifySecp256k1(gsl::span<const uint8_t> message,
86+
gsl::span<const uint8_t> signature,
87+
const PublicKey &public_key) const;
88+
89+
// ECDSA
90+
outcome::result<KeyPair> generateEcdsa() const;
91+
outcome::result<PublicKey> deriveEcdsa(const PrivateKey &key) const;
92+
outcome::result<Buffer> signEcdsa(gsl::span<const uint8_t> message,
93+
const PrivateKey &private_key) const;
94+
outcome::result<bool> verifyEcdsa(gsl::span<const uint8_t> message,
95+
gsl::span<const uint8_t> signature,
96+
const PublicKey &public_key) const;
6497

6598
std::shared_ptr<random::CSPRNG> random_provider_;
6699
std::shared_ptr<ed25519::Ed25519Provider> ed25519_provider_;
100+
std::shared_ptr<rsa::RsaProvider> rsa_provider_;
101+
std::shared_ptr<ecdsa::EcdsaProvider> ecdsa_provider_;
102+
std::shared_ptr<secp256k1::Secp256k1Provider> secp256k1_provider_;
67103
};
68104
} // namespace libp2p::crypto
69105

include/libp2p/crypto/ecdsa_provider.hpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,22 +17,22 @@ namespace libp2p::crypto::ecdsa {
1717
* @brief Generate private and public keys
1818
* @return ECDSA key pair or error code
1919
*/
20-
virtual outcome::result<KeyPair> GenerateKeyPair() const = 0;
20+
virtual outcome::result<KeyPair> generate() const = 0;
2121

2222
/**
2323
* @brief Generate ECDSA public key from private key
2424
* @param key - ECDSA private key
2525
* @return Generated public key or error code
2626
*/
27-
virtual outcome::result<PublicKey> DerivePublicKey(const PrivateKey &key) const = 0;
27+
virtual outcome::result<PublicKey> derive(const PrivateKey &key) const = 0;
2828

2929
/**
3030
* @brief Create signature for a message
3131
* @param message - data to signing
3232
* @param privateKey - key for signing
3333
* @return ECDSA signature or error code
3434
*/
35-
virtual outcome::result<Signature> Sign(gsl::span<uint8_t> message,
35+
virtual outcome::result<Signature> sign(gsl::span<const uint8_t> message,
3636
const PrivateKey &key) const = 0;
3737

3838
/**
@@ -42,7 +42,7 @@ namespace libp2p::crypto::ecdsa {
4242
* @param publicKey - key for signature verifying
4343
* @return Result of the verification or error code
4444
*/
45-
virtual outcome::result<bool> Verify(gsl::span<uint8_t> message,
45+
virtual outcome::result<bool> verify(gsl::span<const uint8_t> message,
4646
const Signature &signature,
4747
const PublicKey &publicKey) const = 0;
4848

0 commit comments

Comments
 (0)