ssh/algorithm/hash/
hash_ctx.rs

1use crate::model::Data;
2
3/// <https://www.rfc-editor.org/rfc/rfc4253#section-7.2>
4///
5/// The key exchange produces two values: a shared secret K, and an
6/// exchange hash H.  Encryption and authentication keys are derived from
7/// these.  The exchange hash H from the first key exchange is
8/// additionally used as the session identifier, which is a unique
9/// identifier for this connection.  It is used by authentication methods
10/// as a part of the data that is signed as a proof of possession of a
11/// private key.  Once computed, the session identifier is not changed,
12/// even if keys are later re-exchanged.
13///
14/// H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)
15///
16///
17#[derive(Clone, Debug, Default)]
18pub struct HashCtx {
19    /// string    V_C, the client's identification string (CR and LF excluded)
20    pub v_c: Vec<u8>,
21    /// string    V_S, the server's identification string (CR and LF excluded)
22    pub v_s: Vec<u8>,
23
24    /// string    I_C, the payload of the client's SSH_MSG_KEXINIT
25    pub i_c: Vec<u8>,
26    /// string    I_S, the payload of the server's SSH_MSG_KEXINIT
27    pub i_s: Vec<u8>,
28
29    /// string    K_S, the host key
30    pub k_s: Vec<u8>,
31
32    /// mpint     e, exchange value sent by the client
33    pub e: Vec<u8>,
34    /// mpint     f, exchange value sent by the server
35    pub f: Vec<u8>,
36
37    /// mpint     K, the shared secret
38    pub k: Vec<u8>,
39}
40
41impl HashCtx {
42    pub fn new() -> Self {
43        HashCtx {
44            v_c: vec![],
45            v_s: vec![],
46            i_c: vec![],
47            i_s: vec![],
48            k_s: vec![],
49            e: vec![],
50            f: vec![],
51            k: vec![],
52        }
53    }
54
55    pub fn set_v_c(&mut self, vc: &str) {
56        let mut data = Data::new();
57        data.put_str(vc);
58        self.v_c = data.to_vec();
59    }
60    pub fn set_v_s(&mut self, vs: &str) {
61        let mut data = Data::new();
62        data.put_str(vs);
63        self.v_s = data.to_vec();
64    }
65    pub fn set_i_c(&mut self, ic: &[u8]) {
66        let mut data = Data::new();
67        data.put_u8s(ic);
68        self.i_c = data.to_vec();
69    }
70    pub fn set_i_s(&mut self, is: &[u8]) {
71        let mut data = Data::new();
72        data.put_u8s(is);
73        self.i_s = data.to_vec();
74    }
75    pub fn set_k_s(&mut self, ks: &[u8]) {
76        let mut data = Data::new();
77        data.put_u8s(ks);
78        self.k_s = data.to_vec();
79    }
80    pub fn set_e(&mut self, qc: &[u8]) {
81        let mut data = Data::new();
82        data.put_u8s(qc);
83        self.e = data.to_vec();
84    }
85    pub fn set_f(&mut self, qs: &[u8]) {
86        let mut data = Data::new();
87        data.put_u8s(qs);
88        self.f = data.to_vec();
89    }
90    pub fn set_k(&mut self, k: &[u8]) {
91        let mut data = Data::new();
92        data.put_mpint(k);
93        self.k = data.to_vec();
94    }
95
96    pub fn as_bytes(&self) -> Vec<u8> {
97        let mut v = vec![];
98        v.extend(&self.v_c);
99        v.extend(&self.v_s);
100        v.extend(&self.i_c);
101        v.extend(&self.i_s);
102        v.extend(&self.k_s);
103        v.extend(&self.e);
104        v.extend(&self.f);
105        v.extend(&self.k);
106        v
107    }
108}