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
use error::NoiseError;
use handshakestate::HandshakeState;
use std::convert::{TryFrom, TryInto};
use transportstate::*;

/// Methods that must be implemented across all states in the NoiseSession state machine.
pub trait NoiseSessionState {
    fn is_payload_encrypted(&self) -> bool;
    fn write_message(&mut self, payload: &[u8], output: &mut [u8]) -> Result<usize, NoiseError>;
    fn read_message(&mut self, input: &[u8], payload: &mut [u8]) -> Result<usize, NoiseError>;
}

/// The high-level state machine for the flow from handshake to transport stages.
pub struct NoiseSession<S> where S: NoiseSessionState {
    state: S,
}

impl TryFrom<NoiseSession<HandshakeState>> for NoiseSession<TransportState> {
    type Err = NoiseError;

    fn try_from(old: NoiseSession<HandshakeState>) -> Result<Self, Self::Err> {
        let initiator = old.state.is_initiator();
        let cipherstates = old.state.finish()?;
        Ok(NoiseSession {
            state: TransportState::new(cipherstates, initiator)
        })
    }
}

impl From<HandshakeState> for NoiseSession<HandshakeState> {
    fn from(handshake_state: HandshakeState) -> Self {
        Self {
            state: handshake_state
        }
    }
}

impl NoiseSessionState for HandshakeState {
    fn is_payload_encrypted(&self) -> bool {
        self.is_write_encrypted()
    }

    fn write_message(&mut self, payload: &[u8], output: &mut [u8]) -> Result<usize, NoiseError> {
        self.write_handshake_message(payload, output)
    }

    fn read_message(&mut self, input: &[u8], payload: &mut [u8]) -> Result<usize, NoiseError> {
        self.read_handshake_message(input, payload)
    }
}

impl NoiseSessionState for TransportState {
    fn is_payload_encrypted(&self) -> bool {
        true
    }

    fn write_message(&mut self, payload: &[u8], output: &mut [u8]) -> Result<usize, NoiseError> {
        self.write_transport_message(payload, output)
    }

    fn read_message(&mut self, input: &[u8], payload: &mut [u8]) -> Result<usize, NoiseError> {
        self.read_transport_message(input, payload)
    }
}

impl NoiseSession<HandshakeState> {
    pub fn is_handshake_finished(&self) -> bool {
        self.state.is_finished()
    }

    pub fn into_transport_mode(self) -> Result<NoiseSession<TransportState>, NoiseError> {
        if !self.state.is_finished() {
            Err(NoiseError::StateError("handshake not yet finished"))
        } else {
            self.try_into()
        }
    }
}

impl<S: NoiseSessionState> NoiseSessionState for NoiseSession<S> {
    fn is_payload_encrypted(&self) -> bool {
        self.state.is_payload_encrypted()
    }

    fn write_message(&mut self, payload: &[u8], output: &mut [u8]) -> Result<usize, NoiseError> {
        self.state.write_message(payload, output)
    }

    fn read_message(&mut self, input: &[u8], payload: &mut [u8]) -> Result<usize, NoiseError> {
        self.state.read_message(input, payload)
    }
}