Adding client enumeration mitigations (#153)

This commit is contained in:
Kevin Lewi
2021-06-21 01:29:39 -07:00
committed by Kevin Lewi
parent 98f1821897
commit f0c13945d1
14 changed files with 895 additions and 901 deletions
+139 -147
View File
@@ -10,7 +10,7 @@ use crate::{
errors::*,
group::Group,
key_exchange::tripledh::{NonceLen, TripleDH},
keypair::{PrivateKey, PublicKey, SizedBytesExt},
keypair::KeyPair,
opaque::*,
slow_hash::NoOpHash,
tests::mock_rng::CycleRng,
@@ -44,11 +44,13 @@ pub struct TestVectorParameters {
pub server_s_sk: Vec<u8>,
pub server_e_pk: Vec<u8>,
pub server_e_sk: Vec<u8>,
pub credential_identifier: Vec<u8>,
pub id_u: Vec<u8>,
pub id_s: Vec<u8>,
pub password: Vec<u8>,
pub blinding_factor: Vec<u8>,
pub oprf_key: Vec<u8>,
pub oprf_seed: Vec<u8>,
pub masking_nonce: Vec<u8>,
pub envelope_nonce: Vec<u8>,
pub client_nonce: Vec<u8>,
pub server_nonce: Vec<u8>,
@@ -61,7 +63,6 @@ pub struct TestVectorParameters {
pub credential_response: Vec<u8>,
pub credential_finalization: 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>,
@@ -70,40 +71,42 @@ pub struct TestVectorParameters {
}
static STR_PASSWORD: &str = "password";
static STR_CREDENTIAL_IDENTIFIER: &str = "credential_identifier";
static TEST_VECTOR: &str = r#"
{
"client_s_pk": "6e0a6082dd29936c44b47ecb8a5fe72e4b321a0ac314b0080ca4c48afdabd215",
"client_s_sk": "3000848b34d9073885d427e766b7093cc13bdce992ef31cd00ba2c77ff074504",
"client_e_pk": "5260ad6eb47ac1db44babcce9327327d50e1a0133c0425acca3efcf41b119718",
"client_e_sk": "1526e0bed9af28830da956589d65768ed2a20d9689e82c90b89e4e33904e4009",
"server_s_pk": "c21a38653eb19437669bfa066a446b6eea7c1f253ac7adf4798d6c68e171b273",
"server_s_sk": "2a38b385e9fb7e0a89aa0f005c729b0c4e22eeedea8c105cf136d9c5c334880f",
"server_e_pk": "125f4a2dd9353c8c37a08527a323908835d3fbc374260d32e829d5c3fa81f325",
"server_e_sk": "7ef6ada36f3983c0f24705a29d3a453e3e17c28d347f226b24c0aa5ab12a700d",
"client_s_pk": "e6201a178ea486df66929dc15e6b7cf522a02c4ff05afdfe221bbda08f9c5142",
"client_s_sk": "901f0363ae5b8606740ad0f4849c3f993743d3b1750244c27aa8a53035b42306",
"client_e_pk": "823dc5bf4e3479cf1be9cf2f9fe08f31a5171eb4ef012747b16364f4485e0022",
"client_e_sk": "288cece1cfbca7441b35fa4f6a1f4291855835e623c4874edefd735e507c3f0f",
"server_s_pk": "c44776fd33a5fb022bf6e26c4a5cb2c1ddbb785bd5822324df8eca6d80c1d279",
"server_s_sk": "5f1c3382a1cc430beeb9bdd044d4453d930fac8fe0d6bb65740b6baca208aa01",
"server_e_pk": "987fcf872beaf9547adbc66a63481e0f315960836d46956af2b1eb2608142f2e",
"server_e_sk": "a5d8174ade9f423a18438af605ee5b11047cf9973c21fffefcd336f690dd6103",
"credential_identifier": "637265644964656e746966696572",
"id_u": "696455",
"id_s": "696453",
"password": "70617373776f7264",
"blinding_factor": "a32862d66eb57246321fb6b229e83786745c3afdf8957ebe38b01c17571ba105",
"oprf_key": "0851f5ec43e0b702bfcb9d8ec208085b51c0fc5200234901407c176327aa0b02",
"envelope_nonce": "78b006042d011bdca5d0058a978d2103a6d546de311a2e8cd025fbc67303a468",
"client_nonce": "43497a6f86ba31a6a7f399271fb3b4b4f82c4af086bc431ebaeab7d768ff8a64",
"server_nonce": "680cd27da18bc56d4317e7db61de1726a70ebe4e49aee38a3bdb6787cf85466e",
"blinding_factor": "ac66fda6a29b52b1c719453adea5370852f906448609601e7da7892c29017b0b",
"oprf_seed": "c682275f90adc465ff551a82e54b6e16bd2e49cda05f7c6e6988a269b43a10f824ae31e90c8f8bbbb8cc85f552c0809acab37169332f68351dc7edc575d524f3",
"masking_nonce": "596b51d2a8a4485ae8d506684942cc2be327b72bac3ccf9864376264b2f5c5dbc5283e39cde28751430c6ab072c7c769c481ef61999488d740203a0b3dbce92d",
"envelope_nonce": "9b33bc17a2daa8346449bffe8c479202237a0e074ba82b88b6c4d122b22edac7",
"client_nonce": "a854353a0d88014af9eda6cb7ee3aff7d12fd4174c05221f3300d6ae12561ac0",
"server_nonce": "949f7773f95493a238f20a2212924108c6492d9eff5e1151b082c869496d1a7c",
"info1": "696e666f31",
"einfo2": "65696e666f32",
"registration_request": "14ba86e53018ce5507d2bfb2d98ad3f60e302d826bff3410a5ec669c8e1ef17d",
"registration_response": "aee5c937a85acfbdbd71faf1c5519bfe9e44b0b7489dcc663df9f1ca5b520b6ac21a38653eb19437669bfa066a446b6eea7c1f253ac7adf4798d6c68e171b273",
"registration_upload": "6e0a6082dd29936c44b47ecb8a5fe72e4b321a0ac314b0080ca4c48afdabd2150278b006042d011bdca5d0058a978d2103a6d546de311a2e8cd025fbc67303a4687618b32fe2ec2a5c2b6efecec1e6e535106de80af68733673daf0b644965966fa3f279e532d7ecef363f8d55ff6df4c473cfb1049a73f632972bfcc6744185d13a671dd6678d49fb1629a6fbfbe266937378fd9e772c2dd72692d1a35c020010",
"credential_request": "14ba86e53018ce5507d2bfb2d98ad3f60e302d826bff3410a5ec669c8e1ef17d43497a6f86ba31a6a7f399271fb3b4b4f82c4af086bc431ebaeab7d768ff8a640005696e666f315260ad6eb47ac1db44babcce9327327d50e1a0133c0425acca3efcf41b119718",
"credential_response": "aee5c937a85acfbdbd71faf1c5519bfe9e44b0b7489dcc663df9f1ca5b520b6ac21a38653eb19437669bfa066a446b6eea7c1f253ac7adf4798d6c68e171b2730278b006042d011bdca5d0058a978d2103a6d546de311a2e8cd025fbc67303a4687618b32fe2ec2a5c2b6efecec1e6e535106de80af68733673daf0b644965966fa3f279e532d7ecef363f8d55ff6df4c473cfb1049a73f632972bfcc6744185d13a671dd6678d49fb1629a6fbfbe266937378fd9e772c2dd72692d1a35c020010680cd27da18bc56d4317e7db61de1726a70ebe4e49aee38a3bdb6787cf85466e125f4a2dd9353c8c37a08527a323908835d3fbc374260d32e829d5c3fa81f32500068a4c321f3c375613862ba83f7e5abb8f1d26dbd8035d39f192eb1324c2214457098054a2cbdf5d4ab2894eaf152af8c4be61d701c5a1ab1ec3e1cee5810898140b81771db0be",
"credential_finalization": "330aa8ac01bbc9d9642fe1c286187379efe12da14aceab86b22449d21f242d89adabc0295751b4e007beabc413ae9cbf9979e324749953705fd85b87c9c1b1a2",
"client_registration_state": "a32862d66eb57246321fb6b229e83786745c3afdf8957ebe38b01c17571ba10570617373776f7264",
"client_login_state": "a32862d66eb57246321fb6b229e83786745c3afdf8957ebe38b01c17571ba105006714ba86e53018ce5507d2bfb2d98ad3f60e302d826bff3410a5ec669c8e1ef17d43497a6f86ba31a6a7f399271fb3b4b4f82c4af086bc431ebaeab7d768ff8a640005696e666f315260ad6eb47ac1db44babcce9327327d50e1a0133c0425acca3efcf41b11971800401526e0bed9af28830da956589d65768ed2a20d9689e82c90b89e4e33904e400943497a6f86ba31a6a7f399271fb3b4b4f82c4af086bc431ebaeab7d768ff8a6470617373776f7264",
"server_registration_state": "0851f5ec43e0b702bfcb9d8ec208085b51c0fc5200234901407c176327aa0b02",
"server_login_state": "89cd93dce8f59cf7b187736c50cbc3ca2e0bbbad0a0be1ddee180a2d95db60695b384be2dd673434ef94bcdbb1b457f63f41cd79ed2422c021c34ca1433b70576920ebb950ad1c40c8c015ec6832e12427e755ba21d005f0b6d5d66d2368ab5ec6f32151fced5a3aa25472c425912242de3638ef57f28b0dd02a956064e5bb9b8fcd73add52d233a454d6b20125e9506a95aae8772ebbfac4d70efe1fb10078fd40f93d84aa7db53853ca74436c917c427cd5c2e408860937e6f7ab80816ca47",
"password_file": "0851f5ec43e0b702bfcb9d8ec208085b51c0fc5200234901407c176327aa0b026e0a6082dd29936c44b47ecb8a5fe72e4b321a0ac314b0080ca4c48afdabd2150278b006042d011bdca5d0058a978d2103a6d546de311a2e8cd025fbc67303a4687618b32fe2ec2a5c2b6efecec1e6e535106de80af68733673daf0b644965966fa3f279e532d7ecef363f8d55ff6df4c473cfb1049a73f632972bfcc6744185d13a671dd6678d49fb1629a6fbfbe266937378fd9e772c2dd72692d1a35c020010",
"export_key": "8197f91f0d4de1ab126d8dfd06abd0d5df420ce40a135ef376e4ffe515930f413632390e7dc3dcfd19afff62b9113e10eb6c359fc327df6e9ad4d0f06c242322",
"session_key": "8fcd73add52d233a454d6b20125e9506a95aae8772ebbfac4d70efe1fb10078fd40f93d84aa7db53853ca74436c917c427cd5c2e408860937e6f7ab80816ca47"
"registration_request": "3a5d9fb60e6e91e97da6ca425a7ae8c5defce2ac0c6d89a8189f42f928fa3f04",
"registration_response": "145476844f947d9b639540c66045fc0e9c755d7a03c10ed618135fcd53cbdf30c44776fd33a5fb022bf6e26c4a5cb2c1ddbb785bd5822324df8eca6d80c1d279",
"registration_upload": "e6201a178ea486df66929dc15e6b7cf522a02c4ff05afdfe221bbda08f9c514276430085ed2a1f6f9ec49e0ee31f886c806ef1a15b07b0e243a736f38cfed069f97788f2843fc74b8dd6906186af8b77503a5e7932b22c0b772741a475352581029b33bc17a2daa8346449bffe8c479202237a0e074ba82b88b6c4d122b22edac7f32699e8be005286b985ec51d2b37212b04ccfc566cdd38a941177c31cae8158949c584667bf6bec49701e2ee9ac080d51919607993e31e9abf6a31368072e293011a8fce6781db258f1ccdff6b603eed9f405891d72c6e00145d8939ed226ad",
"credential_request": "3a5d9fb60e6e91e97da6ca425a7ae8c5defce2ac0c6d89a8189f42f928fa3f04a854353a0d88014af9eda6cb7ee3aff7d12fd4174c05221f3300d6ae12561ac00005696e666f31823dc5bf4e3479cf1be9cf2f9fe08f31a5171eb4ef012747b16364f4485e0022",
"credential_response": "145476844f947d9b639540c66045fc0e9c755d7a03c10ed618135fcd53cbdf30596b51d2a8a4485ae8d506684942cc2be327b72bac3ccf9864376264b2f5c5dba3f796185711239a9e6ef70e66331a52aaaa93629d44987f10a4374ac6a91ab27779da2bf6b2fe37bb9defb73c1a25fdfe8eb06d55d1e40588173b52d075853c57a919f0e088fbdbefa58659a011384145667a12c0ee7474d8f72e86ea52ed1de3617be02b90a90da1b7dd5d5f606da651ea97ceee7a00eb0d56ef76e587921d0a79ed45e37258a7933a31e0d378be00cbcfa1096b62feadbdf9612a33183909aea5d8174ade9f423a18438af605ee5b11047cf9973c21fffefcd336f690dd6103fca1950aac58db4be36a8902ef986dccf93ac6d8ac3203fb5ab2bed06996f27d0006d61f243b55af0cc2a44b7c0f3e060a9091b166cdf4dc3a1017aefd9c419462246f8b4998a853495fb13ebada79f98807d804189e03055047cbf7cf8374924aa137840342e566",
"credential_finalization": "716d4d7cb3090d6897cd01a693df9f8254b910c75a872f62dc5e08f5c23af724c3d499d0d0e8a888ab4ea3fc1eefb870ab64f0513a978a97dc0e99cd47d05142",
"client_registration_state": "ac66fda6a29b52b1c719453adea5370852f906448609601e7da7892c29017b0b70617373776f7264",
"client_login_state": "ac66fda6a29b52b1c719453adea5370852f906448609601e7da7892c29017b0b00673a5d9fb60e6e91e97da6ca425a7ae8c5defce2ac0c6d89a8189f42f928fa3f04a854353a0d88014af9eda6cb7ee3aff7d12fd4174c05221f3300d6ae12561ac00005696e666f31823dc5bf4e3479cf1be9cf2f9fe08f31a5171eb4ef012747b16364f4485e00220040288cece1cfbca7441b35fa4f6a1f4291855835e623c4874edefd735e507c3f0fa854353a0d88014af9eda6cb7ee3aff7d12fd4174c05221f3300d6ae12561ac070617373776f7264",
"server_login_state": "20508608406858c2038cd6ceef7ef4363648b341576b89f0fbf1c5dd262efade90e16a1cc74f73971fc7c37a0fca8209bf13b0015fefe3e32637d2e951b8500282a29681b6264fa2dd4c3b88cd7d654bdc8e8fb50ed6d78869b403978a1dd05a2c0c602037c1eba611ea2780c5c9ea68a620440adc9ec828e203590420207ad5396a1ffedeb4048f38e8197866c256dd034d3481615fa7f269a3512c99e461e21e8e1be737f7064ed8881205d9271c2c01453eef262140e0561fb64499abe863",
"password_file": "e6201a178ea486df66929dc15e6b7cf522a02c4ff05afdfe221bbda08f9c514276430085ed2a1f6f9ec49e0ee31f886c806ef1a15b07b0e243a736f38cfed069f97788f2843fc74b8dd6906186af8b77503a5e7932b22c0b772741a475352581029b33bc17a2daa8346449bffe8c479202237a0e074ba82b88b6c4d122b22edac7f32699e8be005286b985ec51d2b37212b04ccfc566cdd38a941177c31cae8158949c584667bf6bec49701e2ee9ac080d51919607993e31e9abf6a31368072e293011a8fce6781db258f1ccdff6b603eed9f405891d72c6e00145d8939ed226ad",
"export_key": "b01eea8b84b9fa10a179d8002cc782d69cc82c9c02c19200322457126624b24cf981c99257ec09b2d738b7a7a474b50149c8c855e63f2ba7aa0cfe4493334742",
"session_key": "396a1ffedeb4048f38e8197866c256dd034d3481615fa7f269a3512c99e461e21e8e1be737f7064ed8881205d9271c2c01453eef262140e0561fb64499abe863"
}
"#;
@@ -123,11 +126,13 @@ fn populate_test_vectors(values: &Value) -> TestVectorParameters {
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(),
credential_identifier: decode(&values, "credential_identifier").unwrap(),
id_u: decode(&values, "id_u").unwrap(),
id_s: decode(&values, "id_s").unwrap(),
password: decode(&values, "password").unwrap(),
blinding_factor: decode(&values, "blinding_factor").unwrap(),
oprf_key: decode(&values, "oprf_key").unwrap(),
oprf_seed: decode(&values, "oprf_seed").unwrap(),
masking_nonce: decode(&values, "masking_nonce").unwrap(),
envelope_nonce: decode(&values, "envelope_nonce").unwrap(),
client_nonce: decode(&values, "client_nonce").unwrap(),
server_nonce: decode(&values, "server_nonce").unwrap(),
@@ -141,7 +146,6 @@ fn populate_test_vectors(values: &Value) -> TestVectorParameters {
credential_finalization: decode(&values, "credential_finalization").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(),
export_key: decode(&values, "export_key").unwrap(),
@@ -160,6 +164,13 @@ fn stringify_test_vectors(p: &TestVectorParameters) -> String {
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());
s.push_str(
format!(
"\"credential_identifier\": \"{}\",\n",
hex::encode(&p.credential_identifier)
)
.as_str(),
);
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());
s.push_str(format!("\"password\": \"{}\",\n", hex::encode(&p.password)).as_str());
@@ -170,7 +181,14 @@ fn stringify_test_vectors(p: &TestVectorParameters) -> String {
)
.as_str(),
);
s.push_str(format!("\"oprf_key\": \"{}\",\n", hex::encode(&p.oprf_key)).as_str());
s.push_str(format!("\"oprf_seed\": \"{}\",\n", hex::encode(&p.oprf_seed)).as_str());
s.push_str(
format!(
"\"masking_nonce\": \"{}\",\n",
hex::encode(&p.masking_nonce)
)
.as_str(),
);
s.push_str(
format!(
"\"envelope_nonce\": \"{}\",\n",
@@ -238,13 +256,6 @@ fn stringify_test_vectors(p: &TestVectorParameters) -> String {
)
.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",
@@ -269,15 +280,18 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
let mut rng = OsRng;
// Inputs
let server_s_kp = CS::generate_random_keypair(&mut rng);
let server_e_kp = CS::generate_random_keypair(&mut rng);
let client_s_kp = CS::generate_random_keypair(&mut rng);
let client_e_kp = CS::generate_random_keypair(&mut rng);
let server_s_kp = KeyPair::<CS::Group>::generate_random(&mut rng);
let server_e_kp = KeyPair::<CS::Group>::generate_random(&mut rng);
let client_s_kp = KeyPair::<CS::Group>::generate_random(&mut rng);
let client_e_kp = KeyPair::<CS::Group>::generate_random(&mut rng);
let credential_identifier = b"credIdentifier";
let id_u = b"idU";
let id_s = b"idS";
let password = b"password";
let mut oprf_key_raw = [0u8; 32];
rng.fill_bytes(&mut oprf_key_raw);
let mut oprf_seed = [0u8; 64];
rng.fill_bytes(&mut oprf_seed);
let mut masking_nonce = [0u8; 64];
rng.fill_bytes(&mut masking_nonce);
let mut envelope_nonce = [0u8; 32];
rng.fill_bytes(&mut envelope_nonce);
let mut client_nonce = vec![0u8; NonceLen::to_usize()];
@@ -285,6 +299,10 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
let mut server_nonce = vec![0u8; NonceLen::to_usize()];
rng.fill_bytes(&mut server_nonce);
let server_setup =
ServerSetup::<CS>::deserialize(&[&oprf_seed, &server_s_kp.private().to_arr()[..]].concat())
.unwrap();
let blinding_factor = CS::Group::random_nonzero_scalar(&mut rng);
let blinding_factor_bytes = CS::Group::scalar_as_bytes(&blinding_factor).clone();
@@ -307,20 +325,16 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
.to_vec();
let client_registration_state = client_registration_start_result.state.serialize().to_vec();
let mut oprf_key_rng = CycleRng::new(oprf_key_raw.to_vec());
let server_registration_start_result = ServerRegistration::<CS>::start(
&mut oprf_key_rng,
&server_setup,
client_registration_start_result.message,
server_s_kp.public(),
&credential_identifier[..],
)
.unwrap();
let registration_response_bytes = server_registration_start_result
.message
.serialize()
.to_vec();
let oprf_key_bytes =
CS::Group::scalar_as_bytes(&server_registration_start_result.state.oprf_key).clone();
let server_registration_state = server_registration_start_result.state.serialize().to_vec();
let mut client_s_sk_and_nonce: Vec<u8> = Vec::new();
client_s_sk_and_nonce.extend_from_slice(&client_s_kp.private().to_arr());
@@ -340,10 +354,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
.serialize()
.to_vec();
let password_file = server_registration_start_result
.state
.finish(client_registration_finish_result.message)
.unwrap();
let password_file = ServerRegistration::finish(client_registration_finish_result.message);
let password_file_bytes = password_file.serialize();
let mut client_login_start: Vec<u8> = Vec::new();
@@ -363,6 +374,7 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
let mut server_e_sk_and_nonce_rng = CycleRng::new(
[
masking_nonce.to_vec(),
server_e_kp.private().to_arr().to_vec(),
server_nonce.to_vec(),
]
@@ -370,9 +382,10 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
);
let server_login_start_result = ServerLogin::<CS>::start(
&mut server_e_sk_and_nonce_rng,
password_file,
server_s_kp.private(),
&server_setup,
Some(password_file),
client_login_start_result.message,
credential_identifier,
ServerLoginStartParameters::WithInfoAndIdentifiers(
einfo2.to_vec(),
id_u.to_vec(),
@@ -401,11 +414,13 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
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(),
credential_identifier: credential_identifier.to_vec(),
id_u: id_u.to_vec(),
id_s: id_s.to_vec(),
password: password.to_vec(),
blinding_factor: blinding_factor_bytes.to_vec(),
oprf_key: oprf_key_bytes.to_vec(),
oprf_seed: oprf_seed.to_vec(),
masking_nonce: masking_nonce.to_vec(),
envelope_nonce: envelope_nonce.to_vec(),
client_nonce: client_nonce.to_vec(),
server_nonce: server_nonce.to_vec(),
@@ -419,7 +434,6 @@ fn generate_parameters<CS: CipherSuite>() -> TestVectorParameters {
credential_finalization: credential_finalization_bytes,
password_file: password_file_bytes,
client_registration_state,
server_registration_state,
client_login_state,
server_login_state,
session_key: client_login_finish_result.session_key,
@@ -463,7 +477,7 @@ fn test_serialization() -> Result<(), ProtocolError> {
serde_json::to_string(&client_registration_start_result.message).unwrap();
assert_eq!(
registration_request_json,
r#""FLqG5TAYzlUH0r+y2YrT9g4wLYJr/zQQpexmnI4e8X0=""#
r#""Ol2ftg5ukel9pspCWnroxd784qwMbYmoGJ9C+Sj6PwQ=""#
);
let registration_request: RegistrationRequest<RistrettoSha5123dhNoSlowHash> =
serde_json::from_str(&registration_request_json).unwrap();
@@ -489,21 +503,21 @@ fn test_serialization() -> Result<(), ProtocolError> {
#[test]
fn test_registration_response() -> Result<(), ProtocolError> {
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
let mut oprf_key_rng = CycleRng::new(parameters.oprf_key);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::deserialize(
&[&parameters.oprf_seed[..], &parameters.server_s_sk[..]].concat(),
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut oprf_key_rng,
&server_setup,
RegistrationRequest::deserialize(&parameters.registration_request[..])?,
&PublicKey::from_bytes(&parameters.server_s_pk[..])?,
&parameters.credential_identifier,
)?;
assert_eq!(
hex::encode(parameters.registration_response),
hex::encode(server_registration_start_result.message.serialize())
);
assert_eq!(
hex::encode(&parameters.server_registration_state),
hex::encode(server_registration_start_result.state.serialize())
);
Ok(())
}
@@ -539,12 +553,11 @@ fn test_registration_upload() -> Result<(), ProtocolError> {
fn test_password_file() -> Result<(), ProtocolError> {
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
let server_registration = ServerRegistration::<RistrettoSha5123dhNoSlowHash>::deserialize(
&parameters.server_registration_state[..],
)?;
let password_file = server_registration.finish(RegistrationUpload::deserialize(
&parameters.registration_upload[..],
)?)?;
let password_file = ServerRegistration::finish(RegistrationUpload::<
RistrettoSha5123dhNoSlowHash,
>::deserialize(
&parameters.registration_upload[..]
)?);
assert_eq!(
hex::encode(parameters.password_file),
@@ -584,15 +597,28 @@ fn test_credential_request() -> Result<(), ProtocolError> {
fn test_credential_response() -> Result<(), ProtocolError> {
let parameters = populate_test_vectors(&serde_json::from_str(TEST_VECTOR).unwrap());
let mut server_e_sk_and_nonce_rng =
CycleRng::new([parameters.server_e_sk, parameters.server_nonce].concat());
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::deserialize(
&[&parameters.oprf_seed[..], &parameters.server_s_sk[..]].concat(),
)?;
let mut server_e_sk_and_nonce_rng = CycleRng::new(
[
parameters.masking_nonce,
parameters.server_e_sk,
parameters.server_nonce,
]
.concat(),
);
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_e_sk_and_nonce_rng,
ServerRegistration::deserialize(&parameters.password_file[..])?,
&PrivateKey::from_bytes(&parameters.server_s_sk[..])?,
&server_setup,
Some(ServerRegistration::deserialize(
&parameters.password_file[..],
)?),
CredentialRequest::<RistrettoSha5123dhNoSlowHash>::deserialize(
&parameters.credential_request[..],
)?,
&parameters.credential_identifier,
ServerLoginStartParameters::WithInfoAndIdentifiers(
parameters.einfo2.to_vec(),
parameters.id_u,
@@ -675,9 +701,10 @@ fn test_complete_flow(
registration_password: &[u8],
login_password: &[u8],
) -> Result<(), ProtocolError> {
let credential_identifier = b"credentialIdentifier";
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
@@ -685,18 +712,16 @@ fn test_complete_flow(
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
&server_setup,
client_registration_start_result.message,
server_kp.public(),
credential_identifier,
)?;
let client_registration_finish_result = client_registration_start_result.state.finish(
&mut client_rng,
server_registration_start_result.message,
ClientRegistrationFinishParameters::default(),
)?;
let p_file = server_registration_start_result
.state
.finish(client_registration_finish_result.message)?;
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
login_password,
@@ -704,9 +729,10 @@ fn test_complete_flow(
)?;
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
p_file,
&server_kp.private(),
&server_setup,
Some(p_file),
client_login_start_result.message,
credential_identifier,
ServerLoginStartParameters::default(),
)?;
@@ -772,40 +798,11 @@ fn test_zeroize_client_registration_start() -> Result<(), ProtocolError> {
Ok(())
}
#[test]
fn test_zeroize_server_registration_start() -> Result<(), ProtocolError> {
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
STR_PASSWORD.as_bytes(),
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
client_registration_start_result.message,
server_kp.public(),
)?;
let mut state = server_registration_start_result.state;
let ptrs = state.as_byte_ptrs();
state.zeroize();
for (ptr, len) in ptrs {
let bytes = unsafe { from_raw_parts(ptr, len) };
assert!(bytes.iter().all(|&x| x == 0));
}
Ok(())
}
#[test]
fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
@@ -813,9 +810,9 @@ fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
&server_setup,
client_registration_start_result.message,
server_kp.public(),
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
)?;
let client_registration_finish_result = client_registration_start_result.state.finish(
&mut client_rng,
@@ -839,7 +836,7 @@ fn test_zeroize_client_registration_finish() -> Result<(), ProtocolError> {
fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> {
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
@@ -847,18 +844,16 @@ fn test_zeroize_server_registration_finish() -> Result<(), ProtocolError> {
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
&server_setup,
client_registration_start_result.message,
server_kp.public(),
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
)?;
let client_registration_finish_result = client_registration_start_result.state.finish(
&mut client_rng,
server_registration_start_result.message,
ClientRegistrationFinishParameters::default(),
)?;
let p_file = server_registration_start_result
.state
.finish(client_registration_finish_result.message)?;
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
let mut state = p_file;
let ptrs = state.as_byte_ptrs();
@@ -897,7 +892,7 @@ fn test_zeroize_client_login_start() -> Result<(), ProtocolError> {
fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
@@ -905,18 +900,16 @@ fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
&server_setup,
client_registration_start_result.message,
server_kp.public(),
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
)?;
let client_registration_finish_result = client_registration_start_result.state.finish(
&mut client_rng,
server_registration_start_result.message,
ClientRegistrationFinishParameters::default(),
)?;
let p_file = server_registration_start_result
.state
.finish(client_registration_finish_result.message)?;
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
STR_PASSWORD.as_bytes(),
@@ -924,9 +917,10 @@ fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
)?;
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
p_file,
&server_kp.private(),
&server_setup,
Some(p_file),
client_login_start_result.message,
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
ServerLoginStartParameters::default(),
)?;
@@ -946,7 +940,7 @@ fn test_zeroize_server_login_start() -> Result<(), ProtocolError> {
fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
@@ -954,18 +948,16 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
&server_setup,
client_registration_start_result.message,
server_kp.public(),
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
)?;
let client_registration_finish_result = client_registration_start_result.state.finish(
&mut client_rng,
server_registration_start_result.message,
ClientRegistrationFinishParameters::default(),
)?;
let p_file = server_registration_start_result
.state
.finish(client_registration_finish_result.message)?;
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
STR_PASSWORD.as_bytes(),
@@ -973,9 +965,10 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
)?;
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
p_file,
&server_kp.private(),
&server_setup,
Some(p_file),
client_login_start_result.message,
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
ServerLoginStartParameters::default(),
)?;
let client_login_finish_result = client_login_start_result.state.finish(
@@ -999,7 +992,7 @@ fn test_zeroize_client_login_finish() -> Result<(), ProtocolError> {
fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
let mut client_rng = OsRng;
let mut server_rng = OsRng;
let server_kp = RistrettoSha5123dhNoSlowHash::generate_random_keypair(&mut server_rng);
let server_setup = ServerSetup::<RistrettoSha5123dhNoSlowHash>::new(&mut server_rng);
let client_registration_start_result =
ClientRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
@@ -1007,18 +1000,16 @@ fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
)?;
let server_registration_start_result =
ServerRegistration::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
&server_setup,
client_registration_start_result.message,
server_kp.public(),
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
)?;
let client_registration_finish_result = client_registration_start_result.state.finish(
&mut client_rng,
server_registration_start_result.message,
ClientRegistrationFinishParameters::default(),
)?;
let p_file = server_registration_start_result
.state
.finish(client_registration_finish_result.message)?;
let p_file = ServerRegistration::finish(client_registration_finish_result.message);
let client_login_start_result = ClientLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut client_rng,
STR_PASSWORD.as_bytes(),
@@ -1026,9 +1017,10 @@ fn test_zeroize_server_login_finish() -> Result<(), ProtocolError> {
)?;
let server_login_start_result = ServerLogin::<RistrettoSha5123dhNoSlowHash>::start(
&mut server_rng,
p_file,
&server_kp.private(),
&server_setup,
Some(p_file),
client_login_start_result.message,
STR_CREDENTIAL_IDENTIFIER.as_bytes(),
ServerLoginStartParameters::default(),
)?;
let client_login_finish_result = client_login_start_result.state.finish(