From 38797f8e192f11644fa4ad6ae30651ada5f777c5 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Mon, 12 Sep 2022 15:07:40 +1000 Subject: [PATCH 1/2] Introduce `NoiseAuthenticated::xx` ctor with X25519 DH key exchange This is the most common way of doing noise in libp2p and thus deserves a convenience ctor. --- Cargo.toml | 2 +- core/tests/transport_upgrade.rs | 10 ++-------- examples/chat-tokio.rs | 10 ++++------ examples/ipfs-private.rs | 5 +---- protocols/dcutr/examples/client.rs | 9 ++++----- protocols/gossipsub/src/lib.rs | 3 +-- protocols/kad/src/behaviour/test.rs | 5 +---- protocols/ping/tests/ping.rs | 5 +---- protocols/relay/examples/relay_v2.rs | 9 ++++----- protocols/rendezvous/tests/harness.rs | 9 ++------- protocols/request-response/tests/ping.rs | 8 +++----- src/lib.rs | 12 ++---------- transports/noise/CHANGELOG.md | 7 +++++++ transports/noise/Cargo.toml | 2 +- transports/noise/src/lib.rs | 18 +++++++++++++++--- transports/noise/tests/smoke.rs | 6 +++--- 16 files changed, 52 insertions(+), 68 deletions(-) diff --git a/Cargo.toml b/Cargo.toml index 89e63a4e5cd..9f8107869f0 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -88,7 +88,7 @@ libp2p-identify = { version = "0.39.0", path = "protocols/identify", optional = libp2p-kad = { version = "0.40.0", path = "protocols/kad", optional = true } libp2p-metrics = { version = "0.9.0", path = "misc/metrics", optional = true } libp2p-mplex = { version = "0.36.0", path = "muxers/mplex", optional = true } -libp2p-noise = { version = "0.39.0", path = "transports/noise", optional = true } +libp2p-noise = { version = "0.39.1", path = "transports/noise", optional = true } libp2p-ping = { version = "0.39.0", path = "protocols/ping", optional = true } libp2p-plaintext = { version = "0.36.0", path = "transports/plaintext", optional = true } libp2p-pnet = { version = "0.22.0", path = "transports/pnet", optional = true } diff --git a/core/tests/transport_upgrade.rs b/core/tests/transport_upgrade.rs index 723a04b0780..dac84534369 100644 --- a/core/tests/transport_upgrade.rs +++ b/core/tests/transport_upgrade.rs @@ -79,12 +79,9 @@ where fn upgrade_pipeline() { let listener_keys = identity::Keypair::generate_ed25519(); let listener_id = listener_keys.public().to_peer_id(); - let listener_noise_keys = noise::Keypair::::new() - .into_authentic(&listener_keys) - .unwrap(); let mut listener_transport = MemoryTransport::default() .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(listener_noise_keys).into_authenticated()) + .authenticate(noise::NoiseAuthenticated::xx(&listener_keys).unwrap()) .apply(HelloUpgrade {}) .apply(HelloUpgrade {}) .apply(HelloUpgrade {}) @@ -93,12 +90,9 @@ fn upgrade_pipeline() { let dialer_keys = identity::Keypair::generate_ed25519(); let dialer_id = dialer_keys.public().to_peer_id(); - let dialer_noise_keys = noise::Keypair::::new() - .into_authentic(&dialer_keys) - .unwrap(); let mut dialer_transport = MemoryTransport::default() .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(dialer_noise_keys).into_authenticated()) + .authenticate(noise::NoiseAuthenticated::xx(&dialer_keys).unwrap()) .apply(HelloUpgrade {}) .apply(HelloUpgrade {}) .apply(HelloUpgrade {}) diff --git a/examples/chat-tokio.rs b/examples/chat-tokio.rs index f82d30934c9..5ee00f9eedc 100644 --- a/examples/chat-tokio.rs +++ b/examples/chat-tokio.rs @@ -70,16 +70,14 @@ async fn main() -> Result<(), Box> { let peer_id = PeerId::from(id_keys.public()); println!("Local peer id: {:?}", peer_id); - // Create a keypair for authenticated encryption of the transport. - let noise_keys = noise::Keypair::::new() - .into_authentic(&id_keys) - .expect("Signing libp2p-noise static DH keypair failed."); - // Create a tokio-based TCP transport use noise for authenticated // encryption and Mplex for multiplexing of substreams on a TCP stream. let transport = TokioTcpTransport::new(GenTcpConfig::default().nodelay(true)) .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate( + noise::NoiseAuthenticated::xx(&id_keys) + .expect("Signing libp2p-noise static DH keypair failed."), + ) .multiplex(mplex::MplexConfig::new()) .boxed(); diff --git a/examples/ipfs-private.rs b/examples/ipfs-private.rs index 93e73cd5976..c0596816919 100644 --- a/examples/ipfs-private.rs +++ b/examples/ipfs-private.rs @@ -57,10 +57,7 @@ pub fn build_transport( key_pair: identity::Keypair, psk: Option, ) -> transport::Boxed<(PeerId, StreamMuxerBox)> { - let noise_keys = noise::Keypair::::new() - .into_authentic(&key_pair) - .unwrap(); - let noise_config = noise::NoiseConfig::xx(noise_keys).into_authenticated(); + let noise_config = noise::NoiseAuthenticated::xx(&key_pair).unwrap(); let yamux_config = YamuxConfig::default(); let base_transport = TcpTransport::new(GenTcpConfig::default().nodelay(true)); diff --git a/protocols/dcutr/examples/client.rs b/protocols/dcutr/examples/client.rs index dd73b7d3ac3..54448ff635d 100644 --- a/protocols/dcutr/examples/client.rs +++ b/protocols/dcutr/examples/client.rs @@ -89,10 +89,6 @@ fn main() -> Result<(), Box> { let (relay_transport, client) = Client::new_transport_and_behaviour(local_peer_id); - let noise_keys = noise::Keypair::::new() - .into_authentic(&local_key) - .expect("Signing libp2p-noise static DH keypair failed."); - let transport = OrTransport::new( relay_transport, block_on(DnsConfig::system(TcpTransport::new( @@ -101,7 +97,10 @@ fn main() -> Result<(), Box> { .unwrap(), ) .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate( + noise::NoiseAuthenticated::xx(&local_key) + .expect("Signing libp2p-noise static DH keypair failed."), + ) .multiplex(libp2p_yamux::YamuxConfig::default()) .boxed(); diff --git a/protocols/gossipsub/src/lib.rs b/protocols/gossipsub/src/lib.rs index d86263aace4..4022a23185d 100644 --- a/protocols/gossipsub/src/lib.rs +++ b/protocols/gossipsub/src/lib.rs @@ -97,10 +97,9 @@ //! //! // Set up an encrypted TCP Transport over the Mplex //! // This is test transport (memory). -//! let noise_keys = libp2p_noise::Keypair::::new().into_authentic(&local_key).unwrap(); //! let transport = MemoryTransport::default() //! .upgrade(libp2p_core::upgrade::Version::V1) -//! .authenticate(libp2p_noise::NoiseConfig::xx(noise_keys).into_authenticated()) +//! .authenticate(libp2p_noise::NoiseAuthenticated::xx(&local_key).unwrap()) //! .multiplex(libp2p_mplex::MplexConfig::new()) //! .boxed(); //! diff --git a/protocols/kad/src/behaviour/test.rs b/protocols/kad/src/behaviour/test.rs index 1f67be5a19d..aab7fa0ef28 100644 --- a/protocols/kad/src/behaviour/test.rs +++ b/protocols/kad/src/behaviour/test.rs @@ -56,12 +56,9 @@ fn build_node() -> (Multiaddr, TestSwarm) { fn build_node_with_config(cfg: KademliaConfig) -> (Multiaddr, TestSwarm) { let local_key = identity::Keypair::generate_ed25519(); let local_public_key = local_key.public(); - let noise_keys = noise::Keypair::::new() - .into_authentic(&local_key) - .unwrap(); let transport = MemoryTransport::default() .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate(noise::NoiseAuthenticated::xx(&local_key).unwrap()) .multiplex(yamux::YamuxConfig::default()) .boxed(); diff --git a/protocols/ping/tests/ping.rs b/protocols/ping/tests/ping.rs index ac45949ced7..2f75c09fb3d 100644 --- a/protocols/ping/tests/ping.rs +++ b/protocols/ping/tests/ping.rs @@ -243,14 +243,11 @@ fn unsupported_doesnt_fail() { fn mk_transport(muxer: MuxerChoice) -> (PeerId, transport::Boxed<(PeerId, StreamMuxerBox)>) { let id_keys = identity::Keypair::generate_ed25519(); let peer_id = id_keys.public().to_peer_id(); - let noise_keys = noise::Keypair::::new() - .into_authentic(&id_keys) - .unwrap(); ( peer_id, TcpTransport::new(GenTcpConfig::default().nodelay(true)) .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate(noise::NoiseAuthenticated::xx(&id_keys).unwrap()) .multiplex(match muxer { MuxerChoice::Yamux => upgrade::EitherUpgrade::A(yamux::YamuxConfig::default()), MuxerChoice::Mplex => upgrade::EitherUpgrade::B(mplex::MplexConfig::default()), diff --git a/protocols/relay/examples/relay_v2.rs b/protocols/relay/examples/relay_v2.rs index 25d0bb7fc94..b89c88b2829 100644 --- a/protocols/relay/examples/relay_v2.rs +++ b/protocols/relay/examples/relay_v2.rs @@ -48,13 +48,12 @@ fn main() -> Result<(), Box> { let tcp_transport = TcpTransport::default(); - let noise_keys = noise::Keypair::::new() - .into_authentic(&local_key) - .expect("Signing libp2p-noise static DH keypair failed."); - let transport = tcp_transport .upgrade(upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate( + noise::NoiseAuthenticated::xx(&local_key) + .expect("Signing libp2p-noise static DH keypair failed."), + ) .multiplex(libp2p_yamux::YamuxConfig::default()) .boxed(); diff --git a/protocols/rendezvous/tests/harness.rs b/protocols/rendezvous/tests/harness.rs index 555a5476bab..30dace245ff 100644 --- a/protocols/rendezvous/tests/harness.rs +++ b/protocols/rendezvous/tests/harness.rs @@ -27,7 +27,7 @@ use libp2p::core::transport::MemoryTransport; use libp2p::core::upgrade::SelectUpgrade; use libp2p::core::{identity, Multiaddr, PeerId, Transport}; use libp2p::mplex::MplexConfig; -use libp2p::noise::{Keypair, NoiseConfig, X25519Spec}; +use libp2p::noise::NoiseAuthenticated; use libp2p::swarm::{AddressScore, NetworkBehaviour, Swarm, SwarmBuilder, SwarmEvent}; use libp2p::yamux::YamuxConfig; use std::fmt::Debug; @@ -43,14 +43,9 @@ where let identity = identity::Keypair::generate_ed25519(); let peer_id = PeerId::from(identity.public()); - let dh_keys = Keypair::::new() - .into_authentic(&identity) - .expect("failed to create dh_keys"); - let noise = NoiseConfig::xx(dh_keys).into_authenticated(); - let transport = MemoryTransport::default() .upgrade(Version::V1) - .authenticate(noise) + .authenticate(NoiseAuthenticated::xx(&identity).unwrap()) .multiplex(SelectUpgrade::new( YamuxConfig::default(), MplexConfig::new(), diff --git a/protocols/request-response/tests/ping.rs b/protocols/request-response/tests/ping.rs index 8cbc06e7444..bfb8641c106 100644 --- a/protocols/request-response/tests/ping.rs +++ b/protocols/request-response/tests/ping.rs @@ -29,7 +29,7 @@ use libp2p_core::{ upgrade::{self, read_length_prefixed, write_length_prefixed}, Multiaddr, PeerId, }; -use libp2p_noise::{Keypair, NoiseConfig, X25519Spec}; +use libp2p_noise::NoiseAuthenticated; use libp2p_request_response::*; use libp2p_swarm::{Swarm, SwarmEvent}; use libp2p_tcp::{GenTcpConfig, TcpTransport}; @@ -295,14 +295,12 @@ fn emits_inbound_connection_closed_if_channel_is_dropped() { fn mk_transport() -> (PeerId, transport::Boxed<(PeerId, StreamMuxerBox)>) { let id_keys = identity::Keypair::generate_ed25519(); let peer_id = id_keys.public().to_peer_id(); - let noise_keys = Keypair::::new() - .into_authentic(&id_keys) - .unwrap(); + ( peer_id, TcpTransport::new(GenTcpConfig::default().nodelay(true)) .upgrade(upgrade::Version::V1) - .authenticate(NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate(NoiseAuthenticated::xx(&id_keys).unwrap()) .multiplex(libp2p_yamux::YamuxConfig::default()) .boxed(), ) diff --git a/src/lib.rs b/src/lib.rs index 3ed00408cb5..96a197cf516 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -217,13 +217,9 @@ pub async fn development_transport( dns_tcp.or_transport(ws_dns_tcp) }; - let noise_keys = noise::Keypair::::new() - .into_authentic(&keypair) - .expect("Signing libp2p-noise static DH keypair failed."); - Ok(transport .upgrade(core::upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate(noise::NoiseAuthenticated::xx(&keypair).unwrap()) .multiplex(core::upgrade::SelectUpgrade::new( yamux::YamuxConfig::default(), mplex::MplexConfig::default(), @@ -277,13 +273,9 @@ pub fn tokio_development_transport( dns_tcp.or_transport(ws_dns_tcp) }; - let noise_keys = noise::Keypair::::new() - .into_authentic(&keypair) - .expect("Signing libp2p-noise static DH keypair failed."); - Ok(transport .upgrade(core::upgrade::Version::V1) - .authenticate(noise::NoiseConfig::xx(noise_keys).into_authenticated()) + .authenticate(noise::NoiseAuthenticated::xx(&keypair).unwrap()) .multiplex(core::upgrade::SelectUpgrade::new( yamux::YamuxConfig::default(), mplex::MplexConfig::default(), diff --git a/transports/noise/CHANGELOG.md b/transports/noise/CHANGELOG.md index de2c1034a9e..d0becf116ce 100644 --- a/transports/noise/CHANGELOG.md +++ b/transports/noise/CHANGELOG.md @@ -1,3 +1,10 @@ +# 0.39.1 [unreleased] + +- Introduce `NoiseAuthenticated::xx` constructor, assuming a X25519 DH key exchange. An XX key exchange and X25519 keys + are the most common way of using noise in libp2p and thus deserve a convenience constructor. See [PR XXXX]. + +[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX + # 0.39.0 - Update to `libp2p-core` `v0.36.0`. diff --git a/transports/noise/Cargo.toml b/transports/noise/Cargo.toml index 5ee9330818d..8fef520cb9a 100644 --- a/transports/noise/Cargo.toml +++ b/transports/noise/Cargo.toml @@ -3,7 +3,7 @@ name = "libp2p-noise" edition = "2021" rust-version = "1.56.1" description = "Cryptographic handshake protocol using the noise framework." -version = "0.39.0" +version = "0.39.1" authors = ["Parity Technologies "] license = "MIT" repository = "https://github.com/libp2p/rust-libp2p" diff --git a/transports/noise/src/lib.rs b/transports/noise/src/lib.rs index ee609fd028d..1712176d7ef 100644 --- a/transports/noise/src/lib.rs +++ b/transports/noise/src/lib.rs @@ -41,12 +41,11 @@ //! ``` //! use libp2p_core::{identity, Transport, upgrade}; //! use libp2p_tcp::TcpTransport; -//! use libp2p_noise::{Keypair, X25519Spec, NoiseConfig}; +//! use libp2p_noise::{Keypair, X25519Spec, NoiseAuthenticated}; //! //! # fn main() { //! let id_keys = identity::Keypair::generate_ed25519(); -//! let dh_keys = Keypair::::new().into_authentic(&id_keys).unwrap(); -//! let noise = NoiseConfig::xx(dh_keys).into_authenticated(); +//! let noise = NoiseAuthenticated::xx(&id_keys).unwrap(); //! let builder = TcpTransport::default().upgrade(upgrade::Version::V1).authenticate(noise); //! // let transport = builder.multiplex(...); //! # } @@ -357,6 +356,19 @@ pub struct NoiseAuthenticated { config: NoiseConfig, } +impl NoiseAuthenticated { + /// Create a new [`NoiseAuthenticated`] for the `XX` handshake pattern using X25519 DH keys. + /// + /// For now, this is the only combination that is guaranteed to be compatible with other libp2p implementations. + pub fn xx(id_keys: &identity::Keypair) -> Result { + let dh_keys = Keypair::::new(); + let noise_keys = dh_keys.into_authentic(id_keys)?; + let config = NoiseConfig::xx(noise_keys); + + Ok(config.into_authenticated()) + } +} + impl UpgradeInfo for NoiseAuthenticated where NoiseConfig: UpgradeInfo, diff --git a/transports/noise/tests/smoke.rs b/transports/noise/tests/smoke.rs index 0148d03b4d6..14d09621dd9 100644 --- a/transports/noise/tests/smoke.rs +++ b/transports/noise/tests/smoke.rs @@ -27,7 +27,8 @@ use libp2p_core::identity; use libp2p_core::transport::{self, Transport}; use libp2p_core::upgrade::{self, apply_inbound, apply_outbound, Negotiated}; use libp2p_noise::{ - Keypair, NoiseConfig, NoiseError, NoiseOutput, RemoteIdentity, X25519Spec, X25519, + Keypair, NoiseAuthenticated, NoiseConfig, NoiseError, NoiseOutput, RemoteIdentity, X25519Spec, + X25519, }; use libp2p_tcp::TcpTransport; use log::info; @@ -39,8 +40,7 @@ fn core_upgrade_compat() { // Tests API compaibility with the libp2p-core upgrade API, // i.e. if it compiles, the "test" is considered a success. let id_keys = identity::Keypair::generate_ed25519(); - let dh_keys = Keypair::::new().into_authentic(&id_keys).unwrap(); - let noise = NoiseConfig::xx(dh_keys).into_authenticated(); + let noise = NoiseAuthenticated::xx(&id_keys).unwrap(); let _ = TcpTransport::default() .upgrade(upgrade::Version::V1) .authenticate(noise); From 48c3b0df2dd680026b86458391bf8cb023c30de8 Mon Sep 17 00:00:00 2001 From: Thomas Eizinger Date: Fri, 16 Sep 2022 10:50:44 +1000 Subject: [PATCH 2/2] Apply suggestions from code review Co-authored-by: Max Inden --- transports/noise/CHANGELOG.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/transports/noise/CHANGELOG.md b/transports/noise/CHANGELOG.md index d0becf116ce..1416aab4e30 100644 --- a/transports/noise/CHANGELOG.md +++ b/transports/noise/CHANGELOG.md @@ -1,9 +1,9 @@ # 0.39.1 [unreleased] - Introduce `NoiseAuthenticated::xx` constructor, assuming a X25519 DH key exchange. An XX key exchange and X25519 keys - are the most common way of using noise in libp2p and thus deserve a convenience constructor. See [PR XXXX]. + are the most common way of using noise in libp2p and thus deserve a convenience constructor. See [PR 2887]. -[PR XXXX]: https://github.com/libp2p/rust-libp2p/pull/XXXX +[PR 2887]: https://github.com/libp2p/rust-libp2p/pull/2887 # 0.39.0