From 5a3bb649bc20aa8621330b1616184dae64788f2e Mon Sep 17 00:00:00 2001 From: Lubos Slovak <lubos.slovak@nic.cz> Date: Tue, 8 Oct 2013 16:12:27 +0200 Subject: [PATCH] Moved node to NSEC3 connecting to node adjusting. Saves one iteration over the zone + properly sets NSEC3 references when disabling NSEC3. refs #4 --- src/libknot/dnssec/zone-nsec.c | 126 ++++++++----------------------- src/libknot/dnssec/zone-nsec.h | 31 ++++---- src/libknot/zone/zone-contents.c | 126 ++++++++++++------------------- 3 files changed, 94 insertions(+), 189 deletions(-) diff --git a/src/libknot/dnssec/zone-nsec.c b/src/libknot/dnssec/zone-nsec.c index c8fea7066..577f6f638 100644 --- a/src/libknot/dnssec/zone-nsec.c +++ b/src/libknot/dnssec/zone-nsec.c @@ -434,43 +434,6 @@ static knot_dname_t *nsec3_hash_to_dname(const uint8_t *hash, size_t hash_size, return dname; } -/*! - * \brief Create NSEC3 owner name from regular owner name. - * - * \param owner Node owner name. - * \param params Params for NSEC3 hashing function. - * \param apex Apex size. - * \param apex_size Size of the zone apex. - * - * \return NSEC3 owner name, NULL in case of error. - */ -static knot_dname_t *create_nsec3_owner(const knot_dname_t *owner, - const knot_nsec3_params_t *params, - const char *apex, size_t apex_size) -{ - assert(owner); - assert(params); - assert(apex); - - uint8_t *hash = NULL; - size_t hash_size = 0; - int name_size = knot_dname_size(owner); - - if (name_size < 0) { - return NULL; - } - - if (knot_nsec3_hash(params, owner, name_size, &hash, &hash_size) - != KNOT_EOK) { - return NULL; - } - - knot_dname_t *result = nsec3_hash_to_dname(hash, hash_size, apex, apex_size); - free(hash); - - return result; -} - /* - NSEC3 nodes construction ---------------------------------------------- */ /*! @@ -862,6 +825,36 @@ static bool get_zone_soa_min_ttl(const knot_zone_contents_t *zone, /* - public API ------------------------------------------------------------ */ +/*! + * \brief Create NSEC3 owner name from regular owner name. + */ +knot_dname_t *create_nsec3_owner(const knot_dname_t *owner, + const knot_nsec3_params_t *params, + const char *apex, size_t apex_size) +{ + if (owner == NULL || params == NULL || apex == NULL) { + return NULL; + } + + uint8_t *hash = NULL; + size_t hash_size = 0; + int name_size = knot_dname_size(owner); + + if (name_size < 0) { + return NULL; + } + + if (knot_nsec3_hash(params, owner, name_size, &hash, &hash_size) + != KNOT_EOK) { + return NULL; + } + + knot_dname_t *result = nsec3_hash_to_dname(hash, hash_size, apex, apex_size); + free(hash); + + return result; +} + /*! * \brief Create NSEC or NSEC3 chain in the zone. */ @@ -894,62 +887,3 @@ int knot_zone_create_nsec_chain(const knot_zone_contents_t *zone, // Sign newly created records right away return knot_zone_sign_nsecs_in_changeset(zone_keys, policy, changeset); } - -/*! - * \brief Connect regular and NSEC3 nodes in the zone. - */ -int knot_zone_connect_nsec_nodes(knot_zone_contents_t *zone) -{ - if (!zone) { - return KNOT_EINVAL; - } - - if (!is_nsec3_enabled(zone)) { - return KNOT_EOK; - } - - char *apex; - size_t apex_size; - if (!get_zone_apex_str(zone, &apex, &apex_size)) { - return KNOT_ENOMEM; - } - - bool sorted = false; - hattrie_iter_t *it = hattrie_iter_begin(zone->nodes, sorted); - if (!it) { - free(apex); - return KNOT_ENOMEM; - } - - int result = KNOT_EOK; - - while (!hattrie_iter_finished(it)) { - knot_node_t *node = (knot_node_t *)*hattrie_iter_val(it); - - knot_dname_t *nsec3_name; - nsec3_name = create_nsec3_owner(node->owner, - &zone->nsec3_params, apex, - apex_size); - if (!nsec3_name) { - result = KNOT_ENOMEM; - break; - } - - knot_node_t *nsec3_node = NULL; - result = knot_zone_tree_get(zone->nsec3_nodes, nsec3_name, - &nsec3_node); - if (result != KNOT_EOK) { - break; - } - - node->nsec3_node = nsec3_node; - - knot_dname_free(&nsec3_name); - hattrie_iter_next(it); - } - - free(apex); - hattrie_iter_free(it); - - return result; -} diff --git a/src/libknot/dnssec/zone-nsec.h b/src/libknot/dnssec/zone-nsec.h index 491f45f6e..0cea6944d 100644 --- a/src/libknot/dnssec/zone-nsec.h +++ b/src/libknot/dnssec/zone-nsec.h @@ -44,6 +44,20 @@ */ bool is_nsec3_enabled(const knot_zone_contents_t *zone); +/*! + * \brief Create NSEC3 owner name from regular owner name. + * + * \param owner Node owner name. + * \param params Params for NSEC3 hashing function. + * \param apex Apex name. + * \param apex_size Size of the zone apex name. + * + * \return NSEC3 owner name, NULL in case of error. + */ +knot_dname_t *create_nsec3_owner(const knot_dname_t *owner, + const knot_nsec3_params_t *params, + const char *apex, size_t apex_size); + /*! * \brief Create NSEC or NSEC3 chain in the zone. * @@ -57,23 +71,6 @@ int knot_zone_create_nsec_chain(const knot_zone_contents_t *zone, const knot_zone_keys_t *zone_keys, const knot_dnssec_policy_t *policy); -/*! - * \brief Connect regular and NSEC3 nodes in the zone. - * - * \note No need to call this function after 'knot_zone_create_nsec_chain'. - * \note Exits succesfully if NSEC3 is not enabled. - * \note Skips nodes with missing related NSEC3 nodes. - * - * \param zone Zone for which the operation is performed. - * - * \return Error code, KNOT_EOK if successful. - * - * \todo IMPORTANT: this is called always when zone adjusting is. IMHO it can - * be moved back into zone adjusting as before commit bb795a4. This only - * leads to confusion and duplication of code. - */ -int knot_zone_connect_nsec_nodes(knot_zone_contents_t *zone); - #endif // _KNOT_DNSSEC_ZONE_NSEC_H_ /*! @} */ diff --git a/src/libknot/zone/zone-contents.c b/src/libknot/zone/zone-contents.c index dc33e4d09..97ebbd508 100644 --- a/src/libknot/zone/zone-contents.c +++ b/src/libknot/zone/zone-contents.c @@ -128,6 +128,37 @@ static void knot_zone_contents_destroy_node_rrsets_from_tree( knot_node_free(tnode); } +/*----------------------------------------------------------------------------*/ + +static int knot_zone_contents_nsec3_name(const knot_zone_contents_t *zone, + const knot_dname_t *name, + knot_dname_t **nsec3_name) +{ + assert(nsec3_name != NULL); + *nsec3_name = NULL; + + const knot_nsec3_params_t *nsec3_params = + knot_zone_contents_nsec3params(zone); + + if (nsec3_params == NULL) { + return KNOT_ENSEC3PAR; + } + + const knot_dname_t *apex_name = knot_node_owner( + knot_zone_contents_apex(zone)); + assert(apex_name); + + *nsec3_name = create_nsec3_owner(name, nsec3_params, + (const char *)apex_name, + knot_dname_size(apex_name)); + if (nsec3_name == NULL) { + return KNOT_ERROR; + } + + return KNOT_EOK; +} + + /*----------------------------------------------------------------------------*/ /*! @@ -192,6 +223,24 @@ static void knot_zone_contents_adjust_normal_node(knot_node_t **tnode, if (!knot_node_is_non_auth(node) && knot_node_rrset_count(node) > 0) { args->previous_node = node; } + + // Connect to NSEC3 node (only if NSEC3 tree is not empty) + knot_node_t *nsec3 = NULL; + knot_dname_t *nsec3_name = NULL; + int ret = knot_zone_contents_nsec3_name(args->zone, + knot_node_owner(node), + &nsec3_name); + if (ret == KNOT_EOK) { + assert(nsec3_name); + knot_zone_tree_get(args->zone->nsec3_nodes, nsec3_name, &nsec3); + knot_node_set_nsec3_node(node, nsec3); + } else if (ret == KNOT_ENSEC3PAR) { + knot_node_set_nsec3_node(node, NULL); + } else { + args->err = ret; + } + + knot_dname_free(&nsec3_name); } /*----------------------------------------------------------------------------*/ @@ -225,79 +274,6 @@ static void knot_zone_contents_adjust_nsec3_node(knot_node_t **tnode, knot_node_set_previous(node, args->previous_node); args->previous_node = node; } - -/*----------------------------------------------------------------------------*/ - -static int knot_zone_contents_nsec3_name(const knot_zone_contents_t *zone, - const knot_dname_t *name, - knot_dname_t **nsec3_name) -{ - assert(nsec3_name != NULL); - - *nsec3_name = NULL; - - const knot_nsec3_params_t *nsec3_params = - knot_zone_contents_nsec3params(zone); - - if (nsec3_params == NULL) { - return KNOT_ENSEC3PAR; - } - - uint8_t *hashed_name = NULL; - size_t hash_size = 0; - - int res = knot_nsec3_hash(nsec3_params, name, knot_dname_size(name), - &hashed_name, &hash_size); - - if (res != 0) { - char *n = knot_dname_to_str(name); - dbg_zone("Error while hashing name %s.\n", n); - free(n); - return KNOT_ECRYPTO; - } - - dbg_zone("Hash: "); - dbg_zone_hex((char *)hashed_name, hash_size); - dbg_zone("\n"); - - uint8_t *name_b32 = NULL; - size_t size = base32hex_encode_alloc(hashed_name, hash_size, - &name_b32); - - if (size == 0) { - char *n = knot_dname_to_str(name); - free(n); - free(name_b32); - return KNOT_ECRYPTO; - } - - assert(name_b32 != NULL); - free(hashed_name); - - /* Will be returned to caller, make sure it is released after use. */ - *nsec3_name = knot_dname_from_str((char *)name_b32, size); - - free(name_b32); - - if (*nsec3_name == NULL) { - return KNOT_ERROR; - } - - knot_dname_to_lower(*nsec3_name); - - assert(zone->apex->owner != NULL); - knot_dname_t *ret = knot_dname_cat(*nsec3_name, zone->apex->owner); - - if (ret == NULL) { - free(*nsec3_name); - return KNOT_ERROR; - } - - *nsec3_name = ret; - - return KNOT_EOK; -} - /*----------------------------------------------------------------------------*/ /*! * \brief Tries to find the given domain name in the zone tree. @@ -1355,9 +1331,7 @@ int knot_zone_contents_adjust(knot_zone_contents_t *zone, assert(zone->apex == adjust_arg.first_node); - // connect NSEC3 nodes - - return knot_zone_connect_nsec_nodes(zone); + return KNOT_EOK; } /*----------------------------------------------------------------------------*/ -- GitLab