/*! Unit tests that require access to the testing-only function BridgeLine::random() or private fields */ use super::bridge_table::BridgeLine; use super::proto::*; use super::*; #[test] fn test_open_invite() { // Create a BridegDb let bdb = BridgeDb::new(20); // Create a BridgeAuth let mut ba = BridgeAuth::new(bdb.pubkey); // Make 20 buckets with one random bridge each for _ in 0..20 { let bucket: [BridgeLine; 3] = [BridgeLine::random(), Default::default(), Default::default()]; ba.bridge_table.new_bucket(bucket); } // And 20 more with three random bridges each for _ in 0..20 { let bucket: [BridgeLine; 3] = [ BridgeLine::random(), BridgeLine::random(), BridgeLine::random(), ]; ba.bridge_table.new_bucket(bucket); } // Create the encrypted bridge table ba.enc_bridge_table(); // Issue an open invitation let inv = bdb.invite(); // Use it to get a Lox credential let (req, state) = open_invite::request(&inv); let resp = ba.handle_open_invite(req).unwrap(); let cred = open_invite::handle_response(state, resp, &ba.lox_pub).unwrap(); // Check that we can use the credential to read a bucket let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap(); let encbuckets = ba.enc_bridge_table(); let bucket = bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); println!("cred = {:?}", cred); println!("bucket = {:?}", bucket); assert!(bucket.1.is_none()); assert!(ba.verify_lox(&cred)); } fn setup() -> (BridgeDb, BridgeAuth) { // Create a BridegDb let bdb = BridgeDb::new(15); // Create a BridgeAuth let mut ba = BridgeAuth::new(bdb.pubkey); // Make 15 buckets with one random bridge each for _ in 0..15 { let bucket: [BridgeLine; 3] = [BridgeLine::random(), Default::default(), Default::default()]; ba.bridge_table.new_bucket(bucket); } // Make 5 more buckets, each containing 3 of the previously // created bridges for i in 0u32..5 { let iusize = i as usize; let bucket: [BridgeLine; 3] = [ ba.bridge_table.buckets[3 * iusize][0], ba.bridge_table.buckets[3 * iusize + 1][0], ba.bridge_table.buckets[3 * iusize + 2][0], ]; ba.bridge_table.new_bucket(bucket); // Add the allowed migrations to the migration table ba.migration_table.table.insert(3 * i, 15 + i); ba.migration_table.table.insert(3 * i + 1, 15 + i); ba.migration_table.table.insert(3 * i + 2, 15 + i); } // Create the encrypted bridge table ba.enc_bridge_table(); (bdb, ba) } fn trust_promotion(bdb: &BridgeDb, ba: &mut BridgeAuth) -> (cred::Lox, cred::Migration) { // Issue an open invitation let inv = bdb.invite(); // Use it to get a Lox credential let (req, state) = open_invite::request(&inv); let resp = ba.handle_open_invite(req).unwrap(); let cred = open_invite::handle_response(state, resp, &ba.lox_pub).unwrap(); assert!(ba.verify_lox(&cred)); // Time passes ba.advance_days(47); let (promreq, promstate) = trust_promotion::request(&cred, &ba.lox_pub, ba.today()).unwrap(); let promresp = ba.handle_trust_promotion(promreq).unwrap(); let migcred = trust_promotion::handle_response(promstate, promresp).unwrap(); (cred, migcred) } #[test] fn test_trust_promotion() { let (bdb, mut ba) = setup(); let (_loxcred, migcred) = trust_promotion(&bdb, &mut ba); assert!(ba.verify_migration(&migcred)); // Check that we can use the to_bucket in the Migration credenital // to read a bucket let (id, key) = bridge_table::from_scalar(migcred.to_bucket).unwrap(); let encbuckets = ba.enc_bridge_table(); let bucket = bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); println!("bucket = {:?}", bucket); assert!(ba.verify_reachability(&bucket.1.unwrap())); } fn level0_migration(bdb: &BridgeDb, ba: &mut BridgeAuth) -> cred::Lox { let (loxcred, migcred) = trust_promotion(bdb, ba); let (migreq, migstate) = migration::request(&loxcred, &migcred, &ba.lox_pub, &ba.migration_pub).unwrap(); let migresp = ba.handle_migration(migreq).unwrap(); let newloxcred = migration::handle_response(migstate, migresp, &ba.lox_pub).unwrap(); newloxcred } #[test] fn test_level0_migration() { let (bdb, mut ba) = setup(); let newloxcred = level0_migration(&bdb, &mut ba); assert!(ba.verify_lox(&newloxcred)); println!("newloxcred = {:?}", newloxcred); // Check that we can use the credenital to read a bucket let (id, key) = bridge_table::from_scalar(newloxcred.bucket).unwrap(); let encbuckets = ba.enc_bridge_table(); let bucket = bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); println!("bucket = {:?}", bucket); assert!(ba.verify_reachability(&bucket.1.unwrap())); } fn level_up(ba: &mut BridgeAuth, cred: &cred::Lox) -> cred::Lox { // Read the bucket in the credential to get today's Bucket // Reachability credential let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap(); let encbuckets = ba.enc_bridge_table(); let bucket = bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); let reachcred = bucket.1.unwrap(); // Use the Bucket Reachability credential to advance to the next // level let (req, state) = level_up::request( &cred, &reachcred, &ba.lox_pub, &ba.reachability_pub, ba.today(), ) .unwrap(); let resp = ba.handle_level_up(req).unwrap(); let cred = level_up::handle_response(state, resp, &ba.lox_pub).unwrap(); cred } #[test] fn test_level_up() { let (bdb, mut ba) = setup(); let cred1 = level0_migration(&bdb, &mut ba); assert!(scalar_u32(&cred1.trust_level).unwrap() == 1); // Time passes ba.advance_days(20); let cred2 = level_up(&mut ba, &cred1); assert!(scalar_u32(&cred2.trust_level).unwrap() == 2); println!("cred2 = {:?}", cred2); assert!(ba.verify_lox(&cred2)); // Time passes ba.advance_days(30); let cred3 = level_up(&mut ba, &cred2); assert!(scalar_u32(&cred3.trust_level).unwrap() == 3); println!("cred3 = {:?}", cred3); assert!(ba.verify_lox(&cred3)); // Time passes ba.advance_days(60); let cred4 = level_up(&mut ba, &cred3); assert!(scalar_u32(&cred3.trust_level).unwrap() == 3); println!("cred4 = {:?}", cred4); assert!(ba.verify_lox(&cred4)); } fn issue_invite(ba: &mut BridgeAuth, cred: &cred::Lox) -> (cred::Lox, cred::Invitation) { // Read the bucket in the credential to get today's Bucket // Reachability credential let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap(); let encbuckets = ba.enc_bridge_table(); let bucket = bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); let reachcred = bucket.1.unwrap(); let (req, state) = issue_invite::request( &cred, &reachcred, &ba.lox_pub, &ba.reachability_pub, ba.today(), ) .unwrap(); let resp = ba.handle_issue_invite(req).unwrap(); issue_invite::handle_response(state, resp, &ba.lox_pub, &ba.invitation_pub).unwrap() } #[test] fn test_issue_invite() { let (bdb, mut ba) = setup(); let cred1 = level0_migration(&bdb, &mut ba); assert!(scalar_u32(&cred1.trust_level).unwrap() == 1); // Time passes ba.advance_days(20); let cred2 = level_up(&mut ba, &cred1); assert!(scalar_u32(&cred2.trust_level).unwrap() == 2); println!("cred2 = {:?}", cred2); assert!(ba.verify_lox(&cred2)); let (cred3, invite) = issue_invite(&mut ba, &cred2); assert!(ba.verify_lox(&cred3)); assert!(ba.verify_invitation(&invite)); println!("cred3 = {:?}", cred3); println!("invite = {:?}", invite); } fn redeem_invite(ba: &mut BridgeAuth, inv: &cred::Invitation) -> cred::Lox { let (req, state) = redeem_invite::request(&inv, &ba.invitation_pub, ba.today()).unwrap(); panic!("Not finished") } #[test] fn test_redeem_invite() { let (bdb, mut ba) = setup(); let cred1 = level0_migration(&bdb, &mut ba); assert!(scalar_u32(&cred1.trust_level).unwrap() == 1); // Time passes ba.advance_days(20); let cred2 = level_up(&mut ba, &cred1); assert!(scalar_u32(&cred2.trust_level).unwrap() == 2); println!("cred2 = {:?}", cred2); assert!(ba.verify_lox(&cred2)); let (cred3, invite) = issue_invite(&mut ba, &cred2); println!("cred3 = {:?}", cred3); println!("invite = {:?}", invite); let cred4 = redeem_invite(&mut ba, &invite); assert!(ba.verify_lox(&cred4)); println!("cred4 = {:?}", cred4); }