/*! \file */
+#include <inttypes.h>
+
#include <isc/mem.h>
#include <isc/util.h>
#define DNS_EDE_VALID(v) ISC_MAGIC_VALID(v, DNS_EDE_MAGIC)
static bool
-dns__ede_checkandupdateedeused(dns_edectx_t *edectx, uint16_t code) {
- if (edectx->edeused & (1 << code)) {
+dns__ede_checkandupdateedeused(dns_edectx_t *edectx, dns_edecode_t code) {
+ if (edectx->edeused & (UINT64_C(1) << code)) {
return true;
}
- edectx->edeused |= 1 << code;
+ edectx->edeused |= UINT64_C(1) << code;
return false;
}
#pragma once
+#include <inttypes.h>
+
#include <isc/mem.h>
+#include <isc/util.h>
#include <dns/message.h>
/*%< EDNS0 extended DNS errors */
-enum {
+typedef enum ISC_FIXED_ENUM(dns_edecode, uint16_t) {
+ // typedef enum ISC_FIXED_ENUM(dns_edecode, uint16_t) {
DNS_EDE_OTHER = 0, /*%< Other Error */
DNS_EDE_DNSKEYALG = 1, /*%< Unsupported DNSKEY Algorithm */
DNS_EDE_DSDIGESTTYPE = 2, /*%< Unsupported DS Digest Type */
DNS_EDE_NOREACHABLEAUTH = 22, /*%< No Reachable Authority */
DNS_EDE_NETWORKERROR = 23, /*%< Network Error */
DNS_EDE_INVALIDDATA = 24, /*%< Invalid Data */
- DNS_EDE_MAX_CODE
-};
+ DNS_EDE_NTA = 33, /*%< Negative Trust Anchor */
+ DNS_EDE_MAX_CODE,
+ DNS_EDE_ENFORCE = UINT16_MAX, /*%< Enforce uint16_t size */
+} dns_edecode_t;
+
+STATIC_ASSERT(sizeof(dns_edecode_t) == sizeof(uint16_t),
+ "dns_edecode_t is not uint16_t sized");
/*
* From RFC 8914:
int magic;
isc_mem_t *mctx;
dns_ednsopt_t *ede[DNS_EDE_MAX_ERRORS];
- uint32_t edeused;
+ uint64_t edeused;
size_t nextede;
};
/*%<
* the response client message.
*/
+STATIC_ASSERT(DNS_EDE_MAX_CODE <=
+ CHAR_BIT * sizeof(((dns_edectx_t *){ NULL })->edeused),
+ "DNS_EDE_MAX_CODE does not fit in the edeused bitmap");
+/*
+ * Make sure we can fit the currently supported EDE codes in the edeused bitmap.
+ */
+
void
dns_ede_init(isc_mem_t *mctx, dns_edectx_t *edectx);
/*%<
static bool
issecuredomain(fetchctx_t *fctx, const dns_name_t *name, dns_rdatatype_t type,
- isc_stdtime_t now, bool *ntap) {
+ isc_stdtime_t now) {
dns_name_t suffix;
unsigned int labels;
+ bool secure_domain, nta = false;
/*
* For DS variants we need to check fom the parent domain,
name = &suffix;
}
- return dns_view_issecuredomain(fctx->res->view, name, now,
- CHECKNTA(fctx), ntap);
+ secure_domain = dns_view_issecuredomain(fctx->res->view, name, now,
+ CHECKNTA(fctx), &nta);
+
+ /*
+ * A covering negative trust anchor suppressed DNSSEC validation for
+ * an otherwise secure name (RFC 7646). Disclose that to the client
+ * via an Extended DNS Error (draft-farrokhi-dnsop-ede-nta). Duplicate
+ * codes are coalesced by dns_ede_add(), so this is emitted at most
+ * once per fetch.
+ */
+ if (nta) {
+ dns_ede_add(&fctx->edectx, DNS_EDE_NTA,
+ "Negative Trust Anchor applied (RFC 7646)");
+ }
+
+ return secure_domain;
}
static isc_result_t
/*
* Is DNSSEC validation required for this name?
*/
- bool secure_domain = issecuredomain(fctx, name, fctx->type, rctx->now,
- NULL);
+ bool secure_domain = issecuredomain(fctx, name, fctx->type, rctx->now);
bool need_validation = secure_domain &&
((fctx->options & DNS_FETCHOPT_NOVALIDATE) == 0);
/*
* Is DNSSEC validation required for this name?
*/
- bool secure_domain = issecuredomain(fctx, name, fctx->type, rctx->now,
- NULL);
+ bool secure_domain = issecuredomain(fctx, name, fctx->type, rctx->now);
bool need_validation = secure_domain &&
((fctx->options & DNS_FETCHOPT_NOVALIDATE) == 0);
secure_domain = issecuredomain(fctx, name,
dns_rdatatype_ds,
- fctx->now, NULL);
+ fctx->now);
if (secure_domain) {
rdataset->trust =
dns_trust_pending_answer;
#else /* __has_builtin(__builtin_types_compatible_p) */
#define ISC_TYPES_COMPATIBLE(x, y) 1
#endif /* __has_builtin(__builtin_types_compatible_p) */
+
+/* clang-format off */
+/*
+ * This needs some extra plumbing for non-C23 compilers, see
+ * lib/dns/include/dns/ede.h:dns_edecode_t for example.
+ */
+#if defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+#define ISC_FIXED_ENUM(name, type) name: type
+#else
+#define ISC_FIXED_ENUM(name, type) __attribute__((__packed__)) name
+#endif
+/* clang-format on */