Compare commits

...

2 Commits

Author SHA1 Message Date
Vecna c1b058ce4e cargo-fmt 2024-02-26 18:01:07 -05:00
Vecna cc670963c5 Check that date in Lox proof matches date in PR 2024-02-26 18:00:43 -05:00
4 changed files with 41 additions and 22 deletions

View File

@ -25,6 +25,7 @@ serde = "1.0.195"
serde_json = "1.0" serde_json = "1.0"
serde_with = {version = "3.5.0", features = ["json"]} serde_with = {version = "3.5.0", features = ["json"]}
sha1 = "0.10" sha1 = "0.10"
sha2 = "0.10"
sha3 = "0.10" sha3 = "0.10"
sled = "0.34.7" sled = "0.34.7"
time = "0.3.30" time = "0.3.30"

View File

@ -45,7 +45,9 @@ fn get_extra_info_or_error(entry: &HashMap<String, String>) -> Result<ExtraInfo,
// How did we get here?? // How did we get here??
return Err("Cannot parse extra-info: Missing nickname or fingerprint".to_string()); return Err("Cannot parse extra-info: Missing nickname or fingerprint".to_string());
} }
if !(entry.contains_key("bridge-stats-end") || entry.contains_key("published")) || !entry.contains_key("bridge-ips") { if !(entry.contains_key("bridge-stats-end") || entry.contains_key("published"))
|| !entry.contains_key("bridge-ips")
{
// Some extra-infos are missing data on connecting IPs... // Some extra-infos are missing data on connecting IPs...
// But we can't do anything in that case. // But we can't do anything in that case.
return Err(format!( return Err(format!(
@ -69,10 +71,7 @@ fn get_extra_info_or_error(entry: &HashMap<String, String>) -> Result<ExtraInfo,
entry.get("published").unwrap().as_str() entry.get("published").unwrap().as_str()
}; };
JulianDay::from( JulianDay::from(
DateTime::parse_from_str( DateTime::parse_from_str(&(date_str.to_owned() + " +0000"), "%F %T %z")
&(date_str.to_owned() + " +0000"),
"%F %T %z",
)
.unwrap() .unwrap()
.date_naive(), .date_naive(),
) )

View File

@ -126,28 +126,42 @@ pub struct DailyBridgeInfo {
impl DailyBridgeInfo { impl DailyBridgeInfo {
pub fn new() -> Self { pub fn new() -> Self {
Self { Self {
info_by_country: BTreeMap::<String, BTreeMap::<BridgeInfoType, u32>>::new(), info_by_country: BTreeMap::<String, BTreeMap<BridgeInfoType, u32>>::new(),
} }
} }
pub fn add_info(&mut self, info_type: BridgeInfoType, count_per_country: &BTreeMap::<String, u32>) { pub fn add_info(
&mut self,
info_type: BridgeInfoType,
count_per_country: &BTreeMap<String, u32>,
) {
for country in count_per_country.keys() { for country in count_per_country.keys() {
if self.info_by_country.contains_key(country) { if self.info_by_country.contains_key(country) {
let info = self.info_by_country.get_mut(country).unwrap(); let info = self.info_by_country.get_mut(country).unwrap();
if !info.contains_key(&info_type) { if !info.contains_key(&info_type) {
info.insert(info_type, *count_per_country.get(&country.to_string()).unwrap()); info.insert(
info_type,
*count_per_country.get(&country.to_string()).unwrap(),
);
} else if info_type == BridgeInfoType::BridgeIps { } else if info_type == BridgeInfoType::BridgeIps {
// Use newest value we've seen today // Use newest value we've seen today
if info.get(&info_type).unwrap() < count_per_country.get(country).unwrap() { if info.get(&info_type).unwrap() < count_per_country.get(country).unwrap() {
info.insert(BridgeInfoType::BridgeIps, *count_per_country.get(&country.to_string()).unwrap()); info.insert(
BridgeInfoType::BridgeIps,
*count_per_country.get(&country.to_string()).unwrap(),
);
} }
} else { } else {
let new_count = info.get(&info_type).unwrap() + *count_per_country.get(&country.to_string()).unwrap(); let new_count = info.get(&info_type).unwrap()
+ *count_per_country.get(&country.to_string()).unwrap();
info.insert(info_type, new_count); info.insert(info_type, new_count);
} }
} else { } else {
let mut info = BTreeMap::<BridgeInfoType, u32>::new(); let mut info = BTreeMap::<BridgeInfoType, u32>::new();
info.insert(info_type, *count_per_country.get(&country.to_string()).unwrap()); info.insert(
info_type,
*count_per_country.get(&country.to_string()).unwrap(),
);
self.info_by_country.insert(country.to_string(), info); self.info_by_country.insert(country.to_string(), info);
} }
} }
@ -201,15 +215,12 @@ pub fn add_extra_info_to_db(db: &Db, extra_info: ExtraInfo) {
// If we already have an entry, compare it with the new one. For each // If we already have an entry, compare it with the new one. For each
// country:count mapping, use the greater of the two counts. // country:count mapping, use the greater of the two counts.
if bridge_info.info_by_day.contains_key(&extra_info.date) { if bridge_info.info_by_day.contains_key(&extra_info.date) {
let daily_bridge_info = bridge_info let daily_bridge_info = bridge_info.info_by_day.get_mut(&extra_info.date).unwrap();
.info_by_day
.get_mut(&extra_info.date)
.unwrap();
daily_bridge_info.add_info(BridgeInfoType::BridgeIps, &extra_info.bridge_ips); daily_bridge_info.add_info(BridgeInfoType::BridgeIps, &extra_info.bridge_ips);
} else { } else {
// No existing entry; make a new one. // No existing entry; make a new one.
let mut daily_bridge_info = DailyBridgeInfo { let mut daily_bridge_info = DailyBridgeInfo {
info_by_country: BTreeMap::<String, BTreeMap::<BridgeInfoType, u32>>::new(), info_by_country: BTreeMap::<String, BTreeMap<BridgeInfoType, u32>>::new(),
}; };
daily_bridge_info.add_info(BridgeInfoType::BridgeIps, &extra_info.bridge_ips); daily_bridge_info.add_info(BridgeInfoType::BridgeIps, &extra_info.bridge_ips);
bridge_info bridge_info

View File

@ -3,11 +3,12 @@
use crate::{get_date, CONFIG, COUNTRY_CODES}; use crate::{get_date, CONFIG, COUNTRY_CODES};
use curve25519_dalek::Scalar; use curve25519_dalek::{RistrettoPoint, Scalar};
use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey}; use ed25519_dalek::{Signature, Signer, SigningKey, Verifier, VerifyingKey};
use lox_library::{cred::Lox, proto::positive_report as lox_pr, IssuerPubKey}; use lox_library::{cred::Lox, proto::positive_report as lox_pr, IssuerPubKey};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use sha1::{Digest, Sha1}; use sha1::{Digest, Sha1};
use sha2::Sha512;
use std::option::Option; use std::option::Option;
#[derive(Debug)] #[derive(Debug)]
@ -16,6 +17,7 @@ pub enum PositiveReportError {
FailedToDeserialize, // couldn't deserialize to SerializablePositiveReport FailedToDeserialize, // couldn't deserialize to SerializablePositiveReport
InvalidBridgeToken, InvalidBridgeToken,
InvalidCountryCode, InvalidCountryCode,
InvalidLoxProof,
MissingBridgeToken, MissingBridgeToken,
MissingCountryCode, MissingCountryCode,
} }
@ -130,7 +132,9 @@ impl PositiveReport {
} }
} }
// Verify knowledge of bucket ID // Verify knowledge of bucket ID
let H = self.lox_proof.H; let H = RistrettoPoint::hash_from_bytes::<Sha512>(
format!("{}{}", lox_pr::H_GENERATOR_STRING, self.lox_proof.date).as_bytes(),
);
let BP = self.lox_proof.BP; let BP = self.lox_proof.BP;
if bucket * H != BP { if bucket * H != BP {
return false; return false;
@ -162,9 +166,13 @@ impl SerializablePositiveReport {
if !COUNTRY_CODES.contains(self.country.as_str()) { if !COUNTRY_CODES.contains(self.country.as_str()) {
return Err(PositiveReportError::InvalidCountryCode); return Err(PositiveReportError::InvalidCountryCode);
} }
if self.date > get_date().into() { let date: u32 = get_date().into();
if self.date > date {
return Err(PositiveReportError::DateInFuture); return Err(PositiveReportError::DateInFuture);
} }
if self.lox_proof.date != date {
return Err(PositiveReportError::InvalidLoxProof);
}
let bridge_token = if self.bridge_token.is_none() { let bridge_token = if self.bridge_token.is_none() {
None None
} else { } else {