mod error;
mod io;
mod protocol;
mod upgrade;
pub use error::NoiseError;
pub use io::handshake;
pub use io::handshake::{Handshake, IdentityExchange, RemoteIdentity};
pub use io::NoiseOutput;
pub use protocol::{x25519::X25519, x25519_spec::X25519Spec};
pub use protocol::{AuthenticKeypair, Keypair, KeypairIdentity, PublicKey, SecretKey};
pub use protocol::{Protocol, ProtocolParams, IK, IX, XX};
use futures::prelude::*;
use libp2prs_core::identity;
use zeroize::Zeroize;
#[derive(Clone)]
pub struct NoiseConfig<P, C: Zeroize, R = ()> {
dh_keys: AuthenticKeypair<C>,
local_priv_key: identity::Keypair,
params: ProtocolParams,
legacy: LegacyConfig,
remote: R,
_marker: std::marker::PhantomData<P>,
}
impl<H, C: Zeroize, R> NoiseConfig<H, C, R> {
pub fn set_legacy_config(&mut self, cfg: LegacyConfig) -> &mut Self {
self.legacy = cfg;
self
}
}
impl<C> NoiseConfig<XX, C>
where
C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
{
pub fn xx(dh_keys: AuthenticKeypair<C>, local_priv_key: identity::Keypair) -> Self {
NoiseConfig {
dh_keys,
local_priv_key,
params: C::params_xx(),
legacy: LegacyConfig::default(),
remote: (),
_marker: std::marker::PhantomData,
}
}
pub async fn handshake<T>(self, socket: T, initiator: bool) -> Result<(RemoteIdentity<C>, NoiseOutput<T>), NoiseError>
where
T: AsyncRead + AsyncWrite + Send + Unpin + 'static,
{
let builder = self.params.into_builder().local_private_key(self.dh_keys.secret().as_ref());
let session = {
if initiator {
builder.build_initiator()
} else {
builder.build_responder()
}
.map_err(NoiseError::from)
};
if initiator {
handshake::rt15_initiator::<T, C>(socket, session, self.dh_keys.into_identity(), IdentityExchange::Mutual, self.legacy)
} else {
handshake::rt15_responder::<T, C>(socket, session, self.dh_keys.into_identity(), IdentityExchange::Mutual, self.legacy)
}
.await
}
}
#[derive(Clone)]
pub struct LegacyConfig {
pub send_legacy_handshake: bool,
pub recv_legacy_handshake: bool,
}
impl Default for LegacyConfig {
fn default() -> Self {
Self {
send_legacy_handshake: false,
recv_legacy_handshake: false,
}
}
}