#!/usr/bin/python3 from pyasn1_modules import pem, rfc2459 from pyasn1.codec.der import decoder from pyasn1.type import univ import sys import os import subprocess def main(): records = dict() for root, _, files in os.walk(sys.argv[1]): for filename in files: if filename == 'cert.pem': certname = os.path.join(root, filename) altnames = parse_cert(certname) for altname in altnames: nameparts = altname.split('.') zone = '.'.join(nameparts[-2:]) domain = '.'.join(nameparts[:-2]) if domain == "": continue ldns = subprocess.Popen(["ldns-dane", "create", "-c", certname, altname, "443", "3", "1", "1"], stdout=subprocess.PIPE) data = ldns.stdout.read().decode().strip().split('\t') record = "{0:<35s}\t{1}".format(data[0], '\t'.join(data[2:])) if not zone in records: records[zone] = [] records[zone].append(record) for zone, data in records.items(): with open(os.path.join("output", zone), "w") as zonefile: zonefile.write('\n'.join(data)) def parse_cert(fname): names = [] with open(fname) as fhd: bits = pem.readPemFromFile(fhd) cert = decoder.decode(bits, asn1Spec=rfc2459.Certificate())[0] extensions = cert['tbsCertificate']['extensions'] for extension in extensions: if extension['extnID'] != univ.ObjectIdentifier('2.5.29.17'): continue data = extension['extnValue'].asOctets() altnames = decoder.decode(data)[0] altnames = decoder.decode(altnames, asn1Spec=rfc2459.SubjectAltName())[0] for altname in altnames: result = altname['dNSName'] if result is not None: names.append(str(result)) return names if __name__ == '__main__': main()