diff --git a/src/lib.rs b/src/lib.rs index 871bd77..c46d1dc 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -388,27 +388,46 @@ pub fn new_negative_report_key(db: &Db, date: u32) -> Option { } } -/// Receive an encrypted negative report. Attempt to decrypt it and if -/// successful, add it to the database to be processed later. -pub fn handle_encrypted_negative_report(db: &Db, enc_report: EncryptedNegativeReport) { +/// If we have a key for the requested day, return the secret part. +pub fn get_negative_report_secret_key(db: &Db, date: u32) -> Option { if db.contains_key("nr-keys").unwrap() { let nr_keys: BTreeMap = match bincode::deserialize(&db.get("nr-keys").unwrap().unwrap()) { Ok(map) => map, Err(_) => { - return; + return None; } }; - if nr_keys.contains_key(&enc_report.date) { - let secret = nr_keys.get(&enc_report.date).unwrap(); - let nr = match enc_report.decrypt(&secret) { - Ok(nr) => nr, - Err(_) => { - return; - } - }; - save_negative_report_to_process(&db, nr); + if nr_keys.contains_key(&date) { + let secret = nr_keys.get(&date).unwrap(); + Some(secret.clone()) + } else { + None } + } else { + None + } +} + +/// If we have a key for the requested day, return the public part. +pub fn get_negative_report_public_key(db: &Db, date: u32) -> Option { + match get_negative_report_secret_key(&db, date) { + Some(secret) => Some(PublicKey::from(&secret)), + None => None, + } +} + +/// Receive an encrypted negative report. Attempt to decrypt it and if +/// successful, add it to the database to be processed later. +pub fn handle_encrypted_negative_report(db: &Db, enc_report: EncryptedNegativeReport) { + match get_negative_report_secret_key(&db, enc_report.date) { + Some(secret) => match enc_report.decrypt(&secret) { + Ok(nr) => { + save_negative_report_to_process(&db, nr); + } + Err(_) => {} + }, + None => {} } } diff --git a/src/request_handler.rs b/src/request_handler.rs index 93636d4..8f23739 100644 --- a/src/request_handler.rs +++ b/src/request_handler.rs @@ -15,10 +15,31 @@ pub async fn handle(db: &Db, req: Request) -> Result, Infal .body(Body::from("Allow POST")) .unwrap()), _ => match (req.method(), req.uri().path()) { + #[cfg(feature = "simulation")] + (&Method::POST, "/nrkey") => Ok::<_, Infallible>({ + // We need a way for simulated users to get the keys to + // encrypt their negative reports. As Troll Patrol may + // not be directly accessible when users are submitting + // negative reports, in practice we expect that these + // keys will be made available elsewhere. + let bytes = body::to_bytes(req.into_body()).await.unwrap(); + // Expect the body to contain the date for the key the + // user requests. + let date: u32 = match serde_json::from_slice(&bytes) { + Ok(date) => date, + Err(e) => { + let response = json!({"error": e.to_string()}); + let val = serde_json::to_string(&response).unwrap(); + return Ok(prepare_header(val)); + } + }; + let pubkey = get_negative_report_public_key(&db, date); + prepare_header(serde_json::to_string(&pubkey).unwrap()) + }), (&Method::POST, "/negativereport") => Ok::<_, Infallible>({ let bytes = body::to_bytes(req.into_body()).await.unwrap(); // We cannot depend on the transport layer providing E2EE, so - // positive reports should be separately encrypted. + // negative reports should be separately encrypted. let enr: EncryptedNegativeReport = match bincode::deserialize(&bytes) { Ok(enr) => enr, Err(e) => { diff --git a/src/simulation/state.rs b/src/simulation/state.rs index ad6aefa..3e893f4 100644 --- a/src/simulation/state.rs +++ b/src/simulation/state.rs @@ -1,7 +1,5 @@ use lox_cli::networking::*; use lox_library::IssuerPubKey; -use std::collections::HashMap; -use x25519_dalek::PublicKey; pub struct State { pub la_pubkeys: Vec, @@ -16,5 +14,4 @@ pub struct State { pub prob_user_is_censor: f64, pub prob_user_submits_reports: f64, pub probs_user_in_country: Vec<(String, f64)>, - pub tp_pubkeys: HashMap, } diff --git a/src/simulation/user.rs b/src/simulation/user.rs index a6a2d39..f7d996d 100644 --- a/src/simulation/user.rs +++ b/src/simulation/user.rs @@ -9,6 +9,7 @@ use lox_library::{ bridge_table::BridgeLine, cred::Lox, proto::check_blockage::MIN_TRUST_LEVEL, scalar_u32, }; use rand::Rng; +use x25519_dalek::PublicKey; pub struct User { // Does this user cooperate with a censor? @@ -142,7 +143,18 @@ impl User { pub async fn send_negative_reports(state: &State, reports: Vec) { let date = get_date(); - let pubkey = state.tp_pubkeys.get(&date).unwrap(); + //let pubkey = state.tp_pubkeys.get(&date).unwrap(); + let pubkey = serde_json::from_slice::>( + &state + .net_tp + .request( + "/nrkey".to_string(), + serde_json::to_string(&date).unwrap().into(), + ) + .await, + ) + .unwrap() + .unwrap(); for report in reports { state .net_tp