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
use crate::model::Data;
/// <https://www.rfc-editor.org/rfc/rfc4253#section-7.2>
///
/// The key exchange produces two values: a shared secret K, and an
/// exchange hash H. Encryption and authentication keys are derived from
/// these. The exchange hash H from the first key exchange is
/// additionally used as the session identifier, which is a unique
/// identifier for this connection. It is used by authentication methods
/// as a part of the data that is signed as a proof of possession of a
/// private key. Once computed, the session identifier is not changed,
/// even if keys are later re-exchanged.
///
/// H = hash(V_C || V_S || I_C || I_S || K_S || e || f || K)
///
///
#[derive(Clone, Debug, Default)]
pub struct HashCtx {
/// string V_C, the client's identification string (CR and LF excluded)
pub v_c: Vec<u8>,
/// string V_S, the server's identification string (CR and LF excluded)
pub v_s: Vec<u8>,
/// string I_C, the payload of the client's SSH_MSG_KEXINIT
pub i_c: Vec<u8>,
/// string I_S, the payload of the server's SSH_MSG_KEXINIT
pub i_s: Vec<u8>,
/// string K_S, the host key
pub k_s: Vec<u8>,
/// mpint e, exchange value sent by the client
pub e: Vec<u8>,
/// mpint f, exchange value sent by the server
pub f: Vec<u8>,
/// mpint K, the shared secret
pub k: Vec<u8>,
}
impl HashCtx {
pub fn new() -> Self {
HashCtx {
v_c: vec![],
v_s: vec![],
i_c: vec![],
i_s: vec![],
k_s: vec![],
e: vec![],
f: vec![],
k: vec![],
}
}
pub fn set_v_c(&mut self, vc: &str) {
let mut data = Data::new();
data.put_str(vc);
self.v_c = data.to_vec();
}
pub fn set_v_s(&mut self, vs: &str) {
let mut data = Data::new();
data.put_str(vs);
self.v_s = data.to_vec();
}
pub fn set_i_c(&mut self, ic: &[u8]) {
let mut data = Data::new();
data.put_u8s(ic);
self.i_c = data.to_vec();
}
pub fn set_i_s(&mut self, is: &[u8]) {
let mut data = Data::new();
data.put_u8s(is);
self.i_s = data.to_vec();
}
pub fn set_k_s(&mut self, ks: &[u8]) {
let mut data = Data::new();
data.put_u8s(ks);
self.k_s = data.to_vec();
}
pub fn set_e(&mut self, qc: &[u8]) {
let mut data = Data::new();
data.put_u8s(qc);
self.e = data.to_vec();
}
pub fn set_f(&mut self, qs: &[u8]) {
let mut data = Data::new();
data.put_u8s(qs);
self.f = data.to_vec();
}
pub fn set_k(&mut self, k: &[u8]) {
let mut data = Data::new();
data.put_mpint(k);
self.k = data.to_vec();
}
pub fn as_bytes(&self) -> Vec<u8> {
let mut v = vec![];
v.extend(&self.v_c);
v.extend(&self.v_s);
v.extend(&self.i_c);
v.extend(&self.i_s);
v.extend(&self.k_s);
v.extend(&self.e);
v.extend(&self.f);
v.extend(&self.k);
v
}
}