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 #ifndef _NSEC3_TYPES_H
45 #define	_NSEC3_TYPES_H
46 
47 #include <arpa/inet.h>
48 
49 #include <dnscore/ptr_vector.h>
50 #include <dnscore/typebitmap.h>
51 
52 #include <dnsdb/zdb_types.h>
53 #include <dnsdb/nsec3_collection.h>
54 
55 #if !ZDB_HAS_NSEC3_SUPPORT
56 #error "Please do not include nsec3.h if ZDB_HAS_NSEC3_SUPPORT is 0"
57 #endif
58 
59 #ifdef	__cplusplus
60 extern "C"
61 {
62 #endif
63 
64 /*
65  * There is no sense in using more than one.
66  * Two can be a transition state
67  *
68  * This limit is actually used for ICMTL generation
69  * The NSEC3 structure is cheap on memory (every bit count on a TLD) but
70  * there is a price for this.  It is mostly irrelevant, but for ICMTL and
71  * anything trying to get specific NSEC3 rdata bits without knowing the
72  * NSEC3PARAM as well.
73  *
74  */
75 
76 #define MAX_SUPPORTED_NSEC3PARAM    4
77 
78 #define NSEC3_DIGEST_TAG	    0x474944334e	/* N3DIG */
79 #define NSEC3_ZONE_TAG		    0x454e4f5a334e	/* N3ZONE */
80 #define NSEC3_CONTEXT_RECORD_TAG    0x585443334e	/* N3CTX */
81 #define NSEC3_RDATA_TAG		    0x4154414452334e	/* N3RDATA */
82 #define NSEC3_LABELEXT_TAG	    0x54584542414c334e	/* N3LABEXT */
83 #define NSEC3_TYPEBITMAPS_TAG	    0x5350414d4254334e	/* N3TBMAPS */
84 #define NSEC3_LABELPTRARRAY_TAG	    0x595252412a4c334e	/* N3L*ARRY */
85 
86     /** The NSEC3 node with this flag on is scheduled for a processing (ie: signature)
87      *  It is thus FORBIDDEN to delete it (but it MUST be removed from the NSEC3 collection)
88      *
89      *  So instead of a delete the NSEC3_PROPRIETARY_FLAG_DELETED flag should be used and the NSEC3 record has to be put in a
90      *  "scheduled for delete" list.  The schedule being done after the signature the nsec3 record will be effectively removed.
91      *
92      */
93 
94 #define NSEC3_PROPRIETARY_FLAG_SCHEDULED 0x80
95 #define NSEC3_PROPRIETARY_FLAG_DELETED   0x40
96 
97 /**
98  * @note 20161011 edf -- to sum it up :
99  *
100  * 1 byte for the hash
101  * 1 bytes for the flags
102  * 1 byte for the opt-out flag
103  * 2 bytes for the iterations
104  * 1 byte for the salt length
105  * 255 bytes for the salt
106  * 1 byte for the hash len
107  * 255 bytes for the hash
108  * 256 * (1 + 1 +32) bytes for the type bitmap encoding
109  */
110 
111 #define TMP_NSEC3_TTLRDATA_SIZE (1 + 1 + 1 + 2 + 1 + MAX_DOMAIN_LENGTH + 1 + MAX_DOMAIN_LENGTH + TYPE_BIT_MAPS_MAX_RDATA_SIZE)
112 
113 //typedef struct nsec3_node nsec3_zone_item;
114 #define nsec3_zone_item struct nsec3_node
115 
116 typedef nsec3_zone_item** nsec3_zone_item_pointer_array;
117 
118 typedef struct nsec3_label_extension nsec3_label_extension;
119 
120 typedef nsec3_label_extension** nsec3_label_extension_array;
121 
122 /*
123  * Index instead of a pointer.
124  * The relevant information are:
125  *
126  * index
127  * (index+1) MOD count
128  */
129 
130 struct nsec3_label_extension
131 {
132     nsec3_zone_item* _self;
133     nsec3_zone_item* _star;
134 
135     struct nsec3_label_extension *_next;
136 };
137 
nsec3_label_extension_self(const struct nsec3_label_extension * n3le)138 static inline nsec3_zone_item *nsec3_label_extension_self(const struct nsec3_label_extension *n3le)
139 {
140     return n3le->_self;
141 }
142 
nsec3_label_extension_star(const struct nsec3_label_extension * n3le)143 static inline nsec3_zone_item *nsec3_label_extension_star(const struct nsec3_label_extension *n3le)
144 {
145     return n3le->_star;
146 }
147 
nsec3_label_extension_next(const struct nsec3_label_extension * n3le)148 static inline struct nsec3_label_extension *nsec3_label_extension_next(const struct nsec3_label_extension *n3le)
149 {
150     return n3le->_next;
151 }
152 
nsec3_label_extension_set_self(struct nsec3_label_extension * n3le,nsec3_zone_item * self)153 static inline void nsec3_label_extension_set_self(struct nsec3_label_extension *n3le, nsec3_zone_item *self)
154 {
155     n3le->_self = self;
156 }
157 
nsec3_label_extension_set_star(struct nsec3_label_extension * n3le,nsec3_zone_item * star)158 static inline void nsec3_label_extension_set_star(struct nsec3_label_extension *n3le, nsec3_zone_item *star)
159 {
160     n3le->_star = star;
161 }
162 
nsec3_label_extension_set_next(struct nsec3_label_extension * n3le,struct nsec3_label_extension * next)163 static inline void nsec3_label_extension_set_next(struct nsec3_label_extension *n3le, struct nsec3_label_extension *next)
164 {
165     n3le->_next = next;
166 }
167 
nsec3_label_extension_next_ptr(struct nsec3_label_extension * n3le)168 static inline struct nsec3_label_extension **nsec3_label_extension_next_ptr(struct nsec3_label_extension *n3le)
169 {
170     return &n3le->_next;
171 }
172 
173 
174 static inline nsec3_label_extension*
nsec3_label_extension_get_from_label(zdb_rr_label * label,int index)175 nsec3_label_extension_get_from_label(zdb_rr_label *label, int index)
176 {
177     yassert(label != NULL);
178 
179     //yassert(index > 0);
180     nsec3_label_extension *n3e = label->nsec.nsec3;
181     while(index > 0)
182     {
183         yassert(n3e != NULL);
184         n3e = nsec3_label_extension_next(n3e);
185         index--;
186     }
187     return n3e;
188 }
189 
190 /*
191 typedef struct nsec3_zone nsec3_zone;
192 */
193 
194 struct nsec3_zone
195 {
196     struct nsec3_zone*	next;       // next chain
197     nsec3_zone_item* items;         // collection
198     u8 rdata[];                     // NSEC3PARAM head
199 };
200 
201 #define NSEC3PARAM_MINIMUM_LENGTH		5
202 
203 #define NSEC3PARAM_RDATA_ALGORITHM(n3prd)	(((const u8*)(n3prd))[0])
204 #define NSEC3PARAM_RDATA_FLAGS(n3prd)		(((const u8*)(n3prd))[1])
205 #define NSEC3PARAM_RDATA_ITERATIONS_NE(n3prd)	GET_U16_AT(((const u8*)(n3prd))[2]) // network order
206 #define NSEC3PARAM_RDATA_ITERATIONS(n3prd)	NU16(GET_U16_AT(((const u8*)(n3prd))[2])) // network order
207 #define NSEC3PARAM_RDATA_SALT_LEN(n3prd)	(((const u8*)(n3prd))[4])
208 #define NSEC3PARAM_RDATA_SALT(n3prd)		(&((u8*)(n3prd))[NSEC3PARAM_MINIMUM_LENGTH])
209 #define NSEC3PARAM_RDATA_SIZE_FROM_SALT(salt_len) (NSEC3PARAM_MINIMUM_LENGTH + (salt_len))
210 #define NSEC3PARAM_RDATA_SIZE_FROM_RDATA(rdata_bytes_) (NSEC3PARAM_RDATA_SIZE_FROM_SALT(NSEC3PARAM_RDATA_SALT_LEN(rdata_bytes_)))
211 
212 #define NSEC3_ZONE_ALGORITHM(n3_)		    NSEC3PARAM_RDATA_ALGORITHM((n3_)->rdata)
213 #define NSEC3_ZONE_FLAGS(n3_)			    NSEC3PARAM_RDATA_FLAGS((n3_)->rdata)
214 #define NSEC3_ZONE_ITERATIONS(n3_)	        NSEC3PARAM_RDATA_ITERATIONS((n3_)->rdata)
215 #define NSEC3_ZONE_SALT_LEN(n3_)		    NSEC3PARAM_RDATA_SALT_LEN((n3_)->rdata)
216 #define NSEC3_ZONE_SALT(n3_)	    		NSEC3PARAM_RDATA_SALT((n3_)->rdata)
217 
218 #define NSEC3PARAM_DEFAULT_TTL			0
219 
220 /// @note: defined in rfc.h : NSEC3_FLAGS_OPTOUT 0x01
221 
222 #define NSEC3_FLAGS_MARKED_FOR_ICMTL_ADD	0x80   /* DO NOT PUT THIS IN THE RFC
223 							* IT'S PROPRIETARY
224 							*/
225 #define NSEC3_FLAGS_MARKED_FOR_ICMTL_DEL	0x40   /* DO NOT PUT THIS IN THE RFC
226 							* IT'S PROPRIETARY
227 							*/
228 
229 #define NSEC3_ZONE_STRUCT_SIZE_FROM_SALT(salt_len) (sizeof(nsec3_zone) + NSEC3PARAM_RDATA_SIZE_FROM_SALT(salt_len) - 1)
230 
231 #define NSEC3_ZONE_RDATA_SIZE(n3_)		NSEC3PARAM_RDATA_SIZE_FROM_SALT(NSEC3_ZONE_SALT_LEN(n3_))
232 #define NSEC3_ZONE_STRUCT_SIZE(n3_)		NSEC3_ZONE_STRUCT_SIZE_FROM_SALT(NSEC3_ZONE_SALT_LEN(n3_))
233 
234 #define nsec3_zone_get_iterations(n3_)		(ntohs(GET_U16_AT((n3_)->rdata[2])))
235 #define nsec3_zone_set_iterations(n3_,iter_)	(GET_U16_AT((n3_)->rdata[2]) = htons(iter_))
236 
237 #define nsec3_zone_get_item_next(n3_,idx_)	((nsec3_zone_item*)((n3_)->items.data[(idx_+1)%nsec3_zone_get_item_count(n3_)]))
238 
239 #define ZONE_HAS_NSEC3PARAM(zone_) (((zone_)->nsec.nsec3!=NULL) && (zdb_record_find(&(zone_)->apex->resource_record_set, TYPE_NSEC3PARAM)!=NULL))
240 #define ZONE_NSEC3_AVAILABLE(zone_) (zdb_rr_label_flag_isset(((zone_)->apex), ZDB_RR_LABEL_NSEC3|ZDB_RR_LABEL_NSEC3_OPTOUT))
241 
zdb_rr_label_nsec_linked(const zdb_rr_label * label)242 static inline bool zdb_rr_label_nsec_linked(const zdb_rr_label *label)
243 {
244     return (label->_flags & ZDB_RR_LABEL_NSEC) != 0;
245 }
246 
zdb_rr_label_nsec3_linked(const zdb_rr_label * label)247 static inline bool zdb_rr_label_nsec3_linked(const zdb_rr_label *label)
248 {
249     return (label->_flags & ZDB_RR_LABEL_NSEC3) != 0;
250 }
251 
zdb_rr_label_nsec3optout_linked(const zdb_rr_label * label)252 static inline bool zdb_rr_label_nsec3optout_linked(const zdb_rr_label *label)
253 {
254     return (label->_flags & ZDB_RR_LABEL_NSEC3_OPTOUT) != 0;
255 }
256 
zdb_rr_label_nsec3any_linked(const zdb_rr_label * label)257 static inline bool zdb_rr_label_nsec3any_linked(const zdb_rr_label *label)
258 {
259     return (label->_flags & (ZDB_RR_LABEL_NSEC3|ZDB_RR_LABEL_NSEC3_OPTOUT)) != 0;
260 }
261 
nsec3_label_extension_alloc()262 static inline nsec3_label_extension *nsec3_label_extension_alloc()
263 {
264     nsec3_label_extension *n3le;
265     ZALLOC_OBJECT_OR_DIE( n3le, nsec3_label_extension, NSEC3_LABELEXT_TAG); // in nsec3_label_link
266 #if DEBUG
267     memset(n3le, 0xac, sizeof(nsec3_label_extension));
268 #endif
269     return n3le;
270 }
271 
nsec3_label_extension_alloc_list(int count)272 static inline nsec3_label_extension *nsec3_label_extension_alloc_list(int count)
273 {
274     nsec3_label_extension *n3le = nsec3_label_extension_alloc();
275     n3le->_self = NULL;
276     n3le->_star = NULL;
277     nsec3_label_extension *prev = n3le;
278     while(--count > 0)
279     {
280         prev->_next = nsec3_label_extension_alloc();
281         prev = prev->_next;
282         prev->_self = NULL;
283         prev->_star = NULL;
284     }
285     prev->_next = NULL;
286 
287     return n3le;
288 }
289 
nsec3_label_extension_free(nsec3_label_extension * n3le)290 static inline void nsec3_label_extension_free(nsec3_label_extension *n3le)
291 {
292 #if DEBUG
293     memset(n3le, 0xfe, sizeof(nsec3_label_extension));
294 #endif
295     ZFREE(n3le, nsec3_label_extension);
296 }
297 
nsec3param_get_flags(void * rdata_)298 static inline u8 nsec3param_get_flags(void *rdata_)
299 {
300     u8 *rdata = (u8*)rdata_;
301     return rdata[1];
302 }
303 
nsec3param_set_flags(void * rdata_,u8 flags)304 static inline void nsec3param_set_flags(void *rdata_, u8 flags)
305 {
306     u8 *rdata = (u8*)rdata_;
307     rdata[1] = flags;
308 }
309 
310 #ifdef	__cplusplus
311 }
312 #endif
313 
314 #endif	/* _NSEC3_TYPES_H */
315 /** @} */
316