Skip to content

Commit

Permalink
Move into_{responder,initiator} to ProtocolParams
Browse files Browse the repository at this point in the history
This allows us to reuse them in all places.
  • Loading branch information
thomaseizinger committed Sep 26, 2022
1 parent 5adfe25 commit ae18dd7
Show file tree
Hide file tree
Showing 2 changed files with 117 additions and 113 deletions.
140 changes: 30 additions & 110 deletions transports/noise/src/lib.rs
Expand Up @@ -69,7 +69,6 @@ use crate::handshake::State;
use crate::io::handshake;
use futures::prelude::*;
use libp2p_core::{identity, InboundUpgrade, OutboundUpgrade, PeerId, UpgradeInfo};
use snow::HandshakeState;
use std::pin::Pin;
use zeroize::Zeroize;

Expand Down Expand Up @@ -110,35 +109,6 @@ impl<H, C: Zeroize, R> NoiseConfig<H, C, R> {
}
}

impl<H, C, R> NoiseConfig<H, C, R>
where
C: Zeroize + AsRef<[u8]>,
{
fn into_responder(self) -> Result<HandshakeState, NoiseError> {
let state = self
.params
.into_builder()
.prologue(self.prologue.as_ref())
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_responder()
.map_err(NoiseError::from)?;

Ok(state)
}

fn into_initiator(self) -> Result<HandshakeState, NoiseError> {
let state = self
.params
.into_builder()
.prologue(self.prologue.as_ref())
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_initiator()
.map_err(NoiseError::from)?;

Ok(state)
}
}

impl<C> NoiseConfig<IX, C>
where
C: Protocol<C> + Zeroize,
Expand Down Expand Up @@ -237,11 +207,11 @@ where

fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future {
async move {
let session = self
.params
.into_builder()
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_responder()?;
let session = self.params.into_responder(
&self.prologue,
self.dh_keys.dh_keypair().secret(),
None,
)?;

let mut state = State::new(
socket,
Expand Down Expand Up @@ -278,11 +248,11 @@ where

fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future {
async move {
let session = self
.params
.into_builder()
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_initiator()?;
let session = self.params.into_responder(
&self.prologue,
self.dh_keys.dh_keypair().secret(),
None,
)?;

let mut state = State::new(
socket,
Expand Down Expand Up @@ -323,11 +293,11 @@ where

fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future {
async move {
let session = self
.params
.into_builder()
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_responder()?;
let session = self.params.into_responder(
&self.prologue,
self.dh_keys.dh_keypair().secret(),
None,
)?;

let mut state = State::new(
socket,
Expand Down Expand Up @@ -369,11 +339,11 @@ where

fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future {
async move {
let session = self
.params
.into_builder()
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_initiator()?;
let session = self.params.into_responder(
&self.prologue,
self.dh_keys.dh_keypair().secret(),
None,
)?;

let mut state = State::new(
socket,
Expand Down Expand Up @@ -414,11 +384,11 @@ where

fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future {
async move {
let session = self
.params
.into_builder()
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.build_responder()?;
let session = self.params.into_responder(
&self.prologue,
self.dh_keys.dh_keypair().secret(),
None,
)?;

let mut state = State::new(
socket,
Expand Down Expand Up @@ -458,13 +428,11 @@ where

fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future {
async move {
let session = self
.params
.into_builder()
.prologue(self.prologue.as_ref())
.local_private_key(self.dh_keys.dh_keypair().secret().as_ref())
.remote_public_key(self.remote.0.as_ref())
.build_initiator()?;
let session = self.params.into_initiator(
&self.prologue,
self.dh_keys.dh_keypair().secret(),
Some(&self.remote.0),
)?;

let mut state = State::new(
socket,
Expand Down Expand Up @@ -587,51 +555,3 @@ pub struct LegacyConfig {
/// libp2p implementations.
pub recv_legacy_handshake: bool,
}

#[cfg(test)]
mod tests {
use super::*;

#[test]
fn handshake_hashes_disagree_if_prologue_differs() {
let alice = new_xx_config()
.with_prologue(b"alice prologue".to_vec())
.into_initiator()
.unwrap();
let bob = new_xx_config()
.with_prologue(b"bob prologue".to_vec())
.into_responder()
.unwrap();

let alice_handshake_hash = alice.get_handshake_hash();
let bob_handshake_hash = bob.get_handshake_hash();

assert_ne!(alice_handshake_hash, bob_handshake_hash)
}

#[test]
fn handshake_hashes_agree_if_prologue_is_the_same() {
let alice = new_xx_config()
.with_prologue(b"shared knowledge".to_vec())
.into_initiator()
.unwrap();
let bob = new_xx_config()
.with_prologue(b"shared knowledge".to_vec())
.into_responder()
.unwrap();

let alice_handshake_hash = alice.get_handshake_hash();
let bob_handshake_hash = bob.get_handshake_hash();

assert_eq!(alice_handshake_hash, bob_handshake_hash)
}

fn new_xx_config() -> NoiseConfig<XX, X25519> {
let dh_keys = Keypair::<X25519>::new();
let noise_keys = dh_keys
.into_authentic(&identity::Keypair::generate_ed25519())
.unwrap();

NoiseConfig::xx(noise_keys)
}
}
90 changes: 87 additions & 3 deletions transports/noise/src/protocol.rs
Expand Up @@ -34,9 +34,56 @@ use zeroize::Zeroize;
pub struct ProtocolParams(snow::params::NoiseParams);

impl ProtocolParams {
/// Turn the protocol parameters into a session builder.
pub(crate) fn into_builder(self) -> snow::Builder<'static> {
snow::Builder::with_resolver(self.0, Box::new(Resolver))
pub(crate) fn into_responder<C>(
self,
prologue: &[u8],
private_key: &SecretKey<C>,
remote_public_key: Option<&PublicKey<C>>,
) -> Result<snow::HandshakeState, snow::Error>
where
C: Zeroize + AsRef<[u8]> + Protocol<C>,
{
let state = self
.into_builder(prologue, private_key, remote_public_key)
.build_responder()?;

Ok(state)
}

pub(crate) fn into_initiator<C>(
self,
prologue: &[u8],
private_key: &SecretKey<C>,
remote_public_key: Option<&PublicKey<C>>,
) -> Result<snow::HandshakeState, snow::Error>
where
C: Zeroize + AsRef<[u8]> + Protocol<C>,
{
let state = self
.into_builder(prologue, private_key, remote_public_key)
.build_initiator()?;

Ok(state)
}

fn into_builder<'b, C>(
self,
prologue: &'b [u8],
private_key: &'b SecretKey<C>,
remote_public_key: Option<&'b PublicKey<C>>,
) -> snow::Builder<'b>
where
C: Zeroize + AsRef<[u8]> + Protocol<C>,
{
let mut builder = snow::Builder::with_resolver(self.0, Box::new(Resolver))
.prologue(prologue.as_ref())
.local_private_key(private_key.as_ref());

if let Some(remote_public_key) = remote_public_key {
builder = builder.remote_public_key(remote_public_key.as_ref());
}

builder
}
}

Expand Down Expand Up @@ -284,3 +331,40 @@ impl rand::RngCore for Rng {
impl rand::CryptoRng for Rng {}

impl snow::types::Random for Rng {}

#[cfg(test)]
mod tests {
use super::*;
use crate::X25519;

#[test]
fn handshake_hashes_disagree_if_prologue_differs() {
let alice = xx_builder(b"alice prologue").build_initiator().unwrap();
let bob = xx_builder(b"bob prologue").build_responder().unwrap();

let alice_handshake_hash = alice.get_handshake_hash();
let bob_handshake_hash = bob.get_handshake_hash();

assert_ne!(alice_handshake_hash, bob_handshake_hash)
}

#[test]
fn handshake_hashes_agree_if_prologue_is_the_same() {
let alice = xx_builder(b"shared knowledge").build_initiator().unwrap();
let bob = xx_builder(b"shared knowledge").build_responder().unwrap();

let alice_handshake_hash = alice.get_handshake_hash();
let bob_handshake_hash = bob.get_handshake_hash();

assert_eq!(alice_handshake_hash, bob_handshake_hash)
}

fn xx_builder(prologue: &'static [u8]) -> snow::Builder<'static> {
X25519::params_xx().into_builder(prologue, &TEST_KEY.secret(), None)
}

// Hack to work around borrow-checker.
lazy_static::lazy_static! {
static ref TEST_KEY: Keypair<X25519> = Keypair::<X25519>::new();
}
}

0 comments on commit ae18dd7

Please sign in to comment.