/* 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 "openssl-util.h"
#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h"
#include "sort-util.h"
#include "string-table.h"

#if PREFER_OPENSSL
#  pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(RSA*, RSA_free, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(EC_KEY*, EC_KEY_free, NULL);
#  pragma GCC diagnostic pop
#endif

#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_OPENSSL_OR_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(
                hash_algorithm_t 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) {
        int r;

#if PREFER_OPENSSL
#  pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        _cleanup_(RSA_freep) RSA *rpubkey = NULL;
        _cleanup_(EVP_PKEY_freep) EVP_PKEY *epubkey = NULL;
        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *ctx = NULL;
        _cleanup_(BN_freep) BIGNUM *e = NULL, *m = NULL;

        assert(hash_algorithm);

        e = BN_bin2bn(exponent, exponent_size, NULL);
        if (!e)
                return -EIO;

        m = BN_bin2bn(modulus, modulus_size, NULL);
        if (!m)
                return -EIO;

        rpubkey = RSA_new();
        if (!rpubkey)
                return -ENOMEM;

        if (RSA_set0_key(rpubkey, m, e, NULL) <= 0)
                return -EIO;
        e = m = NULL;

        assert((size_t) RSA_size(rpubkey) == signature_size);

        epubkey = EVP_PKEY_new();
        if (!epubkey)
                return -ENOMEM;

        if (EVP_PKEY_assign_RSA(epubkey, RSAPublicKey_dup(rpubkey)) <= 0)
                return -EIO;

        ctx = EVP_PKEY_CTX_new(epubkey, NULL);
        if (!ctx)
                return -ENOMEM;

        if (EVP_PKEY_verify_init(ctx) <= 0)
                return -EIO;

        if (EVP_PKEY_CTX_set_rsa_padding(ctx, RSA_PKCS1_PADDING) <= 0)
                return -EIO;

        if (EVP_PKEY_CTX_set_signature_md(ctx, hash_algorithm) <= 0)
                return -EIO;

        r = EVP_PKEY_verify(ctx, signature, signature_size, data, data_size);
        if (r < 0)
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "Signature verification failed: 0x%lx", ERR_get_error());

#  pragma GCC diagnostic pop
#else
        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;

        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)
                r = log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                    "RSA signature check failed: %s", gpg_strerror(ge));
        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);
#endif
        return r;
}

static int dnssec_rsa_verify(
                hash_algorithm_t 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(
                hash_algorithm_t hash_algorithm,
                elliptic_curve_t 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) {
        int k;

#if PREFER_OPENSSL
#  pragma GCC diagnostic push
#    pragma GCC diagnostic ignored "-Wdeprecated-declarations"
        _cleanup_(EC_GROUP_freep) EC_GROUP *ec_group = NULL;
        _cleanup_(EC_POINT_freep) EC_POINT *p = NULL;
        _cleanup_(EC_KEY_freep) EC_KEY *eckey = NULL;
        _cleanup_(BN_CTX_freep) BN_CTX *bctx = NULL;
        _cleanup_(BN_freep) BIGNUM *r = NULL, *s = NULL;
        _cleanup_(ECDSA_SIG_freep) ECDSA_SIG *sig = NULL;

        assert(hash_algorithm);

        ec_group = EC_GROUP_new_by_curve_name(curve);
        if (!ec_group)
                return -ENOMEM;

        p = EC_POINT_new(ec_group);
        if (!p)
                return -ENOMEM;

        bctx = BN_CTX_new();
        if (!bctx)
                return -ENOMEM;

        if (EC_POINT_oct2point(ec_group, p, key, key_size, bctx) <= 0)
                return -EIO;

        eckey = EC_KEY_new();
        if (!eckey)
                return -ENOMEM;

        if (EC_KEY_set_group(eckey, ec_group) <= 0)
                return -EIO;

        if (EC_KEY_set_public_key(eckey, p) <= 0)
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "EC_POINT_bn2point failed: 0x%lx", ERR_get_error());

        assert(EC_KEY_check_key(eckey) == 1);

        r = BN_bin2bn(signature_r, signature_r_size, NULL);
        if (!r)
                return -EIO;

        s = BN_bin2bn(signature_s, signature_s_size, NULL);
        if (!s)
                return -EIO;

        /* TODO: We should eventually use the EVP API once it supports ECDSA signature verification */

        sig = ECDSA_SIG_new();
        if (!sig)
                return -ENOMEM;

        if (ECDSA_SIG_set0(sig, r, s) <= 0)
                return -EIO;
        r = s = NULL;

        k = ECDSA_do_verify(data, data_size, sig, eckey);
        if (k < 0)
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "Signature verification failed: 0x%lx", ERR_get_error());

#  pragma GCC diagnostic pop
#else
        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;

        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);
#endif
        return k;
}

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

        elliptic_curve_t curve;
        size_t key_size;
        uint8_t *q;

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

        if (algorithm == DNSSEC_ALGORITHM_ECDSAP256SHA256) {
                curve = OPENSSL_OR_GCRYPT(NID_X9_62_prime256v1, "NIST P-256");  /* NIST P-256 */
                key_size = 32;
        } else if (algorithm == DNSSEC_ALGORITHM_ECDSAP384SHA384) {
                curve = OPENSSL_OR_GCRYPT(NID_secp384r1, "NIST P-384");         /* NIST P-384 */
                key_size = 48;
        } 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);
}

static int dnssec_eddsa_verify_raw(
                elliptic_curve_t curve,
                const uint8_t *signature, size_t signature_size,
                const uint8_t *data, size_t data_size,
                const uint8_t *key, size_t key_size) {

#if PREFER_OPENSSL
        _cleanup_(EVP_PKEY_freep) EVP_PKEY *evkey = NULL;
        _cleanup_(EVP_PKEY_CTX_freep) EVP_PKEY_CTX *pctx = NULL;
        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = NULL;
        int r;

        assert(curve == NID_ED25519);
        assert(signature_size == key_size * 2);

        uint8_t *q = newa(uint8_t, signature_size + 1);
        q[0] = 0x04; /* Prepend 0x04 to indicate an uncompressed key */
        memcpy(q+1, signature, signature_size);

        evkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, key, key_size);
        if (!evkey)
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "EVP_PKEY_new_raw_public_key failed: 0x%lx", ERR_get_error());

        pctx = EVP_PKEY_CTX_new(evkey, NULL);
        if (!pctx)
                return -ENOMEM;

        ctx = EVP_MD_CTX_new();
        if (!ctx)
                return -ENOMEM;

        /* This prevents EVP_DigestVerifyInit from managing pctx and complicating our free logic. */
        EVP_MD_CTX_set_pkey_ctx(ctx, pctx);

        /* One might be tempted to use EVP_PKEY_verify_init, but see Ed25519(7ssl). */
        if (EVP_DigestVerifyInit(ctx, &pctx, NULL, NULL, evkey) <= 0)
                return -EIO;

        r = EVP_DigestVerify(ctx, signature, signature_size, data, data_size);
        if (r < 0)
                return log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                       "Signature verification failed: 0x%lx", ERR_get_error());

        return r;

#elif GCRYPT_VERSION_NUMBER >= 0x010600
        gcry_sexp_t public_key_sexp = NULL, data_sexp = NULL, signature_sexp = NULL;
        gcry_error_t ge;
        int k;

        assert(signature_size == key_size * 2);

        ge = gcry_sexp_build(&signature_sexp,
                             NULL,
                             "(sig-val (eddsa (r %b) (s %b)))",
                             (int) key_size,
                             signature,
                             (int) key_size,
                             signature + key_size);
        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)
                k = log_debug_errno(SYNTHETIC_ERRNO(EIO),
                                    "EdDSA signature check failed: %s", gpg_strerror(ge));
        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;
#else
        return -EOPNOTSUPP;
#endif
}

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

        if (algorithm == DNSSEC_ALGORITHM_ED25519) {
                curve = OPENSSL_OR_GCRYPT(NID_ED25519, "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, rrsig->rrsig.signature_size,
                        data, data_size,
                        dnskey->dnskey.key, key_size);
}

static int md_add_uint8(hash_context_t ctx, uint8_t v) {
#if PREFER_OPENSSL
        return EVP_DigestUpdate(ctx, &v, sizeof(v));
#else
        gcry_md_write(ctx, &v, sizeof(v));
        return 0;
#endif
}

static int md_add_uint16(hash_context_t ctx, uint16_t v) {
        v = htobe16(v);
#if PREFER_OPENSSL
        return EVP_DigestUpdate(ctx, &v, sizeof(v));
#else
        gcry_md_write(ctx, &v, sizeof(v));
        return 0;
#endif
}

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 hash_md_t algorithm_to_implementation_id(uint8_t algorithm) {

        /* Translates a DNSSEC signature algorithm into an openssl/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 OPENSSL_OR_GCRYPT(EVP_sha1(), GCRY_MD_SHA1);

        case DNSSEC_ALGORITHM_RSASHA256:
        case DNSSEC_ALGORITHM_ECDSAP256SHA256:
                return OPENSSL_OR_GCRYPT(EVP_sha256(), GCRY_MD_SHA256);

        case DNSSEC_ALGORITHM_ECDSAP384SHA384:
                return OPENSSL_OR_GCRYPT(EVP_sha384(), GCRY_MD_SHA384);

        case DNSSEC_ALGORITHM_RSASHA512:
                return OPENSSL_OR_GCRYPT(EVP_sha512(), GCRY_MD_SHA512);

        default:
                return OPENSSL_OR_GCRYPT(NULL, -EOPNOTSUPP);
        }
}

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

        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;
}

static int dnssec_rrset_serialize_sig(
                DnsResourceRecord *rrsig,
                const char *source,
                DnsResourceRecord **list,
                size_t list_len,
                bool wildcard,
                char **ret_sig_data,
                size_t *ret_sig_size) {

        _cleanup_free_ char *sig_data = NULL;
        size_t sig_size = 0;
        _cleanup_fclose_ FILE *f = NULL;
        uint8_t wire_format_name[DNS_WIRE_FORMAT_HOSTNAME_MAX];
        DnsResourceRecord *rr;
        int r;

        assert(rrsig);
        assert(source);
        assert(list || list_len == 0);
        assert(ret_sig_data);
        assert(ret_sig_size);

        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 < list_len; 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);
        f = safe_fclose(f);  /* sig_data may be reallocated when f is closed. */
        if (r < 0)
                return r;

        *ret_sig_data = TAKE_PTR(sig_data);
        *ret_sig_size = sig_size;
        return 0;
}

static int dnssec_rrset_verify_sig(
                DnsResourceRecord *rrsig,
                DnsResourceRecord *dnskey,
                const char *sig_data,
                size_t sig_size) {

        assert(rrsig);
        assert(dnskey);
        assert(sig_data);
        assert(sig_size > 0);

        hash_md_t md_algorithm;

#if PREFER_OPENSSL
        uint8_t hash[EVP_MAX_MD_SIZE];
        unsigned hash_size;
#else
        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
        void *hash;
        size_t hash_size;

        initialize_libgcrypt(false);
#endif

        switch (rrsig->rrsig.algorithm) {
        case DNSSEC_ALGORITHM_ED25519:
#if PREFER_OPENSSL || GCRYPT_VERSION_NUMBER >= 0x010600
                return dnssec_eddsa_verify(
                                rrsig->rrsig.algorithm,
                                sig_data, sig_size,
                                rrsig,
                                dnskey);
#endif
        case DNSSEC_ALGORITHM_ED448:
                return -EOPNOTSUPP;
        default:
                /* OK, the RRs are now in canonical order. Let's calculate the digest */
                md_algorithm = algorithm_to_implementation_id(rrsig->rrsig.algorithm);
#if PREFER_OPENSSL
                if (!md_algorithm)
                        return -EOPNOTSUPP;

                _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
                if (!ctx)
                        return -ENOMEM;

                if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
                        return -EIO;

                if (EVP_DigestUpdate(ctx, sig_data, sig_size) <= 0)
                        return -EIO;

                if (EVP_DigestFinal_ex(ctx, hash, &hash_size) <= 0)
                        return -EIO;

                assert(hash_size > 0);

#else
                if (md_algorithm < 0)
                        return md_algorithm;

                gcry_error_t 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;
#endif
        }

        switch (rrsig->rrsig.algorithm) {

        case DNSSEC_ALGORITHM_RSASHA1:
        case DNSSEC_ALGORITHM_RSASHA1_NSEC3_SHA1:
        case DNSSEC_ALGORITHM_RSASHA256:
        case DNSSEC_ALGORITHM_RSASHA512:
                return dnssec_rsa_verify(
                                OPENSSL_OR_GCRYPT(md_algorithm, gcry_md_algo_name(md_algorithm)),
                                hash, hash_size,
                                rrsig,
                                dnskey);

        case DNSSEC_ALGORITHM_ECDSAP256SHA256:
        case DNSSEC_ALGORITHM_ECDSAP384SHA384:
                return dnssec_ecdsa_verify(
                                OPENSSL_OR_GCRYPT(md_algorithm, gcry_md_algo_name(md_algorithm)),
                                rrsig->rrsig.algorithm,
                                hash, hash_size,
                                rrsig,
                                dnskey);

        default:
                assert_not_reached();
        }
}

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

        DnsResourceRecord **list, *rr;
        const char *source, *name;
        _cleanup_free_ char *sig_data = NULL;
        size_t sig_size = 0; /* avoid false maybe-uninitialized warning */
        size_t n = 0;
        bool wildcard;
        int r;

        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);

        r = dnssec_rrset_serialize_sig(rrsig, source, list, n, wildcard,
                                       &sig_data, &sig_size);
        if (r < 0)
                return r;

        r = dnssec_rrset_verify_sig(rrsig, dnskey, sig_data, sig_size);
        if (r == -EOPNOTSUPP) {
                *result = DNSSEC_UNSUPPORTED_ALGORITHM;
                return 0;
        }
        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);

        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 (dns_answer_isempty(a))
                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();
                        }
                }
        }

        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 hash_md_t digest_to_hash_md(uint8_t algorithm) {

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

        switch (algorithm) {

        case DNSSEC_DIGEST_SHA1:
                return OPENSSL_OR_GCRYPT(EVP_sha1(), GCRY_MD_SHA1);

        case DNSSEC_DIGEST_SHA256:
                return OPENSSL_OR_GCRYPT(EVP_sha256(), GCRY_MD_SHA256);

        case DNSSEC_DIGEST_SHA384:
                return OPENSSL_OR_GCRYPT(EVP_sha384(), GCRY_MD_SHA384);

        default:
                return OPENSSL_OR_GCRYPT(NULL, -EOPNOTSUPP);
        }
}

int dnssec_verify_dnskey_by_ds(DnsResourceRecord *dnskey, DnsResourceRecord *ds, bool mask_revoke) {
        uint8_t wire_format[DNS_WIRE_FORMAT_HOSTNAME_MAX];
        int r;

        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;

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

        hash_md_t md_algorithm = digest_to_hash_md(ds->ds.digest_type);

#if PREFER_OPENSSL
        if (!md_algorithm)
                return -EOPNOTSUPP;

        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = NULL;
        uint8_t result[EVP_MAX_MD_SIZE];

        unsigned hash_size = EVP_MD_size(md_algorithm);
        assert(hash_size > 0);

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

        ctx = EVP_MD_CTX_new();
        if (!ctx)
                return -ENOMEM;

        if (EVP_DigestInit_ex(ctx, md_algorithm, NULL) <= 0)
                return -EIO;

        if (EVP_DigestUpdate(ctx, wire_format, r) <= 0)
                return -EIO;

        if (mask_revoke)
                md_add_uint16(ctx, dnskey->dnskey.flags & ~DNSKEY_FLAG_REVOKE);
        else
                md_add_uint16(ctx, dnskey->dnskey.flags);

        r = md_add_uint8(ctx, dnskey->dnskey.protocol);
        if (r <= 0)
                return r;
        r = md_add_uint8(ctx, dnskey->dnskey.algorithm);
        if (r <= 0)
                return r;
        if (EVP_DigestUpdate(ctx, dnskey->dnskey.key, dnskey->dnskey.key_size) <= 0)
                return -EIO;

        if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
                return -EIO;

#else
        if (md_algorithm < 0)
                return -EOPNOTSUPP;

        initialize_libgcrypt(false);

        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;

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

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

        gcry_error_t 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);

        void *result = gcry_md_read(md, 0);
        if (!result)
                return -EIO;
#endif

        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 hash_md_t nsec3_hash_to_hash_md(uint8_t algorithm) {

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

        switch (algorithm) {

        case NSEC3_ALGORITHM_SHA1:
                return OPENSSL_OR_GCRYPT(EVP_sha1(), GCRY_MD_SHA1);

        default:
                return OPENSSL_OR_GCRYPT(NULL, -EOPNOTSUPP);
        }
}

int dnssec_nsec3_hash(DnsResourceRecord *nsec3, const char *name, void *ret) {
        uint8_t wire_format[DNS_WIRE_FORMAT_HOSTNAME_MAX];
        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));

        hash_md_t algorithm = nsec3_hash_to_hash_md(nsec3->nsec3.algorithm);
#if PREFER_OPENSSL
        if (!algorithm)
                return -EOPNOTSUPP;

        size_t hash_size = EVP_MD_size(algorithm);
        assert(hash_size > 0);

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

        _cleanup_(EVP_MD_CTX_freep) EVP_MD_CTX *ctx = EVP_MD_CTX_new();
        if (!ctx)
                return -ENOMEM;

        if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
                return -EIO;

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

        if (EVP_DigestUpdate(ctx, wire_format, r) <= 0)
                return -EIO;
        if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
                return -EIO;

        uint8_t result[EVP_MAX_MD_SIZE];
        if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
                return -EIO;

        for (unsigned k = 0; k < nsec3->nsec3.iterations; k++) {
                if (EVP_DigestInit_ex(ctx, algorithm, NULL) <= 0)
                        return -EIO;
                if (EVP_DigestUpdate(ctx, result, hash_size) <= 0)
                        return -EIO;
                if (EVP_DigestUpdate(ctx, nsec3->nsec3.salt, nsec3->nsec3.salt_size) <= 0)
                        return -EIO;

                if (EVP_DigestFinal_ex(ctx, result, NULL) <= 0)
                        return -EIO;
        }
#else
        if (algorithm < 0)
                return algorithm;

        initialize_libgcrypt(false);

        unsigned 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;

        _cleanup_(gcry_md_closep) gcry_md_hd_t md = NULL;
        gcry_error_t 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);

        void *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;
        }
#endif

        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 PREFER_OPENSSL
        if (!nsec3_hash_to_hash_md(rr->nsec3.algorithm))
                return 0;
#else
        if (nsec3_hash_to_hash_md(rr->nsec3.algorithm) < 0)
                return 0;
#endif

        /* 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);
