Codebase list dnsviz / 2821f62
Revamp code that ignores SHA1 if something better exists Casey Deccio 3 years ago
1 changed file(s) with 52 addition(s) and 24 deletion(s). Raw diff Collapse all Expand all
434434
435435 # RFC 4509
436436 if self.ds.digest_type == 1:
437 digest_algs = set()
438 my_digest_algs = {}
437 stronger_algs_all_ds = set()
438 stronger_algs_this_dnskey = set()
439 # Cycle through all other DS records in the DS RRset:
440 # 1. Create a list of digest types that are stronger than SHA1
441 # and are being used by DS records across the *entire* DS
442 # RRset. Store them in digest_algs_all_ds.
443 # 2. Create a list of digest types that are stronger than SHA1,
444 # correspond to DS records go with the same DNSKEY as *this*
445 # DS record, and have valid or indeterminate status (i.e., not
446 # invalid). These are DS records with the same DNSSEC
447 # algorithm and key tag, but different digest types. Store
448 # them in stronger_algs_this_dnskey.
449 #
450 # Note: It is possible that a DS with a different digest
451 # type matches a different DNSKEY than the present DNSKEY--due
452 # to key tag collisions. If it does, there will be a warning,
453 # but it should be both rare and innocuous.
439454 for ds_rdata in self.ds_meta.rrset:
440 digest_algs.add(ds_rdata.digest_type)
455
456 if ds_rdata.digest_type not in DS_DIGEST_ALGS_STRONGER_THAN_SHA1:
457 continue
458
459 stronger_algs_all_ds.add(ds_rdata.digest_type)
441460 if (ds_rdata.algorithm, ds_rdata.key_tag) == (self.ds.algorithm, self.ds.key_tag):
442 # Here we produce a status of the DS with algorithm 2 with
443 # respect to the DNSKEY for comparison with the current DS
444 # with algorithm 1. It is possible that the DS with the
445 # different digest type matches a different DNSKEY than the
446 # present DNSKEY. If it does, there will be a warning, but
447 # it should be both rare and innocuous.
448461 if ds_rdata.digest_type == self.ds.digest_type:
449462 continue
450 elif ds_rdata.digest_type not in my_digest_algs or \
451 my_digest_algs[ds_rdata.digest_type].validation_status != DS_STATUS_VALID:
452 my_digest_algs[ds_rdata.digest_type] = \
453 DSStatus(ds_rdata, self.ds_meta, self.dnskey, supported_digest_algs)
454
455 for digest_alg in DS_DIGEST_ALGS_STRONGER_THAN_SHA1:
456 if digest_alg in supported_digest_algs and digest_alg in digest_algs and \
457 (digest_alg not in my_digest_algs or my_digest_algs[digest_alg].validation_status not in \
458 (DS_STATUS_VALID, DS_STATUS_INDETERMINATE_NO_DNSKEY, DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM, DS_STATUS_INDETERMINATE_MATCH_PRE_REVOKE)):
459
460 if digest_alg in DS_DIGEST_ALGS_IGNORING_SHA1:
461 self.warnings.append(Errors.DSDigestAlgorithmIgnored(algorithm=1, new_algorithm=digest_alg))
462 if self.validation_status == DS_STATUS_VALID:
463 self.validation_status = DS_STATUS_ALGORITHM_IGNORED
464463 else:
465 self.warnings.append(Errors.DSDigestAlgorithmMaybeIgnored(algorithm=1, new_algorithm=digest_alg))
464 status = DSStatus(ds_rdata, self.ds_meta, self.dnskey, supported_digest_algs)
465 if status.validation_status in \
466 (DS_STATUS_VALID, DS_STATUS_INDETERMINATE_NO_DNSKEY, DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM, DS_STATUS_INDETERMINATE_MATCH_PRE_REVOKE):
467 stronger_algs_this_dnskey.add(ds_rdata.digest_type)
468
469 # Consider only digest types that we actually support
470 stronger_algs_all_ds.intersection_update(supported_digest_algs)
471 stronger_algs_this_dnskey.intersection_update(supported_digest_algs)
472
473 if stronger_algs_all_ds:
474 # If there are DS records in the DS RRset with digest type
475 # stronger than SHA1, then this one MUST be ignored by
476 # validators (RFC 4509). We don't actually issue a warning,
477 # however, unless a DS with stronger digest type is not being
478 # used to validate the current DNSKEY; if there is such a DS,
479 # then there is no reason to complain.
480
481 if not stronger_algs_this_dnskey:
482 # If there are any DS records in the DS RRset with digest type
483 # stronger than SHA1, and none of them can properly validate
484 # the current DNSKEY, then this one stands alone.
485 for digest_alg in stronger_algs_all_ds:
486 if digest_alg in DS_DIGEST_ALGS_IGNORING_SHA1:
487 if self.validation_status == DS_STATUS_VALID:
488 self.validation_status = DS_STATUS_ALGORITHM_IGNORED
489 self.warnings.append(Errors.DSDigestAlgorithmIgnored(algorithm=1, new_algorithm=digest_alg))
490 else:
491 self.warnings.append(Errors.DSDigestAlgorithmMaybeIgnored(algorithm=1, new_algorithm=digest_alg))
492
493
466494
467495 def __str__(self):
468496 return '%s record(s) corresponding to DNSKEY for %s (algorithm %d (%s), key tag %d)' % (dns.rdatatype.to_text(self.ds_meta.rrset.rdtype), fmt.humanize_name(self.ds_meta.rrset.name), self.ds.algorithm, fmt.DNSKEY_ALGORITHMS.get(self.ds.algorithm, self.ds.algorithm), self.ds.key_tag)