sexp: Fix broken gcry_sexp_nth.
[libgcrypt.git] / src / sexp.c
1 /* sexp.c  -  S-Expression handling
2  * Copyright (C) 1999, 2000, 2001, 2002, 2003,
3  *               2004, 2006, 2007, 2008, 2011  Free Software Foundation, Inc.
4  * Copyright (C) 2013, 2014 g10 Code GmbH
5  *
6  * This file is part of Libgcrypt.
7  *
8  * Libgcrypt is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU Lesser general Public License as
10  * published by the Free Software Foundation; either version 2.1 of
11  * the License, or (at your option) any later version.
12  *
13  * Libgcrypt is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  * GNU Lesser General Public License for more details.
17  *
18  * You should have received a copy of the GNU Lesser General Public
19  * License along with this program; if not, write to the Free Software
20  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
21  */
22
23
24 #include <config.h>
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28 #include <stdarg.h>
29 #include <ctype.h>
30 #include <errno.h>
31
32 #define GCRYPT_NO_MPI_MACROS 1
33 #include "g10lib.h"
34
35
36 /* Notes on the internal memory layout.
37
38    We store an S-expression as one memory buffer with tags, length and
39    value.  The simplest list would thus be:
40
41    /----------+----------+---------+------+-----------+----------\
42    | open_tag | data_tag | datalen | data | close_tag | stop_tag |
43    \----------+----------+---------+------+-----------+----------/
44
45    Expressed more compact and with an example:
46
47    /----+----+----+---+----+----\
48    | OT | DT | DL | D | CT | ST |  "(foo)"
49    \----+----+----+---+----+----/
50
51    The open tag must always be the first tag of a list as requires by
52    the S-expression specs.  At least data element (data_tag, datalen,
53    data) is required as well.  The close_tag finishes the list and
54    would actually be sufficient.  For fail-safe reasons a final stop
55    tag is always the last byte in a buffer; it has a value of 0 so
56    that string function accidently applied to an S-expression will
57    never access unallocated data.  We do not support display hints and
58    thus don't need to represent them.  A list may have more an
59    arbitrary number of data elements but at least one is required.
60    The length of each data must be greater than 0 and has a current
61    limit to 65535 bytes (by means of the DATALEN type).
62
63    A list with two data elements:
64
65    /----+----+----+---+----+----+---+----+----\
66    | OT | DT | DL | D | DT | DL | D | CT | ST |  "(foo bar)"
67    \----+----+----+---+----+----+---+----+----/
68
69    In the above example both DL fields have a value of 3.
70    A list of a list with one data element:
71
72    /----+----+----+----+---+----+----+----\
73    | OT | OT | DT | DL | D | CT | CT | ST |  "((foo))"
74    \----+----+----+----+---+----+----+----/
75
76    A list with one element followed by another list:
77
78    /----+----+----+---+----+----+----+---+----+----+----\
79    | OT | DT | DL | D | OT | DT | DL | D | CT | CT | ST |  "(foo (bar))"
80    \----+----+----+---+----+----+----+---+----+----+----/
81
82  */
83
84 typedef unsigned short DATALEN;
85
86 struct gcry_sexp
87 {
88   byte d[1];
89 };
90
91 #define ST_STOP  0
92 #define ST_DATA  1  /* datalen follows */
93 /*#define ST_HINT  2   datalen follows (currently not used) */
94 #define ST_OPEN  3
95 #define ST_CLOSE 4
96
97 /* The atoi macros assume that the buffer has only valid digits.  */
98 #define atoi_1(p)   (*(p) - '0' )
99 #define xtoi_1(p)   (*(p) <= '9'? (*(p)- '0'): \
100                      *(p) <= 'F'? (*(p)-'A'+10):(*(p)-'a'+10))
101 #define xtoi_2(p)   ((xtoi_1(p) * 16) + xtoi_1((p)+1))
102
103 #define TOKEN_SPECIALS  "-./_:*+="
104
105 static gcry_err_code_t
106 do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
107                 const char *buffer, size_t length, int argflag,
108                 void **arg_list, va_list arg_ptr);
109
110 static gcry_err_code_t
111 do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
112                const char *buffer, size_t length, int argflag,
113                void **arg_list, ...);
114
115 /* Return true if P points to a byte containing a whitespace according
116    to the S-expressions definition. */
117 #undef whitespacep
118 static GPG_ERR_INLINE int
119 whitespacep (const char *p)
120 {
121   switch (*p)
122     {
123     case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
124     default: return 0;
125     }
126 }
127
128
129 #if 0
130 static void
131 dump_mpi( gcry_mpi_t a )
132 {
133     char buffer[1000];
134     size_t n = 1000;
135
136     if( !a )
137         fputs("[no MPI]", stderr );
138     else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
139         fputs("[MPI too large to print]", stderr );
140     else
141         fputs( buffer, stderr );
142 }
143 #endif
144
145 static void
146 dump_string (const byte *p, size_t n, int delim )
147 {
148   for (; n; n--, p++ )
149     {
150       if ((*p & 0x80) || iscntrl( *p ) || *p == delim )
151         {
152           if( *p == '\n' )
153             log_printf ("\\n");
154           else if( *p == '\r' )
155             log_printf ("\\r");
156           else if( *p == '\f' )
157             log_printf ("\\f");
158           else if( *p == '\v' )
159             log_printf ("\\v");
160             else if( *p == '\b' )
161               log_printf ("\\b");
162           else if( !*p )
163             log_printf ("\\0");
164           else
165             log_printf ("\\x%02x", *p );
166         }
167       else
168         log_printf ("%c", *p);
169     }
170 }
171
172
173 void
174 _gcry_sexp_dump (const gcry_sexp_t a)
175 {
176   const byte *p;
177   int indent = 0;
178   int type;
179
180   if (!a)
181     {
182       log_printf ( "[nil]\n");
183       return;
184     }
185
186   p = a->d;
187   while ( (type = *p) != ST_STOP )
188     {
189       p++;
190       switch ( type )
191         {
192         case ST_OPEN:
193           log_printf ("%*s[open]\n", 2*indent, "");
194           indent++;
195           break;
196         case ST_CLOSE:
197           if( indent )
198             indent--;
199           log_printf ("%*s[close]\n", 2*indent, "");
200           break;
201         case ST_DATA: {
202           DATALEN n;
203           memcpy ( &n, p, sizeof n );
204           p += sizeof n;
205           log_printf ("%*s[data=\"", 2*indent, "" );
206           dump_string (p, n, '\"' );
207           log_printf ("\"]\n");
208           p += n;
209         }
210         break;
211         default:
212           log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type);
213           break;
214         }
215     }
216 }
217
218
219 /* Pass list through except when it is an empty list - in that case
220  * return NULL and release the passed list.  This is used to make sure
221  * that no forbidden empty lists are created.
222  */
223 static gcry_sexp_t
224 normalize ( gcry_sexp_t list )
225 {
226   unsigned char *p;
227
228   if ( !list )
229     return NULL;
230   p = list->d;
231   if ( *p == ST_STOP )
232     {
233       /* this is "" */
234       sexp_release ( list );
235       return NULL;
236     }
237   if ( *p == ST_OPEN && p[1] == ST_CLOSE )
238     {
239       /* this is "()" */
240       sexp_release ( list );
241       return NULL;
242     }
243
244   return list;
245 }
246
247 /* Create a new S-expression object by reading LENGTH bytes from
248    BUFFER, assuming it is canonical encoded or autodetected encoding
249    when AUTODETECT is set to 1.  With FREEFNC not NULL, ownership of
250    the buffer is transferred to the newly created object.  FREEFNC
251    should be the freefnc used to release BUFFER; there is no guarantee
252    at which point this function is called; most likey you want to use
253    free() or gcry_free().
254
255    Passing LENGTH and AUTODETECT as 0 is allowed to indicate that
256    BUFFER points to a valid canonical encoded S-expression.  A LENGTH
257    of 0 and AUTODETECT 1 indicates that buffer points to a
258    null-terminated string.
259
260    This function returns 0 and and the pointer to the new object in
261    RETSEXP or an error code in which case RETSEXP is set to NULL.  */
262 gcry_err_code_t
263 _gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
264                   int autodetect, void (*freefnc)(void*) )
265 {
266   gcry_err_code_t errcode;
267   gcry_sexp_t se;
268
269   if (!retsexp)
270     return GPG_ERR_INV_ARG;
271   *retsexp = NULL;
272   if (autodetect < 0 || autodetect > 1 || !buffer)
273     return GPG_ERR_INV_ARG;
274
275   if (!length && !autodetect)
276     { /* What a brave caller to assume that there is really a canonical
277          encoded S-expression in buffer */
278       length = _gcry_sexp_canon_len (buffer, 0, NULL, &errcode);
279       if (!length)
280         return errcode;
281     }
282   else if (!length && autodetect)
283     { /* buffer is a string */
284       length = strlen ((char *)buffer);
285     }
286
287   errcode = do_sexp_sscan (&se, NULL, buffer, length, 0, NULL);
288   if (errcode)
289     return errcode;
290
291   *retsexp = se;
292   if (freefnc)
293     {
294       /* For now we release the buffer immediately.  As soon as we
295          have changed the internal represenation of S-expression to
296          the canoncial format - which has the advantage of faster
297          parsing - we will use this function as a closure in our
298          GCRYSEXP object and use the BUFFER directly.  */
299       freefnc (buffer);
300     }
301   return 0;
302 }
303
304 /* Same as gcry_sexp_create but don't transfer ownership */
305 gcry_err_code_t
306 _gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
307                int autodetect)
308 {
309   return _gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
310 }
311
312
313 /****************
314  * Release resource of the given SEXP object.
315  */
316 void
317 _gcry_sexp_release( gcry_sexp_t sexp )
318 {
319   if (sexp)
320     {
321       if (_gcry_is_secure (sexp))
322         {
323           /* Extra paranoid wiping. */
324           const byte *p = sexp->d;
325           int type;
326
327           while ( (type = *p) != ST_STOP )
328             {
329               p++;
330               switch ( type )
331                 {
332                 case ST_OPEN:
333                   break;
334                 case ST_CLOSE:
335                   break;
336                 case ST_DATA:
337                   {
338                     DATALEN n;
339                     memcpy ( &n, p, sizeof n );
340                     p += sizeof n;
341                     p += n;
342                   }
343                   break;
344                 default:
345                   break;
346                 }
347             }
348           wipememory (sexp->d, p - sexp->d);
349         }
350       xfree ( sexp );
351     }
352 }
353
354
355 /****************
356  * Make a pair from lists a and b, don't use a or b later on.
357  * Special behaviour:  If one is a single element list we put the
358  * element straight into the new pair.
359  */
360 gcry_sexp_t
361 _gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
362 {
363   (void)a;
364   (void)b;
365
366   /* NYI: Implementation should be quite easy with our new data
367      representation */
368   BUG ();
369   return NULL;
370 }
371
372
373 /****************
374  * Make a list from all items in the array the end of the array is marked
375  * with a NULL.
376  */
377 gcry_sexp_t
378 _gcry_sexp_alist( const gcry_sexp_t *array )
379 {
380   (void)array;
381
382   /* NYI: Implementation should be quite easy with our new data
383      representation. */
384   BUG ();
385   return NULL;
386 }
387
388 /****************
389  * Make a list from all items, the end of list is indicated by a NULL
390  */
391 gcry_sexp_t
392 _gcry_sexp_vlist( const gcry_sexp_t a, ... )
393 {
394   (void)a;
395   /* NYI: Implementation should be quite easy with our new data
396      representation. */
397   BUG ();
398   return NULL;
399 }
400
401
402 /****************
403  * Append n to the list a
404  * Returns: a new ist (which maybe a)
405  */
406 gcry_sexp_t
407 _gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
408 {
409   (void)a;
410   (void)n;
411   /* NYI: Implementation should be quite easy with our new data
412      representation. */
413   BUG ();
414   return NULL;
415 }
416
417 gcry_sexp_t
418 _gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
419 {
420   (void)a;
421   (void)n;
422   /* NYI: Implementation should be quite easy with our new data
423      representation. */
424   BUG ();
425   return NULL;
426 }
427
428
429
430 /****************
431  * Locate token in a list. The token must be the car of a sublist.
432  * Returns: A new list with this sublist or NULL if not found.
433  */
434 gcry_sexp_t
435 _gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
436 {
437   const byte *p;
438   DATALEN n;
439
440   if ( !list )
441     return NULL;
442
443   if ( !toklen )
444     toklen = strlen(tok);
445
446   p = list->d;
447   while ( *p != ST_STOP )
448     {
449       if ( *p == ST_OPEN && p[1] == ST_DATA )
450         {
451           const byte *head = p;
452
453           p += 2;
454           memcpy ( &n, p, sizeof n );
455           p += sizeof n;
456           if ( n == toklen && !memcmp( p, tok, toklen ) )
457             { /* found it */
458               gcry_sexp_t newlist;
459               byte *d;
460               int level = 1;
461
462               /* Look for the end of the list.  */
463               for ( p += n; level; p++ )
464                 {
465                   if ( *p == ST_DATA )
466                     {
467                         memcpy ( &n, ++p, sizeof n );
468                         p += sizeof n + n;
469                         p--; /* Compensate for later increment. */
470                     }
471                   else if ( *p == ST_OPEN )
472                     {
473                       level++;
474                     }
475                   else if ( *p == ST_CLOSE )
476                     {
477                       level--;
478                     }
479                   else if ( *p == ST_STOP )
480                     {
481                       BUG ();
482                     }
483                 }
484               n = p - head;
485
486               newlist = xtrymalloc ( sizeof *newlist + n );
487               if (!newlist)
488                 {
489                   /* No way to return an error code, so we can only
490                      return Not Found. */
491                   return NULL;
492                 }
493               d = newlist->d;
494               memcpy ( d, head, n ); d += n;
495               *d++ = ST_STOP;
496               return normalize ( newlist );
497             }
498           p += n;
499         }
500       else if ( *p == ST_DATA )
501         {
502           memcpy ( &n, ++p, sizeof n ); p += sizeof n;
503           p += n;
504         }
505       else
506         p++;
507     }
508   return NULL;
509 }
510
511 /****************
512  * Return the length of the given list
513  */
514 int
515 _gcry_sexp_length (const gcry_sexp_t list)
516 {
517   const byte *p;
518   DATALEN n;
519   int type;
520   int length = 0;
521   int level = 0;
522
523   if (!list)
524     return 0;
525
526   p = list->d;
527   while ((type=*p) != ST_STOP)
528     {
529       p++;
530       if (type == ST_DATA)
531         {
532           memcpy (&n, p, sizeof n);
533           p += sizeof n + n;
534           if (level == 1)
535             length++;
536         }
537       else if (type == ST_OPEN)
538         {
539           if (level == 1)
540             length++;
541           level++;
542         }
543       else if (type == ST_CLOSE)
544         {
545           level--;
546         }
547     }
548   return length;
549 }
550
551
552 /* Return the internal lengths offset of LIST.  That is the size of
553    the buffer from the first ST_OPEN, which is returned at R_OFF, to
554    the corresponding ST_CLOSE inclusive.  */
555 static size_t
556 get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
557 {
558   const unsigned char *p;
559   DATALEN n;
560   int type;
561   int level = 0;
562
563   *r_off = 0;
564   if (list)
565     {
566       p = list->d;
567       while ( (type=*p) != ST_STOP )
568         {
569           p++;
570           if (type == ST_DATA)
571             {
572               memcpy (&n, p, sizeof n);
573               p += sizeof n + n;
574             }
575           else if (type == ST_OPEN)
576             {
577               if (!level)
578                 *r_off = (p-1) - list->d;
579               level++;
580             }
581           else if ( type == ST_CLOSE )
582             {
583               level--;
584               if (!level)
585                 return p - list->d;
586             }
587         }
588     }
589   return 0; /* Not a proper list.  */
590 }
591
592
593
594 /* Extract the n-th element of the given LIST.  Returns NULL for
595    no-such-element, a corrupt list, or memory failure.  */
596 gcry_sexp_t
597 _gcry_sexp_nth (const gcry_sexp_t list, int number)
598 {
599   const byte *p;
600   DATALEN n;
601   gcry_sexp_t newlist;
602   byte *d;
603   int level = 0;
604
605   if (!list || list->d[0] != ST_OPEN)
606     return NULL;
607   p = list->d;
608
609   while (number > 0)
610     {
611       p++;
612       if (*p == ST_DATA)
613         {
614           memcpy (&n, ++p, sizeof n);
615           p += sizeof n + n;
616           p--;
617           if (!level)
618             number--;
619         }
620       else if (*p == ST_OPEN)
621         {
622           level++;
623         }
624       else if (*p == ST_CLOSE)
625         {
626           level--;
627           if ( !level )
628             number--;
629         }
630       else if (*p == ST_STOP)
631         {
632           return NULL;
633         }
634     }
635   p++;
636
637   if (*p == ST_DATA)
638     {
639       memcpy (&n, p+1, sizeof n);
640       newlist = xtrymalloc (sizeof *newlist + 1 + 1 + sizeof n + n + 1);
641       if (!newlist)
642         return NULL;
643       d = newlist->d;
644       *d++ = ST_OPEN;
645       memcpy (d, p, 1 + sizeof n + n);
646       d += 1 + sizeof n + n;
647       *d++ = ST_CLOSE;
648       *d = ST_STOP;
649     }
650   else if (*p == ST_OPEN)
651     {
652       const byte *head = p;
653
654       level = 1;
655       do {
656         p++;
657         if (*p == ST_DATA)
658           {
659             memcpy (&n, ++p, sizeof n);
660             p += sizeof n + n;
661             p--;
662           }
663         else if (*p == ST_OPEN)
664           {
665             level++;
666           }
667         else if (*p == ST_CLOSE)
668           {
669             level--;
670           }
671         else if (*p == ST_STOP)
672           {
673             BUG ();
674           }
675       } while (level);
676       n = p + 1 - head;
677
678       newlist = xtrymalloc (sizeof *newlist + n);
679       if (!newlist)
680         return NULL;
681       d = newlist->d;
682       memcpy (d, head, n);
683       d += n;
684       *d++ = ST_STOP;
685     }
686   else
687     newlist = NULL;
688
689   return normalize (newlist);
690 }
691
692
693 gcry_sexp_t
694 _gcry_sexp_car (const gcry_sexp_t list)
695 {
696   return _gcry_sexp_nth (list, 0);
697 }
698
699
700 /* Helper to get data from the car.  The returned value is valid as
701    long as the list is not modified. */
702 static const char *
703 do_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
704 {
705   const byte *p;
706   DATALEN n;
707   int level = 0;
708
709   *datalen = 0;
710   if ( !list )
711     return NULL;
712
713   p = list->d;
714   if ( *p == ST_OPEN )
715     p++;             /* Yep, a list. */
716   else if (number)
717     return NULL;     /* Not a list but N > 0 requested. */
718
719   /* Skip over N elements. */
720   while (number > 0)
721     {
722       if (*p == ST_DATA)
723         {
724           memcpy ( &n, ++p, sizeof n );
725           p += sizeof n + n;
726           p--;
727           if ( !level )
728             number--;
729         }
730       else if (*p == ST_OPEN)
731         {
732           level++;
733         }
734       else if (*p == ST_CLOSE)
735         {
736           level--;
737           if ( !level )
738             number--;
739         }
740       else if (*p == ST_STOP)
741         {
742           return NULL;
743         }
744       p++;
745     }
746
747   /* If this is data, return it.  */
748   if (*p == ST_DATA)
749     {
750       memcpy ( &n, ++p, sizeof n );
751       *datalen = n;
752       return (const char*)p + sizeof n;
753     }
754
755   return NULL;
756 }
757
758
759 /* Get data from the car.  The returned value is valid as long as the
760    list is not modified.  */
761 const char *
762 _gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
763 {
764   return do_sexp_nth_data (list, number, datalen);
765 }
766
767
768 /* Get the nth element of a list which needs to be a simple object.
769    The returned value is a malloced buffer and needs to be freed by
770    the caller.  This is basically the same as gcry_sexp_nth_data but
771    with an allocated result. */
772 void *
773 _gcry_sexp_nth_buffer (const gcry_sexp_t list, int number, size_t *rlength)
774 {
775   const char *s;
776   size_t n;
777   char *buf;
778
779   *rlength = 0;
780   s = do_sexp_nth_data (list, number, &n);
781   if (!s || !n)
782     return NULL;
783   buf = xtrymalloc (n);
784   if (!buf)
785     return NULL;
786   memcpy (buf, s, n);
787   *rlength = n;
788   return buf;
789 }
790
791
792 /* Get a string from the car.  The returned value is a malloced string
793    and needs to be freed by the caller.  */
794 char *
795 _gcry_sexp_nth_string (const gcry_sexp_t list, int number)
796 {
797   const char *s;
798   size_t n;
799   char *buf;
800
801   s = do_sexp_nth_data (list, number, &n);
802   if (!s || n < 1 || (n+1) < 1)
803     return NULL;
804   buf = xtrymalloc (n+1);
805   if (!buf)
806     return NULL;
807   memcpy (buf, s, n);
808   buf[n] = 0;
809   return buf;
810 }
811
812
813 /*
814  * Get a MPI from the car
815  */
816 gcry_mpi_t
817 _gcry_sexp_nth_mpi (gcry_sexp_t list, int number, int mpifmt)
818 {
819   size_t n;
820   gcry_mpi_t a;
821
822   if (mpifmt == GCRYMPI_FMT_OPAQUE)
823     {
824       char *p;
825
826       p = _gcry_sexp_nth_buffer (list, number, &n);
827       if (!p)
828         return NULL;
829
830       a = _gcry_is_secure (list)? _gcry_mpi_snew (0) : _gcry_mpi_new (0);
831       if (a)
832         mpi_set_opaque (a, p, n*8);
833       else
834         xfree (p);
835     }
836   else
837     {
838       const char *s;
839
840       if (!mpifmt)
841         mpifmt = GCRYMPI_FMT_STD;
842
843       s = do_sexp_nth_data (list, number, &n);
844       if (!s)
845         return NULL;
846
847       if (_gcry_mpi_scan (&a, mpifmt, s, n, NULL))
848         return NULL;
849     }
850
851   return a;
852 }
853
854
855 /****************
856  * Get the CDR
857  */
858 gcry_sexp_t
859 _gcry_sexp_cdr(const gcry_sexp_t list)
860 {
861   const byte *p;
862   const byte *head;
863   DATALEN n;
864   gcry_sexp_t newlist;
865   byte *d;
866   int level = 0;
867   int skip = 1;
868
869   if (!list || list->d[0] != ST_OPEN)
870     return NULL;
871   p = list->d;
872
873   while (skip > 0)
874     {
875       p++;
876       if (*p == ST_DATA)
877         {
878           memcpy ( &n, ++p, sizeof n );
879           p += sizeof n + n;
880           p--;
881           if ( !level )
882             skip--;
883         }
884       else if (*p == ST_OPEN)
885         {
886           level++;
887         }
888       else if (*p == ST_CLOSE)
889         {
890           level--;
891           if ( !level )
892             skip--;
893         }
894       else if (*p == ST_STOP)
895         {
896           return NULL;
897         }
898     }
899   p++;
900
901   head = p;
902   level = 0;
903   do {
904     if (*p == ST_DATA)
905       {
906         memcpy ( &n, ++p, sizeof n );
907         p += sizeof n + n;
908         p--;
909       }
910     else if (*p == ST_OPEN)
911       {
912         level++;
913       }
914     else if (*p == ST_CLOSE)
915       {
916         level--;
917       }
918     else if (*p == ST_STOP)
919       {
920         return NULL;
921       }
922     p++;
923   } while (level);
924   n = p - head;
925
926   newlist = xtrymalloc (sizeof *newlist + n + 2);
927   if (!newlist)
928     return NULL;
929   d = newlist->d;
930   *d++ = ST_OPEN;
931   memcpy (d, head, n);
932   d += n;
933   *d++ = ST_CLOSE;
934   *d++ = ST_STOP;
935
936   return normalize (newlist);
937 }
938
939
940 gcry_sexp_t
941 _gcry_sexp_cadr ( const gcry_sexp_t list )
942 {
943   gcry_sexp_t a, b;
944
945   a = _gcry_sexp_cdr (list);
946   b = _gcry_sexp_car (a);
947   sexp_release (a);
948   return b;
949 }
950
951
952 static GPG_ERR_INLINE int
953 hextonibble (int s)
954 {
955   if (s >= '0' && s <= '9')
956     return s - '0';
957   else if (s >= 'A' && s <= 'F')
958     return 10 + s - 'A';
959   else if (s >= 'a' && s <= 'f')
960     return 10 + s - 'a';
961   else
962     return 0;
963 }
964
965
966 struct make_space_ctx
967 {
968   gcry_sexp_t sexp;
969   size_t allocated;
970   byte *pos;
971 };
972
973
974 static gpg_err_code_t
975 make_space ( struct make_space_ctx *c, size_t n )
976 {
977   size_t used = c->pos - c->sexp->d;
978
979   if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
980     {
981       gcry_sexp_t newsexp;
982       byte *newhead;
983       size_t newsize;
984
985       newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
986       if (newsize <= c->allocated)
987         return GPG_ERR_TOO_LARGE;
988       newsexp = xtryrealloc ( c->sexp, sizeof *newsexp + newsize - 1);
989       if (!newsexp)
990         return gpg_err_code_from_errno (errno);
991       c->allocated = newsize;
992       newhead = newsexp->d;
993       c->pos = newhead + used;
994       c->sexp = newsexp;
995     }
996   return 0;
997 }
998
999
1000 /* Unquote STRING of LENGTH and store it into BUF.  The surrounding
1001    quotes are must already be removed from STRING.  We assume that the
1002    quoted string is syntacillay correct.  */
1003 static size_t
1004 unquote_string (const char *string, size_t length, unsigned char *buf)
1005 {
1006   int esc = 0;
1007   const unsigned char *s = (const unsigned char*)string;
1008   unsigned char *d = buf;
1009   size_t n = length;
1010
1011   for (; n; n--, s++)
1012     {
1013       if (esc)
1014         {
1015           switch (*s)
1016             {
1017             case 'b':  *d++ = '\b'; break;
1018             case 't':  *d++ = '\t'; break;
1019             case 'v':  *d++ = '\v'; break;
1020             case 'n':  *d++ = '\n'; break;
1021             case 'f':  *d++ = '\f'; break;
1022             case 'r':  *d++ = '\r'; break;
1023             case '"':  *d++ = '\"'; break;
1024             case '\'': *d++ = '\''; break;
1025             case '\\': *d++ = '\\'; break;
1026
1027             case '\r':  /* ignore CR[,LF] */
1028               if (n>1 && s[1] == '\n')
1029                 {
1030                   s++; n--;
1031                 }
1032               break;
1033
1034             case '\n':  /* ignore LF[,CR] */
1035               if (n>1 && s[1] == '\r')
1036                 {
1037                   s++; n--;
1038                 }
1039               break;
1040
1041             case 'x': /* hex value */
1042               if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
1043                 {
1044                   s++; n--;
1045                   *d++ = xtoi_2 (s);
1046                   s++; n--;
1047                 }
1048               break;
1049
1050             default:
1051               if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
1052                 {
1053                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
1054                   s += 2;
1055                   n -= 2;
1056                 }
1057               break;
1058             }
1059           esc = 0;
1060         }
1061       else if( *s == '\\' )
1062         esc = 1;
1063       else
1064         *d++ = *s;
1065     }
1066
1067   return d - buf;
1068 }
1069
1070 /****************
1071  * Scan the provided buffer and return the S expression in our internal
1072  * format.  Returns a newly allocated expression.  If erroff is not NULL and
1073  * a parsing error has occurred, the offset into buffer will be returned.
1074  * If ARGFLAG is true, the function supports some printf like
1075  * expressions.
1076  *  These are:
1077  *      %m - MPI
1078  *      %s - string (no autoswitch to secure allocation)
1079  *      %d - integer stored as string (no autoswitch to secure allocation)
1080  *      %b - memory buffer; this takes _two_ arguments: an integer with the
1081  *           length of the buffer and a pointer to the buffer.
1082  *      %S - Copy an gcry_sexp_t here.  The S-expression needs to be a
1083  *           regular one, starting with a parenthesis.
1084  *           (no autoswitch to secure allocation)
1085  *  all other format elements are currently not defined and return an error.
1086  *  this includes the "%%" sequence becauce the percent sign is not an
1087  *  allowed character.
1088  * FIXME: We should find a way to store the secure-MPIs not in the string
1089  * but as reference to somewhere - this can help us to save huge amounts
1090  * of secure memory.  The problem is, that if only one element is secure, all
1091  * other elements are automagicaly copied to secure memory too, so the most
1092  * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
1093  * regardless whether it is needed or not.
1094  */
1095 static gpg_err_code_t
1096 do_vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1097                 const char *buffer, size_t length, int argflag,
1098                 void **arg_list, va_list arg_ptr)
1099 {
1100   gcry_err_code_t err = 0;
1101   static const char tokenchars[] =
1102     "abcdefghijklmnopqrstuvwxyz"
1103     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1104     "0123456789-./_:*+=";
1105   const char *p;
1106   size_t n;
1107   const char *digptr = NULL;
1108   const char *quoted = NULL;
1109   const char *tokenp = NULL;
1110   const char *hexfmt = NULL;
1111   const char *base64 = NULL;
1112   const char *disphint = NULL;
1113   const char *percent = NULL;
1114   int hexcount = 0;
1115   int quoted_esc = 0;
1116   int datalen = 0;
1117   size_t dummy_erroff;
1118   struct make_space_ctx c;
1119   int arg_counter = 0;
1120   int level = 0;
1121
1122   if (!erroff)
1123     erroff = &dummy_erroff;
1124
1125   /* Depending on whether ARG_LIST is non-zero or not, this macro gives
1126      us the next argument, either from the variable argument list as
1127      specified by ARG_PTR or from the argument array ARG_LIST.  */
1128 #define ARG_NEXT(storage, type)                          \
1129   do                                                     \
1130     {                                                    \
1131       if (!arg_list)                                     \
1132         storage = va_arg (arg_ptr, type);                \
1133       else                                               \
1134         storage = *((type *) (arg_list[arg_counter++])); \
1135     }                                                    \
1136   while (0)
1137
1138   /* The MAKE_SPACE macro is used before each store operation to
1139      ensure that the buffer is large enough.  It requires a global
1140      context named C and jumps out to the label LEAVE on error! It
1141      also sets ERROFF using the variables BUFFER and P.  */
1142 #define MAKE_SPACE(n)  do {                                                \
1143                             gpg_err_code_t _ms_err = make_space (&c, (n)); \
1144                             if (_ms_err)                                   \
1145                               {                                            \
1146                                 err = _ms_err;                             \
1147                                 *erroff = p - buffer;                      \
1148                                 goto leave;                                \
1149                               }                                            \
1150                        } while (0)
1151
1152   /* The STORE_LEN macro is used to store the length N at buffer P. */
1153 #define STORE_LEN(p,n) do {                                                \
1154                             DATALEN ashort = (n);                          \
1155                             memcpy ( (p), &ashort, sizeof(ashort) );       \
1156                             (p) += sizeof (ashort);                        \
1157                         } while (0)
1158
1159   /* We assume that the internal representation takes less memory than
1160      the provided one.  However, we add space for one extra datalen so
1161      that the code which does the ST_CLOSE can use MAKE_SPACE */
1162   c.allocated = length + sizeof(DATALEN);
1163   if (buffer && length && _gcry_is_secure (buffer))
1164     c.sexp = xtrymalloc_secure (sizeof *c.sexp + c.allocated - 1);
1165   else
1166     c.sexp = xtrymalloc (sizeof *c.sexp + c.allocated - 1);
1167   if (!c.sexp)
1168     {
1169       err = gpg_err_code_from_errno (errno);
1170       *erroff = 0;
1171       goto leave;
1172     }
1173   c.pos = c.sexp->d;
1174
1175   for (p = buffer, n = length; n; p++, n--)
1176     {
1177       if (tokenp && !hexfmt)
1178         {
1179           if (strchr (tokenchars, *p))
1180             continue;
1181           else
1182             {
1183               datalen = p - tokenp;
1184               MAKE_SPACE (datalen);
1185               *c.pos++ = ST_DATA;
1186               STORE_LEN (c.pos, datalen);
1187               memcpy (c.pos, tokenp, datalen);
1188               c.pos += datalen;
1189               tokenp = NULL;
1190             }
1191         }
1192
1193       if (quoted)
1194         {
1195           if (quoted_esc)
1196             {
1197               switch (*p)
1198                 {
1199                 case 'b': case 't': case 'v': case 'n': case 'f':
1200                 case 'r': case '"': case '\'': case '\\':
1201                   quoted_esc = 0;
1202                   break;
1203
1204                 case '0': case '1': case '2': case '3': case '4':
1205                 case '5': case '6': case '7':
1206                   if (!((n > 2)
1207                         && (p[1] >= '0') && (p[1] <= '7')
1208                         && (p[2] >= '0') && (p[2] <= '7')))
1209                     {
1210                       *erroff = p - buffer;
1211                       /* Invalid octal value.  */
1212                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1213                       goto leave;
1214                     }
1215                   p += 2;
1216                   n -= 2;
1217                   quoted_esc = 0;
1218                   break;
1219
1220                 case 'x':
1221                   if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
1222                     {
1223                       *erroff = p - buffer;
1224                       /* Invalid hex value.  */
1225                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1226                       goto leave;
1227                     }
1228                   p += 2;
1229                   n -= 2;
1230                   quoted_esc = 0;
1231                   break;
1232
1233                 case '\r':
1234                   /* ignore CR[,LF] */
1235                   if (n && (p[1] == '\n'))
1236                     {
1237                       p++;
1238                       n--;
1239                     }
1240                   quoted_esc = 0;
1241                   break;
1242
1243                 case '\n':
1244                   /* ignore LF[,CR] */
1245                   if (n && (p[1] == '\r'))
1246                     {
1247                       p++;
1248                       n--;
1249                     }
1250                   quoted_esc = 0;
1251                   break;
1252
1253                 default:
1254                   *erroff = p - buffer;
1255                   /* Invalid quoted string escape.  */
1256                   err = GPG_ERR_SEXP_BAD_QUOTATION;
1257                   goto leave;
1258                 }
1259             }
1260           else if (*p == '\\')
1261             quoted_esc = 1;
1262           else if (*p == '\"')
1263             {
1264               /* Keep it easy - we know that the unquoted string will
1265                  never be larger. */
1266               unsigned char *save;
1267               size_t len;
1268
1269               quoted++; /* Skip leading quote.  */
1270               MAKE_SPACE (p - quoted);
1271               *c.pos++ = ST_DATA;
1272               save = c.pos;
1273               STORE_LEN (c.pos, 0); /* Will be fixed up later.  */
1274               len = unquote_string (quoted, p - quoted, c.pos);
1275               c.pos += len;
1276               STORE_LEN (save, len);
1277               quoted = NULL;
1278             }
1279         }
1280       else if (hexfmt)
1281         {
1282           if (isxdigit (*p))
1283             hexcount++;
1284           else if (*p == '#')
1285             {
1286               if ((hexcount & 1))
1287                 {
1288                   *erroff = p - buffer;
1289                   err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
1290                   goto leave;
1291                 }
1292
1293               datalen = hexcount / 2;
1294               MAKE_SPACE (datalen);
1295               *c.pos++ = ST_DATA;
1296               STORE_LEN (c.pos, datalen);
1297               for (hexfmt++; hexfmt < p; hexfmt++)
1298                 {
1299                   int tmpc;
1300
1301                   if (whitespacep (hexfmt))
1302                     continue;
1303                   tmpc = hextonibble (*(const unsigned char*)hexfmt);
1304                   for (hexfmt++; hexfmt < p && whitespacep (hexfmt); hexfmt++)
1305                     ;
1306                   if (hexfmt < p)
1307                     {
1308                       tmpc *= 16;
1309                       tmpc += hextonibble (*(const unsigned char*)hexfmt);
1310                     }
1311                   *c.pos++ = tmpc;
1312                 }
1313               hexfmt = NULL;
1314             }
1315           else if (!whitespacep (p))
1316             {
1317               *erroff = p - buffer;
1318               err = GPG_ERR_SEXP_BAD_HEX_CHAR;
1319               goto leave;
1320             }
1321         }
1322       else if (base64)
1323         {
1324           if (*p == '|')
1325             base64 = NULL;
1326         }
1327       else if (digptr)
1328         {
1329           if (digitp (p))
1330             ;
1331           else if (*p == ':')
1332             {
1333               datalen = atoi (digptr); /* FIXME: check for overflow.  */
1334               digptr = NULL;
1335               if (datalen > n - 1)
1336                 {
1337                   *erroff = p - buffer;
1338                   /* Buffer too short.  */
1339                   err = GPG_ERR_SEXP_STRING_TOO_LONG;
1340                   goto leave;
1341                 }
1342               /* Make a new list entry.  */
1343               MAKE_SPACE (datalen);
1344               *c.pos++ = ST_DATA;
1345               STORE_LEN (c.pos, datalen);
1346               memcpy (c.pos, p + 1, datalen);
1347               c.pos += datalen;
1348               n -= datalen;
1349               p += datalen;
1350             }
1351           else if (*p == '\"')
1352             {
1353               digptr = NULL; /* We ignore the optional length.  */
1354               quoted = p;
1355               quoted_esc = 0;
1356             }
1357           else if (*p == '#')
1358             {
1359               digptr = NULL; /* We ignore the optional length.  */
1360               hexfmt = p;
1361               hexcount = 0;
1362             }
1363           else if (*p == '|')
1364             {
1365               digptr = NULL; /* We ignore the optional length.  */
1366               base64 = p;
1367             }
1368           else
1369             {
1370               *erroff = p - buffer;
1371               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1372               goto leave;
1373             }
1374         }
1375       else if (percent)
1376         {
1377           if (*p == 'm' || *p == 'M')
1378             {
1379               /* Insert an MPI.  */
1380               gcry_mpi_t m;
1381               size_t nm = 0;
1382               int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;
1383
1384               ARG_NEXT (m, gcry_mpi_t);
1385
1386               if (mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
1387                 {
1388                   void *mp;
1389                   unsigned int nbits;
1390
1391                   mp = mpi_get_opaque (m, &nbits);
1392                   nm = (nbits+7)/8;
1393                   if (mp && nm)
1394                     {
1395                       MAKE_SPACE (nm);
1396                       if (!_gcry_is_secure (c.sexp->d)
1397                           && mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
1398                         {
1399                           /* We have to switch to secure allocation.  */
1400                           gcry_sexp_t newsexp;
1401                           byte *newhead;
1402
1403                           newsexp = xtrymalloc_secure (sizeof *newsexp
1404                                                        + c.allocated - 1);
1405                           if (!newsexp)
1406                             {
1407                               err = gpg_err_code_from_errno (errno);
1408                               goto leave;
1409                             }
1410                           newhead = newsexp->d;
1411                           memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1412                           c.pos = newhead + (c.pos - c.sexp->d);
1413                           xfree (c.sexp);
1414                           c.sexp = newsexp;
1415                         }
1416
1417                       *c.pos++ = ST_DATA;
1418                       STORE_LEN (c.pos, nm);
1419                       memcpy (c.pos, mp, nm);
1420                       c.pos += nm;
1421                     }
1422                 }
1423               else
1424                 {
1425                   if (_gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
1426                     BUG ();
1427
1428                   MAKE_SPACE (nm);
1429                   if (!_gcry_is_secure (c.sexp->d)
1430                       && mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
1431                     {
1432                       /* We have to switch to secure allocation.  */
1433                       gcry_sexp_t newsexp;
1434                       byte *newhead;
1435
1436                       newsexp = xtrymalloc_secure (sizeof *newsexp
1437                                                    + c.allocated - 1);
1438                       if (!newsexp)
1439                         {
1440                           err = gpg_err_code_from_errno (errno);
1441                           goto leave;
1442                         }
1443                       newhead = newsexp->d;
1444                       memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1445                       c.pos = newhead + (c.pos - c.sexp->d);
1446                       xfree (c.sexp);
1447                       c.sexp = newsexp;
1448                     }
1449
1450                   *c.pos++ = ST_DATA;
1451                   STORE_LEN (c.pos, nm);
1452                   if (_gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
1453                     BUG ();
1454                   c.pos += nm;
1455                 }
1456             }
1457           else if (*p == 's')
1458             {
1459               /* Insert an string.  */
1460               const char *astr;
1461               size_t alen;
1462
1463               ARG_NEXT (astr, const char *);
1464               alen = strlen (astr);
1465
1466               MAKE_SPACE (alen);
1467               *c.pos++ = ST_DATA;
1468               STORE_LEN (c.pos, alen);
1469               memcpy (c.pos, astr, alen);
1470               c.pos += alen;
1471             }
1472           else if (*p == 'b')
1473             {
1474               /* Insert a memory buffer.  */
1475               const char *astr;
1476               int alen;
1477
1478               ARG_NEXT (alen, int);
1479               ARG_NEXT (astr, const char *);
1480
1481               MAKE_SPACE (alen);
1482               if (alen
1483                   && !_gcry_is_secure (c.sexp->d)
1484                   && _gcry_is_secure (astr))
1485               {
1486                   /* We have to switch to secure allocation.  */
1487                   gcry_sexp_t newsexp;
1488                   byte *newhead;
1489
1490                   newsexp = xtrymalloc_secure (sizeof *newsexp
1491                                                + c.allocated - 1);
1492                   if (!newsexp)
1493                     {
1494                       err = gpg_err_code_from_errno (errno);
1495                       goto leave;
1496                     }
1497                   newhead = newsexp->d;
1498                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1499                   c.pos = newhead + (c.pos - c.sexp->d);
1500                   xfree (c.sexp);
1501                   c.sexp = newsexp;
1502                 }
1503
1504               *c.pos++ = ST_DATA;
1505               STORE_LEN (c.pos, alen);
1506               memcpy (c.pos, astr, alen);
1507               c.pos += alen;
1508             }
1509           else if (*p == 'd')
1510             {
1511               /* Insert an integer as string.  */
1512               int aint;
1513               size_t alen;
1514               char buf[35];
1515
1516               ARG_NEXT (aint, int);
1517               sprintf (buf, "%d", aint);
1518               alen = strlen (buf);
1519               MAKE_SPACE (alen);
1520               *c.pos++ = ST_DATA;
1521               STORE_LEN (c.pos, alen);
1522               memcpy (c.pos, buf, alen);
1523               c.pos += alen;
1524             }
1525           else if (*p == 'u')
1526             {
1527               /* Insert an unsigned integer as string.  */
1528               unsigned int aint;
1529               size_t alen;
1530               char buf[35];
1531
1532               ARG_NEXT (aint, unsigned int);
1533               sprintf (buf, "%u", aint);
1534               alen = strlen (buf);
1535               MAKE_SPACE (alen);
1536               *c.pos++ = ST_DATA;
1537               STORE_LEN (c.pos, alen);
1538               memcpy (c.pos, buf, alen);
1539               c.pos += alen;
1540             }
1541           else if (*p == 'S')
1542             {
1543               /* Insert a gcry_sexp_t.  */
1544               gcry_sexp_t asexp;
1545               size_t alen, aoff;
1546
1547               ARG_NEXT (asexp, gcry_sexp_t);
1548               alen = get_internal_buffer (asexp, &aoff);
1549               if (alen)
1550                 {
1551                   MAKE_SPACE (alen);
1552                   memcpy (c.pos, asexp->d + aoff, alen);
1553                   c.pos += alen;
1554                 }
1555             }
1556           else
1557             {
1558               *erroff = p - buffer;
1559               /* Invalid format specifier.  */
1560               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1561               goto leave;
1562             }
1563           percent = NULL;
1564         }
1565       else if (*p == '(')
1566         {
1567           if (disphint)
1568             {
1569               *erroff = p - buffer;
1570               /* Open display hint.  */
1571               err = GPG_ERR_SEXP_UNMATCHED_DH;
1572               goto leave;
1573             }
1574           MAKE_SPACE (0);
1575           *c.pos++ = ST_OPEN;
1576           level++;
1577         }
1578       else if (*p == ')')
1579         {
1580           /* Walk up.  */
1581           if (disphint)
1582             {
1583               *erroff = p - buffer;
1584               /* Open display hint.  */
1585               err = GPG_ERR_SEXP_UNMATCHED_DH;
1586               goto leave;
1587             }
1588           MAKE_SPACE (0);
1589           *c.pos++ = ST_CLOSE;
1590           level--;
1591         }
1592       else if (*p == '\"')
1593         {
1594           quoted = p;
1595           quoted_esc = 0;
1596         }
1597       else if (*p == '#')
1598         {
1599           hexfmt = p;
1600           hexcount = 0;
1601         }
1602       else if (*p == '|')
1603         base64 = p;
1604       else if (*p == '[')
1605         {
1606           if (disphint)
1607             {
1608               *erroff = p - buffer;
1609               /* Open display hint.  */
1610               err = GPG_ERR_SEXP_NESTED_DH;
1611               goto leave;
1612             }
1613           disphint = p;
1614         }
1615       else if (*p == ']')
1616         {
1617           if (!disphint)
1618             {
1619               *erroff = p - buffer;
1620               /* Open display hint.  */
1621               err = GPG_ERR_SEXP_UNMATCHED_DH;
1622               goto leave;
1623             }
1624           disphint = NULL;
1625         }
1626       else if (digitp (p))
1627         {
1628           if (*p == '0')
1629             {
1630               /* A length may not begin with zero.  */
1631               *erroff = p - buffer;
1632               err = GPG_ERR_SEXP_ZERO_PREFIX;
1633               goto leave;
1634             }
1635           digptr = p;
1636         }
1637       else if (strchr (tokenchars, *p))
1638         tokenp = p;
1639       else if (whitespacep (p))
1640         ;
1641       else if (*p == '{')
1642         {
1643           /* fixme: handle rescanning: we can do this by saving our
1644              current state and start over at p+1 -- Hmmm. At this
1645              point here we are in a well defined state, so we don't
1646              need to save it.  Great.  */
1647           *erroff = p - buffer;
1648           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1649           goto leave;
1650         }
1651       else if (strchr ("&\\", *p))
1652         {
1653           /* Reserved punctuation.  */
1654           *erroff = p - buffer;
1655           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1656           goto leave;
1657         }
1658       else if (argflag && (*p == '%'))
1659         percent = p;
1660       else
1661         {
1662           /* Bad or unavailable.  */
1663           *erroff = p - buffer;
1664           err = GPG_ERR_SEXP_BAD_CHARACTER;
1665           goto leave;
1666         }
1667     }
1668   MAKE_SPACE (0);
1669   *c.pos++ = ST_STOP;
1670
1671   if (level && !err)
1672     err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1673
1674  leave:
1675   if (err)
1676     {
1677       /* Error -> deallocate.  */
1678       if (c.sexp)
1679         {
1680           /* Extra paranoid wipe on error. */
1681           if (_gcry_is_secure (c.sexp))
1682             wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
1683           xfree (c.sexp);
1684         }
1685       /* This might be expected by existing code...  */
1686       *retsexp = NULL;
1687     }
1688   else
1689     *retsexp = normalize (c.sexp);
1690
1691   return err;
1692 #undef MAKE_SPACE
1693 #undef STORE_LEN
1694 }
1695
1696
1697 static gpg_err_code_t
1698 do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1699                const char *buffer, size_t length, int argflag,
1700                void **arg_list, ...)
1701 {
1702   gcry_err_code_t rc;
1703   va_list arg_ptr;
1704
1705   va_start (arg_ptr, arg_list);
1706   rc = do_vsexp_sscan (retsexp, erroff, buffer, length, argflag,
1707                        arg_list, arg_ptr);
1708   va_end (arg_ptr);
1709
1710   return rc;
1711 }
1712
1713
1714 gpg_err_code_t
1715 _gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
1716 {
1717   gcry_err_code_t rc;
1718   va_list arg_ptr;
1719
1720   va_start (arg_ptr, format);
1721   rc = do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1722                        NULL, arg_ptr);
1723   va_end (arg_ptr);
1724
1725   return rc;
1726 }
1727
1728
1729 gcry_err_code_t
1730 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
1731                    const char *format, va_list arg_ptr)
1732 {
1733   return do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1734                          NULL, arg_ptr);
1735 }
1736
1737
1738 /* Like gcry_sexp_build, but uses an array instead of variable
1739    function arguments.  */
1740 gcry_err_code_t
1741 _gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1742                         const char *format, void **arg_list)
1743 {
1744   return do_sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
1745 }
1746
1747
1748 gcry_err_code_t
1749 _gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1750                   const char *buffer, size_t length)
1751 {
1752   return do_sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
1753 }
1754
1755 \f
1756 /* Figure out a suitable encoding for BUFFER of LENGTH.
1757    Returns: 0 = Binary
1758             1 = String possible
1759             2 = Token possible
1760 */
1761 static int
1762 suitable_encoding (const unsigned char *buffer, size_t length)
1763 {
1764   const unsigned char *s;
1765   int maybe_token = 1;
1766
1767   if (!length)
1768     return 1;
1769
1770   if (*buffer & 0x80)
1771     return 0; /* If the MSB is set we assume that buffer represents a
1772                  negative number.  */
1773   if (!*buffer)
1774     return 0; /* Starting with a zero is pretty much a binary string.  */
1775
1776   for (s=buffer; length; s++, length--)
1777     {
1778       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1779            && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1780         return 0; /*binary*/
1781       if ( maybe_token
1782            && !alphap (s) && !digitp (s)  && !strchr (TOKEN_SPECIALS, *s))
1783         maybe_token = 0;
1784     }
1785   s = buffer;
1786   if ( maybe_token && !digitp (s) )
1787     return 2;
1788   return 1;
1789 }
1790
1791
1792 static int
1793 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1794 {
1795   int i;
1796
1797   if (dest)
1798     {
1799       *dest++ = '#';
1800       for (i=0; i < len; i++, dest += 2 )
1801         sprintf (dest, "%02X", src[i]);
1802       *dest++ = '#';
1803     }
1804   return len*2+2;
1805 }
1806
1807 static int
1808 convert_to_string (const unsigned char *s, size_t len, char *dest)
1809 {
1810   if (dest)
1811     {
1812       char *p = dest;
1813       *p++ = '\"';
1814       for (; len; len--, s++ )
1815         {
1816           switch (*s)
1817             {
1818             case '\b': *p++ = '\\'; *p++ = 'b';  break;
1819             case '\t': *p++ = '\\'; *p++ = 't';  break;
1820             case '\v': *p++ = '\\'; *p++ = 'v';  break;
1821             case '\n': *p++ = '\\'; *p++ = 'n';  break;
1822             case '\f': *p++ = '\\'; *p++ = 'f';  break;
1823             case '\r': *p++ = '\\'; *p++ = 'r';  break;
1824             case '\"': *p++ = '\\'; *p++ = '\"';  break;
1825             case '\'': *p++ = '\\'; *p++ = '\'';  break;
1826             case '\\': *p++ = '\\'; *p++ = '\\';  break;
1827             default:
1828               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1829                 {
1830                   sprintf (p, "\\x%02x", *s);
1831                   p += 4;
1832                 }
1833               else
1834                 *p++ = *s;
1835             }
1836         }
1837       *p++ = '\"';
1838       return p - dest;
1839     }
1840   else
1841     {
1842       int count = 2;
1843       for (; len; len--, s++ )
1844         {
1845           switch (*s)
1846             {
1847             case '\b':
1848             case '\t':
1849             case '\v':
1850             case '\n':
1851             case '\f':
1852             case '\r':
1853             case '\"':
1854             case '\'':
1855             case '\\': count += 2; break;
1856             default:
1857               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1858                 count += 4;
1859               else
1860                 count++;
1861             }
1862         }
1863       return count;
1864     }
1865 }
1866
1867
1868
1869 static int
1870 convert_to_token (const unsigned char *src, size_t len, char *dest)
1871 {
1872   if (dest)
1873     memcpy (dest, src, len);
1874   return len;
1875 }
1876
1877
1878 /****************
1879  * Print SEXP to buffer using the MODE.  Returns the length of the
1880  * SEXP in buffer or 0 if the buffer is too short (We have at least an
1881  * empty list consisting of 2 bytes).  If a buffer of NULL is provided,
1882  * the required length is returned.
1883  */
1884 size_t
1885 _gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1886                    void *buffer, size_t maxlength )
1887 {
1888   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1889   const unsigned char *s;
1890   char *d;
1891   DATALEN n;
1892   char numbuf[20];
1893   size_t len = 0;
1894   int i, indent = 0;
1895
1896   s = list? list->d : empty;
1897   d = buffer;
1898   while ( *s != ST_STOP )
1899     {
1900       switch ( *s )
1901         {
1902         case ST_OPEN:
1903           s++;
1904           if ( mode != GCRYSEXP_FMT_CANON )
1905             {
1906               if (indent)
1907                 len++;
1908               len += indent;
1909             }
1910           len++;
1911           if ( buffer )
1912             {
1913               if ( len >= maxlength )
1914                 return 0;
1915               if ( mode != GCRYSEXP_FMT_CANON )
1916                 {
1917                   if (indent)
1918                     *d++ = '\n';
1919                   for (i=0; i < indent; i++)
1920                     *d++ = ' ';
1921                 }
1922               *d++ = '(';
1923             }
1924           indent++;
1925           break;
1926         case ST_CLOSE:
1927           s++;
1928           len++;
1929           if ( buffer )
1930             {
1931               if ( len >= maxlength )
1932                 return 0;
1933               *d++ = ')';
1934             }
1935           indent--;
1936           if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
1937             {
1938               len++;
1939               len += indent;
1940               if (buffer)
1941                 {
1942                   if (len >= maxlength)
1943                     return 0;
1944                   *d++ = '\n';
1945                   for (i=0; i < indent; i++)
1946                     *d++ = ' ';
1947                 }
1948             }
1949           break;
1950         case ST_DATA:
1951           s++;
1952           memcpy ( &n, s, sizeof n ); s += sizeof n;
1953           if (mode == GCRYSEXP_FMT_ADVANCED)
1954             {
1955               int type;
1956               size_t nn;
1957
1958               switch ( (type=suitable_encoding (s, n)))
1959                 {
1960                 case 1: nn = convert_to_string (s, n, NULL); break;
1961                 case 2: nn = convert_to_token (s, n, NULL); break;
1962                 default: nn = convert_to_hex (s, n, NULL); break;
1963                 }
1964               len += nn;
1965               if (buffer)
1966                 {
1967                   if (len >= maxlength)
1968                     return 0;
1969                   switch (type)
1970                     {
1971                     case 1: convert_to_string (s, n, d); break;
1972                     case 2: convert_to_token (s, n, d); break;
1973                     default: convert_to_hex (s, n, d); break;
1974                     }
1975                   d += nn;
1976                 }
1977               if (s[n] != ST_CLOSE)
1978                 {
1979                   len++;
1980                   if (buffer)
1981                     {
1982                       if (len >= maxlength)
1983                         return 0;
1984                       *d++ = ' ';
1985                     }
1986                 }
1987             }
1988           else
1989             {
1990               sprintf (numbuf, "%u:", (unsigned int)n );
1991               len += strlen (numbuf) + n;
1992               if ( buffer )
1993                 {
1994                   if ( len >= maxlength )
1995                     return 0;
1996                   d = stpcpy ( d, numbuf );
1997                   memcpy ( d, s, n ); d += n;
1998                 }
1999             }
2000           s += n;
2001           break;
2002         default:
2003           BUG ();
2004         }
2005     }
2006   if ( mode != GCRYSEXP_FMT_CANON )
2007     {
2008       len++;
2009       if (buffer)
2010         {
2011           if ( len >= maxlength )
2012             return 0;
2013           *d++ = '\n';
2014         }
2015     }
2016   if (buffer)
2017     {
2018       if ( len >= maxlength )
2019         return 0;
2020       *d++ = 0; /* for convenience we make a C string */
2021     }
2022   else
2023     len++; /* we need one byte more for this */
2024
2025   return len;
2026 }
2027
2028
2029 /* Scan a canonical encoded buffer with implicit length values and
2030    return the actual length this S-expression uses.  For a valid S-Exp
2031    it should never return 0.  If LENGTH is not zero, the maximum
2032    length to scan is given - this can be used for syntax checks of
2033    data passed from outside. errorcode and erroff may both be passed as
2034    NULL.  */
2035 size_t
2036 _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
2037                       size_t *erroff, gcry_err_code_t *errcode)
2038 {
2039   const unsigned char *p;
2040   const unsigned char *disphint = NULL;
2041   unsigned int datalen = 0;
2042   size_t dummy_erroff;
2043   gcry_err_code_t dummy_errcode;
2044   size_t count = 0;
2045   int level = 0;
2046
2047   if (!erroff)
2048     erroff = &dummy_erroff;
2049   if (!errcode)
2050     errcode = &dummy_errcode;
2051
2052   *errcode = GPG_ERR_NO_ERROR;
2053   *erroff = 0;
2054   if (!buffer)
2055     return 0;
2056   if (*buffer != '(')
2057     {
2058       *errcode = GPG_ERR_SEXP_NOT_CANONICAL;
2059       return 0;
2060     }
2061
2062   for (p=buffer; ; p++, count++ )
2063     {
2064       if (length && count >= length)
2065         {
2066           *erroff = count;
2067           *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
2068           return 0;
2069         }
2070
2071       if (datalen)
2072         {
2073           if (*p == ':')
2074             {
2075               if (length && (count+datalen) >= length)
2076                 {
2077                   *erroff = count;
2078                   *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
2079                   return 0;
2080                 }
2081               count += datalen;
2082               p += datalen;
2083               datalen = 0;
2084             }
2085           else if (digitp(p))
2086             datalen = datalen*10 + atoi_1(p);
2087           else
2088             {
2089               *erroff = count;
2090               *errcode = GPG_ERR_SEXP_INV_LEN_SPEC;
2091               return 0;
2092             }
2093         }
2094       else if (*p == '(')
2095         {
2096           if (disphint)
2097             {
2098               *erroff = count;
2099               *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
2100               return 0;
2101             }
2102           level++;
2103         }
2104       else if (*p == ')')
2105         { /* walk up */
2106           if (!level)
2107             {
2108               *erroff = count;
2109               *errcode = GPG_ERR_SEXP_UNMATCHED_PAREN;
2110               return 0;
2111             }
2112           if (disphint)
2113             {
2114               *erroff = count;
2115               *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
2116               return 0;
2117             }
2118           if (!--level)
2119             return ++count; /* ready */
2120         }
2121       else if (*p == '[')
2122         {
2123           if (disphint)
2124             {
2125               *erroff = count;
2126               *errcode = GPG_ERR_SEXP_NESTED_DH;
2127               return 0;
2128             }
2129           disphint = p;
2130         }
2131       else if (*p == ']')
2132         {
2133           if ( !disphint )
2134             {
2135               *erroff = count;
2136               *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
2137               return 0;
2138             }
2139           disphint = NULL;
2140         }
2141       else if (digitp (p) )
2142         {
2143           if (*p == '0')
2144             {
2145               *erroff = count;
2146               *errcode = GPG_ERR_SEXP_ZERO_PREFIX;
2147               return 0;
2148             }
2149           datalen = atoi_1 (p);
2150         }
2151       else if (*p == '&' || *p == '\\')
2152         {
2153           *erroff = count;
2154           *errcode = GPG_ERR_SEXP_UNEXPECTED_PUNC;
2155           return 0;
2156         }
2157       else
2158         {
2159           *erroff = count;
2160           *errcode = GPG_ERR_SEXP_BAD_CHARACTER;
2161           return 0;
2162         }
2163     }
2164 }
2165
2166
2167 /* Extract MPIs from an s-expression using a list of parameters.  The
2168  * names of these parameters are given by the string LIST.  Some
2169  * special characters may be given to control the conversion:
2170  *
2171  *    + :: Switch to unsigned integer format (default).
2172  *    - :: Switch to standard signed format.
2173  *    / :: Switch to opaque format.
2174  *    & :: Switch to buffer descriptor mode - see below.
2175  *    ? :: The previous parameter is optional.
2176  *
2177  * In general parameter names are single letters.  To use a string for
2178  * a parameter name, enclose the name in single quotes.
2179  *
2180  * Unless in gcry_buffer_t mode for each parameter name a pointer to
2181  * an MPI variable is expected and finally a NULL is expected.
2182  * Example:
2183  *
2184  *   _gcry_sexp_extract_param (key, NULL, "n/x+ed",
2185  *                             &mpi_n, &mpi_x, &mpi_e, NULL)
2186  *
2187  * This stores the parameter "N" from KEY as an unsigned MPI into
2188  * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
2189  * parameter "E" again as an unsigned MPI into MPI_E.
2190  *
2191  * If in buffer descriptor mode a pointer to gcry_buffer_t descriptor
2192  * is expected instead of a pointer to an MPI.  The caller may use two
2193  * different operation modes: If the DATA field of the provided buffer
2194  * descriptor is NULL, the function allocates a new buffer and stores
2195  * it at DATA; the other fields are set accordingly with OFF being 0.
2196  * If DATA is not NULL, the function assumes that DATA, SIZE, and OFF
2197  * describe a buffer where to but the data; on return the LEN field
2198  * receives the number of bytes copied to that buffer; if the buffer
2199  * is too small, the function immediately returns with an error code
2200  * (and LEN set to 0).
2201  *
2202  * PATH is an optional string used to locate a token.  The exclamation
2203  * mark separated tokens are used to via gcry_sexp_find_token to find
2204  * a start point inside SEXP.
2205  *
2206  * The function returns NULL on success.  On error an error code is
2207  * returned and the passed MPIs are either unchanged or set to NULL.
2208  */
2209 gpg_err_code_t
2210 _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
2211                            const char *list, va_list arg_ptr)
2212 {
2213   gpg_err_code_t rc;
2214   const char *s, *s2;
2215   gcry_mpi_t *array[20];
2216   char arrayisdesc[20];
2217   int idx;
2218   gcry_sexp_t l1;
2219   int mode = '+'; /* Default to GCRYMPI_FMT_USG.  */
2220   gcry_sexp_t freethis = NULL;
2221
2222   memset (arrayisdesc, 0, sizeof arrayisdesc);
2223
2224   /* First copy all the args into an array.  This is required so that
2225      we are able to release already allocated MPIs if later an error
2226      was found.  */
2227   for (s=list, idx=0; *s && idx < DIM (array); s++)
2228     {
2229       if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?')
2230         ;
2231       else if (whitespacep (s))
2232         ;
2233       else
2234         {
2235           if (*s == '\'')
2236             {
2237               s++;
2238               s2 = strchr (s, '\'');
2239               if (!s2 || s2 == s)
2240                 {
2241                   /* Closing quote not found or empty string.  */
2242                   return GPG_ERR_SYNTAX;
2243                 }
2244               s = s2;
2245             }
2246           array[idx] = va_arg (arg_ptr, gcry_mpi_t *);
2247           if (!array[idx])
2248             return GPG_ERR_MISSING_VALUE; /* NULL pointer given.  */
2249           idx++;
2250         }
2251     }
2252   if (*s)
2253     return GPG_ERR_LIMIT_REACHED;  /* Too many list elements.  */
2254   if (va_arg (arg_ptr, gcry_mpi_t *))
2255     return GPG_ERR_INV_ARG;  /* Not enough list elemends.  */
2256
2257   /* Drill down.  */
2258   while (path && *path)
2259     {
2260       size_t n;
2261
2262       s = strchr (path, '!');
2263       if (s == path)
2264         {
2265           rc = GPG_ERR_NOT_FOUND;
2266           goto cleanup;
2267         }
2268       n = s? s - path : 0;
2269       l1 = _gcry_sexp_find_token (sexp, path, n);
2270       if (!l1)
2271         {
2272           rc = GPG_ERR_NOT_FOUND;
2273           goto cleanup;
2274         }
2275       sexp = l1; l1 = NULL;
2276       sexp_release (freethis);
2277       freethis = sexp;
2278       if (n)
2279         path += n + 1;
2280       else
2281         path = NULL;
2282     }
2283
2284
2285   /* Now extract all parameters.  */
2286   for (s=list, idx=0; *s; s++)
2287     {
2288       if (*s == '&' || *s == '+' || *s == '-' || *s == '/')
2289         mode = *s;
2290       else if (whitespacep (s))
2291         ;
2292       else if (*s == '?')
2293         ; /* Only used via lookahead.  */
2294       else
2295         {
2296           if (*s == '\'')
2297             {
2298               /* Find closing quote, find token, set S to closing quote.  */
2299               s++;
2300               s2 = strchr (s, '\'');
2301               if (!s2 || s2 == s)
2302                 {
2303                   /* Closing quote not found or empty string.  */
2304                   rc = GPG_ERR_SYNTAX;
2305                   goto cleanup;
2306                 }
2307               l1 = _gcry_sexp_find_token (sexp, s, s2 - s);
2308               s = s2;
2309             }
2310           else
2311             l1 = _gcry_sexp_find_token (sexp, s, 1);
2312
2313           if (!l1 && s[1] == '?')
2314             {
2315               /* Optional element not found.  */
2316               if (mode == '&')
2317                 {
2318                   gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2319                   if (!spec->data)
2320                     {
2321                       spec->size = 0;
2322                       spec->off = 0;
2323                     }
2324                   spec->len = 0;
2325                 }
2326               else
2327                 *array[idx] = NULL;
2328             }
2329           else if (!l1)
2330             {
2331               rc = GPG_ERR_NO_OBJ;  /* List element not found.  */
2332               goto cleanup;
2333             }
2334            else
2335             {
2336               if (mode == '&')
2337                 {
2338                   gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2339
2340                   if (spec->data)
2341                     {
2342                       const char *pbuf;
2343                       size_t nbuf;
2344
2345                       pbuf = _gcry_sexp_nth_data (l1, 1, &nbuf);
2346                       if (!pbuf || !nbuf)
2347                         {
2348                           rc = GPG_ERR_INV_OBJ;
2349                           goto cleanup;
2350                         }
2351                       if (spec->off + nbuf > spec->size)
2352                         {
2353                           rc = GPG_ERR_BUFFER_TOO_SHORT;
2354                           goto cleanup;
2355                         }
2356                       memcpy ((char*)spec->data + spec->off, pbuf, nbuf);
2357                       spec->len = nbuf;
2358                       arrayisdesc[idx] = 1;
2359                     }
2360                   else
2361                     {
2362                       spec->data = _gcry_sexp_nth_buffer (l1, 1, &spec->size);
2363                       if (!spec->data)
2364                         {
2365                           rc = GPG_ERR_INV_OBJ; /* Or out of core.  */
2366                           goto cleanup;
2367                         }
2368                       spec->len = spec->size;
2369                       spec->off = 0;
2370                       arrayisdesc[idx] = 2;
2371                     }
2372                 }
2373               else if (mode == '/')
2374                 *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
2375               else if (mode == '-')
2376                 *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_STD);
2377               else
2378                 *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
2379               sexp_release (l1); l1 = NULL;
2380               if (!*array[idx])
2381                 {
2382                   rc = GPG_ERR_INV_OBJ;  /* Conversion failed.  */
2383                   goto cleanup;
2384                 }
2385             }
2386           idx++;
2387         }
2388     }
2389
2390   sexp_release (freethis);
2391   return 0;
2392
2393  cleanup:
2394   sexp_release (freethis);
2395   sexp_release (l1);
2396   while (idx--)
2397     {
2398       if (!arrayisdesc[idx])
2399         {
2400           _gcry_mpi_release (*array[idx]);
2401           *array[idx] = NULL;
2402         }
2403       else if (!arrayisdesc[idx] == 1)
2404         {
2405           /* Caller provided buffer.  */
2406           gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2407           spec->len = 0;
2408         }
2409       else
2410         {
2411           /* We might have allocated a buffer.  */
2412           gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2413           xfree (spec->data);
2414           spec->data = NULL;
2415           spec->size = spec->off = spec->len = 0;
2416         }
2417      }
2418   return rc;
2419 }
2420
2421 gpg_error_t
2422 _gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
2423                           const char *list, ...)
2424 {
2425   gcry_err_code_t rc;
2426   va_list arg_ptr;
2427
2428   va_start (arg_ptr, list);
2429   rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
2430   va_end (arg_ptr);
2431   return gpg_error (rc);
2432 }