| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185 |
- /*! A module for the protocol for the user to check for the availability
- of a migration credential they can use in order to move to a new bucket
- if theirs has been blocked.
- The user presents their current Lox credential:
- - id: revealed
- - bucket: blinded
- - trust_level: revealed to be 3 or above
- - level_since: blinded
- - invites_remaining: blinded
- - blockages: blinded
- They are allowed to to this as long as they are level 3 or above. If
- they have too many blockages (but are level 3 or above), they will be
- allowed to perform this migration, but will not be able to advance to
- level 3 in their new bucket, so this will be their last allowed
- migration without rejoining the system either with a new invitation or
- an open invitation.
- They will receive in return the encrypted MAC (Pk, EncQk) for their
- implicit Migration Key credential with attributes id and bucket,
- along with a HashMap of encrypted Migration credentials. For each
- (from_i, to_i) in the BA's migration list, there will be an entry in
- the HashMap with key H1(id, from_attr_i, Qk_i) and value
- Enc_{H2(id, from_attr_i, Qk_i)}(to_attr_i, P_i, Q_i). Here H1 and H2
- are the first 16 bytes and the second 16 bytes respectively of the
- SHA256 hash of the input, P_i and Q_i are a MAC on the Migration
- credential with attributes id, from_attr_i, and to_attr_i. Qk_i is the
- value EncQk would decrypt to if bucket were equal to from_attr_i. */
- #[cfg(feature = "bridgeauth")]
- use super::super::dup_filter::SeenType;
- #[cfg(feature = "bridgeauth")]
- use super::super::BridgeAuth;
- use super::super::{scalar_u32, G};
- use super::errors::CredentialError;
- use super::level_up::MAX_LEVEL;
- use crate::lox_creds::{Lox, Migration, MigrationKey};
- use crate::migration_table;
- use crate::migration_table::ENC_MIGRATION_BYTES;
- #[cfg(feature = "bridgeauth")]
- use crate::migration_table::WNAF_SIZE;
- use cmz::*;
- use group::Group;
- #[cfg(feature = "bridgeauth")]
- use group::WnafBase;
- use rand::{CryptoRng, RngCore};
- use sha2::Sha512;
- use std::collections::HashMap;
- /// The minimum trust level a Lox credential must have to be allowed to
- /// perform this protocol.
- pub const MIN_TRUST_LEVEL: u32 = 3;
- muCMZProtocol! { check_blockage<min_trust_level, max_trust_level>,
- L: Lox { id: R, bucket: H, trust_level: R, level_since: H, invites_remaining: R, blockages: R },
- M: MigrationKey { lox_id: J, from_bucket: H} ,
- L.bucket = M.from_bucket,
- [min_trust_level..max_trust_leve].contains(L.trust_level),
- }
- pub fn request(
- L: Lox,
- mig_pubkeys: CMZPubkey<G>,
- ) -> Result<(check_blockage::Request, check_blockage::ClientState), CredentialError> {
- let mut rng = rand::thread_rng();
- cmz_group_init(G::hash_from_bytes::<Sha512>(b"CMZ Generator A"));
- // Ensure that the credenials can be correctly shown; that is, the
- // ids match and the Lox credential bucket matches the Migration
- // credential from_bucket
- if L.id.is_none() {
- return Err(CredentialError::CredentialMismatch);
- }
- // Ensure the credential can be correctly shown: it must be the case
- // that trust_level >= MIN_TRUST_LEVEL
- if let Some(tl) = L.trust_level {
- let level: u32 = match scalar_u32(&tl) {
- Some(v) => v,
- None => {
- return Err(CredentialError::InvalidField(
- String::from("trust_level"),
- String::from("could not be converted to u32"),
- ))
- }
- };
- if level < MIN_TRUST_LEVEL {
- return Err(CredentialError::InvalidField(
- String::from("trust_level"),
- format!("level {:?} not in range", level),
- ));
- }
- }
- let params = check_blockage::Params {
- min_trust_level: MIN_TRUST_LEVEL.into(),
- max_trust_level: (MAX_LEVEL as u32).into(),
- };
- match check_blockage::prepare(
- &mut rng,
- &L,
- MigrationKey::using_pubkey(&mig_pubkeys),
- ¶ms,
- ) {
- Ok(req_state) => Ok(req_state),
- Err(e) => Err(CredentialError::CMZError(e)),
- }
- }
- #[cfg(feature = "bridgeauth")]
- impl BridgeAuth {
- pub fn handle_check_blockage(
- &mut self,
- req: check_blockage::Request,
- ) -> Result<
- (
- check_blockage::Reply,
- HashMap<[u8; 16], [u8; ENC_MIGRATION_BYTES]>,
- ),
- CredentialError,
- > {
- let mut rng = rand::thread_rng();
- let reqbytes = req.as_bytes();
- let recvreq = check_blockage::Request::try_from(&reqbytes[..]).unwrap();
- match check_blockage::handle(
- &mut rng,
- recvreq,
- |L: &mut Lox, M: &mut MigrationKey| {
- L.set_privkey(&self.lox_priv);
- M.set_privkey(&self.migrationkey_priv);
- M.lox_id = L.id;
- M.from_bucket = L.bucket;
- Ok(check_blockage::Params {
- min_trust_level: MIN_TRUST_LEVEL.into(),
- max_trust_level: (MAX_LEVEL as u32).into(),
- })
- },
- |L: &Lox, _M: &MigrationKey| {
- if self.id_filter.filter(&L.id.unwrap()) == SeenType::Seen {
- return Err(CMZError::RevealAttrMissing("id", "Credential Expired"));
- }
- Ok(())
- },
- ) {
- Ok((response, (L_issuer, M_issuer))) => {
- let Pktable: WnafBase<G, WNAF_SIZE> = WnafBase::new(M_issuer.MAC.P);
- let enc_migration_table = self.blockage_migration_table.encrypt_table(
- L_issuer.id.unwrap(),
- &self.bridge_table,
- &Pktable,
- &self.migration_priv,
- &self.migrationkey_priv,
- );
- Ok((response, enc_migration_table))
- }
- Err(e) => Err(CredentialError::CMZError(e)),
- }
- }
- }
- pub fn handle_response(
- migration_pubkey: CMZPubkey<G>,
- state: check_blockage::ClientState,
- rep: check_blockage::Reply,
- enc_migration_table: HashMap<[u8; 16], [u8; ENC_MIGRATION_BYTES]>,
- ) -> Result<Migration, CMZError> {
- let replybytes = rep.as_bytes();
- let recvreply = check_blockage::Reply::try_from(&replybytes[..]).unwrap();
- let migkey = match state.finalize(recvreply) {
- Ok(cred) => cred,
- Err(_e) => return Err(CMZError::Unknown),
- };
- match migration_table::decrypt_cred(
- migkey,
- migration_table::MigrationType::Blockage,
- migration_pubkey,
- &enc_migration_table,
- ) {
- Some(cred) => Ok(cred),
- None => Err(CMZError::Unknown),
- }
- }
|