Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F18825108
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
49 KB
Subscribers
None
View Options
diff --git a/tests/t-common.h b/tests/t-common.h
index 288963df..35469860 100644
--- a/tests/t-common.h
+++ b/tests/t-common.h
@@ -1,99 +1,122 @@
/* t-common.h - Common code for the tests.
* Copyright (C) 2013 g10 Code GmbH
*
* This file is part of libgpg-error.
*
* libgpg-error is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* libgpg-error 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#include <stdarg.h>
#include "../src/gcrypt.h"
-#ifndef PGM
-# error Macro PGM not defined.
+#ifndef PGMNAME
+# error Macro PGMNAME not defined.
#endif
+#ifndef _GCRYPT_CONFIG_H_INCLUDED
+# error config.h not included
+#endif
+
+/* A couple of useful macros. */
+#ifndef DIM
+# define DIM(v) (sizeof(v)/sizeof((v)[0]))
+#endif
+#define my_isascii(c) (!((c) & 0x80))
+#define digitp(p) (*(p) >= '0' && *(p) <= '9')
+#define hexdigitp(a) (digitp (a) \
+ || (*(a) >= 'A' && *(a) <= 'F') \
+ || (*(a) >= 'a' && *(a) <= 'f'))
+#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
+ *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
+#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
+#define xmalloc(a) gcry_xmalloc ((a))
+#define xcalloc(a,b) gcry_xcalloc ((a),(b))
+#define xstrdup(a) gcry_xstrdup ((a))
+#define xfree(a) gcry_free ((a))
+#define pass() do { ; } while (0)
+/* Standard global variables. */
static int verbose;
static int debug;
static int errorcount;
+/* Reporting functions. */
static void
die (const char *format, ...)
{
va_list arg_ptr ;
fflush (stdout);
#ifdef HAVE_FLOCKFILE
flockfile (stderr);
#endif
- fprintf (stderr, "%s: ", PGM);
+ fprintf (stderr, "%s: ", PGMNAME);
va_start (arg_ptr, format) ;
vfprintf (stderr, format, arg_ptr);
va_end (arg_ptr);
if (*format && format[strlen(format)-1] != '\n')
putc ('\n', stderr);
#ifdef HAVE_FLOCKFILE
funlockfile (stderr);
#endif
exit (1);
}
static void
fail (const char *format, ...)
{
va_list arg_ptr;
fflush (stdout);
#ifdef HAVE_FLOCKFILE
flockfile (stderr);
#endif
- fprintf (stderr, "%s: ", PGM);
+ fprintf (stderr, "%s: ", PGMNAME);
va_start (arg_ptr, format);
vfprintf (stderr, format, arg_ptr);
va_end (arg_ptr);
if (*format && format[strlen(format)-1] != '\n')
putc ('\n', stderr);
#ifdef HAVE_FLOCKFILE
funlockfile (stderr);
#endif
errorcount++;
if (errorcount >= 50)
die ("stopped after 50 errors.");
}
static void
-show (const char *format, ...)
+info (const char *format, ...)
{
va_list arg_ptr;
if (!verbose)
return;
#ifdef HAVE_FLOCKFILE
flockfile (stderr);
#endif
- fprintf (stderr, "%s: ", PGM);
+ fprintf (stderr, "%s: ", PGMNAME);
va_start (arg_ptr, format);
vfprintf (stderr, format, arg_ptr);
if (*format && format[strlen(format)-1] != '\n')
putc ('\n', stderr);
va_end (arg_ptr);
#ifdef HAVE_FLOCKFILE
funlockfile (stderr);
#endif
}
diff --git a/tests/t-lock.c b/tests/t-lock.c
index c6c1e418..22b67ef5 100644
--- a/tests/t-lock.c
+++ b/tests/t-lock.c
@@ -1,460 +1,463 @@
/* t-lock.c - Check the lock functions
* Copyright (C) 2014 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public License
* as published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#if HAVE_CONFIG_H
# include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include <errno.h>
#include <unistd.h>
#if HAVE_PTHREAD
# include <pthread.h>
#endif
-#define PGM "t-lock"
+#define PGMNAME "t-lock"
#include "t-common.h"
/* Mingw requires us to include windows.h after winsock2.h which is
included by gcrypt.h. */
#ifdef _WIN32
# include <windows.h>
#endif
#ifdef _WIN32
# define THREAD_RET_TYPE DWORD WINAPI
# define THREAD_RET_VALUE 0
#else
# define THREAD_RET_TYPE void *
# define THREAD_RET_VALUE NULL
#endif
#define PRIV_CTL_EXTERNAL_LOCK_TEST 61
#define EXTERNAL_LOCK_TEST_INIT 30111
#define EXTERNAL_LOCK_TEST_LOCK 30112
#define EXTERNAL_LOCK_TEST_UNLOCK 30113
#define EXTERNAL_LOCK_TEST_DESTROY 30114
/* Number of threads to run. */
#define N_NONCE_THREADS 8
/* Number of interations. */
#define N_NONCE_ITERATIONS 1000
/* Requested nonce size. */
#define NONCE_SIZE 11
/* This tests works by having a a couple of accountant threads which do
random transactions between accounts and a revision threads which
checks that the balance of all accounts is invariant. The idea for
this check is due to Bruno Haible. */
#define N_ACCOUNT 8
#define ACCOUNT_VALUE 42
static int account[N_ACCOUNT];
/* Number of transactions done by each accountant. */
#define N_TRANSACTIONS 1000
/* Number of accountants to run. */
#define N_ACCOUNTANTS 5
/* Maximum transaction value. A quite low value is used so that we
would get an integer overflow. */
#define MAX_TRANSACTION_VALUE 50
/* Flag to tell the revision thread to finish. */
static volatile int stop_revision_thread;
struct thread_arg_s
{
int no;
};
/* Wrapper functions to access Libgcrypt's internal test lock. */
static void
external_lock_test_init (int line)
{
gpg_error_t err;
err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_INIT);
if (err)
fail ("init lock failed at %d: %s", line, gpg_strerror (err));
}
static void
external_lock_test_lock (int line)
{
gpg_error_t err;
err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_LOCK);
if (err)
fail ("taking lock failed at %d: %s", line, gpg_strerror (err));
}
static void
external_lock_test_unlock (int line)
{
gpg_error_t err;
err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_UNLOCK);
if (err)
fail ("releasing lock failed at %d: %s", line, gpg_strerror (err));
}
static void
external_lock_test_destroy (int line)
{
gpg_error_t err;
err = gcry_control (PRIV_CTL_EXTERNAL_LOCK_TEST, EXTERNAL_LOCK_TEST_DESTROY);
if (err)
fail ("destroying lock failed at %d: %s", line, gpg_strerror (err));
}
/* The nonce thread. We simply request a couple of nonces and
return. */
static THREAD_RET_TYPE
nonce_thread (void *argarg)
{
struct thread_arg_s *arg = argarg;
int i;
char nonce[NONCE_SIZE];
for (i = 0; i < N_NONCE_ITERATIONS; i++)
{
gcry_create_nonce (nonce, sizeof nonce);
if (i && !(i%100))
- show ("thread %d created %d nonces so far", arg->no, i);
+ info ("thread %d created %d nonces so far", arg->no, i);
}
gcry_free (arg);
return THREAD_RET_VALUE;
}
/* To check our locking function we run several threads all accessing
the nonce functions. If this function returns we know that there
are no obvious deadlocks or failed lock initialization. */
static void
check_nonce_lock (void)
{
struct thread_arg_s *arg;
#ifdef _WIN32
HANDLE threads[N_NONCE_THREADS];
int i;
int rc;
for (i=0; i < N_NONCE_THREADS; i++)
{
arg = gcry_xmalloc (sizeof *arg);
arg->no = i;
threads[i] = CreateThread (NULL, 0, nonce_thread, arg, 0, NULL);
if (!threads[i])
die ("error creating nonce thread %d: rc=%d",
i, (int)GetLastError ());
}
for (i=0; i < N_NONCE_THREADS; i++)
{
rc = WaitForSingleObject (threads[i], INFINITE);
if (rc == WAIT_OBJECT_0)
- show ("nonce thread %d has terminated", i);
+ info ("nonce thread %d has terminated", i);
else
fail ("waiting for nonce thread %d failed: %d",
i, (int)GetLastError ());
CloseHandle (threads[i]);
}
#elif HAVE_PTHREAD
pthread_t threads[N_NONCE_THREADS];
int rc, i;
for (i=0; i < N_NONCE_THREADS; i++)
{
arg = gcry_xmalloc (sizeof *arg);
arg->no = i;
pthread_create (&threads[i], NULL, nonce_thread, arg);
}
for (i=0; i < N_NONCE_THREADS; i++)
{
rc = pthread_join (threads[i], NULL);
if (rc)
fail ("pthread_join failed for nonce thread %d: %s",
i, strerror (errno));
else
- show ("nonce thread %d has terminated", i);
+ info ("nonce thread %d has terminated", i);
}
#endif /*!_WIN32*/
}
/* Initialze all accounts. */
static void
init_accounts (void)
{
int i;
for (i=0; i < N_ACCOUNT; i++)
account[i] = ACCOUNT_VALUE;
}
/* Check that the sum of all accounts matches the intial sum. */
static void
check_accounts (void)
{
int i, sum;
sum = 0;
for (i = 0; i < N_ACCOUNT; i++)
sum += account[i];
if (sum != N_ACCOUNT * ACCOUNT_VALUE)
die ("accounts out of balance");
}
static void
print_accounts (void)
{
int i;
for (i=0; i < N_ACCOUNT; i++)
printf ("account %d: %6d\n", i, account[i]);
}
/* Get a a random integer value in the range 0 to HIGH. */
static unsigned int
get_rand (int high)
{
return (unsigned int)(1+(int)((double)(high+1)*rand ()/(RAND_MAX+1.0))) - 1;
}
/* Pick a random account. Note that this fucntion is not
thread-safe. */
static int
pick_account (void)
{
return get_rand (N_ACCOUNT - 1);
}
/* Pick a random value for a transaction. This is not thread-safe. */
static int
pick_value (void)
{
return get_rand (MAX_TRANSACTION_VALUE);
}
/* This is the revision department. */
static THREAD_RET_TYPE
revision_thread (void *arg)
{
(void)arg;
while (!stop_revision_thread)
{
external_lock_test_lock (__LINE__);
check_accounts ();
external_lock_test_unlock (__LINE__);
}
return THREAD_RET_VALUE;
}
/* This is one of our accountants. */
static THREAD_RET_TYPE
accountant_thread (void *arg)
{
int i;
int acc1, acc2;
int value;
(void)arg;
for (i = 0; i < N_TRANSACTIONS; i++)
{
external_lock_test_lock (__LINE__);
acc1 = pick_account ();
acc2 = pick_account ();
value = pick_value ();
account[acc1] += value;
account[acc2] -= value;
external_lock_test_unlock (__LINE__);
}
return THREAD_RET_VALUE;
}
static void
run_test (void)
{
#ifdef _WIN32
HANDLE rthread;
HANDLE athreads[N_ACCOUNTANTS];
int i;
int rc;
external_lock_test_init (__LINE__);
stop_revision_thread = 0;
rthread = CreateThread (NULL, 0, revision_thread, NULL, 0, NULL);
if (!rthread)
die ("error creating revision thread: rc=%d", (int)GetLastError ());
for (i=0; i < N_ACCOUNTANTS; i++)
{
athreads[i] = CreateThread (NULL, 0, accountant_thread, NULL, 0, NULL);
if (!athreads[i])
die ("error creating accountant thread %d: rc=%d",
i, (int)GetLastError ());
}
for (i=0; i < N_ACCOUNTANTS; i++)
{
rc = WaitForSingleObject (athreads[i], INFINITE);
if (rc == WAIT_OBJECT_0)
- show ("accountant thread %d has terminated", i);
+ info ("accountant thread %d has terminated", i);
else
fail ("waiting for accountant thread %d failed: %d",
i, (int)GetLastError ());
CloseHandle (athreads[i]);
}
stop_revision_thread = 1;
rc = WaitForSingleObject (rthread, INFINITE);
if (rc == WAIT_OBJECT_0)
- show ("revision thread has terminated");
+ info ("revision thread has terminated");
else
fail ("waiting for revision thread failed: %d", (int)GetLastError ());
CloseHandle (rthread);
#else /*!_WIN32*/
pthread_t rthread;
pthread_t athreads[N_ACCOUNTANTS];
int rc, i;
external_lock_test_init (__LINE__);
stop_revision_thread = 0;
pthread_create (&rthread, NULL, revision_thread, NULL);
for (i=0; i < N_ACCOUNTANTS; i++)
pthread_create (&athreads[i], NULL, accountant_thread, NULL);
for (i=0; i < N_ACCOUNTANTS; i++)
{
rc = pthread_join (athreads[i], NULL);
if (rc)
fail ("pthread_join failed for accountant thread %d: %s",
i, strerror (errno));
else
- show ("accountant thread %d has terminated", i);
+ info ("accountant thread %d has terminated", i);
}
stop_revision_thread = 1;
rc = pthread_join (rthread, NULL);
if (rc)
fail ("pthread_join failed for the revision thread: %s", strerror (errno));
else
- show ("revision thread has terminated");
+ info ("revision thread has terminated");
#endif /*!_WIN32*/
external_lock_test_destroy (__LINE__);
}
int
main (int argc, char **argv)
{
int last_argc = -1;
if (argc)
{
argc--; argv++;
}
while (argc && last_argc != argc )
{
last_argc = argc;
if (!strcmp (*argv, "--help"))
{
puts (
"usage: ./t-lock [options]\n"
"\n"
"Options:\n"
" --verbose Show what is going on\n"
" --debug Flyswatter\n"
);
exit (0);
}
if (!strcmp (*argv, "--verbose"))
{
verbose = 1;
argc--; argv++;
}
else if (!strcmp (*argv, "--debug"))
{
verbose = debug = 1;
argc--; argv++;
}
}
srand (time(NULL)*getpid());
if (debug)
gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
gcry_control (GCRYCTL_DISABLE_SECMEM, 0);
if (!gcry_check_version (GCRYPT_VERSION))
die ("version mismatch");
+ /* We are using non-public interfaces - check the exact version. */
+ if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
+ die ("exact version match failed");
gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
check_nonce_lock ();
init_accounts ();
check_accounts ();
run_test ();
check_accounts ();
/* Run a second time to check deinit code. */
run_test ();
check_accounts ();
if (verbose)
print_accounts ();
return errorcount ? 1 : 0;
}
diff --git a/tests/t-sexp.c b/tests/t-sexp.c
index 4c482776..35103822 100644
--- a/tests/t-sexp.c
+++ b/tests/t-sexp.c
@@ -1,1062 +1,1045 @@
/* t-sexp.c - S-expression regression tests
- * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
+ * Copyright (C) 2014 g10 Code GmbH
*
* This file is part of Libgcrypt.
*
* Libgcrypt is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* Libgcrypt 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
+ * License along with this program; if not, see <http://www.gnu.org/licenses/>.
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdarg.h>
#include <assert.h>
#include "../src/gcrypt-int.h"
#define PGMNAME "t-sexp"
-
-#ifndef DIM
-# define DIM(v) (sizeof(v)/sizeof((v)[0]))
-#endif
-#define my_isascii(c) (!((c) & 0x80))
-#define digitp(p) (*(p) >= '0' && *(p) <= '9')
-#define hexdigitp(a) (digitp (a) \
- || (*(a) >= 'A' && *(a) <= 'F') \
- || (*(a) >= 'a' && *(a) <= 'f'))
-#define xtoi_1(p) (*(p) <= '9'? (*(p)- '0'): \
- *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
-#define xtoi_2(p) ((xtoi_1(p) * 16) + xtoi_1((p)+1))
-#define xmalloc(a) gcry_xmalloc ((a))
-#define xcalloc(a,b) gcry_xcalloc ((a),(b))
-#define xstrdup(a) gcry_xstrdup ((a))
-#define xfree(a) gcry_free ((a))
-#define pass() do { ; } while (0)
-
-
-static int verbose;
-static int error_count;
-
-static void
-die (const char *format, ...)
-{
- va_list arg_ptr ;
-
- fflush (stdout);
- fprintf (stderr, "%s: ", PGMNAME);
- va_start( arg_ptr, format ) ;
- vfprintf (stderr, format, arg_ptr );
- va_end(arg_ptr);
- if (*format && format[strlen(format)-1] != '\n')
- putc ('\n', stderr);
- exit (1);
-}
-
-static void
-info (const char *format, ...)
-{
- va_list arg_ptr;
-
- if (verbose)
- {
- va_start( arg_ptr, format ) ;
- vfprintf (stderr, format, arg_ptr );
- va_end(arg_ptr);
- if (*format && format[strlen(format)-1] != '\n')
- putc ('\n', stderr);
- }
-}
-
-static void
-fail ( const char *format, ... )
-{
- va_list arg_ptr ;
-
- fputs (PGMNAME ": ", stderr);
- va_start( arg_ptr, format ) ;
- vfprintf (stderr, format, arg_ptr );
- va_end(arg_ptr);
- if (*format && format[strlen(format)-1] != '\n')
- putc ('\n', stderr);
- error_count++;
-}
-
+#include "t-common.h"
/* Convert STRING consisting of hex characters into its binary
representation and return it as an allocated buffer. The valid
length of the buffer is returned at R_LENGTH. The string is
delimited by end of string. The function returns NULL on
error. */
static void *
hex2buffer (const char *string, size_t *r_length)
{
const char *s;
unsigned char *buffer;
size_t length;
buffer = xmalloc (strlen(string)/2+1);
length = 0;
for (s=string; *s; s +=2 )
{
if (!hexdigitp (s) || !hexdigitp (s+1))
return NULL; /* Invalid hex digits. */
((unsigned char*)buffer)[length++] = xtoi_2 (s);
}
*r_length = length;
return buffer;
}
static gcry_mpi_t
hex2mpi (const char *string)
{
gpg_error_t err;
gcry_mpi_t val;
err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
if (err)
die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
return val;
}
static gcry_mpi_t
hex2mpiopa (const char *string)
{
char *buffer;
size_t buflen;
gcry_mpi_t val;
buffer = hex2buffer (string, &buflen);
if (!buffer)
die ("hex2mpiopa '%s' failed: parser error\n", string);
val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
if (!buffer)
die ("hex2mpiopa '%s' failed: set_opaque error%s\n", string);
return val;
}
/* Compare A to B, where B is given as a hex string. */
static int
cmp_mpihex (gcry_mpi_t a, const char *b)
{
gcry_mpi_t bval;
int res;
if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
bval = hex2mpiopa (b);
else
bval = hex2mpi (b);
res = gcry_mpi_cmp (a, bval);
gcry_mpi_release (bval);
return res;
}
/* Compare A to B, where A is a buffer and B a hex string. */
static int
cmp_bufhex (const void *a, size_t alen, const char *b)
{
void *bbuf;
size_t blen;
int res;
if (!a && !b)
return 0;
if (a && !b)
return 1;
if (!a && b)
return -1;
bbuf = hex2buffer (b, &blen);
if (!bbuf)
die ("cmp_bufhex: error converting hex string\n");
if (alen != blen)
return alen < blen? -1 : 1;
res = memcmp (a, bbuf, alen);
xfree (bbuf);
return res;
}
/* fixme: we need better tests */
static void
basic (void)
{
int pass;
gcry_sexp_t sexp;
int idx;
char *secure_buffer;
size_t secure_buffer_len;
const char *string;
static struct {
const char *token;
const char *parm;
} values[] = {
{ "public-key", NULL },
{ "dsa", NULL },
{ "dsa", "p" },
{ "dsa", "y" },
{ "dsa", "q" },
{ "dsa", "g" },
{ NULL }
};
info ("doing some pretty pointless tests\n");
secure_buffer_len = 99;
secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
memset (secure_buffer, 'G', secure_buffer_len);
for (pass=0;;pass++)
{
gcry_mpi_t m;
switch (pass)
{
case 0:
string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
"(q #61626364656667#) (g %m)))");
m = gcry_mpi_set_ui (NULL, 42);
if ( gcry_sexp_build (&sexp, NULL, string, m ) )
{
gcry_mpi_release (m);
fail (" scanning `%s' failed\n", string);
return;
}
gcry_mpi_release (m);
break;
case 1:
string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
"(q %b) (g %m)))");
m = gcry_mpi_set_ui (NULL, 42);
if ( gcry_sexp_build (&sexp, NULL, string,
15, "foo\0\x01\0x02789012345", m) )
{
gcry_mpi_release (m);
fail (" scanning `%s' failed\n", string);
return;
}
gcry_mpi_release (m);
break;
case 2:
string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
"(q %b) (g %m)))");
m = gcry_mpi_set_ui (NULL, 17);
if ( gcry_sexp_build (&sexp, NULL, string,
secure_buffer_len, secure_buffer, m) )
{
gcry_mpi_release (m);
fail (" scanning `%s' failed\n", string);
return;
}
gcry_mpi_release (m);
if (!gcry_is_secure (sexp))
fail ("gcry_sexp_build did not switch to secure memory\n");
break;
case 3:
{
gcry_sexp_t help_sexp;
if (gcry_sexp_new (&help_sexp,
"(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
{
fail (" scanning fixed string failed\n");
return;
}
string = ("(public-key (dsa (p #41424344#) (parm %S) "
"(y dummy)(q %b) (g %m)))");
m = gcry_mpi_set_ui (NULL, 17);
if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
secure_buffer_len, secure_buffer, m) )
{
gcry_mpi_release (m);
fail (" scanning `%s' failed\n", string);
return;
}
gcry_mpi_release (m);
gcry_sexp_release (help_sexp);
}
break;
default:
return; /* Ready. */
}
/* now find something */
for (idx=0; values[idx].token; idx++)
{
const char *token = values[idx].token;
const char *parm = values[idx].parm;
gcry_sexp_t s1, s2;
gcry_mpi_t a;
const char *p;
size_t n;
s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
if (!s1)
{
fail ("didn't found `%s'\n", token);
continue;
}
p = gcry_sexp_nth_data (s1, 0, &n);
if (!p)
{
gcry_sexp_release (s1);
fail ("no car for `%s'\n", token);
continue;
}
/* info ("car=`%.*s'\n", (int)n, p); */
s2 = gcry_sexp_cdr (s1);
if (!s2)
{
gcry_sexp_release (s1);
fail ("no cdr for `%s'\n", token);
continue;
}
p = gcry_sexp_nth_data (s2, 0, &n);
gcry_sexp_release (s2);
if (p)
{
gcry_sexp_release (s1);
fail ("data at car of `%s'\n", token);
continue;
}
if (parm)
{
s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
gcry_sexp_release (s1);
if (!s2)
{
fail ("didn't found `%s'\n", parm);
continue;
}
p = gcry_sexp_nth_data (s2, 0, &n);
if (!p)
{
gcry_sexp_release (s2);
fail("no car for `%s'\n", parm );
continue;
}
/* info ("car=`%.*s'\n", (int)n, p); */
p = gcry_sexp_nth_data (s2, 1, &n);
if (!p)
{
gcry_sexp_release (s2);
fail("no cdr for `%s'\n", parm );
continue;
}
/* info ("cdr=`%.*s'\n", (int)n, p); */
a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
gcry_sexp_release (s2);
if (!a)
{
fail("failed to cdr the mpi for `%s'\n", parm);
continue;
}
gcry_mpi_release (a);
}
else
gcry_sexp_release (s1);
}
gcry_sexp_release (sexp);
sexp = NULL;
}
gcry_free (secure_buffer);
}
static void
canon_len (void)
{
static struct {
size_t textlen; /* length of the buffer */
size_t expected;/* expected length or 0 on error and then ... */
size_t erroff; /* ... and at this offset */
gcry_error_t errcode; /* ... with this error code */
const char *text;
} values[] = {
{ 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " },
{ 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" },
{ 14, 0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" },
{ 15, 0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" },
{ 2, 0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"},
{ 4, 0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"},
{ 5, 5, 0, GPG_ERR_NO_ERROR, "(1:x)"},
{ 2, 2, 0, GPG_ERR_NO_ERROR, "()"},
{ 4, 2, 0, GPG_ERR_NO_ERROR, "()()"},
{ 4, 4, 0, GPG_ERR_NO_ERROR, "(())"},
{ 3, 0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"},
{ 3, 0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"},
{ 9, 9, 0, GPG_ERR_NO_ERROR, "(3:abc())"},
{ 10, 0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"},
/* fixme: we need much more cases */
{ 0 },
};
int idx;
gcry_error_t errcode;
size_t n, erroff;
info ("checking canoncial length test function\n");
for (idx=0; values[idx].text; idx++)
{
n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text,
values[idx].textlen,
&erroff, &errcode);
if (n && n == values[idx].expected)
; /* success */
else if (!n && !values[idx].expected)
{ /* we expected an error - check that this is the right one */
if (values[idx].erroff != erroff)
fail ("canonical length test %d - wrong error offset %u\n",
idx, (unsigned int)erroff);
if (gcry_err_code (errcode) != values[idx].errcode)
fail ("canonical length test %d - wrong error code %d\n",
idx, errcode);
}
else
fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n",
idx, (unsigned int)n, (unsigned int)erroff, errcode);
}
}
static void
back_and_forth_one (int testno, const char *buffer, size_t length)
{
gcry_error_t rc;
gcry_sexp_t se, se1;
size_t n, n1;
char *p1;
rc = gcry_sexp_new (&se, buffer, length, 1);
if (rc)
{
fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
return;
}
n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
if (!n1)
{
fail ("baf %d: get required length for canon failed\n", testno);
return;
}
p1 = gcry_xmalloc (n1);
n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
if (n1 != n+1) /* sprints adds an extra 0 but dies not return it */
{
fail ("baf %d: length mismatch for canon\n", testno);
return;
}
rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
if (rc)
{
fail ("baf %d: gcry_sexp_create failed: %s\n",
testno, gpg_strerror (rc));
return;
}
gcry_sexp_release (se1);
/* Again but with memory checking. */
p1 = gcry_xmalloc (n1+2);
*p1 = '\x55';
p1[n1+1] = '\xaa';
n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
{
fail ("baf %d: length mismatch for canon\n", testno);
return;
}
if (*p1 != '\x55' || p1[n1+1] != '\xaa')
fail ("baf %d: memory corrupted (1)\n", testno);
rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
if (rc)
{
fail ("baf %d: gcry_sexp_create failed: %s\n",
testno, gpg_strerror (rc));
return;
}
if (*p1 != '\x55' || p1[n1+1] != '\xaa')
fail ("baf %d: memory corrupted (2)\n", testno);
gcry_sexp_release (se1);
if (*p1 != '\x55' || p1[n1+1] != '\xaa')
fail ("baf %d: memory corrupted (3)\n", testno);
gcry_free (p1);
/* FIXME: we need a lot more tests */
gcry_sexp_release (se);
}
static void
back_and_forth (void)
{
static struct { const char *buf; int len; } tests[] = {
{ "(7:g34:fgh1::2:())", 0 },
{ "(7:g34:fgh1::2:())", 18 },
{
"(protected-private-key \n"
" (rsa \n"
" (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n"
" (e #010001#)\n"
" (protected openpgp-s2k3-sha1-aes-cbc \n"
" (\n"
" (sha1 #C2A5673BD3882405# \"96\")\n"
" #8D08AAF6A9209ED69D71EB7E64D78715#)\n"
" #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
" )\n"
" )\n", 0 },
{ NULL, 0 }
};
int idx;
for (idx=0; tests[idx].buf; idx++)
back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
}
static void
check_sscan (void)
{
static struct {
const char *text;
gcry_error_t expected_err;
} values[] = {
/* Bug reported by Olivier L'Heureux 2003-10-07 */
{ "(7:sig-val(3:dsa"
"(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
"\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
"(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
"\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))",
GPG_ERR_NO_ERROR },
{ "(7:sig-val(3:dsa"
"(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
"\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
"(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
"\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))",
GPG_ERR_SEXP_UNMATCHED_PAREN },
{ "(7:sig-val(3:dsa"
"(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
"\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
"(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
"\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))",
GPG_ERR_SEXP_UNMATCHED_PAREN },
{ NULL, 0 }
};
int idx;
gcry_error_t err;
gcry_sexp_t s;
info ("checking gcry_sexp_sscan\n");
for (idx=0; values[idx].text; idx++)
{
err = gcry_sexp_sscan (&s, NULL,
values[idx].text,
strlen (values[idx].text));
if (gpg_err_code (err) != values[idx].expected_err)
fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err));
gcry_sexp_release (s);
}
}
static void
check_extract_param (void)
{
/* This sample data is a real key but with some parameters of the
public key modified. */
static char sample1[] =
"(key-data"
" (public-key"
" (ecc"
" (curve Ed25519)"
" (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
" (a #EF#)"
" (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
" (g #14"
" 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
" 6666666666666666666666666666666666666666666666666666666666666658#)"
" (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
" (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
"))"
" (private-key"
" (ecc"
" (curve Ed25519)"
" (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
" (a #FF#)"
" (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
" (g #04"
" 216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
" 6666666666666666666666666666666666666666666666666666666666666658#)"
" (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
" (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
" (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
")))";
static char sample1_p[] =
"7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
static char sample1_px[] =
"6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
static char sample1_a[] = "FF";
static char sample1_ax[] = "EF";
static char sample1_b[] =
"D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
static char sample1_bx[] =
"C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
static char sample1_g[] =
"04"
"216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
"6666666666666666666666666666666666666666666666666666666666666658";
static char sample1_gx[] =
"14"
"216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
"6666666666666666666666666666666666666666666666666666666666666658";
static char sample1_n[] =
"1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
static char sample1_nx[] =
"0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
static char sample1_q[] =
"30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
static char sample1_qx[] =
"20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
static char sample1_d[] =
"56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";
static struct {
const char *sexp_str;
const char *path;
const char *list;
int nparam;
gpg_err_code_t expected_err;
const char *exp_p;
const char *exp_a;
const char *exp_b;
const char *exp_g;
const char *exp_n;
const char *exp_q;
const char *exp_d;
} tests[] = {
{
sample1,
NULL,
"pabgnqd", 6,
GPG_ERR_MISSING_VALUE,
},
{
sample1,
NULL,
"pabgnq", 7,
GPG_ERR_INV_ARG
},
{
sample1,
NULL,
"pab'gnq", 7,
GPG_ERR_SYNTAX
},
{
sample1,
NULL,
"pab''gnq", 7,
GPG_ERR_SYNTAX
},
{
sample1,
NULL,
"pabgnqd", 7,
0,
sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
sample1_qx, sample1_d
},
{
sample1,
NULL,
" pab\tg nq\nd ", 7,
0,
sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
sample1_qx, sample1_d
},
{
sample1,
NULL,
"abg", 3,
0,
sample1_ax, sample1_bx, sample1_gx
},
{
sample1,
NULL,
"ab'g'", 3,
0,
sample1_ax, sample1_bx, sample1_gx
},
{
sample1,
NULL,
"x?abg", 4,
0,
NULL, sample1_ax, sample1_bx, sample1_gx
},
{
sample1,
NULL,
"p?abg", 4,
GPG_ERR_USER_1,
NULL, sample1_ax, sample1_bx, sample1_gx
},
{
sample1,
NULL,
"pax?gnqd", 7,
0,
sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
sample1_qx, sample1_d
},
{
sample1,
"public-key",
"pabgnqd", 7,
GPG_ERR_NO_OBJ, /* d is not in public key. */
sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
sample1_qx, sample1_d
},
{
sample1,
"private-key",
"pabgnqd", 7,
0,
sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
sample1_q, sample1_d
},
{
sample1,
"public-key!ecc",
"pabgnq", 6,
0,
sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
sample1_qx
},
{
sample1,
"public-key!ecc!foo",
"pabgnq", 6,
GPG_ERR_NOT_FOUND
},
{
sample1,
"public-key!!ecc",
"pabgnq", 6,
GPG_ERR_NOT_FOUND
},
{
sample1,
"private-key",
"pa/bgnqd", 7,
0,
sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
sample1_q, sample1_d
},
{
sample1,
"private-key",
"p-a+bgnqd", 7,
0,
sample1_p, "-01", sample1_b, sample1_g, sample1_n,
sample1_q, sample1_d
},
{NULL}
};
int idx, i;
const char *paramstr;
int paramidx;
gpg_error_t err;
gcry_sexp_t sxp;
gcry_mpi_t mpis[7];
gcry_buffer_t ioarray[7];
char iobuffer[200];
info ("checking gcry_sexp_extract_param\n");
for (idx=0; tests[idx].sexp_str; idx++)
{
err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
if (err)
die ("converting string to sexp failed: %s", gpg_strerror (err));
memset (mpis, 0, sizeof mpis);
switch (tests[idx].nparam)
{
case 0:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
NULL);
break;
case 1:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, NULL);
break;
case 2:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, mpis+1, NULL);
break;
case 3:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, mpis+1, mpis+2, NULL);
break;
case 4:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, mpis+1, mpis+2, mpis+3, NULL);
break;
case 5:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
NULL);
break;
case 6:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
mpis+5, NULL);
break;
case 7:
err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
mpis+5, mpis+6, NULL);
break;
default:
die ("test %d: internal error", idx);
}
if (tests[idx].expected_err
&& tests[idx].expected_err != GPG_ERR_USER_1)
{
if (tests[idx].expected_err != gpg_err_code (err))
fail ("gcry_sexp_extract_param test %d failed: "
"expected error '%s' - got '%s'", idx,
gpg_strerror (tests[idx].expected_err),gpg_strerror (err));
}
else if (err)
{
fail ("gcry_sexp_extract_param test %d failed: %s",
idx, gpg_strerror (err));
}
else /* No error - check the extracted values. */
{
for (paramidx=0; paramidx < DIM (mpis); paramidx++)
{
switch (paramidx)
{
case 0: paramstr = tests[idx].exp_p; break;
case 1: paramstr = tests[idx].exp_a; break;
case 2: paramstr = tests[idx].exp_b; break;
case 3: paramstr = tests[idx].exp_g; break;
case 4: paramstr = tests[idx].exp_n; break;
case 5: paramstr = tests[idx].exp_q; break;
case 6: paramstr = tests[idx].exp_d; break;
default:
die ("test %d: internal error: bad param %d",
idx, paramidx);
}
if (tests[idx].expected_err == GPG_ERR_USER_1
&& mpis[paramidx] && !paramstr && paramidx == 0)
; /* Okay Special case error for param 0. */
else if (!mpis[paramidx] && !paramstr)
; /* Okay. */
else if (!mpis[paramidx] && paramstr)
fail ("test %d: value for param %d expected but not returned",
idx, paramidx);
else if (mpis[paramidx] && !paramstr)
fail ("test %d: value for param %d not expected",
idx, paramidx);
else if (cmp_mpihex (mpis[paramidx], paramstr))
{
fail ("test %d: param %d mismatch", idx, paramidx);
gcry_log_debug ("expected: %s\n", paramstr);
gcry_log_debugmpi (" got", mpis[paramidx]);
}
else if (tests[idx].expected_err && paramidx == 0)
fail ("test %d: param %d: expected error '%s' - got 'Success'",
idx, paramidx, gpg_strerror (tests[idx].expected_err));
}
}
for (i=0; i < DIM (mpis); i++)
gcry_mpi_release (mpis[i]);
gcry_sexp_release (sxp);
}
info ("checking gcry_sexp_extract_param/desc\n");
memset (ioarray, 0, sizeof ioarray);
err = gcry_sexp_new (&sxp, sample1, 0, 1);
if (err)
die ("converting string to sexp failed: %s", gpg_strerror (err));
ioarray[1].size = sizeof iobuffer;
ioarray[1].data = iobuffer;
ioarray[1].off = 0;
ioarray[2].size = sizeof iobuffer;
ioarray[2].data = iobuffer;
ioarray[2].off = 50;
assert (ioarray[2].off < sizeof iobuffer);
err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
ioarray+0, ioarray+1, ioarray+2, NULL);
if (err)
fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
else
{
if (!ioarray[0].data)
fail ("gcry_sexp_extract_param/desc failed: no P");
else if (ioarray[0].size != 32)
fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
else if (ioarray[0].len != 32)
fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
else if (ioarray[0].off)
fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
{
fail ("gcry_sexp_extract_param/desc failed: P mismatch");
gcry_log_debug ("expected: %s\n", sample1_p);
gcry_log_debughex (" got", ioarray[0].data, ioarray[0].len);
}
if (!ioarray[1].data)
fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
else if (ioarray[1].size != sizeof iobuffer)
fail ("gcry_sexp_extract_param/desc failed: A size changed");
else if (ioarray[1].off != 0)
fail ("gcry_sexp_extract_param/desc failed: A off changed");
else if (ioarray[1].len != 1)
fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
ioarray[1].len, sample1_a))
{
fail ("gcry_sexp_extract_param/desc failed: A mismatch");
gcry_log_debug ("expected: %s\n", sample1_a);
gcry_log_debughex (" got",
(char *)ioarray[1].data + ioarray[1].off,
ioarray[1].len);
}
if (!ioarray[2].data)
fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
else if (ioarray[2].size != sizeof iobuffer)
fail ("gcry_sexp_extract_param/desc failed: B size changed");
else if (ioarray[2].off != 50)
fail ("gcry_sexp_extract_param/desc failed: B off changed");
else if (ioarray[2].len != 32)
fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
ioarray[2].len, sample1_b))
{
fail ("gcry_sexp_extract_param/desc failed: B mismatch");
gcry_log_debug ("expected: %s\n", sample1_b);
gcry_log_debughex (" got",
(char *)ioarray[2].data + ioarray[2].off,
ioarray[2].len);
}
xfree (ioarray[0].data);
}
gcry_sexp_release (sxp);
info ("checking gcry_sexp_extract_param long name\n");
memset (ioarray, 0, sizeof ioarray);
memset (mpis, 0, sizeof mpis);
err = gcry_sexp_new (&sxp, sample1, 0, 1);
if (err)
die ("converting string to sexp failed: %s", gpg_strerror (err));
err = gcry_sexp_extract_param (sxp, "key-data!private-key",
"&'curve'+p",
ioarray+0, mpis+0, NULL);
if (err)
fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));
if (!ioarray[0].data)
fail ("gcry_sexp_extract_param long name failed: no curve");
else if (ioarray[0].size != 7)
fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
else if (ioarray[0].len != 7)
fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
else if (ioarray[0].off)
fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
else if (strncmp (ioarray[0].data, "Ed25519", 7))
{
fail ("gcry_sexp_extract_param long name failed: curve mismatch");
gcry_log_debug ("expected: %s\n", "Ed25519");
gcry_log_debug (" got: %.*s\n",
(int)ioarray[0].len, (char*)ioarray[0].data);
}
if (!mpis[0])
fail ("gcry_sexp_extract_param long name failed: p not returned");
else if (cmp_mpihex (mpis[0], sample1_p))
{
fail ("gcry_sexp_extract_param long name failed: p mismatch");
gcry_log_debug ("expected: %s\n", sample1_p);
gcry_log_debugmpi (" got", mpis[0]);
}
gcry_free (ioarray[0].data);
gcry_mpi_release (mpis[0]);
gcry_sexp_release (sxp);
}
+
+
int
main (int argc, char **argv)
{
- if (argc > 1 && !strcmp (argv[1], "--verbose"))
- verbose = 1;
+ int last_argc = -1;
+
+ if (argc)
+ {
+ argc--; argv++;
+ }
+ while (argc && last_argc != argc )
+ {
+ last_argc = argc;
+ if (!strcmp (*argv, "--"))
+ {
+ argc--; argv++;
+ break;
+ }
+ else if (!strcmp (*argv, "--help"))
+ {
+ puts (
+"usage: " PGMNAME " [options]\n"
+"\n"
+"Options:\n"
+" --verbose Show what is going on\n"
+" --debug Flyswatter\n"
+);
+ exit (0);
+ }
+ else if (!strcmp (*argv, "--verbose"))
+ {
+ verbose = 1;
+ argc--; argv++;
+ }
+ else if (!strcmp (*argv, "--debug"))
+ {
+ verbose = debug = 1;
+ argc--; argv++;
+ }
+ else if (!strncmp (*argv, "--", 2))
+ die ("unknown option '%s'", *argv);
+ }
+ if (debug)
+ gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
+ if (!gcry_check_version (GCRYPT_VERSION))
+ die ("version mismatch");
+ /* #include "../src/gcrypt-int.h" indicates that internal interfaces
+ may be used; thus better do an exact version check. */
+ if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
+ die ("exact version match failed");
+ gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
+ gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
basic ();
canon_len ();
back_and_forth ();
check_sscan ();
check_extract_param ();
- return error_count? 1:0;
+ return errorcount? 1:0;
}
File Metadata
Details
Attached
Mime Type
text/x-diff
Expires
Mon, Dec 23, 1:58 PM (1 d, 18 h)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
d0/87/522e257df25d1ea295dd0aab4a77
Attached To
rC libgcrypt
Event Timeline
Log In to Comment