mirror of
https://gitlab.redox-os.org/CoffeeCode/redox-ssh.git
synced 2025-12-28 19:02:19 +01:00
Implement dynamic key exchange selection"
This commit is contained in:
parent
874f42313b
commit
743cb40e39
2 changed files with 34 additions and 14 deletions
|
|
@ -2,6 +2,7 @@ use std::fmt;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use error::{ConnectionError, ConnectionResult};
|
use error::{ConnectionError, ConnectionResult};
|
||||||
|
use key_exchange::{self, KeyExchange};
|
||||||
|
|
||||||
/// Slice of implemented key exchange algorithms, ordered by preference
|
/// Slice of implemented key exchange algorithms, ordered by preference
|
||||||
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] =
|
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] =
|
||||||
|
|
@ -55,6 +56,19 @@ pub enum KeyExchangeAlgorithm {
|
||||||
EXT_INFO_C,
|
EXT_INFO_C,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl KeyExchangeAlgorithm {
|
||||||
|
pub fn instance(&self) -> Option<Box<KeyExchange>> {
|
||||||
|
use self::KeyExchangeAlgorithm::*;
|
||||||
|
match self
|
||||||
|
{
|
||||||
|
&CURVE25519_SHA256 => Some(
|
||||||
|
Box::new(key_exchange::Curve25519::new()),
|
||||||
|
),
|
||||||
|
_ => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl FromStr for KeyExchangeAlgorithm {
|
impl FromStr for KeyExchangeAlgorithm {
|
||||||
type Err = ();
|
type Err = ();
|
||||||
fn from_str(s: &str) -> Result<KeyExchangeAlgorithm, ()> {
|
fn from_str(s: &str) -> Result<KeyExchangeAlgorithm, ()> {
|
||||||
|
|
|
||||||
|
|
@ -387,34 +387,40 @@ impl<'a> Connection {
|
||||||
|
|
||||||
pub fn kex_init(&mut self, packet: Packet) -> ConnectionResult<()> {
|
pub fn kex_init(&mut self, packet: Packet) -> ConnectionResult<()> {
|
||||||
use algorithm::*;
|
use algorithm::*;
|
||||||
{
|
|
||||||
|
let (kex_algo, srv_host_key_algo, enc_algo, mac_algo, comp_algo) = {
|
||||||
let mut reader = packet.reader();
|
let mut reader = packet.reader();
|
||||||
let _ = reader.read_bytes(16)?; // Cookie. Throw it away.
|
let _ = reader.read_bytes(16)?; // Cookie. Throw it away.
|
||||||
|
|
||||||
let kex_algos = reader.read_enum_list::<KeyExchangeAlgorithm>()?;
|
let kex_algos = reader.read_enum_list::<KeyExchangeAlgorithm>()?;
|
||||||
let srv_host_key_algos =
|
let srv_host_key_algos =
|
||||||
reader.read_enum_list::<PublicKeyAlgorithm>()?;
|
reader.read_enum_list::<PublicKeyAlgorithm>()?;
|
||||||
|
|
||||||
let enc_algos_c2s = reader.read_enum_list::<EncryptionAlgorithm>()?;
|
let enc_algos_c2s = reader.read_enum_list::<EncryptionAlgorithm>()?;
|
||||||
let enc_algos_s2c = reader.read_enum_list::<EncryptionAlgorithm>()?;
|
let enc_algos_s2c = reader.read_enum_list::<EncryptionAlgorithm>()?;
|
||||||
|
|
||||||
let mac_algos_c2s = reader.read_enum_list::<MacAlgorithm>()?;
|
let mac_algos_c2s = reader.read_enum_list::<MacAlgorithm>()?;
|
||||||
let mac_algos_s2c = reader.read_enum_list::<MacAlgorithm>()?;
|
let mac_algos_s2c = reader.read_enum_list::<MacAlgorithm>()?;
|
||||||
|
|
||||||
let comp_algos_c2s = reader
|
let comp_algos_c2s = reader
|
||||||
.read_enum_list::<CompressionAlgorithm>()?;
|
.read_enum_list::<CompressionAlgorithm>()?;
|
||||||
let comp_algos_s2c = reader
|
let comp_algos_s2c = reader
|
||||||
.read_enum_list::<CompressionAlgorithm>()?;
|
.read_enum_list::<CompressionAlgorithm>()?;
|
||||||
|
|
||||||
let kex_algo = negotiate(KEY_EXCHANGE, kex_algos.as_slice())?;
|
(
|
||||||
let srv_host_key_algo =
|
negotiate(KEY_EXCHANGE, kex_algos.as_slice())?,
|
||||||
negotiate(HOST_KEY, srv_host_key_algos.as_slice())?;
|
negotiate(HOST_KEY, srv_host_key_algos.as_slice())?,
|
||||||
let enc_algo = negotiate(ENCRYPTION, enc_algos_s2c.as_slice())?;
|
negotiate(ENCRYPTION, enc_algos_s2c.as_slice())?,
|
||||||
let mac_algo = negotiate(MAC, mac_algos_s2c.as_slice())?;
|
negotiate(MAC, mac_algos_s2c.as_slice())?,
|
||||||
let comp_algo = negotiate(COMPRESSION, comp_algos_s2c.as_slice())?;
|
negotiate(COMPRESSION, comp_algos_s2c.as_slice())?,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
debug!("Negotiated Kex Algorithm: {:?}", kex_algo);
|
debug!("Negotiated Kex Algorithm: {:?}", kex_algo);
|
||||||
debug!("Negotiated Host Key Algorithm: {:?}", srv_host_key_algo);
|
debug!("Negotiated Host Key Algorithm: {:?}", srv_host_key_algo);
|
||||||
debug!("Negotiated Encryption Algorithm: {:?}", enc_algo);
|
debug!("Negotiated Encryption Algorithm: {:?}", enc_algo);
|
||||||
debug!("Negotiated Mac Algorithm: {:?}", mac_algo);
|
debug!("Negotiated Mac Algorithm: {:?}", mac_algo);
|
||||||
debug!("Negotiated Comp Algorithm: {:?}", comp_algo);
|
debug!("Negotiated Comp Algorithm: {:?}", comp_algo);
|
||||||
}
|
|
||||||
|
|
||||||
// Save payload for hash generation
|
// Save payload for hash generation
|
||||||
self.hash_data.client_kexinit = Some(packet.payload());
|
self.hash_data.client_kexinit = Some(packet.payload());
|
||||||
|
|
@ -443,7 +449,7 @@ impl<'a> Connection {
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
self.state = ConnectionState::KeyExchange;
|
self.state = ConnectionState::KeyExchange;
|
||||||
self.key_exchange = Some(Box::new(key_exchange::Curve25519::new()));
|
self.key_exchange = kex_algo.instance();
|
||||||
|
|
||||||
packet.write_to(&mut self.stream)?;
|
packet.write_to(&mut self.stream)?;
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue