|
|
@@ -20,7 +20,7 @@ threshold, the user's report submission will be rejected.
|
|
|
|
|
|
The user presents their current Lox credential:
|
|
|
- id: revealed
|
|
|
-- bucket: blinded
|
|
|
+- bucket: blinded (but known to the server)
|
|
|
- trust_level: blinded
|
|
|
- level_since: blinded
|
|
|
- invites_remaining: blinded
|
|
|
@@ -28,8 +28,6 @@ The user presents their current Lox credential:
|
|
|
- false_reports: blinded
|
|
|
- pending: revealed
|
|
|
|
|
|
-and D = bucket * H to indicate which bucket they have
|
|
|
-
|
|
|
and a new Lox credential to be issued:
|
|
|
|
|
|
- id: jointly chosen by the user and BA
|
|
|
@@ -52,8 +50,7 @@ and a new Lox credential to be issued:
|
|
|
#[cfg(feature = "bridgeauth")]
|
|
|
use super::super::dup_filter::SeenType;
|
|
|
use super::super::{
|
|
|
- bridge_table::MAX_BRIDGES_PER_BUCKET, get_H, report_table::MAX_FALSE_REPORTS, scalar_u32,
|
|
|
- Scalar, G,
|
|
|
+ bridge_table::MAX_BRIDGES_PER_BUCKET, report_table::MAX_FALSE_REPORTS, scalar_u32, Scalar, G,
|
|
|
};
|
|
|
#[cfg(feature = "bridgeauth")]
|
|
|
use super::super::{report_table::ReportStatus, BridgeAuth, BridgeLine};
|
|
|
@@ -66,7 +63,7 @@ use sha2::Sha512;
|
|
|
|
|
|
const SESSION_ID: &[u8] = b"report_submit";
|
|
|
|
|
|
-muCMZProtocol! { report_submit<max_false_reports, new_false_reports, bucket>,
|
|
|
+muCMZProtocol! { report_submit<max_false_reports, new_false_reports>,
|
|
|
L: Lox { id: R, bucket: H, trust_level: H, level_since: H, invites_remaining: H, blockages: H, false_reports: H, pending: R },
|
|
|
N: Lox { id: J, bucket: H, trust_level: H, level_since: H, invites_remaining: H, blockages: H, false_reports: H, pending: I },
|
|
|
N.bucket = L.bucket,
|
|
|
@@ -76,12 +73,6 @@ muCMZProtocol! { report_submit<max_false_reports, new_false_reports, bucket>,
|
|
|
N.blockages = L.blockages,
|
|
|
(0..=max_false_reports).contains(L.false_reports + new_false_reports),
|
|
|
N.false_reports = L.false_reports + new_false_reports,
|
|
|
-
|
|
|
- // Before checking this proof, we need to determine (from D =
|
|
|
- // bucket*H submitted in the report) which bucket the user is
|
|
|
- // claiming to have in their credential. Check that the user's
|
|
|
- // claimed bucket is correct.
|
|
|
- L.bucket = bucket,
|
|
|
}
|
|
|
|
|
|
pub fn request(
|
|
|
@@ -92,7 +83,6 @@ pub fn request(
|
|
|
) -> Result<
|
|
|
(
|
|
|
(report_submit::Request, report_submit::ClientState),
|
|
|
- G,
|
|
|
[bool; MAX_BRIDGES_PER_BUCKET],
|
|
|
),
|
|
|
CredentialError,
|
|
|
@@ -135,9 +125,6 @@ pub fn request(
|
|
|
return Err(CredentialError::NoBridgesReported);
|
|
|
}
|
|
|
|
|
|
- let H = get_H();
|
|
|
- let D = L.bucket.unwrap() * H;
|
|
|
-
|
|
|
let mut N = Lox::using_pubkey(L.get_pubkey());
|
|
|
N.bucket = L.bucket;
|
|
|
N.trust_level = L.trust_level;
|
|
|
@@ -150,10 +137,9 @@ pub fn request(
|
|
|
let params = report_submit::Params {
|
|
|
max_false_reports: MAX_FALSE_REPORTS.into(),
|
|
|
new_false_reports: new_false_reports.into(),
|
|
|
- bucket: L.bucket.unwrap(),
|
|
|
};
|
|
|
match report_submit::prepare(rng, SESSION_ID, &L, N, ¶ms) {
|
|
|
- Ok(req_state) => Ok((req_state, D, bridges_being_reported)),
|
|
|
+ Ok(req_state) => Ok((req_state, bridges_being_reported)),
|
|
|
Err(e) => Err(CredentialError::CMZError(e)),
|
|
|
}
|
|
|
}
|
|
|
@@ -163,35 +149,12 @@ impl BridgeAuth {
|
|
|
pub fn handle_report_submit(
|
|
|
&mut self,
|
|
|
req: report_submit::Request,
|
|
|
- D: G,
|
|
|
bridges_being_reported: [bool; MAX_BRIDGES_PER_BUCKET],
|
|
|
) -> Result<report_submit::Reply, CredentialError> {
|
|
|
let mut rng = rand::thread_rng();
|
|
|
let reqbytes = req.as_bytes();
|
|
|
let recvreq = report_submit::Request::try_from(&reqbytes[..]).unwrap();
|
|
|
|
|
|
- let (bucket, bridges) = match self.bridge_table.get_bucket_and_bridges(D) {
|
|
|
- Ok((bucket, bridges)) => (bucket, bridges),
|
|
|
- Err(e) => {
|
|
|
- return Err(e);
|
|
|
- }
|
|
|
- };
|
|
|
-
|
|
|
- // Check that user indicated at least one non-default bridge to
|
|
|
- // submit a report for
|
|
|
- let mut reporting_a_bridge = false;
|
|
|
- for i in 0..MAX_BRIDGES_PER_BUCKET {
|
|
|
- if bridges_being_reported[i] {
|
|
|
- if bridges[i] == BridgeLine::default().get_hashed_fingerprint() {
|
|
|
- return Err(CredentialError::NonExistentBridgeReported);
|
|
|
- }
|
|
|
- reporting_a_bridge = true;
|
|
|
- }
|
|
|
- }
|
|
|
- if !reporting_a_bridge {
|
|
|
- return Err(CredentialError::NoBridgesReported);
|
|
|
- }
|
|
|
-
|
|
|
let mut bridges_with_old_reports = Vec::<[u8; 20]>::new();
|
|
|
|
|
|
match report_submit::handle(
|
|
|
@@ -202,6 +165,50 @@ impl BridgeAuth {
|
|
|
L.set_privkey(&self.lox_priv);
|
|
|
N.set_privkey(&self.lox_priv);
|
|
|
|
|
|
+ let bucket = match self
|
|
|
+ .report_table
|
|
|
+ .get_user_bucket(L.pending.unwrap().clone())
|
|
|
+ {
|
|
|
+ Some(bucket) => bucket,
|
|
|
+ None => {
|
|
|
+ return Err(CMZError::RevealAttrMissing(
|
|
|
+ "pending",
|
|
|
+ "Pending value is incorrect",
|
|
|
+ ));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ let bridges = match self.bridge_table.get_bridge_hashed_fingerprints(bucket) {
|
|
|
+ Ok(bridges) => bridges,
|
|
|
+ Err(_) => {
|
|
|
+ return Err(CMZError::RevealAttrMissing(
|
|
|
+ "bucket",
|
|
|
+ "Bucket value is incorrect",
|
|
|
+ ));
|
|
|
+ }
|
|
|
+ };
|
|
|
+
|
|
|
+ // Check that user indicated at least one non-default bridge to
|
|
|
+ // submit a report for
|
|
|
+ let mut reporting_a_bridge = false;
|
|
|
+ for i in 0..MAX_BRIDGES_PER_BUCKET {
|
|
|
+ if bridges_being_reported[i] {
|
|
|
+ if bridges[i] == BridgeLine::default().get_hashed_fingerprint() {
|
|
|
+ return Err(CMZError::RevealAttrMissing(
|
|
|
+ "bridges_being_reported",
|
|
|
+ "Report submitted for a bridge that does not exist",
|
|
|
+ ));
|
|
|
+ }
|
|
|
+ reporting_a_bridge = true;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if !reporting_a_bridge {
|
|
|
+ return Err(CMZError::RevealAttrMissing(
|
|
|
+ "bridges_being_reported",
|
|
|
+ "No bridges are being reported",
|
|
|
+ ));
|
|
|
+ }
|
|
|
+
|
|
|
let mut new_false_reports: u32 = 0;
|
|
|
|
|
|
for i in 0..MAX_BRIDGES_PER_BUCKET {
|
|
|
@@ -243,7 +250,6 @@ impl BridgeAuth {
|
|
|
Ok(report_submit::Params {
|
|
|
max_false_reports: MAX_FALSE_REPORTS.into(),
|
|
|
new_false_reports: new_false_reports.into(),
|
|
|
- bucket: bucket,
|
|
|
})
|
|
|
},
|
|
|
|L: &Lox, _N: &Lox| {
|
|
|
@@ -290,11 +296,16 @@ mod tests {
|
|
|
use crate::mock_auth::TestHarness;
|
|
|
|
|
|
use crate::proto::*;
|
|
|
- use crate::{report_table::ReportStatus, BridgeLine, Scalar, MAX_BRIDGES_PER_BUCKET};
|
|
|
+ use crate::{
|
|
|
+ report_table::{CountryCode, ReportStatus},
|
|
|
+ BridgeLine, Scalar, MAX_BRIDGES_PER_BUCKET,
|
|
|
+ };
|
|
|
use std::time::SystemTime;
|
|
|
|
|
|
#[test]
|
|
|
- fn test_report_submit() {
|
|
|
+ fn test_report_protocols() {
|
|
|
+ let cc = CountryCode::RU;
|
|
|
+
|
|
|
let mut th = TestHarness::new();
|
|
|
let rng = &mut rand::thread_rng();
|
|
|
let invite = th.bdb.invite().unwrap();
|
|
|
@@ -303,7 +314,7 @@ mod tests {
|
|
|
assert_eq!(lox_cred.pending.unwrap(), Scalar::ZERO);
|
|
|
|
|
|
// Enter pending state
|
|
|
- lox_cred = th.report_init(rng, lox_cred.clone());
|
|
|
+ lox_cred = th.report_init(rng, lox_cred.clone(), cc);
|
|
|
th.verify_lox(&lox_cred);
|
|
|
let pending_1 = lox_cred.pending.unwrap();
|
|
|
assert!(pending_1 != Scalar::ZERO);
|
|
|
@@ -325,11 +336,11 @@ mod tests {
|
|
|
// report for bridge 1 or 2.
|
|
|
let report_submit_request =
|
|
|
report_submit::request(rng, lox_cred.clone(), 0, [false, true, false]);
|
|
|
- let ((rs_request, _rs_client_state), D_server, bridges_being_reported_server) =
|
|
|
+ let ((rs_request, _rs_client_state), bridges_being_reported_server) =
|
|
|
report_submit_request.unwrap();
|
|
|
- let report_submit_response =
|
|
|
- th.ba
|
|
|
- .handle_report_submit(rs_request, D_server, bridges_being_reported_server);
|
|
|
+ let report_submit_response = th
|
|
|
+ .ba
|
|
|
+ .handle_report_submit(rs_request, bridges_being_reported_server);
|
|
|
assert!(report_submit_response.is_err());
|
|
|
|
|
|
// Submit a report for bridge 0
|
|
|
@@ -354,24 +365,25 @@ mod tests {
|
|
|
// We should be unable to resolve pending state due to pending
|
|
|
// report
|
|
|
let report_resolve_request = report_resolve::request(rng, lox_cred.clone(), 0);
|
|
|
- let ((rr_request, _rr_client_state), D_server) = report_resolve_request.unwrap();
|
|
|
- let report_resolve_response = th.ba.handle_report_resolve(rr_request, D_server);
|
|
|
+ let (rr_request, _rr_client_state) = report_resolve_request.unwrap();
|
|
|
+ let report_resolve_response = th.ba.handle_report_resolve(rr_request);
|
|
|
assert!(report_resolve_response.is_err());
|
|
|
|
|
|
// We should be unable to submit another report for bridge 0 due
|
|
|
// to pending report for bridge 0
|
|
|
let report_submit_request =
|
|
|
report_submit::request(rng, lox_cred.clone(), 0, [true, false, false]);
|
|
|
- let ((rs_request, _rs_client_state), D_server, bridges_being_reported_server) =
|
|
|
+ let ((rs_request, _rs_client_state), bridges_being_reported_server) =
|
|
|
report_submit_request.unwrap();
|
|
|
- let report_submit_response =
|
|
|
- th.ba
|
|
|
- .handle_report_submit(rs_request, D_server, bridges_being_reported_server);
|
|
|
+ let report_submit_response = th
|
|
|
+ .ba
|
|
|
+ .handle_report_submit(rs_request, bridges_being_reported_server);
|
|
|
assert!(report_submit_response.is_err());
|
|
|
|
|
|
// Let the report time out
|
|
|
th.ba.report_table.mark_old_reports_simulated_time(
|
|
|
&bucket[0].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
SystemTime::now(),
|
|
|
);
|
|
|
|
|
|
@@ -383,6 +395,7 @@ mod tests {
|
|
|
// Bridge was not blocked
|
|
|
th.ba.report_table.process_scan_result(
|
|
|
&bucket[0].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
ReportStatus::NotBlocked,
|
|
|
);
|
|
|
|
|
|
@@ -421,6 +434,7 @@ mod tests {
|
|
|
// Time out
|
|
|
th.ba.report_table.mark_old_reports_simulated_time(
|
|
|
&bucket[0].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
SystemTime::now(),
|
|
|
);
|
|
|
|
|
|
@@ -446,7 +460,7 @@ mod tests {
|
|
|
assert!(report_submit_request.is_err());
|
|
|
|
|
|
// Enter pending state
|
|
|
- lox_cred = th.report_init(rng, lox_cred.clone());
|
|
|
+ lox_cred = th.report_init(rng, lox_cred.clone(), cc);
|
|
|
|
|
|
// Submit reports for bridges 0 and 2
|
|
|
lox_cred = th.report_submit(rng, lox_cred.clone(), 0, [true, false, true]);
|
|
|
@@ -455,16 +469,17 @@ mod tests {
|
|
|
// there is a pending report for bridge 2)
|
|
|
let report_submit_request =
|
|
|
report_submit::request(rng, lox_cred.clone(), 0, [false, true, true]);
|
|
|
- let ((rs_request, _rs_client_state), D_server, bridges_being_reported_server) =
|
|
|
+ let ((rs_request, _rs_client_state), bridges_being_reported_server) =
|
|
|
report_submit_request.unwrap();
|
|
|
- let report_submit_response =
|
|
|
- th.ba
|
|
|
- .handle_report_submit(rs_request, D_server, bridges_being_reported_server);
|
|
|
+ let report_submit_response = th
|
|
|
+ .ba
|
|
|
+ .handle_report_submit(rs_request, bridges_being_reported_server);
|
|
|
assert!(report_submit_response.is_err());
|
|
|
|
|
|
// Bridge 2 is not blocked
|
|
|
th.ba.report_table.process_scan_result(
|
|
|
&bucket[2].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
ReportStatus::NotBlocked,
|
|
|
);
|
|
|
|
|
|
@@ -499,16 +514,20 @@ mod tests {
|
|
|
);
|
|
|
|
|
|
// Two of them are accessible, and one is blocked
|
|
|
- th.ba
|
|
|
- .report_table
|
|
|
- .process_scan_result(&bucket[0].get_hashed_fingerprint(), ReportStatus::Blocked);
|
|
|
+ th.ba.report_table.process_scan_result(
|
|
|
+ &bucket[0].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
+ ReportStatus::Blocked,
|
|
|
+ );
|
|
|
th.ba.bridge_blocked(&bucket[0], &mut th.bdb);
|
|
|
th.ba.report_table.process_scan_result(
|
|
|
&bucket[1].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
ReportStatus::NotBlocked,
|
|
|
);
|
|
|
th.ba.report_table.process_scan_result(
|
|
|
&bucket[2].get_hashed_fingerprint(),
|
|
|
+ cc,
|
|
|
ReportStatus::NotBlocked,
|
|
|
);
|
|
|
|
|
|
@@ -534,11 +553,11 @@ mod tests {
|
|
|
// Can't just lie about the number of false reports
|
|
|
let report_submit_request =
|
|
|
report_submit::request(rng, lox_cred.clone(), 0, [false, true, true]);
|
|
|
- let ((rs_request, _rs_client_state), D_server, bridges_being_reported_server) =
|
|
|
+ let ((rs_request, _rs_client_state), bridges_being_reported_server) =
|
|
|
report_submit_request.unwrap();
|
|
|
- let report_submit_response =
|
|
|
- th.ba
|
|
|
- .handle_report_submit(rs_request, D_server, bridges_being_reported_server);
|
|
|
+ let report_submit_response = th
|
|
|
+ .ba
|
|
|
+ .handle_report_submit(rs_request, bridges_being_reported_server);
|
|
|
assert!(report_submit_response.is_err());
|
|
|
|
|
|
// Resolve
|