Explorar o código

Start adding args, support promoting to trust level 1

Vecna hai 1 ano
pai
achega
a3bf510c44
Modificáronse 3 ficheiros con 96 adicións e 43 borrados
  1. 2 0
      Cargo.toml
  2. 88 38
      src/bin/lox_client.rs
  3. 6 5
      src/client_lib.rs

+ 2 - 0
Cargo.toml

@@ -8,7 +8,9 @@ edition = "2021"
 [dependencies]
 #lox = { git = "https://git-crysp.uwaterloo.ca/iang/lox.git", branch = "vvecna/lox_test" }
 lox = { git = "https://gitlab.torproject.org/onyinyang/lox.git" }
+curve25519-dalek = { package = "curve25519-dalek-ng", version = "3", default-features = false, features = ["serde", "std"] }
 ed25519-dalek = { version = "1", features = ["serde"] }
+getopts = "0.2"
 serde = "1"
 bincode = "1"
 serde_json = "1.0"

+ 88 - 38
src/bin/lox_client.rs

@@ -3,16 +3,61 @@
 mod client_lib;
 use client_lib::*;
 
+use curve25519_dalek::scalar::Scalar;
+use getopts::Options;
+use lox::bridge_table::BridgeLine;
 use lox::IssuerPubKey;
+use serde::Serialize;
 use std::env::args;
 use std::fs::File;
 use std::io::Write;
 use std::path::Path;
 
+// Prints the argument details for this program
+fn print_usage(program: &str, opts: Options) {
+    let brief = format!("Usage: {} [options]", program);
+    print!("{}", opts.usage(&brief));
+}
+
+// Helper function to save serializable objects to files
+fn save_object<T: Serialize>(obj: T, filename: &str) {
+    let mut outfile = File::create(filename).expect(&("Failed to create ".to_string() + filename));
+    write!(outfile, "{}", serde_json::to_string(&obj).unwrap())
+        .expect(&("Failed to write to ".to_string() + filename));
+}
+
 #[tokio::main]
 async fn main() {
-    // TODO: Do proper argument handling
-    let server_addr = args().nth(1).unwrap(); // must include http://
+    let args: Vec<String> = args().collect();
+
+    let mut opts = Options::new();
+    opts.optflag("h", "help", "print this help menu");
+    opts.optflag("L", "level-up", "increase trust level");
+    opts.optflag("N", "new-lox-cred", "get a new Lox Credential");
+    opts.optopt(
+        "",
+        "server",
+        "Lox Auth server address [http://localhost:8001]",
+        "ADDR",
+    );
+
+    let matches = match opts.parse(&args[1..]) {
+        Ok(m) => m,
+        Err(f) => {
+            panic!("{}", f.to_string())
+        }
+    };
+
+    if matches.opt_present("h") {
+        print_usage(&args[0], opts);
+        return;
+    }
+
+    let server_addr = if matches.opt_present("server") {
+        matches.opt_str("server").unwrap()
+    } else {
+        "http://localhost:8001".to_string()
+    };
 
     // Get Lox Authority public keys
     // TODO: Make this filename configurable
@@ -26,51 +71,56 @@ async fn main() {
         // download from Lox Auth
         let pubkeys = get_lox_auth_keys(&server_addr).await;
         // save to file for next time
-        let mut lox_auth_pubkeys_outfile = File::create(lox_auth_pubkeys_filename)
-            .expect("Failed to create lox_auth pubkeys file");
-        write!(
-            lox_auth_pubkeys_outfile,
-            "{}",
-            serde_json::to_string(&pubkeys).unwrap()
-        )
-        .expect("Failed to write to lox_auth pubkeys file");
+        save_object(&pubkeys, &lox_auth_pubkeys_filename);
         pubkeys
     };
 
     // Get Lox Credential and BridgeLine
-    // TODO: Make these filenames configurable
     let lox_cred_filename = "lox_cred.json";
     let bridgeline_filename = "bridgeline.json";
-    let (lox_cred, bridgeline) = if Path::new(lox_cred_filename).exists()
-        && Path::new(bridgeline_filename).exists()
+    let (lox_cred, bridgeline) = if matches.opt_present("N")
+        || !Path::new(lox_cred_filename).exists()
+        || !Path::new(bridgeline_filename).exists()
     {
-        let lox_cred_infile = File::open(lox_cred_filename).unwrap();
-        let lox_cred = serde_json::from_reader(lox_cred_infile).unwrap();
-        let bridgeline_infile = File::open(bridgeline_filename).unwrap();
-        let bridgeline = serde_json::from_reader(bridgeline_infile).unwrap();
-        (lox_cred, bridgeline)
-    } else {
-        // get new credential based on an open invite
+        // get new Lox Credential
         let open_invite = get_open_invitation(&server_addr).await;
-        let (cred, bridgeline) =
+        let (cred, bl) =
             get_lox_credential(&server_addr, &open_invite, get_lox_pub(&lox_auth_pubkeys)).await;
+
         // save to files for next time
-        let mut lox_cred_outfile =
-            File::create(lox_cred_filename).expect("Failed to create lox credential file");
-        write!(
-            lox_cred_outfile,
-            "{}",
-            serde_json::to_string(&cred).unwrap()
-        )
-        .expect("Failed to write to lox credential file");
-        let mut bridgeline_outfile =
-            File::create(bridgeline_filename).expect("Failed to create bridgeline file");
-        write!(
-            bridgeline_outfile,
-            "{}",
-            serde_json::to_string(&bridgeline).unwrap()
-        )
-        .expect("Failed to write to bridgeline file");
-        (cred, bridgeline)
+        save_object(&cred, &lox_cred_filename);
+        save_object(&bl, &bridgeline_filename);
+        (cred, bl)
+    } else {
+        // Read existing Lox Credential and BridgeLine from files
+        let cred = serde_json::from_reader(File::open(lox_cred_filename).unwrap()).unwrap();
+        let bl = serde_json::from_reader(File::open(bridgeline_filename).unwrap()).unwrap();
+        (cred, bl)
     };
+
+    if matches.opt_present("L") {
+        // If trust level is 0, do trust promotion, otherwise level up.
+        if lox_cred.trust_level == Scalar::zero() {
+            let migration_cred =
+                trust_promotion(&server_addr, &lox_cred, get_lox_pub(&lox_auth_pubkeys)).await;
+            let cred = trust_migration(
+                &server_addr,
+                &lox_cred,
+                &migration_cred,
+                get_lox_pub(&lox_auth_pubkeys),
+                get_migration_pub(&lox_auth_pubkeys),
+            )
+            .await;
+        } else {
+            let encbuckets = get_reachability_credential(&server_addr).await;
+            let cred = level_up(
+                &server_addr,
+                &lox_cred,
+                &encbuckets,
+                get_lox_pub(&lox_auth_pubkeys),
+                get_reachability_pub(&lox_auth_pubkeys),
+            )
+            .await;
+        }
+    }
 }

+ 6 - 5
src/client_lib.rs

@@ -66,10 +66,10 @@ pub async fn get_lox_auth_keys(server_addr: &str) -> Vec<IssuerPubKey> {
 }
 
 // Get encrypted bridge table
-pub async fn get_reachability_credential(server_addr: &str) -> EncBridgeTable {
+pub async fn get_reachability_credential(server_addr: &str) -> Vec<[u8; ENC_BUCKET_BYTES]> {
     let resp = net_request(server_addr.to_string() + "/reachability", [].to_vec()).await;
-    let reachability_cred = serde_json::from_slice(&resp).unwrap();
-    reachability_cred
+    let reachability_cred: EncBridgeTable = serde_json::from_slice(&resp).unwrap();
+    reachability_cred.etable
 }
 
 // Get an open invitation
@@ -100,9 +100,10 @@ pub async fn trust_promotion(
     lox_pub: &IssuerPubKey,
 ) -> lox::cred::Migration {
     let (req, state) =
-        trust_promotion::request(&lox_cred, &lox_pub, today(Duration::ZERO)).unwrap();
+//        trust_promotion::request(&lox_cred, &lox_pub, today(Duration::ZERO)).unwrap();
+        trust_promotion::request(&lox_cred, &lox_pub, today(Duration::from_secs(60 * 60 * 24 * 31))).unwrap(); // FOR TESTING ONLY
     let encoded_req: Vec<u8> = serde_json::to_vec(&req).unwrap();
-    let encoded_resp = net_request(server_addr.to_string() + "/promreq", encoded_req).await;
+    let encoded_resp = net_request(server_addr.to_string() + "/trustpromo", encoded_req).await;
     let decoded_resp: trust_promotion::Response = serde_json::from_slice(&encoded_resp).unwrap();
     let migration_cred = trust_promotion::handle_response(state, decoded_resp).unwrap();
     migration_cred