Exemplo n.º 1
0
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
Exemplo n.º 2
0
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
Exemplo n.º 3
0
 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])
Exemplo n.º 4
0
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
Exemplo n.º 5
0
 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}")