diff --git a/Cargo.lock b/Cargo.lock index c3e9b5b92..a85022924 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3072,7 +3072,7 @@ dependencies = [ "md-5", "openssl", "openssl-sys", - "rand 0.8.5", + "rand 0.9.1", "serde", "sha-crypt", "sha2", @@ -3302,7 +3302,7 @@ dependencies = [ "num_enum", "openssl", "openssl-sys", - "rand 0.8.5", + "rand 0.9.1", "regex", "rusqlite", "serde", @@ -4216,8 +4216,8 @@ dependencies = [ "kanidm_client", "mathru", "mimalloc", - "rand 0.8.5", - "rand_chacha 0.3.1", + "rand 0.9.1", + "rand_chacha 0.9.0", "serde", "serde_json", "tokio", @@ -4602,7 +4602,7 @@ checksum = "b820744eb4dc9b57a3398183639c511b5a26d2ed702cedd3febaa1393caa22cc" dependencies = [ "bytes", "getrandom 0.3.2", - "rand 0.9.0", + "rand 0.9.1", "ring", "rustc-hash 2.1.1", "rustls", @@ -4656,13 +4656,12 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.0" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", - "zerocopy 0.8.24", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 9dbaa47c1..6761d8275 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -237,8 +237,8 @@ prctl = "1.0.0" proc-macro2 = "1.0.93" qrcode = "^0.12.0" quote = "1" -rand = "^0.8.5" -rand_chacha = "0.3.1" +rand = "0.9.1" +rand_chacha = "0.9.0" regex = "1.11.0" reqwest = { version = "0.12.12", default-features = false, features = [ "cookies", diff --git a/libs/crypto/src/lib.rs b/libs/crypto/src/lib.rs index f95b2ae73..c1417d35b 100644 --- a/libs/crypto/src/lib.rs +++ b/libs/crypto/src/lib.rs @@ -834,9 +834,9 @@ impl TryFrom<&str> for Password { impl Password { fn bench_pbkdf2(pbkdf2_cost: usize) -> Option<Duration> { - let mut rng = rand::thread_rng(); - let salt: Vec<u8> = (0..PBKDF2_SALT_LEN).map(|_| rng.gen()).collect(); - let input: Vec<u8> = (0..PBKDF2_SALT_LEN).map(|_| rng.gen()).collect(); + let mut rng = rand::rng(); + let salt: Vec<u8> = (0..PBKDF2_SALT_LEN).map(|_| rng.random()).collect(); + let input: Vec<u8> = (0..PBKDF2_SALT_LEN).map(|_| rng.random()).collect(); // This is 512 bits of output let mut key: Vec<u8> = (0..PBKDF2_KEY_LEN).map(|_| 0).collect(); @@ -855,9 +855,9 @@ impl Password { } fn bench_argon2id(params: Params) -> Option<Duration> { - let mut rng = rand::thread_rng(); - let salt: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.gen()).collect(); - let input: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.gen()).collect(); + let mut rng = rand::rng(); + let salt: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.random()).collect(); + let input: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.random()).collect(); let mut key: Vec<u8> = (0..ARGON2_KEY_LEN).map(|_| 0).collect(); let argon = Argon2::new(Algorithm::Argon2id, Version::V0x13, params); @@ -873,8 +873,8 @@ impl Password { pub fn new_pbkdf2(policy: &CryptoPolicy, cleartext: &str) -> Result<Self, CryptoError> { let pbkdf2_cost = policy.pbkdf2_cost; - let mut rng = rand::thread_rng(); - let salt: Vec<u8> = (0..PBKDF2_SALT_LEN).map(|_| rng.gen()).collect(); + let mut rng = rand::rng(); + let salt: Vec<u8> = (0..PBKDF2_SALT_LEN).map(|_| rng.random()).collect(); let mut key: Vec<u8> = (0..PBKDF2_KEY_LEN).map(|_| 0).collect(); pbkdf2_hmac( @@ -897,8 +897,8 @@ impl Password { let argon = Argon2::new(Algorithm::Argon2id, version, policy.argon2id_params.clone()); - let mut rng = rand::thread_rng(); - let salt: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.gen()).collect(); + let mut rng = rand::rng(); + let salt: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.random()).collect(); let mut key: Vec<u8> = (0..ARGON2_KEY_LEN).map(|_| 0).collect(); argon @@ -925,8 +925,8 @@ impl Password { let argon = Argon2::new(Algorithm::Argon2id, version, policy.argon2id_params.clone()); - let mut rng = rand::thread_rng(); - let salt: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.gen()).collect(); + let mut rng = rand::rng(); + let salt: Vec<u8> = (0..ARGON2_SALT_LEN).map(|_| rng.random()).collect(); let mut check_key: Vec<u8> = (0..ARGON2_KEY_LEN).map(|_| 0).collect(); argon diff --git a/server/lib/src/credential/totp.rs b/server/lib/src/credential/totp.rs index f6ae0fd1e..e887f90e9 100644 --- a/server/lib/src/credential/totp.rs +++ b/server/lib/src/credential/totp.rs @@ -145,8 +145,8 @@ impl Totp { // Create a new token with secure key and algo. pub fn generate_secure(step: u64) -> Self { - let mut rng = rand::thread_rng(); - let secret: Vec<u8> = (0..SECRET_SIZE_BYTES).map(|_| rng.gen()).collect(); + let mut rng = rand::rng(); + let secret: Vec<u8> = (0..SECRET_SIZE_BYTES).map(|_| rng.random()).collect(); let algo = TotpAlgo::Sha256; let digits = TotpDigits::Six; Totp { diff --git a/server/lib/src/idm/oauth2.rs b/server/lib/src/idm/oauth2.rs index 9628e1ea4..dc9d8a73f 100644 --- a/server/lib/src/idm/oauth2.rs +++ b/server/lib/src/idm/oauth2.rs @@ -2992,11 +2992,12 @@ fn validate_scopes(req_scopes: &BTreeSet<String>) -> Result<(), Oauth2Error> { #[cfg(any(feature = "dev-oauth2-device-flow", test))] #[allow(dead_code)] fn gen_device_code() -> Result<[u8; 16], Oauth2Error> { - let mut rng = rand::thread_rng(); + use rand::TryRngCore; + + let mut rng = rand::rng(); let mut result = [0u8; 16]; // doing it here because of feature-shenanigans. - use rand::Rng; - if let Err(err) = rng.try_fill(&mut result) { + if let Err(err) = rng.try_fill_bytes(&mut result) { error!("Failed to generate device code! {:?}", err); return Err(Oauth2Error::ServerError(OperationError::Backend)); } @@ -3009,8 +3010,8 @@ fn gen_device_code() -> Result<[u8; 16], Oauth2Error> { /// Returns (xxx-yyy-zzz, digits) where one's the human-facing code, the other is what we store in the DB. fn gen_user_code() -> (String, u32) { use rand::Rng; - let mut rng = rand::thread_rng(); - let num: u32 = rng.gen_range(0..=999999999); + let mut rng = rand::rng(); + let num: u32 = rng.random_range(0..=999999999); let result = format!("{:09}", num); ( format!("{}-{}-{}", &result[0..3], &result[3..6], &result[6..9]), diff --git a/server/lib/src/idm/server.rs b/server/lib/src/idm/server.rs index d6fc173ea..d047bb319 100644 --- a/server/lib/src/idm/server.rs +++ b/server/lib/src/idm/server.rs @@ -236,7 +236,7 @@ impl IdmServer { let qs_read = self.qs.read().await?; let mut sid = [0; 4]; - let mut rng = StdRng::from_entropy(); + let mut rng = StdRng::from_os_rng(); rng.fill(&mut sid); Ok(IdmServerAuthTransaction { @@ -279,7 +279,7 @@ impl IdmServer { let qs_write = self.qs.write(ts).await?; let mut sid = [0; 4]; - let mut rng = StdRng::from_entropy(); + let mut rng = StdRng::from_os_rng(); rng.fill(&mut sid); Ok(IdmServerProxyWriteTransaction { diff --git a/server/lib/src/utils.rs b/server/lib/src/utils.rs index 1c762b027..2179f45b7 100644 --- a/server/lib/src/utils.rs +++ b/server/lib/src/utils.rs @@ -2,8 +2,8 @@ use crate::prelude::*; use hashbrown::HashSet; -use rand::distributions::{Distribution, Uniform}; -use rand::{thread_rng, Rng}; +use rand::distr::{Distribution, Uniform}; +use rand::{rng, Rng}; use std::ops::Range; #[derive(Debug)] @@ -35,7 +35,7 @@ pub fn uuid_from_duration(d: Duration, sid: Sid) -> Uuid { } pub(crate) fn password_from_random_len(len: u32) -> String { - thread_rng() + rng() .sample_iter(&DistinctAlpha) .take(len as usize) .collect::<String>() @@ -52,7 +52,7 @@ pub fn backup_code_from_random() -> HashSet<String> { pub fn readable_password_from_random() -> String { // 2^112 bits, means we need at least 55^20 to have as many bits of entropy. // this leads us to 4 groups of 5 to create 55^20 - let mut trng = thread_rng(); + let mut trng = rng(); format!( "{}-{}-{}-{}", (&mut trng) @@ -81,7 +81,7 @@ impl Distribution<char> for DistinctAlpha { abcdefghjkpqrstuvwxyz\ 0123456789"; - let range = Uniform::new(0, RANGE); + let range = Uniform::new(0, RANGE).expect("Failed to get a uniform range"); let n = range.sample(rng); GEN_ASCII_STR_CHARSET[n as usize] as char diff --git a/tools/orca/src/error.rs b/tools/orca/src/error.rs index a2cc9697d..f73d3913b 100644 --- a/tools/orca/src/error.rs +++ b/tools/orca/src/error.rs @@ -8,4 +8,6 @@ pub enum Error { Interrupt, Crossbeam, InvalidState, + #[allow(dead_code)] + RandomNumber(String), } diff --git a/tools/orca/src/generate.rs b/tools/orca/src/generate.rs index afd779ff2..b34bf5fd8 100644 --- a/tools/orca/src/generate.rs +++ b/tools/orca/src/generate.rs @@ -4,8 +4,9 @@ use crate::model::ActorRole; use crate::profile::Profile; use crate::state::{Credential, Flag, Group, GroupName, Person, PreflightState, State}; use hashbrown::HashMap; -use rand::distributions::{Alphanumeric, DistString, Uniform}; -use rand::seq::{index, SliceRandom}; +use rand::distr::{Alphanumeric, SampleString, Uniform}; +use rand::seq::{index, IndexedRandom}; + use rand::{Rng, SeedableRng}; use rand_chacha::ChaCha8Rng; @@ -171,7 +172,8 @@ pub async fn populate(_client: &KanidmOrcaClient, profile: Profile) -> Result<St let baseline = persons.len() / 3; let inverse = persons.len() - baseline; // Randomly add extra from the inverse - let extra = Uniform::new(0, inverse); + let extra = + Uniform::new(0, inverse).map_err(|err| Error::RandomNumber(err.to_string()))?; baseline + seeded_rng.sample(extra) } }; diff --git a/tools/orca/src/models/basic.rs b/tools/orca/src/models/basic.rs index c362906a4..23f4c3142 100644 --- a/tools/orca/src/models/basic.rs +++ b/tools/orca/src/models/basic.rs @@ -27,7 +27,7 @@ impl ActorBasic { pub fn new(mut cha_rng: ChaCha8Rng, warmup_time_ms: u64) -> Self { let max_backoff_time_in_ms = 2 * warmup_time_ms / 3; let randomised_backoff_time = - Duration::from_millis(cha_rng.gen_range(0..max_backoff_time_in_ms)); + Duration::from_millis(cha_rng.random_range(0..max_backoff_time_in_ms)); ActorBasic { state: State::Unauthenticated, randomised_backoff_time, diff --git a/tools/orca/src/models/latency_measurer.rs b/tools/orca/src/models/latency_measurer.rs index 6601fac09..d681186a3 100644 --- a/tools/orca/src/models/latency_measurer.rs +++ b/tools/orca/src/models/latency_measurer.rs @@ -76,7 +76,7 @@ impl ActorLatencyMeasurer { let max_backoff_time_in_ms = 2 * warmup_time_ms / 3; let randomised_backoff_time = - Duration::from_millis(cha_rng.gen_range(0..max_backoff_time_in_ms)); + Duration::from_millis(cha_rng.random_range(0..max_backoff_time_in_ms)); Ok(ActorLatencyMeasurer { state: State::Unauthenticated, randomised_backoff_time, diff --git a/tools/orca/src/models/read.rs b/tools/orca/src/models/read.rs index f11eb9984..b280f0b5d 100644 --- a/tools/orca/src/models/read.rs +++ b/tools/orca/src/models/read.rs @@ -25,7 +25,7 @@ impl ActorReader { pub fn new(mut cha_rng: ChaCha8Rng, warmup_time_ms: u64) -> Self { let max_backoff_time_in_ms = warmup_time_ms - 1000; let randomised_backoff_time = - Duration::from_millis(cha_rng.gen_range(0..max_backoff_time_in_ms)); + Duration::from_millis(cha_rng.random_range(0..max_backoff_time_in_ms)); ActorReader { state: State::Unauthenticated, randomised_backoff_time, diff --git a/tools/orca/src/models/write.rs b/tools/orca/src/models/write.rs index 969f153ff..09da27c1a 100644 --- a/tools/orca/src/models/write.rs +++ b/tools/orca/src/models/write.rs @@ -26,7 +26,7 @@ impl ActorWriter { pub fn new(mut cha_rng: ChaCha8Rng, warmup_time_ms: u64) -> Self { let max_backoff_time_in_ms = 2 * warmup_time_ms / 3; let randomised_backoff_time = - Duration::from_millis(cha_rng.gen_range(0..max_backoff_time_in_ms)); + Duration::from_millis(cha_rng.random_range(0..max_backoff_time_in_ms)); ActorWriter { state: State::Unauthenticated, randomised_backoff_time, diff --git a/tools/orca/src/profile.rs b/tools/orca/src/profile.rs index 9b080d81d..d39a4c77b 100644 --- a/tools/orca/src/profile.rs +++ b/tools/orca/src/profile.rs @@ -1,6 +1,6 @@ use crate::error::Error; use crate::state::{GroupName, Model}; -use rand::{thread_rng, Rng}; +use rand::{rng, Rng}; use serde::de::{value, IntoDeserializer}; use serde::{Deserialize, Serialize}; use std::collections::BTreeMap; @@ -200,8 +200,8 @@ impl ProfileBuilder { } = self; let seed: u64 = seed.unwrap_or_else(|| { - let mut rng = thread_rng(); - rng.gen() + let mut rng = rng(); + rng.random() }); //TODO: Allow to specify group properties from the CLI diff --git a/tools/orca/src/run.rs b/tools/orca/src/run.rs index 393e6981f..c95187828 100644 --- a/tools/orca/src/run.rs +++ b/tools/orca/src/run.rs @@ -187,7 +187,7 @@ pub async fn execute(state: State, control_rx: broadcast::Receiver<Signal>) -> R }) }) .collect::<Result<Vec<_>, _>>()?; - let main_client_index = seeded_rng.gen_range(0..cloned_clients.len()); + let main_client_index = seeded_rng.random_range(0..cloned_clients.len()); let main_client = cloned_clients.remove(main_client_index); //note that cloned_clients now contains all other clients except the first one