/*! \brief Clears wildcard child if set in parent node. */ static void fix_wildcard_child(zone_node_t *node, const knot_dname_t *owner) { if ((node->flags & NODE_FLAGS_WILDCARD_CHILD) && knot_dname_is_wildcard(owner)) { node->flags &= ~NODE_FLAGS_WILDCARD_CHILD; } }
static int adjust_pointers(zone_node_t **tnode, void *data) { assert(data != NULL); assert(tnode != NULL); zone_adjust_arg_t *args = (zone_adjust_arg_t *)data; zone_node_t *node = *tnode; // remember first node if (args->first_node == NULL) { args->first_node = node; } // clear Removed NSEC flag so that no relicts remain node->flags &= ~NODE_FLAGS_REMOVED_NSEC; // check if this node is not a wildcard child of its parent if (knot_dname_is_wildcard(node->owner)) { assert(node->parent != NULL); node->parent->flags |= NODE_FLAGS_WILDCARD_CHILD; } // set flags (delegation point, non-authoritative) if (node->parent && ((node->parent->flags & NODE_FLAGS_DELEG) || node->parent->flags & NODE_FLAGS_NONAUTH)) { node->flags |= NODE_FLAGS_NONAUTH; } else if (node_rrtype_exists(node, KNOT_RRTYPE_NS) && node != args->zone->apex) { node->flags |= NODE_FLAGS_DELEG; } else { // Default. node->flags = NODE_FLAGS_AUTH; } // set pointer to previous node node->prev = args->previous_node; // update remembered previous pointer only if authoritative if (!(node->flags & NODE_FLAGS_NONAUTH) && node->rrset_count > 0) { args->previous_node = node; } return KNOT_EOK; }
static int zone_contents_add_node(zone_contents_t *zone, zone_node_t *node, bool create_parents) { if (zone == NULL || node == NULL) { return KNOT_EINVAL; } int ret = 0; if ((ret = zone_contents_check_node(zone, node)) != 0) { dbg_zone("Node check failed.\n"); return ret; } ret = zone_tree_insert(zone->nodes, node); if (ret != KNOT_EOK) { dbg_zone("Failed to insert node into zone tree.\n"); return ret; } if (!create_parents) { return KNOT_EOK; } dbg_zone_detail("Creating parents of the node.\n"); /* No parents for root domain. */ if (*node->owner == '\0') return KNOT_EOK; zone_node_t *next_node = NULL; const uint8_t *parent = knot_wire_next_label(node->owner, NULL); if (knot_dname_cmp(zone->apex->owner, parent) == 0) { dbg_zone_detail("Zone apex is the parent.\n"); node_set_parent(node, zone->apex); // check if the node is not wildcard child of the parent if (knot_dname_is_wildcard(node->owner)) { zone->apex->flags |= NODE_FLAGS_WILDCARD_CHILD; } } else { while (parent != NULL && !(next_node = zone_contents_get_node(zone, parent))) { /* Create a new node. */ dbg_zone_detail("Creating new node.\n"); next_node = node_new(parent, NULL); if (next_node == NULL) { return KNOT_ENOMEM; } /* Insert node to a tree. */ dbg_zone_detail("Inserting new node to zone tree.\n"); ret = zone_tree_insert(zone->nodes, next_node); if (ret != KNOT_EOK) { node_free(&next_node, NULL); return ret; } /* Update node pointers. */ node_set_parent(node, next_node); if (knot_dname_is_wildcard(node->owner)) { next_node->flags |= NODE_FLAGS_WILDCARD_CHILD; } dbg_zone_detail("Next parent.\n"); node = next_node; parent = knot_wire_next_label(parent, NULL); } // set the found parent (in the zone) as the parent of the last // inserted node assert(node->parent == NULL); node_set_parent(node, next_node); dbg_zone_detail("Created all parents.\n"); } return KNOT_EOK; }
int kr_rrset_validate_with_key(const knot_pkt_t *pkt, knot_section_t section_id, const knot_rrset_t *covered, const knot_rrset_t *keys, size_t key_pos, const struct dseckey *key, const knot_dname_t *zone_name, uint32_t timestamp, bool has_nsec3) { struct dseckey *created_key = NULL; if (key == NULL) { const knot_rdata_t *krr = knot_rdataset_at(&keys->rrs, key_pos); int ret = kr_dnssec_key_from_rdata(&created_key, keys->owner, knot_rdata_data(krr), knot_rdata_rdlen(krr)); if (ret != 0) { return ret; } key = created_key; } uint16_t keytag = dnssec_key_get_keytag((dnssec_key_t *)key); int covered_labels = knot_dname_labels(covered->owner, NULL); if (knot_dname_is_wildcard(covered->owner)) { /* The asterisk does not count, RFC4034 3.1.3, paragraph 3. */ --covered_labels; } const knot_pktsection_t *sec = knot_pkt_section(pkt, section_id); for (unsigned i = 0; i < sec->count; ++i) { /* Consider every RRSIG that matches owner and covers the class/type. */ const knot_rrset_t *rrsig = knot_pkt_rr(sec, i); if (rrsig->type != KNOT_RRTYPE_RRSIG) { continue; } if ((covered->rclass != rrsig->rclass) || !knot_dname_is_equal(covered->owner, rrsig->owner)) { continue; } for (uint16_t j = 0; j < rrsig->rrs.rr_count; ++j) { int val_flgs = 0; int trim_labels = 0; if (knot_rrsig_type_covered(&rrsig->rrs, j) != covered->type) { continue; } if (validate_rrsig_rr(&val_flgs, covered_labels, rrsig, j, keys, key_pos, keytag, zone_name, timestamp) != 0) { continue; } if (val_flgs & FLG_WILDCARD_EXPANSION) { trim_labels = wildcard_radix_len_diff(covered->owner, rrsig, j); if (trim_labels < 0) { break; } } if (kr_check_signature(rrsig, j, (dnssec_key_t *) key, covered, trim_labels) != 0) { continue; } if (val_flgs & FLG_WILDCARD_EXPANSION) { int ret = 0; if (!has_nsec3) { ret = kr_nsec_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner); } else { ret = kr_nsec3_wildcard_answer_response_check(pkt, KNOT_AUTHORITY, covered->owner, trim_labels - 1); } if (ret != 0) { continue; } } /* Validated with current key, OK */ kr_dnssec_key_free(&created_key); return kr_ok(); } } /* No applicable key found, cannot be validated. */ kr_dnssec_key_free(&created_key); return kr_error(ENOENT); }