]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- xfr-tsig, algorithm table.
authorW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 13 Jun 2025 08:15:41 +0000 (10:15 +0200)
committerW.C.A. Wijngaards <wouter@nlnetlabs.nl>
Fri, 13 Jun 2025 08:15:41 +0000 (10:15 +0200)
util/tsig.c
util/tsig.h

index bde33192661459130725a3a972793ea4e12b30ac..3d8243b44fe6a5bf7a0da80dc05219d1f6008e23 100644 (file)
 #include <openssl/evp.h>
 #include <openssl/hmac.h>
 
+/**
+ * The list of TSIG algorithms. It has short_name, wireformat_name,
+ * wireformat_name_len, digest, max_digest_size.
+ */
+static struct tsig_algorithm tsig_algorithm_table[] = {
+       { "hmac-md5",
+         (uint8_t*)"\x08hmac-md5\x07sig-alg\x03reg\x03int\x00", 26,
+         "md5", 16 },
+       { "hmac-sha1", (uint8_t*)"\x09hmac-sha1\x00", 11, "sha1", 20 },
+       { "hmac-sha224", (uint8_t*)"\x0Bhmac-sha224\x00", 13, "sha224", 28 },
+       { "hmac-sha256", (uint8_t*)"\x0Bhmac-sha256\x00", 13, "sha256", 32 },
+       { "hmac-sha384", (uint8_t*)"\x0Bhmac-sha384\x00", 13, "sha384", 48 },
+       { "hmac-sha512", (uint8_t*)"\x0Bhmac-sha512\x00", 13, "sha512", 64 }
+};
+
 int
 tsig_key_compare(const void* v1, const void* v2)
 {
@@ -113,6 +128,101 @@ void tsig_key_delete(struct tsig_key* key)
        free(key);
 }
 
+int
+tsig_algo_check_name(const char* algo_name)
+{
+       /* It is either the long name for md5, "hmac-md5.sig-alg.reg.int."
+        * or a short name, "hmac-sha256", or a digest name "sha256".
+        * The name is case insensitive. */
+       if(strncasecmp(algo_name, "hmac-", 5) == 0) {
+               /* The name starts with 'hmac-'. */
+               if(strncasecmp(algo_name+5, "sha", 3) == 0) {
+                       /* sha1 */
+                       if(strcasecmp(algo_name+8, "1") == 0 ||
+                               strcasecmp(algo_name+8, "1.") == 0)
+                               return 1;
+                       /* sha224 */
+                       if(strcasecmp(algo_name+8, "224") == 0 ||
+                               strcasecmp(algo_name+8, "224.") == 0)
+                               return 1;
+                       /* sha256 */
+                       if(strcasecmp(algo_name+8, "256") == 0 ||
+                               strcasecmp(algo_name+8, "256.") == 0)
+                               return 1;
+                       /* sha384 */
+                       if(strcasecmp(algo_name+8, "384") == 0 ||
+                               strcasecmp(algo_name+8, "384.") == 0)
+                               return 1;
+                       /* sha512 */
+                       if(strcasecmp(algo_name+8, "512") == 0 ||
+                               strcasecmp(algo_name+8, "512.") == 0)
+                               return 1;
+               }
+               if(strncasecmp(algo_name+5, "md5", 3) == 0) {
+                       /* 'hmac-md5' or 'hmac-md5.' */
+                       if(strcasecmp(algo_name+8, "") == 0 ||
+                               strcasecmp(algo_name+8, ".") == 0)
+                               return 1;
+                       if(strcasecmp(algo_name,
+                               "hmac-md5.sig-alg.reg.int.") == 0
+                         || strcasecmp(algo_name,
+                               "hmac-md5.sig-alg.reg.int") == 0)
+                               return 1;
+               }
+       }
+       if(strncasecmp(algo_name, "sha", 3) == 0) {
+               if(strcasecmp(algo_name+3, "1") == 0)
+                       return 1;
+               if(strcasecmp(algo_name+3, "224") == 0)
+                       return 1;
+               if(strcasecmp(algo_name+3, "256") == 0)
+                       return 1;
+               if(strcasecmp(algo_name+3, "384") == 0)
+                       return 1;
+               if(strcasecmp(algo_name+3, "512") == 0)
+                       return 1;
+       }
+       if(strcasecmp(algo_name, "md5") == 0)
+               return 1;
+       return 0;
+}
+
+struct tsig_algorithm*
+tsig_algo_find_name(const char* algo_name)
+{
+       size_t i;
+       char buf[40];
+       const char* lookfor = algo_name;
+       if(algo_name == NULL || algo_name[0] == 0 ||
+               strlen(algo_name)+5 >= sizeof(buf))
+               return NULL;
+       if(strncasecmp(algo_name, "hmac-", 5) != 0) {
+               snprintf(buf, sizeof(buf), "hmac-%s", algo_name);
+               lookfor = buf;
+               if(buf[strlen(buf)-1] == '.') {
+                       /* Remove trailing '.' */
+                       buf[strlen(buf)-1] = 0;
+               }
+       } else {
+               if(algo_name[strlen(algo_name)-1] == '.') {
+                       /* Remove trailing '.' */
+                       snprintf(buf, sizeof(buf), "%s", algo_name);
+                       buf[strlen(buf)-1] = 0;
+                       lookfor = buf;
+               }
+               if(strcasecmp(lookfor, "hmac-md5.sig-alg.reg.int") == 0)
+                       lookfor = "hmac-md5";
+       }
+       
+       for(i=0; i<sizeof(tsig_algorithm_table)/sizeof(*tsig_algorithm_table);
+           i++) {
+               if(strcasecmp(tsig_algorithm_table[i].short_name, lookfor)
+                       == 0)
+                       return &tsig_algorithm_table[i];
+       }
+       return NULL;
+}
+
 /**
  * Skip packet query rr.
  * @param pkt: the packet, position before the rr, ends after the rr.
index 4b49fa2421e9f39dec8942b8d9e43939e4828bcc..eb4391d758b990cf346997da12dc0dc508d077c1 100644 (file)
@@ -91,6 +91,11 @@ struct tsig_algorithm {
        uint8_t* wireformat_name;
        /** length of the wireformat_name */
        size_t wireformat_name_len;
+       /** digest name, like "md5" */
+       const char* digest;
+       /** the maximum size of the digest from the algorithm, in bytes,
+        * like 16 for MD5, and 20 for SHA1. */
+       size_t max_digest_size;
 };
 
 /**
@@ -147,6 +152,20 @@ void tsig_key_table_delete(struct tsig_key_table* key_table);
  */
 void tsig_key_delete(struct tsig_key* key);
 
+/**
+ * See if an algorithm name is in the list of accepted algorithm names.
+ * @param algo_name: string to check
+ * @return 0 on failure.
+ */
+int tsig_algo_check_name(const char* algo_name);
+
+/**
+ * Get the TSIG algorithm for the algorithm name.
+ * @param algo_name: string to find.
+ * @return NULL on failure, tsig algorithm structure.
+ */
+struct tsig_algorithm* tsig_algo_find_name(const char* algo_name);
+
 /**
  * Verify pkt with the name (domain name), algorithm and key.
  * out 0 on success, an error code otherwise.