<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">diff --git a/lib/dns/include/dns/message.h b/lib/dns/include/dns/message.h
index f9c82f023dd..2c2a19f2d58 100644
--- a/lib/dns/include/dns/message.h
+++ b/lib/dns/include/dns/message.h
@@ -280,18 +280,16 @@ struct dns_message {
 	ISC_LIST(dns_rdata_t) freerdata;
 	ISC_LIST(dns_rdatalist_t) freerdatalist;
 
-	dns_rcode_t tsigstatus;
-	dns_rcode_t querytsigstatus;
-	dns_name_t *tsigname; /* Owner name of TSIG, if any
-			       * */
+	dns_rcode_t	tsigstatus;
+	dns_rcode_t	querytsigstatus;
+	dns_name_t     *tsigname; /* Owner name of TSIG, if any */
 	dns_rdataset_t *querytsig;
 	dns_tsigkey_t  *tsigkey;
 	dst_context_t  *tsigctx;
 	int		sigstart;
 	int		timeadjust;
 
-	dns_name_t *sig0name; /* Owner name of SIG0, if any
-			       * */
+	dns_name_t  *sig0name; /* Owner name of SIG0, if any */
 	dst_key_t   *sig0key;
 	dns_rcode_t  sig0status;
 	isc_region_t query;
diff --git a/lib/dns/include/dns/tsig.h b/lib/dns/include/dns/tsig.h
index edd0694df04..1f1f4af7339 100644
--- a/lib/dns/include/dns/tsig.h
+++ b/lib/dns/include/dns/tsig.h
@@ -79,12 +79,14 @@ struct dns_tsigkeyring {
 
 struct dns_tsigkey {
 	/* Unlocked */
-	unsigned int	   magic; /*%&lt; Magic number. */
-	isc_mem_t	  *mctx;
-	dst_key_t	  *key; /*%&lt; Key */
-	dns_fixedname_t	   fn;
-	dns_name_t	  *name;	  /*%&lt; Key name */
-	const dns_name_t  *algorithm;	  /*%&lt; Algorithm name */
+	unsigned int	magic; /*%&lt; Magic number. */
+	isc_mem_t      *mctx;
+	dst_key_t      *key; /*%&lt; Key */
+	dns_fixedname_t fn;
+	dns_name_t     *name;		  /*%&lt; Key name */
+	dst_algorithm_t alg;		  /*&lt; Algorithm */
+	dns_name_t	algname;	  /*&lt; Algorithm name, only used if
+					    algorithm is DST_ALG_UNKNOWN */
 	dns_name_t	  *creator;	  /*%&lt; name that created secret */
 	bool		   generated : 1; /*%&lt; key was auto-generated */
 	bool		   restored  : 1; /*%&lt; key was restored at startup */
@@ -240,6 +242,16 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkeyp, const dns_name_t *name,
  *\li		#ISC_R_NOTFOUND
  */
 
+const dns_name_t *
+dns_tsigkey_algorithm(dns_tsigkey_t *tkey);
+/*%&lt;
+ * 	Returns the key algorithm associated with a tsigkey object.
+ *
+ * 	Note that when a tsigkey object is created with algorithm
+ * 	DST_ALG_UNKNOWN, the unknown algorithm's name must be cloned
+ * 	into tsigkey-&gt;algname.
+ */
+
 void
 dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsigkeyring_t **ringp);
 /*%&lt;
diff --git a/lib/dns/message.c b/lib/dns/message.c
index 04699cfad59..468ef43fc3b 100644
--- a/lib/dns/message.c
+++ b/lib/dns/message.c
@@ -680,12 +680,11 @@ msgreset(dns_message_t *msg, bool everything) {
 
 static unsigned int
 spacefortsig(dns_tsigkey_t *key, int otherlen) {
-	isc_region_t r1, r2;
-	unsigned int x;
-	isc_result_t result;
+	isc_region_t r1 = { 0 }, r2 = { 0 };
+	unsigned int x = 0;
 
 	/*
-	 * The space required for an TSIG record is:
+	 * The space required for a TSIG record is:
 	 *
 	 *	n1 bytes for the name
 	 *	2 bytes for the type
@@ -706,11 +705,11 @@ spacefortsig(dns_tsigkey_t *key, int otherlen) {
 	 */
 
 	dns_name_toregion(key-&gt;name, &amp;r1);
-	dns_name_toregion(key-&gt;algorithm, &amp;r2);
-	if (key-&gt;key == NULL) {
-		x = 0;
-	} else {
-		result = dst_key_sigsize(key-&gt;key, &amp;x);
+	if (key-&gt;alg != DST_ALG_UNKNOWN) {
+		dns_name_toregion(dns_tsigkey_algorithm(key), &amp;r2);
+	}
+	if (key-&gt;key != NULL) {
+		isc_result_t result = dst_key_sigsize(key-&gt;key, &amp;x);
 		if (result != ISC_R_SUCCESS) {
 			x = 0;
 		}
diff --git a/lib/dns/tsig.c b/lib/dns/tsig.c
index a6b839cdcf5..25b9c7f5082 100644
--- a/lib/dns/tsig.c
+++ b/lib/dns/tsig.c
@@ -205,28 +205,6 @@ adjust_lru(dns_tsigkey_t *tkey) {
 	}
 }
 
-static const dns_name_t *
-namefromalg(dst_algorithm_t alg) {
-	switch (alg) {
-	case DST_ALG_HMACMD5:
-		return dns_tsig_hmacmd5_name;
-	case DST_ALG_HMACSHA1:
-		return dns_tsig_hmacsha1_name;
-	case DST_ALG_HMACSHA224:
-		return dns_tsig_hmacsha224_name;
-	case DST_ALG_HMACSHA256:
-		return dns_tsig_hmacsha256_name;
-	case DST_ALG_HMACSHA384:
-		return dns_tsig_hmacsha384_name;
-	case DST_ALG_HMACSHA512:
-		return dns_tsig_hmacsha512_name;
-	case DST_ALG_GSSAPI:
-		return dns_tsig_gssapi_name;
-	default:
-		return NULL;
-	}
-}
-
 isc_result_t
 dns_tsigkey_createfromkey(const dns_name_t *name, dst_algorithm_t algorithm,
 			  dst_key_t *dstkey, bool generated, bool restored,
@@ -246,6 +224,8 @@ dns_tsigkey_createfromkey(const dns_name_t *name, dst_algorithm_t algorithm,
 		.restored = restored,
 		.inception = inception,
 		.expire = expire,
+		.alg = algorithm,
+		.algname = DNS_NAME_INITEMPTY,
 		.link = ISC_LINK_INITIALIZER,
 	};
 
@@ -263,8 +243,6 @@ dns_tsigkey_createfromkey(const dns_name_t *name, dst_algorithm_t algorithm,
 		goto cleanup_name;
 	}
 
-	tkey-&gt;algorithm = namefromalg(algorithm);
-
 	if (creator != NULL) {
 		tkey-&gt;creator = isc_mem_get(mctx, sizeof(dns_name_t));
 		dns_name_init(tkey-&gt;creator, NULL);
@@ -448,7 +426,8 @@ dump_key(dns_tsigkey_t *tkey, FILE *fp) {
 
 	dns_name_format(tkey-&gt;name, namestr, sizeof(namestr));
 	dns_name_format(tkey-&gt;creator, creatorstr, sizeof(creatorstr));
-	dns_name_format(tkey-&gt;algorithm, algorithmstr, sizeof(algorithmstr));
+	dns_name_format(dns_tsigkey_algorithm(tkey), algorithmstr,
+			sizeof(algorithmstr));
 	result = dst_key_dump(tkey-&gt;key, tkey-&gt;mctx, &amp;buffer, &amp;length);
 	if (result == ISC_R_SUCCESS) {
 		fprintf(fp, "%s %s %u %u %s %.*s\n", namestr, creatorstr,
@@ -621,7 +600,7 @@ dns_tsig_sign(dns_message_t *msg) {
 	};
 
 	dns_name_init(&amp;tsig.algorithm, NULL);
-	dns_name_clone(key-&gt;algorithm, &amp;tsig.algorithm);
+	dns_name_clone(dns_tsigkey_algorithm(key), &amp;tsig.algorithm);
 
 	isc_buffer_init(&amp;databuf, data, sizeof(data));
 
@@ -978,12 +957,17 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
 		}
 		if (result != ISC_R_SUCCESS) {
 			msg-&gt;tsigstatus = dns_tsigerror_badkey;
-			result = dns_tsigkey_create(
-				keyname, dns__tsig_algfromname(&amp;tsig.algorithm),
-				NULL, 0, mctx, &amp;msg-&gt;tsigkey);
+			alg = dns__tsig_algfromname(&amp;tsig.algorithm);
+			result = dns_tsigkey_create(keyname, alg, NULL, 0, mctx,
+						    &amp;msg-&gt;tsigkey);
 			if (result != ISC_R_SUCCESS) {
 				return result;
 			}
+			if (alg == DST_ALG_UNKNOWN) {
+				dns_name_clone(&amp;tsig.algorithm,
+					       &amp;msg-&gt;tsigkey-&gt;algname);
+			}
+
 			tsig_log(msg-&gt;tsigkey, 2, "unknown key");
 			return DNS_R_TSIGVERIFYFAILURE;
 		}
@@ -1107,7 +1091,7 @@ dns_tsig_verify(isc_buffer_t *source, dns_message_t *msg,
 		/*
 		 * Digest the key algorithm.
 		 */
-		dns_name_toregion(tsigkey-&gt;algorithm, &amp;r);
+		dns_name_toregion(dns_tsigkey_algorithm(tsigkey), &amp;r);
 		result = dst_context_adddata(ctx, &amp;r);
 		if (result != ISC_R_SUCCESS) {
 			goto cleanup_context;
@@ -1555,7 +1539,8 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
 		RWUNLOCK(&amp;ring-&gt;lock, locktype);
 		return result;
 	}
-	if (algorithm != NULL &amp;&amp; !dns_name_equal(key-&gt;algorithm, algorithm)) {
+
+	if (algorithm != NULL &amp;&amp; key-&gt;alg != dns__tsig_algfromname(algorithm)) {
 		RWUNLOCK(&amp;ring-&gt;lock, locktype);
 		return ISC_R_NOTFOUND;
 	}
@@ -1581,6 +1566,39 @@ dns_tsigkey_find(dns_tsigkey_t **tsigkey, const dns_name_t *name,
 	return ISC_R_SUCCESS;
 }
 
+const dns_name_t *
+dns_tsigkey_algorithm(dns_tsigkey_t *tkey) {
+	REQUIRE(VALID_TSIGKEY(tkey));
+
+	switch (tkey-&gt;alg) {
+	case DST_ALG_HMACMD5:
+		return dns_tsig_hmacmd5_name;
+	case DST_ALG_HMACSHA1:
+		return dns_tsig_hmacsha1_name;
+	case DST_ALG_HMACSHA224:
+		return dns_tsig_hmacsha224_name;
+	case DST_ALG_HMACSHA256:
+		return dns_tsig_hmacsha256_name;
+	case DST_ALG_HMACSHA384:
+		return dns_tsig_hmacsha384_name;
+	case DST_ALG_HMACSHA512:
+		return dns_tsig_hmacsha512_name;
+	case DST_ALG_GSSAPI:
+		return dns_tsig_gssapi_name;
+
+	case DST_ALG_UNKNOWN:
+		/*
+		 * If the tsigkey object was created with an
+		 * unknown algorithm, then we cloned
+		 * the algorithm name here.
+		 */
+		return &amp;tkey-&gt;algname;
+
+	default:
+		UNREACHABLE();
+	}
+}
+
 void
 dns_tsigkeyring_create(isc_mem_t *mctx, dns_tsigkeyring_t **ringp) {
 	dns_tsigkeyring_t *ring = NULL;
diff --git a/tests/dns/tsig_test.c b/tests/dns/tsig_test.c
index 48adbab5a33..ef0a5b3c26a 100644
--- a/tests/dns/tsig_test.c
+++ b/tests/dns/tsig_test.c
@@ -118,7 +118,7 @@ add_tsig(dst_context_t *tsigctx, dns_tsigkey_t *key, isc_buffer_t *target,
 	tsig.common.rdtype = dns_rdatatype_tsig;
 	ISC_LINK_INIT(&amp;tsig.common, link);
 	dns_name_init(&amp;tsig.algorithm, NULL);
-	dns_name_clone(key-&gt;algorithm, &amp;tsig.algorithm);
+	dns_name_clone(dns_tsigkey_algorithm(key), &amp;tsig.algorithm);
 
 	tsig.timesigned = now;
 	tsig.fudge = DNS_TSIG_FUDGE;
</pre></body></html>