common: New function hex2fixedbuf.

* 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>
This commit is contained in:
Werner Koch 2019-10-01 10:32:31 +02:00
parent a605dbb430
commit 61765136cf
No known key found for this signature in database
GPG Key ID: E3FDFF218E45B72B
3 changed files with 71 additions and 1 deletions

View File

@ -191,7 +191,7 @@ bin2hexcolon (const void *buffer, size_t length, char *stringbuf)
HEXSTRING. HEXSTRING.
On success the function returns a pointer to the next character On success the function returns a pointer to the next character
after HEXSTRING (which is either end-of-string or a 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 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 is stored there (an extra Nul byte is not counted); this will even
be done if BUFFER has been passed as NULL. */ be done if BUFFER has been passed as NULL. */
@ -264,3 +264,34 @@ hex2str_alloc (const char *hexstring, size_t *r_count)
BUG (); BUG ();
return result; 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);
}

View 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 int
@ -458,6 +495,7 @@ main (int argc, char **argv)
test_bin2hex (); test_bin2hex ();
test_bin2hexcolon (); test_bin2hexcolon ();
test_hex2str (); test_hex2str ();
test_hex2fixedbuf ();
return 0; return 0;
} }

View File

@ -206,6 +206,7 @@ char *bin2hexcolon (const void *buffer, size_t length, char *stringbuf);
const char *hex2str (const char *hexstring, const char *hex2str (const char *hexstring,
char *buffer, size_t bufsize, size_t *buflen); char *buffer, size_t bufsize, size_t *buflen);
char *hex2str_alloc (const char *hexstring, size_t *r_count); char *hex2str_alloc (const char *hexstring, size_t *r_count);
unsigned int hex2fixedbuf (const char *hexstr, void *buffer, size_t bufsize);
/*-- percent.c --*/ /*-- percent.c --*/
char *percent_plus_escape (const char *string); char *percent_plus_escape (const char *string);