Commit 743cb40e authored by Thomas Gatzweiler's avatar Thomas Gatzweiler
Browse files

Implement dynamic key exchange selection"

parent 874f4231
......@@ -2,6 +2,7 @@ use std::fmt;
use std::str::FromStr;
use error::{ConnectionError, ConnectionResult};
use key_exchange::{self, KeyExchange};
/// Slice of implemented key exchange algorithms, ordered by preference
pub static KEY_EXCHANGE: &[KeyExchangeAlgorithm] =
......@@ -55,6 +56,19 @@ pub enum KeyExchangeAlgorithm {
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 {
type Err = ();
fn from_str(s: &str) -> Result<KeyExchangeAlgorithm, ()> {
......
......@@ -387,34 +387,40 @@ impl<'a> Connection {
pub fn kex_init(&mut self, packet: Packet) -> ConnectionResult<()> {
use algorithm::*;
{
let (kex_algo, srv_host_key_algo, enc_algo, mac_algo, comp_algo) = {
let mut reader = packet.reader();
let _ = reader.read_bytes(16)?; // Cookie. Throw it away.
let kex_algos = reader.read_enum_list::<KeyExchangeAlgorithm>()?;
let srv_host_key_algos =
reader.read_enum_list::<PublicKeyAlgorithm>()?;
let enc_algos_c2s = 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_s2c = reader.read_enum_list::<MacAlgorithm>()?;
let comp_algos_c2s = reader
.read_enum_list::<CompressionAlgorithm>()?;
let comp_algos_s2c = reader
.read_enum_list::<CompressionAlgorithm>()?;
let kex_algo = negotiate(KEY_EXCHANGE, kex_algos.as_slice())?;
let srv_host_key_algo =
negotiate(HOST_KEY, srv_host_key_algos.as_slice())?;
let enc_algo = negotiate(ENCRYPTION, enc_algos_s2c.as_slice())?;
let mac_algo = negotiate(MAC, mac_algos_s2c.as_slice())?;
let comp_algo = negotiate(COMPRESSION, comp_algos_s2c.as_slice())?;
debug!("Negotiated Kex Algorithm: {:?}", kex_algo);
debug!("Negotiated Host Key Algorithm: {:?}", srv_host_key_algo);
debug!("Negotiated Encryption Algorithm: {:?}", enc_algo);
debug!("Negotiated Mac Algorithm: {:?}", mac_algo);
debug!("Negotiated Comp Algorithm: {:?}", comp_algo);
}
(
negotiate(KEY_EXCHANGE, kex_algos.as_slice())?,
negotiate(HOST_KEY, srv_host_key_algos.as_slice())?,
negotiate(ENCRYPTION, enc_algos_s2c.as_slice())?,
negotiate(MAC, mac_algos_s2c.as_slice())?,
negotiate(COMPRESSION, comp_algos_s2c.as_slice())?,
)
};
debug!("Negotiated Kex Algorithm: {:?}", kex_algo);
debug!("Negotiated Host Key Algorithm: {:?}", srv_host_key_algo);
debug!("Negotiated Encryption Algorithm: {:?}", enc_algo);
debug!("Negotiated Mac Algorithm: {:?}", mac_algo);
debug!("Negotiated Comp Algorithm: {:?}", comp_algo);
// Save payload for hash generation
self.hash_data.client_kexinit = Some(packet.payload());
......@@ -443,7 +449,7 @@ impl<'a> Connection {
})?;
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)?;
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment