]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
Optimize selecting the signing key
authorOndřej Surý <ondrej@isc.org>
Thu, 11 Jan 2024 12:58:52 +0000 (13:58 +0100)
committerMichał Kępień <michal@isc.org>
Thu, 1 Feb 2024 20:47:29 +0000 (21:47 +0100)
Don't parse the crypto data before parsing and matching the id and the
algorithm for consecutive DNSKEYs.  This allows us to parse the RData
only in case the other parameters match allowing us to skip keys that
are of no interest to us, but still would consume precious CPU time by
parsing possibly garbage with OpenSSL.

lib/dns/dst_api.c
lib/dns/include/dst/dst.h
lib/dns/validator.c

index 4ffda8b35815e0759853a2a88d00989ca24f0e6a..0658c691a8000b51fbf990bc1f523fb88a55af26 100644 (file)
@@ -164,7 +164,8 @@ computeid(dst_key_t *key);
 static isc_result_t
 frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
           unsigned int protocol, dns_rdataclass_t rdclass,
-          isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
+          isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+          dst_key_t **keyp);
 
 static isc_result_t
 algorithm_status(unsigned int alg);
@@ -753,6 +754,13 @@ dst_key_todns(const dst_key_t *key, isc_buffer_t *target) {
 isc_result_t
 dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
                isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
+       return (dst_key_fromdns_ex(name, rdclass, source, mctx, false, keyp));
+}
+
+isc_result_t
+dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
+                  isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+                  dst_key_t **keyp) {
        uint8_t alg, proto;
        uint32_t flags, extflags;
        dst_key_t *key = NULL;
@@ -783,7 +791,7 @@ dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
        }
 
        result = frombuffer(name, alg, flags, proto, rdclass, source, mctx,
-                           &key);
+                           no_rdata, &key);
        if (result != ISC_R_SUCCESS) {
                return (result);
        }
@@ -804,7 +812,7 @@ dst_key_frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
        REQUIRE(dst_initialized);
 
        result = frombuffer(name, alg, flags, protocol, rdclass, source, mctx,
-                           &key);
+                           false, &key);
        if (result != ISC_R_SUCCESS) {
                return (result);
        }
@@ -2351,7 +2359,8 @@ computeid(dst_key_t *key) {
 static isc_result_t
 frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
           unsigned int protocol, dns_rdataclass_t rdclass,
-          isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp) {
+          isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+          dst_key_t **keyp) {
        dst_key_t *key;
        isc_result_t ret;
 
@@ -2376,10 +2385,12 @@ frombuffer(const dns_name_t *name, unsigned int alg, unsigned int flags,
                        return (DST_R_UNSUPPORTEDALG);
                }
 
-               ret = key->func->fromdns(key, source);
-               if (ret != ISC_R_SUCCESS) {
-                       dst_key_free(&key);
-                       return (ret);
+               if (!no_rdata) {
+                       ret = key->func->fromdns(key, source);
+                       if (ret != ISC_R_SUCCESS) {
+                               dst_key_free(&key);
+                               return (ret);
+                       }
                }
        }
 
index ca292b0ef0400949d6e85c9880e1bddc32d53238..f845e9bd2e75588669d2e45259fa20e247e1dabb 100644 (file)
@@ -482,6 +482,10 @@ dst_key_tofile(const dst_key_t *key, int type, const char *directory);
  */
 
 isc_result_t
+dst_key_fromdns_ex(const dns_name_t *name, dns_rdataclass_t rdclass,
+                  isc_buffer_t *source, isc_mem_t *mctx, bool no_rdata,
+                  dst_key_t **keyp);
+isc_result_t
 dst_key_fromdns(const dns_name_t *name, dns_rdataclass_t rdclass,
                isc_buffer_t *source, isc_mem_t *mctx, dst_key_t **keyp);
 /*%<
index 4dd170604e738cc6dbc3e9475de4c8f2d68a5b5c..47c48131fbe698c875a4ecb99139193044b9e7a6 100644 (file)
@@ -1118,6 +1118,7 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
        isc_buffer_t b;
        dns_rdata_t rdata = DNS_RDATA_INIT;
        dst_key_t *oldkey = val->key;
+       bool no_rdata = false;
 
        if (oldkey == NULL) {
                result = dns_rdataset_first(rdataset);
@@ -1127,7 +1128,7 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
                result = dns_rdataset_next(rdataset);
        }
        if (result != ISC_R_SUCCESS) {
-               goto failure;
+               goto done;
        }
 
        do {
@@ -1136,8 +1137,9 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
                isc_buffer_init(&b, rdata.data, rdata.length);
                isc_buffer_add(&b, rdata.length);
                INSIST(val->key == NULL);
-               result = dst_key_fromdns(&siginfo->signer, rdata.rdclass, &b,
-                                        val->view->mctx, &val->key);
+               result = dst_key_fromdns_ex(&siginfo->signer, rdata.rdclass, &b,
+                                           val->view->mctx, no_rdata,
+                                           &val->key);
                if (result == ISC_R_SUCCESS) {
                        if (siginfo->algorithm ==
                                    (dns_secalg_t)dst_key_alg(val->key) &&
@@ -1147,18 +1149,24 @@ select_signing_key(dns_validator_t *val, dns_rdataset_t *rdataset) {
                                    0 &&
                            dst_key_iszonekey(val->key))
                        {
-                               /*
-                                * This is the key we're looking for.
-                                */
-                               return (ISC_R_SUCCESS);
+                               if (no_rdata) {
+                                       /* Retry with full key */
+                                       dns_rdata_reset(&rdata);
+                                       dst_key_free(&val->key);
+                                       no_rdata = false;
+                                       continue;
+                               }
+                               /* This is the key we're looking for. */
+                               goto done;
                        }
                        dst_key_free(&val->key);
                }
                dns_rdata_reset(&rdata);
                result = dns_rdataset_next(rdataset);
+               no_rdata = true;
        } while (result == ISC_R_SUCCESS);
 
-failure:
+done:
        if (result == ISC_R_NOMORE) {
                result = ISC_R_NOTFOUND;
        }