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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
use crate::{Identity, ProfileIdentifier};
use async_trait::async_trait;
use ockam_core::{Address, Message, Result, Route, Routed};
use ockam_node::Context;
use ockam_vault_sync_core::VaultSync;

mod secure_channel_worker;
pub(crate) use secure_channel_worker::*;
mod listener;
pub(crate) use listener::*;
mod messages;
pub(crate) use messages::*;
mod trust_policy;
pub use trust_policy::*;
mod local_info;
pub use local_info::*;

#[async_trait]
pub trait SecureChannelTrait {
    async fn create_secure_channel_async(
        self,
        ctx: &Context,
        route: Route,
        trust_policy: impl TrustPolicy,
        vault: &Address,
    ) -> Result<Address>;

    async fn create_secure_channel_listener_async(
        self,
        ctx: &Context,
        address: Address,
        trust_policy: impl TrustPolicy,
        vault: &Address,
    ) -> Result<()>;
}

#[async_trait]
impl<P: Identity + Send> SecureChannelTrait for P {
    /// Create mutually authenticated secure channel
    async fn create_secure_channel_async(
        self,
        ctx: &Context,
        route: Route,
        trust_policy: impl TrustPolicy,
        vault: &Address,
    ) -> Result<Address> {
        let vault = VaultSync::create_with_worker(ctx, vault)?;
        SecureChannelWorker::create_initiator(ctx, route, self, trust_policy, vault).await
    }

    /// Create mutually authenticated secure channel listener
    async fn create_secure_channel_listener_async(
        self,
        ctx: &Context,
        address: Address,
        trust_policy: impl TrustPolicy,
        vault: &Address,
    ) -> Result<()> {
        let vault = VaultSync::create_with_worker(ctx, vault)?;
        let listener = ProfileChannelListener::new(trust_policy, self, vault);
        ctx.start_worker(address, listener).await
    }
}

// TODO: rename
pub fn check_message_origin<T: Message>(
    msg: &Routed<T>,
    their_profile_id: &ProfileIdentifier,
) -> Result<bool> {
    let local_msg = msg.local_message();
    let local_info = LocalInfo::decode(local_msg.local_info())?;

    let res = local_info.their_profile_id() == their_profile_id;

    Ok(res)
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::{Entity, SecureChannels};
    use ockam_core::{route, Message};

    #[test]
    fn disable_test_channel() {
        let (mut ctx, mut executor) = ockam_node::start_node();
        executor
            .execute(async move {
                let mut alice = Entity::create(&ctx).unwrap();
                let mut bob = Entity::create(&ctx).unwrap();

                let _alice_trust_policy = IdentifierTrustPolicy::new(bob.identifier().unwrap());
                let _bob_trust_policy = IdentifierTrustPolicy::new(alice.identifier().unwrap());

                bob.create_secure_channel_listener(
                    "bob_listener",
                    // FIXME: bob_trust_policy,
                )
                .unwrap();

                let alice_channel = alice
                    .create_secure_channel(
                        route!["bob_listener"],
                        // FIXME: alice_trust_policy,
                    )
                    .unwrap();

                ctx.send(
                    route![alice_channel, ctx.address()],
                    "Hello, Bob!".to_string(),
                )
                .await
                .unwrap();
                let msg = ctx.receive::<String>().await.unwrap().take();

                let local_info = LocalInfo::decode(msg.local_message().local_info()).unwrap();
                assert_eq!(local_info.their_profile_id(), &alice.identifier().unwrap());

                let return_route = msg.return_route();
                assert_eq!("Hello, Bob!", msg.body());

                ctx.send(return_route, "Hello, Alice!".to_string())
                    .await
                    .unwrap();

                let msg = ctx.receive::<String>().await.unwrap().take();

                let local_info = msg.local_message().local_info();

                let local_info = LocalInfo::decode(local_info).unwrap();
                assert_eq!(local_info.their_profile_id(), &bob.identifier().unwrap());

                assert_eq!("Hello, Alice!", msg.body());

                ctx.stop().await.unwrap();
            })
            .unwrap();
    }
}