Skip to content

Commit 8f8d753

Browse files
authored
Updates for password-hash trait Params bound changes (#753)
Companion PR to RustCrypto/traits#2106 The afforementioned upstream PR changed the bounds from ones which work on PHC types like `phc::PasswordHash` and `phc::ParamsString` to core traits like `Display` and `FromStr`. This updates the `Params` types in `argon2`, `balloon-hash`, `pbkdf2`, and `scrypt` to impl the traits needed to meet the new bounds. Notably this PR is mostly additive and continues to support all the old traits, while adding support for new ones (thunking through `phc::ParamsString`)
1 parent cb37cc2 commit 8f8d753

File tree

5 files changed

+192
-63
lines changed

5 files changed

+192
-63
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

argon2/src/params.rs

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,10 @@ use base64ct::{Base64Unpadded as B64, Encoding};
55
use core::str::FromStr;
66

77
#[cfg(feature = "password-hash")]
8-
use password_hash::{PasswordHash, phc::ParamsString};
8+
use {
9+
core::fmt::{self, Display},
10+
password_hash::{PasswordHash, phc::ParamsString},
11+
};
912

1013
/// Argon2 password hash parameters.
1114
///
@@ -346,13 +349,29 @@ param_buf!(
346349
);
347350

348351
#[cfg(feature = "password-hash")]
349-
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
352+
impl Display for Params {
353+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
354+
ParamsString::try_from(self).map_err(|_| fmt::Error)?.fmt(f)
355+
}
356+
}
357+
358+
#[cfg(feature = "password-hash")]
359+
impl FromStr for Params {
360+
type Err = password_hash::Error;
361+
362+
fn from_str(s: &str) -> password_hash::Result<Self> {
363+
Self::try_from(&ParamsString::from_str(s)?)
364+
}
365+
}
366+
367+
#[cfg(feature = "password-hash")]
368+
impl TryFrom<&ParamsString> for Params {
350369
type Error = password_hash::Error;
351370

352-
fn try_from(hash: &'a PasswordHash<'a>) -> password_hash::Result<Self> {
371+
fn try_from(params: &ParamsString) -> password_hash::Result<Self> {
353372
let mut builder = ParamsBuilder::new();
354373

355-
for (ident, value) in hash.params.iter() {
374+
for (ident, value) in params.iter() {
356375
match ident.as_str() {
357376
"m" => {
358377
builder.m_cost(value.decimal()?);
@@ -373,11 +392,22 @@ impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
373392
}
374393
}
375394

395+
Ok(builder.build()?)
396+
}
397+
}
398+
399+
#[cfg(feature = "password-hash")]
400+
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
401+
type Error = password_hash::Error;
402+
403+
fn try_from(hash: &'a PasswordHash<'a>) -> password_hash::Result<Self> {
404+
let mut params = Self::try_from(&hash.params)?;
405+
376406
if let Some(output) = &hash.hash {
377-
builder.output_len(output.len());
407+
params.output_len = Some(output.len());
378408
}
379409

380-
Ok(builder.build()?)
410+
Ok(params)
381411
}
382412
}
383413

balloon-hash/src/params.rs

Lines changed: 37 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,16 @@
22
33
use crate::{Error, Result};
44
use core::num::NonZeroU32;
5-
65
#[cfg(feature = "password-hash")]
7-
use password_hash::{
8-
errors::InvalidValue,
9-
phc::{ParamsString, PasswordHash},
6+
use {
7+
core::{
8+
fmt::{self, Display},
9+
str::FromStr,
10+
},
11+
password_hash::{
12+
errors::InvalidValue,
13+
phc::{ParamsString, PasswordHash},
14+
},
1015
};
1116

1217
/// Balloon password hash parameters.
@@ -56,13 +61,29 @@ impl Default for Params {
5661
}
5762

5863
#[cfg(feature = "password-hash")]
59-
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
64+
impl Display for Params {
65+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
66+
ParamsString::try_from(self).map_err(|_| fmt::Error)?.fmt(f)
67+
}
68+
}
69+
70+
#[cfg(feature = "password-hash")]
71+
impl FromStr for Params {
72+
type Err = password_hash::Error;
73+
74+
fn from_str(s: &str) -> password_hash::Result<Self> {
75+
Self::try_from(&ParamsString::from_str(s)?)
76+
}
77+
}
78+
79+
#[cfg(feature = "password-hash")]
80+
impl TryFrom<&ParamsString> for Params {
6081
type Error = password_hash::Error;
6182

62-
fn try_from(hash: &'a PasswordHash<'a>) -> password_hash::Result<Self> {
83+
fn try_from(params_string: &ParamsString) -> password_hash::Result<Self> {
6384
let mut params = Self::default();
6485

65-
for (ident, value) in hash.params.iter() {
86+
for (ident, value) in params_string.iter() {
6687
match ident.as_str() {
6788
"s" => {
6889
params.s_cost = NonZeroU32::new(value.decimal()?)
@@ -84,6 +105,15 @@ impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
84105
}
85106
}
86107

108+
#[cfg(feature = "password-hash")]
109+
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
110+
type Error = password_hash::Error;
111+
112+
fn try_from(hash: &'a PasswordHash<'a>) -> password_hash::Result<Self> {
113+
Self::try_from(&hash.params)
114+
}
115+
}
116+
87117
#[cfg(feature = "password-hash")]
88118
impl TryFrom<Params> for ParamsString {
89119
type Error = password_hash::Error;

pbkdf2/src/simple.rs

Lines changed: 55 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
//! Implementation of the `password-hash` crate API.
22
33
use crate::pbkdf2_hmac;
4-
use core::{cmp::Ordering, fmt, str::FromStr};
4+
use core::{
5+
cmp::Ordering,
6+
fmt::{self, Display, Formatter},
7+
str::FromStr,
8+
};
59
use password_hash::{
610
CustomizedPasswordHasher, Error, PasswordHasher, Result,
711
errors::InvalidValue,
@@ -205,42 +209,59 @@ impl Default for Params {
205209
}
206210
}
207211

208-
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
209-
type Error = Error;
212+
impl Display for Params {
213+
fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
214+
ParamsString::try_from(self).map_err(|_| fmt::Error)?.fmt(f)
215+
}
216+
}
210217

211-
fn try_from(hash: &'a PasswordHash<'a>) -> Result<Self> {
212-
let mut params = Params::default();
213-
let mut output_length = None;
218+
impl FromStr for Params {
219+
type Err = password_hash::Error;
214220

215-
if hash.version.is_some() {
216-
return Err(Error::Version);
217-
}
221+
fn from_str(s: &str) -> password_hash::Result<Self> {
222+
Self::try_from(&ParamsString::from_str(s)?)
223+
}
224+
}
218225

219-
for (ident, value) in hash.params.iter() {
226+
impl TryFrom<&ParamsString> for Params {
227+
type Error = password_hash::Error;
228+
229+
fn try_from(params_string: &ParamsString) -> password_hash::Result<Self> {
230+
let mut params = Params::default();
231+
232+
for (ident, value) in params_string.iter() {
220233
match ident.as_str() {
221234
"i" => params.rounds = value.decimal()?,
222235
"l" => {
223-
output_length = Some(
224-
value
225-
.decimal()?
226-
.try_into()
227-
.map_err(|_| InvalidValue::Malformed.param_error())?,
228-
)
236+
params.output_length = value
237+
.decimal()?
238+
.try_into()
239+
.map_err(|_| InvalidValue::Malformed.param_error())?
229240
}
230241
_ => return Err(Error::ParamNameInvalid),
231242
}
232243
}
233244

234-
if let Some(len) = output_length {
235-
if let Some(hash) = &hash.hash {
236-
match hash.len().cmp(&len) {
237-
Ordering::Less => return Err(InvalidValue::TooShort.param_error()),
238-
Ordering::Greater => return Err(InvalidValue::TooLong.param_error()),
239-
Ordering::Equal => (),
240-
}
241-
}
245+
Ok(params)
246+
}
247+
}
248+
249+
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
250+
type Error = Error;
242251

243-
params.output_length = len;
252+
fn try_from(hash: &'a PasswordHash<'a>) -> Result<Self> {
253+
if hash.version.is_some() {
254+
return Err(Error::Version);
255+
}
256+
257+
let params = Self::try_from(&hash.params)?;
258+
259+
if let Some(hash) = &hash.hash {
260+
match hash.len().cmp(&params.output_length) {
261+
Ordering::Less => return Err(InvalidValue::TooShort.param_error()),
262+
Ordering::Greater => return Err(InvalidValue::TooLong.param_error()),
263+
Ordering::Equal => (),
264+
}
244265
}
245266

246267
Ok(params)
@@ -250,7 +271,15 @@ impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
250271
impl TryFrom<Params> for ParamsString {
251272
type Error = Error;
252273

253-
fn try_from(input: Params) -> Result<ParamsString> {
274+
fn try_from(params: Params) -> Result<ParamsString> {
275+
Self::try_from(&params)
276+
}
277+
}
278+
279+
impl TryFrom<&Params> for ParamsString {
280+
type Error = Error;
281+
282+
fn try_from(input: &Params) -> Result<ParamsString> {
254283
let mut output = ParamsString::new();
255284
output.add_decimal("i", input.rounds)?;
256285
output.add_decimal("l", input.output_length as u32)?;

scrypt/src/params.rs

Lines changed: 63 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,16 @@
1-
use core::mem::size_of;
2-
31
use crate::errors::InvalidParams;
42

53
#[cfg(feature = "simple")]
6-
use password_hash::{
7-
Error,
8-
errors::InvalidValue,
9-
phc::{Output, ParamsString, PasswordHash},
4+
use {
5+
core::{
6+
fmt::{self, Display},
7+
str::FromStr,
8+
},
9+
password_hash::{
10+
Error,
11+
errors::InvalidValue,
12+
phc::{Output, ParamsString, PasswordHash},
13+
},
1014
};
1115

1216
#[cfg(all(feature = "simple", doc))]
@@ -174,19 +178,31 @@ impl Default for Params {
174178
}
175179

176180
#[cfg(feature = "simple")]
177-
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
178-
type Error = password_hash::Error;
181+
impl Display for Params {
182+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
183+
ParamsString::try_from(self).map_err(|_| fmt::Error)?.fmt(f)
184+
}
185+
}
179186

180-
fn try_from(hash: &'a PasswordHash<'a>) -> Result<Self, password_hash::Error> {
187+
#[cfg(feature = "simple")]
188+
impl FromStr for Params {
189+
type Err = Error;
190+
191+
fn from_str(s: &str) -> password_hash::Result<Self> {
192+
Self::try_from(&ParamsString::from_str(s)?)
193+
}
194+
}
195+
196+
#[cfg(feature = "password-hash")]
197+
impl TryFrom<&ParamsString> for Params {
198+
type Error = Error;
199+
200+
fn try_from(params: &ParamsString) -> password_hash::Result<Self> {
181201
let mut log_n = Self::RECOMMENDED_LOG_N;
182202
let mut r = Self::RECOMMENDED_R;
183203
let mut p = Self::RECOMMENDED_P;
184204

185-
if hash.version.is_some() {
186-
return Err(Error::Version);
187-
}
188-
189-
for (ident, value) in hash.params.iter() {
205+
for (ident, value) in params.iter() {
190206
match ident.as_str() {
191207
"ln" => {
192208
log_n = value
@@ -196,25 +212,49 @@ impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
196212
}
197213
"r" => r = value.decimal()?,
198214
"p" => p = value.decimal()?,
199-
_ => return Err(password_hash::Error::ParamNameInvalid),
215+
_ => return Err(Error::ParamNameInvalid),
200216
}
201217
}
202218

203-
let len = hash
204-
.hash
205-
.map(|out| out.len())
206-
.unwrap_or(Self::RECOMMENDED_LEN);
219+
Params::new(log_n, r, p).map_err(|_| InvalidValue::Malformed.param_error())
220+
}
221+
}
222+
223+
#[cfg(feature = "simple")]
224+
impl<'a> TryFrom<&'a PasswordHash<'a>> for Params {
225+
type Error = Error;
226+
227+
fn try_from(hash: &'a PasswordHash<'a>) -> password_hash::Result<Self> {
228+
if hash.version.is_some() {
229+
return Err(Error::Version);
230+
}
231+
232+
let mut params = Params::try_from(&hash.params)?;
233+
234+
params.len = Some(
235+
hash.hash
236+
.map(|out| out.len())
237+
.unwrap_or(Self::RECOMMENDED_LEN),
238+
);
207239

208-
Params::new_with_output_len(log_n, r, p, len)
209-
.map_err(|_| InvalidValue::Malformed.param_error())
240+
Ok(params)
210241
}
211242
}
212243

213244
#[cfg(feature = "simple")]
214245
impl TryFrom<Params> for ParamsString {
215-
type Error = password_hash::Error;
246+
type Error = Error;
247+
248+
fn try_from(params: Params) -> Result<ParamsString, Error> {
249+
Self::try_from(&params)
250+
}
251+
}
252+
253+
#[cfg(feature = "simple")]
254+
impl TryFrom<&Params> for ParamsString {
255+
type Error = Error;
216256

217-
fn try_from(input: Params) -> Result<ParamsString, password_hash::Error> {
257+
fn try_from(input: &Params) -> Result<ParamsString, Error> {
218258
let mut output = ParamsString::new();
219259
output.add_decimal("ln", input.log_n as u32)?;
220260
output.add_decimal("r", input.r)?;

0 commit comments

Comments
 (0)