Add PowerPC extra CFLAGS also for chacha20-ppc and crc-ppc
[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, 2017 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 License
19  * along with this program; if not, see <https://www.gnu.org/licenses/>.
20  * SPDX-License-Identifier: LGPL-2.1+
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 accidentally 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 list (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 b64count = 0;
1116   int quoted_esc = 0;
1117   int datalen = 0;
1118   size_t dummy_erroff;
1119   struct make_space_ctx c;
1120   int arg_counter = 0;
1121   int level = 0;
1122
1123   if (!retsexp)
1124     return GPG_ERR_INV_ARG;
1125   *retsexp = NULL;
1126
1127   if (!buffer)
1128     return GPG_ERR_INV_ARG;
1129
1130   if (!erroff)
1131     erroff = &dummy_erroff;
1132
1133   /* Depending on whether ARG_LIST is non-zero or not, this macro gives
1134      us the next argument, either from the variable argument list as
1135      specified by ARG_PTR or from the argument array ARG_LIST.  */
1136 #define ARG_NEXT(storage, type)                          \
1137   do                                                     \
1138     {                                                    \
1139       if (!arg_list)                                     \
1140         storage = va_arg (arg_ptr, type);                \
1141       else                                               \
1142         storage = *((type *) (arg_list[arg_counter++])); \
1143     }                                                    \
1144   while (0)
1145
1146   /* The MAKE_SPACE macro is used before each store operation to
1147      ensure that the buffer is large enough.  It requires a global
1148      context named C and jumps out to the label LEAVE on error! It
1149      also sets ERROFF using the variables BUFFER and P.  */
1150 #define MAKE_SPACE(n)  do {                                                \
1151                             gpg_err_code_t _ms_err = make_space (&c, (n)); \
1152                             if (_ms_err)                                   \
1153                               {                                            \
1154                                 err = _ms_err;                             \
1155                                 *erroff = p - buffer;                      \
1156                                 goto leave;                                \
1157                               }                                            \
1158                        } while (0)
1159
1160   /* The STORE_LEN macro is used to store the length N at buffer P. */
1161 #define STORE_LEN(p,n) do {                                                \
1162                             DATALEN ashort = (n);                          \
1163                             memcpy ( (p), &ashort, sizeof(ashort) );       \
1164                             (p) += sizeof (ashort);                        \
1165                         } while (0)
1166
1167   /* We assume that the internal representation takes less memory than
1168      the provided one.  However, we add space for one extra datalen so
1169      that the code which does the ST_CLOSE can use MAKE_SPACE */
1170   c.allocated = length + sizeof(DATALEN);
1171   if (length && _gcry_is_secure (buffer))
1172     c.sexp = xtrymalloc_secure (sizeof *c.sexp + c.allocated - 1);
1173   else
1174     c.sexp = xtrymalloc (sizeof *c.sexp + c.allocated - 1);
1175   if (!c.sexp)
1176     {
1177       err = gpg_err_code_from_errno (errno);
1178       *erroff = 0;
1179       goto leave;
1180     }
1181   c.pos = c.sexp->d;
1182
1183   for (p = buffer, n = length; n; p++, n--)
1184     {
1185       if (tokenp && !hexfmt)
1186         {
1187           if (strchr (tokenchars, *p))
1188             continue;
1189           else
1190             {
1191               datalen = p - tokenp;
1192               MAKE_SPACE (datalen);
1193               *c.pos++ = ST_DATA;
1194               STORE_LEN (c.pos, datalen);
1195               memcpy (c.pos, tokenp, datalen);
1196               c.pos += datalen;
1197               tokenp = NULL;
1198             }
1199         }
1200
1201       if (quoted)
1202         {
1203           if (quoted_esc)
1204             {
1205               switch (*p)
1206                 {
1207                 case 'b': case 't': case 'v': case 'n': case 'f':
1208                 case 'r': case '"': case '\'': case '\\':
1209                   quoted_esc = 0;
1210                   break;
1211
1212                 case '0': case '1': case '2': case '3': case '4':
1213                 case '5': case '6': case '7':
1214                   if (!((n > 2)
1215                         && (p[1] >= '0') && (p[1] <= '7')
1216                         && (p[2] >= '0') && (p[2] <= '7')))
1217                     {
1218                       *erroff = p - buffer;
1219                       /* Invalid octal value.  */
1220                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1221                       goto leave;
1222                     }
1223                   p += 2;
1224                   n -= 2;
1225                   quoted_esc = 0;
1226                   break;
1227
1228                 case 'x':
1229                   if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
1230                     {
1231                       *erroff = p - buffer;
1232                       /* Invalid hex value.  */
1233                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1234                       goto leave;
1235                     }
1236                   p += 2;
1237                   n -= 2;
1238                   quoted_esc = 0;
1239                   break;
1240
1241                 case '\r':
1242                   /* ignore CR[,LF] */
1243                   if (n && (p[1] == '\n'))
1244                     {
1245                       p++;
1246                       n--;
1247                     }
1248                   quoted_esc = 0;
1249                   break;
1250
1251                 case '\n':
1252                   /* ignore LF[,CR] */
1253                   if (n && (p[1] == '\r'))
1254                     {
1255                       p++;
1256                       n--;
1257                     }
1258                   quoted_esc = 0;
1259                   break;
1260
1261                 default:
1262                   *erroff = p - buffer;
1263                   /* Invalid quoted string escape.  */
1264                   err = GPG_ERR_SEXP_BAD_QUOTATION;
1265                   goto leave;
1266                 }
1267             }
1268           else if (*p == '\\')
1269             quoted_esc = 1;
1270           else if (*p == '\"')
1271             {
1272               /* Keep it easy - we know that the unquoted string will
1273                  never be larger. */
1274               unsigned char *save;
1275               size_t len;
1276
1277               quoted++; /* Skip leading quote.  */
1278               MAKE_SPACE (p - quoted);
1279               *c.pos++ = ST_DATA;
1280               save = c.pos;
1281               STORE_LEN (c.pos, 0); /* Will be fixed up later.  */
1282               len = unquote_string (quoted, p - quoted, c.pos);
1283               c.pos += len;
1284               STORE_LEN (save, len);
1285               quoted = NULL;
1286             }
1287         }
1288       else if (hexfmt)
1289         {
1290           if (isxdigit (*p))
1291             hexcount++;
1292           else if (*p == '#')
1293             {
1294               if ((hexcount & 1))
1295                 {
1296                   *erroff = p - buffer;
1297                   err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
1298                   goto leave;
1299                 }
1300
1301               datalen = hexcount / 2;
1302               MAKE_SPACE (datalen);
1303               *c.pos++ = ST_DATA;
1304               STORE_LEN (c.pos, datalen);
1305               for (hexfmt++; hexfmt < p; hexfmt++)
1306                 {
1307                   int tmpc;
1308
1309                   if (whitespacep (hexfmt))
1310                     continue;
1311                   tmpc = hextonibble (*(const unsigned char*)hexfmt);
1312                   for (hexfmt++; hexfmt < p && whitespacep (hexfmt); hexfmt++)
1313                     ;
1314                   if (hexfmt < p)
1315                     {
1316                       tmpc *= 16;
1317                       tmpc += hextonibble (*(const unsigned char*)hexfmt);
1318                     }
1319                   *c.pos++ = tmpc;
1320                 }
1321               hexfmt = NULL;
1322             }
1323           else if (!whitespacep (p))
1324             {
1325               *erroff = p - buffer;
1326               err = GPG_ERR_SEXP_BAD_HEX_CHAR;
1327               goto leave;
1328             }
1329         }
1330       else if (base64)
1331         {
1332           if (digitp (p) || alphap (p) || *p == '+' || *p == '/' || *p == '=')
1333             b64count++;
1334           else if (*p == '|')
1335             {
1336               gpgrt_b64state_t b64state;
1337               char *b64buf;
1338               int i;
1339
1340               base64++;         /* Skip beginning '|' */
1341               b64buf = xtrymalloc (b64count);
1342               if (!b64buf)
1343                 {
1344                   err = gpg_err_code_from_syserror ();
1345                   goto leave;
1346                 }
1347               memcpy (b64buf, base64, b64count);
1348
1349               b64state = gpgrt_b64dec_start (NULL);
1350               if (!b64state)
1351                 {
1352                   err = gpg_err_code_from_syserror ();
1353                   xfree (b64buf);
1354                   goto leave;
1355                 }
1356               err = gpgrt_b64dec_proc (b64state, b64buf, b64count,
1357                                        (size_t *)&datalen);
1358               if (err && gpg_err_code (err) != GPG_ERR_EOF)
1359                 {
1360                   xfree (b64state);
1361                   xfree (b64buf);
1362                   goto leave;
1363                 }
1364               err = gpgrt_b64dec_finish (b64state);
1365               if (err)
1366                 {
1367                   xfree (b64buf);
1368                   goto leave;
1369                 }
1370
1371               MAKE_SPACE (datalen);
1372               *c.pos++ = ST_DATA;
1373               STORE_LEN (c.pos, datalen);
1374               for (i = 0; i < datalen; i++)
1375                 *c.pos++ = b64buf[i];
1376
1377               xfree (b64buf);
1378               base64 = NULL;
1379             }
1380           else
1381             {
1382               *erroff = p - buffer;
1383               err = GPG_ERR_SEXP_BAD_CHARACTER;
1384               goto leave;
1385             }
1386         }
1387       else if (digptr)
1388         {
1389           if (digitp (p))
1390             ;
1391           else if (*p == ':')
1392             {
1393               datalen = atoi (digptr); /* FIXME: check for overflow.  */
1394               digptr = NULL;
1395               if (datalen > n - 1)
1396                 {
1397                   *erroff = p - buffer;
1398                   /* Buffer too short.  */
1399                   err = GPG_ERR_SEXP_STRING_TOO_LONG;
1400                   goto leave;
1401                 }
1402               /* Make a new list entry.  */
1403               MAKE_SPACE (datalen);
1404               *c.pos++ = ST_DATA;
1405               STORE_LEN (c.pos, datalen);
1406               memcpy (c.pos, p + 1, datalen);
1407               c.pos += datalen;
1408               n -= datalen;
1409               p += datalen;
1410             }
1411           else if (*p == '\"')
1412             {
1413               digptr = NULL; /* We ignore the optional length.  */
1414               quoted = p;
1415               quoted_esc = 0;
1416             }
1417           else if (*p == '#')
1418             {
1419               digptr = NULL; /* We ignore the optional length.  */
1420               hexfmt = p;
1421               hexcount = 0;
1422             }
1423           else if (*p == '|')
1424             {
1425               digptr = NULL; /* We ignore the optional length.  */
1426               base64 = p;
1427               b64count = 0;
1428             }
1429           else
1430             {
1431               *erroff = p - buffer;
1432               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1433               goto leave;
1434             }
1435         }
1436       else if (percent)
1437         {
1438           if (*p == 'm' || *p == 'M')
1439             {
1440               /* Insert an MPI.  */
1441               gcry_mpi_t m;
1442               size_t nm = 0;
1443               int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;
1444
1445               ARG_NEXT (m, gcry_mpi_t);
1446
1447               if (mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
1448                 {
1449                   void *mp;
1450                   unsigned int nbits;
1451
1452                   mp = mpi_get_opaque (m, &nbits);
1453                   nm = (nbits+7)/8;
1454                   if (mp && nm)
1455                     {
1456                       MAKE_SPACE (nm);
1457                       if (!_gcry_is_secure (c.sexp->d)
1458                           && mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
1459                         {
1460                           /* We have to switch to secure allocation.  */
1461                           gcry_sexp_t newsexp;
1462                           byte *newhead;
1463
1464                           newsexp = xtrymalloc_secure (sizeof *newsexp
1465                                                        + c.allocated - 1);
1466                           if (!newsexp)
1467                             {
1468                               err = gpg_err_code_from_errno (errno);
1469                               goto leave;
1470                             }
1471                           newhead = newsexp->d;
1472                           memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1473                           c.pos = newhead + (c.pos - c.sexp->d);
1474                           xfree (c.sexp);
1475                           c.sexp = newsexp;
1476                         }
1477
1478                       *c.pos++ = ST_DATA;
1479                       STORE_LEN (c.pos, nm);
1480                       memcpy (c.pos, mp, nm);
1481                       c.pos += nm;
1482                     }
1483                 }
1484               else
1485                 {
1486                   err = _gcry_mpi_print (mpifmt, NULL, 0, &nm, m);
1487                   if (err)
1488                     goto leave;
1489
1490                   MAKE_SPACE (nm);
1491                   if (!_gcry_is_secure (c.sexp->d)
1492                       && mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
1493                     {
1494                       /* We have to switch to secure allocation.  */
1495                       gcry_sexp_t newsexp;
1496                       byte *newhead;
1497
1498                       newsexp = xtrymalloc_secure (sizeof *newsexp
1499                                                    + c.allocated - 1);
1500                       if (!newsexp)
1501                         {
1502                           err = gpg_err_code_from_errno (errno);
1503                           goto leave;
1504                         }
1505                       newhead = newsexp->d;
1506                       memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1507                       c.pos = newhead + (c.pos - c.sexp->d);
1508                       xfree (c.sexp);
1509                       c.sexp = newsexp;
1510                     }
1511
1512                   *c.pos++ = ST_DATA;
1513                   STORE_LEN (c.pos, nm);
1514                   err = _gcry_mpi_print (mpifmt, c.pos, nm, &nm, m);
1515                   if (err)
1516                     goto leave;
1517                   c.pos += nm;
1518                 }
1519             }
1520           else if (*p == 's')
1521             {
1522               /* Insert an string.  */
1523               const char *astr;
1524               size_t alen;
1525
1526               ARG_NEXT (astr, const char *);
1527               alen = strlen (astr);
1528
1529               MAKE_SPACE (alen);
1530               *c.pos++ = ST_DATA;
1531               STORE_LEN (c.pos, alen);
1532               memcpy (c.pos, astr, alen);
1533               c.pos += alen;
1534             }
1535           else if (*p == 'b')
1536             {
1537               /* Insert a memory buffer.  */
1538               const char *astr;
1539               int alen;
1540
1541               ARG_NEXT (alen, int);
1542               ARG_NEXT (astr, const char *);
1543
1544               if (alen < 0)
1545                 {
1546                   *erroff = p - buffer;
1547                   err = GPG_ERR_INV_ARG;
1548                   goto leave;
1549                 }
1550
1551               MAKE_SPACE (alen);
1552               if (alen
1553                   && !_gcry_is_secure (c.sexp->d)
1554                   && _gcry_is_secure (astr))
1555               {
1556                   /* We have to switch to secure allocation.  */
1557                   gcry_sexp_t newsexp;
1558                   byte *newhead;
1559
1560                   newsexp = xtrymalloc_secure (sizeof *newsexp
1561                                                + c.allocated - 1);
1562                   if (!newsexp)
1563                     {
1564                       err = gpg_err_code_from_errno (errno);
1565                       goto leave;
1566                     }
1567                   newhead = newsexp->d;
1568                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1569                   c.pos = newhead + (c.pos - c.sexp->d);
1570                   xfree (c.sexp);
1571                   c.sexp = newsexp;
1572                 }
1573
1574               *c.pos++ = ST_DATA;
1575               STORE_LEN (c.pos, alen);
1576               memcpy (c.pos, astr, alen);
1577               c.pos += alen;
1578             }
1579           else if (*p == 'd')
1580             {
1581               /* Insert an integer as string.  */
1582               int aint;
1583               size_t alen;
1584               char buf[35];
1585
1586               ARG_NEXT (aint, int);
1587               snprintf (buf, sizeof buf, "%d", aint);
1588               alen = strlen (buf);
1589               MAKE_SPACE (alen);
1590               *c.pos++ = ST_DATA;
1591               STORE_LEN (c.pos, alen);
1592               memcpy (c.pos, buf, alen);
1593               c.pos += alen;
1594             }
1595           else if (*p == 'u')
1596             {
1597               /* Insert an unsigned integer as string.  */
1598               unsigned int aint;
1599               size_t alen;
1600               char buf[35];
1601
1602               ARG_NEXT (aint, unsigned int);
1603               snprintf (buf, sizeof buf, "%u", aint);
1604               alen = strlen (buf);
1605               MAKE_SPACE (alen);
1606               *c.pos++ = ST_DATA;
1607               STORE_LEN (c.pos, alen);
1608               memcpy (c.pos, buf, alen);
1609               c.pos += alen;
1610             }
1611           else if (*p == 'S')
1612             {
1613               /* Insert a gcry_sexp_t.  */
1614               gcry_sexp_t asexp;
1615               size_t alen, aoff;
1616
1617               ARG_NEXT (asexp, gcry_sexp_t);
1618               alen = get_internal_buffer (asexp, &aoff);
1619               if (alen)
1620                 {
1621                   MAKE_SPACE (alen);
1622                   memcpy (c.pos, asexp->d + aoff, alen);
1623                   c.pos += alen;
1624                 }
1625             }
1626           else
1627             {
1628               *erroff = p - buffer;
1629               /* Invalid format specifier.  */
1630               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1631               goto leave;
1632             }
1633           percent = NULL;
1634         }
1635       else if (*p == '(')
1636         {
1637           if (disphint)
1638             {
1639               *erroff = p - buffer;
1640               /* Open display hint.  */
1641               err = GPG_ERR_SEXP_UNMATCHED_DH;
1642               goto leave;
1643             }
1644           MAKE_SPACE (0);
1645           *c.pos++ = ST_OPEN;
1646           level++;
1647         }
1648       else if (*p == ')')
1649         {
1650           /* Walk up.  */
1651           if (disphint)
1652             {
1653               *erroff = p - buffer;
1654               /* Open display hint.  */
1655               err = GPG_ERR_SEXP_UNMATCHED_DH;
1656               goto leave;
1657             }
1658
1659           if (level == 0)
1660             {
1661               *erroff = p - buffer;
1662               err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1663               goto leave;
1664             }
1665           MAKE_SPACE (0);
1666           *c.pos++ = ST_CLOSE;
1667           level--;
1668         }
1669       else if (*p == '\"')
1670         {
1671           quoted = p;
1672           quoted_esc = 0;
1673         }
1674       else if (*p == '#')
1675         {
1676           hexfmt = p;
1677           hexcount = 0;
1678         }
1679       else if (*p == '|')
1680         {
1681           base64 = p;
1682           b64count = 0;
1683         }
1684       else if (*p == '[')
1685         {
1686           if (disphint)
1687             {
1688               *erroff = p - buffer;
1689               /* Open display hint.  */
1690               err = GPG_ERR_SEXP_NESTED_DH;
1691               goto leave;
1692             }
1693           disphint = p;
1694         }
1695       else if (*p == ']')
1696         {
1697           if (!disphint)
1698             {
1699               *erroff = p - buffer;
1700               /* Open display hint.  */
1701               err = GPG_ERR_SEXP_UNMATCHED_DH;
1702               goto leave;
1703             }
1704           disphint = NULL;
1705         }
1706       else if (digitp (p))
1707         {
1708           if (*p == '0')
1709             {
1710               /* A length may not begin with zero.  */
1711               *erroff = p - buffer;
1712               err = GPG_ERR_SEXP_ZERO_PREFIX;
1713               goto leave;
1714             }
1715           digptr = p;
1716         }
1717       else if (strchr (tokenchars, *p))
1718         tokenp = p;
1719       else if (whitespacep (p))
1720         ;
1721       else if (*p == '{')
1722         {
1723           /* fixme: handle rescanning: we can do this by saving our
1724              current state and start over at p+1 -- Hmmm. At this
1725              point here we are in a well defined state, so we don't
1726              need to save it.  Great.  */
1727           *erroff = p - buffer;
1728           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1729           goto leave;
1730         }
1731       else if (strchr ("&\\", *p))
1732         {
1733           /* Reserved punctuation.  */
1734           *erroff = p - buffer;
1735           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1736           goto leave;
1737         }
1738       else if (argflag && (*p == '%'))
1739         percent = p;
1740       else
1741         {
1742           /* Bad or unavailable.  */
1743           *erroff = p - buffer;
1744           err = GPG_ERR_SEXP_BAD_CHARACTER;
1745           goto leave;
1746         }
1747     }
1748   MAKE_SPACE (0);
1749   *c.pos++ = ST_STOP;
1750
1751   if (level && !err)
1752     err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1753
1754  leave:
1755   if (err)
1756     {
1757       /* Error -> deallocate.  */
1758       if (c.sexp)
1759         {
1760           /* Extra paranoid wipe on error. */
1761           if (_gcry_is_secure (c.sexp))
1762             wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
1763           xfree (c.sexp);
1764         }
1765     }
1766   else
1767     *retsexp = normalize (c.sexp);
1768
1769   return err;
1770 #undef MAKE_SPACE
1771 #undef STORE_LEN
1772 }
1773
1774
1775 static gpg_err_code_t
1776 do_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1777                const char *buffer, size_t length, int argflag,
1778                void **arg_list, ...)
1779 {
1780   gcry_err_code_t rc;
1781   va_list arg_ptr;
1782
1783   va_start (arg_ptr, arg_list);
1784   rc = do_vsexp_sscan (retsexp, erroff, buffer, length, argflag,
1785                        arg_list, arg_ptr);
1786   va_end (arg_ptr);
1787
1788   return rc;
1789 }
1790
1791
1792 gpg_err_code_t
1793 _gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
1794 {
1795   gcry_err_code_t rc;
1796   va_list arg_ptr;
1797
1798   va_start (arg_ptr, format);
1799   rc = do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1800                        NULL, arg_ptr);
1801   va_end (arg_ptr);
1802
1803   return rc;
1804 }
1805
1806
1807 gcry_err_code_t
1808 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
1809                    const char *format, va_list arg_ptr)
1810 {
1811   return do_vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1812                          NULL, arg_ptr);
1813 }
1814
1815
1816 /* Like gcry_sexp_build, but uses an array instead of variable
1817    function arguments.  */
1818 gcry_err_code_t
1819 _gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1820                         const char *format, void **arg_list)
1821 {
1822   return do_sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
1823 }
1824
1825
1826 gcry_err_code_t
1827 _gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1828                   const char *buffer, size_t length)
1829 {
1830   return do_sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
1831 }
1832
1833 \f
1834 /* Figure out a suitable encoding for BUFFER of LENGTH.
1835    Returns: 0 = Binary
1836             1 = String possible
1837             2 = Token possible
1838 */
1839 static int
1840 suitable_encoding (const unsigned char *buffer, size_t length)
1841 {
1842   const unsigned char *s;
1843   int maybe_token = 1;
1844
1845   if (!length)
1846     return 1;
1847
1848   if (*buffer & 0x80)
1849     return 0; /* If the MSB is set we assume that buffer represents a
1850                  negative number.  */
1851   if (!*buffer)
1852     return 0; /* Starting with a zero is pretty much a binary string.  */
1853
1854   for (s=buffer; length; s++, length--)
1855     {
1856       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1857            && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1858         return 0; /*binary*/
1859       if ( maybe_token
1860            && !alphap (s) && !digitp (s)  && !strchr (TOKEN_SPECIALS, *s))
1861         maybe_token = 0;
1862     }
1863   s = buffer;
1864   if ( maybe_token && !digitp (s) )
1865     return 2;
1866   return 1;
1867 }
1868
1869
1870 static int
1871 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1872 {
1873   int i;
1874
1875   if (dest)
1876     {
1877       *dest++ = '#';
1878       for (i=0; i < len; i++, dest += 2 )
1879         snprintf (dest, 3, "%02X", src[i]);
1880       *dest++ = '#';
1881     }
1882   return len*2+2;
1883 }
1884
1885 static int
1886 convert_to_string (const unsigned char *s, size_t len, char *dest)
1887 {
1888   if (dest)
1889     {
1890       char *p = dest;
1891       *p++ = '\"';
1892       for (; len; len--, s++ )
1893         {
1894           switch (*s)
1895             {
1896             case '\b': *p++ = '\\'; *p++ = 'b';  break;
1897             case '\t': *p++ = '\\'; *p++ = 't';  break;
1898             case '\v': *p++ = '\\'; *p++ = 'v';  break;
1899             case '\n': *p++ = '\\'; *p++ = 'n';  break;
1900             case '\f': *p++ = '\\'; *p++ = 'f';  break;
1901             case '\r': *p++ = '\\'; *p++ = 'r';  break;
1902             case '\"': *p++ = '\\'; *p++ = '\"';  break;
1903             case '\'': *p++ = '\\'; *p++ = '\'';  break;
1904             case '\\': *p++ = '\\'; *p++ = '\\';  break;
1905             default:
1906               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1907                 {
1908                   snprintf (p, 5, "\\x%02x", *s);
1909                   p += 4;
1910                 }
1911               else
1912                 *p++ = *s;
1913             }
1914         }
1915       *p++ = '\"';
1916       return p - dest;
1917     }
1918   else
1919     {
1920       int count = 2;
1921       for (; len; len--, s++ )
1922         {
1923           switch (*s)
1924             {
1925             case '\b':
1926             case '\t':
1927             case '\v':
1928             case '\n':
1929             case '\f':
1930             case '\r':
1931             case '\"':
1932             case '\'':
1933             case '\\': count += 2; break;
1934             default:
1935               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1936                 count += 4;
1937               else
1938                 count++;
1939             }
1940         }
1941       return count;
1942     }
1943 }
1944
1945
1946
1947 static int
1948 convert_to_token (const unsigned char *src, size_t len, char *dest)
1949 {
1950   if (dest)
1951     memcpy (dest, src, len);
1952   return len;
1953 }
1954
1955
1956 /****************
1957  * Print SEXP to buffer using the MODE.  Returns the length of the
1958  * SEXP in buffer or 0 if the buffer is too short (We have at least an
1959  * empty list consisting of 2 bytes).  If a buffer of NULL is provided,
1960  * the required length is returned.
1961  */
1962 size_t
1963 _gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1964                    void *buffer, size_t maxlength )
1965 {
1966   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1967   const unsigned char *s;
1968   char *d;
1969   DATALEN n;
1970   char numbuf[20];
1971   size_t len = 0;
1972   int i, indent = 0;
1973
1974   s = list? list->d : empty;
1975   d = buffer;
1976   while ( *s != ST_STOP )
1977     {
1978       switch ( *s )
1979         {
1980         case ST_OPEN:
1981           s++;
1982           if ( mode != GCRYSEXP_FMT_CANON )
1983             {
1984               if (indent)
1985                 len++;
1986               len += indent;
1987             }
1988           len++;
1989           if ( buffer )
1990             {
1991               if ( len >= maxlength )
1992                 return 0;
1993               if ( mode != GCRYSEXP_FMT_CANON )
1994                 {
1995                   if (indent)
1996                     *d++ = '\n';
1997                   for (i=0; i < indent; i++)
1998                     *d++ = ' ';
1999                 }
2000               *d++ = '(';
2001             }
2002           indent++;
2003           break;
2004         case ST_CLOSE:
2005           s++;
2006           len++;
2007           if ( buffer )
2008             {
2009               if ( len >= maxlength )
2010                 return 0;
2011               *d++ = ')';
2012             }
2013           indent--;
2014           if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
2015             {
2016               len++;
2017               len += indent;
2018               if (buffer)
2019                 {
2020                   if (len >= maxlength)
2021                     return 0;
2022                   *d++ = '\n';
2023                   for (i=0; i < indent; i++)
2024                     *d++ = ' ';
2025                 }
2026             }
2027           break;
2028         case ST_DATA:
2029           s++;
2030           memcpy ( &n, s, sizeof n ); s += sizeof n;
2031           if (mode == GCRYSEXP_FMT_ADVANCED)
2032             {
2033               int type;
2034               size_t nn;
2035
2036               switch ( (type=suitable_encoding (s, n)))
2037                 {
2038                 case 1: nn = convert_to_string (s, n, NULL); break;
2039                 case 2: nn = convert_to_token (s, n, NULL); break;
2040                 default: nn = convert_to_hex (s, n, NULL); break;
2041                 }
2042               len += nn;
2043               if (buffer)
2044                 {
2045                   if (len >= maxlength)
2046                     return 0;
2047                   switch (type)
2048                     {
2049                     case 1: convert_to_string (s, n, d); break;
2050                     case 2: convert_to_token (s, n, d); break;
2051                     default: convert_to_hex (s, n, d); break;
2052                     }
2053                   d += nn;
2054                 }
2055               if (s[n] != ST_CLOSE)
2056                 {
2057                   len++;
2058                   if (buffer)
2059                     {
2060                       if (len >= maxlength)
2061                         return 0;
2062                       *d++ = ' ';
2063                     }
2064                 }
2065             }
2066           else
2067             {
2068               snprintf (numbuf, sizeof numbuf, "%u:", (unsigned int)n );
2069               len += strlen (numbuf) + n;
2070               if ( buffer )
2071                 {
2072                   if ( len >= maxlength )
2073                     return 0;
2074                   d = stpcpy ( d, numbuf );
2075                   memcpy ( d, s, n ); d += n;
2076                 }
2077             }
2078           s += n;
2079           break;
2080         default:
2081           BUG ();
2082         }
2083     }
2084   if ( mode != GCRYSEXP_FMT_CANON )
2085     {
2086       len++;
2087       if (buffer)
2088         {
2089           if ( len >= maxlength )
2090             return 0;
2091           *d++ = '\n';
2092         }
2093     }
2094   if (buffer)
2095     {
2096       if ( len >= maxlength )
2097         return 0;
2098       *d++ = 0; /* for convenience we make a C string */
2099     }
2100   else
2101     len++; /* we need one byte more for this */
2102
2103   return len;
2104 }
2105
2106
2107 /* Scan a canonical encoded buffer with implicit length values and
2108    return the actual length this S-expression uses.  For a valid S-Exp
2109    it should never return 0.  If LENGTH is not zero, the maximum
2110    length to scan is given - this can be used for syntax checks of
2111    data passed from outside. errorcode and erroff may both be passed as
2112    NULL.  */
2113 size_t
2114 _gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
2115                       size_t *erroff, gcry_err_code_t *errcode)
2116 {
2117   const unsigned char *p;
2118   const unsigned char *disphint = NULL;
2119   unsigned int datalen = 0;
2120   size_t dummy_erroff;
2121   gcry_err_code_t dummy_errcode;
2122   size_t count = 0;
2123   int level = 0;
2124
2125   if (!erroff)
2126     erroff = &dummy_erroff;
2127   if (!errcode)
2128     errcode = &dummy_errcode;
2129
2130   *errcode = GPG_ERR_NO_ERROR;
2131   *erroff = 0;
2132   if (!buffer)
2133     return 0;
2134   if (*buffer != '(')
2135     {
2136       *errcode = GPG_ERR_SEXP_NOT_CANONICAL;
2137       return 0;
2138     }
2139
2140   for (p=buffer; ; p++, count++ )
2141     {
2142       if (length && count >= length)
2143         {
2144           *erroff = count;
2145           *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
2146           return 0;
2147         }
2148
2149       if (datalen)
2150         {
2151           if (*p == ':')
2152             {
2153               if (length && (count+datalen) >= length)
2154                 {
2155                   *erroff = count;
2156                   *errcode = GPG_ERR_SEXP_STRING_TOO_LONG;
2157                   return 0;
2158                 }
2159               count += datalen;
2160               p += datalen;
2161               datalen = 0;
2162             }
2163           else if (digitp(p))
2164             datalen = datalen*10 + atoi_1(p);
2165           else
2166             {
2167               *erroff = count;
2168               *errcode = GPG_ERR_SEXP_INV_LEN_SPEC;
2169               return 0;
2170             }
2171         }
2172       else if (*p == '(')
2173         {
2174           if (disphint)
2175             {
2176               *erroff = count;
2177               *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
2178               return 0;
2179             }
2180           level++;
2181         }
2182       else if (*p == ')')
2183         { /* walk up */
2184           if (!level)
2185             {
2186               *erroff = count;
2187               *errcode = GPG_ERR_SEXP_UNMATCHED_PAREN;
2188               return 0;
2189             }
2190           if (disphint)
2191             {
2192               *erroff = count;
2193               *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
2194               return 0;
2195             }
2196           if (!--level)
2197             return ++count; /* ready */
2198         }
2199       else if (*p == '[')
2200         {
2201           if (disphint)
2202             {
2203               *erroff = count;
2204               *errcode = GPG_ERR_SEXP_NESTED_DH;
2205               return 0;
2206             }
2207           disphint = p;
2208         }
2209       else if (*p == ']')
2210         {
2211           if ( !disphint )
2212             {
2213               *erroff = count;
2214               *errcode = GPG_ERR_SEXP_UNMATCHED_DH;
2215               return 0;
2216             }
2217           disphint = NULL;
2218         }
2219       else if (digitp (p) )
2220         {
2221           if (*p == '0')
2222             {
2223               *erroff = count;
2224               *errcode = GPG_ERR_SEXP_ZERO_PREFIX;
2225               return 0;
2226             }
2227           datalen = atoi_1 (p);
2228         }
2229       else if (*p == '&' || *p == '\\')
2230         {
2231           *erroff = count;
2232           *errcode = GPG_ERR_SEXP_UNEXPECTED_PUNC;
2233           return 0;
2234         }
2235       else
2236         {
2237           *erroff = count;
2238           *errcode = GPG_ERR_SEXP_BAD_CHARACTER;
2239           return 0;
2240         }
2241     }
2242 }
2243
2244
2245 /* Extract MPIs from an s-expression using a list of parameters.  The
2246  * names of these parameters are given by the string LIST.  Some
2247  * special characters may be given to control the conversion:
2248  *
2249  *    + :: Switch to unsigned integer format (default).
2250  *    - :: Switch to standard signed format.
2251  *    / :: Switch to opaque format.
2252  *    & :: Switch to buffer descriptor mode - see below.
2253  *    ? :: The previous parameter is optional.
2254  *
2255  * In general parameter names are single letters.  To use a string for
2256  * a parameter name, enclose the name in single quotes.
2257  *
2258  * Unless in gcry_buffer_t mode for each parameter name a pointer to
2259  * an MPI variable is expected that must be set to NULL prior to
2260  * invoking this function, and finally a NULL is expected.  Example:
2261  *
2262  *   _gcry_sexp_extract_param (key, NULL, "n/x+ed",
2263  *                             &mpi_n, &mpi_x, &mpi_e, NULL)
2264  *
2265  * This stores the parameter "N" from KEY as an unsigned MPI into
2266  * MPI_N, the parameter "X" as an opaque MPI into MPI_X, and the
2267  * parameter "E" again as an unsigned MPI into MPI_E.
2268  *
2269  * If in buffer descriptor mode a pointer to gcry_buffer_t descriptor
2270  * is expected instead of a pointer to an MPI.  The caller may use two
2271  * different operation modes: If the DATA field of the provided buffer
2272  * descriptor is NULL, the function allocates a new buffer and stores
2273  * it at DATA; the other fields are set accordingly with OFF being 0.
2274  * If DATA is not NULL, the function assumes that DATA, SIZE, and OFF
2275  * describe a buffer where to but the data; on return the LEN field
2276  * receives the number of bytes copied to that buffer; if the buffer
2277  * is too small, the function immediately returns with an error code
2278  * (and LEN set to 0).
2279  *
2280  * PATH is an optional string used to locate a token.  The exclamation
2281  * mark separated tokens are used to via gcry_sexp_find_token to find
2282  * a start point inside SEXP.
2283  *
2284  * The function returns 0 on success.  On error an error code is
2285  * returned, all passed MPIs that might have been allocated up to this
2286  * point are deallocated and set to NULL, and all passed buffers are
2287  * either truncated if the caller supplied the buffer, or deallocated
2288  * if the function allocated the buffer.
2289  */
2290 gpg_err_code_t
2291 _gcry_sexp_vextract_param (gcry_sexp_t sexp, const char *path,
2292                            const char *list, va_list arg_ptr)
2293 {
2294   gpg_err_code_t rc;
2295   const char *s, *s2;
2296   gcry_mpi_t *array[20];
2297   char arrayisdesc[20];
2298   int idx;
2299   gcry_sexp_t l1 = NULL;
2300   int mode = '+'; /* Default to GCRYMPI_FMT_USG.  */
2301   gcry_sexp_t freethis = NULL;
2302
2303   memset (arrayisdesc, 0, sizeof arrayisdesc);
2304
2305   /* First copy all the args into an array.  This is required so that
2306      we are able to release already allocated MPIs if later an error
2307      was found.  */
2308   for (s=list, idx=0; *s && idx < DIM (array); s++)
2309     {
2310       if (*s == '&' || *s == '+' || *s == '-' || *s == '/' || *s == '?')
2311         ;
2312       else if (whitespacep (s))
2313         ;
2314       else
2315         {
2316           if (*s == '\'')
2317             {
2318               s++;
2319               s2 = strchr (s, '\'');
2320               if (!s2 || s2 == s)
2321                 {
2322                   /* Closing quote not found or empty string.  */
2323                   return GPG_ERR_SYNTAX;
2324                 }
2325               s = s2;
2326             }
2327           array[idx] = va_arg (arg_ptr, gcry_mpi_t *);
2328           if (!array[idx])
2329             return GPG_ERR_MISSING_VALUE; /* NULL pointer given.  */
2330           idx++;
2331         }
2332     }
2333   if (*s)
2334     return GPG_ERR_LIMIT_REACHED;  /* Too many list elements.  */
2335   if (va_arg (arg_ptr, gcry_mpi_t *))
2336     return GPG_ERR_INV_ARG;  /* Not enough list elemends.  */
2337
2338   /* Drill down.  */
2339   while (path && *path)
2340     {
2341       size_t n;
2342
2343       s = strchr (path, '!');
2344       if (s == path)
2345         {
2346           rc = GPG_ERR_NOT_FOUND;
2347           goto cleanup;
2348         }
2349       n = s? s - path : 0;
2350       l1 = _gcry_sexp_find_token (sexp, path, n);
2351       if (!l1)
2352         {
2353           rc = GPG_ERR_NOT_FOUND;
2354           goto cleanup;
2355         }
2356       sexp = l1; l1 = NULL;
2357       sexp_release (freethis);
2358       freethis = sexp;
2359       if (n)
2360         path += n + 1;
2361       else
2362         path = NULL;
2363     }
2364
2365
2366   /* Now extract all parameters.  */
2367   for (s=list, idx=0; *s; s++)
2368     {
2369       if (*s == '&' || *s == '+' || *s == '-' || *s == '/')
2370         mode = *s;
2371       else if (whitespacep (s))
2372         ;
2373       else if (*s == '?')
2374         ; /* Only used via lookahead.  */
2375       else
2376         {
2377           if (*s == '\'')
2378             {
2379               /* Find closing quote, find token, set S to closing quote.  */
2380               s++;
2381               s2 = strchr (s, '\'');
2382               if (!s2 || s2 == s)
2383                 {
2384                   /* Closing quote not found or empty string.  */
2385                   rc = GPG_ERR_SYNTAX;
2386                   goto cleanup;
2387                 }
2388               l1 = _gcry_sexp_find_token (sexp, s, s2 - s);
2389               s = s2;
2390             }
2391           else
2392             l1 = _gcry_sexp_find_token (sexp, s, 1);
2393
2394           if (!l1 && s[1] == '?')
2395             {
2396               /* Optional element not found.  */
2397               if (mode == '&')
2398                 {
2399                   gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2400                   if (!spec->data)
2401                     {
2402                       spec->size = 0;
2403                       spec->off = 0;
2404                     }
2405                   spec->len = 0;
2406                 }
2407               else
2408                 *array[idx] = NULL;
2409             }
2410           else if (!l1)
2411             {
2412               rc = GPG_ERR_NO_OBJ;  /* List element not found.  */
2413               goto cleanup;
2414             }
2415            else
2416             {
2417               if (mode == '&')
2418                 {
2419                   gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2420
2421                   if (spec->data)
2422                     {
2423                       const char *pbuf;
2424                       size_t nbuf;
2425
2426                       pbuf = _gcry_sexp_nth_data (l1, 1, &nbuf);
2427                       if (!pbuf || !nbuf)
2428                         {
2429                           rc = GPG_ERR_INV_OBJ;
2430                           goto cleanup;
2431                         }
2432                       if (spec->off + nbuf > spec->size)
2433                         {
2434                           rc = GPG_ERR_BUFFER_TOO_SHORT;
2435                           goto cleanup;
2436                         }
2437                       memcpy ((char*)spec->data + spec->off, pbuf, nbuf);
2438                       spec->len = nbuf;
2439                       arrayisdesc[idx] = 1;
2440                     }
2441                   else
2442                     {
2443                       spec->data = _gcry_sexp_nth_buffer (l1, 1, &spec->size);
2444                       if (!spec->data)
2445                         {
2446                           rc = GPG_ERR_INV_OBJ; /* Or out of core.  */
2447                           goto cleanup;
2448                         }
2449                       spec->len = spec->size;
2450                       spec->off = 0;
2451                       arrayisdesc[idx] = 2;
2452                     }
2453                 }
2454               else if (mode == '/')
2455                 *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_OPAQUE);
2456               else if (mode == '-')
2457                 *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_STD);
2458               else
2459                 *array[idx] = _gcry_sexp_nth_mpi (l1, 1, GCRYMPI_FMT_USG);
2460               sexp_release (l1); l1 = NULL;
2461               if (!*array[idx])
2462                 {
2463                   rc = GPG_ERR_INV_OBJ;  /* Conversion failed.  */
2464                   goto cleanup;
2465                 }
2466             }
2467           idx++;
2468         }
2469     }
2470
2471   sexp_release (freethis);
2472   return 0;
2473
2474  cleanup:
2475   sexp_release (freethis);
2476   sexp_release (l1);
2477   while (idx--)
2478     {
2479       if (!arrayisdesc[idx])
2480         {
2481           _gcry_mpi_release (*array[idx]);
2482           *array[idx] = NULL;
2483         }
2484       else if (arrayisdesc[idx] == 1)
2485         {
2486           /* Caller provided buffer.  */
2487           gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2488           spec->len = 0;
2489         }
2490       else
2491         {
2492           /* We might have allocated a buffer.  */
2493           gcry_buffer_t *spec = (gcry_buffer_t*)array[idx];
2494           xfree (spec->data);
2495           spec->data = NULL;
2496           spec->size = spec->off = spec->len = 0;
2497         }
2498      }
2499   return rc;
2500 }
2501
2502 gpg_err_code_t
2503 _gcry_sexp_extract_param (gcry_sexp_t sexp, const char *path,
2504                           const char *list, ...)
2505 {
2506   gcry_err_code_t rc;
2507   va_list arg_ptr;
2508
2509   va_start (arg_ptr, list);
2510   rc = _gcry_sexp_vextract_param (sexp, path, list, arg_ptr);
2511   va_end (arg_ptr);
2512   return rc;
2513 }