]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/unbound/validator/val_sigcrypt.h
unbound: Vendor import 1.19.1
[FreeBSD/FreeBSD.git] / contrib / unbound / validator / val_sigcrypt.h
1 /*
2  * validator/val_sigcrypt.h - validator signature crypto functions.
3  *
4  * Copyright (c) 2007, NLnet Labs. All rights reserved.
5  *
6  * This software is open source.
7  * 
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 
12  * Redistributions of source code must retain the above copyright notice,
13  * this list of conditions and the following disclaimer.
14  * 
15  * Redistributions in binary form must reproduce the above copyright notice,
16  * this list of conditions and the following disclaimer in the documentation
17  * and/or other materials provided with the distribution.
18  * 
19  * Neither the name of the NLNET LABS nor the names of its contributors may
20  * be used to endorse or promote products derived from this software without
21  * specific prior written permission.
22  * 
23  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27  * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
29  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
30  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
31  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
32  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
33  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34  */
35
36 /**
37  * \file
38  *
39  * This file contains helper functions for the validator module.
40  * The functions help with signature verification and checking, the
41  * bridging between RR wireformat data and crypto calls.
42  */
43
44 #ifndef VALIDATOR_VAL_SIGCRYPT_H
45 #define VALIDATOR_VAL_SIGCRYPT_H
46 #include "util/data/packed_rrset.h"
47 #include "sldns/pkthdr.h"
48 #include "sldns/rrdef.h"
49 struct val_env;
50 struct module_env;
51 struct module_qstate;
52 struct ub_packed_rrset_key;
53 struct rbtree_type;
54 struct regional;
55 struct sldns_buffer;
56
57 /** number of entries in algorithm needs array */
58 #define ALGO_NEEDS_MAX 256
59
60 /**
61  * Storage for algorithm needs.  DNSKEY algorithms.
62  */
63 struct algo_needs {
64         /** the algorithms (8-bit) with each a number.
65          * 0: not marked.
66          * 1: marked 'necessary but not yet fulfilled'
67          * 2: marked bogus.
68          * Indexed by algorithm number.
69          */
70         uint8_t needs[ALGO_NEEDS_MAX];
71         /** the number of entries in the array that are unfulfilled */
72         size_t num;
73 };
74
75 /**
76  * Initialize algo needs structure, set algos from rrset as needed.
77  * Results are added to an existing need structure.
78  * @param n: struct with storage.
79  * @param dnskey: algos from this struct set as necessary. DNSKEY set.
80  * @param sigalg: adds to signalled algorithm list too.
81  */
82 void algo_needs_init_dnskey_add(struct algo_needs* n,
83         struct ub_packed_rrset_key* dnskey, uint8_t* sigalg);
84
85 /**
86  * Initialize algo needs structure from a signalled algo list.
87  * @param n: struct with storage.
88  * @param sigalg: signalled algorithm list, numbers ends with 0.
89  */
90 void algo_needs_init_list(struct algo_needs* n, uint8_t* sigalg);
91
92 /**
93  * Initialize algo needs structure, set algos from rrset as needed.
94  * @param n: struct with storage.
95  * @param ds: algos from this struct set as necessary. DS set.
96  * @param fav_ds_algo: filter to use only this DS algo.
97  * @param sigalg: list of signalled algos, constructed as output,
98  *      provide size ALGO_NEEDS_MAX+1. list of algonumbers, ends with a zero.
99  */
100 void algo_needs_init_ds(struct algo_needs* n, struct ub_packed_rrset_key* ds,
101         int fav_ds_algo, uint8_t* sigalg);
102
103 /**
104  * Mark this algorithm as a success, sec_secure, and see if we are done.
105  * @param n: storage structure processed.
106  * @param algo: the algorithm processed to be secure.
107  * @return if true, processing has finished successfully, we are satisfied.
108  */
109 int algo_needs_set_secure(struct algo_needs* n, uint8_t algo);
110
111 /**
112  * Mark this algorithm a failure, sec_bogus.  It can later be overridden
113  * by a success for this algorithm (with a different signature).
114  * @param n: storage structure processed.
115  * @param algo: the algorithm processed to be bogus.
116  */
117 void algo_needs_set_bogus(struct algo_needs* n, uint8_t algo);
118
119 /**
120  * See how many algorithms are missing (not bogus or secure, but not processed)
121  * @param n: storage structure processed.
122  * @return number of algorithms missing after processing.
123  */
124 size_t algo_needs_num_missing(struct algo_needs* n);
125
126 /**
127  * See which algo is missing.
128  * @param n: struct after processing.
129  * @return if 0 an algorithm was bogus, if a number, this algorithm was
130  *   missing.  So on 0, report why that was bogus, on number report a missing
131  *   algorithm.  There could be multiple missing, this reports the first one.
132  */
133 int algo_needs_missing(struct algo_needs* n);
134
135 /**
136  * Format error reason for algorithm missing.
137  * @param env: module env with scratch for temp storage of string.
138  * @param alg: DNSKEY-algorithm missing.
139  * @param reason: destination.
140  * @param s: string, appended with 'with algorithm ..'.
141  */
142 void algo_needs_reason(struct module_env* env, int alg, char** reason, char* s);
143
144 /** 
145  * Check if dnskey matches a DS digest 
146  * Does not check dnskey-keyid footprint, just the digest.
147  * @param env: module environment. Uses scratch space.
148  * @param dnskey_rrset: DNSKEY rrset.
149  * @param dnskey_idx: index of RR in rrset.
150  * @param ds_rrset: DS rrset
151  * @param ds_idx: index of RR in DS rrset.
152  * @return true if it matches, false on error, not supported or no match.
153  */
154 int ds_digest_match_dnskey(struct module_env* env,
155         struct ub_packed_rrset_key* dnskey_rrset, size_t dnskey_idx,
156         struct ub_packed_rrset_key* ds_rrset, size_t ds_idx);
157
158 /** 
159  * Get dnskey keytag, footprint value
160  * @param dnskey_rrset: DNSKEY rrset.
161  * @param dnskey_idx: index of RR in rrset.
162  * @return the keytag or 0 for badly formatted DNSKEYs.
163  */
164 uint16_t dnskey_calc_keytag(struct ub_packed_rrset_key* dnskey_rrset, 
165         size_t dnskey_idx);
166
167 /**
168  * Get DS keytag, footprint value that matches the DNSKEY keytag it signs.
169  * @param ds_rrset: DS rrset
170  * @param ds_idx: index of RR in DS rrset.
171  * @return the keytag or 0 for badly formatted DSs.
172  */ 
173 uint16_t ds_get_keytag(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx);
174
175 /** 
176  * See if DNSKEY algorithm is supported 
177  * @param dnskey_rrset: DNSKEY rrset.
178  * @param dnskey_idx: index of RR in rrset.
179  * @return true if supported.
180  */
181 int dnskey_algo_is_supported(struct ub_packed_rrset_key* dnskey_rrset, 
182         size_t dnskey_idx);
183
184 /**
185  * See if the DNSKEY size at that algorithm is supported.
186  * @param dnskey_rrset: DNSKEY rrset.
187  * @param dnskey_idx: index of RR in rrset.
188  * @return true if supported.
189  */
190 int dnskey_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset,
191         size_t dnskey_idx);
192
193 /**
194  * See if the DNSKEY size at that algorithm is supported for all the
195  * RRs in the DNSKEY RRset.
196  * @param dnskey_rrset: DNSKEY rrset.
197  * @return true if supported.
198  */
199 int dnskeyset_size_is_supported(struct ub_packed_rrset_key* dnskey_rrset);
200
201 /** 
202  * See if DS digest algorithm is supported 
203  * @param ds_rrset: DS rrset
204  * @param ds_idx: index of RR in DS rrset.
205  * @return true if supported.
206  */
207 int ds_digest_algo_is_supported(struct ub_packed_rrset_key* ds_rrset, 
208         size_t ds_idx);
209
210 /**
211  * Get DS RR digest algorithm
212  * @param ds_rrset: DS rrset.
213  * @param ds_idx: which DS.
214  * @return algorithm or 0 if DS too short.
215  */
216 int ds_get_digest_algo(struct ub_packed_rrset_key* ds_rrset, size_t ds_idx);
217
218 /** 
219  * See if DS key algorithm is supported 
220  * @param ds_rrset: DS rrset
221  * @param ds_idx: index of RR in DS rrset.
222  * @return true if supported.
223  */
224 int ds_key_algo_is_supported(struct ub_packed_rrset_key* ds_rrset, 
225         size_t ds_idx);
226
227 /**
228  * Get DS RR key algorithm. This value should match with the DNSKEY algo.
229  * @param k: DS rrset.
230  * @param idx: which DS.
231  * @return algorithm or 0 if DS too short.
232  */
233 int ds_get_key_algo(struct ub_packed_rrset_key* k, size_t idx);
234
235 /**
236  * Get DNSKEY RR signature algorithm
237  * @param k: DNSKEY rrset.
238  * @param idx: which DNSKEY RR.
239  * @return algorithm or 0 if DNSKEY too short.
240  */
241 int dnskey_get_algo(struct ub_packed_rrset_key* k, size_t idx);
242
243 /**
244  * Get DNSKEY RR flags 
245  * @param k: DNSKEY rrset.
246  * @param idx: which DNSKEY RR.
247  * @return flags or 0 if DNSKEY too short.
248  */
249 uint16_t dnskey_get_flags(struct ub_packed_rrset_key* k, size_t idx);
250
251 /** 
252  * Verify rrset against dnskey rrset. 
253  * @param env: module environment, scratch space is used.
254  * @param ve: validator environment, date settings.
255  * @param rrset: to be validated.
256  * @param dnskey: DNSKEY rrset, keyset to try.
257  * @param sigalg: if nonNULL provide downgrade protection otherwise one
258  *   algorithm is enough.
259  * @param reason: if bogus, a string returned, fixed or alloced in scratch.
260  * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
261  * @param section: section of packet where this rrset comes from.
262  * @param qstate: qstate with region.
263  * @param verified: if not NULL the number of RRSIG validations is returned.
264  * @return SECURE if one key in the set verifies one rrsig.
265  *      UNCHECKED on allocation errors, unsupported algorithms, malformed data,
266  *      and BOGUS on verification failures (no keys match any signatures).
267  */
268 enum sec_status dnskeyset_verify_rrset(struct module_env* env, 
269         struct val_env* ve, struct ub_packed_rrset_key* rrset, 
270         struct ub_packed_rrset_key* dnskey, uint8_t* sigalg,
271         char** reason, sldns_ede_code *reason_bogus,
272         sldns_pkt_section section, struct module_qstate* qstate, int* verified);
273
274
275 /** 
276  * verify rrset against one specific dnskey (from rrset) 
277  * @param env: module environment, scratch space is used.
278  * @param ve: validator environment, date settings.
279  * @param rrset: to be validated.
280  * @param dnskey: DNSKEY rrset, keyset.
281  * @param dnskey_idx: which key from the rrset to try.
282  * @param reason: if bogus, a string returned, fixed or alloced in scratch.
283  * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure.
284  * @param section: section of packet where this rrset comes from.
285  * @param qstate: qstate with region.
286  * @return secure if *this* key signs any of the signatures on rrset.
287  *      unchecked on error or and bogus on bad signature.
288  */
289 enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve,
290         struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
291         size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus,
292         sldns_pkt_section section, struct module_qstate* qstate);
293
294 /** 
295  * verify rrset, with specific dnskey(from set), for a specific rrsig 
296  * @param region: scratch region used for temporary allocation.
297  * @param buf: scratch buffer used for canonicalized rrset data.
298  * @param ve: validator environment, date settings.
299  * @param now: current time for validation (can be overridden).
300  * @param rrset: to be validated.
301  * @param dnskey: DNSKEY rrset, keyset.
302  * @param dnskey_idx: which key from the rrset to try.
303  * @param sig_idx: which signature to try to validate.
304  * @param sortree: pass NULL at start, the sorted rrset order is returned.
305  *      pass it again for the same rrset.
306  * @param buf_canon: if true, the buffer is already canonical.
307  *      pass false at start. pass old value only for same rrset and same
308  *      signature (but perhaps different key) for reuse.
309  * @param reason: if bogus, a string returned, fixed or alloced in scratch.
310  * @param reason_bogus: EDE (8914) code paired with the reason of failure.
311  * @param section: section of packet where this rrset comes from.
312  * @param qstate: qstate with region.
313  * @return secure if this key signs this signature. unchecked on error or 
314  *      bogus if it did not validate.
315  */
316 enum sec_status dnskey_verify_rrset_sig(struct regional* region,
317         struct sldns_buffer* buf, struct val_env* ve, time_t now,
318         struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey,
319         size_t dnskey_idx, size_t sig_idx,
320         struct rbtree_type** sortree, int* buf_canon,
321         char** reason, sldns_ede_code *reason_bogus,
322         sldns_pkt_section section, struct module_qstate* qstate);
323
324 /**
325  * canonical compare for two tree entries
326  */
327 int canonical_tree_compare(const void* k1, const void* k2);
328
329 /**
330  * Compare two rrsets and see if they are the same, canonicalised.
331  * The rrsets are not altered.
332  * @param region: temporary region.
333  * @param k1: rrset1
334  * @param k2: rrset2
335  * @return true if equal.
336  */
337 int rrset_canonical_equal(struct regional* region,
338         struct ub_packed_rrset_key* k1, struct ub_packed_rrset_key* k2);
339
340 /**
341  * Canonicalize an rrset into the buffer.  For an auth zone record, so
342  * this does not use a signature, or the RRSIG TTL or the wildcard label
343  * count from the RRSIG.
344  * @param region: temporary region.
345  * @param buf: the buffer to use.
346  * @param k: the rrset to insert.
347  * @return false on alloc error.
348  */
349 int rrset_canonicalize_to_buffer(struct regional* region,
350         struct sldns_buffer* buf, struct ub_packed_rrset_key* k);
351
352 #endif /* VALIDATOR_VAL_SIGCRYPT_H */