mod error;
mod io;
mod protocol;
pub use error::NoiseError;
pub use io::NoiseOutput;
pub use io::handshake::{Handshake, RemoteIdentity, IdentityExchange};
pub use protocol::{Keypair, AuthenticKeypair, KeypairIdentity, PublicKey, SecretKey};
pub use protocol::{Protocol, ProtocolParams, x25519::X25519, IX, IK, XX};
use libp2p_core::{identity, UpgradeInfo, InboundUpgrade, OutboundUpgrade, upgrade::Negotiated};
use tokio_io::{AsyncRead, AsyncWrite};
use zeroize::Zeroize;
#[derive(Clone)]
pub struct NoiseConfig<P, C: Zeroize, R = ()> {
dh_keys: AuthenticKeypair<C>,
params: ProtocolParams,
remote: R,
_marker: std::marker::PhantomData<P>
}
impl<C> NoiseConfig<IX, C>
where
C: Protocol<C> + Zeroize
{
pub fn ix(dh_keys: AuthenticKeypair<C>) -> Self {
NoiseConfig {
dh_keys,
params: C::params_ix(),
remote: (),
_marker: std::marker::PhantomData
}
}
}
impl<C> NoiseConfig<XX, C>
where
C: Protocol<C> + Zeroize
{
pub fn xx(dh_keys: AuthenticKeypair<C>) -> Self {
NoiseConfig {
dh_keys,
params: C::params_xx(),
remote: (),
_marker: std::marker::PhantomData
}
}
}
impl<C> NoiseConfig<IK, C>
where
C: Protocol<C> + Zeroize
{
pub fn ik_listener(dh_keys: AuthenticKeypair<C>) -> Self {
NoiseConfig {
dh_keys,
params: C::params_ik(),
remote: (),
_marker: std::marker::PhantomData
}
}
}
impl<C> NoiseConfig<IK, C, (PublicKey<C>, identity::PublicKey)>
where
C: Protocol<C> + Zeroize
{
pub fn ik_dialer(
dh_keys: AuthenticKeypair<C>,
remote_id: identity::PublicKey,
remote_dh: PublicKey<C>
) -> Self {
NoiseConfig {
dh_keys,
params: C::params_ik(),
remote: (remote_dh, remote_id),
_marker: std::marker::PhantomData
}
}
}
impl<T, C> InboundUpgrade<T> for NoiseConfig<IX, C>
where
NoiseConfig<IX, C>: UpgradeInfo,
T: AsyncRead + AsyncWrite + Send + 'static,
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
type Output = (RemoteIdentity<C>, NoiseOutput<Negotiated<T>>);
type Error = NoiseError;
type Future = Handshake<Negotiated<T>, C>;
fn upgrade_inbound(self, socket: Negotiated<T>, _: Self::Info) -> Self::Future {
let session = self.params.into_builder()
.local_private_key(self.dh_keys.secret().as_ref())
.build_responder()
.map_err(NoiseError::from);
Handshake::rt1_responder(socket, session,
self.dh_keys.into_identity(),
IdentityExchange::Mutual)
}
}
impl<T, C> OutboundUpgrade<T> for NoiseConfig<IX, C>
where
NoiseConfig<IX, C>: UpgradeInfo,
T: AsyncRead + AsyncWrite + Send + 'static,
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
type Output = (RemoteIdentity<C>, NoiseOutput<Negotiated<T>>);
type Error = NoiseError;
type Future = Handshake<Negotiated<T>, C>;
fn upgrade_outbound(self, socket: Negotiated<T>, _: Self::Info) -> Self::Future {
let session = self.params.into_builder()
.local_private_key(self.dh_keys.secret().as_ref())
.build_initiator()
.map_err(NoiseError::from);
Handshake::rt1_initiator(socket, session,
self.dh_keys.into_identity(),
IdentityExchange::Mutual)
}
}
impl<T, C> InboundUpgrade<T> for NoiseConfig<XX, C>
where
NoiseConfig<XX, C>: UpgradeInfo,
T: AsyncRead + AsyncWrite + Send + 'static,
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
type Output = (RemoteIdentity<C>, NoiseOutput<Negotiated<T>>);
type Error = NoiseError;
type Future = Handshake<Negotiated<T>, C>;
fn upgrade_inbound(self, socket: Negotiated<T>, _: Self::Info) -> Self::Future {
let session = self.params.into_builder()
.local_private_key(self.dh_keys.secret().as_ref())
.build_responder()
.map_err(NoiseError::from);
Handshake::rt15_responder(socket, session,
self.dh_keys.into_identity(),
IdentityExchange::Mutual)
}
}
impl<T, C> OutboundUpgrade<T> for NoiseConfig<XX, C>
where
NoiseConfig<XX, C>: UpgradeInfo,
T: AsyncRead + AsyncWrite + Send + 'static,
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
type Output = (RemoteIdentity<C>, NoiseOutput<Negotiated<T>>);
type Error = NoiseError;
type Future = Handshake<Negotiated<T>, C>;
fn upgrade_outbound(self, socket: Negotiated<T>, _: Self::Info) -> Self::Future {
let session = self.params.into_builder()
.local_private_key(self.dh_keys.secret().as_ref())
.build_initiator()
.map_err(NoiseError::from);
Handshake::rt15_initiator(socket, session,
self.dh_keys.into_identity(),
IdentityExchange::Mutual)
}
}
impl<T, C> InboundUpgrade<T> for NoiseConfig<IK, C>
where
NoiseConfig<IK, C>: UpgradeInfo,
T: AsyncRead + AsyncWrite + Send + 'static,
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
type Output = (RemoteIdentity<C>, NoiseOutput<Negotiated<T>>);
type Error = NoiseError;
type Future = Handshake<Negotiated<T>, C>;
fn upgrade_inbound(self, socket: Negotiated<T>, _: Self::Info) -> Self::Future {
let session = self.params.into_builder()
.local_private_key(self.dh_keys.secret().as_ref())
.build_responder()
.map_err(NoiseError::from);
Handshake::rt1_responder(socket, session,
self.dh_keys.into_identity(),
IdentityExchange::Receive)
}
}
impl<T, C> OutboundUpgrade<T> for NoiseConfig<IK, C, (PublicKey<C>, identity::PublicKey)>
where
NoiseConfig<IK, C, (PublicKey<C>, identity::PublicKey)>: UpgradeInfo,
T: AsyncRead + AsyncWrite + Send + 'static,
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
type Output = (RemoteIdentity<C>, NoiseOutput<Negotiated<T>>);
type Error = NoiseError;
type Future = Handshake<Negotiated<T>, C>;
fn upgrade_outbound(self, socket: Negotiated<T>, _: Self::Info) -> Self::Future {
let session = self.params.into_builder()
.local_private_key(self.dh_keys.secret().as_ref())
.remote_public_key(self.remote.0.as_ref())
.build_initiator()
.map_err(NoiseError::from);
Handshake::rt1_initiator(socket, session,
self.dh_keys.into_identity(),
IdentityExchange::Send { remote: self.remote.1 })
}
}