// Copyright 2019 Parity Technologies (UK) Ltd. // // Permission is hereby granted, free of charge, to any person obtaining a // copy of this software and associated documentation files (the "Software"), // to deal in the Software without restriction, including without limitation // the rights to use, copy, modify, merge, publish, distribute, sublicense, // and/or sell copies of the Software, and to permit persons to whom the // Software is furnished to do so, subject to the following conditions: // // The above copyright notice and this permission notice shall be included in // all copies or substantial portions of the Software. // // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. //! [Noise protocol framework][noise] support for libp2p. //! //! This crate provides `libp2p_core::InboundUpgrade` and `libp2p_core::OutboundUpgrade` //! implementations for various noise handshake patterns (currently IK, IX, and XX) //! over a particular choice of DH key agreement (currently only X25519). //! //! All upgrades produce as output a pair, consisting of the remote's static public key //! and a `NoiseOutput` which represents the established cryptographic session with the //! remote, implementing `tokio_io::AsyncRead` and `tokio_io::AsyncWrite`. //! //! # Usage //! //! Example: //! //! ``` //! use libp2p_core::Transport; //! use libp2p_tcp::TcpConfig; //! use libp2p_noise::{Keypair, X25519, NoiseConfig}; //! //! # fn main() { //! let keys = Keypair::::new(); //! let transport = TcpConfig::new().with_upgrade(NoiseConfig::xx(keys)); //! // ... //! # } //! ``` //! //! [noise]: http://noiseprotocol.org/ mod error; mod io; mod protocol; pub mod rt1; pub mod rt15; pub use error::NoiseError; pub use io::NoiseOutput; pub use protocol::{Keypair, PublicKey, Protocol, ProtocolParams, IX, IK, XX}; pub use protocol::x25519::X25519; use libp2p_core::{UpgradeInfo, InboundUpgrade, OutboundUpgrade}; use tokio_io::{AsyncRead, AsyncWrite}; use zeroize::Zeroize; /// The protocol upgrade configuration. #[derive(Clone)] pub struct NoiseConfig { keys: Keypair, params: ProtocolParams, remote: R, _marker: std::marker::PhantomData

} impl + Zeroize> NoiseConfig { /// Create a new `NoiseConfig` for the IX handshake pattern. pub fn ix(keys: Keypair) -> Self { NoiseConfig { keys, params: C::params_ix(), remote: (), _marker: std::marker::PhantomData } } } impl + Zeroize> NoiseConfig { /// Create a new `NoiseConfig` for the XX handshake pattern. pub fn xx(keys: Keypair) -> Self { NoiseConfig { keys, params: C::params_xx(), remote: (), _marker: std::marker::PhantomData } } } impl + Zeroize> NoiseConfig { /// Create a new `NoiseConfig` for the IK handshake pattern (recipient side). pub fn ik_listener(keys: Keypair) -> Self { NoiseConfig { keys, params: C::params_ik(), remote: (), _marker: std::marker::PhantomData } } } impl + Zeroize> NoiseConfig> { /// Create a new `NoiseConfig` for the IK handshake pattern (initiator side). pub fn ik_dialer(keys: Keypair, remote: PublicKey) -> Self { NoiseConfig { keys, params: C::params_ik(), remote, _marker: std::marker::PhantomData } } } // Handshake pattern IX ///////////////////////////////////////////////////// impl InboundUpgrade for NoiseConfig where T: AsyncRead + AsyncWrite, NoiseConfig: UpgradeInfo, C: Protocol + AsRef<[u8]> + Zeroize { type Output = (PublicKey, NoiseOutput); type Error = NoiseError; type Future = rt1::NoiseInboundFuture; fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future { let session = self.params.into_builder() .local_private_key(self.keys.secret().as_ref()) .build_responder() .map_err(NoiseError::from); rt1::NoiseInboundFuture::new(socket, session) } } impl OutboundUpgrade for NoiseConfig where T: AsyncRead + AsyncWrite, NoiseConfig: UpgradeInfo, C: Protocol + AsRef<[u8]> + Zeroize { type Output = (PublicKey, NoiseOutput); type Error = NoiseError; type Future = rt1::NoiseOutboundFuture; fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future { let session = self.params.into_builder() .local_private_key(self.keys.secret().as_ref()) .build_initiator() .map_err(NoiseError::from); rt1::NoiseOutboundFuture::new(socket, session) } } // Handshake pattern XX ///////////////////////////////////////////////////// impl InboundUpgrade for NoiseConfig where T: AsyncRead + AsyncWrite, NoiseConfig: UpgradeInfo, C: Protocol + AsRef<[u8]> + Zeroize { type Output = (PublicKey, NoiseOutput); type Error = NoiseError; type Future = rt15::NoiseInboundFuture; fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future { let session = self.params.into_builder() .local_private_key(self.keys.secret().as_ref()) .build_responder() .map_err(NoiseError::from); rt15::NoiseInboundFuture::new(socket, session) } } impl OutboundUpgrade for NoiseConfig where T: AsyncRead + AsyncWrite, NoiseConfig: UpgradeInfo, C: Protocol + AsRef<[u8]> + Zeroize { type Output = (PublicKey, NoiseOutput); type Error = NoiseError; type Future = rt15::NoiseOutboundFuture; fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future { let session = self.params.into_builder() .local_private_key(self.keys.secret().as_ref()) .build_initiator() .map_err(NoiseError::from); rt15::NoiseOutboundFuture::new(socket, session) } } // Handshake pattern IK ///////////////////////////////////////////////////// impl InboundUpgrade for NoiseConfig where T: AsyncRead + AsyncWrite, NoiseConfig: UpgradeInfo, C: Protocol + AsRef<[u8]> + Zeroize { type Output = (PublicKey, NoiseOutput); type Error = NoiseError; type Future = rt1::NoiseInboundFuture; fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future { let session = self.params.into_builder() .local_private_key(self.keys.secret().as_ref()) .build_responder() .map_err(NoiseError::from); rt1::NoiseInboundFuture::new(socket, session) } } impl OutboundUpgrade for NoiseConfig> where T: AsyncRead + AsyncWrite, NoiseConfig>: UpgradeInfo, C: Protocol + AsRef<[u8]> + Zeroize { type Output = (PublicKey, NoiseOutput); type Error = NoiseError; type Future = rt1::NoiseOutboundFuture; fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future { let session = self.params.into_builder() .local_private_key(self.keys.secret().as_ref()) .remote_public_key(self.remote.as_ref()) .build_initiator() .map_err(NoiseError::from); rt1::NoiseOutboundFuture::new(socket, session) } }