More tests

This commit is contained in:
Dennis Schwerdel 2020-10-19 22:38:32 +02:00
parent 8e581ad005
commit 4f2b09d92c
2 changed files with 143 additions and 12 deletions

16
Cargo.lock generated
View File

@ -69,9 +69,9 @@ checksum = "0e4cec68f03f32e44924783795810fa50a7035d8c8ebe78580ad7e6c703fba38"
[[package]] [[package]]
name = "cc" name = "cc"
version = "1.0.60" version = "1.0.61"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ef611cc68ff783f18535d77ddd080185275713d852c4f5cbb6122c462a7a825c" checksum = "ed67cbde08356238e75fc4656be4749481eeffb09e19f320a25237d5221c985d"
[[package]] [[package]]
name = "cfg-if" name = "cfg-if"
@ -461,9 +461,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.58" version = "1.0.59"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a230ea9107ca2220eea9d46de97eddcb04cd00e92d13dda78e478dd33fa82bd4" checksum = "dcac07dbffa1c65e7f816ab9eba78eb142c6d44410f4eeba1e26e4f5dfa56b95"
dependencies = [ dependencies = [
"itoa", "itoa",
"ryu", "ryu",
@ -512,9 +512,9 @@ checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d"
[[package]] [[package]]
name = "standback" name = "standback"
version = "0.2.10" version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "33a71ea1ea5f8747d1af1979bfb7e65c3a025a70609f04ceb78425bc5adad8e6" checksum = "f4e0831040d2cf2bdfd51b844be71885783d489898a192f254ae25d57cce725c"
dependencies = [ dependencies = [
"version_check", "version_check",
] ]
@ -600,9 +600,9 @@ dependencies = [
[[package]] [[package]]
name = "syn" name = "syn"
version = "1.0.42" version = "1.0.45"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9c51d92969d209b54a98397e1b91c8ae82d8c87a7bb87df0b29aa2ad81454228" checksum = "ea9c5432ff16d6152371f808fb5a871cd67368171b09bb21b43df8e4a47a3556"
dependencies = [ dependencies = [
"proc-macro2", "proc-macro2",
"quote", "quote",

View File

@ -388,6 +388,7 @@ pub struct InitState<P: Payload> {
last_message: Option<Vec<u8>>, last_message: Option<Vec<u8>>,
crypto: Option<CryptoCore>, crypto: Option<CryptoCore>,
algorithms: Algorithms, algorithms: Algorithms,
selected_algorithm: Option<&'static Algorithm>,
failed_retries: usize failed_retries: usize
} }
@ -413,6 +414,7 @@ impl<P: Payload> InitState<P> {
last_message: None, last_message: None,
crypto: None, crypto: None,
ecdh_private_key: None, ecdh_private_key: None,
selected_algorithm: None,
algorithms, algorithms,
failed_retries: 0, failed_retries: 0,
close_time: 60 close_time: 60
@ -605,6 +607,7 @@ impl<P: Payload> InitState<P> {
// do ecdh agreement and derive master key // do ecdh agreement and derive master key
let algorithm = self.select_algorithm(&algorithms)?; let algorithm = self.select_algorithm(&algorithms)?;
self.selected_algorithm = algorithm.map(|a| a.0);
if let Some((algorithm, _speed)) = algorithm { if let Some((algorithm, _speed)) = algorithm {
let master_key = self.derive_master_key(algorithm, my_ecdh_private_key, &ecdh_public_key); let master_key = self.derive_master_key(algorithm, my_ecdh_private_key, &ecdh_public_key);
self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash)); self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash));
@ -620,6 +623,7 @@ impl<P: Payload> InitState<P> {
// do ecdh agreement and derive master key // do ecdh agreement and derive master key
let ecdh_private_key = self.ecdh_private_key.take().unwrap(); let ecdh_private_key = self.ecdh_private_key.take().unwrap();
let algorithm = self.select_algorithm(&algorithms)?; let algorithm = self.select_algorithm(&algorithms)?;
self.selected_algorithm = algorithm.map(|a| a.0);
if let Some((algorithm, _speed)) = algorithm { if let Some((algorithm, _speed)) = algorithm {
let master_key = self.derive_master_key(algorithm, ecdh_private_key, &ecdh_public_key); let master_key = self.derive_master_key(algorithm, ecdh_private_key, &ecdh_public_key);
self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash)); self.crypto = Some(CryptoCore::new(master_key, self.salted_node_id_hash > salted_node_id_hash));
@ -793,11 +797,138 @@ mod tests {
assert_eq!(sender.stage(), CLOSING); assert_eq!(sender.stage(), CLOSING);
} }
// TODO Test: duplicated message or replay attacks #[test]
fn untrusted_peer() {
// TODO Test: untrusted peers let (mut sender, _) = create_pair();
let (_, mut receiver) = create_pair();
// TODO Test: manipulated message let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
// TODO Test: algorithm negotiation assert_eq!(sender.stage(), STAGE_PONG);
assert!(receiver.handle_init(&mut out).is_err());
}
#[test]
fn manipulated_message() {
let (mut sender, mut receiver) = create_pair();
let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
assert_eq!(sender.stage(), STAGE_PONG);
out.message_mut()[10] ^= 0x01;
assert!(receiver.handle_init(&mut out).is_err());
}
#[test]
fn connect_to_self() {
let (mut sender, _) = create_pair();
let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
assert_eq!(sender.stage(), STAGE_PONG);
assert!(sender.handle_init(&mut out).is_err());
}
fn test_algorithm_negotiation(
algos1: Algorithms, algos2: Algorithms, success: bool, selected: Option<&'static Algorithm>
) {
let (mut sender, mut receiver) = create_pair();
sender.algorithms = algos1;
receiver.algorithms = algos2;
let mut out = MsgBuffer::new(8);
sender.send_ping(&mut out);
let res = receiver.handle_init(&mut out);
assert_eq!(res.is_ok(), success);
if !success {
return
}
sender.handle_init(&mut out).unwrap();
receiver.handle_init(&mut out).unwrap();
assert_eq!(sender.selected_algorithm, selected);
assert_eq!(sender.selected_algorithm, receiver.selected_algorithm);
}
#[test]
fn algorithm_negotiation() {
// Equal algorithms
test_algorithm_negotiation(
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: false
},
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: false
},
true,
Some(&AES_128_GCM)
);
// Overlapping but different
test_algorithm_negotiation(
Algorithms {
algorithm_speeds: smallvec![(&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: false
},
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0)],
allow_unencrypted: false
},
true,
Some(&AES_256_GCM)
);
// Select fastest pair
test_algorithm_negotiation(
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: false
},
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 40.0), (&AES_256_GCM, 50.0), (&CHACHA20_POLY1305, 60.0)],
allow_unencrypted: false
},
true,
Some(&CHACHA20_POLY1305)
);
// Select unencrypted if supported by both
test_algorithm_negotiation(
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: true
},
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: true
},
true,
None
);
// Do not select unencrypted if only supported by one
test_algorithm_negotiation(
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: true
},
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0), (&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: false
},
true,
Some(&AES_128_GCM)
);
// Fail if no match
test_algorithm_negotiation(
Algorithms {
algorithm_speeds: smallvec![(&AES_128_GCM, 600.0)],
allow_unencrypted: true
},
Algorithms {
algorithm_speeds: smallvec![(&AES_256_GCM, 500.0), (&CHACHA20_POLY1305, 400.0)],
allow_unencrypted: false
},
false,
Some(&AES_128_GCM)
);
}
} }