Page MenuHome GnuPG

No OneTemporary

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

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

Event Timeline