|
@@ -23,10 +23,10 @@ and a new Invitation credential to be issued:
|
|
|
use super::super::dup_filter::SeenType;
|
|
|
#[cfg(feature = "bridgeauth")]
|
|
|
use super::super::BridgeAuth;
|
|
|
+use super::super::{Scalar, G};
|
|
|
use super::errors::CredentialError;
|
|
|
use crate::lox_creds::Invitation;
|
|
|
use cmz::*;
|
|
|
-use curve25519_dalek::ristretto::RistrettoPoint as G;
|
|
|
use group::Group;
|
|
|
use rand::{CryptoRng, RngCore};
|
|
|
use sha2::Sha512;
|
|
@@ -48,12 +48,13 @@ pub fn request(
|
|
|
) -> Result<(update_invite::Request, update_invite::ClientState), CredentialError> {
|
|
|
cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
|
|
|
|
|
|
- match update_invite::prepare(
|
|
|
- &mut *rng,
|
|
|
- SESSION_ID,
|
|
|
- &I,
|
|
|
- Invitation::using_pubkey(&new_pubkeys),
|
|
|
- ) {
|
|
|
+ let mut N = Invitation::using_pubkey(&new_pubkeys);
|
|
|
+ N.inv_id = Some(Scalar::random(rng));
|
|
|
+ N.date = I.date;
|
|
|
+ N.bucket = I.bucket;
|
|
|
+ N.blockages = I.blockages;
|
|
|
+
|
|
|
+ match update_invite::prepare(&mut *rng, SESSION_ID, &I, N) {
|
|
|
Ok(req_state) => Ok(req_state),
|
|
|
Err(e) => Err(CredentialError::CMZError(e)),
|
|
|
}
|
|
@@ -63,9 +64,10 @@ pub fn request(
|
|
|
impl BridgeAuth {
|
|
|
pub fn handle_update_invite(
|
|
|
&mut self,
|
|
|
- rng: &mut (impl CryptoRng + RngCore),
|
|
|
+ old_pub_key: CMZPubkey<G>,
|
|
|
req: update_invite::Request,
|
|
|
) -> Result<update_invite::Reply, CredentialError> {
|
|
|
+ let mut rng = rand::thread_rng();
|
|
|
// Both of these must be true and should be true after rotate_lox_keys is called
|
|
|
if self.old_keys.invitation_keys.is_empty() || self.old_filters.invitation_filter.is_empty()
|
|
|
{
|
|
@@ -75,7 +77,7 @@ impl BridgeAuth {
|
|
|
let reqbytes = req.as_bytes();
|
|
|
let recvreq = update_invite::Request::try_from(&reqbytes[..]).unwrap();
|
|
|
match update_invite::handle(
|
|
|
- &mut *rng,
|
|
|
+ &mut rng,
|
|
|
SESSION_ID,
|
|
|
recvreq,
|
|
|
|I: &mut Invitation, N: &mut Invitation| {
|
|
@@ -88,7 +90,7 @@ impl BridgeAuth {
|
|
|
.old_keys
|
|
|
.invitation_keys
|
|
|
.iter()
|
|
|
- .find(|x| x.pub_key == *I.get_pubkey())
|
|
|
+ .find(|x| x.pub_key == old_pub_key)
|
|
|
{
|
|
|
Some(old_keys) => old_keys,
|
|
|
None => return Err(CMZError::RevealAttrMissing("Key", "Mismatch")),
|
|
@@ -96,9 +98,6 @@ impl BridgeAuth {
|
|
|
let old_priv_key = old_keys.priv_key.clone();
|
|
|
I.set_privkey(&old_priv_key);
|
|
|
N.set_privkey(&self.invitation_priv);
|
|
|
- I.date = N.date;
|
|
|
- I.bucket = N.bucket;
|
|
|
- I.blockages = N.blockages;
|
|
|
Ok(())
|
|
|
},
|
|
|
|I: &Invitation, _N: &Invitation| {
|
|
@@ -106,7 +105,7 @@ impl BridgeAuth {
|
|
|
.old_keys
|
|
|
.invitation_keys
|
|
|
.iter()
|
|
|
- .position(|x| x.pub_key == *I.get_pubkey())
|
|
|
+ .position(|x| x.pub_key == old_pub_key)
|
|
|
{
|
|
|
Some(index) => index,
|
|
|
None => return Err(CMZError::RevealAttrMissing("Key", "Mismatch")),
|
|
@@ -141,3 +140,160 @@ pub fn handle_response(
|
|
|
Err(_e) => Err(CMZError::Unknown),
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+#[cfg(all(test, feature = "bridgeauth"))]
|
|
|
+mod tests {
|
|
|
+ use super::*;
|
|
|
+ use crate::bridge_table;
|
|
|
+ use crate::mock_auth::TestHarness;
|
|
|
+ use crate::proto::{
|
|
|
+ issue_invite,
|
|
|
+ level_up::{self, LEVEL_INTERVAL},
|
|
|
+ migration, open_invite,
|
|
|
+ trust_promotion::{self, UNTRUSTED_INTERVAL},
|
|
|
+ update_invite,
|
|
|
+ };
|
|
|
+ use crate::scalar_u32;
|
|
|
+
|
|
|
+ #[test]
|
|
|
+ fn test_update_invite() {
|
|
|
+ let mut th = TestHarness::new();
|
|
|
+ let rng = &mut rand::thread_rng();
|
|
|
+ let open_invitation_request = open_invite::request(rng, th.ba.lox_pub.clone());
|
|
|
+ assert!(
|
|
|
+ open_invitation_request.is_ok(),
|
|
|
+ "Open invitation request should succeed"
|
|
|
+ );
|
|
|
+ let (request, client_state) = open_invitation_request.unwrap();
|
|
|
+ let invite = th.bdb.invite();
|
|
|
+ let open_invitation_response = th.ba.open_invitation(request, &invite.unwrap());
|
|
|
+ assert!(
|
|
|
+ open_invitation_response.is_ok(),
|
|
|
+ "Open invitation response from server should succeed"
|
|
|
+ );
|
|
|
+ let (response, _) = open_invitation_response.unwrap();
|
|
|
+ let creds = open_invite::handle_response(client_state, response);
|
|
|
+ println!("{}", th.ba.today());
|
|
|
+ assert!(creds.is_ok(), "Handle response should succeed");
|
|
|
+ th.advance_days((UNTRUSTED_INTERVAL + 1).try_into().unwrap());
|
|
|
+ println!("{}", th.ba.today());
|
|
|
+ let lox_cred = creds.unwrap();
|
|
|
+ let trust_promo_request = trust_promotion::request(
|
|
|
+ rng,
|
|
|
+ lox_cred.clone(),
|
|
|
+ th.ba.migrationkey_pub.clone(),
|
|
|
+ th.ba.today(),
|
|
|
+ );
|
|
|
+ assert!(
|
|
|
+ trust_promo_request.is_ok(),
|
|
|
+ "Trust Promotion request should succeed"
|
|
|
+ );
|
|
|
+ let (tp_request, tp_client_state) = trust_promo_request.unwrap();
|
|
|
+ let trust_promo_response = th.ba.handle_trust_promotion(tp_request);
|
|
|
+ assert!(
|
|
|
+ trust_promo_response.is_ok(),
|
|
|
+ "Trust promotion response from server should succeed"
|
|
|
+ );
|
|
|
+ let (response, enc) = trust_promo_response.unwrap();
|
|
|
+ let mig_cred = trust_promotion::handle_response(
|
|
|
+ th.ba.migration_pub.clone(),
|
|
|
+ tp_client_state,
|
|
|
+ response,
|
|
|
+ enc,
|
|
|
+ );
|
|
|
+ assert!(mig_cred.is_ok(), "Handle response should succeed");
|
|
|
+ let migration_request = migration::request(
|
|
|
+ rng,
|
|
|
+ lox_cred.clone(),
|
|
|
+ mig_cred.unwrap(),
|
|
|
+ th.ba.lox_pub.clone(),
|
|
|
+ );
|
|
|
+ assert!(
|
|
|
+ migration_request.is_ok(),
|
|
|
+ "Migration request should succeed"
|
|
|
+ );
|
|
|
+ let (mig_request, mig_client_state) = migration_request.unwrap();
|
|
|
+ let migration_response = th.ba.handle_migration(mig_request);
|
|
|
+ assert!(
|
|
|
+ migration_response.is_ok(),
|
|
|
+ "Migration response from server should succeed"
|
|
|
+ );
|
|
|
+ let response = migration_response.unwrap();
|
|
|
+ let mut cred = migration::handle_response(mig_client_state, response);
|
|
|
+ assert!(cred.is_ok(), "Handle response should succeed");
|
|
|
+ let lox_cred = cred.unwrap();
|
|
|
+ let trust_level: u32 = scalar_u32(&lox_cred.clone().trust_level.unwrap()).unwrap();
|
|
|
+ th.advance_days(LEVEL_INTERVAL[trust_level as usize] + 1);
|
|
|
+ let (id, key) = bridge_table::from_scalar(lox_cred.bucket.unwrap()).unwrap();
|
|
|
+ let encbuckets = th.ba.enc_bridge_table().clone();
|
|
|
+ let reach_pub = th.ba.reachability_pub.clone();
|
|
|
+ let bucket = bridge_table::BridgeTable::decrypt_bucket(
|
|
|
+ id,
|
|
|
+ &key,
|
|
|
+ encbuckets.get(&id).unwrap(),
|
|
|
+ &reach_pub,
|
|
|
+ )
|
|
|
+ .unwrap();
|
|
|
+
|
|
|
+ let reachcred = bucket.1.unwrap();
|
|
|
+
|
|
|
+ let level_up_request = level_up::request(
|
|
|
+ rng,
|
|
|
+ lox_cred.clone(),
|
|
|
+ reachcred.clone(),
|
|
|
+ th.ba.lox_pub.clone(),
|
|
|
+ th.ba.today(),
|
|
|
+ );
|
|
|
+ assert!(level_up_request.is_ok(), "Level up request should succeed");
|
|
|
+ let (level_up_request, level_up_client_state) = level_up_request.unwrap();
|
|
|
+ let level_up_response = th.ba.handle_level_up(level_up_request);
|
|
|
+ assert!(
|
|
|
+ level_up_response.is_ok(),
|
|
|
+ "Level up response from server should succeed"
|
|
|
+ );
|
|
|
+ let response = level_up_response.unwrap();
|
|
|
+ cred = level_up::handle_response(level_up_client_state, response);
|
|
|
+ assert!(cred.is_ok(), "Handle response should succeed");
|
|
|
+ let level_up_cred = cred.unwrap();
|
|
|
+ let issue_invite_request = issue_invite::request(
|
|
|
+ rng,
|
|
|
+ level_up_cred.clone(),
|
|
|
+ th.ba.lox_pub.clone(),
|
|
|
+ reachcred.clone(),
|
|
|
+ th.ba.invitation_pub.clone(),
|
|
|
+ th.ba.today(),
|
|
|
+ );
|
|
|
+ let (issue_invite_request, issue_invite_client_state) = issue_invite_request.unwrap();
|
|
|
+ let issue_invite_response = th.ba.handle_issue_invite(issue_invite_request);
|
|
|
+ assert!(
|
|
|
+ issue_invite_response.is_ok(),
|
|
|
+ "Issue Invite response from server should succeed"
|
|
|
+ );
|
|
|
+ let response = issue_invite_response.unwrap();
|
|
|
+ let i_cred = issue_invite::handle_response(issue_invite_client_state, response);
|
|
|
+ assert!(i_cred.is_ok(), "Handle response should succeed");
|
|
|
+ let issue_invite_cred = i_cred.unwrap();
|
|
|
+
|
|
|
+ let old_pub = th.ba.invitation_pub.clone();
|
|
|
+ th.ba.rotate_invitation_keys(rng);
|
|
|
+ let update_invite_request = update_invite::request(
|
|
|
+ rng,
|
|
|
+ issue_invite_cred.clone().0,
|
|
|
+ th.ba.invitation_pub.clone(),
|
|
|
+ );
|
|
|
+ assert!(
|
|
|
+ update_invite_request.is_ok(),
|
|
|
+ "Update invitation request should succeed"
|
|
|
+ );
|
|
|
+ let (request, client_state) = update_invite_request.unwrap();
|
|
|
+ let update_invite_response = th.ba.handle_update_invite(old_pub, request);
|
|
|
+ assert!(
|
|
|
+ update_invite_response.is_ok(),
|
|
|
+ "Update invite response from server should succeed"
|
|
|
+ );
|
|
|
+ let response = update_invite_response.unwrap();
|
|
|
+ let creds = update_invite::handle_response(client_state, response);
|
|
|
+ assert!(creds.is_ok(), "Handle response should succeed");
|
|
|
+ th.verify_invitation(&creds.unwrap());
|
|
|
+ }
|
|
|
+}
|