Always warn if digest type 1 exists with stronger digest type
Casey Deccio
3 years ago
443 | 443 | # RFC 4509 |
444 | 444 | if self.ds.digest_type == 1: |
445 | 445 | stronger_algs_all_ds = set() |
446 | stronger_algs_this_dnskey = set() | |
447 | # Cycle through all other DS records in the DS RRset: | |
448 | # 1. Create a list of digest types that are stronger than SHA1 | |
449 | # and are being used by DS records across the *entire* DS | |
450 | # RRset. Store them in digest_algs_all_ds. | |
451 | # 2. Create a list of digest types that are stronger than SHA1, | |
452 | # correspond to DS records go with the same DNSKEY as *this* | |
453 | # DS record, and have valid or indeterminate status (i.e., not | |
454 | # invalid). These are DS records with the same DNSSEC | |
455 | # algorithm and key tag, but different digest types. Store | |
456 | # them in stronger_algs_this_dnskey. | |
457 | # | |
458 | # Note: It is possible that a DS with a different digest | |
459 | # type matches a different DNSKEY than the present DNSKEY--due | |
460 | # to key tag collisions. If it does, there will be a warning, | |
461 | # but it should be both rare and innocuous. | |
446 | # Cycle through all other DS records in the DS RRset, and | |
447 | # create a list of digest types that are stronger than SHA1 | |
448 | # and are being used by DS records across the *entire* DS. | |
462 | 449 | for ds_rdata in self.ds_meta.rrset: |
463 | ||
464 | if ds_rdata.digest_type not in DS_DIGEST_ALGS_STRONGER_THAN_SHA1: | |
465 | continue | |
466 | ||
467 | stronger_algs_all_ds.add(ds_rdata.digest_type) | |
468 | if (ds_rdata.algorithm, ds_rdata.key_tag) == (self.ds.algorithm, self.ds.key_tag): | |
469 | if ds_rdata.digest_type == self.ds.digest_type: | |
470 | continue | |
471 | else: | |
472 | status = DSStatus(ds_rdata, self.ds_meta, self.dnskey, supported_digest_algs) | |
473 | if status.validation_status in \ | |
474 | (DS_STATUS_VALID, DS_STATUS_INDETERMINATE_NO_DNSKEY, DS_STATUS_INDETERMINATE_UNKNOWN_ALGORITHM, DS_STATUS_INDETERMINATE_MATCH_PRE_REVOKE): | |
475 | stronger_algs_this_dnskey.add(ds_rdata.digest_type) | |
450 | if ds_rdata.digest_type in DS_DIGEST_ALGS_STRONGER_THAN_SHA1: | |
451 | stronger_algs_all_ds.add(ds_rdata.digest_type) | |
476 | 452 | |
477 | 453 | # Consider only digest types that we actually support |
478 | 454 | stronger_algs_all_ds.intersection_update(supported_digest_algs) |
479 | stronger_algs_this_dnskey.intersection_update(supported_digest_algs) | |
480 | 455 | |
481 | 456 | if stronger_algs_all_ds: |
482 | 457 | # If there are DS records in the DS RRset with digest type |
483 | 458 | # stronger than SHA1, then this one MUST be ignored by |
484 | # validators (RFC 4509). We don't actually issue a warning, | |
485 | # however, unless a DS with stronger digest type is not being | |
486 | # used to validate the current DNSKEY; if there is such a DS, | |
487 | # then there is no reason to complain. | |
488 | ||
489 | if not stronger_algs_this_dnskey: | |
490 | # If there are any DS records in the DS RRset with digest type | |
491 | # stronger than SHA1, and none of them can properly validate | |
492 | # the current DNSKEY, then this one stands alone. | |
493 | for digest_alg in stronger_algs_all_ds: | |
494 | if digest_alg in DS_DIGEST_ALGS_IGNORING_SHA1: | |
495 | if self.validation_status == DS_STATUS_VALID: | |
496 | self.validation_status = DS_STATUS_ALGORITHM_IGNORED | |
497 | self.warnings.append(Errors.DSDigestAlgorithmIgnored(algorithm=1, new_algorithm=digest_alg)) | |
498 | else: | |
499 | self.warnings.append(Errors.DSDigestAlgorithmMaybeIgnored(algorithm=1, new_algorithm=digest_alg)) | |
500 | ||
459 | # validators (RFC 4509). | |
460 | for digest_alg in stronger_algs_all_ds: | |
461 | if digest_alg in DS_DIGEST_ALGS_IGNORING_SHA1: | |
462 | if self.validation_status == DS_STATUS_VALID: | |
463 | self.validation_status = DS_STATUS_ALGORITHM_IGNORED | |
464 | self.warnings.append(Errors.DSDigestAlgorithmIgnored(algorithm=1, new_algorithm=digest_alg)) | |
465 | else: | |
466 | self.warnings.append(Errors.DSDigestAlgorithmMaybeIgnored(algorithm=1, new_algorithm=digest_alg)) | |
501 | 467 | |
502 | 468 | def __str__(self): |
503 | 469 | 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) |