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