1 /*------------------------------------------------------------------------------ 2 * 3 * Copyright (c) 2011-2021, EURid vzw. All rights reserved. 4 * The YADIFA TM software product is provided under the BSD 3-clause license: 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * * Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * * Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * * Neither the name of EURid nor the names of its contributors may be 16 * used to endorse or promote products derived from this software 17 * without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 20 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE 23 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * POSSIBILITY OF SUCH DAMAGE. 30 * 31 *------------------------------------------------------------------------------ 32 * 33 */ 34 35 /** @defgroup nsec3 NSEC3 functions 36 * @ingroup dnsdbdnssec 37 * @brief 38 * 39 * 40 * 41 * @{ 42 */ 43 44 #pragma once 45 46 #include <dnscore/dnsname.h> 47 48 #include <dnscore/nsec3-hash.h> 49 50 #include <dnsdb/zdb_rr_label.h> 51 #include <dnsdb/nsec3_types.h> 52 #include <dnsdb/nsec3_item.h> 53 #include <dnsdb/nsec3_load.h> 54 #include <dnsdb/nsec3_name_error.h> 55 #include <dnsdb/nsec3_nodata_error.h> 56 #include <dnsdb/nsec3_owner.h> 57 #include <dnsdb/nsec3_zone.h> 58 59 /** 60 * Set this to 1 to dump a lot more about the NSEC3 updates/generation. 61 * I use this whenever something weird happens with NSEC3. 62 * (It seems bind is more liberal about handling broken/invalid NSEC3 databases, 63 * YADIFA only accepts valid ones) 64 */ 65 66 #define NSEC3_UPDATE_ZONE_DEBUG 0 67 68 /** 69 * Used to be like this (NSEC3_INCLUDE_ZONE_PATH 1) with older bind 70 * Not anymore in 9.7.1 (probably since 9.7.x) 71 * Set this to 1 to comply with that old bind issue. (not recommended) 72 * 73 */ 74 75 #define NSEC3_INCLUDE_ZONE_PATH 0 76 77 #if !DEBUG 78 #undef NSEC3_UPDATE_ZONE_DEBUG 79 #define NSEC3_UPDATE_ZONE_DEBUG 0 80 #endif 81 82 83 #ifdef __cplusplus 84 extern "C" 85 { 86 #endif 87 88 /* The biggest allowed label is 63 bytes. Let's assume 64. => 89 * Since the digest is base32hex encoded, is un-encoded size is max (64/8)*5 = 40 bytes. 90 * This covers more than a SHA-256 (32 bytes), but it (40) should be the upper bound. 91 */ 92 93 #define MAX_DIGEST_LENGTH 40 94 #define MAX_SALT_LENGTH 255 95 96 #define NSEC3_DIGEST_ALGORITHM_SHA1 1 97 98 #define NSEC3_RDATA_IS_OPTIN(__rdata__) ((((u8*)(__rdata__))[1]&NSEC3_FLAGS_OPTOUT) == 0) 99 #define NSEC3_RDATA_IS_OPTOUT(__rdata__) ((((u8*)(__rdata__))[1]&NSEC3_FLAGS_OPTOUT) != 0) 100 #define NSEC3_RDATA_ALGORITHM(__rdata__) (((u8*)(__rdata__))[0]) 101 #define NSEC3_RDATA_FLAGS(__rdata__) (((u8*)(__rdata__))[1]) 102 #define NSEC3_RDATA_ITERATIONS_NE(__rdata__) (((u16*)(__rdata__))[1]) 103 #define NSEC3_RDATA_ITERATIONS(__rdata__) NU16(NSEC3_RDATA_ITERATIONS_NE(__rdata__)) 104 105 #define TYPE_NSEC3PARAMADD NU16(0xff00) 106 #define TYPE_NSEC3PARAMDEL NU16(0xff01) 107 #define TYPE_NSEC3CHAINSTATE NU16(0xff02) 108 109 /** 110 * 111 * Links a label to already existing nsec3 items 112 * 113 * This function is for when a label has been added "without intelligence". 114 * It will find if the function has got a matching NSEC3 record (by digest) 115 * If so, it will link to it. 116 * 117 * @param n3 118 * @param label 119 * @param fqdn 120 */ 121 122 void nsec3_zone_label_update_chain_links(nsec3_zone *n3, zdb_rr_label* label, int n3_count, u16 coverage_mask, const u8 *fqdn); 123 124 /** 125 * Updates links for the first NSEC3 chain of the zone 126 * Only links to existing NSEC3 records. 127 * Only links label with an extension and self/wild set to NULL 128 * 129 * @param zone 130 */ 131 132 void nsec3_zone_update_chain0_links(zdb_zone *zone); 133 134 void nsec3_destroy_zone(zdb_zone* zone); 135 136 /** 137 * This sets the flags of each NSEC3PARAM of the zone 138 * Please use nsec3_edit_zone_start and nsec3_edit_zone_end 139 * 140 */ 141 142 void nsec3_set_nsec3param_flags(zdb_zone* zone, u8 flags); 143 144 const zdb_rr_label* nsec3_get_closest_provable_encloser( 145 const zdb_rr_label* apex, 146 const_dnslabel_vector_reference sections, 147 s32* sections_topp); 148 /* 149 void nsec3_wild_closest_encloser_proof( 150 const zdb_zone *zone, 151 const dnsname_vector *qname, s32 apex_index, 152 const nsec3_zone_item **wild_closest_provable_encloser_nsec3p); 153 */ 154 void nsec3_wild_closest_encloser_proof( 155 const zdb_zone *zone, 156 const dnsname_vector *qname, s32 apex_index, 157 const nsec3_zone_item **wild_encloser_nsec3p, 158 const nsec3_zone_item **closest_provable_encloser_nsec3p, 159 const nsec3_zone_item **qname_encloser_nsec3p); 160 161 void nsec3_closest_encloser_proof( 162 const zdb_zone *zone, 163 const dnsname_vector *qname, s32 apex_index, 164 const nsec3_zone_item **encloser_nsec3p, 165 const nsec3_zone_item **closest_provable_encloser_nsec3p, 166 const nsec3_zone_item **wild_closest_provable_encloser_nsec3p 167 ); 168 169 /** 170 * Verifies the coherence of the nsec3 database of a zone 171 * 172 * @param zone 173 * 174 */ 175 176 void nsec3_check(zdb_zone *zone); 177 178 /** 179 * For generates the digest label name of an fqdn for a specified NSEC3PARAM chain 180 * 181 * @param n3 the NSEC3PARAM chain 182 * @param fqdn the name to digest 183 * @param fqdn_len the size of the name of the digest 184 * @param out_digest the resulting digest in a Pascal kind of format (1 byte length, then the bytes) 185 * 186 * 1 use (zdb_zone_load) 187 */ 188 189 void nsec3_compute_digest_from_fqdn_with_len(const nsec3_zone *n3, const u8 *fqdn, u32 fqdn_len, u8 *digest, bool isstar); 190 191 ya_result nsec3_get_next_digest_from_rdata(const u8 *rdata, u32 rdata_size, u8 *digest, u32 digest_size); 192 193 // 1 -> 3 -> 9 => 4 194 #define NSEC3_ZONE_DISABLED 0 195 #define NSEC3_ZONE_ENABLED 1 196 #define NSEC3_ZONE_GENERATING 2 197 #define NSEC3_ZONE_REMOVING 4 198 // #define NSEC3_ZONE_REMOVING 8 signing chain 199 200 /** 201 * Sets the NSEC3 maintenance status for a specific chain. 202 * Marks the zone using private records. 203 * 204 * @param zone 205 * @param algorithm 206 * @param optout 207 * @param salt 208 * @param salt_len 209 * @param iterations 210 * @param status 211 * @return 212 */ 213 214 ya_result nsec3_zone_set_status(zdb_zone *zone, u8 secondary_lock, u8 algorithm, u8 optout, u16 iterations, const u8 *salt, u8 salt_len, u8 status); 215 216 /** 217 * Gets the NSEC3 maintenance status for a specific chain. 218 * Get the information from the zone using private records. 219 * 220 * @param zone 221 * @param algorithm 222 * @param optout 223 * @param salt 224 * @param salt_len 225 * @param iterations 226 * @param status 227 * @return 228 */ 229 230 ya_result nsec3_zone_get_status(zdb_zone *zone, u8 algorithm, u8 optout, u16 iterations, const u8 *salt, u8 salt_len, u8 *statusp); 231 232 /** 233 * Gets the NSEC3 maintenance status for a specific chain. 234 * Get the information from the zone using private records. 235 * 236 * The zone must be locked. 237 * 238 * @param zone 239 * @param rdata 240 * @param rdata_size 241 * @param statusp 242 * @return 243 */ 244 245 ya_result nsec3_zone_get_status_from_rdata(zdb_zone *zone, const u8 *rdata, u16 rdata_size, u8 *statusp); 246 247 /** 248 * Returns the number of known chains in the zone. 249 * Inactive chains are also counted. 250 * Zone must be locked. 251 * 252 * @param zone 253 * @return 254 */ 255 256 int nsec3_zone_get_chain_count(zdb_zone *zone); 257 258 /** 259 * Returns pointers to the chains from the zone. 260 * Inactive chains are also counted. 261 * Zone must be locked. 262 * 263 * @param zone 264 * @param n3p 265 * @param max_count 266 * @return 267 */ 268 269 int nsec3_zone_get_chains(zdb_zone *zone, nsec3_zone **n3p, int max_count); 270 271 struct resource_record_view; 272 273 void nsec3_item_resource_record_view_init(struct resource_record_view *rrv); 274 void nsec3_item_resource_record_view_origin_set(struct resource_record_view *rrv, const u8 *origin); 275 void nsec3_item_resource_record_view_nsec3_zone_set(struct resource_record_view *rrv, nsec3_zone *n3); 276 void nsec3_item_resource_record_view_ttl_set(struct resource_record_view *rrv, s32 ttl); 277 void nsec3_item_resource_record_view_item_set(struct resource_record_view *rrv, nsec3_node *item); 278 void nsec3_item_resource_record_finalize(struct resource_record_view *rrv); 279 280 #ifdef __cplusplus 281 } 282 #endif 283 284 /** @} */ 285