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 /**
36 * @defgroup dnskey DNSSEC keys functions
37 * @ingroup dnscorednssec
38 * @addtogroup dnskey DNSKEY functions
39 * @brief
40 *
41 *
42 * @{
43 */
44
45 #include "dnscore/dnskey-signature.h"
46 #include "dnscore/dnskey.h"
47 #include "dnscore/logger.h"
48
49 #define MODULE_MSG_HANDLE g_system_logger
50
51 #define DEBUG_CRYPTO_INTERNALS 0
52
53 #if DEBUG_CRYPTO_INTERNALS
54 #pragma message("WARNING: DEBUG_CRYPTO_INTERNALS is not set to 0")
55 #endif
56
57 #if DEBUG_CRYPTO_INTERNALS
58 #define DNSKEY_SIGN_TIME_LENIENCY 0
59 #else
60 #define DNSKEY_SIGN_TIME_LENIENCY 86400
61 #endif
62
63 struct dnskey_signature_header
64 {
65 // this part MUST match the 18 bytes of wire image of an RRSIG
66
67 u16 type_covered;
68 u8 algorithm;
69 u8 labels;
70 s32 original_ttl;
71
72 u32 expiration;
73 u32 inception; // 16 bytes
74 u16 tag; // 18
75 u8 fqdn_signature[];
76 };
77
78 union dnskey_signature_header_storage
79 {
80 u8 rdata[RRSIG_RDATA_HEADER_LEN + 256 + 2048];
81 struct dnskey_signature_header header;
82 };
83
84 struct dnskey_signature_tctr
85 {
86 u16 rtype;
87 u16 rclass;
88 s32 ttl;
89 u16 rdata_size;
90 };
91
92 static int
dnskey_signature_canonize_sort_record_view_rdata_compare(const void * a,const void * b,void * c)93 dnskey_signature_canonize_sort_record_view_rdata_compare(const void *a, const void *b, void *c)
94 {
95 const u8* ptr_a = (const u8*)a;
96 const u8* ptr_b = (const u8*)b;
97 resource_record_view *view = (resource_record_view*)c;
98
99 u16 rr_a_size = view->vtbl->get_rdata_size(view->data, ptr_a);
100 u16 rr_b_size = view->vtbl->get_rdata_size(view->data, ptr_b);
101
102 int ret;
103
104 int diff_len = rr_a_size;
105 diff_len -= rr_b_size;
106
107 const u8 *rr_a_rdata = view->vtbl->get_rdata(view->data, ptr_a);
108 const u8 *rr_b_rdata = view->vtbl->get_rdata(view->data, ptr_b);
109
110 if(diff_len != 0)
111 {
112 u16 len = MIN(rr_a_size, rr_b_size);
113
114 ret = memcmp(rr_a_rdata, rr_b_rdata, len);
115
116 if(ret == 0)
117 {
118 ret = diff_len;
119 }
120 }
121 else
122 {
123 ret = memcmp(rr_a_rdata, rr_b_rdata, rr_a_size);
124 }
125
126 return ret;
127 }
128
129 void
dnskey_signature_init(dnskey_signature * ds)130 dnskey_signature_init(dnskey_signature *ds)
131 {
132 ZEROMEMORY(ds, sizeof(*ds));
133 }
134
dnskey_signature_set_validity(dnskey_signature * ds,time_t from,time_t to)135 void dnskey_signature_set_validity(dnskey_signature *ds, time_t from, time_t to)
136 {
137 if(from != ds->inception)
138 {
139 ds->inception = (u32)from;
140 ds->has_digest = 0;
141 ds->inception_set = 1;
142 }
143 if(to != ds->expiration)
144 {
145 ds->expiration = (u32)to;
146 ds->has_digest = 0;
147 ds->expiration_set = 1;
148 }
149 }
150
151 void
dnskey_signature_set_view(dnskey_signature * ds,resource_record_view * view)152 dnskey_signature_set_view(dnskey_signature *ds, resource_record_view *view)
153 {
154 ds->rr_view = view;
155 ds->is_canonised = 0;
156 ds->has_digest = 0;
157 }
158
159 void
dnskey_signature_set_rrset_reference(dnskey_signature * ds,ptr_vector * rrset)160 dnskey_signature_set_rrset_reference(dnskey_signature *ds, ptr_vector *rrset)
161 {
162 ds->rrset_reference = rrset;
163 ds->is_canonised = 0;
164 ds->has_digest = 0;
165 }
166
167 void
dnskey_signature_set_canonised(dnskey_signature * ds,bool canonised)168 dnskey_signature_set_canonised(dnskey_signature *ds, bool canonised)
169 {
170 ds->is_canonised = canonised?1:0;
171 }
172
173 /**
174 * out_rrsig_rr points to a mallocated dns_resource_record
175 */
176
177 ya_result
dnskey_signature_sign(dnskey_signature * ds,const dnssec_key * key,void ** out_rrsig_rr)178 dnskey_signature_sign(dnskey_signature *ds, const dnssec_key *key, void **out_rrsig_rr)
179 {
180 u8 *signature;
181 const void *rr0;
182 const u8 *fqdn;
183 size_t fqdn_len;
184 const u8* owner_fqdn;
185 size_t owner_fqdn_len;
186 digest_s *ctx_ptr = &ds->digest_ctx;
187 ya_result ret;
188 struct dnskey_signature_tctr tctr;
189 u8 fqdn_buffer[256];
190
191 union dnskey_signature_header_storage hdr;
192
193 if(key == NULL)
194 {
195 return INVALID_ARGUMENT_ERROR; // no key
196 }
197
198 if(!dnskey_is_private(key))
199 {
200 return DNSSEC_ERROR_KEYRING_KEY_IS_NOT_PRIVATE; // not private
201 }
202
203 if((ds->rrset_reference == NULL) || (ptr_vector_size(ds->rrset_reference) == 0))
204 {
205 return INVALID_ARGUMENT_ERROR; // empty set
206 }
207
208 #if DEBUG || DEBUG_CRYPTO_INTERNALS
209 memset(&hdr, 0xf5, sizeof(hdr));
210 #endif
211
212 time_t inception = ds->inception;
213 time_t expiration = ds->expiration/*dnskey_get_inactive_epoch(key)*/;
214
215 u8 key_algorithm = dnskey_get_algorithm(key);
216
217 if(key_algorithm != ds->key_algorithm)
218 {
219 ds->has_digest = 0;
220 }
221
222 ptr_vector *rrset = ds->rrset_reference;
223 const resource_record_view_vtbl *view_vtbl = ds->rr_view->vtbl;
224 void *data = ds->rr_view->data;
225
226 if(!ds->has_digest)
227 {
228 if(FAIL(ret = dnskey_digest_init(ctx_ptr, key_algorithm)))
229 {
230 return ret;
231 }
232
233 rr0 = ptr_vector_get(rrset, 0);
234
235 fqdn_len = dnsname_canonize(view_vtbl->get_fqdn(data, rr0), fqdn_buffer);
236 fqdn = fqdn_buffer;
237 //dnsname_len(fqdn);
238 hdr.header.labels = 0;
239
240 if((fqdn[0] == 1) && (fqdn[1] == (u8)'*'))
241 {
242 fqdn += *fqdn + 1;
243 }
244
245 while(fqdn[0] != 0)
246 {
247 ++hdr.header.labels;
248 fqdn += *fqdn + 1;
249 }
250
251 fqdn = fqdn_buffer;
252
253 owner_fqdn = dnskey_get_domain(key);
254 owner_fqdn_len = dnsname_len(owner_fqdn);
255
256 if(!ds->is_canonised)
257 {
258 ptr_vector_qsort_r(rrset, dnskey_signature_canonize_sort_record_view_rdata_compare, ds->rr_view);
259 ds->is_canonised = 1;
260 }
261
262 hdr.header.type_covered = view_vtbl->get_type(data, rr0);
263 hdr.header.algorithm = dnskey_get_algorithm(key);
264 // hdr.header.labels has already been set
265 hdr.header.original_ttl = htonl(view_vtbl->get_ttl(data, rr0));
266 hdr.header.expiration = ntohl(expiration);
267 hdr.header.inception = ntohl(inception);
268 hdr.header.tag = htons(dnskey_get_tag_const(key));
269 memcpy(&hdr.header.fqdn_signature[0], owner_fqdn, owner_fqdn_len); // VS false positive: more than enough room has been allocated on the stack
270 signature = &hdr.header.fqdn_signature[owner_fqdn_len];
271
272 tctr.rtype = hdr.header.type_covered;
273 tctr.rclass = view_vtbl->get_class(data, rr0);
274 tctr.ttl = hdr.header.original_ttl;
275
276 size_t hdr_size = signature - (u8*)&hdr;
277
278 #if DEBUG_CRYPTO_INTERNALS
279 log_debug("dnskey_signature_sign: digest for %{dnsname} %{dnstype} and key tag %i", owner_fqdn, &hdr.header.type_covered, dnskey_get_tag_const(key));
280 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, &hdr, hdr_size, 32);
281 #endif
282
283 digest_update(ctx_ptr, &hdr, hdr_size);
284
285 for(int i = 0; i <= ptr_vector_last_index(rrset); ++i)
286 {
287 const void *rr = ptr_vector_get(rrset, i);
288 digest_update(ctx_ptr, fqdn, fqdn_len);
289
290 u16 rdata_size = view_vtbl->get_rdata_size(data, rr);
291 tctr.rdata_size = htons(rdata_size);
292
293 const void *rdata = view_vtbl->get_rdata(data, rr);
294
295 #if DEBUG_CRYPTO_INTERNALS
296 rdata_desc rdd = {tctr.rtype, rdata_size, rdata};
297 log_debug("dnskey_signature_sign: #%i: %{dnsname} %i %{dnsclass} %{typerdatadesc}",
298 i, fqdn, ntohl(tctr.ttl), &tctr.rclass, &rdd);
299 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, fqdn, fqdn_len, 32);
300 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, &tctr, 2 + 2 + 4 + 2, 32);
301 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, rdata, rdata_size, 32);
302 #endif
303 digest_update(ctx_ptr, &tctr, 2 + 2 + 4 + 2);
304 digest_update(ctx_ptr, rdata, rdata_size);
305 }
306
307 s32 digest_size = digest_get_size(ctx_ptr);
308
309 //digest_final_copy_bytes(ctx_ptr, ds->digest_buffer, sizeof(ds->digest_buffer));
310 digest_final(ctx_ptr);
311
312 #if DEBUG_CRYPTO_INTERNALS
313 log_debug("dnskey_signature_sign: digest value");
314 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, digest_get_digest_ptr(ctx_ptr), digest_size, 32);
315 #endif
316
317 ds->digest_size = digest_size;
318 ds->has_digest = 1;
319 }
320 else
321 {
322 // digest has already been computed, only need to ready the signature,
323 // the rr0 and the fqdn
324
325 #if DEBUG_CRYPTO_INTERNALS
326 log_debug("dnskey_signature_sign: digest already computed");
327 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, digest_get_digest_ptr(ctx_ptr), ds->digest_size, 32);
328 #endif
329
330 owner_fqdn = dnskey_get_domain(key);
331 owner_fqdn_len = dnsname_len(owner_fqdn);
332 signature = &hdr.header.fqdn_signature[owner_fqdn_len];
333 rr0 = ptr_vector_get(rrset, 0);
334 fqdn = view_vtbl->get_fqdn(data, rr0);
335
336 tctr.rtype = view_vtbl->get_type(data, rr0);
337 tctr.rclass = view_vtbl->get_class(data, rr0);
338 tctr.ttl = htonl(view_vtbl->get_ttl(data, rr0));
339 }
340
341 void *digest_ptr;
342 digest_get_digest(ctx_ptr, &digest_ptr);
343 s32 signature_size = key->vtbl->dnssec_key_sign_digest(key, digest_ptr, ds->digest_size, signature);
344
345 if(ISOK(signature_size))
346 {
347 #if DEBUG_CRYPTO_INTERNALS
348 log_debug("dnskey_signature_sign: signature value");
349 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, signature, signature_size, 32);
350 #endif
351
352 u16 rrsig_rdata_size = RRSIG_RDATA_HEADER_LEN + owner_fqdn_len + signature_size;
353
354 void *rrsig_rr = view_vtbl->new_instance(data, fqdn, TYPE_RRSIG, tctr.rclass, view_vtbl->get_ttl(data, rr0), rrsig_rdata_size, hdr.rdata);
355
356 *out_rrsig_rr = rrsig_rr;
357
358 return rrsig_rdata_size;
359 }
360 else
361 {
362 return signature_size;
363 }
364 }
365
366
367 ya_result
dnskey_signature_verify(dnskey_signature * ds,const dnssec_key * key,void * in_rrsig_rr)368 dnskey_signature_verify(dnskey_signature *ds, const dnssec_key *key, void *in_rrsig_rr) // not tested
369 {
370 const void *rr0;
371 const u8 *fqdn;
372 size_t fqdn_len;
373 const u8* owner_fqdn;
374 size_t owner_fqdn_len;
375 digest_s *ctx_ptr = &ds->digest_ctx;
376 ya_result ret;
377 struct dnskey_signature_tctr tctr;
378 u8 fqdn_buffer[256];
379
380 union dnskey_signature_header_storage hdr;
381
382 if(key == NULL)
383 {
384 return INVALID_ARGUMENT_ERROR; // no key
385 }
386
387 if((ds->rrset_reference == NULL) || (ptr_vector_size(ds->rrset_reference) == 0))
388 {
389 return INVALID_ARGUMENT_ERROR; // empty set
390 }
391
392 u8 key_algorithm = dnskey_get_algorithm(key);
393
394 if(key_algorithm != ds->key_algorithm)
395 {
396 ds->has_digest = 0;
397 }
398
399 ptr_vector *rrset = ds->rrset_reference;
400 const resource_record_view_vtbl *view_vtbl = ds->rr_view->vtbl;
401 void *data = ds->rr_view->data;
402
403 if(!ds->has_digest)
404 {
405 if(FAIL(ret = dnskey_digest_init(ctx_ptr, key_algorithm)))
406 {
407 return ret;
408 }
409
410 rr0 = ptr_vector_get(rrset, 0);
411
412 fqdn_len = dnsname_canonize(view_vtbl->get_fqdn(data, rr0), fqdn_buffer);
413 fqdn = fqdn_buffer;
414 //dnsname_len(fqdn);
415 hdr.header.labels = 0;
416
417 if((fqdn[0] == 1) && (fqdn[1] == (u8)'*'))
418 {
419 fqdn += *fqdn + 1;
420 }
421
422 while(fqdn[0] != 0)
423 {
424 ++hdr.header.labels;
425 fqdn += *fqdn + 1;
426 }
427
428 fqdn = fqdn_buffer;
429
430 owner_fqdn = dnskey_get_domain(key);
431 owner_fqdn_len = dnsname_len(owner_fqdn);
432
433 if(!ds->is_canonised)
434 {
435 ptr_vector_qsort_r(rrset, dnskey_signature_canonize_sort_record_view_rdata_compare, ds->rr_view);
436 ds->is_canonised = 1;
437 }
438
439 const u8 *rrsig_rdata = view_vtbl->get_rdata(data, in_rrsig_rr);
440 /*u16 rrsig_rdata_size = */ view_vtbl->get_rdata_size(data, in_rrsig_rr);
441 size_t hdr_size = &hdr.header.fqdn_signature[owner_fqdn_len] - (u8*)&hdr;
442
443 memcpy(hdr.rdata, rrsig_rdata, hdr_size);
444 /*
445 hdr.header.type_covered = htons(rrsig_get_type_covered_from_rdata(rrsig_rdata, rrsig_rdata_size));
446 hdr.header.algorithm = rrsig_get_algorithm_from_rdata(rrsig_rdata, rrsig_rdata_size);
447 // hdr.header.labels has already been set
448 hdr.header.original_ttl = htonl(rrsig_get_original_ttl_from_rdata(rrsig_rdata, rrsig_rdata_size));
449 hdr.header.expiration = ntohl(rrsig_get_valid_until_from_rdata(rrsig_rdata, rrsig_rdata_size));
450 hdr.header.inception = ntohl(rrsig_get_valid_from_from_rdata(rrsig_rdata, rrsig_rdata_size));
451 hdr.header.tag = htons(rrsig_get_key_tag_from_rdata(rrsig_rdata, rrsig_rdata_size));
452 memcpy(&hdr.header.fqdn_signature[0], owner_fqdn, owner_fqdn_len);
453 */
454 tctr.rtype = hdr.header.type_covered;
455 tctr.rclass = view_vtbl->get_class(data, rr0);
456 tctr.ttl = hdr.header.original_ttl;
457
458 #if DEBUG_CRYPTO_INTERNALS
459 log_debug("dnskey_signature_verify: digest for %{dnsname} %{dnstype} and key tag %i", owner_fqdn, &hdr.header.type_covered, dnskey_get_tag_const(key));
460 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, &hdr, hdr_size, 32);
461 #endif
462
463 digest_update(ctx_ptr, &hdr, hdr_size);
464
465 for(int i = 0; i <= ptr_vector_last_index(rrset); ++i)
466 {
467 const void *rr = ptr_vector_get(rrset, i);
468 digest_update(ctx_ptr, fqdn, fqdn_len);
469
470 u16 rdata_size = view_vtbl->get_rdata_size(data, rr);
471 tctr.rdata_size = htons(rdata_size);
472
473 const void *rdata = view_vtbl->get_rdata(data, rr);
474
475 #if DEBUG_CRYPTO_INTERNALS
476 rdata_desc rdd = {tctr.rtype, rdata_size, rdata};
477 log_debug("dnskey_signature_verify: #%i: %{dnsname} %i %{dnsclass} %{typerdatadesc}",
478 i, fqdn, ntohl(tctr.ttl), &tctr.rclass, &rdd);
479 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, fqdn, fqdn_len, 32);
480 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, &tctr, 2 + 2 + 4 + 2, 32);
481 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, rdata, rdata_size, 32);
482 #endif
483 digest_update(ctx_ptr, &tctr, 2 + 2 + 4 + 2);
484 digest_update(ctx_ptr, rdata, rdata_size);
485 }
486
487 s32 digest_size = digest_get_size(ctx_ptr);
488
489 //digest_final_copy_bytes(ctx_ptr, ds->digest_buffer, sizeof(ds->digest_buffer));
490 digest_final(ctx_ptr);
491
492 #if DEBUG_CRYPTO_INTERNALS
493 log_debug("dnskey_signature_verify: digest value");
494 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, digest_get_digest_ptr(ctx_ptr), digest_size, 32);
495 #endif
496
497 ds->digest_size = digest_size;
498 ds->has_digest = 1;
499 }
500 else
501 {
502 // digest has already been computed, only need to ready the signature,
503 // the rr0 and the fqdn
504
505 #if DEBUG_CRYPTO_INTERNALS
506 log_debug("dnskey_signature_verify: digest already computed");
507 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, digest_get_digest_ptr(ctx_ptr), ds->digest_size, 32);
508 #endif
509 /// @TODO 20210218 edf -- add optional signature verification")
510 // owner_fqdn = dnskey_get_domain(key); // never read
511 // owner_fqdn_len = dnsname_len(owner_fqdn); // never read
512 //signature = &hdr.header.fqdn_signature[owner_fqdn_len];
513 // rr0 = ptr_vector_get(rrset, 0); // never read
514 // fqdn = view_vtbl->get_fqdn(data, rr0); // never read
515 }
516
517 const u8 *signature_rdata = view_vtbl->get_rdata(ds->rr_view->data, in_rrsig_rr);
518 u16 signature_rdata_size = view_vtbl->get_rdata_size(ds->rr_view->data, in_rrsig_rr);
519
520 u32 rrsig_signer_name_len = dnsname_len(rrsig_get_signer_name_from_rdata(signature_rdata, signature_rdata_size));
521 u32 rrsig_header_len = RRSIG_RDATA_HEADER_LEN + rrsig_signer_name_len;
522 u16 signature_size = signature_rdata_size - rrsig_header_len;
523
524 const u8 *signature = &signature_rdata[rrsig_header_len];
525
526 #if DEBUG_CRYPTO_INTERNALS
527 log_debug("dnskey_signature_verify: signature value");
528 log_memdump(MODULE_MSG_HANDLE, MSG_DEBUG, signature, signature_size, 32);
529 #endif
530
531 void *digest_ptr;
532 digest_get_digest(ctx_ptr, &digest_ptr);
533 bool verified = key->vtbl->dnssec_key_verify_digest(key, digest_ptr, ds->digest_size, signature, signature_size);
534
535 #if DEBUG_CRYPTO_INTERNALS
536 log_debug("dnskey_signature_verify: %s", (verified)?"verified":"wrong");
537 #endif
538
539 return (verified)?SUCCESS:ERROR;
540 }
541
542 void
dnskey_signature_finalize(dnskey_signature * ds)543 dnskey_signature_finalize(dnskey_signature *ds)
544 {
545 (void)ds;
546 }
547
548 ya_result
dnskey_sign_rrset_with_maxinterval(const dnssec_key * key,ptr_vector * rrset,bool canonize,resource_record_view * view,s32 maxinterval,void ** out_rrsig_rr)549 dnskey_sign_rrset_with_maxinterval(const dnssec_key *key, ptr_vector *rrset, bool canonize, resource_record_view *view,
550 s32 maxinterval, void **out_rrsig_rr)
551 {
552 if(dnskey_is_private(key))
553 {
554 dnskey_signature ds;
555 dnskey_signature_init(&ds);
556
557 s32 from_epoch = MAX(time(NULL) - 86400, 0);
558 s32 to_epoch = dnskey_get_inactive_epoch(key);
559
560 // if the key will be inactive well after the maxinterval, use maxinterval to the life-time of the signature
561
562 if(to_epoch - from_epoch > maxinterval + DNSKEY_SIGN_TIME_LENIENCY) // + 86400 : don't limit down for a small period of overhead
563 {
564 if(((s64)from_epoch + (s64)maxinterval) <= MAX_S32)
565 {
566 to_epoch = from_epoch + maxinterval;
567 }
568 else
569 {
570 log_warn("dnskey_sign_rrset_with_maxinterval(%{dnsname}, ..., %i, %p)", dnskey_get_domain(key), maxinterval, out_rrsig_rr);
571 to_epoch = MAX_S32;
572 }
573 }
574 // else limit to the expiration time of the signature
575
576 from_epoch -= DNSKEY_SIGN_TIME_LENIENCY; // give some leniency for the validity start
577
578 dnskey_signature_set_validity(&ds, from_epoch, to_epoch);
579 dnskey_signature_set_view(&ds, view);
580 dnskey_signature_set_rrset_reference(&ds, rrset);
581 dnskey_signature_set_canonised(&ds, !canonize);
582 ya_result ret = dnskey_signature_sign(&ds, key, out_rrsig_rr);
583 dnskey_signature_finalize(&ds);
584
585 return ret;
586 }
587 else
588 {
589 return DNSSEC_ERROR_KEYRING_KEY_IS_NOT_PRIVATE;
590 }
591 }
592
593 /*
594 ya_result
595 dnskey_signature_rrset_verify(dnskey_signature *ds, const dnssec_key *key, ptr_vector *rrset, resource_record_view *view)
596 {
597 }
598 */
599 /**
600 * @}
601 */
602