LCOV - code coverage report
Current view: top level - tests - t-sexp.c (source / functions) Hit Total Coverage
Test: coverage.info Lines: 284 451 63.0 %
Date: 2016-11-29 14:56:30 Functions: 14 14 100.0 %

          Line data    Source code
       1             : /* t-sexp.c  -  S-expression regression tests
       2             :  * Copyright (C) 2001, 2002, 2003, 2005 Free Software Foundation, Inc.
       3             :  * Copyright (C) 2014 g10 Code GmbH
       4             :  *
       5             :  * This file is part of Libgcrypt.
       6             :  *
       7             :  * Libgcrypt is free software; you can redistribute it and/or modify
       8             :  * it under the terms of the GNU Lesser General Public License as
       9             :  * published by the Free Software Foundation; either version 2.1 of
      10             :  * the License, or (at your option) any later version.
      11             :  *
      12             :  * Libgcrypt is distributed in the hope that it will be useful,
      13             :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      14             :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      15             :  * GNU Lesser General Public License for more details.
      16             :  *
      17             :  * You should have received a copy of the GNU Lesser General Public
      18             :  * License along with this program; if not, see <http://www.gnu.org/licenses/>.
      19             :  */
      20             : 
      21             : #ifdef HAVE_CONFIG_H
      22             : #include <config.h>
      23             : #endif
      24             : #include <stdio.h>
      25             : #include <stdlib.h>
      26             : #include <string.h>
      27             : #include <stdarg.h>
      28             : #include <assert.h>
      29             : #include "../src/gcrypt-int.h"
      30             : 
      31             : #define PGMNAME "t-sexp"
      32             : #include "t-common.h"
      33             : 
      34             : 
      35             : /* Convert STRING consisting of hex characters into its binary
      36             :    representation and return it as an allocated buffer. The valid
      37             :    length of the buffer is returned at R_LENGTH.  The string is
      38             :    delimited by end of string.  The function returns NULL on
      39             :    error.  */
      40             : static void *
      41           8 : hex2buffer (const char *string, size_t *r_length)
      42             : {
      43             :   const char *s;
      44             :   unsigned char *buffer;
      45             :   size_t length;
      46             : 
      47           8 :   buffer = xmalloc (strlen(string)/2+1);
      48           8 :   length = 0;
      49         266 :   for (s=string; *s; s +=2 )
      50             :     {
      51         258 :       if (!hexdigitp (s) || !hexdigitp (s+1))
      52           0 :         return NULL;           /* Invalid hex digits. */
      53         258 :       ((unsigned char*)buffer)[length++] = xtoi_2 (s);
      54             :     }
      55           8 :   *r_length = length;
      56           8 :   return buffer;
      57             : }
      58             : 
      59             : 
      60             : static gcry_mpi_t
      61          55 : hex2mpi (const char *string)
      62             : {
      63             :   gpg_error_t err;
      64             :   gcry_mpi_t val;
      65             : 
      66          55 :   err = gcry_mpi_scan (&val, GCRYMPI_FMT_HEX, string, 0, NULL);
      67          55 :   if (err)
      68           0 :     die ("hex2mpi '%s' failed: %s\n", string, gpg_strerror (err));
      69          55 :   return val;
      70             : }
      71             : 
      72             : static gcry_mpi_t
      73           5 : hex2mpiopa (const char *string)
      74             : {
      75             :   char *buffer;
      76             :   size_t buflen;
      77             :   gcry_mpi_t val;
      78             : 
      79           5 :   buffer = hex2buffer (string, &buflen);
      80           5 :   if (!buffer)
      81           0 :     die ("hex2mpiopa '%s' failed: parser error\n", string);
      82           5 :   val = gcry_mpi_set_opaque (NULL, buffer, buflen*8);
      83           5 :   if (!buffer)
      84           0 :     die ("hex2mpiopa '%s' failed: set_opaque error\n", string);
      85           5 :   return val;
      86             : }
      87             : 
      88             : 
      89             : /* Compare A to B, where B is given as a hex string.  */
      90             : static int
      91          60 : cmp_mpihex (gcry_mpi_t a, const char *b)
      92             : {
      93             :   gcry_mpi_t bval;
      94             :   int res;
      95             : 
      96          60 :   if (gcry_mpi_get_flag (a, GCRYMPI_FLAG_OPAQUE))
      97           5 :     bval = hex2mpiopa (b);
      98             :   else
      99          55 :     bval = hex2mpi (b);
     100          60 :   res = gcry_mpi_cmp (a, bval);
     101          60 :   gcry_mpi_release (bval);
     102          60 :   return res;
     103             : }
     104             : 
     105             : /* Compare A to B, where A is a buffer and B a hex string.  */
     106             : static int
     107           3 : cmp_bufhex (const void *a, size_t alen, const char *b)
     108             : {
     109             :   void *bbuf;
     110             :   size_t blen;
     111             :   int res;
     112             : 
     113           3 :   if (!a && !b)
     114           0 :     return 0;
     115           3 :   if (a && !b)
     116           0 :     return 1;
     117           3 :   if (!a && b)
     118           0 :     return -1;
     119             : 
     120           3 :   bbuf = hex2buffer (b, &blen);
     121           3 :   if (!bbuf)
     122           0 :     die ("cmp_bufhex: error converting hex string\n");
     123           3 :   if (alen != blen)
     124           0 :     return alen < blen? -1 : 1;
     125           3 :   res = memcmp (a, bbuf, alen);
     126           3 :   xfree (bbuf);
     127           3 :   return res;
     128             : }
     129             : 
     130             : 
     131             : 
     132             : /* fixme: we need better tests */
     133             : static void
     134           1 : basic (void)
     135             : {
     136             :   int pass;
     137             :   gcry_sexp_t sexp;
     138             :   int idx;
     139             :   char *secure_buffer;
     140             :   size_t secure_buffer_len;
     141             :   const char *string;
     142             :   static struct {
     143             :     const char *token;
     144             :     const char *parm;
     145             :   } values[] = {
     146             :     { "public-key", NULL },
     147             :     { "dsa", NULL },
     148             :     { "dsa", "p" },
     149             :     { "dsa", "y" },
     150             :     { "dsa", "q" },
     151             :     { "dsa", "g" },
     152             :     { NULL }
     153             :   };
     154             : 
     155           1 :   info ("doing some pretty pointless tests\n");
     156             : 
     157           1 :   secure_buffer_len = 99;
     158           1 :   secure_buffer = gcry_xmalloc_secure (secure_buffer_len);
     159           1 :   memset (secure_buffer, 'G', secure_buffer_len);
     160             : 
     161           5 :   for (pass=0;;pass++)
     162             :     {
     163             :       gcry_mpi_t m;
     164             : 
     165           5 :       switch (pass)
     166             :         {
     167             :         case 0:
     168           1 :           string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
     169             :                     "(q #61626364656667#) (g %m)))");
     170             : 
     171           1 :           m = gcry_mpi_set_ui (NULL, 42);
     172           1 :           if ( gcry_sexp_build (&sexp, NULL, string, m ) )
     173             :             {
     174           0 :               gcry_mpi_release (m);
     175           0 :               fail (" scanning `%s' failed\n", string);
     176           0 :               return;
     177             :             }
     178           1 :           gcry_mpi_release (m);
     179           1 :           break;
     180             : 
     181             :         case 1:
     182           1 :           string = ("(public-key (dsa (p #41424344#) (y this_is_y) "
     183             :                     "(q %b) (g %m)))");
     184             : 
     185           1 :           m = gcry_mpi_set_ui (NULL, 42);
     186           1 :           if ( gcry_sexp_build (&sexp, NULL, string,
     187             :                                 15, "foo\0\x01\0x02789012345", m) )
     188             :             {
     189           0 :               gcry_mpi_release (m);
     190           0 :               fail (" scanning `%s' failed\n", string);
     191           0 :               return;
     192             :             }
     193           1 :           gcry_mpi_release (m);
     194           1 :           break;
     195             : 
     196             :         case 2:
     197           1 :           string = ("(public-key (dsa (p #41424344#) (y silly_y_value) "
     198             :                     "(q %b) (g %m)))");
     199             : 
     200           1 :           m = gcry_mpi_set_ui (NULL, 17);
     201           1 :           if ( gcry_sexp_build (&sexp, NULL, string,
     202             :                                 secure_buffer_len, secure_buffer, m) )
     203             :             {
     204           0 :               gcry_mpi_release (m);
     205           0 :               fail (" scanning `%s' failed\n", string);
     206           0 :               return;
     207             :             }
     208           1 :           gcry_mpi_release (m);
     209           1 :           if (!gcry_is_secure (sexp))
     210           0 :             fail ("gcry_sexp_build did not switch to secure memory\n");
     211           1 :           break;
     212             : 
     213             :         case 3:
     214             :           {
     215             :             gcry_sexp_t help_sexp;
     216             : 
     217           1 :             if (gcry_sexp_new (&help_sexp,
     218             :                                "(foobar-parms (xp #1234#)(xq #03#))", 0, 1))
     219             :               {
     220           0 :                 fail (" scanning fixed string failed\n");
     221           0 :                 return;
     222             :               }
     223             : 
     224           1 :             string = ("(public-key (dsa (p #41424344#) (parm %S) "
     225             :                       "(y dummy)(q %b) (g %m)))");
     226           1 :             m = gcry_mpi_set_ui (NULL, 17);
     227           1 :             if ( gcry_sexp_build (&sexp, NULL, string, help_sexp,
     228             :                                   secure_buffer_len, secure_buffer, m) )
     229             :               {
     230           0 :                 gcry_mpi_release (m);
     231           0 :                 fail (" scanning `%s' failed\n", string);
     232           0 :                 return;
     233             :               }
     234           1 :             gcry_mpi_release (m);
     235           1 :             gcry_sexp_release (help_sexp);
     236             :           }
     237           1 :           break;
     238             : 
     239             : 
     240             :         default:
     241           1 :           return; /* Ready. */
     242             :         }
     243             : 
     244             : 
     245             :       /* now find something */
     246          28 :       for (idx=0; values[idx].token; idx++)
     247             :         {
     248          24 :           const char *token = values[idx].token;
     249          24 :           const char *parm = values[idx].parm;
     250             :           gcry_sexp_t s1, s2;
     251             :           gcry_mpi_t a;
     252             :           const char *p;
     253             :           size_t n;
     254             : 
     255          24 :           s1 = gcry_sexp_find_token (sexp, token, strlen(token) );
     256          24 :           if (!s1)
     257             :             {
     258           0 :               fail ("didn't found `%s'\n", token);
     259           0 :               continue;
     260             :             }
     261             : 
     262          24 :           p = gcry_sexp_nth_data (s1, 0, &n);
     263          24 :           if (!p)
     264             :             {
     265           0 :               gcry_sexp_release (s1);
     266           0 :               fail ("no car for `%s'\n", token);
     267           0 :               continue;
     268             :             }
     269             :           /* info ("car=`%.*s'\n", (int)n, p); */
     270             : 
     271          24 :           s2 = gcry_sexp_cdr (s1);
     272          24 :           if (!s2)
     273             :             {
     274           0 :               gcry_sexp_release (s1);
     275           0 :               fail ("no cdr for `%s'\n", token);
     276           0 :               continue;
     277             :             }
     278             : 
     279          24 :           p = gcry_sexp_nth_data (s2, 0, &n);
     280          24 :           gcry_sexp_release (s2);
     281          24 :           if (p)
     282             :             {
     283           0 :               gcry_sexp_release (s1);
     284           0 :               fail ("data at car of `%s'\n", token);
     285           0 :               continue;
     286             :             }
     287             : 
     288          24 :           if (parm)
     289             :             {
     290          16 :               s2 = gcry_sexp_find_token (s1, parm, strlen (parm));
     291          16 :               gcry_sexp_release (s1);
     292          16 :               if (!s2)
     293             :                 {
     294           0 :                   fail ("didn't found `%s'\n", parm);
     295           0 :                   continue;
     296             :                 }
     297          16 :               p = gcry_sexp_nth_data (s2, 0, &n);
     298          16 :               if (!p)
     299             :                 {
     300           0 :                   gcry_sexp_release (s2);
     301           0 :                   fail("no car for `%s'\n", parm );
     302           0 :                   continue;
     303             :                 }
     304             :               /* info ("car=`%.*s'\n", (int)n, p); */
     305          16 :               p = gcry_sexp_nth_data (s2, 1, &n);
     306          16 :               if (!p)
     307             :                 {
     308           0 :                   gcry_sexp_release (s2);
     309           0 :                   fail("no cdr for `%s'\n", parm );
     310           0 :                   continue;
     311             :                 }
     312             :               /* info ("cdr=`%.*s'\n", (int)n, p); */
     313             : 
     314          16 :               a = gcry_sexp_nth_mpi (s2, 0, GCRYMPI_FMT_USG);
     315          16 :               gcry_sexp_release (s2);
     316          16 :               if (!a)
     317             :                 {
     318           0 :                   fail("failed to cdr the mpi for `%s'\n", parm);
     319           0 :                   continue;
     320             :                 }
     321          16 :               gcry_mpi_release (a);
     322             :             }
     323             :           else
     324           8 :             gcry_sexp_release (s1);
     325             :         }
     326             : 
     327           4 :       gcry_sexp_release (sexp);
     328           4 :       sexp = NULL;
     329           4 :     }
     330             :   gcry_free (secure_buffer);
     331             : }
     332             : 
     333             : 
     334             : static void
     335           1 : canon_len (void)
     336             : {
     337             :   static struct {
     338             :     size_t textlen; /* length of the buffer */
     339             :     size_t expected;/* expected length or 0 on error and then ... */
     340             :     size_t erroff;  /* ... and at this offset */
     341             :     gcry_error_t errcode;    /* ... with this error code */
     342             :     const char *text;
     343             :   } values[] = {
     344             :     { 14, 13, 0, GPG_ERR_NO_ERROR, "(9:abcdefghi) " },
     345             :     { 16, 15, 0, GPG_ERR_NO_ERROR, "(10:abcdefghix)" },
     346             :     { 14,  0,14, GPG_ERR_SEXP_STRING_TOO_LONG, "(10:abcdefghi)" },
     347             :     { 15,  0, 1, GPG_ERR_SEXP_ZERO_PREFIX, "(010:abcdefghi)" },
     348             :     {  2,  0, 0, GPG_ERR_SEXP_NOT_CANONICAL, "1:"},
     349             :     {  4,  0, 4, GPG_ERR_SEXP_STRING_TOO_LONG, "(1:)"},
     350             :     {  5,  5, 0, GPG_ERR_NO_ERROR, "(1:x)"},
     351             :     {  2,  2, 0, GPG_ERR_NO_ERROR, "()"},
     352             :     {  4,  2, 0, GPG_ERR_NO_ERROR, "()()"},
     353             :     {  4,  4, 0, GPG_ERR_NO_ERROR, "(())"},
     354             :     {  3,  0, 3, GPG_ERR_SEXP_STRING_TOO_LONG, "(()"},
     355             :     {  3,  0, 1, GPG_ERR_SEXP_BAD_CHARACTER, "( )"},
     356             :     {  9,  9, 0, GPG_ERR_NO_ERROR, "(3:abc())"},
     357             :     { 10,  0, 6, GPG_ERR_SEXP_BAD_CHARACTER, "(3:abc ())"},
     358             :     /* fixme: we need much more cases */
     359             :     { 0 },
     360             :   };
     361             :   int idx;
     362             :   gcry_error_t errcode;
     363             :   size_t n, erroff;
     364             : 
     365           1 :   info ("checking canoncial length test function\n");
     366          15 :   for (idx=0; values[idx].text; idx++)
     367             :     {
     368          14 :       n = gcry_sexp_canon_len ((const unsigned char*)values[idx].text,
     369             :                                values[idx].textlen,
     370             :                                &erroff, &errcode);
     371             : 
     372          14 :       if (n && n == values[idx].expected)
     373             :         ; /* success */
     374           7 :       else if (!n && !values[idx].expected)
     375             :         { /* we expected an error - check that this is the right one */
     376           7 :           if (values[idx].erroff != erroff)
     377           0 :             fail ("canonical length test %d - wrong error offset %u\n",
     378             :                   idx, (unsigned int)erroff);
     379          14 :           if (gcry_err_code (errcode) != values[idx].errcode)
     380           0 :             fail ("canonical length test %d - wrong error code %d\n",
     381             :                   idx, errcode);
     382             :         }
     383             :       else
     384           0 :         fail ("canonical length test %d failed - n=%u, off=%u, err=%d\n",
     385             :               idx, (unsigned int)n, (unsigned int)erroff, errcode);
     386             :     }
     387           1 : }
     388             : 
     389             : 
     390             : /* Compare SE to the canonical formatted expression in
     391             :  * (CANON,CANONLEN).  This is done by a converting SE to canonical
     392             :  * format and doing a byte compare.  Returns 0 if they match.  */
     393             : static int
     394          10 : compare_to_canon (gcry_sexp_t se, const unsigned char *canon, size_t canonlen)
     395             : {
     396             :   size_t n, n1;
     397             :   char *p1;
     398             : 
     399          10 :   n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
     400          10 :   if (!n1)
     401             :     {
     402           0 :       fail ("get required length in compare_to_canon failed\n");
     403           0 :       return -1;
     404             :     }
     405          10 :   p1 = gcry_xmalloc (n1);
     406          10 :   n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
     407          10 :   if (n1 != n+1)
     408             :     {
     409           0 :       fail ("length mismatch in compare_to_canon detected\n");
     410           0 :       xfree (p1);
     411           0 :       return -1;
     412             :     }
     413          10 :   if (n1 != canonlen || memcmp (p1, canon, canonlen))
     414             :     {
     415           0 :       xfree (p1);
     416           0 :       return -1;
     417             :     }
     418          10 :   xfree (p1);
     419          10 :   return 0;
     420             : }
     421             : 
     422             : 
     423             : static void
     424          10 : back_and_forth_one (int testno, const char *buffer, size_t length)
     425             : {
     426             :   gcry_error_t rc;
     427             :   gcry_sexp_t se, se1;
     428             :   unsigned char *canon;
     429             :   size_t canonlen;  /* Including the hidden nul suffix.  */
     430             :   size_t n, n1;
     431             :   char *p1;
     432             : 
     433          10 :   rc = gcry_sexp_new (&se, buffer, length, 1);
     434          10 :   if (rc)
     435             :     {
     436           0 :       fail ("baf %d: gcry_sexp_new failed: %s\n", testno, gpg_strerror (rc));
     437           0 :       return;
     438             :     }
     439          10 :   n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, NULL, 0);
     440          10 :   if (!n1)
     441             :     {
     442           0 :       fail ("baf %d: get required length for canon failed\n", testno);
     443           0 :       return;
     444             :     }
     445          10 :   p1 = gcry_xmalloc (n1);
     446          10 :   n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1, n1);
     447          10 :   if (n1 != n+1) /* sprints adds an extra 0 but does not return it. */
     448             :     {
     449           0 :       fail ("baf %d: length mismatch for canon\n", testno);
     450           0 :       return;
     451             :     }
     452          10 :   canonlen = n1;
     453          10 :   canon = gcry_malloc (canonlen);
     454          10 :   memcpy (canon, p1, canonlen);
     455          10 :   rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
     456          10 :   if (rc)
     457             :     {
     458           0 :       fail ("baf %d: gcry_sexp_create failed: %s\n",
     459             :             testno, gpg_strerror (rc));
     460           0 :       return;
     461             :     }
     462          10 :   gcry_sexp_release (se1);
     463             : 
     464             :   /* Again but with memory checking. */
     465          10 :   p1 = gcry_xmalloc (n1+2);
     466          10 :   *p1 = '\x55';
     467          10 :   p1[n1+1] = '\xaa';
     468          10 :   n = gcry_sexp_sprint (se, GCRYSEXP_FMT_CANON, p1+1, n1);
     469          10 :   if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
     470             :     {
     471           0 :       fail ("baf %d: length mismatch for canon\n", testno);
     472           0 :       return;
     473             :     }
     474          10 :   if (*p1 != '\x55' || p1[n1+1] != '\xaa')
     475           0 :     fail ("baf %d: memory corrupted (1)\n", testno);
     476          10 :   rc = gcry_sexp_create (&se1, p1+1, n, 0, NULL);
     477          10 :   if (rc)
     478             :     {
     479           0 :       fail ("baf %d: gcry_sexp_create failed: %s\n",
     480             :             testno, gpg_strerror (rc));
     481           0 :       return;
     482             :     }
     483          10 :   if (*p1 != '\x55' || p1[n1+1] != '\xaa')
     484           0 :     fail ("baf %d: memory corrupted (2)\n", testno);
     485          10 :   gcry_sexp_release (se1);
     486          10 :   if (*p1 != '\x55' || p1[n1+1] != '\xaa')
     487           0 :     fail ("baf %d: memory corrupted (3)\n", testno);
     488          10 :   gcry_free (p1);
     489             : 
     490             :   /* Check converting to advanced format.  */
     491          10 :   n1 = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, NULL, 0);
     492          10 :   if (!n1)
     493             :     {
     494           0 :       fail ("baf %d: get required length for advanced failed\n", testno);
     495           0 :       return;
     496             :     }
     497          10 :   p1 = gcry_xmalloc (n1);
     498          10 :   n = gcry_sexp_sprint (se, GCRYSEXP_FMT_ADVANCED, p1, n1);
     499          10 :   if (n1 != n+1) /* sprints adds an extra 0 but does not return it */
     500             :     {
     501           0 :       fail ("baf %d: length mismatch for advanced\n", testno);
     502           0 :       return;
     503             :     }
     504          10 :   rc = gcry_sexp_create (&se1, p1, n, 0, gcry_free);
     505          10 :   if (rc)
     506             :     {
     507           0 :       fail ("baf %d: gcry_sexp_create failed: %s\n",
     508             :             testno, gpg_strerror (rc));
     509           0 :       return;
     510             :     }
     511          10 :   if (compare_to_canon (se1, canon, canonlen))
     512             :     {
     513           0 :       fail ("baf %d: converting to advanced failed: %s\n",
     514             :             testno, gpg_strerror (rc));
     515           0 :       return;
     516             :     }
     517          10 :   gcry_sexp_release (se1);
     518             : 
     519             : 
     520             :   /* FIXME: we need a lot more tests */
     521             : 
     522          10 :   gcry_sexp_release (se);
     523          10 :   xfree (canon);
     524             : }
     525             : 
     526             : 
     527             : 
     528             : static void
     529           1 : back_and_forth (void)
     530             : {
     531             :   static struct { const char *buf; int len; } tests[] = {
     532             :     { "(7:g34:fgh1::2:())", 0 },
     533             :     { "(7:g34:fgh1::2:())", 18 },
     534             :     {
     535             : "(protected-private-key \n"
     536             : " (rsa \n"
     537             : "  (n #00BE8A536204687149A48FF9F1715FF3530AD9A836D62102BF4065E5CF5953236DB94F1DF2FF4D525CD4CE7966DDC3C839968E8BAC2948934DF047CC65287CD79F6C23C93E55D7F9231E3942BD496DE383469977635A51ADF4AF747DB958CA02E9940DFC1DC0FC7FC755E7EB6618FEE6DA54B8A06E0CBF9D9257443F9992261435#)\n"
     538             : "  (e #010001#)\n"
     539             : "  (protected openpgp-s2k3-sha1-aes-cbc \n"
     540             : "   (\n"
     541             : "    (sha1 #C2A5673BD3882405# \"96\")\n"
     542             : "    #8D08AAF6A9209ED69D71EB7E64D78715#)\n"
     543             : "   #F7B0B535F8F8E22F4F3DA031224070303F82F9207D42952F1ACF21A4AB1C50304EBB25527992C7B265A9E9FF702826FB88759BDD55E4759E9FCA6C879538C9D043A9C60A326CB6681090BAA731289BD880A7D5774D9999F026E5E7963BFC8C0BDC9F061393CB734B4F259725C0A0A0B15BA39C39146EF6A1B3DC4DF30A22EBE09FD05AE6CB0C8C6532951A925F354F4E26A51964F5BBA50081690C421C8385C4074E9BAB9297D081B857756607EAE652415275A741C89E815558A50AC638EDC5F5030210B4395E3E1A40FF38DCCCB333A19EA88EFE7E4D51B54128C6DF27395646836679AC21B1B25C1DA6F0A7CE9F9BE078EFC7934FA9AE202CBB0AA06C20DFAF9A66FAB7E9073FBE96B9A7F25C3BA45EC3EECA65796AEE313BA148DE5314F30345B452B50B17C4D841A7F27397126E8C10BD0CE3B50A82C0425AAEE7798031671407B681F52916256F78CAF92A477AC27BCBE26DAFD1BCE386A853E2A036F8314BB2E8E5BB1F196434232EFB0288331C2AB16DBC5457CC295EB966CAC5CE73D5DA5D566E469F0EFA82F9A12B8693E0#)\n"
     544             : "  )\n"
     545             : " )\n", 0 },
     546             :     { "((sha1 #8B98CBF4A9823CA7# \"2097\") #3B6FC9#)", 0 },
     547             :     { "((4:sha18:\x8B\x98\xCB\xF4\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
     548             :     { "((4:sha18:\x8B\x98\xCB\x22\xA9\x82\x3C\xA7""4:2097)3:\x3B\x6F\xC9)", 0},
     549             :     { "((sha1 #64652267686970C9# \"2097\") #3B6FC9#)", 0 },
     550             :     { "((4:sha18:\x64\x65\x22\x67\x68\xc3\xa4\x71""4:2097)3:\x3B\x6F\xC9)", 0},
     551             :     { "((sha1 \"defghäq\" \"2097\") #3B6FC9#)", 0 },
     552             :     { "((sha1 \"de\\\"ghäq\" \"2097\") #3B6FC9#)", 0 },
     553             :     { NULL, 0 }
     554             :   };
     555             :   int idx;
     556             : 
     557          11 :   for (idx=0; tests[idx].buf; idx++)
     558          10 :     back_and_forth_one (idx, tests[idx].buf, tests[idx].len);
     559           1 : }
     560             : 
     561             : 
     562             : static void
     563           1 : check_sscan (void)
     564             : {
     565             :   static struct {
     566             :     const char *text;
     567             :     gcry_error_t expected_err;
     568             :   } values[] = {
     569             :     /* Bug reported by Olivier L'Heureux 2003-10-07 */
     570             :     { "(7:sig-val(3:dsa"
     571             :       "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
     572             :       "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
     573             :       "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
     574             :       "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e)))",
     575             :       GPG_ERR_NO_ERROR },
     576             :     { "(7:sig-val(3:dsa"
     577             :       "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
     578             :       "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
     579             :       "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
     580             :       "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))",
     581             :       GPG_ERR_SEXP_UNMATCHED_PAREN },
     582             :     { "(7:sig-val(3:dsa"
     583             :       "(1:r20:\x7e\xff\xd5\xba\xc9\xc9\xa4\x9b\xd4\x26\x8b\x64"
     584             :       "\x06\x7a\xcf\x42\x7b\x6c\x51\xfb)"
     585             :       "(1:s21:\x01\x8c\x6c\x6f\x37\x1a\x8d\xfd\x5a\xb3\x2a\x3d"
     586             :       "\xc5\xae\x23\xed\x32\x62\x30\x62\x3e))))",
     587             :       GPG_ERR_SEXP_UNMATCHED_PAREN },
     588             :     { NULL, 0 }
     589             :   };
     590             :   int idx;
     591             :   gcry_error_t err;
     592             :   gcry_sexp_t s;
     593             : 
     594           1 :   info ("checking gcry_sexp_sscan\n");
     595           4 :   for (idx=0; values[idx].text; idx++)
     596             :     {
     597           3 :       err = gcry_sexp_sscan (&s, NULL,
     598             :                              values[idx].text,
     599             :                              strlen (values[idx].text));
     600           3 :       if (gpg_err_code (err) != values[idx].expected_err)
     601           0 :         fail ("gcry_sexp_sscan test %d failed: %s\n", idx, gpg_strerror (err));
     602           3 :       gcry_sexp_release (s);
     603             :     }
     604           1 : }
     605             : 
     606             : 
     607             : static void
     608           1 : check_extract_param (void)
     609             : {
     610             :   /* This sample data is a real key but with some parameters of the
     611             :      public key modified.  */
     612             :   static char sample1[] =
     613             :     "(key-data"
     614             :     " (public-key"
     615             :     "  (ecc"
     616             :     "   (curve Ed25519)"
     617             :     "   (p #6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
     618             :     "   (a #EF#)"
     619             :     "   (b #C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
     620             :     "   (g #14"
     621             :     "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
     622             :     "       6666666666666666666666666666666666666666666666666666666666666658#)"
     623             :     "   (n #0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
     624             :     "   (q #20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
     625             :     "))"
     626             :     " (private-key"
     627             :     "  (ecc"
     628             :     "   (curve Ed25519)"
     629             :     "   (p #7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED#)"
     630             :     "   (a #FF#)"
     631             :     "   (b #D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6#)"
     632             :     "   (g #04"
     633             :     "       216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
     634             :     "       6666666666666666666666666666666666666666666666666666666666666658#)"
     635             :     "   (n #1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED#)"
     636             :     "   (q #30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62#)"
     637             :     "   (d #56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276#)"
     638             :     ")))";
     639             : 
     640             :   static char sample1_p[] =
     641             :     "7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
     642             :   static char sample1_px[] =
     643             :     "6FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFED";
     644             :   static char sample1_a[] = "FF";
     645             :   static char sample1_ax[] = "EF";
     646             :   static char sample1_b[] =
     647             :     "D2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
     648             :   static char sample1_bx[] =
     649             :     "C2036CEE2B6FFE738CC740797779E89800700A4D4141D8AB75EB4DCA135978B6";
     650             :   static char sample1_g[] =
     651             :     "04"
     652             :     "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
     653             :     "6666666666666666666666666666666666666666666666666666666666666658";
     654             :   static char sample1_gx[] =
     655             :     "14"
     656             :     "216936D3CD6E53FEC0A4E231FDD6DC5C692CC7609525A7B2C9562D608F25D51A"
     657             :     "6666666666666666666666666666666666666666666666666666666666666658";
     658             :   static char sample1_n[] =
     659             :     "1000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
     660             :   static char sample1_nx[] =
     661             :     "0000000000000000000000000000000014DEF9DEA2F79CD65812631A5CF5D3ED";
     662             :   static char sample1_q[] =
     663             :     "30B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
     664             :   static char sample1_qx[] =
     665             :     "20B37806015CA06B3AEB9423EE84A41D7F31AA65F4148553755206D679F8BF62";
     666             :   static char sample1_d[] =
     667             :     "56BEA284A22F443A7AEA8CEFA24DA5055CDF1D490C94D8C568FE0802C9169276";
     668             : 
     669             :   static struct {
     670             :     const char *sexp_str;
     671             :     const char *path;
     672             :     const char *list;
     673             :     int nparam;
     674             :     gpg_err_code_t expected_err;
     675             :     const char *exp_p;
     676             :     const char *exp_a;
     677             :     const char *exp_b;
     678             :     const char *exp_g;
     679             :     const char *exp_n;
     680             :     const char *exp_q;
     681             :     const char *exp_d;
     682             :   } tests[] = {
     683             :     {
     684             :       sample1,
     685             :       NULL,
     686             :       "pabgnqd", 6,
     687             :       GPG_ERR_MISSING_VALUE,
     688             :     },
     689             :     {
     690             :       sample1,
     691             :       NULL,
     692             :       "pabgnq", 7,
     693             :       GPG_ERR_INV_ARG
     694             :     },
     695             :     {
     696             :       sample1,
     697             :       NULL,
     698             :       "pab'gnq", 7,
     699             :       GPG_ERR_SYNTAX
     700             :     },
     701             :     {
     702             :       sample1,
     703             :       NULL,
     704             :       "pab''gnq", 7,
     705             :       GPG_ERR_SYNTAX
     706             :     },
     707             :     {
     708             :       sample1,
     709             :       NULL,
     710             :       "pabgnqd", 7,
     711             :       0,
     712             :       sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
     713             :       sample1_qx, sample1_d
     714             :     },
     715             :     {
     716             :       sample1,
     717             :       NULL,
     718             :       "  pab\tg nq\nd  ", 7,
     719             :       0,
     720             :       sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
     721             :       sample1_qx, sample1_d
     722             :     },
     723             :     {
     724             :       sample1,
     725             :       NULL,
     726             :       "abg", 3,
     727             :       0,
     728             :       sample1_ax, sample1_bx, sample1_gx
     729             :     },
     730             :     {
     731             :       sample1,
     732             :       NULL,
     733             :       "ab'g'", 3,
     734             :       0,
     735             :       sample1_ax, sample1_bx, sample1_gx
     736             :     },
     737             :     {
     738             :       sample1,
     739             :       NULL,
     740             :       "x?abg", 4,
     741             :       0,
     742             :       NULL, sample1_ax, sample1_bx, sample1_gx
     743             :     },
     744             :     {
     745             :       sample1,
     746             :       NULL,
     747             :       "p?abg", 4,
     748             :       GPG_ERR_USER_1,
     749             :       NULL, sample1_ax, sample1_bx, sample1_gx
     750             :     },
     751             :     {
     752             :       sample1,
     753             :       NULL,
     754             :       "pax?gnqd", 7,
     755             :       0,
     756             :       sample1_px, sample1_ax, NULL, sample1_gx, sample1_nx,
     757             :       sample1_qx, sample1_d
     758             :     },
     759             :     {
     760             :       sample1,
     761             :       "public-key",
     762             :       "pabgnqd", 7,
     763             :       GPG_ERR_NO_OBJ,  /* d is not in public key.  */
     764             :       sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
     765             :       sample1_qx, sample1_d
     766             :     },
     767             :     {
     768             :       sample1,
     769             :       "private-key",
     770             :       "pabgnqd", 7,
     771             :       0,
     772             :       sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
     773             :       sample1_q, sample1_d
     774             :     },
     775             :     {
     776             :       sample1,
     777             :       "public-key!ecc",
     778             :       "pabgnq", 6,
     779             :       0,
     780             :       sample1_px, sample1_ax, sample1_bx, sample1_gx, sample1_nx,
     781             :       sample1_qx
     782             :     },
     783             :     {
     784             :       sample1,
     785             :       "public-key!ecc!foo",
     786             :       "pabgnq", 6,
     787             :       GPG_ERR_NOT_FOUND
     788             :     },
     789             :     {
     790             :       sample1,
     791             :       "public-key!!ecc",
     792             :       "pabgnq", 6,
     793             :       GPG_ERR_NOT_FOUND
     794             :     },
     795             :     {
     796             :       sample1,
     797             :       "private-key",
     798             :       "pa/bgnqd", 7,
     799             :       0,
     800             :       sample1_p, sample1_a, sample1_b, sample1_g, sample1_n,
     801             :       sample1_q, sample1_d
     802             :     },
     803             :     {
     804             :       sample1,
     805             :       "private-key",
     806             :       "p-a+bgnqd", 7,
     807             :       0,
     808             :       sample1_p, "-01", sample1_b, sample1_g, sample1_n,
     809             :       sample1_q, sample1_d
     810             :     },
     811             :     {NULL}
     812             :   };
     813             :   int idx, i;
     814             :   const char *paramstr;
     815             :   int paramidx;
     816             :   gpg_error_t err;
     817             :   gcry_sexp_t sxp;
     818             :   gcry_mpi_t mpis[7];
     819             :   gcry_buffer_t ioarray[7];
     820             :   char iobuffer[200];
     821             : 
     822           1 :   info ("checking gcry_sexp_extract_param\n");
     823          19 :   for (idx=0; tests[idx].sexp_str; idx++)
     824             :     {
     825          18 :       err = gcry_sexp_new (&sxp, tests[idx].sexp_str, 0, 1);
     826          18 :       if (err)
     827           0 :         die ("converting string to sexp failed: %s", gpg_strerror (err));
     828             : 
     829          18 :       memset (mpis, 0, sizeof mpis);
     830          18 :       switch (tests[idx].nparam)
     831             :         {
     832             :         case 0:
     833           0 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     834             :                                          NULL);
     835           0 :           break;
     836             :         case 1:
     837           0 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     838             :                                          mpis+0, NULL);
     839           0 :           break;
     840             :         case 2:
     841           0 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     842             :                                          mpis+0, mpis+1, NULL);
     843           0 :           break;
     844             :         case 3:
     845           2 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     846             :                                          mpis+0, mpis+1, mpis+2, NULL);
     847           2 :           break;
     848             :         case 4:
     849           2 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     850             :                                          mpis+0, mpis+1, mpis+2, mpis+3, NULL);
     851           2 :           break;
     852             :         case 5:
     853           0 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     854             :                                          mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
     855             :                                          NULL);
     856           0 :           break;
     857             :         case 6:
     858           4 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     859             :                                          mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
     860             :                                          mpis+5, NULL);
     861           4 :           break;
     862             :         case 7:
     863          10 :           err = gcry_sexp_extract_param (sxp, tests[idx].path, tests[idx].list,
     864             :                                          mpis+0, mpis+1, mpis+2, mpis+3, mpis+4,
     865             :                                          mpis+5, mpis+6, NULL);
     866          10 :           break;
     867             :         default:
     868           0 :           die ("test %d: internal error", idx);
     869             :         }
     870             : 
     871          18 :       if (tests[idx].expected_err
     872           8 :           && tests[idx].expected_err != GPG_ERR_USER_1)
     873             :         {
     874          14 :           if (tests[idx].expected_err != gpg_err_code (err))
     875           0 :             fail ("gcry_sexp_extract_param test %d failed: "
     876             :                   "expected error '%s' - got '%s'", idx,
     877           0 :                   gpg_strerror (tests[idx].expected_err),gpg_strerror (err));
     878             : 
     879             :         }
     880          11 :       else if (err)
     881             :         {
     882           0 :           fail ("gcry_sexp_extract_param test %d failed: %s",
     883             :                 idx, gpg_strerror (err));
     884             :         }
     885             :       else /* No error - check the extracted values.  */
     886             :         {
     887          88 :           for (paramidx=0; paramidx < DIM (mpis); paramidx++)
     888             :             {
     889          77 :               switch (paramidx)
     890             :                 {
     891          11 :                 case 0: paramstr = tests[idx].exp_p; break;
     892          11 :                 case 1: paramstr = tests[idx].exp_a; break;
     893          11 :                 case 2: paramstr = tests[idx].exp_b; break;
     894          11 :                 case 3: paramstr = tests[idx].exp_g; break;
     895          11 :                 case 4: paramstr = tests[idx].exp_n; break;
     896          11 :                 case 5: paramstr = tests[idx].exp_q; break;
     897          11 :                 case 6: paramstr = tests[idx].exp_d; break;
     898             :                 default:
     899           0 :                   die ("test %d: internal error: bad param %d",
     900             :                        idx, paramidx);
     901             :                 }
     902             : 
     903          77 :               if (tests[idx].expected_err == GPG_ERR_USER_1
     904           7 :                   && mpis[paramidx] && !paramstr && paramidx == 0)
     905             :                 ; /* Okay  Special case error for param 0.  */
     906          76 :               else if (!mpis[paramidx] && !paramstr)
     907             :                 ; /* Okay.  */
     908          59 :               else if (!mpis[paramidx] && paramstr)
     909           0 :                 fail ("test %d: value for param %d expected but not returned",
     910             :                       idx, paramidx);
     911          59 :               else if (mpis[paramidx] && !paramstr)
     912           0 :                 fail ("test %d: value for param %d not expected",
     913             :                       idx, paramidx);
     914          59 :               else if (cmp_mpihex (mpis[paramidx], paramstr))
     915             :                 {
     916           0 :                   fail ("test %d: param %d mismatch", idx, paramidx);
     917           0 :                   gcry_log_debug    ("expected: %s\n", paramstr);
     918           0 :                   gcry_log_debugmpi ("     got", mpis[paramidx]);
     919             :                 }
     920          59 :               else if (tests[idx].expected_err && paramidx == 0)
     921           0 :                 fail ("test %d: param %d: expected error '%s' - got 'Success'",
     922           0 :                       idx, paramidx, gpg_strerror (tests[idx].expected_err));
     923             :             }
     924             : 
     925             :         }
     926             : 
     927         144 :       for (i=0; i < DIM (mpis); i++)
     928         126 :         gcry_mpi_release (mpis[i]);
     929          18 :       gcry_sexp_release (sxp);
     930             :     }
     931             : 
     932           1 :   info ("checking gcry_sexp_extract_param/desc\n");
     933             : 
     934           1 :   memset (ioarray, 0, sizeof ioarray);
     935             : 
     936           1 :   err = gcry_sexp_new (&sxp, sample1, 0, 1);
     937           1 :   if (err)
     938           0 :     die ("converting string to sexp failed: %s", gpg_strerror (err));
     939             : 
     940           1 :   ioarray[1].size = sizeof iobuffer;
     941           1 :   ioarray[1].data = iobuffer;
     942           1 :   ioarray[1].off  = 0;
     943           1 :   ioarray[2].size = sizeof iobuffer;
     944           1 :   ioarray[2].data = iobuffer;
     945           1 :   ioarray[2].off  = 50;
     946           1 :   assert (ioarray[2].off < sizeof iobuffer);
     947           1 :   err = gcry_sexp_extract_param (sxp, "key-data!private-key", "&pab",
     948             :                                  ioarray+0, ioarray+1, ioarray+2, NULL);
     949           1 :   if (err)
     950           0 :     fail ("gcry_sexp_extract_param with desc failed: %s", gpg_strerror (err));
     951             :   else
     952             :     {
     953           1 :       if (!ioarray[0].data)
     954           0 :         fail ("gcry_sexp_extract_param/desc failed: no P");
     955           1 :       else if (ioarray[0].size != 32)
     956           0 :         fail ("gcry_sexp_extract_param/desc failed: P has wrong size");
     957           1 :       else if (ioarray[0].len != 32)
     958           0 :         fail ("gcry_sexp_extract_param/desc failed: P has wrong length");
     959           1 :       else if (ioarray[0].off)
     960           0 :         fail ("gcry_sexp_extract_param/desc failed: P has OFF set");
     961           1 :       else if (cmp_bufhex (ioarray[0].data, ioarray[0].len, sample1_p))
     962             :         {
     963           0 :           fail ("gcry_sexp_extract_param/desc failed: P mismatch");
     964           0 :           gcry_log_debug    ("expected: %s\n", sample1_p);
     965           0 :           gcry_log_debughex ("     got", ioarray[0].data, ioarray[0].len);
     966             :         }
     967             : 
     968           1 :       if (!ioarray[1].data)
     969           0 :         fail ("gcry_sexp_extract_param/desc failed: A buffer lost");
     970           1 :       else if (ioarray[1].size != sizeof iobuffer)
     971           0 :         fail ("gcry_sexp_extract_param/desc failed: A size changed");
     972           1 :       else if (ioarray[1].off != 0)
     973           0 :         fail ("gcry_sexp_extract_param/desc failed: A off changed");
     974           1 :       else if (ioarray[1].len != 1)
     975           0 :         fail ("gcry_sexp_extract_param/desc failed: A has wrong length");
     976           1 :       else if (cmp_bufhex ((char *)ioarray[1].data + ioarray[1].off,
     977             :                            ioarray[1].len, sample1_a))
     978             :         {
     979           0 :           fail ("gcry_sexp_extract_param/desc failed: A mismatch");
     980           0 :           gcry_log_debug    ("expected: %s\n", sample1_a);
     981           0 :           gcry_log_debughex ("     got",
     982           0 :                              (char *)ioarray[1].data + ioarray[1].off,
     983             :                              ioarray[1].len);
     984             :         }
     985             : 
     986           1 :       if (!ioarray[2].data)
     987           0 :         fail ("gcry_sexp_extract_param/desc failed: B buffer lost");
     988           1 :       else if (ioarray[2].size != sizeof iobuffer)
     989           0 :         fail ("gcry_sexp_extract_param/desc failed: B size changed");
     990           1 :       else if (ioarray[2].off != 50)
     991           0 :         fail ("gcry_sexp_extract_param/desc failed: B off changed");
     992           1 :       else if (ioarray[2].len != 32)
     993           0 :         fail ("gcry_sexp_extract_param/desc failed: B has wrong length");
     994           1 :       else if (cmp_bufhex ((char *)ioarray[2].data + ioarray[2].off,
     995             :                            ioarray[2].len, sample1_b))
     996             :         {
     997           0 :           fail ("gcry_sexp_extract_param/desc failed: B mismatch");
     998           0 :           gcry_log_debug    ("expected: %s\n", sample1_b);
     999           0 :           gcry_log_debughex ("     got",
    1000           0 :                              (char *)ioarray[2].data + ioarray[2].off,
    1001             :                              ioarray[2].len);
    1002             :         }
    1003             : 
    1004           1 :       xfree (ioarray[0].data);
    1005             :     }
    1006             : 
    1007           1 :   gcry_sexp_release (sxp);
    1008             : 
    1009           1 :   info ("checking gcry_sexp_extract_param long name\n");
    1010             : 
    1011           1 :   memset (ioarray, 0, sizeof ioarray);
    1012           1 :   memset (mpis, 0, sizeof mpis);
    1013             : 
    1014           1 :   err = gcry_sexp_new (&sxp, sample1, 0, 1);
    1015           1 :   if (err)
    1016           0 :     die ("converting string to sexp failed: %s", gpg_strerror (err));
    1017             : 
    1018           1 :   err = gcry_sexp_extract_param (sxp, "key-data!private-key",
    1019             :                                  "&'curve'+p",
    1020             :                                  ioarray+0, mpis+0, NULL);
    1021           1 :   if (err)
    1022           0 :     fail ("gcry_sexp_extract_param long name failed: %s", gpg_strerror (err));
    1023             : 
    1024           1 :   if (!ioarray[0].data)
    1025           0 :     fail ("gcry_sexp_extract_param long name failed: no curve");
    1026           1 :   else if (ioarray[0].size != 7)
    1027           0 :     fail ("gcry_sexp_extract_param long name failed: curve has wrong size");
    1028           1 :   else if (ioarray[0].len != 7)
    1029           0 :     fail ("gcry_sexp_extract_param long name failed: curve has wrong length");
    1030           1 :   else if (ioarray[0].off)
    1031           0 :     fail ("gcry_sexp_extract_param long name failed: curve has OFF set");
    1032           1 :   else if (strncmp (ioarray[0].data, "Ed25519", 7))
    1033             :     {
    1034           0 :       fail ("gcry_sexp_extract_param long name failed: curve mismatch");
    1035           0 :       gcry_log_debug ("expected: %s\n", "Ed25519");
    1036           0 :       gcry_log_debug ("     got: %.*s\n",
    1037           0 :                       (int)ioarray[0].len, (char*)ioarray[0].data);
    1038             :     }
    1039             : 
    1040           1 :   if (!mpis[0])
    1041           0 :     fail ("gcry_sexp_extract_param long name failed: p not returned");
    1042           1 :   else if (cmp_mpihex (mpis[0], sample1_p))
    1043             :     {
    1044           0 :       fail ("gcry_sexp_extract_param long name failed: p mismatch");
    1045           0 :       gcry_log_debug    ("expected: %s\n", sample1_p);
    1046           0 :       gcry_log_debugmpi ("     got", mpis[0]);
    1047             :     }
    1048             : 
    1049           1 :   gcry_free (ioarray[0].data);
    1050           1 :   gcry_mpi_release (mpis[0]);
    1051             : 
    1052           1 :   gcry_sexp_release (sxp);
    1053             : 
    1054           1 : }
    1055             : 
    1056             : 
    1057             : /* A test based on bug 1594.  */
    1058             : static void
    1059           1 : bug_1594 (void)
    1060             : {
    1061             : static char thing[] =
    1062             :   "(signature"
    1063             :   " (public-key"
    1064             :   "  (rsa"
    1065             :   "   (n #00A53A6B3A50BE571F805BD98ECE1FCE4CE291C3D4D3E971740E1EE6D447F526"
    1066             :   "       6AC8973DDC82F0ADD234CC82E0A0A3F48B81ACC8B038DB8ACC3E78DC2ED2642F"
    1067             :   "       6BA353FCA60F47C2801DEB477B37FB8B2F5508AA1C6D922780DB142DEA19B812"
    1068             :   "       C4E64F1138AD3BD61C58DB2D2591BE0BF36A1AC588AA45763BCDFF581050ABA8"
    1069             :   "       CA47BD9723ADD6A308AE28471EDD2B16D03C941D4F2B7E019C43AF8972880633"
    1070             :   "       54E97B7E19F1677D84B69A26B184A77B719DD72C48E0EE36107046F786566A9D"
    1071             :   "       13BAD724D6D78F24700FC22FC000E1B2A8C1B08ED62008395B0764CD9B55E80D"
    1072             :   "       A0A2B61C698DC27EA98E68BB576ACFC2B91B4D7283E7D960948D049D6E3C4CB1"
    1073             :   "       F489B460A120A4BB6C04A843FD3A67454136DE61CF68A927871EFFA9141BD372"
    1074             :   "       A748593C703E0301F039A9E674C50301BFC385BABE5B154250E7D57B82DB31F1"
    1075             :   "       E1AC696F870DCD8FE8DEC75608B988FCA3B484F1FD7755BF452F99597269AF02"
    1076             :   "       E8AF87D0F93DB427291659183D077254C835BFB6DDFD87CD0B5E0738682FCD34"
    1077             :   "       923F22551F73944E6CBE3ED6879B4414676B5DA0F30ED21DFA12BD2230C3C5D2"
    1078             :   "       EA116A3EFEB4AEC21C58E63FAFA549A63190F01859445E9B80F427B80FD4C884"
    1079             :   "       2AD41FE760A3E9DEDFB56CEBE8EA783838B2B392CACDDC760CCE212E388AFBC1"
    1080             :   "       95DC6D0ED87E9091F82A82CE372738C8DE8ABD76ACD06AC8B80AA0597162DF59"
    1081             :   "       67#)"
    1082             :   "   (e #010001#))))";
    1083             :   gcry_sexp_t sig, pubkey, n, n_val;
    1084             : 
    1085           1 :   info ("checking fix for bug 1594\n");
    1086             : 
    1087           1 :   if (gcry_sexp_new (&sig, thing, 0, 1))
    1088           0 :     die ("scanning fixed string failed\n");
    1089           1 :   pubkey = gcry_sexp_find_token (sig, "public-key", 0);
    1090           1 :   gcry_sexp_release (sig);
    1091           1 :   if (!pubkey)
    1092             :     {
    1093           0 :       fail ("'public-key' token not found");
    1094           0 :       return;
    1095             :     }
    1096           1 :   n = gcry_sexp_find_token (pubkey, "n", 0);
    1097           1 :   if (!n)
    1098             :     {
    1099           0 :       fail ("'n' token not found");
    1100           0 :       gcry_sexp_release (pubkey);
    1101           0 :       return;
    1102             :     }
    1103           1 :   n_val = gcry_sexp_nth (n, 1);
    1104             :   /* Bug 1594 would require the following test:
    1105             :    *   if (n_val)
    1106             :    *     fail ("extracting 1-th of 'n' list did not fail");
    1107             :    * However, we meanwhile modified the S-expression functions to
    1108             :    * behave like Scheme to allow the access of any element of a list.
    1109             :    */
    1110           1 :   if (!n_val)
    1111           0 :     fail ("extracting 1-th of 'n' list failed");
    1112             :   /*gcry_log_debugsxp ("1-th", n_val); => "(#00A5...#)"  */
    1113           1 :   gcry_sexp_release (n_val);
    1114           1 :   n_val = gcry_sexp_nth (n, 2);
    1115           1 :   if (n_val)
    1116           0 :     fail ("extracting 2-th of 'n' list did not fail");
    1117           1 :   n_val = gcry_sexp_nth (n, 0);
    1118           1 :   if (!n_val)
    1119           0 :     fail ("extracting 0-th of 'n' list failed");
    1120             :   /*gcry_log_debugsxp ("0-th", n_val); => "(n)"  */
    1121           1 :   if (gcry_sexp_nth (n_val, 1))
    1122           0 :     fail ("extracting 1-th of car of 'n' list did not fail");
    1123           1 :   gcry_sexp_release (n_val);
    1124           1 :   gcry_sexp_release (n);
    1125           1 :   gcry_sexp_release (pubkey);
    1126             : }
    1127             : 
    1128             : 
    1129             : int
    1130           1 : main (int argc, char **argv)
    1131             : {
    1132           1 :   int last_argc = -1;
    1133             : 
    1134           1 :   if (argc)
    1135             :     {
    1136           1 :       argc--; argv++;
    1137             :     }
    1138           2 :   while (argc && last_argc != argc )
    1139             :     {
    1140           0 :       last_argc = argc;
    1141           0 :       if (!strcmp (*argv, "--"))
    1142             :         {
    1143           0 :           argc--; argv++;
    1144           0 :           break;
    1145             :         }
    1146           0 :       else if (!strcmp (*argv, "--help"))
    1147             :         {
    1148           0 :           puts (
    1149             : "usage: " PGMNAME " [options]\n"
    1150             : "\n"
    1151             : "Options:\n"
    1152             : "  --verbose      Show what is going on\n"
    1153             : "  --debug        Flyswatter\n"
    1154             : );
    1155           0 :           exit (0);
    1156             :         }
    1157           0 :       else if (!strcmp (*argv, "--verbose"))
    1158             :         {
    1159           0 :           verbose = 1;
    1160           0 :           argc--; argv++;
    1161             :         }
    1162           0 :       else if (!strcmp (*argv, "--debug"))
    1163             :         {
    1164           0 :           verbose = debug = 1;
    1165           0 :           argc--; argv++;
    1166             :         }
    1167           0 :       else if (!strncmp (*argv, "--", 2))
    1168           0 :         die ("unknown option '%s'", *argv);
    1169             :     }
    1170             : 
    1171           1 :   if (debug)
    1172           0 :     gcry_control (GCRYCTL_SET_DEBUG_FLAGS, 1u, 0);
    1173           1 :   gcry_control (GCRYCTL_DISABLE_SECMEM_WARN);
    1174           1 :   gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
    1175           1 :   if (!gcry_check_version (GCRYPT_VERSION))
    1176           0 :     die ("version mismatch");
    1177             :   /* #include "../src/gcrypt-int.h" indicates that internal interfaces
    1178             :      may be used; thus better do an exact version check. */
    1179           1 :   if (strcmp (gcry_check_version (NULL), GCRYPT_VERSION))
    1180           0 :     die ("exact version match failed");
    1181           1 :   gcry_control (GCRYCTL_ENABLE_QUICK_RANDOM, 0);
    1182           1 :   gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);
    1183             : 
    1184           1 :   basic ();
    1185           1 :   canon_len ();
    1186           1 :   back_and_forth ();
    1187           1 :   check_sscan ();
    1188           1 :   check_extract_param ();
    1189           1 :   bug_1594 ();
    1190             : 
    1191           1 :   return errorcount? 1:0;
    1192             : }

Generated by: LCOV version 1.11