From 873293a6f871ba6102d75df2379471b43bcf0096 Mon Sep 17 00:00:00 2001 From: Cameron Garnham Date: Wed, 21 Sep 2022 21:12:22 +0200 Subject: [PATCH] crypto: ephemeral instance seeds with keepers * Implement a lazy static that holds ephemeral seeds that are freshly generated on app load. * New `crypto` supporting module that provides a simple interface to accessing the seed. * Provide a 'default seed', that is zeroed-out when testing, and random when not testing. --- src/lib.rs | 11 +++++ src/main.rs | 5 ++- src/protocol/crypto.rs | 98 ++++++++++++++++++++++++++++++++++++++++++ src/protocol/mod.rs | 1 + 4 files changed, 114 insertions(+), 1 deletion(-) create mode 100644 src/protocol/crypto.rs diff --git a/src/lib.rs b/src/lib.rs index 882e126bc..5f003b5fd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -27,3 +27,14 @@ pub mod static_time { pub static ref TIME_AT_APP_START: SystemTime = SystemTime::now(); } } + +pub mod ephemeral_instance_keys { + use rand::rngs::ThreadRng; + use rand::Rng; + + pub type Seed = [u8; 32]; + + lazy_static! { + pub static ref RANDOM_SEED: Seed = Rng::gen(&mut ThreadRng::default()); + } +} diff --git a/src/main.rs b/src/main.rs index 47896ff43..bac7854bb 100644 --- a/src/main.rs +++ b/src/main.rs @@ -3,7 +3,7 @@ use std::sync::Arc; use log::info; use torrust_tracker::tracker::statistics::StatsTracker; use torrust_tracker::tracker::tracker::TorrentTracker; -use torrust_tracker::{logging, setup, static_time, Configuration}; +use torrust_tracker::{ephemeral_instance_keys, logging, setup, static_time, Configuration}; #[tokio::main] async fn main() { @@ -12,6 +12,9 @@ async fn main() { // Set the time of Torrust app starting lazy_static::initialize(&static_time::TIME_AT_APP_START); + // Initialize the Ephemeral Instance Random Seed + lazy_static::initialize(&ephemeral_instance_keys::RANDOM_SEED); + // Initialize Torrust config let config = match Configuration::load_from_file(CONFIG_PATH) { Ok(config) => Arc::new(config), diff --git a/src/protocol/crypto.rs b/src/protocol/crypto.rs new file mode 100644 index 000000000..18cfaf5e6 --- /dev/null +++ b/src/protocol/crypto.rs @@ -0,0 +1,98 @@ +pub mod keys { + + pub mod seeds { + use self::detail::DEFAULT_SEED; + use crate::ephemeral_instance_keys::{Seed, RANDOM_SEED}; + + pub trait SeedKeeper { + type Seed: Sized + Default + AsMut<[u8]>; + fn get_seed() -> &'static Self::Seed; + } + + pub struct InstanceSeed; + pub struct DefaultSeed; + + impl SeedKeeper for InstanceSeed { + type Seed = Seed; + + fn get_seed() -> &'static Self::Seed { + &RANDOM_SEED + } + } + + impl SeedKeeper for DefaultSeed { + type Seed = Seed; + + #[allow(clippy::needless_borrow)] + fn get_seed() -> &'static Self::Seed { + &DEFAULT_SEED + } + } + + #[cfg(test)] + mod tests { + use super::detail::ZEROED_TEST_SEED; + use super::{DefaultSeed, InstanceSeed, SeedKeeper}; + use crate::ephemeral_instance_keys::Seed; + + pub struct ZeroedTestSeed; + + impl SeedKeeper for ZeroedTestSeed { + type Seed = Seed; + + #[allow(clippy::needless_borrow)] + fn get_seed() -> &'static Self::Seed { + &ZEROED_TEST_SEED + } + } + + #[test] + fn the_default_seed_and_the_zeroed_seed_should_be_the_same_when_testing() { + assert_eq!(DefaultSeed::get_seed(), ZeroedTestSeed::get_seed()) + } + + #[test] + fn the_default_seed_and_the_instance_seed_should_be_different_when_testing() { + assert_ne!(DefaultSeed::get_seed(), InstanceSeed::get_seed()) + } + } + + mod detail { + use crate::ephemeral_instance_keys::Seed; + + #[allow(dead_code)] + pub const ZEROED_TEST_SEED: &Seed = &[0u8; 32]; + + #[cfg(test)] + pub use ZEROED_TEST_SEED as DEFAULT_SEED; + + #[cfg(not(test))] + pub use crate::ephemeral_instance_keys::RANDOM_SEED as DEFAULT_SEED; + + #[cfg(test)] + mod tests { + use std::convert::TryInto; + + use crate::ephemeral_instance_keys::RANDOM_SEED; + use crate::protocol::crypto::keys::seeds::detail::ZEROED_TEST_SEED; + use crate::protocol::crypto::keys::seeds::DEFAULT_SEED; + + #[test] + fn it_should_have_a_zero_test_seed() { + assert_eq!(*ZEROED_TEST_SEED, [0u8; 32]) + } + + #[test] + fn it_should_default_to_zeroed_seed_when_testing() { + assert_eq!(*DEFAULT_SEED, *ZEROED_TEST_SEED) + } + + #[test] + fn it_should_have_a_large_random_seed() { + assert!(u128::from_ne_bytes((*RANDOM_SEED)[..16].try_into().unwrap()) > u64::MAX as u128); + assert!(u128::from_ne_bytes((*RANDOM_SEED)[16..].try_into().unwrap()) > u64::MAX as u128); + } + } + } + } +} diff --git a/src/protocol/mod.rs b/src/protocol/mod.rs index fcb28b3b2..85e4f90ad 100644 --- a/src/protocol/mod.rs +++ b/src/protocol/mod.rs @@ -1,3 +1,4 @@ pub mod clock; pub mod common; +pub mod crypto; pub mod utils;