feat(noise): deprecate non-compliant implementation (#3227)

For the last [two years](https://github.com/libp2p/rust-libp2p/blob/master/CHANGELOG.md#version-0190-2020-05-18), we have been carrying around a non-compliant implementation of the noise protocol for libp2p. It is time to follow through on the announcement in that changelog entry and deprecate it. Users should use the spec compliant implementation instead.

1. This will reduce the maintenance effort of our codebase.
2. We will improve compile-times because we no longer need to depend on `libsodium` to test cryptography that is only part of the non-compliant implementation.
3. It will simplify usage of `rust-libp2p` because users cannot accidentally choose the wrong implementation.
This commit is contained in:
Thomas Eizinger
2022-12-20 00:28:07 +11:00
committed by GitHub
parent fbd4192e2a
commit 5458446205
7 changed files with 49 additions and 70 deletions

View File

@ -1,3 +1,9 @@
# 0.41.1 [unreleased]
- Deprecate non-compliant noise implementation. We intend to remove it in a future release without replacement. See [PR 3227].
[PR 3227]: https://github.com/libp2p/rust-libp2p/pull/3227
# 0.41.0
- Remove `prost::Error` from public API. See [PR 3058].

View File

@ -3,7 +3,7 @@ name = "libp2p-noise"
edition = "2021"
rust-version = "1.60.0"
description = "Cryptographic handshake protocol using the noise framework."
version = "0.41.0"
version = "0.41.1"
authors = ["Parity Technologies <admin@parity.io>"]
license = "MIT"
repository = "https://github.com/libp2p/rust-libp2p"

View File

@ -60,7 +60,9 @@ mod protocol;
pub use io::handshake::RemoteIdentity;
pub use io::NoiseOutput;
pub use protocol::{x25519::X25519, x25519_spec::X25519Spec};
#[allow(deprecated)]
pub use protocol::x25519::X25519;
pub use protocol::x25519_spec::X25519Spec;
pub use protocol::{AuthenticKeypair, Keypair, KeypairIdentity, PublicKey, SecretKey};
pub use protocol::{Protocol, ProtocolParams, IK, IX, XX};

View File

@ -245,7 +245,7 @@ impl snow::resolvers::CryptoResolver for Resolver {
fn resolve_dh(&self, choice: &snow::params::DHChoice) -> Option<Box<dyn snow::types::Dh>> {
if let snow::params::DHChoice::Curve25519 = choice {
Some(Box::new(Keypair::<x25519::X25519>::default()))
Some(Box::new(Keypair::<x25519_spec::X25519Spec>::default()))
} else {
None
}
@ -308,7 +308,7 @@ impl snow::types::Random for Rng {}
#[cfg(test)]
mod tests {
use super::*;
use crate::X25519;
use crate::X25519Spec;
use once_cell::sync::Lazy;
#[test]
@ -334,9 +334,9 @@ mod tests {
}
fn xx_builder(prologue: &'static [u8]) -> snow::Builder<'static> {
X25519::params_xx().into_builder(prologue, TEST_KEY.secret(), None)
X25519Spec::params_xx().into_builder(prologue, TEST_KEY.secret(), None)
}
// Hack to work around borrow-checker.
static TEST_KEY: Lazy<Keypair<X25519>> = Lazy::new(Keypair::<X25519>::new);
static TEST_KEY: Lazy<Keypair<X25519Spec>> = Lazy::new(Keypair::<X25519Spec>::new);
}

View File

@ -23,6 +23,8 @@
//! **Note**: This set of protocols is not interoperable with other
//! libp2p implementations.
#![allow(deprecated)]
use crate::{NoiseConfig, NoiseError, Protocol, ProtocolParams};
use curve25519_dalek::edwards::CompressedEdwardsY;
use libp2p_core::UpgradeInfo;
@ -56,6 +58,10 @@ static PARAMS_XX: Lazy<ProtocolParams> = Lazy::new(|| {
/// A X25519 key.
#[derive(Clone)]
#[deprecated(
since = "0.41.1",
note = "Will be removed because it is not compliant with the official libp2p specification. Use `X25519Spec` instead."
)]
pub struct X25519([u8; 32]);
impl AsRef<[u8]> for X25519 {
@ -135,15 +141,6 @@ impl Protocol<X25519> for X25519 {
}
impl Keypair<X25519> {
/// An "empty" keypair as a starting state for DH computations in `snow`,
/// which get manipulated through the `snow::types::Dh` interface.
pub(super) fn default() -> Self {
Keypair {
secret: SecretKey(X25519([0u8; 32])),
public: PublicKey(X25519([0u8; 32])),
}
}
/// Create a new X25519 keypair.
pub fn new() -> Keypair<X25519> {
let mut sk_bytes = [0u8; 32];

View File

@ -29,7 +29,7 @@ use rand::Rng;
use x25519_dalek::{x25519, X25519_BASEPOINT_BYTES};
use zeroize::Zeroize;
use super::{x25519::X25519, *};
use super::*;
/// Prefix of static key signatures for domain separation.
const STATIC_KEY_DOMAIN: &str = "noise-libp2p-static-key:";
@ -51,6 +51,15 @@ impl Zeroize for X25519Spec {
}
impl Keypair<X25519Spec> {
/// An "empty" keypair as a starting state for DH computations in `snow`,
/// which get manipulated through the `snow::types::Dh` interface.
pub(super) fn default() -> Self {
Keypair {
secret: SecretKey(X25519Spec([0u8; 32])),
public: PublicKey(X25519Spec([0u8; 32])),
}
}
/// Create a new X25519 keypair.
pub fn new() -> Keypair<X25519Spec> {
let mut sk_bytes = [0u8; 32];
@ -110,15 +119,18 @@ impl<R> UpgradeInfo for NoiseConfig<IK, X25519Spec, R> {
/// interoperable with other libp2p implementations.
impl Protocol<X25519Spec> for X25519Spec {
fn params_ik() -> ProtocolParams {
X25519::params_ik()
#[allow(deprecated)]
x25519::X25519::params_ik()
}
fn params_ix() -> ProtocolParams {
X25519::params_ix()
#[allow(deprecated)]
x25519::X25519::params_ix()
}
fn params_xx() -> ProtocolParams {
X25519::params_xx()
#[allow(deprecated)]
x25519::X25519::params_xx()
}
fn public_from_bytes(bytes: &[u8]) -> Result<PublicKey<X25519Spec>, NoiseError> {

View File

@ -28,7 +28,6 @@ use libp2p_core::upgrade::{apply_inbound, apply_outbound, Negotiated};
use libp2p_core::{identity, transport, upgrade};
use libp2p_noise::{
Keypair, NoiseAuthenticated, NoiseConfig, NoiseError, NoiseOutput, RemoteIdentity, X25519Spec,
X25519,
};
use libp2p_tcp as tcp;
use log::info;
@ -47,7 +46,7 @@ fn core_upgrade_compat() {
}
#[test]
fn xx_spec() {
fn xx() {
let _ = env_logger::try_init();
fn prop(mut messages: Vec<Message>) -> bool {
messages.truncate(5);
@ -95,51 +94,6 @@ fn xx_spec() {
.quickcheck(prop as fn(Vec<Message>) -> bool)
}
#[test]
fn xx() {
let _ = env_logger::try_init();
fn prop(mut messages: Vec<Message>) -> bool {
messages.truncate(5);
let server_id = identity::Keypair::generate_ed25519();
let client_id = identity::Keypair::generate_ed25519();
let server_id_public = server_id.public();
let client_id_public = client_id.public();
let server_dh = Keypair::<X25519>::new().into_authentic(&server_id).unwrap();
let server_transport = tcp::async_io::Transport::default()
.and_then(move |output, endpoint| {
upgrade::apply(
output,
NoiseConfig::xx(server_dh),
endpoint,
upgrade::Version::V1,
)
})
.and_then(move |out, _| expect_identity(out, &client_id_public))
.boxed();
let client_dh = Keypair::<X25519>::new().into_authentic(&client_id).unwrap();
let client_transport = tcp::async_io::Transport::default()
.and_then(move |output, endpoint| {
upgrade::apply(
output,
NoiseConfig::xx(client_dh),
endpoint,
upgrade::Version::V1,
)
})
.and_then(move |out, _| expect_identity(out, &server_id_public))
.boxed();
run(server_transport, client_transport, messages);
true
}
QuickCheck::new()
.max_tests(30)
.quickcheck(prop as fn(Vec<Message>) -> bool)
}
#[test]
fn ix() {
let _ = env_logger::try_init();
@ -151,7 +105,9 @@ fn ix() {
let server_id_public = server_id.public();
let client_id_public = client_id.public();
let server_dh = Keypair::<X25519>::new().into_authentic(&server_id).unwrap();
let server_dh = Keypair::<X25519Spec>::new()
.into_authentic(&server_id)
.unwrap();
let server_transport = tcp::async_io::Transport::default()
.and_then(move |output, endpoint| {
upgrade::apply(
@ -164,7 +120,9 @@ fn ix() {
.and_then(move |out, _| expect_identity(out, &client_id_public))
.boxed();
let client_dh = Keypair::<X25519>::new().into_authentic(&client_id).unwrap();
let client_dh = Keypair::<X25519Spec>::new()
.into_authentic(&client_id)
.unwrap();
let client_transport = tcp::async_io::Transport::default()
.and_then(move |output, endpoint| {
upgrade::apply(
@ -196,7 +154,9 @@ fn ik_xx() {
let client_id = identity::Keypair::generate_ed25519();
let client_id_public = client_id.public();
let server_dh = Keypair::<X25519>::new().into_authentic(&server_id).unwrap();
let server_dh = Keypair::<X25519Spec>::new()
.into_authentic(&server_id)
.unwrap();
let server_dh_public = server_dh.public_dh_key().clone();
let server_transport = tcp::async_io::Transport::default()
.and_then(move |output, endpoint| {
@ -213,7 +173,9 @@ fn ik_xx() {
.and_then(move |out, _| expect_identity(out, &client_id_public))
.boxed();
let client_dh = Keypair::<X25519>::new().into_authentic(&client_id).unwrap();
let client_dh = Keypair::<X25519Spec>::new()
.into_authentic(&client_id)
.unwrap();
let server_id_public2 = server_id_public.clone();
let client_transport = tcp::async_io::Transport::default()
.and_then(move |output, endpoint| {