mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-03 12:11:33 +01:00
g13: Add functions to handle uint in a keyblob.
* g13/utils.c (append_tuple_uint): New. (find_tuple_uint): New. * g13/t-utils.c: New. * g13/Makefile.am (noinst_PROGRAMS, TESTS): New. (module_tests, t_common_ldadd): New. (t_utils_SOURCES, t_utils_LDADD): New. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
dc1dbc43a6
commit
4f152f3276
@ -23,6 +23,9 @@ EXTRA_DIST = ChangeLog-2011
|
||||
bin_PROGRAMS = g13
|
||||
sbin_PROGRAMS = g13-syshelp
|
||||
|
||||
noinst_PROGRAMS = $(module_tests)
|
||||
TESTS = $(module_tests)
|
||||
|
||||
AM_CPPFLAGS = -I$(top_srcdir)/common
|
||||
|
||||
include $(top_srcdir)/am/cmacros.am
|
||||
@ -61,3 +64,14 @@ g13_syshelp_SOURCES = \
|
||||
g13_syshelp_LDADD = $(libcommon) \
|
||||
$(LIBGCRYPT_LIBS) $(LIBASSUAN_LIBS) \
|
||||
$(GPG_ERROR_LIBS) $(LIBINTL) $(LIBICONV)
|
||||
|
||||
|
||||
module_tests = t-utils
|
||||
t_common_ldadd = $(libcommon) $(LIBGCRYPT_LIBS) \
|
||||
$(LIBASSUAN_LIBS)
|
||||
|
||||
t_utils_SOURCES = t-utils.c utils.c
|
||||
t_utils_LDADD = $(t_common_ldadd)
|
||||
|
||||
|
||||
$(PROGRAMS) : $(libcommon) $(libcommonpth)
|
||||
|
223
g13/t-utils.c
Normal file
223
g13/t-utils.c
Normal file
@ -0,0 +1,223 @@
|
||||
/* t-utils.c - Module test for utils.c
|
||||
* Copyright (C) 2016 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
* GnuPG is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* GnuPG is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
|
||||
#include "util.h"
|
||||
#include "keyblob.h"
|
||||
#include "utils.h"
|
||||
|
||||
#define PGM "t-utils"
|
||||
|
||||
static int verbose;
|
||||
static int debug;
|
||||
static int errcount;
|
||||
|
||||
/* Test for the functions append_tuple_uint and find_tuple_unit. */
|
||||
static void
|
||||
test_tuple_uint (void)
|
||||
{
|
||||
static struct {
|
||||
int tag;
|
||||
int len;
|
||||
char *data;
|
||||
unsigned long long val;
|
||||
gpg_err_code_t ec;
|
||||
} tv[] = {
|
||||
{ 1, 0, "", 0, GPG_ERR_ERANGE },
|
||||
{ 2, 1, "\x00", 0, 0},
|
||||
{ 3, 1, "\x7f", 127ull, 0},
|
||||
{ 4, 1, "\x80", 0, GPG_ERR_ERANGE },
|
||||
{ 5, 1, "\x81", 0, GPG_ERR_ERANGE },
|
||||
{ 6, 2, "\x80\x01", 0, GPG_ERR_ERANGE },
|
||||
{ 7, 2, "\x00\x80", 128ull, 0 },
|
||||
{ 8, 1, "\x01", 1, 0 },
|
||||
{ 9, 1, "\x40", 64, 0 },
|
||||
{ 10, 2, "\x40\x00", 16384, 0 },
|
||||
{ 11, 8, "\x7f\xff\xff\xff\xff\xff\xff\xff", 0x7fffffffffffffffull, 0 },
|
||||
{ 12, 9, "\x00\xff\xff\xff\xff\xff\xff\xff\xff", 0xffffffffffffffffull, 0},
|
||||
{ 13, 9, "\x01\xff\xff\xff\xff\xff\xff\xff\xff", 0, GPG_ERR_ERANGE }
|
||||
};
|
||||
int tidx;
|
||||
gpg_error_t err;
|
||||
membuf_t mb, mb2;
|
||||
void *p;
|
||||
const void *s;
|
||||
size_t n;
|
||||
tupledesc_t tuples;
|
||||
tupledesc_t tuples2;
|
||||
unsigned long long value;
|
||||
int i;
|
||||
|
||||
init_membuf (&mb, 512);
|
||||
init_membuf (&mb2, 512);
|
||||
append_tuple (&mb, KEYBLOB_TAG_BLOBVERSION, "\x01", 1);
|
||||
append_tuple (&mb2, KEYBLOB_TAG_BLOBVERSION, "\x01", 1);
|
||||
for (tidx=0; tidx < DIM (tv); tidx++)
|
||||
{
|
||||
append_tuple (&mb, tv[tidx].tag, tv[tidx].data, tv[tidx].len);
|
||||
if (!tv[tidx].ec)
|
||||
append_tuple_uint (&mb2, tv[tidx].tag, tv[tidx].val);
|
||||
}
|
||||
|
||||
p = get_membuf (&mb, &n);
|
||||
if (!p)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
fprintf (stderr, PGM ":%s: get_membuf failed: %s\n",
|
||||
__func__, gpg_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
err = create_tupledesc (&tuples, p, n);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ":%s: create_tupledesc failed: %s\n",
|
||||
__func__, gpg_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
p = get_membuf (&mb2, &n);
|
||||
if (!p)
|
||||
{
|
||||
err = gpg_error_from_syserror ();
|
||||
fprintf (stderr, PGM ":%s: get_membuf failed: %s\n",
|
||||
__func__, gpg_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
err = create_tupledesc (&tuples2, p, n);
|
||||
if (err)
|
||||
{
|
||||
fprintf (stderr, PGM ":%s: create_tupledesc failed: %s\n",
|
||||
__func__, gpg_strerror (err));
|
||||
exit (1);
|
||||
}
|
||||
|
||||
for (tidx=0; tidx < DIM (tv); tidx++)
|
||||
{
|
||||
err = find_tuple_uint (tuples, tv[tidx].tag, &value);
|
||||
if (tv[tidx].ec != gpg_err_code (err))
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: wrong error returned; "
|
||||
"expected(%s) got(%s)\n",
|
||||
__func__, tidx,
|
||||
gpg_strerror (tv[tidx].ec), gpg_strerror (err));
|
||||
errcount++;
|
||||
}
|
||||
else if (!err && tv[tidx].val != value)
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: wrong value returned; "
|
||||
"expected(%llx) got(%llx)\n",
|
||||
__func__, tidx, tv[tidx].val, value);
|
||||
errcount++;
|
||||
}
|
||||
|
||||
err = find_tuple_uint (tuples2, tv[tidx].tag, &value);
|
||||
if (gpg_err_code (err) == GPG_ERR_NOT_FOUND)
|
||||
{
|
||||
if (!tv[tidx].ec)
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: find_tuple failed: %s\n",
|
||||
__func__, tidx, gpg_strerror (err));
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
else if (tv[tidx].ec != gpg_err_code (err))
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: wrong error returned (2); "
|
||||
"expected(%s) got(%s)\n",
|
||||
__func__, tidx,
|
||||
gpg_strerror (tv[tidx].ec), gpg_strerror (err));
|
||||
errcount++;
|
||||
}
|
||||
else if (!err && tv[tidx].val != value)
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: wrong value returned (2); "
|
||||
"expected(%llx) got(%llx)\n",
|
||||
__func__, tidx, tv[tidx].val, value);
|
||||
errcount++;
|
||||
}
|
||||
|
||||
s = find_tuple (tuples2, tv[tidx].tag, &n);
|
||||
if (!s)
|
||||
;
|
||||
else if (tv[tidx].len != n)
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: wrong string length returned; "
|
||||
"expected(%d) got(%zu)\n",
|
||||
__func__, tidx, tv[tidx].len, n);
|
||||
errcount++;
|
||||
}
|
||||
else if (memcmp (tv[tidx].data, s, n))
|
||||
{
|
||||
fprintf (stderr, PGM ":%s:tidx=%d: wrong string returned:",
|
||||
__func__, tidx);
|
||||
for (i=0; i < n; i++)
|
||||
fprintf (stderr, " %02x", ((unsigned char*)s)[i]);
|
||||
fputc ('\n', stderr);
|
||||
errcount++;
|
||||
}
|
||||
}
|
||||
|
||||
destroy_tupledesc (tuples);
|
||||
destroy_tupledesc (tuples2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int
|
||||
main (int argc, char **argv)
|
||||
{
|
||||
int last_argc = -1;
|
||||
|
||||
gpgrt_init ();
|
||||
if (argc)
|
||||
{ argc--; argv++; }
|
||||
while (argc && last_argc != argc )
|
||||
{
|
||||
last_argc = argc;
|
||||
if (!strcmp (*argv, "--"))
|
||||
{
|
||||
argc--; argv++;
|
||||
break;
|
||||
}
|
||||
else if (!strcmp (*argv, "--verbose"))
|
||||
{
|
||||
verbose++;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strcmp (*argv, "--debug"))
|
||||
{
|
||||
verbose += 2;
|
||||
debug++;
|
||||
argc--; argv++;
|
||||
}
|
||||
else if (!strncmp (*argv, "--", 2))
|
||||
{
|
||||
fprintf (stderr, PGM ": unknown option '%s'\n", *argv);
|
||||
exit (1);
|
||||
}
|
||||
}
|
||||
|
||||
test_tuple_uint ();
|
||||
|
||||
return !!errcount;
|
||||
}
|
81
g13/utils.c
81
g13/utils.c
@ -1,5 +1,6 @@
|
||||
/* utils.c - Utility functions
|
||||
* Copyright (C) 2009 Free Software Foundation, Inc.
|
||||
* Copyright (C) 2009, 2015, 2016 Werner Koch
|
||||
*
|
||||
* This file is part of GnuPG.
|
||||
*
|
||||
@ -61,10 +62,45 @@ append_tuple (membuf_t *membuf, int tag, const void *value, size_t length)
|
||||
}
|
||||
|
||||
|
||||
/* Append the unsigned integer VALUE under TAG to MEMBUF. We make
|
||||
* sure that the most significant bit is always cleared to explicitly
|
||||
* flag the value as unsigned. */
|
||||
void
|
||||
append_tuple_uint (membuf_t *membuf, int tag, unsigned long long value)
|
||||
{
|
||||
unsigned char buf[16];
|
||||
unsigned char *p;
|
||||
unsigned int len;
|
||||
|
||||
p = buf + sizeof buf;
|
||||
len = 0;
|
||||
do
|
||||
{
|
||||
if (p == buf)
|
||||
BUG () ;
|
||||
*--p = (value & 0xff);
|
||||
value >>= 8;
|
||||
len++;
|
||||
}
|
||||
while (value);
|
||||
|
||||
/* Prepend a zero byte if the first byte has its MSB set. */
|
||||
if ((*p & 0x80))
|
||||
{
|
||||
if (p == buf)
|
||||
BUG () ;
|
||||
*--p = 0;
|
||||
len++;
|
||||
}
|
||||
|
||||
append_tuple (membuf, tag, p, len);
|
||||
}
|
||||
|
||||
|
||||
/* Create a tuple object by moving the ownership of (DATA,DATALEN) to
|
||||
a new object. Returns 0 on success and stores the new object at
|
||||
R_TUPLEHD. The return object must be released using
|
||||
destroy_tuples(). */
|
||||
* a new object. Returns 0 on success and stores the new object at
|
||||
* R_TUPLEHD. The return object must be released using
|
||||
* destroy_tuples(). */
|
||||
gpg_error_t
|
||||
create_tupledesc (tupledesc_t *r_desc, void *data, size_t datalen)
|
||||
{
|
||||
@ -108,7 +144,7 @@ ref_tupledesc (tupledesc_t tupledesc)
|
||||
|
||||
/* Find the first tuple with tag TAG. On success return a pointer to
|
||||
its value and store the length of the value at R_LENGTH. If no
|
||||
tuple was return NULL. For future use by next_tupe, the last
|
||||
tuple was found return NULL. For use by next_tuple, the last
|
||||
position is stored in the descriptor. */
|
||||
const void *
|
||||
find_tuple (tupledesc_t tupledesc, unsigned int tag, size_t *r_length)
|
||||
@ -147,6 +183,43 @@ find_tuple (tupledesc_t tupledesc, unsigned int tag, size_t *r_length)
|
||||
}
|
||||
|
||||
|
||||
/* Similar to find-tuple but expects an unsigned int value and stores
|
||||
* that at R_VALUE. If the tag was not found GPG_ERR_NOT_FOUND is
|
||||
* returned and 0 stored at R_VALUE. If the value cannot be converted
|
||||
* to an unsigned integer GPG_ERR_ERANGE is returned. */
|
||||
gpg_error_t
|
||||
find_tuple_uint (tupledesc_t tupledesc, unsigned int tag,
|
||||
unsigned long long *r_value)
|
||||
{
|
||||
const unsigned char *s;
|
||||
size_t n;
|
||||
unsigned long long value = 0;
|
||||
|
||||
*r_value = 0;
|
||||
|
||||
s = find_tuple (tupledesc, tag, &n);
|
||||
if (!s)
|
||||
return gpg_error (GPG_ERR_NOT_FOUND);
|
||||
if (!n || (*s & 0x80)) /* No bytes or negative. */
|
||||
return gpg_error (GPG_ERR_ERANGE);
|
||||
if (n && !*s) /* Skip a leading zero. */
|
||||
{
|
||||
n--;
|
||||
s++;
|
||||
}
|
||||
if (n > sizeof value)
|
||||
return gpg_error (GPG_ERR_ERANGE);
|
||||
for (; n; n--, s++)
|
||||
{
|
||||
value <<= 8;
|
||||
value |= *s;
|
||||
}
|
||||
|
||||
*r_value = value;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
const void *
|
||||
next_tuple (tupledesc_t tupledesc, unsigned int *r_tag, size_t *r_length)
|
||||
{
|
||||
|
@ -25,6 +25,8 @@
|
||||
/* Append a new tuple to a memory buffer. */
|
||||
void append_tuple (membuf_t *membuf,
|
||||
int tag, const void *value, size_t length);
|
||||
void append_tuple_uint (membuf_t *membuf, int tag,
|
||||
unsigned long long value);
|
||||
|
||||
/* The tuple descriptor object. */
|
||||
struct tupledesc_s;
|
||||
@ -36,6 +38,8 @@ void destroy_tupledesc (tupledesc_t tupledesc);
|
||||
tupledesc_t ref_tupledesc (tupledesc_t tupledesc);
|
||||
const void *find_tuple (tupledesc_t tupledesc,
|
||||
unsigned int tag, size_t *r_length);
|
||||
gpg_error_t find_tuple_uint (tupledesc_t tupledesc, unsigned int tag,
|
||||
unsigned long long *r_value);
|
||||
const void *next_tuple (tupledesc_t tupledesc,
|
||||
unsigned int *r_tag, size_t *r_length);
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user