Make an easier to use test harness

This commit is contained in:
Ian Goldberg 2021-05-04 18:26:58 -04:00
parent b0290f5480
commit cf19bf80ee
1 changed files with 216 additions and 187 deletions

View File

@ -5,51 +5,13 @@ use super::bridge_table::BridgeLine;
use super::proto::*; use super::proto::*;
use super::*; use super::*;
#[test] struct TestHarness {
fn test_open_invite() { bdb: BridgeDb,
// Create a BridegDb pub ba: BridgeAuth,
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) { impl TestHarness {
fn new() -> Self {
// Create a BridegDb // Create a BridegDb
let bdb = BridgeDb::new(15); let bdb = BridgeDb::new(15);
// Create a BridgeAuth // Create a BridgeAuth
@ -79,78 +41,42 @@ fn setup() -> (BridgeDb, BridgeAuth) {
// Create the encrypted bridge table // Create the encrypted bridge table
ba.enc_bridge_table(); ba.enc_bridge_table();
(bdb, ba) Self { bdb, ba }
} }
fn trust_promotion(bdb: &BridgeDb, ba: &mut BridgeAuth) -> (cred::Lox, cred::Migration) { fn advance_days(&mut self, days: u16) {
self.ba.advance_days(days);
}
fn open_invite(&mut self) -> cred::Lox {
// Issue an open invitation // Issue an open invitation
let inv = bdb.invite(); let inv = self.bdb.invite();
// Use it to get a Lox credential // Use it to get a Lox credential
let (req, state) = open_invite::request(&inv); let (req, state) = open_invite::request(&inv);
let resp = ba.handle_open_invite(req).unwrap(); let resp = self.ba.handle_open_invite(req).unwrap();
let cred = open_invite::handle_response(state, resp, &ba.lox_pub).unwrap(); open_invite::handle_response(state, resp, &self.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 trust_promotion(&mut self, cred: &cred::Lox) -> cred::Migration {
fn test_trust_promotion() { let (promreq, promstate) =
let (bdb, mut ba) = setup(); trust_promotion::request(&cred, &self.ba.lox_pub, self.ba.today()).unwrap();
let promresp = self.ba.handle_trust_promotion(promreq).unwrap();
let (_loxcred, migcred) = trust_promotion(&bdb, &mut ba); trust_promotion::handle_response(promstate, promresp).unwrap()
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 { fn level0_migration(&mut self, loxcred: &cred::Lox, migcred: &cred::Migration) -> cred::Lox {
let (loxcred, migcred) = trust_promotion(bdb, ba);
let (migreq, migstate) = let (migreq, migstate) =
migration::request(&loxcred, &migcred, &ba.lox_pub, &ba.migration_pub).unwrap(); migration::request(loxcred, migcred, &self.ba.lox_pub, &self.ba.migration_pub).unwrap();
let migresp = ba.handle_migration(migreq).unwrap(); let migresp = self.ba.handle_migration(migreq).unwrap();
let newloxcred = migration::handle_response(migstate, migresp, &ba.lox_pub).unwrap(); migration::handle_response(migstate, migresp, &self.ba.lox_pub).unwrap()
newloxcred
} }
#[test] fn level_up(&mut self, cred: &cred::Lox) -> cred::Lox {
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 // Read the bucket in the credential to get today's Bucket
// Reachability credential // Reachability credential
let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap(); let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
let encbuckets = ba.enc_bridge_table(); let encbuckets = self.ba.enc_bridge_table();
let bucket = let bucket =
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
let reachcred = bucket.1.unwrap(); let reachcred = bucket.1.unwrap();
@ -160,52 +86,20 @@ fn level_up(ba: &mut BridgeAuth, cred: &cred::Lox) -> cred::Lox {
let (req, state) = level_up::request( let (req, state) = level_up::request(
&cred, &cred,
&reachcred, &reachcred,
&ba.lox_pub, &self.ba.lox_pub,
&ba.reachability_pub, &self.ba.reachability_pub,
ba.today(), self.ba.today(),
) )
.unwrap(); .unwrap();
let resp = ba.handle_level_up(req).unwrap(); let resp = self.ba.handle_level_up(req).unwrap();
let cred = level_up::handle_response(state, resp, &ba.lox_pub).unwrap(); level_up::handle_response(state, resp, &self.ba.lox_pub).unwrap()
cred
} }
#[test] fn issue_invite(&mut self, cred: &cred::Lox) -> (cred::Lox, cred::Invitation) {
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 // Read the bucket in the credential to get today's Bucket
// Reachability credential // Reachability credential
let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap(); let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
let encbuckets = ba.enc_bridge_table(); let encbuckets = self.ba.enc_bridge_table();
let bucket = let bucket =
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap(); bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
let reachcred = bucket.1.unwrap(); let reachcred = bucket.1.unwrap();
@ -213,64 +107,199 @@ fn issue_invite(ba: &mut BridgeAuth, cred: &cred::Lox) -> (cred::Lox, cred::Invi
let (req, state) = issue_invite::request( let (req, state) = issue_invite::request(
&cred, &cred,
&reachcred, &reachcred,
&ba.lox_pub, &self.ba.lox_pub,
&ba.reachability_pub, &self.ba.reachability_pub,
ba.today(), self.ba.today(),
) )
.unwrap(); .unwrap();
let resp = ba.handle_issue_invite(req).unwrap(); let resp = self.ba.handle_issue_invite(req).unwrap();
issue_invite::handle_response(state, resp, &ba.lox_pub, &ba.invitation_pub).unwrap() issue_invite::handle_response(state, resp, &self.ba.lox_pub, &self.ba.invitation_pub)
.unwrap()
}
fn redeem_invite(&mut self, inv: &cred::Invitation) -> cred::Lox {
let (req, state) =
redeem_invite::request(&inv, &self.ba.invitation_pub, self.ba.today()).unwrap();
let resp = self.ba.handle_redeem_invite(req).unwrap();
redeem_invite::handle_response(state, resp, &self.ba.lox_pub).unwrap()
}
}
#[test]
fn test_open_invite() {
let mut th = TestHarness::new();
// Join an untrusted user
let cred = th.open_invite();
// Check that we can use the credential to read a bucket
let (id, key) = bridge_table::from_scalar(cred.bucket).unwrap();
let encbuckets = th.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!(th.ba.verify_lox(&cred));
}
#[test]
fn test_trust_promotion() {
let mut th = TestHarness::new();
let cred = th.open_invite();
assert!(th.ba.verify_lox(&cred));
// Time passes
th.advance_days(47);
let migcred = th.trust_promotion(&cred);
assert!(th.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 = th.ba.enc_bridge_table();
let bucket =
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
println!("bucket = {:?}", bucket);
assert!(th.ba.verify_reachability(&bucket.1.unwrap()));
}
#[test]
fn test_level0_migration() {
let mut th = TestHarness::new();
let cred = th.open_invite();
assert!(th.ba.verify_lox(&cred));
// Time passes
th.advance_days(47);
let migcred = th.trust_promotion(&cred);
assert!(th.ba.verify_migration(&migcred));
let newloxcred = th.level0_migration(&cred, &migcred);
assert!(th.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 = th.ba.enc_bridge_table();
let bucket =
bridge_table::BridgeTable::decrypt_bucket(id, &key, &encbuckets[id as usize]).unwrap();
println!("bucket = {:?}", bucket);
assert!(th.ba.verify_reachability(&bucket.1.unwrap()));
}
#[test]
fn test_level_up() {
let mut th = TestHarness::new();
// Join an untrusted user
let cred = th.open_invite();
// Time passes
th.advance_days(47);
// Go up to level 1
let migcred = th.trust_promotion(&cred);
let cred1 = th.level0_migration(&cred, &migcred);
assert!(scalar_u32(&cred1.trust_level).unwrap() == 1);
// Time passes
th.advance_days(20);
let cred2 = th.level_up(&cred1);
assert!(scalar_u32(&cred2.trust_level).unwrap() == 2);
println!("cred2 = {:?}", cred2);
assert!(th.ba.verify_lox(&cred2));
// Time passes
th.advance_days(30);
let cred3 = th.level_up(&cred2);
assert!(scalar_u32(&cred3.trust_level).unwrap() == 3);
println!("cred3 = {:?}", cred3);
assert!(th.ba.verify_lox(&cred3));
// Time passes
th.advance_days(60);
let cred4 = th.level_up(&cred3);
assert!(scalar_u32(&cred3.trust_level).unwrap() == 3);
println!("cred4 = {:?}", cred4);
assert!(th.ba.verify_lox(&cred4));
} }
#[test] #[test]
fn test_issue_invite() { fn test_issue_invite() {
let (bdb, mut ba) = setup(); let mut th = TestHarness::new();
let cred1 = level0_migration(&bdb, &mut ba);
// Join an untrusted user
let cred = th.open_invite();
// Time passes
th.advance_days(47);
// Go up to level 1
let migcred = th.trust_promotion(&cred);
let cred1 = th.level0_migration(&cred, &migcred);
assert!(scalar_u32(&cred1.trust_level).unwrap() == 1); assert!(scalar_u32(&cred1.trust_level).unwrap() == 1);
// Time passes // Time passes
ba.advance_days(20); th.advance_days(20);
let cred2 = level_up(&mut ba, &cred1); // Go up to level 2
let cred2 = th.level_up(&cred1);
assert!(scalar_u32(&cred2.trust_level).unwrap() == 2); assert!(scalar_u32(&cred2.trust_level).unwrap() == 2);
println!("cred2 = {:?}", cred2); println!("cred2 = {:?}", cred2);
assert!(ba.verify_lox(&cred2)); assert!(th.ba.verify_lox(&cred2));
let (cred3, invite) = issue_invite(&mut ba, &cred2); // Issue an invitation
assert!(ba.verify_lox(&cred3)); let (cred2a, invite) = th.issue_invite(&cred2);
assert!(ba.verify_invitation(&invite)); assert!(th.ba.verify_lox(&cred2a));
println!("cred3 = {:?}", cred3); assert!(th.ba.verify_invitation(&invite));
println!("cred2a = {:?}", cred2a);
println!("invite = {:?}", invite); 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();
let resp = ba.handle_redeem_invite(req).unwrap();
redeem_invite::handle_response(state, resp, &ba.lox_pub).unwrap()
}
#[test] #[test]
fn test_redeem_invite() { fn test_redeem_invite() {
let (bdb, mut ba) = setup(); let mut th = TestHarness::new();
let cred1 = level0_migration(&bdb, &mut ba);
// Join an untrusted user
let cred = th.open_invite();
// Time passes
th.advance_days(47);
// Go up to level 1
let migcred = th.trust_promotion(&cred);
let cred1 = th.level0_migration(&cred, &migcred);
assert!(scalar_u32(&cred1.trust_level).unwrap() == 1); assert!(scalar_u32(&cred1.trust_level).unwrap() == 1);
// Time passes // Time passes
ba.advance_days(20); th.advance_days(20);
let cred2 = level_up(&mut ba, &cred1); // Go up to level 2
let cred2 = th.level_up(&cred1);
assert!(scalar_u32(&cred2.trust_level).unwrap() == 2); assert!(scalar_u32(&cred2.trust_level).unwrap() == 2);
println!("cred2 = {:?}", cred2); println!("cred2 = {:?}", cred2);
assert!(ba.verify_lox(&cred2)); assert!(th.ba.verify_lox(&cred2));
let (cred3, invite) = issue_invite(&mut ba, &cred2); // Issue an invitation to Bob
println!("cred3 = {:?}", cred3); let (cred2a, bob_invite) = th.issue_invite(&cred2);
println!("invite = {:?}", invite); assert!(th.ba.verify_lox(&cred2a));
assert!(th.ba.verify_invitation(&bob_invite));
println!("cred2a = {:?}", cred2a);
println!("bob_invite = {:?}", bob_invite);
// Time passes // Time passes
ba.advance_days(12); th.advance_days(12);
let cred4 = redeem_invite(&mut ba, &invite); // Bob joins the system
assert!(ba.verify_lox(&cred4)); let bob_cred = th.redeem_invite(&bob_invite);
println!("cred4 = {:?}", cred4); assert!(th.ba.verify_lox(&bob_cred));
println!("bob_cred = {:?}", bob_cred);
} }