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 /src/lib.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 'src/lib.rs')
-rw-r--r-- | src/lib.rs | 48 |
1 files changed, 39 insertions, 9 deletions
@@ -10,12 +10,20 @@ pub use spake2::*; #[cfg(test)] mod tests { - use spake2::{Ed25519Group, ErrorType, SPAKE2, SPAKEErr}; + use spake2::{Ed25519Group, ErrorType, Identity, Password, SPAKE2, SPAKEErr}; #[test] fn test_basic() { - 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 key1 = s1.finish(msg2.as_slice()).unwrap(); let key2 = s2.finish(msg1.as_slice()).unwrap(); assert_eq!(key1, key2); @@ -23,8 +31,16 @@ mod tests { #[test] fn test_mismatch() { - let (s1, msg1) = SPAKE2::<Ed25519Group>::start_a(b"password", b"idA", b"idB"); - let (s2, msg2) = SPAKE2::<Ed25519Group>::start_b(b"password2", 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"password2"), + &Identity::new(b"idA"), + &Identity::new(b"idB"), + ); let key1 = s1.finish(msg2.as_slice()).unwrap(); let key2 = s2.finish(msg1.as_slice()).unwrap(); assert_ne!(key1, key2); @@ -32,7 +48,11 @@ mod tests { #[test] fn test_reflected_message() { - let (s1, msg1) = SPAKE2::<Ed25519Group>::start_a(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 r = s1.finish(msg1.as_slice()); assert_eq!( r.unwrap_err(), @@ -44,7 +64,11 @@ mod tests { #[test] fn test_bad_length() { - let (s1, msg1) = SPAKE2::<Ed25519Group>::start_a(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 mut msg2 = Vec::<u8>::with_capacity(msg1.len() + 1); msg2.resize(msg1.len() + 1, 0u8); let r = s1.finish(&msg2); @@ -58,8 +82,14 @@ mod tests { #[test] fn test_basic_symmetric() { - let (s1, msg1) = SPAKE2::<Ed25519Group>::start_symmetric(b"password", b"idS"); - let (s2, msg2) = SPAKE2::<Ed25519Group>::start_symmetric(b"password", b"idS"); + let (s1, msg1) = SPAKE2::<Ed25519Group>::start_symmetric( + &Password::new(b"password"), + &Identity::new(b"idS"), + ); + let (s2, msg2) = SPAKE2::<Ed25519Group>::start_symmetric( + &Password::new(b"password"), + &Identity::new(b"idS"), + ); let key1 = s1.finish(msg2.as_slice()).unwrap(); let key2 = s2.finish(msg1.as_slice()).unwrap(); assert_eq!(key1, key2); |