Codebase list dnsviz / bdaa08f
Merge pull request #69 from dnsviz/obsoletealg Obsoletealg Casey Deccio authored 3 years ago GitHub committed 3 years ago
9 changed file(s) with 269 addition(s) and 52 deletion(s). Raw diff Collapse all Expand all
251251 super(AlgorithmNotSupported, self).__init__(**kwargs)
252252 self.template_kwargs['algorithm_text'] = dns.dnssec.algorithm_to_text(self.template_kwargs['algorithm'])
253253
254 class AlgorithmValidationProhibited(RRSIGError):
255 '''
256 >>> e = AlgorithmValidationProhibited(algorithm=5)
257 >>> e.args
258 [5]
259 >>> e.description
260 'DNSSEC specification prohibits validation of RRSIGs with DNSSEC algorithm 5 (RSASHA1).'
261 '''
262
263 _abstract = False
264 code = 'ALGORITHM_VALIDATION_PROHIBITED'
265 description_template = "DNSSEC specification prohibits validation of RRSIGs with DNSSEC algorithm %(algorithm)d (%(algorithm_text)s)."
266 references = ['RFC 8624, Sec. 3.1']
267 required_params = ['algorithm']
268
269 def __init__(self, **kwargs):
270 super(AlgorithmValidationProhibited, self).__init__(**kwargs)
271 self.template_kwargs['algorithm_text'] = dns.dnssec.algorithm_to_text(self.template_kwargs['algorithm'])
272
273 class AlgorithmProhibited(RRSIGError):
274 '''
275 >>> e = AlgorithmProhibited(algorithm=5)
276 >>> e.args
277 [5]
278 >>> e.description
279 'DNSSEC specification prohibits signing with DNSSEC algorithm 5 (RSASHA1).'
280 '''
281
282 _abstract = False
283 code = 'ALGORITHM_PROHIBITED'
284 description_template = "DNSSEC specification prohibits signing with DNSSEC algorithm %(algorithm)d (%(algorithm_text)s)."
285 references = ['RFC 8624, Sec. 3.1']
286 required_params = ['algorithm']
287
288 def __init__(self, **kwargs):
289 super(AlgorithmProhibited, self).__init__(**kwargs)
290 self.template_kwargs['algorithm_text'] = dns.dnssec.algorithm_to_text(self.template_kwargs['algorithm'])
291
292 class AlgorithmNotRecommended(RRSIGError):
293 '''
294 >>> e = AlgorithmNotRecommended(algorithm=5)
295 >>> e.args
296 [5]
297 >>> e.description
298 'DNSSEC specification recommends not signing with DNSSEC algorithm 5 (RSASHA1).'
299 '''
300
301 _abstract = False
302 code = 'ALGORITHM_NOT_RECOMMENDED'
303 description_template = "DNSSEC specification recommends not signing with DNSSEC algorithm %(algorithm)d (%(algorithm_text)s)."
304 references = ['RFC 8624, Sec. 3.1']
305 required_params = ['algorithm']
306
307 def __init__(self, **kwargs):
308 super(AlgorithmNotRecommended, self).__init__(**kwargs)
309 self.template_kwargs['algorithm_text'] = dns.dnssec.algorithm_to_text(self.template_kwargs['algorithm'])
310
254311 class DNSKEYRevokedRRSIG(RRSIGError):
255312 '''
256313 >>> e = DNSKEYRevokedRRSIG()
511568
512569 def __init__(self, **kwargs):
513570 super(DigestAlgorithmNotSupported, self).__init__(**kwargs)
571 self.template_kwargs['algorithm_text'] = fmt.DS_DIGEST_TYPES.get(self.template_kwargs['algorithm'], self.template_kwargs['algorithm'])
572
573 class DigestAlgorithmValidationProhibited(DSDigestError):
574 '''
575 >>> e = DigestAlgorithmValidationProhibited(algorithm=5)
576 >>> e.description
577 'DNSSEC specification prohibits validation of DS records that use digest algorithm 5 (5).'
578 '''
579
580 _abstract = False
581 code = 'DIGEST_ALGORITHM_VALIDATION_PROHIBITED'
582 description_template = "DNSSEC specification prohibits validation of DS records that use digest algorithm %(algorithm)d (%(algorithm_text)s)."
583 references = ['RFC 8624, Sec. 3.2']
584 required_params = ['algorithm']
585
586 def __init__(self, **kwargs):
587 super(DigestAlgorithmValidationProhibited, self).__init__(**kwargs)
588 self.template_kwargs['algorithm_text'] = fmt.DS_DIGEST_TYPES.get(self.template_kwargs['algorithm'], self.template_kwargs['algorithm'])
589
590 class DigestAlgorithmProhibited(DSDigestError):
591 '''
592 >>> e = DigestAlgorithmProhibited(algorithm=5)
593 >>> e.description
594 'DNSSEC specification prohibits signing with DS records that use digest algorithm 5 (5).'
595 '''
596
597 _abstract = False
598 code = 'DIGEST_ALGORITHM_PROHIBITED'
599 description_template = "DNSSEC specification prohibits signing with DS records that use digest algorithm %(algorithm)d (%(algorithm_text)s)."
600 references = ['RFC 8624, Sec. 3.2']
601 required_params = ['algorithm']
602
603 def __init__(self, **kwargs):
604 super(DigestAlgorithmProhibited, self).__init__(**kwargs)
605 self.template_kwargs['algorithm_text'] = fmt.DS_DIGEST_TYPES.get(self.template_kwargs['algorithm'], self.template_kwargs['algorithm'])
606
607 class DigestAlgorithmNotRecommended(DSDigestError):
608 '''
609 >>> e = DigestAlgorithmNotRecommended(algorithm=5)
610 >>> e.description
611 'DNSSEC specification recommends not signing with DS records that use digest algorithm 5 (5).'
612 '''
613
614 _abstract = False
615 code = 'DIGEST_ALGORITHM_NOT_RECOMMENDED'
616 description_template = "DNSSEC specification recommends not signing with DS records that use digest algorithm %(algorithm)d (%(algorithm_text)s)."
617 references = ['RFC 8624, Sec. 3.2']
618 required_params = ['algorithm']
619
620 def __init__(self, **kwargs):
621 super(DigestAlgorithmNotRecommended, self).__init__(**kwargs)
514622 self.template_kwargs['algorithm_text'] = fmt.DS_DIGEST_TYPES.get(self.template_kwargs['algorithm'], self.template_kwargs['algorithm'])
515623
516624 class DNSKEYRevokedDS(DSDigestError):
2626
2727 from __future__ import unicode_literals
2828
29 import copy
2930 import errno
3031 import logging
3132
786787 (not x.effective_tcp and x.udp_responsive)) and \
787788 (not require_valid or x.is_valid_response()))
788789
789 def populate_status(self, trusted_keys, supported_algs=None, supported_digest_algs=None, is_dlv=False, trace=None, follow_mx=True):
790 def _populate_status(self, trusted_keys, supported_algs=None, supported_digest_algs=None, is_dlv=False, trace=None, follow_mx=True):
790791 if trace is None:
791792 trace = []
792793
803804 if self.stub:
804805 return
805806
806 # identify supported algorithms as intersection of explicitly supported
807 # and software supported
808 if supported_algs is not None:
809 supported_algs.intersection_update(crypto._supported_algs)
810 else:
811 supported_algs = crypto._supported_algs
812 if supported_digest_algs is not None:
813 supported_digest_algs.intersection_update(crypto._supported_digest_algs)
814 else:
815 supported_digest_algs = crypto._supported_digest_algs
816
817807 # populate status of dependencies
818808 for cname in self.cname_targets:
819809 for target, cname_obj in self.cname_targets[cname].items():
820810 if cname_obj is not None:
821 cname_obj.populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
811 cname_obj._populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
822812 if follow_mx:
823813 for target, mx_obj in self.mx_targets.items():
824814 if mx_obj is not None:
825 mx_obj.populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self], follow_mx=False)
815 mx_obj._populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self], follow_mx=False)
826816 for signer, signer_obj in self.external_signers.items():
827817 if signer_obj is not None:
828 signer_obj.populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
818 signer_obj._populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
829819 for target, ns_obj in self.ns_dependencies.items():
830820 if ns_obj is not None:
831 ns_obj.populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
821 ns_obj._populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
832822
833823 # populate status of ancestry
834824 if self.nxdomain_ancestor is not None:
835 self.nxdomain_ancestor.populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
825 self.nxdomain_ancestor._populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
836826 if self.parent is not None:
837 self.parent.populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
827 self.parent._populate_status(trusted_keys, supported_algs, supported_digest_algs, trace=trace + [self])
838828 if self.dlv_parent is not None:
839 self.dlv_parent.populate_status(trusted_keys, supported_algs, supported_digest_algs, is_dlv=True, trace=trace + [self])
829 self.dlv_parent._populate_status(trusted_keys, supported_algs, supported_digest_algs, is_dlv=True, trace=trace + [self])
840830
841831 _logger.debug('Assessing status of %s...' % (fmt.humanize_name(self.name)))
842832 self._populate_name_status()
851841 if self.dlv_parent is not None:
852842 self._populate_ds_status(dns.rdatatype.DLV, supported_algs, supported_digest_algs)
853843 self._populate_dnskey_status(trusted_keys)
844
845 def populate_status(self, trusted_keys, supported_algs=None, supported_digest_algs=None, is_dlv=False, follow_mx=True, validate_prohibited_algs=False):
846 # identify supported algorithms as intersection of explicitly supported
847 # and software supported
848 if supported_algs is not None:
849 supported_algs.intersection_update(crypto._supported_algs)
850 else:
851 supported_algs = copy.copy(crypto._supported_algs)
852 if supported_digest_algs is not None:
853 supported_digest_algs.intersection_update(crypto._supported_digest_algs)
854 else:
855 supported_digest_algs = copy.copy(crypto._supported_digest_algs)
856
857 # unless we are overriding, mark prohibited algorithms as not supported
858 if not validate_prohibited_algs:
859 supported_algs.difference_update(Status.DNSKEY_ALGS_VALIDATION_PROHIBITED)
860 supported_digest_algs.difference_update(Status.DS_DIGEST_ALGS_VALIDATION_PROHIBITED)
861
862 self._populate_status(trusted_keys, supported_algs, supported_digest_algs, is_dlv, None, follow_mx)
854863
855864 def _populate_name_status(self, trace=None):
856865 # using trace allows _populate_name_status to be called independent of
21112120 # is bogus because there should have been matching KSK.
21122121 self.delegation_status[rdtype] = Status.DELEGATION_STATUS_BOGUS
21132122 else:
2114 # If no algorithsm are supported, then this is a
2123 # If no algorithms are supported, then this is a
21152124 # provably insecure delegation.
21162125 self.delegation_status[rdtype] = Status.DELEGATION_STATUS_INSECURE
21172126 else:
168168 DS_DIGEST_ALGS_STRONGER_THAN_SHA1 = (2, 4)
169169 DS_DIGEST_ALGS_IGNORING_SHA1 = (2,)
170170
171 # RFC 8624 Section 3.1
172 DNSKEY_ALGS_NOT_RECOMMENDED = (5, 7, 10)
173 DNSKEY_ALGS_PROHIBITED = (1, 3, 6, 12)
174 DNSKEY_ALGS_VALIDATION_PROHIBITED = (1, 3, 6)
175
176 # RFC 8624 Section 3.2
177 DS_DIGEST_ALGS_NOT_RECOMMENDED = ()
178 DS_DIGEST_ALGS_PROHIBITED = (0, 1, 3)
179 DS_DIGEST_ALGS_VALIDATION_PROHIBITED = ()
180
171181 class RRSIGStatus(object):
172182 def __init__(self, rrset, rrsig, dnskey, zone_name, reference_ts, supported_algs):
173183 self.rrset = rrset
185195
186196 self.validation_status = RRSIG_STATUS_VALID
187197 if self.signature_valid is None or self.dnskey.rdata.algorithm not in supported_algs:
198 # Either we can't validate the cryptographic signature, or we are
199 # explicitly directed to ignore the algorithm.
188200 if self.dnskey is None:
201 # In this case, there is no corresponding DNSKEY, so we make
202 # the status "INDETERMINATE".
189203 if self.validation_status == RRSIG_STATUS_VALID:
190204 self.validation_status = RRSIG_STATUS_INDETERMINATE_NO_DNSKEY
205
191206 else:
192 if self.validation_status == RRSIG_STATUS_VALID:
193 self.validation_status = RRSIG_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM
194 self.warnings.append(Errors.AlgorithmNotSupported(algorithm=self.rrsig.algorithm))
207 # If there is a DNSKEY, then we look at *why* we are ignoring
208 # the cryptographic signature.
209 if self.dnskey.rdata.algorithm in DNSKEY_ALGS_VALIDATION_PROHIBITED:
210 # In this case, specification dictates that the algorithm
211 # MUST NOT be validated, so we mark it as ignored.
212 if self.validation_status == RRSIG_STATUS_VALID:
213 self.validation_status = RRSIG_STATUS_ALGORITHM_IGNORED
214 else:
215 # In this case, we can't validate this particular
216 # algorithm, either because the code doesn't support it,
217 # or because we have been explicitly directed to ignore it.
218 # In either case, mark it as "UNKNOWN", and warn that it is
219 # not supported.
220 if self.validation_status == RRSIG_STATUS_VALID:
221 self.validation_status = RRSIG_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM
222 self.warnings.append(Errors.AlgorithmNotSupported(algorithm=self.rrsig.algorithm))
223
224 # Independent of whether or not we considered the cryptographic
225 # validation, issue a warning if we are using an algorithm for which
226 # validation or signing has been prohibited.
227 #
228 # Signing is prohibited
229 if self.dnskey.rdata.algorithm in DNSKEY_ALGS_VALIDATION_PROHIBITED:
230 self.warnings.append(Errors.AlgorithmValidationProhibited(algorithm=self.rrsig.algorithm))
231 # Validation is prohibited or, at least, not recommended
232 if self.dnskey.rdata.algorithm in DNSKEY_ALGS_PROHIBITED:
233 self.warnings.append(Errors.AlgorithmProhibited(algorithm=self.rrsig.algorithm))
234 elif self.dnskey.rdata.algorithm in DNSKEY_ALGS_NOT_RECOMMENDED:
235 self.warnings.append(Errors.AlgorithmNotRecommended(algorithm=self.rrsig.algorithm))
195236
196237 if self.rrset.ttl_cmp:
197238 if self.rrset.rrset.ttl != self.rrset.rrsig_info[self.rrsig].ttl:
350391
351392 self.validation_status = DS_STATUS_VALID
352393 if self.digest_valid is None or self.ds.digest_type not in supported_digest_algs:
394 # Either we cannot reproduce a digest with this type, or we are
395 # explicitly directed to ignore the digest type.
353396 if self.dnskey is None:
397 # In this case, there is no corresponding DNSKEY, so we make
398 # the status "INDETERMINATE".
354399 if self.validation_status == DS_STATUS_VALID:
355400 self.validation_status = DS_STATUS_INDETERMINATE_NO_DNSKEY
356401 else:
357 if self.validation_status == DS_STATUS_VALID:
358 self.validation_status = DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM
359 self.warnings.append(Errors.DigestAlgorithmNotSupported(algorithm=ds.digest_type))
402 # If there is a DNSKEY, then we look at *why* we are ignoring
403 # the digest of the DNSKEY.
404 if self.ds.digest_type in DS_DIGEST_ALGS_VALIDATION_PROHIBITED:
405 # In this case, specification dictates that the algorithm
406 # MUST NOT be validated, so we mark it as ignored.
407 if self.validation_status == DS_STATUS_VALID:
408 self.validation_status = DS_STATUS_ALGORITHM_IGNORED
409 else:
410 # In this case, we can't validate this particular
411 # digest type, either because the code doesn't support it,
412 # or because we have been explicitly directed to ignore it.
413 # In either case, mark it as "UNKNOWN", and warn that it is
414 # not supported.
415 if self.validation_status == DS_STATUS_VALID:
416 self.validation_status = DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM
417 self.warnings.append(Errors.DigestAlgorithmNotSupported(algorithm=self.ds.digest_type))
418
419 # Independent of whether or not we considered the digest for
420 # validation, issue a warning if we are using a digest type for which
421 # validation or signing has been prohibited.
422 #
423 # Signing is prohibited
424 if self.ds.digest_type in DS_DIGEST_ALGS_VALIDATION_PROHIBITED:
425 self.warnings.append(Errors.DigestAlgorithmValidationProhibited(algorithm=self.ds.digest_type))
426 # Validation is prohibited or, at least, not recommended
427 if self.ds.digest_type in DS_DIGEST_ALGS_PROHIBITED:
428 self.warnings.append(Errors.DigestAlgorithmProhibited(algorithm=self.ds.digest_type))
429 elif self.ds.digest_type in DS_DIGEST_ALGS_NOT_RECOMMENDED:
430 self.warnings.append(Errors.DigestAlgorithmNotRecommended(algorithm=self.ds.digest_type))
360431
361432 if self.dnskey is not None and \
362433 self.dnskey.rdata.flags & fmt.DNSKEY_FLAGS['revoke']:
377448
378449 # RFC 4509
379450 if self.ds.digest_type == 1:
380 digest_algs = set()
381 my_digest_algs = {}
451 stronger_algs_all_ds = set()
452 # Cycle through all other DS records in the DS RRset, and
453 # create a list of digest types that are stronger than SHA1
454 # and are being used by DS records across the *entire* DS.
382455 for ds_rdata in self.ds_meta.rrset:
383 digest_algs.add(ds_rdata.digest_type)
384 if (ds_rdata.algorithm, ds_rdata.key_tag) == (self.ds.algorithm, self.ds.key_tag):
385 # Here we produce a status of the DS with algorithm 2 with
386 # respect to the DNSKEY for comparison with the current DS
387 # with algorithm 1. It is possible that the DS with the
388 # different digest type matches a different DNSKEY than the
389 # present DNSKEY. If it does, there will be a warning, but
390 # it should be both rare and innocuous.
391 if ds_rdata.digest_type == self.ds.digest_type:
392 continue
393 elif ds_rdata.digest_type not in my_digest_algs or \
394 my_digest_algs[ds_rdata.digest_type].validation_status != DS_STATUS_VALID:
395 my_digest_algs[ds_rdata.digest_type] = \
396 DSStatus(ds_rdata, self.ds_meta, self.dnskey, supported_digest_algs)
397
398 for digest_alg in DS_DIGEST_ALGS_STRONGER_THAN_SHA1:
399 if digest_alg in supported_digest_algs and digest_alg in digest_algs and \
400 (digest_alg not in my_digest_algs or my_digest_algs[digest_alg].validation_status not in \
401 (DS_STATUS_VALID, DS_STATUS_INDETERMINATE_NO_DNSKEY, DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM, DS_STATUS_INDETERMINATE_MATCH_PRE_REVOKE)):
402
456 if ds_rdata.digest_type in DS_DIGEST_ALGS_STRONGER_THAN_SHA1:
457 stronger_algs_all_ds.add(ds_rdata.digest_type)
458
459 # Consider only digest types that we actually support
460 stronger_algs_all_ds.intersection_update(supported_digest_algs)
461
462 if stronger_algs_all_ds:
463 # If there are DS records in the DS RRset with digest type
464 # stronger than SHA1, then this one MUST be ignored by
465 # validators (RFC 4509).
466 for digest_alg in stronger_algs_all_ds:
403467 if digest_alg in DS_DIGEST_ALGS_IGNORING_SHA1:
404 self.warnings.append(Errors.DSDigestAlgorithmIgnored(algorithm=1, new_algorithm=digest_alg))
405468 if self.validation_status == DS_STATUS_VALID:
406469 self.validation_status = DS_STATUS_ALGORITHM_IGNORED
470 self.warnings.append(Errors.DSDigestAlgorithmIgnored(algorithm=1, new_algorithm=digest_alg))
407471 else:
408472 self.warnings.append(Errors.DSDigestAlgorithmMaybeIgnored(algorithm=1, new_algorithm=digest_alg))
409473
197197 type=self.comma_separated_ints_set,
198198 action='store', metavar='<digest_alg>,[<digest_alg>...]',
199199 help='Support only the specified DNSSEC digest algorithm(s)')
200 self.parser.add_argument('-b', '--validate-prohibited-algs',
201 const=True, default=False,
202 action='store_const',
203 help='Validate algorithms for which validation is otherwise prohibited')
200204 self.parser.add_argument('-C', '--enforce-cookies',
201205 const=True, default=False,
202206 action='store_const',
456460
457461 G = DNSAuthGraph()
458462 for name_obj in name_objs:
459 name_obj.populate_status(arghelper.trusted_keys, supported_algs=arghelper.args.algorithms, supported_digest_algs=arghelper.args.digest_algorithms)
463 name_obj.populate_status(arghelper.trusted_keys, supported_algs=arghelper.args.algorithms, supported_digest_algs=arghelper.args.digest_algorithms, validate_prohibited_algs=arghelper.args.validate_prohibited_algs)
460464 for qname, rdtype in name_obj.queries:
461465 if arghelper.args.rr_types is None:
462466 # if rdtypes was not specified, then graph all, with some
220220 type=self.comma_separated_ints_set,
221221 action='store', metavar='<digest_alg>,[<digest_alg>...]',
222222 help='Support only the specified DNSSEC digest algorithm(s)')
223 self.parser.add_argument('-b', '--validate-prohibited-algs',
224 const=True, default=False,
225 action='store_const',
226 help='Validate algorithms for which validation is otherwise prohibited')
223227 self.parser.add_argument('-C', '--enforce-cookies',
224228 const=True, default=False,
225229 action='store_const',
453457
454458 d = OrderedDict()
455459 for name_obj in name_objs:
456 name_obj.populate_status(arghelper.trusted_keys, supported_algs=arghelper.args.algorithms, supported_digest_algs=arghelper.args.digest_algorithms)
460 name_obj.populate_status(arghelper.trusted_keys, supported_algs=arghelper.args.algorithms, supported_digest_algs=arghelper.args.digest_algorithms, validate_prohibited_algs=arghelper.args.validate_prohibited_algs)
457461
458462 if arghelper.trusted_keys:
459463 G = DNSAuthGraph()
355355 type=self.comma_separated_ints_set,
356356 action='store', metavar='<digest_alg>,[<digest_alg>...]',
357357 help='Support only the specified DNSSEC digest algorithm(s)')
358 self.parser.add_argument('-b', '--validate-prohibited-algs',
359 const=True, default=False,
360 action='store_const',
361 help='Validate algorithms for which validation is otherwise prohibited')
358362 self.parser.add_argument('-C', '--enforce-cookies',
359363 const=True, default=False,
360364 action='store_const',
589593
590594 G = DNSAuthGraph()
591595 for name_obj in name_objs:
592 name_obj.populate_status(arghelper.trusted_keys, supported_algs=arghelper.args.algorithms, supported_digest_algs=arghelper.args.digest_algorithms)
596 name_obj.populate_status(arghelper.trusted_keys, supported_algs=arghelper.args.algorithms, supported_digest_algs=arghelper.args.digest_algorithms, validate_prohibited_algs=arghelper.args.validate_prohibited_algs)
593597 for qname, rdtype in name_obj.queries:
594598 if arghelper.args.rr_types is None:
595599 # if rdtypes was not specified, then graph all, with some
9191 unknown. Additionally, when a zone has only DS records with unsupported digest
9292 algorithms, the zone is treated as "insecure", assuming the DS records are
9393 properly authenticated.
94 .TP
95 .B -b, --validate-prohibited-algs
96 Validate algorithms for which validation is otherwise prohibited. Current
97 DNSSEC specification prohibits validators from validating older, weaker
98 algorithms associated with DNSKEY and DS records (see RFC 8624). If this
99 option is used, then a warning will be still be issued for DNSSEC records that
100 use these older algorithms, but the code will still assess their cryptographic
101 status, rather than ignoring them.
94102 .TP
95103 .B -C, --enforce-cookies
96104 Enforce DNS cookies strictly. Require a server to return a "BADCOOKIE" response
8888 algorithms, the zone is treated as "insecure", assuming the DS records are
8989 properly authenticated.
9090 .TP
91 .B -b, --validate-prohibited-algs
92 Validate algorithms for which validation is otherwise prohibited. Current
93 DNSSEC specification prohibits validators from validating older, weaker
94 algorithms associated with DNSKEY and DS records (see RFC 8624). If this
95 option is used, then a warning will be still be issued for DNSSEC records that
96 use these older algorithms, but the code will still assess their cryptographic
97 status, rather than ignoring them.
98 .TP
9199 .B -C, --enforce-cookies
92100 Enforce DNS cookies strictly. Require a server to return a "BADCOOKIE" response
93101 when a query contains a COOKIE option with no server cookie or with an invalid
9191 unknown. Additionally, when a zone has only DS records with unsupported digest
9292 algorithms, the zone is treated as "insecure", assuming the DS records are
9393 properly authenticated.
94 .TP
95 .B -b, --validate-prohibited-algs
96 Validate algorithms for which validation is otherwise prohibited. Current
97 DNSSEC specification prohibits validators from validating older, weaker
98 algorithms associated with DNSKEY and DS records (see RFC 8624). If this
99 option is used, then a warning will be still be issued for DNSSEC records that
100 use these older algorithms, but the code will still assess their cryptographic
101 status, rather than ignoring them.
94102 .TP
95103 .B -C, --enforce-cookies
96104 Enforce DNS cookies strictly. Require a server to return a "BADCOOKIE" response