def _pcb_list_to_remove(self, candidates, rev_info): """ Calculates the list of PCBs to remove. Called by _remove_revoked_pcbs. :param candidates: Candidate PCBs. :type candidates: List :param rev_info: The RevocationInfo object. :type rev_info: RevocationInfo """ to_remove = [] processed = set() for cand in candidates: if cand.id in processed: continue processed.add(cand.id) if not ConnectedHashTree.verify_epoch(rev_info.p.epoch): continue # If the interface on which we received the PCB is # revoked, then the corresponding pcb needs to be removed. root_verify = ConnectedHashTree.verify(rev_info, self._get_ht_root()) if (self.addr.isd_as == rev_info.isd_as() and cand.pcb.p.ifID == rev_info.p.ifID and root_verify): to_remove.append(cand.id) for asm in cand.pcb.iter_asms(): if self._verify_revocation_for_asm(rev_info, asm, False): to_remove.append(cand.id) return to_remove
def _verify_revocation_for_asm(self, rev_info, as_marking, verify_all=True): """ Verifies a revocation for a given AS marking. :param rev_info: The RevocationInfo object. :param as_marking: The ASMarking object. :param verify_all: If true, verify all PCBMs (including peers), otherwise only verify the up/down hop. :return: True, if the revocation successfully revokes an upstream interface in the AS marking, False otherwise. """ if rev_info.isd_as() != as_marking.isd_as(): return False if not ConnectedHashTree.verify(rev_info, as_marking.p.hashTreeRoot): return False for pcbm in as_marking.iter_pcbms(): if rev_info.p.ifID in [ pcbm.hof().ingress_if, pcbm.hof().egress_if ]: return True if not verify_all: break return False
def test(self): # Check that the revocation proof is verifiable in T. isd_as = ISD_AS("1-11") if_ids = [23, 35, 120] initial_seed = b"qwerty" inst = ConnectedHashTree(isd_as, if_ids, initial_seed, HashType.SHA256) root = inst.get_root() # Call proof = inst.get_proof(120) # Tests ntools.eq_(ConnectedHashTree.verify(proof, root), True)
def test_one_timestep(self): # Check that the revocation proof is verifiable across T and T+1. # Setup isd_as = ISD_AS("1-11") if_ids = [23, 35, 120] initial_seed = b"qwerty" inst = ConnectedHashTree(isd_as, if_ids, initial_seed) root = inst.get_root() # Call next_tree = inst.get_next_tree(isd_as, if_ids, b"new!!seed") inst.update(next_tree) # Tests proof = inst.get_proof(35) # if_id = 35. ntools.eq_(ConnectedHashTree.verify(proof, root), True)
def test_two_timesteps(self): # Check that the revocation proof is "NOT" verifiable across T and T+2. # Setup isd_as = ISD_AS("1-11") if_ids = [23, 35, 120] initial_seed = b"qwerty" inst = ConnectedHashTree(isd_as, if_ids, initial_seed, HashType.SHA256) root = inst.get_root() # Call new_tree = inst.get_next_tree(isd_as, if_ids, b"newseed.@1", HashType.SHA256) inst.update(new_tree) new_tree = inst.get_next_tree(isd_as, if_ids, b"newseed.@2", HashType.SHA256) inst.update(new_tree) # Tests proof = inst.get_proof(35) # if_id = 35. ntools.eq_(ConnectedHashTree.verify(proof, root), False)
def _skip_peer(cls, peer_rev, ht_root): # pragma: no cover if not peer_rev: return False return (ConnectedHashTree.verify_epoch(peer_rev.p.epoch) and ConnectedHashTree.verify(peer_rev, ht_root))
def _skip_peer(peer_rev, ht_root): # pragma: no cover if not peer_rev: return False rev_status = ConnectedHashTree.verify_epoch(peer_rev.p.epoch) return (rev_status == ConnectedHashTree.EPOCH_OK and ConnectedHashTree.verify(peer_rev, ht_root))