]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Implement digest_sig and digest_rrsig for ZONEMD
authorMark Andrews <marka@isc.org>
Wed, 23 Jun 2021 09:51:51 +0000 (19:51 +1000)
committerMark Andrews <marka@isc.org>
Wed, 5 Mar 2025 10:34:52 +0000 (10:34 +0000)
ZONEMD needs to be able to digest SIG and RRSIG records.  The signer
field can be compressed in SIG so we need to call dns_name_digest().
While for RRSIG the records the signer field is not compressed the
canonical form has the signer field downcased (RFC 4034, 6.2).  This
also implies that compare_rrsig needs to downcase the signer field
during comparison.

(cherry picked from commit 006c5990ce88aa5b5869a6140392ef80f38e415a)

lib/dns/rdata/generic/rrsig_46.c
lib/dns/rdata/generic/sig_24.c

index 2cc315bdeab687dde3b26c833b77b20121a7c548..2fb197b300deee32217602acb49e0defc838e4f5 100644 (file)
@@ -361,6 +361,9 @@ static int
 compare_rrsig(ARGS_COMPARE) {
        isc_region_t r1;
        isc_region_t r2;
+       dns_name_t name1;
+       dns_name_t name2;
+       int order;
 
        REQUIRE(rdata1->type == rdata2->type);
        REQUIRE(rdata1->rdclass == rdata2->rdclass);
@@ -370,6 +373,32 @@ compare_rrsig(ARGS_COMPARE) {
 
        dns_rdata_toregion(rdata1, &r1);
        dns_rdata_toregion(rdata2, &r2);
+
+       INSIST(r1.length > 18);
+       INSIST(r2.length > 18);
+       r1.length = 18;
+       r2.length = 18;
+       order = isc_region_compare(&r1, &r2);
+       if (order != 0) {
+               return order;
+       }
+
+       dns_name_init(&name1, NULL);
+       dns_name_init(&name2, NULL);
+       dns_rdata_toregion(rdata1, &r1);
+       dns_rdata_toregion(rdata2, &r2);
+       isc_region_consume(&r1, 18);
+       isc_region_consume(&r2, 18);
+       dns_name_fromregion(&name1, &r1);
+       dns_name_fromregion(&name2, &r2);
+       order = dns_name_rdatacompare(&name1, &name2);
+       if (order != 0) {
+               return order;
+       }
+
+       isc_region_consume(&r1, name_length(&name1));
+       isc_region_consume(&r2, name_length(&name2));
+
        return isc_region_compare(&r1, &r2);
 }
 
@@ -547,13 +576,32 @@ additionaldata_rrsig(ARGS_ADDLDATA) {
 
 static isc_result_t
 digest_rrsig(ARGS_DIGEST) {
+       isc_region_t r1, r2;
+       dns_name_t name;
+
        REQUIRE(rdata->type == dns_rdatatype_rrsig);
 
-       UNUSED(rdata);
-       UNUSED(digest);
-       UNUSED(arg);
+       dns_rdata_toregion(rdata, &r1);
+       r2 = r1;
+
+       /*
+        * Type covered (2) + Algorithm (1) +
+        * Labels (1) + Original TTL (4) +
+        * Expire time (4) +  Time signed (4) +
+        * Key ID (2).
+        */
+       isc_region_consume(&r2, 18);
+       r1.length = 18;
+       RETERR((digest)(arg, &r1));
 
-       return ISC_R_NOTIMPLEMENTED;
+       /* Signer */
+       dns_name_init(&name, NULL);
+       dns_name_fromregion(&name, &r2);
+       RETERR(dns_name_digest(&name, digest, arg));
+       isc_region_consume(&r2, name_length(&name));
+
+       /* Signature */
+       return (digest)(arg, &r2);
 }
 
 static dns_rdatatype_t
@@ -594,47 +642,7 @@ checknames_rrsig(ARGS_CHECKNAMES) {
 
 static int
 casecompare_rrsig(ARGS_COMPARE) {
-       isc_region_t r1;
-       isc_region_t r2;
-       dns_name_t name1;
-       dns_name_t name2;
-       int order;
-
-       REQUIRE(rdata1->type == rdata2->type);
-       REQUIRE(rdata1->rdclass == rdata2->rdclass);
-       REQUIRE(rdata1->type == dns_rdatatype_rrsig);
-       REQUIRE(rdata1->length != 0);
-       REQUIRE(rdata2->length != 0);
-
-       dns_rdata_toregion(rdata1, &r1);
-       dns_rdata_toregion(rdata2, &r2);
-
-       INSIST(r1.length > 18);
-       INSIST(r2.length > 18);
-       r1.length = 18;
-       r2.length = 18;
-       order = isc_region_compare(&r1, &r2);
-       if (order != 0) {
-               return order;
-       }
-
-       dns_name_init(&name1, NULL);
-       dns_name_init(&name2, NULL);
-       dns_rdata_toregion(rdata1, &r1);
-       dns_rdata_toregion(rdata2, &r2);
-       isc_region_consume(&r1, 18);
-       isc_region_consume(&r2, 18);
-       dns_name_fromregion(&name1, &r1);
-       dns_name_fromregion(&name2, &r2);
-       order = dns_name_rdatacompare(&name1, &name2);
-       if (order != 0) {
-               return order;
-       }
-
-       isc_region_consume(&r1, name_length(&name1));
-       isc_region_consume(&r2, name_length(&name2));
-
-       return isc_region_compare(&r1, &r2);
+       return compare_rrsig(rdata1, rdata2);
 }
 
 #endif /* RDATA_GENERIC_RRSIG_46_C */
index 92bbc790ddd14e3a988c1a51a7e244153116b444..31b293c589a144e86e8c8253d1e0f40524d0e6fe 100644 (file)
@@ -539,13 +539,32 @@ additionaldata_sig(ARGS_ADDLDATA) {
 
 static isc_result_t
 digest_sig(ARGS_DIGEST) {
+       isc_region_t r1, r2;
+       dns_name_t name;
+
        REQUIRE(rdata->type == dns_rdatatype_sig);
 
-       UNUSED(rdata);
-       UNUSED(digest);
-       UNUSED(arg);
+       dns_rdata_toregion(rdata, &r1);
+       r2 = r1;
+
+       /*
+        * Type covered (2) + Algorithm (1) +
+        * Labels (1) + Original TTL (4) +
+        * Expire time (4) +  Time signed (4) +
+        * Key ID (2).
+        */
+       isc_region_consume(&r2, 18);
+       r1.length = 18;
+       RETERR((digest)(arg, &r1));
+
+       /* Signer */
+       dns_name_init(&name, NULL);
+       dns_name_fromregion(&name, &r2);
+       RETERR(dns_name_digest(&name, digest, arg));
+       isc_region_consume(&r2, name_length(&name));
 
-       return ISC_R_NOTIMPLEMENTED;
+       /* Signature */
+       return (digest)(arg, &r2);
 }
 
 static dns_rdatatype_t