def check_nsec_bitmap( nsec3s: List[dns.rdtypes.ANY.NSEC3], nsec3param: dns.rdtypes.ANY.NSEC3PARAM, name: str, ) -> bool: """ Checks whether there is an NSEC3 record for the QNAME that does not have the type DS in its bitmap field. :param nsec3s: :param nsec3param: :param name: :return: """ success = True # check whether the owner name matches to QNAME name_hash = nsec_utils.nsec3_hash( name, nsec3param.salt, nsec3param.iterations, nsec3param.algorithm, ) owner_name, nsec3 = nsec3s[0] owner_hash = str(owner_name).split(".")[0] success &= name_hash == owner_hash # check if the bitmap field does not contain the DS type bitmap_list = nsec_utils.nsec_window_to_array(nsec3.items[0]) success &= dns.rdatatype.DS not in bitmap_list return success
def check_name_cover( nsec3s: List[dns.rdtypes.ANY.NSEC3], nsec3param: dns.rdtypes.ANY.NSEC3PARAM, name: str, ) -> bool: """ This method checks if a name is covered by a NSEC3 record by hashing it and comparing it to all NSEC3s in the nsec3s list. :param nsec3s: :param nsec3param: :param next_closer_name: :return: """ name_hash = nsec_utils.nsec3_hash( name, nsec3param.salt, nsec3param.iterations, nsec3param.algorithm, ) for name, nsec3 in nsec3s: current_name_hash = name[0].decode("utf-8").upper() next_name_hash = nsec_utils.nsec3_next_to_string(nsec3.items[0]) if current_name_hash < name_hash < next_name_hash: return True return False
def test_hash_invalid_salt_length(self): data = ( "example.com", "9F1AB450CF71D", 0, "qfo2sv6jaej4cm11a3npoorfrckdao2c", 1, ) with self.assertRaises(ValueError): hash = nsec_utils.nsec3_hash(data[0], data[1], data[2], data[4])
def find_closest_encloser( nsec3s: List[dns.rdtypes.ANY.NSEC3], nsec3param: dns.rdtypes.ANY.NSEC3PARAM, qname: dns.name.Name, ) -> Tuple[bool, str, str]: """ This method tries to finds the closest encloser by chopping of labels of the QNAME until there is a NSEC3 for the hash value. :param nsec3s: :param nsec3param: :param qname: :return: """ l = len(qname) - 1 tmp = [t.decode() for t in qname] closest_encloser = ".".join(tmp) next_closer_name = closest_encloser for i in range(l): closest_enclosure_hash = nsec_utils.nsec3_hash( closest_encloser, nsec3param.salt, nsec3param.iterations, nsec3param.algorithm, ) for name, nsec3 in nsec3s: current_name_hash = name[0].decode("utf-8").upper() if closest_enclosure_hash == current_name_hash: return True, closest_encloser, next_closer_name next_closer_name = closest_encloser tmp = [t.decode() for t in qname[i + 1:]] closest_encloser = ".".join(tmp) return False, closest_encloser, next_closer_name
def test_hash_function(self): for d in self.DATA: hash = nsec_utils.nsec3_hash(d[0], d[1], d[2], d[4]) self.assertEqual(hash, d[3].upper(), f"Error {d}")