diff options
author | Brian Warner <warner@lothar.com> | 2018-06-03 13:57:19 -0700 |
---|---|---|
committer | Brian Warner <warner@lothar.com> | 2018-06-03 14:56:20 -0700 |
commit | 0869881573ec805ec2337469ed5c4184cb0382e2 (patch) | |
tree | f9d3b91ddad329910a6ec0ea9693d25616af4651 /benches/spake2.rs | |
parent | 9bd20219ac9d6727a4b99cf6dd48e44b3190c6c9 (diff) | |
download | PAKEs-0869881573ec805ec2337469ed5c4184cb0382e2.tar.xz |
use newtypes for Password and Identity to avoid usage errors
This a breaking API change. The next release should bump the minor version
number.
As discussed in https://github.com/warner/spake2.rs/issues/3 and
https://github.com/warner/magic-wormhole.rs/issues/32 , if an application
were to accidentally swap the "password" and "identity" arguments (mainly for
start_symmetric which only takes two args), the app would appear to work, but
would contain a devastating security vulnerability (online brute-force
password attack, with precomputation enabled).
You might think of newtypes as giving the API named parameters. Instead of:
`s = start_symmetric(b"pw", b"appid")`
you get:
`s = start_symmetric(&Password::new(b"pw"), &Identity::new(b"appid"))`
but it protects you (with a compile-time error) against mistakes like:
`s = start_symmetric(&Identity::new(b"appid"), &Password::new(b"pw"))`
I'd like to find a way to remove requirement to pass a reference (and enable
`start_symmetric(Password::new(..)..)`).
Diffstat (limited to 'benches/spake2.rs')
-rw-r--r-- | benches/spake2.rs | 41 |
1 files changed, 29 insertions, 12 deletions
diff --git a/benches/spake2.rs b/benches/spake2.rs index d945d5a..8323342 100644 --- a/benches/spake2.rs +++ b/benches/spake2.rs @@ -4,32 +4,49 @@ extern crate bencher; extern crate spake2; use bencher::Bencher; -use spake2::{Ed25519Group, SPAKE2}; +use spake2::{Ed25519Group, Identity, Password, SPAKE2}; fn spake2_start(bench: &mut Bencher) { bench.iter(|| { - let (_, _) = SPAKE2::<Ed25519Group>::start_a(b"password", b"A", b"B"); + let (_, _) = SPAKE2::<Ed25519Group>::start_a( + &Password::new(b"password"), + &Identity::new(b"idA"), + &Identity::new(b"idB"), + ); }) } /* fn spake2_finish(bench: &mut Bencher) { // this doesn't work, because s1 is consumed by doing finish() - let (s1, msg1) = SPAKE2::<Ed25519Group>::start_a(b"password", - b"idA", b"idB"); - let (s2, msg2) = SPAKE2::<Ed25519Group>::start_b(b"password", - b"idA", b"idB"); + let (s1, msg1) = SPAKE2::<Ed25519Group>::start_a( + &Password::new(b"password"), + &Identity::new(b"idA"), + &Identity::new(b"idB"), + ); + let (s2, msg2) = SPAKE2::<Ed25519Group>::start_b( + &Password::new(b"password"), + &Identity::new(b"idA"), + &Identity::new(b"idB"), + ); let msg2_slice = msg2.as_slice(); - bench.iter(|| { - s1.finish(msg2_slice) - }) -}*/ + bench.iter(|| s1.finish(msg2_slice)) +} +*/ fn spake2_start_and_finish(bench: &mut Bencher) { - let (_, msg2) = SPAKE2::<Ed25519Group>::start_b(b"password", b"idA", b"idB"); + let (_, msg2) = SPAKE2::<Ed25519Group>::start_b( + &Password::new(b"password"), + &Identity::new(b"idA"), + &Identity::new(b"idB"), + ); let msg2_slice = msg2.as_slice(); bench.iter(|| { - let (s1, _) = SPAKE2::<Ed25519Group>::start_a(b"password", b"idA", b"idB"); + let (s1, _) = SPAKE2::<Ed25519Group>::start_a( + &Password::new(b"password"), + &Identity::new(b"idA"), + &Identity::new(b"idB"), + ); s1.finish(msg2_slice) }) } |