1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

//! This crate implements wrappers around our [Noise][noise] implementation.
//! Noise is a protocol framework to encrypt and authentication connections.
//! We use Noise to secure connections between peers in Diem.
//! Specifically, we use the [Noise IK][ik] handshake which is a one round-trip protocol
//! (the client sends one message, then the server responds).
//! For more information about Noise and our implementation, refer to the [crypto] crate.
//!
//! Usage example:
//!
//! ```
//! use network::noise::{AntiReplayTimestamps, HandshakeAuthMode, NoiseUpgrader};
//! use futures::{executor, future, io::{AsyncReadExt, AsyncWriteExt}};
//! use memsocket::MemorySocket;
//! use diem_config::{config::{Peer, PeerRole, RoleType}, network_id::{NetworkContext, NetworkId}};
//! use diem_crypto::{x25519, ed25519, Uniform, PrivateKey, test_utils::TEST_SEED};
//! use diem_infallible::RwLock;
//! use rand::{rngs::StdRng, SeedableRng};
//! use diem_types::PeerId;
//! use std::{collections::{HashSet, HashMap}, io, sync::Arc};
//!
//! fn example() -> io::Result<()> {
//! // create client and server NoiseUpgrader
//! let mut rng = StdRng::from_seed(TEST_SEED);
//! let client_private = x25519::PrivateKey::generate(&mut rng);
//! let client_public = client_private.public_key();
//! let client_peer_id = PeerId::random();
//!
//! let server_private = x25519::PrivateKey::generate(&mut rng);
//! let server_public = server_private.public_key();
//! let server_peer_id = PeerId::random();
//!
//! // create list of trusted peers
//! let client_pubkey_set: HashSet<_> = vec![client_public].into_iter().collect();
//! let server_pubkey_set: HashSet<_> = vec![server_public].into_iter().collect();
//! let trusted_peers: HashMap<_, _> = vec![
//!     (client_peer_id, Peer::new(Vec::new(), client_pubkey_set, PeerRole::Validator)),
//!     (server_peer_id, Peer::new(Vec::new(), server_pubkey_set, PeerRole::Validator))
//! ].into_iter().collect();
//! let trusted_peers = Arc::new(RwLock::new(trusted_peers));
//!
//! let client_auth = HandshakeAuthMode::mutual(trusted_peers.clone());
//! let client_context = NetworkContext::new(
//!     RoleType::Validator,
//!     NetworkId::Validator,
//!     client_peer_id,
//! );
//! let client = NoiseUpgrader::new(client_context, client_private, client_auth);
//!
//! let server_auth = HandshakeAuthMode::mutual(trusted_peers);
//! let server_context = NetworkContext::new(
//!     RoleType::Validator,
//!     NetworkId::Validator,
//!     server_peer_id,
//! );
//! let server = NoiseUpgrader::new(server_context, server_private, server_auth);
//!
//! // use an in-memory socket as example
//! let (dialer_socket, listener_socket) = MemorySocket::new_pair();
//!
//! // perform the handshake
//! let (client_session, server_session) = executor::block_on(future::join(
//!    client.upgrade_outbound(dialer_socket, server_public, AntiReplayTimestamps::now),
//!    server.upgrade_inbound(listener_socket),
//! ));
//!
//! let mut client_session = client_session
//!     .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
//! let (mut server_session, _client_peer_id, _trust_level) = server_session
//!     .map_err(|err| io::Error::new(io::ErrorKind::Other, err))?;
//!
//! // client -> server
//! executor::block_on(client_session.write_all(b"client hello"))?;
//! executor::block_on(client_session.flush())?;
//!
//! let mut buf = [0; 12];
//! executor::block_on(server_session.read_exact(&mut buf))?;
//! assert_eq!(&buf, b"client hello");
//!
//! // client <- server
//! executor::block_on(server_session.write_all(b"server hello"))?;
//! executor::block_on(server_session.flush())?;
//!
//! let mut buf = [0; 12];
//! executor::block_on(client_session.read_exact(&mut buf))?;
//! assert_eq!(&buf, b"server hello");
//!
//! Ok(())
//! }
//!
//! example().unwrap();
//! ```
//!
//! [noise]: http://noiseprotocol.org/
//! [ik]: https://noiseexplorer.com/patterns/IK
//! [crypto]: ../diem_crypto/noise/index.html

pub mod error;
pub mod handshake;
pub mod stream;

#[cfg(any(test, feature = "fuzzing"))]
pub mod fuzzing;

pub use error::NoiseHandshakeError;
pub use handshake::{AntiReplayTimestamps, HandshakeAuthMode, NoiseUpgrader};