aboutsummaryrefslogtreecommitdiff
path: root/src/lib.rs
diff options
context:
space:
mode:
authorBrian Warner <warner@lothar.com>2018-06-03 13:57:19 -0700
committerBrian Warner <warner@lothar.com>2018-06-03 14:56:20 -0700
commit0869881573ec805ec2337469ed5c4184cb0382e2 (patch)
treef9d3b91ddad329910a6ec0ea9693d25616af4651 /src/lib.rs
parent9bd20219ac9d6727a4b99cf6dd48e44b3190c6c9 (diff)
downloadPAKEs-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.rs48
1 files changed, 39 insertions, 9 deletions
diff --git a/src/lib.rs b/src/lib.rs
index dfc4b23..030498e 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -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);