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