2020-06-05 09:35:14 -07:00
|
|
|
// Copyright (c) Facebook, Inc. and its affiliates.
|
|
|
|
|
//
|
|
|
|
|
// This source code is licensed under the MIT license found in the
|
|
|
|
|
// LICENSE file in the root directory of this source tree.
|
|
|
|
|
|
|
|
|
|
use crate::{
|
2020-06-14 23:25:31 -07:00
|
|
|
ciphersuite::CipherSuite,
|
2020-06-05 09:35:14 -07:00
|
|
|
errors::*,
|
|
|
|
|
group::Group,
|
2020-07-13 15:23:29 -07:00
|
|
|
key_exchange::tripledh::{TripleDH, NONCE_LEN},
|
2020-11-03 21:44:00 +00:00
|
|
|
keypair::{Key, KeyPair, X25519KeyPair},
|
2020-06-05 09:35:14 -07:00
|
|
|
opaque::*,
|
2020-07-02 12:24:53 -07:00
|
|
|
slow_hash::NoOpHash,
|
2020-06-05 09:35:14 -07:00
|
|
|
tests::mock_rng::CycleRng,
|
2020-11-16 14:05:43 -08:00
|
|
|
*,
|
2020-06-05 09:35:14 -07:00
|
|
|
};
|
|
|
|
|
use curve25519_dalek::edwards::EdwardsPoint;
|
2020-11-02 13:51:43 -08:00
|
|
|
use generic_array::GenericArray;
|
2020-11-03 21:44:00 +00:00
|
|
|
use generic_bytes::SizedBytes;
|
2020-06-05 09:35:14 -07:00
|
|
|
use rand_core::{OsRng, RngCore};
|
|
|
|
|
use serde_json::Value;
|
|
|
|
|
use std::convert::TryFrom;
|
|
|
|
|
|
|
|
|
|
// Tests
|
|
|
|
|
// =====
|
|
|
|
|
|
2020-07-02 12:24:53 -07:00
|
|
|
struct X255193dhNoSlowHash;
|
|
|
|
|
impl CipherSuite for X255193dhNoSlowHash {
|
2020-06-14 23:25:31 -07:00
|
|
|
type Group = EdwardsPoint;
|
2020-07-02 12:24:53 -07:00
|
|
|
type KeyFormat = X25519KeyPair;
|
2020-07-13 15:23:29 -07:00
|
|
|
type KeyExchange = TripleDH;
|
2020-07-27 15:25:04 -07:00
|
|
|
type Hash = sha2::Sha256;
|
2020-07-02 12:24:53 -07:00
|
|
|
type SlowHash = NoOpHash;
|
2020-06-14 23:25:31 -07:00
|
|
|
}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
pub struct TestVectorParameters {
|
|
|
|
|
pub client_s_pk: Vec<u8>,
|
|
|
|
|
pub client_s_sk: Vec<u8>,
|
|
|
|
|
pub client_e_pk: Vec<u8>,
|
|
|
|
|
pub client_e_sk: Vec<u8>,
|
|
|
|
|
pub server_s_pk: Vec<u8>,
|
|
|
|
|
pub server_s_sk: Vec<u8>,
|
|
|
|
|
pub server_e_pk: Vec<u8>,
|
|
|
|
|
pub server_e_sk: Vec<u8>,
|
2020-11-02 13:51:43 -08:00
|
|
|
pub id_u: Vec<u8>,
|
|
|
|
|
pub id_s: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
pub password: Vec<u8>,
|
|
|
|
|
pub blinding_factor: Vec<u8>,
|
|
|
|
|
pub oprf_key: Vec<u8>,
|
|
|
|
|
pub envelope_nonce: Vec<u8>,
|
|
|
|
|
pub client_nonce: Vec<u8>,
|
|
|
|
|
pub server_nonce: Vec<u8>,
|
2020-11-29 23:06:55 -08:00
|
|
|
pub info1: Vec<u8>,
|
|
|
|
|
pub info2: Vec<u8>,
|
|
|
|
|
pub einfo2: Vec<u8>,
|
|
|
|
|
pub info3: Vec<u8>,
|
|
|
|
|
pub einfo3: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
pub r1: Vec<u8>,
|
|
|
|
|
pub r2: Vec<u8>,
|
|
|
|
|
pub r3: Vec<u8>,
|
|
|
|
|
pub l1: Vec<u8>,
|
|
|
|
|
pub l2: Vec<u8>,
|
|
|
|
|
pub l3: Vec<u8>,
|
|
|
|
|
client_registration_state: Vec<u8>,
|
|
|
|
|
server_registration_state: Vec<u8>,
|
|
|
|
|
client_login_state: Vec<u8>,
|
|
|
|
|
server_login_state: Vec<u8>,
|
|
|
|
|
pub password_file: Vec<u8>,
|
2020-09-01 11:23:00 -07:00
|
|
|
pub export_key: Vec<u8>,
|
2020-06-05 09:35:14 -07:00
|
|
|
pub shared_secret: Vec<u8>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static TEST_VECTOR: &str = r#"
|
|
|
|
|
{
|
2020-12-04 13:19:29 -08:00
|
|
|
"client_s_pk": "5320b55752ad2061c1804050f8a225a4ab1184bc17d8fa6b3c86470c33d9ce42",
|
|
|
|
|
"client_s_sk": "e8719d2f7aca0ab85a991ac4221ff7fde7665b9bd17658777c5417ef5c59796a",
|
|
|
|
|
"client_e_pk": "77fc3fefb8178ae08461756b54364c4f2d1363d5ce3187af128a3f84a6c5722a",
|
|
|
|
|
"client_e_sk": "48b452f6d0b28387cfa98245bda9230b6df215ed5b820bffb8511ec6802d8075",
|
|
|
|
|
"server_s_pk": "b8c5defc933aaf3640d13f217c392e06fe5fd41fae8571204fcbb804a566cd2e",
|
|
|
|
|
"server_s_sk": "60f5ab9ff1a3ba9cf6242812be91635db16e8e1826bf06fb97893d7cf82a2656",
|
|
|
|
|
"server_e_pk": "5a314dc389c12bf041b14e131fadebcc98e0fc33d3cd996ad9392c7ae6bff468",
|
|
|
|
|
"server_e_sk": "606034b9be54759ea5802a2dd71e4413e98d52c46e60f2d0868642ad9e6a9b46",
|
2020-11-02 13:51:43 -08:00
|
|
|
"id_u": "696455",
|
|
|
|
|
"id_s": "696453",
|
2020-06-05 09:35:14 -07:00
|
|
|
"password": "70617373776f7264",
|
2020-12-04 13:19:29 -08:00
|
|
|
"blinding_factor": "c0accb2010d728cfce827d4cb3769000c8b42ac341db8ba196fbe75809d91300",
|
|
|
|
|
"oprf_key": "7f1d2a048a7aad9d1cf2b96473e3adbb1e0626eafe0abdfd09f1f700beda9d0f",
|
|
|
|
|
"envelope_nonce": "abb706633ac7092e2aa63dedd4b456d7d99870f099c4f2c51ba75da0f20db8e8",
|
|
|
|
|
"client_nonce": "1a92d39b2f9acdbef96dcc586b35ae056a085ede41b05f9f81801f69558d44c7",
|
|
|
|
|
"server_nonce": "e04e9f1a4d35882c0ce435e3f467f601f26fe246e5f60ee9b600d9a63b91c0ad",
|
2020-11-29 23:06:55 -08:00
|
|
|
"info1": "696e666f31",
|
|
|
|
|
"info2": "696e666f32",
|
|
|
|
|
"einfo2": "65696e666f32",
|
|
|
|
|
"info3": "696e666f33",
|
|
|
|
|
"einfo3": "65696e666f33",
|
2020-12-04 13:19:29 -08:00
|
|
|
"r1": "0020c4ad91692b704470e0613850b9bfcc5b265d43f9ba03dd6ff028f0fb6b365957",
|
|
|
|
|
"r2": "00205cbfd7b74c7fe6088f8117e7e63000675762920b75e0f4630ed67d4d960c7aa80020b8c5defc933aaf3640d13f217c392e06fe5fd41fae8571204fcbb804a566cd2e01010103",
|
|
|
|
|
"r3": "abb706633ac7092e2aa63dedd4b456d7d99870f099c4f2c51ba75da0f20db8e80023e76da9b9fbf400fea214ecdab24966e4d3fea9d0c3d5d672597e1e702eb30547495ada0023030020b8c5defc933aaf3640d13f217c392e06fe5fd41fae8571204fcbb804a566cd2e00204e0e5754fbbd48efcdab43cee37f6455f357f3edc54316cb69da8f8e92f5ed8900205320b55752ad2061c1804050f8a225a4ab1184bc17d8fa6b3c86470c33d9ce42",
|
|
|
|
|
"l1": "0020c4ad91692b704470e0613850b9bfcc5b265d43f9ba03dd6ff028f0fb6b3659571a92d39b2f9acdbef96dcc586b35ae056a085ede41b05f9f81801f69558d44c70005696e666f3177fc3fefb8178ae08461756b54364c4f2d1363d5ce3187af128a3f84a6c5722a",
|
|
|
|
|
"l2": "00205cbfd7b74c7fe6088f8117e7e63000675762920b75e0f4630ed67d4d960c7aa8abb706633ac7092e2aa63dedd4b456d7d99870f099c4f2c51ba75da0f20db8e80023e76da9b9fbf400fea214ecdab24966e4d3fea9d0c3d5d672597e1e702eb30547495ada0023030020b8c5defc933aaf3640d13f217c392e06fe5fd41fae8571204fcbb804a566cd2e00204e0e5754fbbd48efcdab43cee37f6455f357f3edc54316cb69da8f8e92f5ed89606034b9be54759ea5802a2dd71e4413e98d52c46e60f2d0868642ad9e6a9b460005696e666f325a314dc389c12bf041b14e131fadebcc98e0fc33d3cd996ad9392c7ae6bff468000665696e666f32661aa1d3e579032df30a78312d38a4c3d8d8a0f1b9bb7bbdbff040e0881a248e",
|
|
|
|
|
"l3": "0005696e666f33000665696e666f3317090781af5a220941ddd6db7d4f2af33d9b316a48aee163647131970bae50ba",
|
|
|
|
|
"client_registration_state": "00036964550003696453c0accb2010d728cfce827d4cb3769000c8b42ac341db8ba196fbe75809d9130070617373776f7264",
|
|
|
|
|
"client_login_state": "00036964550003696453c0accb2010d728cfce827d4cb3769000c8b42ac341db8ba196fbe75809d9130048b452f6d0b28387cfa98245bda9230b6df215ed5b820bffb8511ec6802d80751a92d39b2f9acdbef96dcc586b35ae056a085ede41b05f9f81801f69558d44c7288b735853d9e1d8ab699b7c4aef54680f036c56140dc0a4991f6d02a95babc970617373776f7264",
|
|
|
|
|
"server_registration_state": "7f1d2a048a7aad9d1cf2b96473e3adbb1e0626eafe0abdfd09f1f700beda9d0f",
|
|
|
|
|
"server_login_state": "2bfb97200c110fa3a9a020920829ce9e7e74a9e843ae86949e16300dc6e25b09e7e0522de623f021a7ba5d150ab8cba2eca4be458d3c22ae6109813a215a03d88f757f3390c767cd9433007c1abf9226c9e0da8e5d1a3d5722773c070b05f44b",
|
|
|
|
|
"password_file": "7f1d2a048a7aad9d1cf2b96473e3adbb1e0626eafe0abdfd09f1f700beda9d0f5320b55752ad2061c1804050f8a225a4ab1184bc17d8fa6b3c86470c33d9ce42abb706633ac7092e2aa63dedd4b456d7d99870f099c4f2c51ba75da0f20db8e80023e76da9b9fbf400fea214ecdab24966e4d3fea9d0c3d5d672597e1e702eb30547495ada0023030020b8c5defc933aaf3640d13f217c392e06fe5fd41fae8571204fcbb804a566cd2e00204e0e5754fbbd48efcdab43cee37f6455f357f3edc54316cb69da8f8e92f5ed89",
|
|
|
|
|
"export_key": "139998e9d44e2fa629689d8bef9f900a60278e2acd55f4e59906255b10494d58",
|
|
|
|
|
"shared_secret": "8f757f3390c767cd9433007c1abf9226c9e0da8e5d1a3d5722773c070b05f44b"
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
"#;
|
|
|
|
|
|
|
|
|
|
fn decode(values: &Value, key: &str) -> Option<Vec<u8>> {
|
|
|
|
|
values[key]
|
|
|
|
|
.as_str()
|
|
|
|
|
.and_then(|s| hex::decode(&s.to_string()).ok())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn populate_test_vectors(values: &Value) -> TestVectorParameters {
|
|
|
|
|
TestVectorParameters {
|
|
|
|
|
client_s_pk: decode(&values, "client_s_pk").unwrap(),
|
|
|
|
|
client_s_sk: decode(&values, "client_s_sk").unwrap(),
|
|
|
|
|
client_e_pk: decode(&values, "client_e_pk").unwrap(),
|
|
|
|
|
client_e_sk: decode(&values, "client_e_sk").unwrap(),
|
|
|
|
|
server_s_pk: decode(&values, "server_s_pk").unwrap(),
|
|
|
|
|
server_s_sk: decode(&values, "server_s_sk").unwrap(),
|
|
|
|
|
server_e_pk: decode(&values, "server_e_pk").unwrap(),
|
|
|
|
|
server_e_sk: decode(&values, "server_e_sk").unwrap(),
|
2020-11-02 13:51:43 -08:00
|
|
|
id_u: decode(&values, "id_u").unwrap(),
|
|
|
|
|
id_s: decode(&values, "id_s").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
password: decode(&values, "password").unwrap(),
|
|
|
|
|
blinding_factor: decode(&values, "blinding_factor").unwrap(),
|
|
|
|
|
oprf_key: decode(&values, "oprf_key").unwrap(),
|
|
|
|
|
envelope_nonce: decode(&values, "envelope_nonce").unwrap(),
|
|
|
|
|
client_nonce: decode(&values, "client_nonce").unwrap(),
|
|
|
|
|
server_nonce: decode(&values, "server_nonce").unwrap(),
|
2020-11-29 23:06:55 -08:00
|
|
|
info1: decode(&values, "info1").unwrap(),
|
|
|
|
|
info2: decode(&values, "info2").unwrap(),
|
|
|
|
|
einfo2: decode(&values, "einfo2").unwrap(),
|
|
|
|
|
info3: decode(&values, "info3").unwrap(),
|
|
|
|
|
einfo3: decode(&values, "einfo3").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
r1: decode(&values, "r1").unwrap(),
|
|
|
|
|
r2: decode(&values, "r2").unwrap(),
|
|
|
|
|
r3: decode(&values, "r3").unwrap(),
|
|
|
|
|
l1: decode(&values, "l1").unwrap(),
|
|
|
|
|
l2: decode(&values, "l2").unwrap(),
|
|
|
|
|
l3: decode(&values, "l3").unwrap(),
|
|
|
|
|
client_registration_state: decode(&values, "client_registration_state").unwrap(),
|
|
|
|
|
client_login_state: decode(&values, "client_login_state").unwrap(),
|
|
|
|
|
server_registration_state: decode(&values, "server_registration_state").unwrap(),
|
|
|
|
|
server_login_state: decode(&values, "server_login_state").unwrap(),
|
|
|
|
|
password_file: decode(&values, "password_file").unwrap(),
|
2020-09-01 11:23:00 -07:00
|
|
|
export_key: decode(&values, "export_key").unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
shared_secret: decode(&values, "shared_secret").unwrap(),
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn stringify_test_vectors(p: &TestVectorParameters) -> String {
|
|
|
|
|
let mut s = String::new();
|
|
|
|
|
s.push_str("{\n");
|
|
|
|
|
s.push_str(format!("\"client_s_pk\": \"{}\",\n", hex::encode(&p.client_s_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"client_s_sk\": \"{}\",\n", hex::encode(&p.client_s_sk)).as_str());
|
|
|
|
|
s.push_str(format!("\"client_e_pk\": \"{}\",\n", hex::encode(&p.client_e_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"client_e_sk\": \"{}\",\n", hex::encode(&p.client_e_sk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_s_pk\": \"{}\",\n", hex::encode(&p.server_s_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_s_sk\": \"{}\",\n", hex::encode(&p.server_s_sk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_e_pk\": \"{}\",\n", hex::encode(&p.server_e_pk)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_e_sk\": \"{}\",\n", hex::encode(&p.server_e_sk)).as_str());
|
2020-11-02 13:51:43 -08:00
|
|
|
s.push_str(format!("\"id_u\": \"{}\",\n", hex::encode(&p.id_u)).as_str());
|
|
|
|
|
s.push_str(format!("\"id_s\": \"{}\",\n", hex::encode(&p.id_s)).as_str());
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str(format!("\"password\": \"{}\",\n", hex::encode(&p.password)).as_str());
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"blinding_factor\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.blinding_factor)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(format!("\"oprf_key\": \"{}\",\n", hex::encode(&p.oprf_key)).as_str());
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"envelope_nonce\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.envelope_nonce)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(format!("\"client_nonce\": \"{}\",\n", hex::encode(&p.client_nonce)).as_str());
|
|
|
|
|
s.push_str(format!("\"server_nonce\": \"{}\",\n", hex::encode(&p.server_nonce)).as_str());
|
2020-11-29 23:06:55 -08:00
|
|
|
s.push_str(format!("\"info1\": \"{}\",\n", hex::encode(&p.info1)).as_str());
|
|
|
|
|
s.push_str(format!("\"info2\": \"{}\",\n", hex::encode(&p.info2)).as_str());
|
|
|
|
|
s.push_str(format!("\"einfo2\": \"{}\",\n", hex::encode(&p.einfo2)).as_str());
|
|
|
|
|
s.push_str(format!("\"info3\": \"{}\",\n", hex::encode(&p.info3)).as_str());
|
|
|
|
|
s.push_str(format!("\"einfo3\": \"{}\",\n", hex::encode(&p.einfo3)).as_str());
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str(format!("\"r1\": \"{}\",\n", hex::encode(&p.r1)).as_str());
|
|
|
|
|
s.push_str(format!("\"r2\": \"{}\",\n", hex::encode(&p.r2)).as_str());
|
|
|
|
|
s.push_str(format!("\"r3\": \"{}\",\n", hex::encode(&p.r3)).as_str());
|
|
|
|
|
s.push_str(format!("\"l1\": \"{}\",\n", hex::encode(&p.l1)).as_str());
|
|
|
|
|
s.push_str(format!("\"l2\": \"{}\",\n", hex::encode(&p.l2)).as_str());
|
|
|
|
|
s.push_str(format!("\"l3\": \"{}\",\n", hex::encode(&p.l3)).as_str());
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"client_registration_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.client_registration_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"client_login_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.client_login_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"server_registration_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.server_registration_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"server_login_state\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.server_login_state)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
|
|
|
|
s.push_str(
|
|
|
|
|
format!(
|
|
|
|
|
"\"password_file\": \"{}\",\n",
|
|
|
|
|
hex::encode(&p.password_file)
|
|
|
|
|
)
|
|
|
|
|
.as_str(),
|
|
|
|
|
);
|
2020-09-01 11:23:00 -07:00
|
|
|
s.push_str(format!("\"export_key\": \"{}\",\n", hex::encode(&p.export_key)).as_str());
|
2020-06-05 09:35:14 -07:00
|
|
|
s.push_str(format!("\"shared_secret\": \"{}\"\n", hex::encode(&p.shared_secret)).as_str());
|
|
|
|
|
s.push_str("}\n");
|
|
|
|
|
s
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-22 08:50:39 -04:00
|
|
|
fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters
|
|
|
|
|
where
|
|
|
|
|
// Unsightly constraints due to the (required) use of the SizedBytes
|
|
|
|
|
// instance for KP in ServerRegistration::start. See also the impl
|
|
|
|
|
// Tryfrom<&[u8]> for ServerRegistration (those are the same constraints).
|
|
|
|
|
<<CS::KeyFormat as KeyPair>::Repr as SizedBytes>::Len:
|
|
|
|
|
std::ops::Add<<<CS::KeyFormat as KeyPair>::Repr as SizedBytes>::Len>,
|
|
|
|
|
generic_array::typenum::Sum<
|
|
|
|
|
<<CS::KeyFormat as KeyPair>::Repr as SizedBytes>::Len,
|
|
|
|
|
<<CS::KeyFormat as KeyPair>::Repr as SizedBytes>::Len,
|
|
|
|
|
>: generic_array::ArrayLength<u8>,
|
|
|
|
|
{
|
2020-06-05 09:35:14 -07:00
|
|
|
let mut rng = OsRng;
|
|
|
|
|
|
|
|
|
|
// Inputs
|
2020-07-02 12:24:53 -07:00
|
|
|
let server_s_kp = CS::generate_random_keypair(&mut rng).unwrap();
|
|
|
|
|
let server_e_kp = CS::generate_random_keypair(&mut rng).unwrap();
|
|
|
|
|
let client_s_kp = CS::generate_random_keypair(&mut rng).unwrap();
|
|
|
|
|
let client_e_kp = CS::generate_random_keypair(&mut rng).unwrap();
|
2020-11-02 13:51:43 -08:00
|
|
|
let id_u = b"idU";
|
|
|
|
|
let id_s = b"idS";
|
2020-06-05 09:35:14 -07:00
|
|
|
let password = b"password";
|
|
|
|
|
let mut blinding_factor_raw = [0u8; 64];
|
|
|
|
|
rng.fill_bytes(&mut blinding_factor_raw);
|
|
|
|
|
let mut oprf_key_raw = [0u8; 32];
|
|
|
|
|
rng.fill_bytes(&mut oprf_key_raw);
|
2020-09-01 11:23:00 -07:00
|
|
|
let mut envelope_nonce = [0u8; 32];
|
2020-06-05 09:35:14 -07:00
|
|
|
rng.fill_bytes(&mut envelope_nonce);
|
|
|
|
|
let mut client_nonce = [0u8; NONCE_LEN];
|
|
|
|
|
rng.fill_bytes(&mut client_nonce);
|
|
|
|
|
let mut server_nonce = [0u8; NONCE_LEN];
|
|
|
|
|
rng.fill_bytes(&mut server_nonce);
|
|
|
|
|
|
2020-11-29 23:06:55 -08:00
|
|
|
let info1 = b"info1";
|
|
|
|
|
let info2 = b"info2";
|
|
|
|
|
let einfo2 = b"einfo2";
|
|
|
|
|
let info3 = b"info3";
|
|
|
|
|
let einfo3 = b"einfo3";
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
let mut blinding_factor_registration_rng = CycleRng::new(blinding_factor_raw.to_vec());
|
2020-11-16 14:05:43 -08:00
|
|
|
let (r1, client_registration) = ClientRegistration::<CS>::start(
|
2020-06-05 09:35:14 -07:00
|
|
|
password,
|
2020-11-16 14:05:43 -08:00
|
|
|
ClientRegistrationStartParameters::WithIdentifiers(id_u.to_vec(), id_s.to_vec()),
|
2020-06-05 09:35:14 -07:00
|
|
|
&mut blinding_factor_registration_rng,
|
2020-11-04 11:33:58 -05:00
|
|
|
std::convert::identity,
|
2020-06-05 09:35:14 -07:00
|
|
|
)
|
|
|
|
|
.unwrap();
|
2020-09-10 17:01:06 -04:00
|
|
|
let r1_bytes = r1.serialize().to_vec();
|
2020-07-03 18:28:35 -04:00
|
|
|
let blinding_factor_bytes =
|
2020-11-02 13:51:43 -08:00
|
|
|
CS::Group::scalar_as_bytes(&client_registration.token.blind).clone();
|
2020-06-05 09:35:14 -07:00
|
|
|
let client_registration_state = client_registration.to_bytes().to_vec();
|
|
|
|
|
|
|
|
|
|
let mut oprf_key_rng = CycleRng::new(oprf_key_raw.to_vec());
|
2020-11-16 14:05:43 -08:00
|
|
|
let (r2, server_registration) =
|
|
|
|
|
ServerRegistration::<CS>::start(r1, server_s_kp.public(), &mut oprf_key_rng).unwrap();
|
2020-09-10 17:01:06 -04:00
|
|
|
let r2_bytes = r2.serialize().to_vec();
|
2020-07-03 18:28:35 -04:00
|
|
|
let oprf_key_bytes = CS::Group::scalar_as_bytes(&server_registration.oprf_key).clone();
|
2020-06-05 09:35:14 -07:00
|
|
|
let server_registration_state = server_registration.to_bytes().to_vec();
|
|
|
|
|
|
|
|
|
|
let mut client_s_sk_and_nonce: Vec<u8> = Vec::new();
|
2020-09-22 08:50:39 -04:00
|
|
|
client_s_sk_and_nonce.extend_from_slice(&client_s_kp.private().to_arr());
|
2020-06-05 09:35:14 -07:00
|
|
|
client_s_sk_and_nonce.extend_from_slice(&envelope_nonce);
|
|
|
|
|
|
|
|
|
|
let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce);
|
2020-09-01 11:23:00 -07:00
|
|
|
let (r3, export_key_registration) = client_registration
|
2020-11-16 14:05:43 -08:00
|
|
|
.finish(r2, &mut finish_registration_rng)
|
2020-06-05 09:35:14 -07:00
|
|
|
.unwrap();
|
2020-09-10 17:01:06 -04:00
|
|
|
let r3_bytes = r3.serialize().to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
let password_file = server_registration.finish(r3).unwrap();
|
|
|
|
|
let password_file_bytes = password_file.to_bytes();
|
|
|
|
|
|
|
|
|
|
let mut client_login_start: Vec<u8> = Vec::new();
|
|
|
|
|
client_login_start.extend_from_slice(&blinding_factor_raw);
|
2020-09-22 08:50:39 -04:00
|
|
|
client_login_start.extend_from_slice(&client_e_kp.private().to_arr());
|
2020-06-05 09:35:14 -07:00
|
|
|
client_login_start.extend_from_slice(&client_nonce);
|
|
|
|
|
|
|
|
|
|
let mut client_login_start_rng = CycleRng::new(client_login_start);
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_start_result = ClientLogin::<CS>::start(
|
2020-11-02 13:51:43 -08:00
|
|
|
password,
|
|
|
|
|
&mut client_login_start_rng,
|
2020-11-29 23:06:55 -08:00
|
|
|
ClientLoginStartParameters::WithInfoAndIdentifiers(
|
|
|
|
|
info1.to_vec(),
|
2020-11-16 14:05:43 -08:00
|
|
|
id_u.to_vec(),
|
|
|
|
|
id_s.to_vec(),
|
|
|
|
|
),
|
2020-11-04 11:33:58 -05:00
|
|
|
std::convert::identity,
|
2020-11-02 13:51:43 -08:00
|
|
|
)
|
|
|
|
|
.unwrap();
|
2020-11-16 14:05:43 -08:00
|
|
|
let l1_bytes = client_login_start_result
|
|
|
|
|
.credential_request
|
|
|
|
|
.serialize()
|
|
|
|
|
.to_vec();
|
|
|
|
|
let client_login_state = client_login_start_result
|
|
|
|
|
.client_login_state
|
|
|
|
|
.to_bytes()
|
|
|
|
|
.to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2020-09-22 08:50:39 -04:00
|
|
|
let mut server_e_sk_rng = CycleRng::new(server_e_kp.private().to_arr().to_vec());
|
2020-11-16 14:05:43 -08:00
|
|
|
let server_login_start_result = ServerLogin::<CS>::start(
|
2020-06-05 09:35:14 -07:00
|
|
|
password_file,
|
|
|
|
|
server_s_kp.private(),
|
2020-11-16 14:05:43 -08:00
|
|
|
client_login_start_result.credential_request,
|
2020-06-05 09:35:14 -07:00
|
|
|
&mut server_e_sk_rng,
|
2020-11-29 23:06:55 -08:00
|
|
|
ServerLoginStartParameters::WithInfo(info2.to_vec(), einfo2.to_vec()),
|
2020-06-05 09:35:14 -07:00
|
|
|
)
|
|
|
|
|
.unwrap();
|
2020-11-16 14:05:43 -08:00
|
|
|
let l2_bytes = server_login_start_result
|
|
|
|
|
.credential_response
|
|
|
|
|
.serialize()
|
|
|
|
|
.to_vec();
|
|
|
|
|
let server_login_state = server_login_start_result
|
|
|
|
|
.server_login_state
|
|
|
|
|
.to_bytes()
|
|
|
|
|
.to_vec();
|
|
|
|
|
|
|
|
|
|
let client_login_finish_result = client_login_start_result
|
|
|
|
|
.client_login_state
|
|
|
|
|
.finish(
|
|
|
|
|
server_login_start_result.credential_response,
|
2020-11-29 23:06:55 -08:00
|
|
|
ClientLoginFinishParameters::WithInfo(info3.to_vec(), einfo3.to_vec()),
|
2020-11-16 14:05:43 -08:00
|
|
|
)
|
2020-06-05 09:35:14 -07:00
|
|
|
.unwrap();
|
2020-11-16 14:05:43 -08:00
|
|
|
let l3_bytes = client_login_finish_result.key_exchange.to_bytes().to_vec();
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
TestVectorParameters {
|
2020-09-22 08:50:39 -04:00
|
|
|
client_s_pk: client_s_kp.public().to_arr().to_vec(),
|
|
|
|
|
client_s_sk: client_s_kp.private().to_arr().to_vec(),
|
|
|
|
|
client_e_pk: client_e_kp.public().to_arr().to_vec(),
|
|
|
|
|
client_e_sk: client_e_kp.private().to_arr().to_vec(),
|
|
|
|
|
server_s_pk: server_s_kp.public().to_arr().to_vec(),
|
|
|
|
|
server_s_sk: server_s_kp.private().to_arr().to_vec(),
|
|
|
|
|
server_e_pk: server_e_kp.public().to_arr().to_vec(),
|
|
|
|
|
server_e_sk: server_e_kp.private().to_arr().to_vec(),
|
2020-11-02 13:51:43 -08:00
|
|
|
id_u: id_u.to_vec(),
|
|
|
|
|
id_s: id_s.to_vec(),
|
2020-06-05 09:35:14 -07:00
|
|
|
password: password.to_vec(),
|
|
|
|
|
blinding_factor: blinding_factor_bytes.to_vec(),
|
|
|
|
|
oprf_key: oprf_key_bytes.to_vec(),
|
|
|
|
|
envelope_nonce: envelope_nonce.to_vec(),
|
|
|
|
|
client_nonce: client_nonce.to_vec(),
|
|
|
|
|
server_nonce: server_nonce.to_vec(),
|
2020-11-29 23:06:55 -08:00
|
|
|
info1: info1.to_vec(),
|
|
|
|
|
info2: info2.to_vec(),
|
|
|
|
|
einfo2: einfo2.to_vec(),
|
|
|
|
|
info3: info3.to_vec(),
|
|
|
|
|
einfo3: einfo3.to_vec(),
|
2020-06-05 09:35:14 -07:00
|
|
|
r1: r1_bytes,
|
|
|
|
|
r2: r2_bytes,
|
|
|
|
|
r3: r3_bytes,
|
|
|
|
|
l1: l1_bytes,
|
|
|
|
|
l2: l2_bytes,
|
|
|
|
|
l3: l3_bytes,
|
|
|
|
|
password_file: password_file_bytes,
|
|
|
|
|
client_registration_state,
|
|
|
|
|
server_registration_state,
|
|
|
|
|
client_login_state,
|
|
|
|
|
server_login_state,
|
2020-11-16 14:05:43 -08:00
|
|
|
shared_secret: client_login_finish_result.session_secret,
|
2020-09-01 11:23:00 -07:00
|
|
|
export_key: export_key_registration.to_vec(),
|
2020-06-05 09:35:14 -07:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn generate_test_vectors() {
|
2020-07-02 12:24:53 -07:00
|
|
|
let parameters = generate_parameters::<X255193dhNoSlowHash>();
|
2020-06-05 09:35:14 -07:00
|
|
|
println!("{}", stringify_test_vectors(¶meters));
|
|
|
|
|
}
|
|
|
|
|
|
2020-11-02 13:51:43 -08:00
|
|
|
// For fixing the blinding factor
|
|
|
|
|
fn postprocess_blinding_factor<G: Group>(_: G::Scalar) -> G::Scalar {
|
|
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
G::from_scalar_slice(GenericArray::from_slice(¶meters.blinding_factor[..])).unwrap()
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-05 09:35:14 -07:00
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_r1() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
2020-11-02 13:51:43 -08:00
|
|
|
let mut rng = OsRng;
|
2020-11-16 14:05:43 -08:00
|
|
|
let (r1, client_registration) = ClientRegistration::<X255193dhNoSlowHash>::start(
|
|
|
|
|
¶meters.password,
|
|
|
|
|
ClientRegistrationStartParameters::WithIdentifiers(parameters.id_u, parameters.id_s),
|
|
|
|
|
&mut rng,
|
|
|
|
|
postprocess_blinding_factor::<<X255193dhNoSlowHash as CipherSuite>::Group>,
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-09-10 17:01:06 -04:00
|
|
|
assert_eq!(hex::encode(¶meters.r1), hex::encode(r1.serialize()));
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.client_registration_state),
|
|
|
|
|
hex::encode(client_registration.to_bytes())
|
|
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_r2() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
let mut oprf_key_rng = CycleRng::new(parameters.oprf_key);
|
2020-07-02 12:24:53 -07:00
|
|
|
let (r2, server_registration) = ServerRegistration::<X255193dhNoSlowHash>::start(
|
2020-09-10 17:01:06 -04:00
|
|
|
RegisterFirstMessage::deserialize(¶meters.r1[..]).unwrap(),
|
2020-11-16 14:05:43 -08:00
|
|
|
&Key::try_from(¶meters.server_s_pk[..]).unwrap(),
|
2020-06-14 23:25:31 -07:00
|
|
|
&mut oprf_key_rng,
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-09-10 17:01:06 -04:00
|
|
|
assert_eq!(hex::encode(parameters.r2), hex::encode(r2.serialize()));
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.server_registration_state),
|
|
|
|
|
hex::encode(server_registration.to_bytes())
|
|
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_r3() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
|
|
|
|
let client_s_sk_and_nonce: Vec<u8> =
|
|
|
|
|
[parameters.client_s_sk, parameters.envelope_nonce].concat();
|
|
|
|
|
let mut finish_registration_rng = CycleRng::new(client_s_sk_and_nonce);
|
2020-09-01 11:23:00 -07:00
|
|
|
let (r3, export_key_registration) = ClientRegistration::<X255193dhNoSlowHash>::try_from(
|
2020-06-05 09:35:14 -07:00
|
|
|
¶meters.client_registration_state[..],
|
2020-12-09 12:49:59 -08:00
|
|
|
)?
|
2020-06-14 23:25:31 -07:00
|
|
|
.finish(
|
2020-09-10 17:01:06 -04:00
|
|
|
RegisterSecondMessage::deserialize(¶meters.r2[..]).unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
&mut finish_registration_rng,
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-09-10 17:01:06 -04:00
|
|
|
assert_eq!(hex::encode(parameters.r3), hex::encode(r3.serialize()));
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
2020-09-01 11:23:00 -07:00
|
|
|
hex::encode(parameters.export_key),
|
|
|
|
|
hex::encode(export_key_registration.to_vec())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_password_file() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2020-07-02 12:24:53 -07:00
|
|
|
let server_registration = ServerRegistration::<X255193dhNoSlowHash>::try_from(
|
2020-06-14 23:25:31 -07:00
|
|
|
¶meters.server_registration_state[..],
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-06-05 09:35:14 -07:00
|
|
|
let password_file = server_registration
|
2020-12-09 12:49:59 -08:00
|
|
|
.finish(RegisterThirdMessage::deserialize(¶meters.r3[..]).unwrap())?;
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(parameters.password_file),
|
|
|
|
|
hex::encode(password_file.to_bytes())
|
|
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_l1() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
|
|
|
|
let client_login_start = [
|
2020-11-02 13:51:43 -08:00
|
|
|
vec![0u8; 64], // FIXME: don't hardcode this
|
2020-06-05 09:35:14 -07:00
|
|
|
parameters.client_e_sk,
|
|
|
|
|
parameters.client_nonce,
|
|
|
|
|
]
|
|
|
|
|
.concat();
|
|
|
|
|
let mut client_login_start_rng = CycleRng::new(client_login_start);
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_start_result = ClientLogin::<X255193dhNoSlowHash>::start(
|
2020-11-04 11:33:58 -05:00
|
|
|
¶meters.password,
|
|
|
|
|
&mut client_login_start_rng,
|
2020-11-29 23:06:55 -08:00
|
|
|
ClientLoginStartParameters::WithInfoAndIdentifiers(
|
|
|
|
|
parameters.info1,
|
2020-11-16 14:05:43 -08:00
|
|
|
parameters.id_u,
|
|
|
|
|
parameters.id_s,
|
|
|
|
|
),
|
2020-11-04 11:33:58 -05:00
|
|
|
postprocess_blinding_factor::<<X255193dhNoSlowHash as CipherSuite>::Group>,
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-11-16 14:05:43 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.l1),
|
|
|
|
|
hex::encode(client_login_start_result.credential_request.serialize())
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.client_login_state),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(client_login_start_result.client_login_state.to_bytes())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_l2() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
|
|
|
|
let mut server_e_sk_rng = CycleRng::new(parameters.server_e_sk);
|
2020-11-16 14:05:43 -08:00
|
|
|
let server_login_start_result = ServerLogin::<X255193dhNoSlowHash>::start(
|
2020-06-05 09:35:14 -07:00
|
|
|
ServerRegistration::try_from(¶meters.password_file[..]).unwrap(),
|
2020-06-19 11:42:16 -04:00
|
|
|
&Key::try_from(¶meters.server_s_sk[..]).unwrap(),
|
2020-09-10 17:01:06 -04:00
|
|
|
LoginFirstMessage::<X255193dhNoSlowHash>::deserialize(¶meters.l1[..]).unwrap(),
|
2020-06-05 09:35:14 -07:00
|
|
|
&mut server_e_sk_rng,
|
2020-11-29 23:06:55 -08:00
|
|
|
ServerLoginStartParameters::WithInfo(parameters.info2.to_vec(), parameters.einfo2.to_vec()),
|
2020-12-09 12:49:59 -08:00
|
|
|
)?;
|
2020-11-29 23:06:55 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.info1),
|
|
|
|
|
hex::encode(server_login_start_result.plain_info),
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.client_s_pk),
|
|
|
|
|
hex::encode(server_login_start_result.client_s_pk),
|
|
|
|
|
);
|
2020-11-16 14:05:43 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.l2),
|
|
|
|
|
hex::encode(server_login_start_result.credential_response.serialize())
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.server_login_state),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(server_login_start_result.server_login_state.to_bytes())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
2020-12-09 12:49:59 -08:00
|
|
|
fn test_l3() -> Result<(), ProtocolError> {
|
2020-06-05 09:35:14 -07:00
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_finish_result =
|
2020-12-09 12:49:59 -08:00
|
|
|
ClientLogin::<X255193dhNoSlowHash>::try_from(¶meters.client_login_state[..])?.finish(
|
|
|
|
|
LoginSecondMessage::<X255193dhNoSlowHash>::deserialize(¶meters.l2[..]).unwrap(),
|
|
|
|
|
ClientLoginFinishParameters::WithInfo(
|
|
|
|
|
parameters.info3.to_vec(),
|
|
|
|
|
parameters.einfo3.to_vec(),
|
|
|
|
|
),
|
|
|
|
|
)?;
|
2020-11-29 23:06:55 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.info2),
|
|
|
|
|
hex::encode(&client_login_finish_result.plain_info)
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.einfo2),
|
|
|
|
|
hex::encode(&client_login_finish_result.confidential_info)
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.server_s_pk),
|
|
|
|
|
hex::encode(&client_login_finish_result.server_s_pk)
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(None, client_login_finish_result.id_s);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.shared_secret),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(&client_login_finish_result.session_secret)
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(¶meters.l3),
|
|
|
|
|
hex::encode(client_login_finish_result.key_exchange.to_bytes())
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
assert_eq!(
|
2020-09-01 11:23:00 -07:00
|
|
|
hex::encode(¶meters.export_key),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(client_login_finish_result.export_key)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_server_login_finish() -> Result<(), ProtocolError> {
|
|
|
|
|
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
|
|
|
|
|
|
2020-11-16 14:05:43 -08:00
|
|
|
let server_login_result =
|
2020-12-09 12:49:59 -08:00
|
|
|
ServerLogin::<X255193dhNoSlowHash>::try_from(¶meters.server_login_state[..])?
|
|
|
|
|
.finish(LoginThirdMessage::try_from(¶meters.l3[..])?)?;
|
2020-11-29 23:06:55 -08:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(parameters.info3),
|
|
|
|
|
hex::encode(server_login_result.plain_info)
|
|
|
|
|
);
|
|
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(parameters.einfo3),
|
|
|
|
|
hex::encode(server_login_result.confidential_info)
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert_eq!(
|
|
|
|
|
hex::encode(parameters.shared_secret),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(server_login_result.session_secret)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
fn test_complete_flow(
|
|
|
|
|
registration_password: &[u8],
|
|
|
|
|
login_password: &[u8],
|
|
|
|
|
) -> Result<(), ProtocolError> {
|
|
|
|
|
let mut client_rng = OsRng;
|
|
|
|
|
let mut server_rng = OsRng;
|
2020-07-02 12:24:53 -07:00
|
|
|
let server_kp = X255193dhNoSlowHash::generate_random_keypair(&mut server_rng)?;
|
2020-11-16 14:05:43 -08:00
|
|
|
let (register_m1, client_state) = ClientRegistration::<X255193dhNoSlowHash>::start(
|
|
|
|
|
registration_password,
|
|
|
|
|
ClientRegistrationStartParameters::default(),
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
std::convert::identity,
|
|
|
|
|
)?;
|
|
|
|
|
let (register_m2, server_state) = ServerRegistration::<X255193dhNoSlowHash>::start(
|
|
|
|
|
register_m1,
|
|
|
|
|
server_kp.public(),
|
|
|
|
|
&mut server_rng,
|
|
|
|
|
)?;
|
2020-09-01 11:23:00 -07:00
|
|
|
let (register_m3, registration_export_key) =
|
2020-11-16 14:05:43 -08:00
|
|
|
client_state.finish(register_m2, &mut client_rng)?;
|
2020-06-05 09:35:14 -07:00
|
|
|
let p_file = server_state.finish(register_m3)?;
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_start_result = ClientLogin::<X255193dhNoSlowHash>::start(
|
|
|
|
|
login_password,
|
|
|
|
|
&mut client_rng,
|
|
|
|
|
ClientLoginStartParameters::default(),
|
|
|
|
|
std::convert::identity,
|
|
|
|
|
)?;
|
|
|
|
|
let server_login_start_result = ServerLogin::<X255193dhNoSlowHash>::start(
|
2020-07-13 15:23:29 -07:00
|
|
|
p_file,
|
|
|
|
|
&server_kp.private(),
|
2020-11-16 14:05:43 -08:00
|
|
|
client_login_start_result.credential_request,
|
2020-07-13 15:23:29 -07:00
|
|
|
&mut server_rng,
|
2020-11-16 14:05:43 -08:00
|
|
|
ServerLoginStartParameters::default(),
|
2020-07-13 15:23:29 -07:00
|
|
|
)?;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_result = client_login_start_result.client_login_state.finish(
|
|
|
|
|
server_login_start_result.credential_response,
|
|
|
|
|
ClientLoginFinishParameters::default(),
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
if hex::encode(registration_password) == hex::encode(login_password) {
|
2020-11-16 14:05:43 -08:00
|
|
|
let client_login_finish_result = client_login_result?;
|
|
|
|
|
let server_login_finish_result = server_login_start_result
|
|
|
|
|
.server_login_state
|
|
|
|
|
.finish(client_login_finish_result.key_exchange)?;
|
2020-06-05 09:35:14 -07:00
|
|
|
|
|
|
|
|
assert_eq!(
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(server_login_finish_result.session_secret),
|
|
|
|
|
hex::encode(client_login_finish_result.session_secret)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
assert_eq!(
|
2020-09-01 11:23:00 -07:00
|
|
|
hex::encode(registration_export_key),
|
2020-11-16 14:05:43 -08:00
|
|
|
hex::encode(client_login_finish_result.export_key)
|
2020-06-05 09:35:14 -07:00
|
|
|
);
|
|
|
|
|
} else {
|
2020-09-19 19:16:30 -04:00
|
|
|
let res = matches!(
|
|
|
|
|
client_login_result,
|
|
|
|
|
Err(ProtocolError::VerificationError(
|
|
|
|
|
PakeError::InvalidLoginError
|
|
|
|
|
))
|
|
|
|
|
);
|
2020-06-05 09:35:14 -07:00
|
|
|
assert!(res);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Ok(())
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_complete_flow_success() -> Result<(), ProtocolError> {
|
|
|
|
|
test_complete_flow(b"good password", b"good password")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
|
fn test_complete_flow_fail() -> Result<(), ProtocolError> {
|
|
|
|
|
test_complete_flow(b"good password", b"bad password")
|
|
|
|
|
}
|