diff --git a/CHANGES b/CHANGES
index 4e17e0333e..cdf0f42017 100644
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,6 @@
+3934. [bug] Catch bad 'sit-secret' in named-checkconf. Improve
+ sit-secrets documentation. [RT #36980]
+
3933. [bug] Corrected the implementation of dns_rdata_casecompare()
for the HIP rdata type. [RT #36911]
diff --git a/bin/tests/system/sit/bad-sit-badhex.conf b/bin/tests/system/sit/bad-sit-badhex.conf
new file mode 100644
index 0000000000..6b84d8a6a1
--- /dev/null
+++ b/bin/tests/system/sit/bad-sit-badhex.conf
@@ -0,0 +1,3 @@
+options {
+ sit-secret "012345678901234567890123456789012345678901234567890123456789012";
+};
diff --git a/bin/tests/system/sit/bad-sit-toolong.conf b/bin/tests/system/sit/bad-sit-toolong.conf
new file mode 100644
index 0000000000..aec4d252c8
--- /dev/null
+++ b/bin/tests/system/sit/bad-sit-toolong.conf
@@ -0,0 +1,3 @@
+options {
+ sit-secret "01234567890123456789012345678901234567890123456789012345678901234567890";
+};
diff --git a/bin/tests/system/sit/tests.sh b/bin/tests/system/sit/tests.sh
index fa1a71abb0..5842a98714 100755
--- a/bin/tests/system/sit/tests.sh
+++ b/bin/tests/system/sit/tests.sh
@@ -32,6 +32,15 @@ havetc() {
grep 'flags:.* tc[^;]*;' $1 > /dev/null
}
+for bad in bad*.conf
+do
+ ret=0
+ echo "I:checking that named-checkconf detects error in $bad"
+ $CHECKCONF $bad > /dev/null 2>&1
+ if [ $? != 1 ]; then echo "I:failed"; ret=1; fi
+ status=`expr $status + $ret`
+done
+
n=`expr $n + 1`
echo "I:checking SIT token returned to empty SIT option ($n)"
ret=0
diff --git a/doc/arm/Bv9ARM-book.xml b/doc/arm/Bv9ARM-book.xml
index 7562a331ed..01f2c207c3 100644
--- a/doc/arm/Bv9ARM-book.xml
+++ b/doc/arm/Bv9ARM-book.xml
@@ -6421,12 +6421,16 @@ options {
- sit-secret
+ sit-secret
+
If set, this is a shared secret used for generating
and verifying Source Identity Token EDNS options
within a anycast cluster. If not set the system
- will generate a random secret at startup.
+ will generate a random secret at startup. The
+ shared secret is encoded as a hex string and needs
+ to be 128 bits for AES128, 160 bits for SHA1 and
+ 256 bits for SHA256.
diff --git a/lib/bind9/check.c b/lib/bind9/check.c
index a8d5e00aa6..38c1b244ed 100644
--- a/lib/bind9/check.c
+++ b/lib/bind9/check.c
@@ -24,10 +24,12 @@
#include
#include
#include
+#include
#include
#include
#include
#include
+#include
#include
#include
#include
@@ -35,6 +37,18 @@
#include
#include
+#ifdef ISC_PLATFORM_USESIT
+#ifdef AES_SIT
+#include
+#endif
+#ifdef HMAC_SHA1_SIT
+#include
+#endif
+#ifdef HMAC_SHA256_SIT
+#include
+#endif
+#endif
+
#include
#include
#include
@@ -1186,6 +1200,52 @@ check_options(const cfg_obj_t *options, isc_log_t *logctx, isc_mem_t *mctx,
"(%d seconds)", recheck, lifetime);
}
+#ifdef ISC_PLATFORM_USESIT
+ obj = NULL;
+ (void) cfg_map_get(options, "sit-secret", &obj);
+ if (obj != NULL) {
+ isc_buffer_t b;
+ unsigned char secret[32];
+
+ memset(secret, 0, sizeof(secret));
+ isc_buffer_init(&b, secret, sizeof(secret));
+ tresult = isc_hex_decodestring(cfg_obj_asstring(obj), &b);
+ if (tresult == ISC_R_NOSPACE) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "sit-secret: too long");
+ } else if (tresult != ISC_R_SUCCESS) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "sit-secret: invalid hex string");
+ }
+ if (tresult != ISC_R_SUCCESS)
+ result = tresult;
+#ifdef AES_SIT
+ if (tresult == ISC_R_SUCCESS &&
+ isc_buffer_usedlength(&b) != ISC_AES128_KEYLENGTH) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "AES sit-secret must be on 128 bits");
+ result = ISC_R_RANGE;
+ }
+#endif
+#ifdef HMAC_SHA1_SIT
+ if (tresult == ISC_R_SUCCESS &&
+ isc_buffer_usedlength(&b) != ISC_SHA1_DIGESTLENGTH) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "SHA1 sit-secret must be on 160 bits");
+ result = ISC_R_RANGE;
+ }
+#endif
+#ifdef HMAC_SHA256_SIT
+ if (tresult == ISC_R_SUCCESS &&
+ isc_buffer_usedlength(&b) != ISC_SHA256_DIGESTLENGTH) {
+ cfg_obj_log(obj, logctx, ISC_LOG_ERROR,
+ "SHA256 sit-secret must be on 256 bits");
+ result = ISC_R_RANGE;
+ }
+#endif
+ }
+#endif
+
return (result);
}