easy-srp 0.3.0

easy-srp wraps the rust srp crate and provides an easy to use API.
Documentation
//! Easy to use wrapper around the `srp` crate for SRP6 authentication
//! 
//! See the `README.md` for more information about the usage of this crate. The
//! tests at the end of this file may also provide a good starting point for
//! how to use the client- and server-workflows.

#[cfg(feature = "client")]
mod client;

#[cfg(feature = "client")]
pub use client::{*};

#[cfg(feature = "server")]
mod server;

#[cfg(feature = "server")]
pub use server::{*};

pub mod groups;
pub mod types;
pub mod messages;
pub(crate) mod util;

#[cfg(test)]
mod test {
  #![allow(unused_variables)]

  use base64::Engine;
  use sha2::Sha256;
  use crate::{ClientStep1Result, ClientStep3Params, ClientStep3Result, 
    GenerateVerifierParams, ServerStep2Params, ServerStep2Result, 
    ServerStep4Params, ServerStep4Result};

  #[test]
  pub fn test_salt_none() {
    use sha2::Sha256;
    use crate::groups::G_4096;
    use crate::client::{ClientRegistrationWorkflow, GenerateVerifierParams};
    
    let verifier_wf = ClientRegistrationWorkflow::<Sha256>::new(&G_4096);
    
    let username = "lorem".to_string();
    let password = "ipsum".to_string();
    
    let verifier = verifier_wf.generate_verifier(GenerateVerifierParams {
      username: username.clone(),
      password: password.clone(),
      salt: None
    }).expect("could not generate verifier.");

    assert!(!verifier.salt.is_empty());
  }

  #[test]
  pub fn test_salt_default_size() {
    use sha2::Sha256;
    use crate::groups::G_4096;
    use crate::client::{ClientRegistrationWorkflow, GenerateVerifierParams};
    
    let verifier_wf = ClientRegistrationWorkflow::<Sha256>::new(&G_4096);
    
    let username = "lorem".to_string();
    let password = "ipsum".to_string();
    
    let verifier = verifier_wf.generate_verifier(GenerateVerifierParams {
      username: username.clone(),
      password: password.clone(),
      salt: None
    }).expect("could not generate verifier.");

    assert!(!verifier.salt.is_empty());
    assert!(verifier.salt.len() >= 8);
  }

  #[test]
  pub fn test_salt_some() {
    use sha2::Sha256;
    use crate::groups::G_4096;
    use crate::client::{ClientRegistrationWorkflow, GenerateVerifierParams};
    
    let verifier_wf = ClientRegistrationWorkflow::<Sha256>::new(&G_4096);
    
    let username = "lorem".to_string();
    let password = "ipsum".to_string();
    let salt = vec![1u8, 2u8, 4u8, 8u8, 16u8, 32u8, 64u8, 128u8, 7u8, 31u8];

    let verifier = verifier_wf.generate_verifier(GenerateVerifierParams {
      username: username.clone(),
      password: password.clone(),
      salt: Some(salt.clone())
    }).expect("could not generate verifier.");

    assert!(verifier.salt.len() == salt.len());
    assert!(verifier.salt.as_slice() == salt.as_slice());
  }

  #[test]
  pub fn test_verifier_generation() {
    use sha2::Sha256;
    use crate::groups::G_4096;
    use crate::client::{ClientRegistrationWorkflow, GenerateVerifierParams};
    
    let verifier_wf = ClientRegistrationWorkflow::<Sha256>::new(&G_4096);
    
    let username = "lorem".to_string();
    let password = "ipsum".to_string();
    
    let verifier = verifier_wf.generate_verifier(GenerateVerifierParams {
      username: username.clone(),
      password: password.clone(),
      salt: None
    }).expect("could not generate verifier.");
  }

  #[test]
  pub fn test_full_workflow() {
    let test_group = &crate::groups::G_4096;
    let verifier_wf = crate::client::ClientRegistrationWorkflow::<Sha256>::new(test_group);

    let username = "lorem".to_string();
    let password = "ipsum".to_string();

    let verifier = verifier_wf.generate_verifier(GenerateVerifierParams {
      username: username.clone(),
      password: password.clone(),
      salt: None
    }).expect("could not generate verifier.");

    let client_wf = crate::client::ClientAuthenticationWorkflow::<Sha256>::new(test_group);
    let step1_result: ClientStep1Result = client_wf.step1().expect("could not compute step1");

    let server_wf = crate::server::ServerAuthenticationWorkflow::<Sha256>::new(test_group);
    let step2_result: ServerStep2Result = server_wf.step2(ServerStep2Params {
      // client_public_a: step1_result.client_public_a.as_slice(),
      stored_verifier: verifier.verifier.as_slice()
    }).expect("could not compute step2");

    let step3_result: ClientStep3Result<Sha256> = client_wf.step3(ClientStep3Params {
      client_a: step1_result.client_private_a.as_slice(),
      username: username.clone(),
      password: password.clone(),
      salt: verifier.salt.as_slice(),
      server_public_b: step2_result.server_public_b.as_slice()
    }).expect("could not compute step3");

    let step4_result: ServerStep4Result<Sha256> = server_wf.step4(ServerStep4Params {
      client_public_a: step1_result.client_public_a.as_slice(),
      server_private_b: step2_result.server_private_b.as_slice(),
      stored_verifier: verifier.verifier.as_slice(),
      client_proof: step3_result.proof()
    }).expect("could not compute step4");

    step4_result.verify_client(step3_result.proof())
      .expect("could not verify client.");

    step3_result.verify_server(step4_result.proof())
      .expect("could not verify server.");

    let client_key = step3_result.key();
    let server_key = step4_result.key();

    let engine = base64::engine::general_purpose::STANDARD_NO_PAD;
    println!("client_key: {}", engine.encode(client_key));
    println!("server_key: {}", engine.encode(server_key));
    
  }
}