title: Secure Channel over many hops
The Ockam routing protocol can route messages over many hops and establishing a Secure Channel requires exchanging messages. Ockam Secure Channels are implemented on top of Ockam Routing so you can create a secure channel that is encrypted and secure, end-to-end, over multiple hops.
For illustration, let's create an end-to-end secure channel within a single node.
Create a new file at:
touch examples/06-secure-channel-many-hops.rs
Add the following code to this file:
use ockam::{Context, Result, Route, SecureChannel};
use ockam_get_started::{Echoer, Hop};
use ockam_vault::SoftwareVault;
use ockam_vault_sync_core::VaultWorker;
#[ockam::node]
async fn main(mut ctx: Context) -> Result<()> {
// Start an echoer worker.
ctx.start_worker("echoer", Echoer).await?;
// Start hop workers - hop1, hop2, hop3.
ctx.start_worker("hop1", Hop).await?;
ctx.start_worker("hop2", Hop).await?;
ctx.start_worker("hop3", Hop).await?;
let vault_address = VaultWorker::start(&ctx, SoftwareVault::default()).await?;
SecureChannel::create_listener(&mut ctx, "secure_channel_listener", vault_address.clone())
.await?;
let route_to_listener = Route::new()
.append("hop1")
.append("hop2")
.append("hop3")
.append("secure_channel_listener");
let channel = SecureChannel::create(&mut ctx, route_to_listener, vault_address).await?;
// Send a message to the echoer worker via the channel.
ctx.send(
Route::new().append(channel.address()).append("echoer"),
"Hello Ockam!".to_string(),
)
.await?;
// Wait to receive a reply and print it.
let reply = ctx.receive::<String>().await?;
println!("App Received: {}", reply); // should print "Hello Ockam!"
ctx.stop().await
}
To run this new node program:
cargo run --example 06-secure-channel-many-hops
In the code above, we create a multi-hop route to the secure channel listener
and provide that route to SecureChannel::create(...)
. This internally creates
a channel_initiator
worker that sends protocol messages over the given
route to establish the channel.
Once the channel is established, we can send messages via the channel Route::new().append(channel.address()).append("echoer")
. They are encrypted as
they enter the channel and cannot be tampered or snooped as they flow along
channel_initiator => hop1 => hop2 => hop3 => channel_responder
.
The channel that we built above was local to one node, which is not very useful for a real applications. Next, we'll see how messages can be routed to other nodes to get end-to-end secure channels over many transport layer hops.