#include <libknot/rrset.h>
#include <libknot/rrtype/nsec.h>
#include <libknot/rrtype/rrsig.h>
-#include <dnssec/error.h>
#include "lib/defines.h"
#include "lib/dnssec/nsec.h"
return kr_nsec_existence_denied(flags) ? kr_ok() : kr_error(ENOENT);
}
-
-int kr_nsec_ref_to_unsigned(const knot_pkt_t *pkt)
-{
- int nsec_found = 0;
- uint8_t *bm = NULL;
- uint16_t bm_size = 0;
- const knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_AUTHORITY);
- if (!sec) {
- return kr_error(EINVAL);
- }
- for (unsigned i = 0; i < sec->count; ++i) {
- const knot_rrset_t *ns = knot_pkt_rr(sec, i);
- if (ns->type == KNOT_RRTYPE_DS) {
- return kr_error(EEXIST);
- }
- if (ns->type != KNOT_RRTYPE_NS) {
- continue;
- }
- nsec_found = 0;
- for (unsigned j = 0; j < sec->count; ++j) {
- const knot_rrset_t *nsec = knot_pkt_rr(sec, j);
- if (nsec->type == KNOT_RRTYPE_DS) {
- return kr_error(EEXIST);
- }
- if (nsec->type != KNOT_RRTYPE_NSEC) {
- continue;
- }
- /* nsec found
- * check if owner name matches the delegation name
- */
- if (knot_dname_is_equal(nsec->owner, ns->owner)) {
- /* nsec does not match the delegation */
- continue;
- }
- nsec_found = 1;
- knot_nsec_bitmap(&nsec->rrs, &bm, &bm_size);
- if (!bm) {
- return kr_error(EINVAL);
- }
- if (kr_nsec_bitmap_contains_type(bm, bm_size,
- KNOT_RRTYPE_NS) &&
- !kr_nsec_bitmap_contains_type(bm, bm_size,
- KNOT_RRTYPE_DS) &&
- !kr_nsec_bitmap_contains_type(bm, bm_size,
- KNOT_RRTYPE_SOA)) {
- /* rfc4035, 5.2 */
- return kr_ok();
- }
- }
- if (nsec_found) {
- /* nsec which owner matches
- * the delegation name was found,
- * but nsec type bitmap contains wrong types
- */
- return kr_error(EINVAL);
- } else {
- /* nsec that matches delegation was not found */
- return kr_error(DNSSEC_NOT_FOUND);
- }
- }
-
- return kr_error(EINVAL);
-}
*/
int kr_nsec_existence_denial(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname, uint16_t stype);
-
-/**
- * Referral to unsigned subzone check (RFC4035 5.2).
- * @note No RRSIGs are validated.
- * @param pkt Packet structure to be processed.
- * @return 0 or error code:
- * DNSSEC_NOT_FOUND - neither ds nor nsec records
- * were not found.
- * EEXIST - ds record was found.
- * EINVAL - bogus.
- */
-int kr_nsec_ref_to_unsigned(const knot_pkt_t *pkt);
return ret;
}
-int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt)
-{
- int ret = kr_error(EINVAL);
- int flags = 0;
- uint8_t *bm = NULL;
- uint16_t bm_size = 0;
- const knot_pktsection_t *sec = knot_pkt_section(pkt, KNOT_AUTHORITY);
- if (!sec) {
- return kr_error(EINVAL);
- }
- for (unsigned i = 0; i < sec->count; ++i) {
- const knot_rrset_t *ns = knot_pkt_rr(sec, i);
- if (ns->type == KNOT_RRTYPE_DS) {
- return kr_error(EEXIST);
- }
- if (ns->type != KNOT_RRTYPE_NS) {
- continue;
- }
- flags = 0;
- for (unsigned j = 0; j < sec->count; ++j) {
- const knot_rrset_t *nsec3 = knot_pkt_rr(sec, j);
- if (nsec3->type == KNOT_RRTYPE_DS) {
- return kr_error(EEXIST);
- }
- if (nsec3->type != KNOT_RRTYPE_NSEC3) {
- continue;
- }
- /* nsec3 found, check if owner name matches
- * the delegation name
- */
- ret = matches_name(&flags, nsec3, ns->owner);
- if (ret != 0) {
- return kr_error(EINVAL);
- }
- if (!(flags & FLG_NAME_MATCHED)) {
- /* nsec3 owner name does not match
- * the delegation name
- */
- continue;
- }
- knot_nsec3_bitmap(&nsec3->rrs, 0, &bm, &bm_size);
- if (!bm) {
- return kr_error(EINVAL);
- }
- if (kr_nsec_bitmap_contains_type(bm, bm_size,
- KNOT_RRTYPE_NS) &&
- !kr_nsec_bitmap_contains_type(bm, bm_size,
- KNOT_RRTYPE_DS) &&
- !kr_nsec_bitmap_contains_type(bm, bm_size,
- KNOT_RRTYPE_SOA)) {
- /* Satisfies rfc5155, 8.9. paragraph 2 */
- return kr_ok();
- }
- }
- if (flags & FLG_NAME_MATCHED) {
- /* nsec3 which owner matches
- * the delegation name was found,
- * but nsec3 type bitmap contains wrong types
- */
- return kr_error(EINVAL);
- }
- /* nsec3 that matches the delegation was not found.
- * Check rfc5155, 8.9. paragraph 4.
- * Find closest provable encloser.
- */
- const knot_dname_t *encloser_name = NULL;
- const knot_rrset_t *covering_next_nsec3 = NULL;
- ret = closest_encloser_proof(pkt, KNOT_AUTHORITY, ns->owner, &encloser_name,
- NULL, &covering_next_nsec3);
- if (ret != 0) {
- return kr_error(EINVAL);
- }
-
- if (has_optout(covering_next_nsec3)) {
- return kr_error(DNSSEC_NOT_FOUND);
- } else {
- return kr_error(EINVAL);
- }
- }
- return kr_error(EINVAL);
-}
-
*/
int kr_nsec3_no_data(const knot_pkt_t *pkt, knot_section_t section_id,
const knot_dname_t *sname, uint16_t stype);
-
-/**
- * Referral to unsigned subzone check (RFC5155 8.9).
- * @note No RRSIGs are validated.
- * @param pkt Packet structure to be processed.
- * @return 0 or error code:
- * DNSSEC_NOT_FOUND - denial of existence can't be proven
- * due to opt-out.
- * EEXIST - ds record was found.
- * EINVAL - bogus.
- */
-int kr_nsec3_ref_to_unsigned(const knot_pkt_t *pkt);
* If it contains neither, the referral is bogus (or an attempted downgrade attack).
*/
+ /* Aggregate DS records (if using multiple keys) */
unsigned section = KNOT_ANSWER;
if (!knot_wire_get_aa(answer->wire)) { /* Referral */
section = KNOT_AUTHORITY;
return kr_ok();
}
+ /* No DS provided, check for proof of non-existence. */
int ret = 0;
const knot_dname_t *proved_name = knot_pkt_qname(answer);
- /* Aggregate DS records (if using multiple keys) */
knot_rrset_t *new_ds = update_ds(cut, knot_pkt_section(answer, section));
if (!new_ds) {
- /* No DS provided, check for proof of non-existence. */
if (!has_nsec3) {
- if (!knot_wire_get_aa(answer->wire)) {
- /* Referral, check if it is referral to unsigned, rfc4035 5.2 */
- ret = kr_nsec_ref_to_unsigned(answer);
- } else {
- /* No-data answer */
- ret = kr_nsec_existence_denial(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
- }
+ ret = kr_nsec_existence_denial(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
} else {
- if (!knot_wire_get_aa(answer->wire)) {
- /* Referral, check if it is referral to unsigned, rfc5155 8.9 */
- ret = kr_nsec3_ref_to_unsigned(answer);
- } else {
- /* No-data answer, QTYPE is DS, rfc5155 8.6 */
- ret = kr_nsec3_no_data(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
- }
+ ret = kr_nsec3_no_data(answer, KNOT_AUTHORITY, proved_name, KNOT_RRTYPE_DS);
if (ret == kr_error(DNSSEC_NOT_FOUND)) {
- /* Not bogus, going insecure due to optout */
+ /* Not bogus, but going insecure */
ret = 0;
}
}