]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
enforce known SSHFP finger print lengths
authorMark Andrews <marka@isc.org>
Fri, 1 Feb 2019 07:18:34 +0000 (18:18 +1100)
committerMark Andrews <marka@isc.org>
Wed, 8 May 2019 22:11:43 +0000 (08:11 +1000)
CHANGES
lib/dns/rdata/generic/sshfp_44.c
lib/dns/tests/rdata_test.c

diff --git a/CHANGES b/CHANGES
index 1e5b2dd211aee199f078d78f659d7a2284f70396..f8b2ab0343dc50320c7c98bba914c2724d1af0da 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,5 @@
+5229.  [protocol]      Enforce known SSHFP fingerprint lengths. [GL #852]
+
 5228.  [func]          If trusted-keys and managed-keys were configured
                        simultaneously for the same name, the key could
                        not be be rolled automatically. This is now
index c4209f4abc93a02e64ae896771e039ce63bedf0a..ce60be5ae50c61cadaa1e0196ecb12137ad1af62 100644 (file)
@@ -20,6 +20,7 @@
 static inline isc_result_t
 fromtext_sshfp(ARGS_FROMTEXT) {
        isc_token_t token;
+       int len = -1;
 
        REQUIRE(type == dns_rdatatype_sshfp);
 
@@ -47,10 +48,24 @@ fromtext_sshfp(ARGS_FROMTEXT) {
                RETTOK(ISC_R_RANGE);
        RETERR(uint8_tobuffer(token.value.as_ulong, target));
 
+       /*
+        * Enforce known digest lengths.
+        */
+       switch (token.value.as_ulong) {
+       case 1:
+               len = ISC_SHA1_DIGESTLENGTH;
+               break;
+       case 2:
+               len = ISC_SHA256_DIGESTLENGTH;
+               break;
+       default:
+               break;
+       }
+
        /*
         * Digest.
         */
-       return (isc_hex_tobuffer(lexer, target, -2));
+       return (isc_hex_tobuffer(lexer, target, len));
 }
 
 static inline isc_result_t
@@ -82,6 +97,10 @@ totext_sshfp(ARGS_TOTEXT) {
        snprintf(buf, sizeof(buf), "%u", n);
        RETERR(str_totext(buf, target));
 
+       if (sr.length == 0U) {
+               return (ISC_R_SUCCESS);
+       }
+
        /*
         * Digest.
         */
@@ -110,8 +129,14 @@ fromwire_sshfp(ARGS_FROMWIRE) {
        UNUSED(options);
 
        isc_buffer_activeregion(source, &sr);
-       if (sr.length < 4)
+       if (sr.length < 2) {
                return (ISC_R_UNEXPECTEDEND);
+       }
+
+       if ((sr.base[1] == 1 && sr.length != ISC_SHA1_DIGESTLENGTH + 2) ||
+           (sr.base[1] == 2 && sr.length != ISC_SHA256_DIGESTLENGTH + 2)) {
+               return (DNS_R_FORMERR);
+       }
 
        isc_buffer_forward(source, sr.length);
        return (mem_tobuffer(target, sr.base, sr.length));
index e692b06e40be14cd9e563d01dc8fa1addd0b2b6f..22f33bcbb74c2c016bd324216a76ab9e74137d70 100644 (file)
@@ -2042,6 +2042,82 @@ rkey(void **state) {
                    dns_rdatatype_rkey, sizeof(dns_rdata_rkey_t));
 }
 
+/* SSHFP RDATA manipulations */
+static void
+sshfp(void **state) {
+       text_ok_t text_ok[] = {
+               TEXT_INVALID(""),       /* too short */
+               TEXT_INVALID("0"),      /* reserved, too short */
+               TEXT_VALID("0 0"),      /* no finger print */
+               TEXT_VALID("0 0 AA"),   /* reserved */
+               TEXT_INVALID("0 1 AA"), /* too short SHA 1 digest */
+               TEXT_INVALID("0 2 AA"), /* too short SHA 256 digest */
+               TEXT_VALID("0 3 AA"),   /* unknown finger print type */
+               /* good length SHA 1 digest */
+               TEXT_VALID("1 1 00112233445566778899AABBCCDDEEFF17181920"),
+               /* good length SHA 256 digest */
+               TEXT_VALID("4 2 A87F1B687AC0E57D2A081A2F282672334D90ED316D2B818CA9580EA3 84D92401"),
+               /*
+                * totext splits the fingerprint into chunks and
+                * emits uppercase hex.
+                */
+               TEXT_VALID_CHANGED("1 2 00112233445566778899aabbccddeeff "
+                                  "00112233445566778899AABBCCDDEEFF",
+                                  "1 2 00112233445566778899AABBCCDDEEFF"
+                                  "00112233445566778899AABB CCDDEEFF"),
+               TEXT_SENTINEL()
+       };
+       wire_ok_t wire_ok[] = {
+               WIRE_INVALID(0x00),             /* reserved too short */
+               WIRE_VALID(0x00, 0x00),         /* reserved no finger print */
+               WIRE_VALID(0x00, 0x00, 0x00),   /* reserved */
+
+               /* too short SHA 1 digests */
+               WIRE_INVALID(0x00, 0x01),
+               WIRE_INVALID(0x00, 0x01, 0x00),
+               WIRE_INVALID(0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
+                            0xEE, 0xFF, 0x17, 0x18, 0x19),
+               /* good length SHA 1 digest */
+               WIRE_VALID(0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                          0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
+                          0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20),
+               /* too long SHA 1 digest */
+               WIRE_INVALID(0x00, 0x01, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
+                            0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21),
+               /* too short SHA 256 digests */
+               WIRE_INVALID(0x00, 0x02),
+               WIRE_INVALID(0x00, 0x02, 0x00),
+               WIRE_INVALID(0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
+                            0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22,
+                            0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
+                            0x31),
+               /* good length SHA 256 digest */
+               WIRE_VALID(0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                          0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
+                          0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22,
+                          0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
+                          0x31, 0x32),
+               /* too long SHA 256 digest */
+               WIRE_INVALID(0x00, 0x02, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55,
+                            0x66, 0x77, 0x88, 0x99, 0xAA, 0xBB, 0xCC, 0xDD,
+                            0xEE, 0xFF, 0x17, 0x18, 0x19, 0x20, 0x21, 0x22,
+                            0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x30,
+                            0x31, 0x32, 0x33),
+               /* unknown digest, * no fingerprint */
+               WIRE_VALID(0x00, 0x03),
+               WIRE_VALID(0x00, 0x03, 0x00),   /* unknown digest */
+               WIRE_SENTINEL()
+       };
+
+       UNUSED(state);
+
+       check_rdata(text_ok, wire_ok, NULL, false, dns_rdataclass_in,
+                   dns_rdatatype_sshfp, sizeof(dns_rdata_sshfp_t));
+}
+
 /*
  * WKS tests.
  *
@@ -2378,6 +2454,7 @@ main(int argc, char **argv) {
                cmocka_unit_test_setup_teardown(nsec, _setup, _teardown),
                cmocka_unit_test_setup_teardown(nsec3, _setup, _teardown),
                cmocka_unit_test_setup_teardown(nxt, _setup, _teardown),
+               cmocka_unit_test_setup_teardown(sshfp, _setup, _teardown),
                cmocka_unit_test_setup_teardown(wks, _setup, _teardown),
                cmocka_unit_test_setup_teardown(rkey, _setup, _teardown),
                cmocka_unit_test_setup_teardown(zonemd, _setup, _teardown),