common: New function hex2fixedbuf.
authorWerner Koch <wk@gnupg.org>
Tue, 1 Oct 2019 08:32:31 +0000 (10:32 +0200)
committerWerner Koch <wk@gnupg.org>
Tue, 1 Oct 2019 08:32:31 +0000 (10:32 +0200)
* common/convert.c (hex2fixedbuf): New.
--

This function is useful for converting hex strings received via assuan
if they have a known length.  For example keygrips or the new UBID.

Signed-off-by: Werner Koch <wk@gnupg.org>
common/convert.c
common/t-convert.c
common/util.h

index 40fb4ee..54182e1 100644 (file)
@@ -191,7 +191,7 @@ bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
    HEXSTRING.
 
    On success the function returns a pointer to the next character
-   after HEXSTRING (which is either end-of-string or the next white
+   after HEXSTRING (which is either end-of-string or the next white
    space).  If BUFLEN is not NULL the number of valid vytes in BUFFER
    is stored there (an extra Nul byte is not counted); this will even
    be done if BUFFER has been passed as NULL. */
@@ -264,3 +264,34 @@ hex2str_alloc (const char *hexstring, size_t *r_count)
     BUG ();
   return result;
 }
+
+
+
+/* Take the hex-encoded string HEXSTR and put it into the provided
+ * BUFFER in binary format.  The length of the buffer is BUFEFR_SIZE
+ * and the expected size of the hex-string (sans leading and trailing
+ * spaces) is 2*BUFFER_SIZE.  Returns the actual scanned length of
+ * HEXSTR including any leading and trailing spaces on success or 0 on
+ * error.  The HEXSTR must be terminated by a Space or a Nul and may
+ * have leading spaces.  */
+unsigned int
+hex2fixedbuf (const char *hexstr, void *buffer_arg, size_t buffer_size)
+{
+  unsigned char *buffer = buffer_arg;
+  const char *s;
+  unsigned int leading_spaces, n;
+
+  for (leading_spaces = 0; *hexstr && *hexstr == ' '; hexstr++)
+    leading_spaces++;
+
+  for (s=hexstr, n=0; hexdigitp (s); s++, n++)
+    ;
+  if ((*s && *s != ' ') || !(n == 2*buffer_size))
+    return 0; /* Invalid or wrong length. */
+  for (s=hexstr, n=0; *s && n < buffer_size; s += 2, n++)
+    buffer[n] = xtoi_2 (s);
+  while (*s && *s == ' ')
+    s++;
+
+  return leading_spaces + (s - hexstr);
+}
index e25de90..c7ba8f6 100644 (file)
@@ -445,6 +445,43 @@ test_hex2str (void)
 
 
 
+static void
+test_hex2fixedbuf (void)
+{
+  static struct {
+    const char *hex;
+    unsigned bufsize;
+    unsigned int resultlen;
+    const char *result;
+  } tests[] = {
+    /* Simple tests.  */
+    { "112233445566778899aabbccddeeff1122", 17, 34,
+      "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22"},
+    { " 112233445566778899aabbccddeeff1122", 17, 35,
+      "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22"},
+    { "112233445566778899aabbccddeeff1122 ", 17, 35,
+      "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22"},
+    { "  112233445566778899aabbccddeeff1122 ", 17, 37,
+      "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11\x22"},
+    { "  112233445566778899aabbccddeeff11 ", 16, 35,
+      "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11"},
+    { "  112233445566778899aabbccddeeff11", 16, 34,
+      "\x11\x22\x33\x44\x55\x66\x77\x88\x99\xaa\xbb\xcc\xdd\xee\xff\x11"}
+  };
+  char buffer[100];  /* Large enough for all tests.  */
+  int idx;
+  unsigned int n;
+
+  for (idx=0; idx < DIM (tests); idx++)
+    {
+      n = hex2fixedbuf (tests[idx].hex, buffer, tests[idx].bufsize);
+      if (n != tests[idx].resultlen)
+        fail (idx);
+      else if (memcmp (buffer, tests[idx].result, tests[idx].bufsize))
+        fail (idx);
+    }
+
+}
 
 
 int
@@ -458,6 +495,7 @@ main (int argc, char **argv)
   test_bin2hex ();
   test_bin2hexcolon ();
   test_hex2str ();
+  test_hex2fixedbuf ();
 
   return 0;
 }
index 8f8a06a..6c87808 100644 (file)
@@ -206,6 +206,7 @@ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
 const char *hex2str (const char *hexstring,
                      char *buffer, size_t bufsize, size_t *buflen);
 char *hex2str_alloc (const char *hexstring, size_t *r_count);
+unsigned int hex2fixedbuf (const char *hexstr, void *buffer, size_t bufsize);
 
 /*-- percent.c --*/
 char *percent_plus_escape (const char *string);