Пример #1
0
def _hashed_order(names, origin=None, salt='', iterations=0):
    """
    Hash the given names using SHA-1 algorithm, the given salt and the given
    number of iterations. Return list of tuples (name, hash) in hash order.
    Used for NSEC3 records generation. See RFC-5155 for details.
    """

    # Add empty non terminals to the list, see RFC-5155, section 7.1
    nameset = set(names)
    for name in names:
        n = name.relativize(origin)
        while len(n) > 1:
            n = n.parent()
            nameset.add(n.derelativize(origin))
    names = list(nameset)

    ret = []
    for name in names:
        h = name.to_digestable(origin)
        i = iterations
        while i >= 0:
            sha = Crypto.Hash.SHA.new()
            sha.update(h)
            sha.update(salt)
            h = sha.digest()
            i -= 1
        ret.append((name, h))

    # Check for hash collision
    if len(ret) != len(set(ret)):
        raise NSEC3Collision()

    ret = sorted(ret, key=lambda x: x[1])
    return ret
Пример #2
0
    def _compute_digest(self, hash_algorithm, scheme=DigestScheme.SIMPLE):
        hashinfo = _digest_hashers.get(hash_algorithm)
        if not hashinfo:
            raise UnsupportedDigestHashAlgorithm
        if scheme != DigestScheme.SIMPLE:
            raise UnsupportedDigestScheme

        if self.relativize:
            origin_name = dns.name.empty
        else:
            origin_name = self.origin
        hasher = hashinfo()
        for (name, node) in sorted(self.items()):
            rrnamebuf = name.to_digestable(self.origin)
            for rdataset in sorted(node,
                                   key=lambda rds: (rds.rdtype, rds.covers)):
                if name == origin_name and \
                   dns.rdatatype.ZONEMD in (rdataset.rdtype, rdataset.covers):
                    continue
                rrfixed = struct.pack('!HHI', rdataset.rdtype,
                                      rdataset.rdclass, rdataset.ttl)
                for rr in sorted(rdataset):
                    rrdata = rr.to_digestable(self.origin)
                    rrlen = struct.pack('!H', len(rrdata))
                    hasher.update(rrnamebuf + rrfixed + rrlen + rrdata)
        return hasher.digest()
Пример #3
0
def nsec3hash(name, algnum, salt, iterations, binary_out=False):
    """
    Compute NSEC3 hash for given domain name and parameters. name is
    of type dns.name.Name, salt is a binary bytestring, algnum and
    iterations are integers.
    """

    if iterations < 0:
        raise ResError("NSEC3 hash iterations must be >= 0")
    if iterations > Prefs.N3_HASHLIMIT:
        raise ResError("NSEC3 hash iterations too high: {} {}".format(
            name, iterations))

    hashfunc = nsec3_hashalg(algnum)
    digest = name.to_digestable()
    while iterations >= 0:
        d = hashes.Hash(hashfunc(), backend=default_backend())
        d.update(digest + salt)
        digest = d.finalize()
        iterations -= 1
    if binary_out:
        return digest

    output = base64.b32encode(digest)
    output = output.translate(b32_to_ext_hex).decode()
    return output