1mod error;
58mod io;
59mod protocol;
60
61pub use error::NoiseError;
62pub use io::NoiseOutput;
63pub use io::handshake;
64pub use io::handshake::{Handshake, RemoteIdentity, IdentityExchange};
65pub use protocol::{Keypair, AuthenticKeypair, KeypairIdentity, PublicKey, SecretKey};
66pub use protocol::{Protocol, ProtocolParams, IX, IK, XX};
67pub use protocol::{x25519::X25519, x25519_spec::X25519Spec};
68
69use futures::prelude::*;
70use mwc_libp2p_core::{identity, PeerId, UpgradeInfo, InboundUpgrade, OutboundUpgrade};
71use std::pin::Pin;
72use zeroize::Zeroize;
73
74#[derive(Clone)]
76pub struct NoiseConfig<P, C: Zeroize, R = ()> {
77 dh_keys: AuthenticKeypair<C>,
78 params: ProtocolParams,
79 legacy: LegacyConfig,
80 remote: R,
81 _marker: std::marker::PhantomData<P>
82}
83
84impl<H, C: Zeroize, R> NoiseConfig<H, C, R> {
85 pub fn into_authenticated(self) -> NoiseAuthenticated<H, C, R> {
88 NoiseAuthenticated { config: self }
89 }
90
91 pub fn set_legacy_config(&mut self, cfg: LegacyConfig) -> &mut Self {
93 self.legacy = cfg;
94 self
95 }
96}
97
98impl<C> NoiseConfig<IX, C>
99where
100 C: Protocol<C> + Zeroize
101{
102 pub fn ix(dh_keys: AuthenticKeypair<C>) -> Self {
104 NoiseConfig {
105 dh_keys,
106 params: C::params_ix(),
107 legacy: LegacyConfig::default(),
108 remote: (),
109 _marker: std::marker::PhantomData
110 }
111 }
112}
113
114impl<C> NoiseConfig<XX, C>
115where
116 C: Protocol<C> + Zeroize
117{
118 pub fn xx(dh_keys: AuthenticKeypair<C>) -> Self {
120 NoiseConfig {
121 dh_keys,
122 params: C::params_xx(),
123 legacy: LegacyConfig::default(),
124 remote: (),
125 _marker: std::marker::PhantomData
126 }
127 }
128}
129
130impl<C> NoiseConfig<IK, C>
131where
132 C: Protocol<C> + Zeroize
133{
134 pub fn ik_listener(dh_keys: AuthenticKeypair<C>) -> Self {
139 NoiseConfig {
140 dh_keys,
141 params: C::params_ik(),
142 legacy: LegacyConfig::default(),
143 remote: (),
144 _marker: std::marker::PhantomData
145 }
146 }
147}
148
149impl<C> NoiseConfig<IK, C, (PublicKey<C>, identity::PublicKey)>
150where
151 C: Protocol<C> + Zeroize
152{
153 pub fn ik_dialer(
158 dh_keys: AuthenticKeypair<C>,
159 remote_id: identity::PublicKey,
160 remote_dh: PublicKey<C>
161 ) -> Self {
162 NoiseConfig {
163 dh_keys,
164 params: C::params_ik(),
165 legacy: LegacyConfig::default(),
166 remote: (remote_dh, remote_id),
167 _marker: std::marker::PhantomData
168 }
169 }
170}
171
172impl<T, C> InboundUpgrade<T> for NoiseConfig<IX, C>
175where
176 NoiseConfig<IX, C>: UpgradeInfo,
177 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
178 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
179{
180 type Output = (RemoteIdentity<C>, NoiseOutput<T>);
181 type Error = NoiseError;
182 type Future = Handshake<T, C>;
183
184 fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future {
185 let session = self.params.into_builder()
186 .local_private_key(self.dh_keys.secret().as_ref())
187 .build_responder()
188 .map_err(NoiseError::from);
189 handshake::rt1_responder(socket, session,
190 self.dh_keys.into_identity(),
191 IdentityExchange::Mutual,
192 self.legacy)
193 }
194}
195
196impl<T, C> OutboundUpgrade<T> for NoiseConfig<IX, C>
197where
198 NoiseConfig<IX, C>: UpgradeInfo,
199 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
200 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
201{
202 type Output = (RemoteIdentity<C>, NoiseOutput<T>);
203 type Error = NoiseError;
204 type Future = Handshake<T, C>;
205
206 fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future {
207 let session = self.params.into_builder()
208 .local_private_key(self.dh_keys.secret().as_ref())
209 .build_initiator()
210 .map_err(NoiseError::from);
211 handshake::rt1_initiator(socket, session,
212 self.dh_keys.into_identity(),
213 IdentityExchange::Mutual,
214 self.legacy)
215 }
216}
217
218impl<T, C> InboundUpgrade<T> for NoiseConfig<XX, C>
221where
222 NoiseConfig<XX, C>: UpgradeInfo,
223 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
224 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
225{
226 type Output = (RemoteIdentity<C>, NoiseOutput<T>);
227 type Error = NoiseError;
228 type Future = Handshake<T, C>;
229
230 fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future {
231 let session = self.params.into_builder()
232 .local_private_key(self.dh_keys.secret().as_ref())
233 .build_responder()
234 .map_err(NoiseError::from);
235 handshake::rt15_responder(socket, session,
236 self.dh_keys.into_identity(),
237 IdentityExchange::Mutual,
238 self.legacy)
239 }
240}
241
242impl<T, C> OutboundUpgrade<T> for NoiseConfig<XX, C>
243where
244 NoiseConfig<XX, C>: UpgradeInfo,
245 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
246 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
247{
248 type Output = (RemoteIdentity<C>, NoiseOutput<T>);
249 type Error = NoiseError;
250 type Future = Handshake<T, C>;
251
252 fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future {
253 let session = self.params.into_builder()
254 .local_private_key(self.dh_keys.secret().as_ref())
255 .build_initiator()
256 .map_err(NoiseError::from);
257 handshake::rt15_initiator(socket, session,
258 self.dh_keys.into_identity(),
259 IdentityExchange::Mutual,
260 self.legacy)
261 }
262}
263
264impl<T, C, R> InboundUpgrade<T> for NoiseConfig<IK, C, R>
267where
268 NoiseConfig<IK, C, R>: UpgradeInfo,
269 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
270 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
271{
272 type Output = (RemoteIdentity<C>, NoiseOutput<T>);
273 type Error = NoiseError;
274 type Future = Handshake<T, C>;
275
276 fn upgrade_inbound(self, socket: T, _: Self::Info) -> Self::Future {
277 let session = self.params.into_builder()
278 .local_private_key(self.dh_keys.secret().as_ref())
279 .build_responder()
280 .map_err(NoiseError::from);
281 handshake::rt1_responder(socket, session,
282 self.dh_keys.into_identity(),
283 IdentityExchange::Receive,
284 self.legacy)
285 }
286}
287
288impl<T, C> OutboundUpgrade<T> for NoiseConfig<IK, C, (PublicKey<C>, identity::PublicKey)>
289where
290 NoiseConfig<IK, C, (PublicKey<C>, identity::PublicKey)>: UpgradeInfo,
291 T: AsyncRead + AsyncWrite + Unpin + Send + 'static,
292 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
293{
294 type Output = (RemoteIdentity<C>, NoiseOutput<T>);
295 type Error = NoiseError;
296 type Future = Handshake<T, C>;
297
298 fn upgrade_outbound(self, socket: T, _: Self::Info) -> Self::Future {
299 let session = self.params.into_builder()
300 .local_private_key(self.dh_keys.secret().as_ref())
301 .remote_public_key(self.remote.0.as_ref())
302 .build_initiator()
303 .map_err(NoiseError::from);
304 handshake::rt1_initiator(socket, session,
305 self.dh_keys.into_identity(),
306 IdentityExchange::Send { remote: self.remote.1 },
307 self.legacy)
308 }
309}
310
311#[derive(Clone)]
324pub struct NoiseAuthenticated<P, C: Zeroize, R> {
325 config: NoiseConfig<P, C, R>
326}
327
328impl<P, C: Zeroize, R> UpgradeInfo for NoiseAuthenticated<P, C, R>
329where
330 NoiseConfig<P, C, R>: UpgradeInfo
331{
332 type Info = <NoiseConfig<P, C, R> as UpgradeInfo>::Info;
333 type InfoIter = <NoiseConfig<P, C, R> as UpgradeInfo>::InfoIter;
334
335 fn protocol_info(&self) -> Self::InfoIter {
336 self.config.protocol_info()
337 }
338}
339
340impl<T, P, C, R> InboundUpgrade<T> for NoiseAuthenticated<P, C, R>
341where
342 NoiseConfig<P, C, R>: UpgradeInfo + InboundUpgrade<T,
343 Output = (RemoteIdentity<C>, NoiseOutput<T>),
344 Error = NoiseError
345 > + 'static,
346 <NoiseConfig<P, C, R> as InboundUpgrade<T>>::Future: Send,
347 T: AsyncRead + AsyncWrite + Send + 'static,
348 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
349{
350 type Output = (PeerId, NoiseOutput<T>);
351 type Error = NoiseError;
352 type Future = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>> + Send>>;
353
354 fn upgrade_inbound(self, socket: T, info: Self::Info) -> Self::Future {
355 Box::pin(self.config.upgrade_inbound(socket, info)
356 .and_then(|(remote, io)| match remote {
357 RemoteIdentity::IdentityKey(pk) => future::ok((pk.into_peer_id(), io)),
358 _ => future::err(NoiseError::AuthenticationFailed)
359 }))
360 }
361}
362
363impl<T, P, C, R> OutboundUpgrade<T> for NoiseAuthenticated<P, C, R>
364where
365 NoiseConfig<P, C, R>: UpgradeInfo + OutboundUpgrade<T,
366 Output = (RemoteIdentity<C>, NoiseOutput<T>),
367 Error = NoiseError
368 > + 'static,
369 <NoiseConfig<P, C, R> as OutboundUpgrade<T>>::Future: Send,
370 T: AsyncRead + AsyncWrite + Send + 'static,
371 C: Protocol<C> + AsRef<[u8]> + Zeroize + Send + 'static,
372{
373 type Output = (PeerId, NoiseOutput<T>);
374 type Error = NoiseError;
375 type Future = Pin<Box<dyn Future<Output = Result<Self::Output, Self::Error>> + Send>>;
376
377 fn upgrade_outbound(self, socket: T, info: Self::Info) -> Self::Future {
378 Box::pin(self.config.upgrade_outbound(socket, info)
379 .and_then(|(remote, io)| match remote {
380 RemoteIdentity::IdentityKey(pk) => future::ok((pk.into_peer_id(), io)),
381 _ => future::err(NoiseError::AuthenticationFailed)
382 }))
383 }
384}
385
386#[derive(Clone)]
388pub struct LegacyConfig {
389 pub send_legacy_handshake: bool,
394 pub recv_legacy_handshake: bool,
399}
400
401impl Default for LegacyConfig {
402 fn default() -> Self {
403 Self {
404 send_legacy_handshake: false,
405 recv_legacy_handshake: false,
406 }
407 }
408}