From 77aa0e51962880c170d924fa735f2268772a0652 Mon Sep 17 00:00:00 2001 From: Daniel Mueller Date: Mon, 14 Jan 2019 10:35:52 -0800 Subject: Use rand_os for random data generation The rand crate comes with a slew of dependencies to cover all sort of randomness related tasks in various scenarios. However, this crate really only requires a tiny subset of this functionality. As it turns out, this core functionality is provided by the rand_os crate. This change drops the dependency to rand in favor of rand_os. In order to accomplish that, it brings back the RngError variant for the CommandError enum to capture the possibility of the creation of the random number generator failing. --- CHANGELOG.md | 2 ++ Cargo.toml | 3 ++- src/auth.rs | 5 ++++- src/util.rs | 19 +++++++++++++++---- 4 files changed, 23 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4969c00..51d2b1e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,8 @@ # Unreleased - Add the `get_production_info` and `clear_new_sd_card_warning` methods to the `Storage` struct. +- Use `rand_os` instead of `rand` for random data creation. + - (Re-)add `CommandError::RngError` variant. # v0.3.2 (2019-01-12) - Make three additional error codes known: `CommandError::StringTooLong`, diff --git a/Cargo.toml b/Cargo.toml index 09811f0..ba0923e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,7 +19,8 @@ test-storage = [] [dependencies] libc = "0.2" nitrokey-sys = "3.4" -rand = "0.6" +rand_core = {version = "0.3", default-features = false} +rand_os = {version = "0.1"} [dev-dependencies] nitrokey-test = {version = "0.1"} diff --git a/src/auth.rs b/src/auth.rs index a129bd8..3280924 100644 --- a/src/auth.rs +++ b/src/auth.rs @@ -149,7 +149,10 @@ where A: AuthenticatedDevice, T: Fn(*const i8, *const i8) -> c_int, { - let temp_password = generate_password(TEMPORARY_PASSWORD_LENGTH); + let temp_password = match generate_password(TEMPORARY_PASSWORD_LENGTH) { + Ok(temp_password) => temp_password, + Err(err) => return Err((device, err)), + }; let password = match get_cstring(password) { Ok(password) => password, Err(err) => return Err((device, err)), diff --git a/src/util.rs b/src/util.rs index cb109d0..54062a5 100644 --- a/src/util.rs +++ b/src/util.rs @@ -4,7 +4,8 @@ use std::fmt; use std::os::raw::{c_char, c_int}; use libc::{c_void, free}; -use rand::Rng; +use rand_core::RngCore; +use rand_os::OsRng; /// Error types returned by Nitrokey device or by the library. #[derive(Clone, Copy, Debug, PartialEq)] @@ -44,6 +45,8 @@ pub enum CommandError { InvalidHexString, /// The target buffer was smaller than the source. TargetBufferTooSmall, + /// An error occurred during random number generation. + RngError, } /// Log level for libnitrokey. @@ -106,10 +109,11 @@ pub fn get_last_error() -> CommandError { }; } -pub fn generate_password(length: usize) -> Vec { +pub fn generate_password(length: usize) -> Result, CommandError> { + let mut rng = OsRng::new()?; let mut data = vec![0u8; length]; - rand::thread_rng().fill(&mut data[..]); - return data; + rng.fill_bytes(&mut data[..]); + Ok(data) } pub fn get_cstring>>(s: T) -> Result { @@ -146,6 +150,7 @@ impl CommandError { "The supplied string is not in hexadecimal format".into() } CommandError::TargetBufferTooSmall => "The target buffer is too small".into(), + CommandError::RngError => "An error occurred during random number generation".into(), } } } @@ -178,6 +183,12 @@ impl From for CommandError { } } +impl From for CommandError { + fn from(_error: rand_core::Error) -> Self { + CommandError::RngError + } +} + impl Into for LogLevel { fn into(self) -> i32 { match self { -- cgit v1.2.1