/* SPDX-License-Identifier: LGPL-2.1-or-later */

#include "alloc-util.h"
#include "dns-domain.h"
#include "fd-util.h"
#include "fileio.h"
#include "gcrypt-util.h"
#include "hexdecoct.h"
#include "memory-util.h"
#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h"
#include "sort-util.h"
#include "string-table.h"

#define VERIFY_RRS_MAX 256
#define MAX_KEY_SIZE (32*1024)

/* Permit a maximum clock skew of 1h 10min. This should be enough to deal with DST confusion */
#define SKEW_MAX (1*USEC_PER_HOUR + 10*USEC_PER_MINUTE)

/* Maximum number of NSEC3 iterations we'll do. RFC5155 says 2500 shall be the maximum useful value */
#define NSEC3_ITERATIONS_MAX 2500

/*
 * The DNSSEC Chain of trust:
 *
 *            Normal RRs are protected via RRSIG RRs in combination with DNSKEY RRs, all in the same zone
 *            DNSKEY RRs are either protected like normal RRs, or via a DS from a zone "higher" up the tree
 *            DS RRs are protected like normal RRs
 *
 * Example chain:
 *            Normal RR → RRSIG/DNSKEY+ → DS → RRSIG/DNSKEY+ → DS → ... → DS → RRSIG/DNSKEY+ → DS
 */

uint16_t dnssec_keytag(DnsResourceRecord *dnskey, bool mask_revoke) {
        const uint8_t *p;
        uint32_t sum, f;

        /* The algorithm from RFC 4034, Appendix B. */

        assert(dnskey);
        assert(dnskey->key->type == DNS_TYPE_DNSKEY);

        f = (uint32_t) dnskey->dnskey.flags;

        if (mask_revoke)
                f &= ~DNSKEY_FLAG_REVOKE;

        sum = f + ((((uint32_t) dnskey->dnskey.protocol) << 8) + (uint32_t) dnskey->dnskey.algorithm);

        p = dnskey->dnskey.key;

        for (size_t i = 0; i < dnskey->dnskey.key_size; i++)
                sum += (i & 1) == 0 ? (uint32_t) p[i] << 8 : (uint32_t) p[i];

        sum += (sum >> 16) & UINT32_C(0xFFFF);

        return sum & UINT32_C(0xFFFF);
}

#if HAVE_GCRYPT

static int rr_compare(DnsResourceRecord * const *a, DnsResourceRecord * const *b) {
        const DnsResourceRecord *x = *a, *y = *b;
        size_t m;
        int r;

        /* Let's order the RRs according to RFC 4034, Section 6.3 */

        assert(x);
        assert(x->wire_format);
        assert(y);
        assert(y->wire_format);

        m = MIN(DNS_RESOURCE_RECORD_RDATA_SIZE(x), DNS_RESOURCE_RECORD_RDATA_SIZE(y));

        r = memcmp(DNS_RESOURCE_RECORD_RDATA(x), DNS_RESOURCE_RECORD_RDATA(y), m);
        if (r != 0)
                return r;

        return CMP(DNS_RESOURCE_RECORD_RDATA_SIZE(x), DNS_RESOURCE_RECORD_RDATA_SIZE(y));
}

static int dnssec_rsa_verify_raw(
                const char *hash_algorithm,
                const void *signature, size_t signature_size,
                const void *data, size_t data_size,
                const void *exponent, size_t exponent_size,
                const void *modulus, size_t modulus_size) {

        gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
        gcry_mpi_t n = NULL, e = NULL, s = NULL;
        gcry_error_t ge;
        int r;

        assert(hash_algorithm);

        ge = gcry_mpi_scan(&s, GCRYMPI_FMT_USG, signature, signature_size, NULL);
        if (ge != 0) {
                r = -EIO;
                goto finish;
        }

        ge = gcry_mpi_scan(&e, GCRYMPI_FMT_USG, exponent, exponent_size, NULL);
        if (ge != 0) {
                r = -EIO;
                goto finish;
        }

        ge = gcry_mpi_scan(&n, GCRYMPI_FMT_USG, modulus, modulus_size, NULL);
        if (ge != 0) {
                r = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&signature_sexp,
                             NULL,
                             "(sig-val (rsa (s %m)))",
                             s);

        if (ge != 0) {
                r = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&data_sexp,
                             NULL,
                             "(data (flags pkcs1) (hash %s %b))",
                             hash_algorithm,
                             (int) data_size,
                             data);
        if (ge != 0) {
                r = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&public_key_sexp,
                             NULL,
                             "(public-key (rsa (n %m) (e %m)))",
                             n,
                             e);
        if (ge != 0) {
                r = -EIO;
                goto finish;
        }

        ge = gcry_pk_verify(signature_sexp, data_sexp, public_key_sexp);
        if (gpg_err_code(ge) == GPG_ERR_BAD_SIGNATURE)
                r = 0;
        else if (ge != 0) {
                log_debug("RSA signature check failed: %s", gpg_strerror(ge));
                r = -EIO;
        } else
                r = 1;

finish:
        if (e)
                gcry_mpi_release(e);
        if (n)
                gcry_mpi_release(n);
        if (s)
                gcry_mpi_release(s);

        if (public_key_sexp)
                gcry_sexp_release(public_key_sexp);
        if (signature_sexp)
                gcry_sexp_release(signature_sexp);
        if (data_sexp)
                gcry_sexp_release(data_sexp);

        return r;
}

static int dnssec_rsa_verify(
                const char *hash_algorithm,
                const void *hash, size_t hash_size,
                DnsResourceRecord *rrsig,
                DnsResourceRecord *dnskey) {

        size_t exponent_size, modulus_size;
        void *exponent, *modulus;

        assert(hash_algorithm);
        assert(hash);
        assert(hash_size > 0);
        assert(rrsig);
        assert(dnskey);

        if (*(uint8_t*) dnskey->dnskey.key == 0) {
                /* exponent is > 255 bytes long */

                exponent = (uint8_t*) dnskey->dnskey.key + 3;
                exponent_size =
                        ((size_t) (((uint8_t*) dnskey->dnskey.key)[1]) << 8) |
                        ((size_t) ((uint8_t*) dnskey->dnskey.key)[2]);

                if (exponent_size < 256)
                        return -EINVAL;

                if (3 + exponent_size >= dnskey->dnskey.key_size)
                        return -EINVAL;

                modulus = (uint8_t*) dnskey->dnskey.key + 3 + exponent_size;
                modulus_size = dnskey->dnskey.key_size - 3 - exponent_size;

        } else {
                /* exponent is <= 255 bytes long */

                exponent = (uint8_t*) dnskey->dnskey.key + 1;
                exponent_size = (size_t) ((uint8_t*) dnskey->dnskey.key)[0];

                if (exponent_size <= 0)
                        return -EINVAL;

                if (1 + exponent_size >= dnskey->dnskey.key_size)
                        return -EINVAL;

                modulus = (uint8_t*) dnskey->dnskey.key + 1 + exponent_size;
                modulus_size = dnskey->dnskey.key_size - 1 - exponent_size;
        }

        return dnssec_rsa_verify_raw(
                        hash_algorithm,
                        rrsig->rrsig.signature, rrsig->rrsig.signature_size,
                        hash, hash_size,
                        exponent, exponent_size,
                        modulus, modulus_size);
}

static int dnssec_ecdsa_verify_raw(
                const char *hash_algorithm,
                const char *curve,
                const void *signature_r, size_t signature_r_size,
                const void *signature_s, size_t signature_s_size,
                const void *data, size_t data_size,
                const void *key, size_t key_size) {

        gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
        gcry_mpi_t q = NULL, r = NULL, s = NULL;
        gcry_error_t ge;
        int k;

        assert(hash_algorithm);

        ge = gcry_mpi_scan(&r, GCRYMPI_FMT_USG, signature_r, signature_r_size, NULL);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_mpi_scan(&s, GCRYMPI_FMT_USG, signature_s, signature_s_size, NULL);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_mpi_scan(&q, GCRYMPI_FMT_USG, key, key_size, NULL);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&signature_sexp,
                             NULL,
                             "(sig-val (ecdsa (r %m) (s %m)))",
                             r,
                             s);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&data_sexp,
                             NULL,
                             "(data (flags rfc6979) (hash %s %b))",
                             hash_algorithm,
                             (int) data_size,
                             data);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&public_key_sexp,
                             NULL,
                             "(public-key (ecc (curve %s) (q %m)))",
                             curve,
                             q);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_pk_verify(signature_sexp, data_sexp, public_key_sexp);
        if (gpg_err_code(ge) == GPG_ERR_BAD_SIGNATURE)
                k = 0;
        else if (ge != 0) {
                log_debug("ECDSA signature check failed: %s", gpg_strerror(ge));
                k = -EIO;
        } else
                k = 1;
finish:
        if (r)
                gcry_mpi_release(r);
        if (s)
                gcry_mpi_release(s);
        if (q)
                gcry_mpi_release(q);

        if (public_key_sexp)
                gcry_sexp_release(public_key_sexp);
        if (signature_sexp)
                gcry_sexp_release(signature_sexp);
        if (data_sexp)
                gcry_sexp_release(data_sexp);

        return k;
}

static int dnssec_ecdsa_verify(
                const char *hash_algorithm,
                int algorithm,
                const void *hash, size_t hash_size,
                DnsResourceRecord *rrsig,
                DnsResourceRecord *dnskey) {

        const char *curve;
        size_t key_size;
        uint8_t *q;

        assert(hash);
        assert(hash_size);
        assert(rrsig);
        assert(dnskey);

        if (algorithm == DNSSEC_ALGORITHM_ECDSAP256SHA256) {
                key_size = 32;
                curve = "NIST P-256";
        } else if (algorithm == DNSSEC_ALGORITHM_ECDSAP384SHA384) {
                key_size = 48;
                curve = "NIST P-384";
        } else
                return -EOPNOTSUPP;

        if (dnskey->dnskey.key_size != key_size * 2)
                return -EINVAL;

        if (rrsig->rrsig.signature_size != key_size * 2)
                return -EINVAL;

        q = newa(uint8_t, key_size*2 + 1);
        q[0] = 0x04; /* Prepend 0x04 to indicate an uncompressed key */
        memcpy(q+1, dnskey->dnskey.key, key_size*2);

        return dnssec_ecdsa_verify_raw(
                        hash_algorithm,
                        curve,
                        rrsig->rrsig.signature, key_size,
                        (uint8_t*) rrsig->rrsig.signature + key_size, key_size,
                        hash, hash_size,
                        q, key_size*2+1);
}

#if GCRYPT_VERSION_NUMBER >= 0x010600
static int dnssec_eddsa_verify_raw(
                const char *curve,
                const void *signature_r, size_t signature_r_size,
                const void *signature_s, size_t signature_s_size,
                const void *data, size_t data_size,
                const void *key, size_t key_size) {

        gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
        gcry_error_t ge;
        int k;

        ge = gcry_sexp_build(&signature_sexp,
                             NULL,
                             "(sig-val (eddsa (r %b) (s %b)))",
                             (int) signature_r_size,
                             signature_r,
                             (int) signature_s_size,
                             signature_s);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&data_sexp,
                             NULL,
                             "(data (flags eddsa) (hash-algo sha512) (value %b))",
                             (int) data_size,
                             data);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_sexp_build(&public_key_sexp,
                             NULL,
                             "(public-key (ecc (curve %s) (flags eddsa) (q %b)))",
                             curve,
                             (int) key_size,
                             key);
        if (ge != 0) {
                k = -EIO;
                goto finish;
        }

        ge = gcry_pk_verify(signature_sexp, data_sexp, public_key_sexp);
        if (gpg_err_code(ge) == GPG_ERR_BAD_SIGNATURE)
                k = 0;
        else if (ge != 0) {
                log_debug("EdDSA signature check failed: %s", gpg_strerror(ge));
                k = -EIO;
        } else
                k = 1;
finish:
        if (public_key_sexp)
                gcry_sexp_release(public_key_sexp);
        if (signature_sexp)
                gcry_sexp_release(signature_sexp);
        if (data_sexp)
                gcry_sexp_release(data_sexp);

        return k;
}

static int dnssec_eddsa_verify(
                int algorithm,
                const void *data, size_t data_size,
                DnsResourceRecord *rrsig,
                DnsResourceRecord *dnskey) {
        const char *curve;
        size_t key_size;

        if (algorithm == DNSSEC_ALGORITHM_ED25519) {
                curve = "Ed25519";
                key_size = 32;
        } else
                return -EOPNOTSUPP;

        if (dnskey->dnskey.key_size != key_size)
                return -EINVAL;

        if (rrsig->rrsig.signature_size != key_size * 2)
                return -EINVAL;

        return dnssec_eddsa_verify_raw(
                        curve,
                        rrsig->rrsig.signature, key_size,
                        (uint8_t*) rrsig->rrsig.signature + key_size, key_size,
                        data, data_size,
                        dnskey->dnskey.key, key_size);
}
#endif

static void md_add_uint8(gcry_md_hd_t md, uint8_t v) {
        gcry_md_write(md, &v, sizeof(v));
}

static void md_add_uint16(gcry_md_hd_t md, uint16_t v) {
        v = htobe16(v);
        gcry_md_write(md, &v, sizeof(v));
}

static void fwrite_uint8(FILE *fp, uint8_t v) {
        fwrite(&v, sizeof(v), 1, fp);
}

static void fwrite_uint16(FILE *fp, uint16_t v) {
        v = htobe16(v);
        fwrite(&v, sizeof(v), 1, fp);
}

static void fwrite_uint32(FILE *fp, uint32_t v) {
        v = htobe32(v);
        fwrite(&v, sizeof(v), 1, fp);
}

static int dnssec_rrsig_prepare(DnsResourceRecord *rrsig) {
        int n_key_labels, n_signer_labels;
        const char *name;
        int r;

        /* Checks whether the specified RRSIG RR is somewhat valid, and initializes the .n_skip_labels_source
         * and .n_skip_labels_signer fields so that we can use them later on. */

        assert(rrsig);
        assert(rrsig->key->type == DNS_TYPE_RRSIG);

        /* Check if this RRSIG RR is already prepared */
        if (rrsig->n_skip_labels_source != UINT8_MAX)
                return 0;

        if (rrsig->rrsig.inception > rrsig->rrsig.expiration)
                return -EINVAL;

        name = dns_resource_key_name(rrsig->key);

        n_key_labels = dns_name_count_labels(name);
        if (n_key_labels < 0)
                return n_key_labels;
        if (rrsig->rrsig.labels > n_key_labels)
                return -EINVAL;

        n_signer_labels = dns_name_count_labels(rrsig->rrsig.signer);
        if (n_signer_labels < 0)
                return n_signer_labels;
        if (n_signer_labels > rrsig->rrsig.labels)
                return -EINVAL;

        r = dns_name_skip(name, n_key_labels - n_signer_labels, &name);
        if (r < 0)
                return r;
        if (r == 0)
                return -EINVAL;

        /* Check if the signer is really a suffix of us */
        r = dns_name_equal(name, rrsig->rrsig.signer);
        if (r < 0)
                return r;
        if (r == 0)
                return -EINVAL;

        assert(n_key_labels < UINT8_MAX); /* UINT8_MAX/-1 means unsigned. */
        rrsig->n_skip_labels_source = n_key_labels - rrsig->rrsig.labels;
        rrsig->n_skip_labels_signer = n_key_labels - n_signer_labels;

        return 0;
}

static int dnssec_rrsig_expired(DnsResourceRecord *rrsig, usec_t realtime) {
        usec_t expiration, inception, skew;

        assert(rrsig);
        assert(rrsig->key->type == DNS_TYPE_RRSIG);

        if (realtime == USEC_INFINITY)
                realtime = now(CLOCK_REALTIME);

        expiration = rrsig->rrsig.expiration * USEC_PER_SEC;
        inception = rrsig->rrsig.inception * USEC_PER_SEC;

        /* Consider inverted validity intervals as expired */
        if (inception > expiration)
                return true;

        /* Permit a certain amount of clock skew of 10% of the valid
         * time range. This takes inspiration from unbound's
         * resolver. */
        skew = (expiration - inception) / 10;
        if (skew > SKEW_MAX)
                skew = SKEW_MAX;

        if (inception < skew)
                inception = 0;
        else
                inception -= skew;

        if (expiration + skew < expiration)
                expiration = USEC_INFINITY;
        else
                expiration += skew;

        return realtime < inception || realtime > expiration;
}

static int algorithm_to_gcrypt_md(uint8_t algorithm) {

        /* Translates a DNSSEC signature algorithm into a gcrypt
         * digest identifier.
         *
         * Note that we implement all algorithms listed as "Must
         * implement" and "Recommended to Implement" in RFC6944. We
         * don't implement any algorithms that are listed as
         * "Optional" or "Must Not Implement". Specifically, we do not
         * implement RSAMD5, DSASHA1, DH, DSA-NSEC3-SHA1, and
         * GOST-ECC. */

        switch (algorithm) {

        case DNSSEC_ALGORITHM_RSASHA1:
        case DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1:
                return GCRY_MD_SHA1;

        case DNSSEC_ALGORITHM_RSASHA256:
        case DNSSEC_ALGORITHM_ECDSAP256SHA256:
                return GCRY_MD_SHA256;

        case DNSSEC_ALGORITHM_ECDSAP384SHA384:
                return GCRY_MD_SHA384;

        case DNSSEC_ALGORITHM_RSASHA512:
                return GCRY_MD_SHA512;

        default:
                return -EOPNOTSUPP;
        }
}

static void dnssec_fix_rrset_ttl(
                DnsResourceRecord *list[],
                unsigned n,
                DnsResourceRecord *rrsig,
                usec_t realtime) {

        assert(list);
        assert(n > 0);
        assert(rrsig);

        for (unsigned k = 0; k < n; k++) {
                DnsResourceRecord *rr = list[k];

                /* Pick the TTL as the minimum of the RR's TTL, the
                 * RR's original TTL according to the RRSIG and the
                 * RRSIG's own TTL, see RFC 4035, Section 5.3.3 */
                rr->ttl = MIN3(rr->ttl, rrsig->rrsig.original_ttl, rrsig->ttl);
                rr->expiry = rrsig->rrsig.expiration * USEC_PER_SEC;

                /* Copy over information about the signer and wildcard source of synthesis */
                rr->n_skip_labels_source = rrsig->n_skip_labels_source;
                rr->n_skip_labels_signer = rrsig->n_skip_labels_signer;
        }

        rrsig->expiry = rrsig->rrsig.expiration * USEC_PER_SEC;
}

int dnssec_verify_rrset(
                DnsAnswer *a,
                const DnsResourceKey *key,
                DnsResourceRecord *rrsig,
                DnsResourceRecord *dnskey,
                usec_t realtime,
                DnssecResult *result) {

        uint8_t wire_format_name[DNS_WIRE_FORMAT_HOSTNAME_MAX];
        DnsResourceRecord **list, *rr;
        const char *source, *name;
        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
        int r, md_algorithm;
        size_t n = 0;
        size_t sig_size = 0;
        _cleanup_free_ char *sig_data = NULL;
        _cleanup_fclose_ FILE *f = NULL;
        size_t hash_size;
        void *hash;
        bool wildcard;

        assert(key);
        assert(rrsig);
        assert(dnskey);
        assert(result);
        assert(rrsig->key->type == DNS_TYPE_RRSIG);
        assert(dnskey->key->type == DNS_TYPE_DNSKEY);

        /* Verifies that the RRSet matches the specified "key" in "a",
         * using the signature "rrsig" and the key "dnskey". It's
         * assumed that RRSIG and DNSKEY match. */

        r = dnssec_rrsig_prepare(rrsig);
        if (r == -EINVAL) {
                *result = DNSSEC_INVALID;
                return r;
        }
        if (r < 0)
                return r;

        r = dnssec_rrsig_expired(rrsig, realtime);
        if (r < 0)
                return r;
        if (r > 0) {
                *result = DNSSEC_SIGNATURE_EXPIRED;
                return 0;
        }

        name = dns_resource_key_name(key);

        /* Some keys may only appear signed in the zone apex, and are invalid anywhere else. (SOA, NS...) */
        if (dns_type_apex_only(rrsig->rrsig.type_covered)) {
                r = dns_name_equal(rrsig->rrsig.signer, name);
                if (r < 0)
                        return r;
                if (r == 0) {
                        *result = DNSSEC_INVALID;
                        return 0;
                }
        }

        /* OTOH DS RRs may not appear in the zone apex, but are valid everywhere else. */
        if (rrsig->rrsig.type_covered == DNS_TYPE_DS) {
                r = dns_name_equal(rrsig->rrsig.signer, name);
                if (r < 0)
                        return r;
                if (r > 0) {
                        *result = DNSSEC_INVALID;
                        return 0;
                }
        }

        /* Determine the "Source of Synthesis" and whether this is a wildcard RRSIG */
        r = dns_name_suffix(name, rrsig->rrsig.labels, &source);
        if (r < 0)
                return r;
        if (r > 0 && !dns_type_may_wildcard(rrsig->rrsig.type_covered)) {
                /* We refuse to validate NSEC3 or SOA RRs that are synthesized from wildcards */
                *result = DNSSEC_INVALID;
                return 0;
        }
        if (r == 1) {
                /* If we stripped a single label, then let's see if that maybe was "*". If so, we are not really
                 * synthesized from a wildcard, we are the wildcard itself. Treat that like a normal name. */
                r = dns_name_startswith(name, "*");
                if (r < 0)
                        return r;
                if (r > 0)
                        source = name;

                wildcard = r == 0;
        } else
                wildcard = r > 0;

        /* Collect all relevant RRs in a single array, so that we can look at the RRset */
        list = newa(DnsResourceRecord *, dns_answer_size(a));

        DNS_ANSWER_FOREACH(rr, a) {
                r = dns_resource_key_equal(key, rr->key);
                if (r < 0)
                        return r;
                if (r == 0)
                        continue;

                /* We need the wire format for ordering, and digest calculation */
                r = dns_resource_record_to_wire_format(rr, true);
                if (r < 0)
                        return r;

                list[n++] = rr;

                if (n > VERIFY_RRS_MAX)
                        return -E2BIG;
        }

        if (n <= 0)
                return -ENODATA;

        /* Bring the RRs into canonical order */
        typesafe_qsort(list, n, rr_compare);

        f = open_memstream_unlocked(&sig_data, &sig_size);
        if (!f)
                return -ENOMEM;

        fwrite_uint16(f, rrsig->rrsig.type_covered);
        fwrite_uint8(f, rrsig->rrsig.algorithm);
        fwrite_uint8(f, rrsig->rrsig.labels);
        fwrite_uint32(f, rrsig->rrsig.original_ttl);
        fwrite_uint32(f, rrsig->rrsig.expiration);
        fwrite_uint32(f, rrsig->rrsig.inception);
        fwrite_uint16(f, rrsig->rrsig.key_tag);

        r = dns_name_to_wire_format(rrsig->rrsig.signer, wire_format_name, sizeof(wire_format_name), true);
        if (r < 0)
                return r;
        fwrite(wire_format_name, 1, r, f);

        /* Convert the source of synthesis into wire format */
        r = dns_name_to_wire_format(source, wire_format_name, sizeof(wire_format_name), true);
        if (r < 0)
                return r;

        for (size_t k = 0; k < n; k++) {
                size_t l;

                rr = list[k];

                /* Hash the source of synthesis. If this is a wildcard, then prefix it with the *. label */
                if (wildcard)
                        fwrite((uint8_t[]) { 1, '*'}, sizeof(uint8_t), 2, f);
                fwrite(wire_format_name, 1, r, f);

                fwrite_uint16(f, rr->key->type);
                fwrite_uint16(f, rr->key->class);
                fwrite_uint32(f, rrsig->rrsig.original_ttl);

                l = DNS_RESOURCE_RECORD_RDATA_SIZE(rr);
                assert(l <= 0xFFFF);

                fwrite_uint16(f, (uint16_t) l);
                fwrite(DNS_RESOURCE_RECORD_RDATA(rr), 1, l, f);
        }

        r = fflush_and_check(f);
        if (r < 0)
                return r;

        initialize_libgcrypt(false);

        switch (rrsig->rrsig.algorithm) {
#if GCRYPT_VERSION_NUMBER >= 0x010600
        case DNSSEC_ALGORITHM_ED25519:
                break;
#else
        case DNSSEC_ALGORITHM_ED25519:
#endif
        case DNSSEC_ALGORITHM_ED448:
                *result = DNSSEC_UNSUPPORTED_ALGORITHM;
                return 0;
        default: {
                gcry_error_t err;

                /* OK, the RRs are now in canonical order. Let's calculate the digest */
                md_algorithm = algorithm_to_gcrypt_md(rrsig->rrsig.algorithm);
                if (md_algorithm == -EOPNOTSUPP) {
                        *result = DNSSEC_UNSUPPORTED_ALGORITHM;
                        return 0;
                }
                if (md_algorithm < 0)
                        return md_algorithm;

                err = gcry_md_open(&md, md_algorithm, 0);
                if (gcry_err_code(err) != GPG_ERR_NO_ERROR || !md)
                        return -EIO;

                hash_size = gcry_md_get_algo_dlen(md_algorithm);
                assert(hash_size > 0);

                gcry_md_write(md, sig_data, sig_size);

                hash = gcry_md_read(md, 0);
                if (!hash)
                        return -EIO;
        }
        }

        switch (rrsig->rrsig.algorithm) {

        case DNSSEC_ALGORITHM_RSASHA1:
        case DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1:
        case DNSSEC_ALGORITHM_RSASHA256:
        case DNSSEC_ALGORITHM_RSASHA512:
                r = dnssec_rsa_verify(
                                gcry_md_algo_name(md_algorithm),
                                hash, hash_size,
                                rrsig,
                                dnskey);
                break;

        case DNSSEC_ALGORITHM_ECDSAP256SHA256:
        case DNSSEC_ALGORITHM_ECDSAP384SHA384:
                r = dnssec_ecdsa_verify(
                                gcry_md_algo_name(md_algorithm),
                                rrsig->rrsig.algorithm,
                                hash, hash_size,
                                rrsig,
                                dnskey);
                break;
#if GCRYPT_VERSION_NUMBER >= 0x010600
        case DNSSEC_ALGORITHM_ED25519:
                r = dnssec_eddsa_verify(
                                rrsig->rrsig.algorithm,
                                sig_data, sig_size,
                                rrsig,
                                dnskey);
                break;
#endif
        }
        if (r < 0)
                return r;

        /* Now, fix the ttl, expiry, and remember the synthesizing source and the signer */
        if (r > 0)
                dnssec_fix_rrset_ttl(list, n, rrsig, realtime);

        if (r == 0)
                *result = DNSSEC_INVALID;
        else if (wildcard)
                *result = DNSSEC_VALIDATED_WILDCARD;
        else
                *result = DNSSEC_VALIDATED;

        return 0;
}

int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok) {

        assert(rrsig);
        assert(dnskey);

        /* Checks if the specified DNSKEY RR matches the key used for
         * the signature in the specified RRSIG RR */

        if (rrsig->key->type != DNS_TYPE_RRSIG)
                return -EINVAL;

        if (dnskey->key->type != DNS_TYPE_DNSKEY)
                return 0;
        if (dnskey->key->class != rrsig->key->class)
                return 0;
        if ((dnskey->dnskey.flags & DNSKEY_FLAG_ZONE_KEY) == 0)
                return 0;
        if (!revoked_ok && (dnskey->dnskey.flags & DNSKEY_FLAG_REVOKE))
                return 0;
        if (dnskey->dnskey.protocol != 3)
                return 0;
        if (dnskey->dnskey.algorithm != rrsig->rrsig.algorithm)
                return 0;

        if (dnssec_keytag(dnskey, false) != rrsig->rrsig.key_tag)
                return 0;

        return dns_name_equal(dns_resource_key_name(dnskey->key), rrsig->rrsig.signer);
}

int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig) {
        assert(key);
        assert(rrsig);

        /* Checks if the specified RRSIG RR protects the RRSet of the specified RR key. */

        if (rrsig->key->type != DNS_TYPE_RRSIG)
                return 0;
        if (rrsig->key->class != key->class)
                return 0;
        if (rrsig->rrsig.type_covered != key->type)
                return 0;

        return dns_name_equal(dns_resource_key_name(rrsig->key), dns_resource_key_name(key));
}

int dnssec_verify_rrset_search(
                DnsAnswer *a,
                const DnsResourceKey *key,
                DnsAnswer *validated_dnskeys,
                usec_t realtime,
                DnssecResult *result,
                DnsResourceRecord **ret_rrsig) {

        bool found_rrsig = false, found_invalid = false, found_expired_rrsig = false, found_unsupported_algorithm = false;
        DnsResourceRecord *rrsig;
        int r;

        assert(key);
        assert(result);

        /* Verifies all RRs from "a" that match the key "key" against DNSKEYs in "validated_dnskeys" */

        if (!a || a->n_rrs <= 0)
                return -ENODATA;

        /* Iterate through each RRSIG RR. */
        DNS_ANSWER_FOREACH(rrsig, a) {
                DnsResourceRecord *dnskey;
                DnsAnswerFlags flags;

                /* Is this an RRSIG RR that applies to RRs matching our key? */
                r = dnssec_key_match_rrsig(key, rrsig);
                if (r < 0)
                        return r;
                if (r == 0)
                        continue;

                found_rrsig = true;

                /* Look for a matching key */
                DNS_ANSWER_FOREACH_FLAGS(dnskey, flags, validated_dnskeys) {
                        DnssecResult one_result;

                        if ((flags & DNS_ANSWER_AUTHENTICATED) == 0)
                                continue;

                        /* Is this a DNSKEY RR that matches they key of our RRSIG? */
                        r = dnssec_rrsig_match_dnskey(rrsig, dnskey, false);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                continue;

                        /* Take the time here, if it isn't set yet, so
                         * that we do all validations with the same
                         * time. */
                        if (realtime == USEC_INFINITY)
                                realtime = now(CLOCK_REALTIME);

                        /* Yay, we found a matching RRSIG with a matching
                         * DNSKEY, awesome. Now let's verify all entries of
                         * the RRSet against the RRSIG and DNSKEY
                         * combination. */

                        r = dnssec_verify_rrset(a, key, rrsig, dnskey, realtime, &one_result);
                        if (r < 0)
                                return r;

                        switch (one_result) {

                        case DNSSEC_VALIDATED:
                        case DNSSEC_VALIDATED_WILDCARD:
                                /* Yay, the RR has been validated,
                                 * return immediately, but fix up the expiry */
                                if (ret_rrsig)
                                        *ret_rrsig = rrsig;

                                *result = one_result;
                                return 0;

                        case DNSSEC_INVALID:
                                /* If the signature is invalid, let's try another
                                   key and/or signature. After all they
                                   key_tags and stuff are not unique, and
                                   might be shared by multiple keys. */
                                found_invalid = true;
                                continue;

                        case DNSSEC_UNSUPPORTED_ALGORITHM:
                                /* If the key algorithm is
                                   unsupported, try another
                                   RRSIG/DNSKEY pair, but remember we
                                   encountered this, so that we can
                                   return a proper error when we
                                   encounter nothing better. */
                                found_unsupported_algorithm = true;
                                continue;

                        case DNSSEC_SIGNATURE_EXPIRED:
                                /* If the signature is expired, try
                                   another one, but remember it, so
                                   that we can return this */
                                found_expired_rrsig = true;
                                continue;

                        default:
                                assert_not_reached("Unexpected DNSSEC validation result");
                        }
                }
        }

        if (found_expired_rrsig)
                *result = DNSSEC_SIGNATURE_EXPIRED;
        else if (found_unsupported_algorithm)
                *result = DNSSEC_UNSUPPORTED_ALGORITHM;
        else if (found_invalid)
                *result = DNSSEC_INVALID;
        else if (found_rrsig)
                *result = DNSSEC_MISSING_KEY;
        else
                *result = DNSSEC_NO_SIGNATURE;

        if (ret_rrsig)
                *ret_rrsig = NULL;

        return 0;
}

int dnssec_has_rrsig(DnsAnswer *a, const DnsResourceKey *key) {
        DnsResourceRecord *rr;
        int r;

        /* Checks whether there's at least one RRSIG in 'a' that protects RRs of the specified key */

        DNS_ANSWER_FOREACH(rr, a) {
                r = dnssec_key_match_rrsig(key, rr);
                if (r < 0)
                        return r;
                if (r > 0)
                        return 1;
        }

        return 0;
}

static int digest_to_gcrypt_md(uint8_t algorithm) {

        /* Translates a DNSSEC digest algorithm into a gcrypt digest identifier */

        switch (algorithm) {

        case DNSSEC_DIGEST_SHA1:
                return GCRY_MD_SHA1;

        case DNSSEC_DIGEST_SHA256:
                return GCRY_MD_SHA256;

        case DNSSEC_DIGEST_SHA384:
                return GCRY_MD_SHA384;

        default:
                return -EOPNOTSUPP;
        }
}

int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds, bool mask_revoke) {
        uint8_t wire_format[DNS_WIRE_FORMAT_HOSTNAME_MAX];
        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
        gcry_error_t err;
        size_t hash_size;
        int md_algorithm, r;
        void *result;

        assert(dnskey);
        assert(ds);

        /* Implements DNSKEY verification by a DS, according to RFC 4035, section 5.2 */

        if (dnskey->key->type != DNS_TYPE_DNSKEY)
                return -EINVAL;
        if (ds->key->type != DNS_TYPE_DS)
                return -EINVAL;
        if ((dnskey->dnskey.flags & DNSKEY_FLAG_ZONE_KEY) == 0)
                return -EKEYREJECTED;
        if (!mask_revoke && (dnskey->dnskey.flags & DNSKEY_FLAG_REVOKE))
                return -EKEYREJECTED;
        if (dnskey->dnskey.protocol != 3)
                return -EKEYREJECTED;

        if (dnskey->dnskey.algorithm != ds->ds.algorithm)
                return 0;
        if (dnssec_keytag(dnskey, mask_revoke) != ds->ds.key_tag)
                return 0;

        initialize_libgcrypt(false);

        md_algorithm = digest_to_gcrypt_md(ds->ds.digest_type);
        if (md_algorithm < 0)
                return md_algorithm;

        hash_size = gcry_md_get_algo_dlen(md_algorithm);
        assert(hash_size > 0);

        if (ds->ds.digest_size != hash_size)
                return 0;

        r = dns_name_to_wire_format(dns_resource_key_name(dnskey->key), wire_format, sizeof(wire_format), true);
        if (r < 0)
                return r;

        err = gcry_md_open(&md, md_algorithm, 0);
        if (gcry_err_code(err) != GPG_ERR_NO_ERROR || !md)
                return -EIO;

        gcry_md_write(md, wire_format, r);
        if (mask_revoke)
                md_add_uint16(md, dnskey->dnskey.flags & ~DNSKEY_FLAG_REVOKE);
        else
                md_add_uint16(md, dnskey->dnskey.flags);
        md_add_uint8(md, dnskey->dnskey.protocol);
        md_add_uint8(md, dnskey->dnskey.algorithm);
        gcry_md_write(md, dnskey->dnskey.key, dnskey->dnskey.key_size);

        result = gcry_md_read(md, 0);
        if (!result)
                return -EIO;

        return memcmp(result, ds->ds.digest, ds->ds.digest_size) == 0;
}

int dnssec_verify_dnskey_by_ds_search(DnsResourceRecord *dnskey, DnsAnswer *validated_ds) {
        DnsResourceRecord *ds;
        DnsAnswerFlags flags;
        int r;

        assert(dnskey);

        if (dnskey->key->type != DNS_TYPE_DNSKEY)
                return 0;

        DNS_ANSWER_FOREACH_FLAGS(ds, flags, validated_ds) {

                if ((flags & DNS_ANSWER_AUTHENTICATED) == 0)
                        continue;

                if (ds->key->type != DNS_TYPE_DS)
                        continue;
                if (ds->key->class != dnskey->key->class)
                        continue;

                r = dns_name_equal(dns_resource_key_name(dnskey->key), dns_resource_key_name(ds->key));
                if (r < 0)
                        return r;
                if (r == 0)
                        continue;

                r = dnssec_verify_dnskey_by_ds(dnskey, ds, false);
                if (IN_SET(r, -EKEYREJECTED, -EOPNOTSUPP))
                        return 0; /* The DNSKEY is revoked or otherwise invalid, or we don't support the digest algorithm */
                if (r < 0)
                        return r;
                if (r > 0)
                        return 1;
        }

        return 0;
}

static int nsec3_hash_to_gcrypt_md(uint8_t algorithm) {

        /* Translates a DNSSEC NSEC3 hash algorithm into a gcrypt digest identifier */

        switch (algorithm) {

        case NSEC3_ALGORITHM_SHA1:
                return GCRY_MD_SHA1;

        default:
                return -EOPNOTSUPP;
        }
}

int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
        uint8_t wire_format[DNS_WIRE_FORMAT_HOSTNAME_MAX];
        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
        gcry_error_t err;
        size_t hash_size;
        int algorithm;
        void *result;
        int r;

        assert(nsec3);
        assert(name);
        assert(ret);

        if (nsec3->key->type != DNS_TYPE_NSEC3)
                return -EINVAL;

        if (nsec3->nsec3.iterations > NSEC3_ITERATIONS_MAX)
                return log_debug_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
                                       "Ignoring NSEC3 RR %s with excessive number of iterations.",
                                       dns_resource_record_to_string(nsec3));

        algorithm = nsec3_hash_to_gcrypt_md(nsec3->nsec3.algorithm);
        if (algorithm < 0)
                return algorithm;

        initialize_libgcrypt(false);

        hash_size = gcry_md_get_algo_dlen(algorithm);
        assert(hash_size > 0);

        if (nsec3->nsec3.next_hashed_name_size != hash_size)
                return -EINVAL;

        r = dns_name_to_wire_format(name, wire_format, sizeof(wire_format), true);
        if (r < 0)
                return r;

        err = gcry_md_open(&md, algorithm, 0);
        if (gcry_err_code(err) != GPG_ERR_NO_ERROR || !md)
                return -EIO;

        gcry_md_write(md, wire_format, r);
        gcry_md_write(md, nsec3->nsec3.salt, nsec3->nsec3.salt_size);

        result = gcry_md_read(md, 0);
        if (!result)
                return -EIO;

        for (unsigned k = 0; k < nsec3->nsec3.iterations; k++) {
                uint8_t tmp[hash_size];
                memcpy(tmp, result, hash_size);

                gcry_md_reset(md);
                gcry_md_write(md, tmp, hash_size);
                gcry_md_write(md, nsec3->nsec3.salt, nsec3->nsec3.salt_size);

                result = gcry_md_read(md, 0);
                if (!result)
                        return -EIO;
        }

        memcpy(ret, result, hash_size);
        return (int) hash_size;
}

static int nsec3_is_good(DnsResourceRecord *rr, DnsResourceRecord *nsec3) {
        const char *a, *b;
        int r;

        assert(rr);

        if (rr->key->type != DNS_TYPE_NSEC3)
                return 0;

        /* RFC 5155, Section 8.2 says we MUST ignore NSEC3 RRs with flags != 0 or 1 */
        if (!IN_SET(rr->nsec3.flags, 0, 1))
                return 0;

        /* Ignore NSEC3 RRs whose algorithm we don't know */
        if (nsec3_hash_to_gcrypt_md(rr->nsec3.algorithm) < 0)
                return 0;
        /* Ignore NSEC3 RRs with an excessive number of required iterations */
        if (rr->nsec3.iterations > NSEC3_ITERATIONS_MAX)
                return 0;

        /* Ignore NSEC3 RRs generated from wildcards. If these NSEC3 RRs weren't correctly signed we can't make this
         * check (since rr->n_skip_labels_source is -1), but that's OK, as we won't trust them anyway in that case. */
        if (!IN_SET(rr->n_skip_labels_source, 0, UINT8_MAX))
                return 0;
        /* Ignore NSEC3 RRs that are located anywhere else than one label below the zone */
        if (!IN_SET(rr->n_skip_labels_signer, 1, UINT8_MAX))
                return 0;

        if (!nsec3)
                return 1;

        /* If a second NSEC3 RR is specified, also check if they are from the same zone. */

        if (nsec3 == rr) /* Shortcut */
                return 1;

        if (rr->key->class != nsec3->key->class)
                return 0;
        if (rr->nsec3.algorithm != nsec3->nsec3.algorithm)
                return 0;
        if (rr->nsec3.iterations != nsec3->nsec3.iterations)
                return 0;
        if (rr->nsec3.salt_size != nsec3->nsec3.salt_size)
                return 0;
        if (memcmp_safe(rr->nsec3.salt, nsec3->nsec3.salt, rr->nsec3.salt_size) != 0)
                return 0;

        a = dns_resource_key_name(rr->key);
        r = dns_name_parent(&a); /* strip off hash */
        if (r <= 0)
                return r;

        b = dns_resource_key_name(nsec3->key);
        r = dns_name_parent(&b); /* strip off hash */
        if (r <= 0)
                return r;

        /* Make sure both have the same parent */
        return dns_name_equal(a, b);
}

static int nsec3_hashed_domain_format(const uint8_t *hashed, size_t hashed_size, const char *zone, char **ret) {
        _cleanup_free_ char *l = NULL;
        char *j;

        assert(hashed);
        assert(hashed_size > 0);
        assert(zone);
        assert(ret);

        l = base32hexmem(hashed, hashed_size, false);
        if (!l)
                return -ENOMEM;

        j = strjoin(l, ".", zone);
        if (!j)
                return -ENOMEM;

        *ret = j;
        return (int) hashed_size;
}

static int nsec3_hashed_domain_make(DnsResourceRecord *nsec3, const char *domain, const char *zone, char **ret) {
        uint8_t hashed[DNSSEC_HASH_SIZE_MAX];
        int hashed_size;

        assert(nsec3);
        assert(domain);
        assert(zone);
        assert(ret);

        hashed_size = dnssec_nsec3_hash(nsec3, domain, hashed);
        if (hashed_size < 0)
                return hashed_size;

        return nsec3_hashed_domain_format(hashed, (size_t) hashed_size, zone, ret);
}

/* See RFC 5155, Section 8
 * First try to find a NSEC3 record that matches our query precisely, if that fails, find the closest
 * enclosure. Secondly, find a proof that there is no closer enclosure and either a proof that there
 * is no wildcard domain as a direct descendant of the closest enclosure, or find an NSEC3 record that
 * matches the wildcard domain.
 *
 * Based on this we can prove either the existence of the record in @key, or NXDOMAIN or NODATA, or
 * that there is no proof either way. The latter is the case if a proof of non-existence of a given
 * name uses an NSEC3 record with the opt-out bit set. Lastly, if we are given insufficient NSEC3 records
 * to conclude anything we indicate this by returning NO_RR. */
static int dnssec_test_nsec3(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated, uint32_t *ttl) {
        _cleanup_free_ char *next_closer_domain = NULL, *wildcard_domain = NULL;
        const char *zone, *p, *pp = NULL, *wildcard;
        DnsResourceRecord *rr, *enclosure_rr, *zone_rr, *wildcard_rr = NULL;
        DnsAnswerFlags flags;
        int hashed_size, r;
        bool a, no_closer = false, no_wildcard = false, optout = false;

        assert(key);
        assert(result);

        /* First step, find the zone name and the NSEC3 parameters of the zone.
         * it is sufficient to look for the longest common suffix we find with
         * any NSEC3 RR in the response. Any NSEC3 record will do as all NSEC3
         * records from a given zone in a response must use the same
         * parameters. */
        zone = dns_resource_key_name(key);
        for (;;) {
                DNS_ANSWER_FOREACH_FLAGS(zone_rr, flags, answer) {
                        r = nsec3_is_good(zone_rr, NULL);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                continue;

                        r = dns_name_equal_skip(dns_resource_key_name(zone_rr->key), 1, zone);
                        if (r < 0)
                                return r;
                        if (r > 0)
                                goto found_zone;
                }

                /* Strip one label from the front */
                r = dns_name_parent(&zone);
                if (r < 0)
                        return r;
                if (r == 0)
                        break;
        }

        *result = DNSSEC_NSEC_NO_RR;
        return 0;

found_zone:
        /* Second step, find the closest encloser NSEC3 RR in 'answer' that matches 'key' */
        p = dns_resource_key_name(key);
        for (;;) {
                _cleanup_free_ char *hashed_domain = NULL;

                hashed_size = nsec3_hashed_domain_make(zone_rr, p, zone, &hashed_domain);
                if (hashed_size == -EOPNOTSUPP) {
                        *result = DNSSEC_NSEC_UNSUPPORTED_ALGORITHM;
                        return 0;
                }
                if (hashed_size < 0)
                        return hashed_size;

                DNS_ANSWER_FOREACH_FLAGS(enclosure_rr, flags, answer) {

                        r = nsec3_is_good(enclosure_rr, zone_rr);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                continue;

                        if (enclosure_rr->nsec3.next_hashed_name_size != (size_t) hashed_size)
                                continue;

                        r = dns_name_equal(dns_resource_key_name(enclosure_rr->key), hashed_domain);
                        if (r < 0)
                                return r;
                        if (r > 0) {
                                a = flags & DNS_ANSWER_AUTHENTICATED;
                                goto found_closest_encloser;
                        }
                }

                /* We didn't find the closest encloser with this name,
                 * but let's remember this domain name, it might be
                 * the next closer name */

                pp = p;

                /* Strip one label from the front */
                r = dns_name_parent(&p);
                if (r < 0)
                        return r;
                if (r == 0)
                        break;
        }

        *result = DNSSEC_NSEC_NO_RR;
        return 0;

found_closest_encloser:
        /* We found a closest encloser in 'p'; next closer is 'pp' */

        if (!pp) {
                /* We have an exact match! If we area looking for a DS RR, then we must insist that we got the NSEC3 RR
                 * from the parent. Otherwise the one from the child. Do so, by checking whether SOA and NS are
                 * appropriately set. */

                if (key->type == DNS_TYPE_DS) {
                        if (systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_SOA))
                                return -EBADMSG;
                } else {
                        if (systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_NS) &&
                            !systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_SOA))
                                return -EBADMSG;
                }

                /* No next closer NSEC3 RR. That means there's a direct NSEC3 RR for our key. */
                if (systemd_bitmap_isset(enclosure_rr->nsec3.types, key->type))
                        *result = DNSSEC_NSEC_FOUND;
                else if (systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_CNAME))
                        *result = DNSSEC_NSEC_CNAME;
                else
                        *result = DNSSEC_NSEC_NODATA;

                if (authenticated)
                        *authenticated = a;
                if (ttl)
                        *ttl = enclosure_rr->ttl;

                return 0;
        }

        /* Ensure this is not a DNAME domain, see RFC5155, section 8.3. */
        if (systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_DNAME))
                return -EBADMSG;

        /* Ensure that this data is from the delegated domain
         * (i.e. originates from the "lower" DNS server), and isn't
         * just glue records (i.e. doesn't originate from the "upper"
         * DNS server). */
        if (systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_NS) &&
            !systemd_bitmap_isset(enclosure_rr->nsec3.types, DNS_TYPE_SOA))
                return -EBADMSG;

        /* Prove that there is no next closer and whether or not there is a wildcard domain. */

        wildcard = strjoina("*.", p);
        r = nsec3_hashed_domain_make(enclosure_rr, wildcard, zone, &wildcard_domain);
        if (r < 0)
                return r;
        if (r != hashed_size)
                return -EBADMSG;

        r = nsec3_hashed_domain_make(enclosure_rr, pp, zone, &next_closer_domain);
        if (r < 0)
                return r;
        if (r != hashed_size)
                return -EBADMSG;

        DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
                _cleanup_free_ char *next_hashed_domain = NULL;

                r = nsec3_is_good(rr, zone_rr);
                if (r < 0)
                        return r;
                if (r == 0)
                        continue;

                r = nsec3_hashed_domain_format(rr->nsec3.next_hashed_name, rr->nsec3.next_hashed_name_size, zone, &next_hashed_domain);
                if (r < 0)
                        return r;

                r = dns_name_between(dns_resource_key_name(rr->key), next_closer_domain, next_hashed_domain);
                if (r < 0)
                        return r;
                if (r > 0) {
                        if (rr->nsec3.flags & 1)
                                optout = true;

                        a = a && (flags & DNS_ANSWER_AUTHENTICATED);

                        no_closer = true;
                }

                r = dns_name_equal(dns_resource_key_name(rr->key), wildcard_domain);
                if (r < 0)
                        return r;
                if (r > 0) {
                        a = a && (flags & DNS_ANSWER_AUTHENTICATED);

                        wildcard_rr = rr;
                }

                r = dns_name_between(dns_resource_key_name(rr->key), wildcard_domain, next_hashed_domain);
                if (r < 0)
                        return r;
                if (r > 0) {
                        if (rr->nsec3.flags & 1)
                                /* This only makes sense if we have a wildcard delegation, which is
                                 * very unlikely, see RFC 4592, Section 4.2, but we cannot rely on
                                 * this not happening, so hence cannot simply conclude NXDOMAIN as
                                 * we would wish */
                                optout = true;

                        a = a && (flags & DNS_ANSWER_AUTHENTICATED);

                        no_wildcard = true;
                }
        }

        if (wildcard_rr && no_wildcard)
                return -EBADMSG;

        if (!no_closer) {
                *result = DNSSEC_NSEC_NO_RR;
                return 0;
        }

        if (wildcard_rr) {
                /* A wildcard exists that matches our query. */
                if (optout)
                        /* This is not specified in any RFC to the best of my knowledge, but
                         * if the next closer enclosure is covered by an opt-out NSEC3 RR
                         * it means that we cannot prove that the source of synthesis is
                         * correct, as there may be a closer match. */
                        *result = DNSSEC_NSEC_OPTOUT;
                else if (systemd_bitmap_isset(wildcard_rr->nsec3.types, key->type))
                        *result = DNSSEC_NSEC_FOUND;
                else if (systemd_bitmap_isset(wildcard_rr->nsec3.types, DNS_TYPE_CNAME))
                        *result = DNSSEC_NSEC_CNAME;
                else
                        *result = DNSSEC_NSEC_NODATA;
        } else {
                if (optout)
                        /* The RFC only specifies that we have to care for optout for NODATA for
                         * DS records. However, children of an insecure opt-out delegation should
                         * also be considered opt-out, rather than verified NXDOMAIN.
                         * Note that we do not require a proof of wildcard non-existence if the
                         * next closer domain is covered by an opt-out, as that would not provide
                         * any additional information. */
                        *result = DNSSEC_NSEC_OPTOUT;
                else if (no_wildcard)
                        *result = DNSSEC_NSEC_NXDOMAIN;
                else {
                        *result = DNSSEC_NSEC_NO_RR;

                        return 0;
                }
        }

        if (authenticated)
                *authenticated = a;

        if (ttl)
                *ttl = enclosure_rr->ttl;

        return 0;
}

static int dnssec_nsec_wildcard_equal(DnsResourceRecord *rr, const char *name) {
        char label[DNS_LABEL_MAX];
        const char *n;
        int r;

        assert(rr);
        assert(rr->key->type == DNS_TYPE_NSEC);

        /* Checks whether the specified RR has a name beginning in "*.", and if the rest is a suffix of our name */

        if (rr->n_skip_labels_source != 1)
                return 0;

        n = dns_resource_key_name(rr->key);
        r = dns_label_unescape(&n, label, sizeof label, 0);
        if (r <= 0)
                return r;
        if (r != 1 || label[0] != '*')
                return 0;

        return dns_name_endswith(name, n);
}

static int dnssec_nsec_in_path(DnsResourceRecord *rr, const char *name) {
        const char *nn, *common_suffix;
        int r;

        assert(rr);
        assert(rr->key->type == DNS_TYPE_NSEC);

        /* Checks whether the specified nsec RR indicates that name is an empty non-terminal (ENT)
         *
         * A couple of examples:
         *
         *      NSEC             bar →   waldo.foo.bar: indicates that foo.bar exists and is an ENT
         *      NSEC   waldo.foo.bar → yyy.zzz.xoo.bar: indicates that xoo.bar and zzz.xoo.bar exist and are ENTs
         *      NSEC yyy.zzz.xoo.bar →             bar: indicates pretty much nothing about ENTs
         */

        /* First, determine parent of next domain. */
        nn = rr->nsec.next_domain_name;
        r = dns_name_parent(&nn);
        if (r <= 0)
                return r;

        /* If the name we just determined is not equal or child of the name we are interested in, then we can't say
         * anything at all. */
        r = dns_name_endswith(nn, name);
        if (r <= 0)
                return r;

        /* If the name we are interested in is not a prefix of the common suffix of the NSEC RR's owner and next domain names, then we can't say anything either. */
        r = dns_name_common_suffix(dns_resource_key_name(rr->key), rr->nsec.next_domain_name, &common_suffix);
        if (r < 0)
                return r;

        return dns_name_endswith(name, common_suffix);
}

static int dnssec_nsec_from_parent_zone(DnsResourceRecord *rr, const char *name) {
        int r;

        assert(rr);
        assert(rr->key->type == DNS_TYPE_NSEC);

        /* Checks whether this NSEC originates to the parent zone or the child zone. */

        r = dns_name_parent(&name);
        if (r <= 0)
                return r;

        r = dns_name_equal(name, dns_resource_key_name(rr->key));
        if (r <= 0)
                return r;

        /* DNAME, and NS without SOA is an indication for a delegation. */
        if (systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_DNAME))
                return 1;

        if (systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_NS) && !systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_SOA))
                return 1;

        return 0;
}

static int dnssec_nsec_covers(DnsResourceRecord *rr, const char *name) {
        const char *signer;
        int r;

        assert(rr);
        assert(rr->key->type == DNS_TYPE_NSEC);

        /* Checks whether the name is covered by this NSEC RR. This means, that the name is somewhere below the NSEC's
         * signer name, and between the NSEC's two names. */

        r = dns_resource_record_signer(rr, &signer);
        if (r < 0)
                return r;

        r = dns_name_endswith(name, signer); /* this NSEC isn't suitable the name is not in the signer's domain */
        if (r <= 0)
                return r;

        return dns_name_between(dns_resource_key_name(rr->key), name, rr->nsec.next_domain_name);
}

static int dnssec_nsec_generate_wildcard(DnsResourceRecord *rr, const char *name, char **wc) {
        const char *common_suffix1, *common_suffix2, *signer;
        int r, labels1, labels2;

        assert(rr);
        assert(rr->key->type == DNS_TYPE_NSEC);

        /* Generates "Wildcard at the Closest Encloser" for the given name and NSEC RR. */

        r = dns_resource_record_signer(rr, &signer);
        if (r < 0)
                return r;

        r = dns_name_endswith(name, signer); /* this NSEC isn't suitable the name is not in the signer's domain */
        if (r <= 0)
                return r;

        r = dns_name_common_suffix(name, dns_resource_key_name(rr->key), &common_suffix1);
        if (r < 0)
                return r;

        r = dns_name_common_suffix(name, rr->nsec.next_domain_name, &common_suffix2);
        if (r < 0)
                return r;

        labels1 = dns_name_count_labels(common_suffix1);
        if (labels1 < 0)
            return labels1;

        labels2 = dns_name_count_labels(common_suffix2);
        if (labels2 < 0)
            return labels2;

        if (labels1 > labels2)
                r = dns_name_concat("*", common_suffix1, 0, wc);
        else
                r = dns_name_concat("*", common_suffix2, 0, wc);

        if (r < 0)
                return r;

        return 0;
}

int dnssec_nsec_test(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated, uint32_t *ttl) {
        bool have_nsec3 = false, covering_rr_authenticated = false, wildcard_rr_authenticated = false;
        DnsResourceRecord *rr, *covering_rr = NULL, *wildcard_rr = NULL;
        DnsAnswerFlags flags;
        const char *name;
        int r;

        assert(key);
        assert(result);

        /* Look for any NSEC/NSEC3 RRs that say something about the specified key. */

        name = dns_resource_key_name(key);

        DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {

                if (rr->key->class != key->class)
                        continue;

                have_nsec3 = have_nsec3 || (rr->key->type == DNS_TYPE_NSEC3);

                if (rr->key->type != DNS_TYPE_NSEC)
                        continue;

                /* The following checks only make sense for NSEC RRs that are not expanded from a wildcard */
                r = dns_resource_record_is_synthetic(rr);
                if (r == -ENODATA) /* No signing RR known. */
                        continue;
                if (r < 0)
                        return r;
                if (r > 0)
                        continue;

                /* Check if this is a direct match. If so, we have encountered a NODATA case */
                r = dns_name_equal(dns_resource_key_name(rr->key), name);
                if (r < 0)
                        return r;
                if (r == 0) {
                        /* If it's not a direct match, maybe it's a wild card match? */
                        r = dnssec_nsec_wildcard_equal(rr, name);
                        if (r < 0)
                                return r;
                }
                if (r > 0) {
                        if (key->type == DNS_TYPE_DS) {
                                /* If we look for a DS RR and the server sent us the NSEC RR of the child zone
                                 * we have a problem. For DS RRs we want the NSEC RR from the parent */
                                if (systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_SOA))
                                        continue;
                        } else {
                                /* For all RR types, ensure that if NS is set SOA is set too, so that we know
                                 * we got the child's NSEC. */
                                if (systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_NS) &&
                                    !systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_SOA))
                                        continue;
                        }

                        if (systemd_bitmap_isset(rr->nsec.types, key->type))
                                *result = DNSSEC_NSEC_FOUND;
                        else if (systemd_bitmap_isset(rr->nsec.types, DNS_TYPE_CNAME))
                                *result = DNSSEC_NSEC_CNAME;
                        else
                                *result = DNSSEC_NSEC_NODATA;

                        if (authenticated)
                                *authenticated = flags & DNS_ANSWER_AUTHENTICATED;
                        if (ttl)
                                *ttl = rr->ttl;

                        return 0;
                }

                /* Check if the name we are looking for is an empty non-terminal within the owner or next name
                 * of the NSEC RR. */
                r = dnssec_nsec_in_path(rr, name);
                if (r < 0)
                        return r;
                if (r > 0) {
                        *result = DNSSEC_NSEC_NODATA;

                        if (authenticated)
                                *authenticated = flags & DNS_ANSWER_AUTHENTICATED;
                        if (ttl)
                                *ttl = rr->ttl;

                        return 0;
                }

                /* The following two "covering" checks, are not useful if the NSEC is from the parent */
                r = dnssec_nsec_from_parent_zone(rr, name);
                if (r < 0)
                        return r;
                if (r > 0)
                        continue;

                /* Check if this NSEC RR proves the absence of an explicit RR under this name */
                r = dnssec_nsec_covers(rr, name);
                if (r < 0)
                        return r;
                if (r > 0 && (!covering_rr || !covering_rr_authenticated)) {
                        covering_rr = rr;
                        covering_rr_authenticated = flags & DNS_ANSWER_AUTHENTICATED;
                }
        }

        if (covering_rr) {
                _cleanup_free_ char *wc = NULL;
                r = dnssec_nsec_generate_wildcard(covering_rr, name, &wc);
                if (r < 0)
                        return r;

                DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {

                        if (rr->key->class != key->class)
                                continue;

                        if (rr->key->type != DNS_TYPE_NSEC)
                                continue;

                        /* Check if this NSEC RR proves the nonexistence of the wildcard */
                        r = dnssec_nsec_covers(rr, wc);
                        if (r < 0)
                                return r;
                        if (r > 0 && (!wildcard_rr || !wildcard_rr_authenticated)) {
                                wildcard_rr = rr;
                                wildcard_rr_authenticated = flags & DNS_ANSWER_AUTHENTICATED;
                        }
                }
        }

        if (covering_rr && wildcard_rr) {
                /* If we could prove that neither the name itself, nor the wildcard at the closest encloser exists, we
                 * proved the NXDOMAIN case. */
                *result = DNSSEC_NSEC_NXDOMAIN;

                if (authenticated)
                        *authenticated = covering_rr_authenticated && wildcard_rr_authenticated;
                if (ttl)
                        *ttl = MIN(covering_rr->ttl, wildcard_rr->ttl);

                return 0;
        }

        /* OK, this was not sufficient. Let's see if NSEC3 can help. */
        if (have_nsec3)
                return dnssec_test_nsec3(answer, key, result, authenticated, ttl);

        /* No appropriate NSEC RR found, report this. */
        *result = DNSSEC_NSEC_NO_RR;
        return 0;
}

static int dnssec_nsec_test_enclosed(DnsAnswer *answer, uint16_t type, const char *name, const char *zone, bool *authenticated) {
        DnsResourceRecord *rr;
        DnsAnswerFlags flags;
        int r;

        assert(name);
        assert(zone);

        /* Checks whether there's an NSEC/NSEC3 that proves that the specified 'name' is non-existing in the specified
         * 'zone'. The 'zone' must be a suffix of the 'name'. */

        DNS_ANSWER_FOREACH_FLAGS(rr, flags, answer) {
                bool found = false;

                if (rr->key->type != type && type != DNS_TYPE_ANY)
                        continue;

                switch (rr->key->type) {

                case DNS_TYPE_NSEC:

                        /* We only care for NSEC RRs from the indicated zone */
                        r = dns_resource_record_is_signer(rr, zone);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                continue;

                        r = dns_name_between(dns_resource_key_name(rr->key), name, rr->nsec.next_domain_name);
                        if (r < 0)
                                return r;

                        found = r > 0;
                        break;

                case DNS_TYPE_NSEC3: {
                        _cleanup_free_ char *hashed_domain = NULL, *next_hashed_domain = NULL;

                        /* We only care for NSEC3 RRs from the indicated zone */
                        r = dns_resource_record_is_signer(rr, zone);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                continue;

                        r = nsec3_is_good(rr, NULL);
                        if (r < 0)
                                return r;
                        if (r == 0)
                                break;

                        /* Format the domain we are testing with the NSEC3 RR's hash function */
                        r = nsec3_hashed_domain_make(
                                        rr,
                                        name,
                                        zone,
                                        &hashed_domain);
                        if (r < 0)
                                return r;
                        if ((size_t) r != rr->nsec3.next_hashed_name_size)
                                break;

                        /* Format the NSEC3's next hashed name as proper domain name */
                        r = nsec3_hashed_domain_format(
                                        rr->nsec3.next_hashed_name,
                                        rr->nsec3.next_hashed_name_size,
                                        zone,
                                        &next_hashed_domain);
                        if (r < 0)
                                return r;

                        r = dns_name_between(dns_resource_key_name(rr->key), hashed_domain, next_hashed_domain);
                        if (r < 0)
                                return r;

                        found = r > 0;
                        break;
                }

                default:
                        continue;
                }

                if (found) {
                        if (authenticated)
                                *authenticated = flags & DNS_ANSWER_AUTHENTICATED;
                        return 1;
                }
        }

        return 0;
}

static int dnssec_test_positive_wildcard_nsec3(
                DnsAnswer *answer,
                const char *name,
                const char *source,
                const char *zone,
                bool *authenticated) {

        const char *next_closer = NULL;
        int r;

        /* Run a positive NSEC3 wildcard proof. Specifically:
         *
         * A proof that the "next closer" of the generating wildcard does not exist.
         *
         * Note a key difference between the NSEC3 and NSEC versions of the proof. NSEC RRs don't have to exist for
         * empty non-transients. NSEC3 RRs however have to. This means it's sufficient to check if the next closer name
         * exists for the NSEC3 RR and we are done.
         *
         * To prove that a.b.c.d.e.f is rightfully synthesized from a wildcard *.d.e.f all we have to check is that
         * c.d.e.f does not exist. */

        for (;;) {
                next_closer = name;
                r = dns_name_parent(&name);
                if (r <= 0)
                        return r;

                r = dns_name_equal(name, source);
                if (r < 0)
                        return r;
                if (r > 0)
                        break;
        }

        return dnssec_nsec_test_enclosed(answer, DNS_TYPE_NSEC3, next_closer, zone, authenticated);
}

static int dnssec_test_positive_wildcard_nsec(
                DnsAnswer *answer,
                const char *name,
                const char *source,
                const char *zone,
                bool *_authenticated) {

        bool authenticated = true;
        int r;

        /* Run a positive NSEC wildcard proof. Specifically:
         *
         * A proof that there's neither a wildcard name nor a non-wildcard name that is a suffix of the name "name" and
         * a prefix of the synthesizing source "source" in the zone "zone".
         *
         * See RFC 5155, Section 8.8 and RFC 4035, Section 5.3.4
         *
         * Note that if we want to prove that a.b.c.d.e.f is rightfully synthesized from a wildcard *.d.e.f, then we
         * have to prove that none of the following exist:
         *
         *      1) a.b.c.d.e.f
         *      2) *.b.c.d.e.f
         *      3)   b.c.d.e.f
         *      4)   *.c.d.e.f
         *      5)     c.d.e.f
         */

        for (;;) {
                _cleanup_free_ char *wc = NULL;
                bool a = false;

                /* Check if there's an NSEC or NSEC3 RR that proves that the mame we determined is really non-existing,
                 * i.e between the owner name and the next name of an NSEC RR. */
                r = dnssec_nsec_test_enclosed(answer, DNS_TYPE_NSEC, name, zone, &a);
                if (r <= 0)
                        return r;

                authenticated = authenticated && a;

                /* Strip one label off */
                r = dns_name_parent(&name);
                if (r <= 0)
                        return r;

                /* Did we reach the source of synthesis? */
                r = dns_name_equal(name, source);
                if (r < 0)
                        return r;
                if (r > 0) {
                        /* Successful exit */
                        *_authenticated = authenticated;
                        return 1;
                }

                /* Safety check, that the source of synthesis is still our suffix */
                r = dns_name_endswith(name, source);
                if (r < 0)
                        return r;
                if (r == 0)
                        return -EBADMSG;

                /* Replace the label we stripped off with an asterisk */
                wc = strjoin("*.", name);
                if (!wc)
                        return -ENOMEM;

                /* And check if the proof holds for the asterisk name, too */
                r = dnssec_nsec_test_enclosed(answer, DNS_TYPE_NSEC, wc, zone, &a);
                if (r <= 0)
                        return r;

                authenticated = authenticated && a;
                /* In the next iteration we'll check the non-asterisk-prefixed version */
        }
}

int dnssec_test_positive_wildcard(
                DnsAnswer *answer,
                const char *name,
                const char *source,
                const char *zone,
                bool *authenticated) {

        int r;

        assert(name);
        assert(source);
        assert(zone);
        assert(authenticated);

        r = dns_answer_contains_zone_nsec3(answer, zone);
        if (r < 0)
                return r;
        if (r > 0)
                return dnssec_test_positive_wildcard_nsec3(answer, name, source, zone, authenticated);
        else
                return dnssec_test_positive_wildcard_nsec(answer, name, source, zone, authenticated);
}

#else

int dnssec_verify_rrset(
                DnsAnswer *a,
                const DnsResourceKey *key,
                DnsResourceRecord *rrsig,
                DnsResourceRecord *dnskey,
                usec_t realtime,
                DnssecResult *result) {

        return -EOPNOTSUPP;
}

int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey, bool revoked_ok) {

        return -EOPNOTSUPP;
}

int dnssec_key_match_rrsig(const DnsResourceKey *key, DnsResourceRecord *rrsig) {

        return -EOPNOTSUPP;
}

int dnssec_verify_rrset_search(
                DnsAnswer *a,
                const DnsResourceKey *key,
                DnsAnswer *validated_dnskeys,
                usec_t realtime,
                DnssecResult *result,
                DnsResourceRecord **ret_rrsig) {

        return -EOPNOTSUPP;
}

int dnssec_has_rrsig(DnsAnswer *a, const DnsResourceKey *key) {

        return -EOPNOTSUPP;
}

int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds, bool mask_revoke) {

        return -EOPNOTSUPP;
}

int dnssec_verify_dnskey_by_ds_search(DnsResourceRecord *dnskey, DnsAnswer *validated_ds) {

        return -EOPNOTSUPP;
}

int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {

        return -EOPNOTSUPP;
}

int dnssec_nsec_test(DnsAnswer *answer, DnsResourceKey *key, DnssecNsecResult *result, bool *authenticated, uint32_t *ttl) {

        return -EOPNOTSUPP;
}

int dnssec_test_positive_wildcard(
                DnsAnswer *answer,
                const char *name,
                const char *source,
                const char *zone,
                bool *authenticated) {

        return -EOPNOTSUPP;
}

#endif

static const char* const dnssec_result_table[_DNSSEC_RESULT_MAX] = {
        [DNSSEC_VALIDATED]             = "validated",
        [DNSSEC_VALIDATED_WILDCARD]    = "validated-wildcard",
        [DNSSEC_INVALID]               = "invalid",
        [DNSSEC_SIGNATURE_EXPIRED]     = "signature-expired",
        [DNSSEC_UNSUPPORTED_ALGORITHM] = "unsupported-algorithm",
        [DNSSEC_NO_SIGNATURE]          = "no-signature",
        [DNSSEC_MISSING_KEY]           = "missing-key",
        [DNSSEC_UNSIGNED]              = "unsigned",
        [DNSSEC_FAILED_AUXILIARY]      = "failed-auxiliary",
        [DNSSEC_NSEC_MISMATCH]         = "nsec-mismatch",
        [DNSSEC_INCOMPATIBLE_SERVER]   = "incompatible-server",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_result, DnssecResult);

static const char* const dnssec_verdict_table[_DNSSEC_VERDICT_MAX] = {
        [DNSSEC_SECURE]        = "secure",
        [DNSSEC_INSECURE]      = "insecure",
        [DNSSEC_BOGUS]         = "bogus",
        [DNSSEC_INDETERMINATE] = "indeterminate",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_verdict, DnssecVerdict);
