From b592f281a23795ee6ea61e2436ff0c4ef6b4b103 Mon Sep 17 00:00:00 2001 From: Pierre Krieger Date: Thu, 7 Dec 2017 15:34:22 +0100 Subject: [PATCH] Add documentation and README for secio --- libp2p-secio/Cargo.toml | 1 + libp2p-secio/README.md | 57 +++++++++++++++++++++++++++++++++++++++++ libp2p-secio/src/lib.rs | 57 +++++++++++++++++++++++++++++++++++++---- 3 files changed, 110 insertions(+), 5 deletions(-) create mode 100644 libp2p-secio/README.md diff --git a/libp2p-secio/Cargo.toml b/libp2p-secio/Cargo.toml index 79a1c394..e86c35a7 100644 --- a/libp2p-secio/Cargo.toml +++ b/libp2p-secio/Cargo.toml @@ -16,4 +16,5 @@ tokio-io = "0.1.0" untrusted = "0.6.0" [dev-dependencies] +libp2p-tcp-transport = { path = "../libp2p-tcp-transport" } tokio-core = "0.1.6" diff --git a/libp2p-secio/README.md b/libp2p-secio/README.md new file mode 100644 index 00000000..a39e8752 --- /dev/null +++ b/libp2p-secio/README.md @@ -0,0 +1,57 @@ +The `secio` protocol is a middleware that will encrypt and decrypt communications going +through a socket (or anything that implements `AsyncRead + AsyncWrite`). + +# Connection upgrade + +The `SecioConfig` struct implements the `ConnectionUpgrade` trait. You can apply it over a +`Transport` by using the `with_upgrade` method. The returned object will also implement +`Transport` and will automatically apply the secio protocol over any connection that is opened +through it. + +```rust +extern crate futures; +extern crate tokio_core; +extern crate tokio_io; +extern crate libp2p_swarm; +extern crate libp2p_secio; +extern crate libp2p_tcp_transport; + +use futures::Future; +use libp2p_secio::{SecioConfig, SecioKeyPair}; +use libp2p_swarm::{Multiaddr, Transport}; +use libp2p_tcp_transport::TcpConfig; +use tokio_core::reactor::Core; +use tokio_io::io::write_all; + +let mut core = Core::new().unwrap(); + +let transport = TcpConfig::new(core.handle()) + .with_upgrade({ + # let private_key = b""; + //let private_key = include_bytes!("test-private-key.pk8"); + # let public_key = vec![]; + //let public_key = include_bytes!("test-public-key.der").to_vec(); + SecioConfig { + // See the documentation of `SecioKeyPair`. + key: SecioKeyPair::rsa_from_pkcs8(private_key, public_key).unwrap(), + } + }); + +let future = transport.dial(Multiaddr::new("/ip4/127.0.0.1/tcp/12345").unwrap()) + .unwrap_or_else(|_| panic!("Unable to dial node")) + .and_then(|connection| { + // Sends "hello world" on the connection, will be encrypted. + write_all(connection, "hello world") + }); + +core.run(future).unwrap(); +``` + +# Manual usage + +> **Note**: You are encouraged to use `SecioConfig` as described above. + +You can add the `secio` layer over a socket by calling `SecioMiddleware::handshake()`. This +method will perform a handshake with the host, and return a future that corresponds to the +moment when the handshake succeeds or errored. On success, the future produces a +`SecioMiddleware` that implements `Sink` and `Stream` and can be used to send packets of data. diff --git a/libp2p-secio/src/lib.rs b/libp2p-secio/src/lib.rs index e2b06e6c..3b67a666 100644 --- a/libp2p-secio/src/lib.rs +++ b/libp2p-secio/src/lib.rs @@ -18,19 +18,66 @@ // FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER // DEALINGS IN THE SOFTWARE. -//! # Implementation of the `secio` protocol. -//! //! The `secio` protocol is a middleware that will encrypt and decrypt communications going //! through a socket (or anything that implements `AsyncRead + AsyncWrite`). //! +//! # Connection upgrade +//! +//! The `SecioConfig` struct implements the `ConnectionUpgrade` trait. You can apply it over a +//! `Transport` by using the `with_upgrade` method. The returned object will also implement +//! `Transport` and will automatically apply the secio protocol over any connection that is opened +//! through it. +//! +//! ```no_run +//! extern crate futures; +//! extern crate tokio_core; +//! extern crate tokio_io; +//! extern crate libp2p_swarm; +//! extern crate libp2p_secio; +//! extern crate libp2p_tcp_transport; +//! +//! # fn main() { +//! use futures::Future; +//! use libp2p_secio::{SecioConfig, SecioKeyPair}; +//! use libp2p_swarm::{Multiaddr, Transport}; +//! use libp2p_tcp_transport::TcpConfig; +//! use tokio_core::reactor::Core; +//! use tokio_io::io::write_all; +//! +//! let mut core = Core::new().unwrap(); +//! +//! let transport = TcpConfig::new(core.handle()) +//! .with_upgrade({ +//! # let private_key = b""; +//! //let private_key = include_bytes!("test-private-key.pk8"); +//! # let public_key = vec![]; +//! //let public_key = include_bytes!("test-public-key.der").to_vec(); +//! SecioConfig { +//! // See the documentation of `SecioKeyPair`. +//! key: SecioKeyPair::rsa_from_pkcs8(private_key, public_key).unwrap(), +//! } +//! }); +//! +//! let future = transport.dial(Multiaddr::new("/ip4/127.0.0.1/tcp/12345").unwrap()) +//! .unwrap_or_else(|_| panic!("Unable to dial node")) +//! .and_then(|connection| { +//! // Sends "hello world" on the connection, will be encrypted. +//! write_all(connection, "hello world") +//! }); +//! +//! core.run(future).unwrap(); +//! # } +//! ``` +//! +//! # Manual usage +//! +//! > **Note**: You are encouraged to use `SecioConfig` as described above. +//! //! You can add the `secio` layer over a socket by calling `SecioMiddleware::handshake()`. This //! method will perform a handshake with the host, and return a future that corresponds to the //! moment when the handshake succeeds or errored. On success, the future produces a //! `SecioMiddleware` that implements `Sink` and `Stream` and can be used to send packets of data. //! -//! However for integration with the rest of `libp2p` you are encouraged to use the -//! `SecioConfig` struct instead. This struct implements the `ConnectionUpgrade` trait and -//! will automatically apply secio on any incoming or outgoing connection. extern crate bytes; extern crate crypto;