diff --git a/services/identity/src/config.rs b/services/identity/src/config.rs --- a/services/identity/src/config.rs +++ b/services/identity/src/config.rs @@ -1,11 +1,11 @@ use curve25519_dalek::ristretto::RistrettoPoint; use once_cell::sync::Lazy; use opaque_ke::{errors::PakeError, keypair::KeyPair}; -use std::{env, fmt, fs, io, path::Path}; +use std::{env, fmt, fs, io, path}; use crate::constants::{ AUTH_TOKEN, LOCALSTACK_ENDPOINT, SECRETS_DIRECTORY, SECRETS_FILE_EXTENSION, - SECRETS_FILE_NAME, + SECRETS_FILE_NAME, SECRETS_SETUP_FILE, }; pub static CONFIG: Lazy = @@ -17,15 +17,18 @@ #[derive(Clone)] pub struct Config { + // Opaque 1.2 server secrets pub server_keypair: KeyPair, // this is temporary, while the only authorized caller is ashoat's keyserver pub keyserver_auth_token: String, pub localstack_endpoint: Option, + // Opaque 2.0 server secrets + pub server_setup: comm_opaque2::ServerSetup, } impl Config { fn load() -> Result { - let mut path = env::current_dir()?; + let mut path = path::PathBuf::new(); path.push(SECRETS_DIRECTORY); path.push(SECRETS_FILE_NAME); path.set_extension(SECRETS_FILE_EXTENSION); @@ -34,10 +37,16 @@ env::var(AUTH_TOKEN).unwrap_or_else(|_| String::from("test")); let localstack_endpoint = env::var(LOCALSTACK_ENDPOINT).ok(); + let mut path = path::PathBuf::new(); + path.push(SECRETS_DIRECTORY); + path.push(SECRETS_SETUP_FILE); + let server_setup = get_server_setup_from_file(&path)?; + Ok(Self { server_keypair, keyserver_auth_token, localstack_endpoint, + server_setup, }) } } @@ -52,22 +61,29 @@ } } -#[derive( - Debug, derive_more::Display, derive_more::From, derive_more::Error, -)] +#[derive(Debug, derive_more::Display, derive_more::From)] pub enum Error { #[display(...)] Pake(PakeError), #[display(...)] + Opaque(comm_opaque2::ProtocolError), + #[display(...)] IO(io::Error), #[display(...)] Env(env::VarError), } -fn get_keypair_from_file>( +fn get_keypair_from_file>( path: P, ) -> Result, Error> { let bytes = fs::read(path)?; KeyPair::from_private_key_slice(&bytes) .map_err(|e| Error::Pake(PakeError::CryptoError(e))) } + +fn get_server_setup_from_file>( + path: &P, +) -> Result, Error> { + let bytes = fs::read(path)?; + comm_opaque2::ServerSetup::deserialize(&bytes).map_err(Error::Opaque) +} diff --git a/services/identity/src/constants.rs b/services/identity/src/constants.rs --- a/services/identity/src/constants.rs +++ b/services/identity/src/constants.rs @@ -3,6 +3,7 @@ pub const SECRETS_DIRECTORY: &str = "secrets"; pub const SECRETS_FILE_NAME: &str = "secret_key"; pub const SECRETS_FILE_EXTENSION: &str = "txt"; +pub const SECRETS_SETUP_FILE: &str = "server_setup.txt"; // DynamoDB diff --git a/services/identity/src/keygen.rs b/services/identity/src/keygen.rs --- a/services/identity/src/keygen.rs +++ b/services/identity/src/keygen.rs @@ -1,24 +1,41 @@ -use crate::constants::{SECRETS_FILE_EXTENSION, SECRETS_FILE_NAME}; +use crate::constants::{ + SECRETS_FILE_EXTENSION, SECRETS_FILE_NAME, SECRETS_SETUP_FILE, +}; use comm_opaque::Cipher; use opaque_ke::{ciphersuite::CipherSuite, rand::rngs::OsRng}; -use std::{env, fs, io}; +use std::{fs, io, path}; pub fn generate_and_persist_keypair(dir: &str) -> Result<(), io::Error> { + let mut secrets_dir = path::PathBuf::new(); + secrets_dir.push(dir); + if !secrets_dir.exists() { + println!("Creating secrets directory {:?}", secrets_dir); + fs::create_dir(&secrets_dir)?; + } + + // Opaque_ke 1.2.0 setup let mut rng = OsRng; let server_kp = Cipher::generate_random_keypair(&mut rng); - let mut path = env::current_dir()?; - path.push(dir); - if !path.exists() { - println!("Creating secrets directory {:?}", path); - fs::create_dir(&path)?; - } + let mut path = secrets_dir.clone(); path.push(SECRETS_FILE_NAME); path.set_extension(SECRETS_FILE_EXTENSION); + if !path.exists() { + println!("Writing secret key to {:?}", path); + fs::write(&path, server_kp.private().to_arr())?; + } else { + println!("{:?} already exists, skipping", path); + } + + // Opaque 2.0 setup + let server_setup = comm_opaque2::server::generate_server_setup(); + let mut path = secrets_dir.clone(); + path.push(SECRETS_SETUP_FILE); if path.exists() { - println!("{:?} already exists", path); - return Ok(()); + eprintln!("{:?} already exists, skipping", path); + } else { + println!("Writing setup file to {:?}", path); + fs::write(&path, server_setup.serialize())?; } - println!("Writing secret key to {:?}", path); - fs::write(&path, server_kp.private().to_arr())?; + Ok(()) } diff --git a/shared/comm-opaque2/src/lib.rs b/shared/comm-opaque2/src/lib.rs --- a/shared/comm-opaque2/src/lib.rs +++ b/shared/comm-opaque2/src/lib.rs @@ -5,6 +5,9 @@ pub mod server; pub use crate::opaque::Cipher; +pub use opaque_ke; +pub use opaque_ke::errors::ProtocolError; +pub use opaque_ke::ServerSetup; #[test] pub fn test_register_and_login() { diff --git a/shared/comm-opaque2/src/server/mod.rs b/shared/comm-opaque2/src/server/mod.rs --- a/shared/comm-opaque2/src/server/mod.rs +++ b/shared/comm-opaque2/src/server/mod.rs @@ -3,3 +3,12 @@ pub use login::Login; pub use register::Registration; + +use opaque_ke::rand::rngs::OsRng; +use opaque_ke::ServerSetup; + +use crate::Cipher; + +pub fn generate_server_setup() -> ServerSetup { + ServerSetup::::new(&mut OsRng) +}