sexp: Add function gcry_sexp_nth_buffer.
[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_error_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_error_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_error_t
214 gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
215                   int autodetect, void (*freefnc)(void*) )
216 {
217   gcry_error_t errcode;
218   gcry_sexp_t se;
219
220   if (!retsexp)
221     return gcry_error (GPG_ERR_INV_ARG);
222   *retsexp = NULL;
223   if (autodetect < 0 || autodetect > 1 || !buffer)
224     return gcry_error (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 gcry_error (GPG_ERR_NO_ERROR);
253 }
254
255 /* Same as gcry_sexp_create but don't transfer ownership */
256 gcry_error_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 the CDR
788  */
789 gcry_sexp_t
790 gcry_sexp_cdr(const gcry_sexp_t list)
791 {
792   const byte *p;
793   const byte *head;
794   DATALEN n;
795   gcry_sexp_t newlist;
796   byte *d;
797   int level = 0;
798   int skip = 1;
799
800   if (!list || list->d[0] != ST_OPEN)
801     return NULL;
802   p = list->d;
803
804   while (skip > 0)
805     {
806       p++;
807       if (*p == ST_DATA)
808         {
809           memcpy ( &n, ++p, sizeof n );
810           p += sizeof n + n;
811           p--;
812           if ( !level )
813             skip--;
814         }
815       else if (*p == ST_OPEN)
816         {
817           level++;
818         }
819       else if (*p == ST_CLOSE)
820         {
821           level--;
822           if ( !level )
823             skip--;
824         }
825       else if (*p == ST_STOP)
826         {
827           return NULL;
828         }
829     }
830   p++;
831
832   head = p;
833   level = 0;
834   do {
835     if (*p == ST_DATA)
836       {
837         memcpy ( &n, ++p, sizeof n );
838         p += sizeof n + n;
839         p--;
840       }
841     else if (*p == ST_OPEN)
842       {
843         level++;
844       }
845     else if (*p == ST_CLOSE)
846       {
847         level--;
848       }
849     else if (*p == ST_STOP)
850       {
851         return NULL;
852       }
853     p++;
854   } while (level);
855   n = p - head;
856
857   newlist = gcry_malloc (sizeof *newlist + n + 2);
858   if (!newlist)
859     return NULL;
860   d = newlist->d;
861   *d++ = ST_OPEN;
862   memcpy (d, head, n);
863   d += n;
864   *d++ = ST_CLOSE;
865   *d++ = ST_STOP;
866
867   return normalize (newlist);
868 }
869
870
871 gcry_sexp_t
872 gcry_sexp_cadr ( const gcry_sexp_t list )
873 {
874   gcry_sexp_t a, b;
875
876   a = gcry_sexp_cdr (list);
877   b = gcry_sexp_car (a);
878   gcry_sexp_release (a);
879   return b;
880 }
881
882
883 static int
884 hextobyte( const byte *s )
885 {
886   int c=0;
887
888   if( *s >= '0' && *s <= '9' )
889     c = 16 * (*s - '0');
890   else if( *s >= 'A' && *s <= 'F' )
891     c = 16 * (10 + *s - 'A');
892   else if( *s >= 'a' && *s <= 'f' ) {
893     c = 16 * (10 + *s - 'a');
894   }
895   s++;
896   if( *s >= '0' && *s <= '9' )
897     c += *s - '0';
898   else if( *s >= 'A' && *s <= 'F' )
899     c += 10 + *s - 'A';
900   else if( *s >= 'a' && *s <= 'f' ) {
901     c += 10 + *s - 'a';
902   }
903   return c;
904 }
905
906
907 struct make_space_ctx
908 {
909   gcry_sexp_t sexp;
910   size_t allocated;
911   byte *pos;
912 };
913
914
915 static gpg_err_code_t
916 make_space ( struct make_space_ctx *c, size_t n )
917 {
918   size_t used = c->pos - c->sexp->d;
919
920   if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
921     {
922       gcry_sexp_t newsexp;
923       byte *newhead;
924       size_t newsize;
925
926       newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
927       if (newsize <= c->allocated)
928         return GPG_ERR_TOO_LARGE;
929       newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
930       if (!newsexp)
931         return gpg_err_code_from_errno (errno);
932       c->allocated = newsize;
933       newhead = newsexp->d;
934       c->pos = newhead + used;
935       c->sexp = newsexp;
936     }
937   return 0;
938 }
939
940
941 /* Unquote STRING of LENGTH and store it into BUF.  The surrounding
942    quotes are must already be removed from STRING.  We assume that the
943    quoted string is syntacillay correct.  */
944 static size_t
945 unquote_string (const char *string, size_t length, unsigned char *buf)
946 {
947   int esc = 0;
948   const unsigned char *s = (const unsigned char*)string;
949   unsigned char *d = buf;
950   size_t n = length;
951
952   for (; n; n--, s++)
953     {
954       if (esc)
955         {
956           switch (*s)
957             {
958             case 'b':  *d++ = '\b'; break;
959             case 't':  *d++ = '\t'; break;
960             case 'v':  *d++ = '\v'; break;
961             case 'n':  *d++ = '\n'; break;
962             case 'f':  *d++ = '\f'; break;
963             case 'r':  *d++ = '\r'; break;
964             case '"':  *d++ = '\"'; break;
965             case '\'': *d++ = '\''; break;
966             case '\\': *d++ = '\\'; break;
967
968             case '\r':  /* ignore CR[,LF] */
969               if (n>1 && s[1] == '\n')
970                 {
971                   s++; n--;
972                 }
973               break;
974
975             case '\n':  /* ignore LF[,CR] */
976               if (n>1 && s[1] == '\r')
977                 {
978                   s++; n--;
979                 }
980               break;
981
982             case 'x': /* hex value */
983               if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
984                 {
985                   s++; n--;
986                   *d++ = xtoi_2 (s);
987                   s++; n--;
988                 }
989               break;
990
991             default:
992               if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
993                 {
994                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
995                   s += 2;
996                   n -= 2;
997                 }
998               break;
999             }
1000           esc = 0;
1001         }
1002       else if( *s == '\\' )
1003         esc = 1;
1004       else
1005         *d++ = *s;
1006     }
1007
1008   return d - buf;
1009 }
1010
1011 /****************
1012  * Scan the provided buffer and return the S expression in our internal
1013  * format.  Returns a newly allocated expression.  If erroff is not NULL and
1014  * a parsing error has occurred, the offset into buffer will be returned.
1015  * If ARGFLAG is true, the function supports some printf like
1016  * expressions.
1017  *  These are:
1018  *      %m - MPI
1019  *      %s - string (no autoswitch to secure allocation)
1020  *      %d - integer stored as string (no autoswitch to secure allocation)
1021  *      %b - memory buffer; this takes _two_ arguments: an integer with the
1022  *           length of the buffer and a pointer to the buffer.
1023  *      %S - Copy an gcry_sexp_t here.  The S-expression needs to be a
1024  *           regular one, starting with a parenthesis.
1025  *           (no autoswitch to secure allocation)
1026  *  all other format elements are currently not defined and return an error.
1027  *  this includes the "%%" sequence becauce the percent sign is not an
1028  *  allowed character.
1029  * FIXME: We should find a way to store the secure-MPIs not in the string
1030  * but as reference to somewhere - this can help us to save huge amounts
1031  * of secure memory.  The problem is, that if only one element is secure, all
1032  * other elements are automagicaly copied to secure memory too, so the most
1033  * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
1034  * regardless whether it is needed or not.
1035  */
1036 static gcry_error_t
1037 vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1038              const char *buffer, size_t length, int argflag,
1039              void **arg_list, va_list arg_ptr)
1040 {
1041   gcry_err_code_t err = 0;
1042   static const char tokenchars[] =
1043     "abcdefghijklmnopqrstuvwxyz"
1044     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
1045     "0123456789-./_:*+=";
1046   const char *p;
1047   size_t n;
1048   const char *digptr = NULL;
1049   const char *quoted = NULL;
1050   const char *tokenp = NULL;
1051   const char *hexfmt = NULL;
1052   const char *base64 = NULL;
1053   const char *disphint = NULL;
1054   const char *percent = NULL;
1055   int hexcount = 0;
1056   int quoted_esc = 0;
1057   int datalen = 0;
1058   size_t dummy_erroff;
1059   struct make_space_ctx c;
1060   int arg_counter = 0;
1061   int level = 0;
1062
1063   if (!erroff)
1064     erroff = &dummy_erroff;
1065
1066   /* Depending on whether ARG_LIST is non-zero or not, this macro gives
1067      us the next argument, either from the variable argument list as
1068      specified by ARG_PTR or from the argument array ARG_LIST.  */
1069 #define ARG_NEXT(storage, type)                          \
1070   do                                                     \
1071     {                                                    \
1072       if (!arg_list)                                     \
1073         storage = va_arg (arg_ptr, type);                \
1074       else                                               \
1075         storage = *((type *) (arg_list[arg_counter++])); \
1076     }                                                    \
1077   while (0)
1078
1079   /* The MAKE_SPACE macro is used before each store operation to
1080      ensure that the buffer is large enough.  It requires a global
1081      context named C and jumps out to the label LEAVE on error! It
1082      also sets ERROFF using the variables BUFFER and P.  */
1083 #define MAKE_SPACE(n)  do {                                                \
1084                             gpg_err_code_t _ms_err = make_space (&c, (n)); \
1085                             if (_ms_err)                                   \
1086                               {                                            \
1087                                 err = _ms_err;                             \
1088                                 *erroff = p - buffer;                      \
1089                                 goto leave;                                \
1090                               }                                            \
1091                        } while (0)
1092
1093   /* The STORE_LEN macro is used to store the length N at buffer P. */
1094 #define STORE_LEN(p,n) do {                                                \
1095                             DATALEN ashort = (n);                          \
1096                             memcpy ( (p), &ashort, sizeof(ashort) );       \
1097                             (p) += sizeof (ashort);                        \
1098                         } while (0)
1099
1100   /* We assume that the internal representation takes less memory than
1101      the provided one.  However, we add space for one extra datalen so
1102      that the code which does the ST_CLOSE can use MAKE_SPACE */
1103   c.allocated = length + sizeof(DATALEN);
1104   if (buffer && length && gcry_is_secure (buffer))
1105     c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
1106   else
1107     c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
1108   if (!c.sexp)
1109     {
1110       err = gpg_err_code_from_errno (errno);
1111       *erroff = 0;
1112       goto leave;
1113     }
1114   c.pos = c.sexp->d;
1115
1116   for (p = buffer, n = length; n; p++, n--)
1117     {
1118       if (tokenp && !hexfmt)
1119         {
1120           if (strchr (tokenchars, *p))
1121             continue;
1122           else
1123             {
1124               datalen = p - tokenp;
1125               MAKE_SPACE (datalen);
1126               *c.pos++ = ST_DATA;
1127               STORE_LEN (c.pos, datalen);
1128               memcpy (c.pos, tokenp, datalen);
1129               c.pos += datalen;
1130               tokenp = NULL;
1131             }
1132         }
1133
1134       if (quoted)
1135         {
1136           if (quoted_esc)
1137             {
1138               switch (*p)
1139                 {
1140                 case 'b': case 't': case 'v': case 'n': case 'f':
1141                 case 'r': case '"': case '\'': case '\\':
1142                   quoted_esc = 0;
1143                   break;
1144
1145                 case '0': case '1': case '2': case '3': case '4':
1146                 case '5': case '6': case '7':
1147                   if (!((n > 2)
1148                         && (p[1] >= '0') && (p[1] <= '7')
1149                         && (p[2] >= '0') && (p[2] <= '7')))
1150                     {
1151                       *erroff = p - buffer;
1152                       /* Invalid octal value.  */
1153                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1154                       goto leave;
1155                     }
1156                   p += 2;
1157                   n -= 2;
1158                   quoted_esc = 0;
1159                   break;
1160
1161                 case 'x':
1162                   if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
1163                     {
1164                       *erroff = p - buffer;
1165                       /* Invalid hex value.  */
1166                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1167                       goto leave;
1168                     }
1169                   p += 2;
1170                   n -= 2;
1171                   quoted_esc = 0;
1172                   break;
1173
1174                 case '\r':
1175                   /* ignore CR[,LF] */
1176                   if (n && (p[1] == '\n'))
1177                     {
1178                       p++;
1179                       n--;
1180                     }
1181                   quoted_esc = 0;
1182                   break;
1183
1184                 case '\n':
1185                   /* ignore LF[,CR] */
1186                   if (n && (p[1] == '\r'))
1187                     {
1188                       p++;
1189                       n--;
1190                     }
1191                   quoted_esc = 0;
1192                   break;
1193
1194                 default:
1195                   *erroff = p - buffer;
1196                   /* Invalid quoted string escape.  */
1197                   err = GPG_ERR_SEXP_BAD_QUOTATION;
1198                   goto leave;
1199                 }
1200             }
1201           else if (*p == '\\')
1202             quoted_esc = 1;
1203           else if (*p == '\"')
1204             {
1205               /* Keep it easy - we know that the unquoted string will
1206                  never be larger. */
1207               unsigned char *save;
1208               size_t len;
1209
1210               quoted++; /* Skip leading quote.  */
1211               MAKE_SPACE (p - quoted);
1212               *c.pos++ = ST_DATA;
1213               save = c.pos;
1214               STORE_LEN (c.pos, 0); /* Will be fixed up later.  */
1215               len = unquote_string (quoted, p - quoted, c.pos);
1216               c.pos += len;
1217               STORE_LEN (save, len);
1218               quoted = NULL;
1219             }
1220         }
1221       else if (hexfmt)
1222         {
1223           if (isxdigit (*p))
1224             hexcount++;
1225           else if (*p == '#')
1226             {
1227               if ((hexcount & 1))
1228                 {
1229                   *erroff = p - buffer;
1230                   err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
1231                   goto leave;
1232                 }
1233
1234               datalen = hexcount / 2;
1235               MAKE_SPACE (datalen);
1236               *c.pos++ = ST_DATA;
1237               STORE_LEN (c.pos, datalen);
1238               for (hexfmt++; hexfmt < p; hexfmt++)
1239                 {
1240                   if (whitespacep (hexfmt))
1241                     continue;
1242                   *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
1243                   hexfmt++;
1244                 }
1245               hexfmt = NULL;
1246             }
1247           else if (!whitespacep (p))
1248             {
1249               *erroff = p - buffer;
1250               err = GPG_ERR_SEXP_BAD_HEX_CHAR;
1251               goto leave;
1252             }
1253         }
1254       else if (base64)
1255         {
1256           if (*p == '|')
1257             base64 = NULL;
1258         }
1259       else if (digptr)
1260         {
1261           if (digitp (p))
1262             ;
1263           else if (*p == ':')
1264             {
1265               datalen = atoi (digptr); /* FIXME: check for overflow.  */
1266               digptr = NULL;
1267               if (datalen > n - 1)
1268                 {
1269                   *erroff = p - buffer;
1270                   /* Buffer too short.  */
1271                   err = GPG_ERR_SEXP_STRING_TOO_LONG;
1272                   goto leave;
1273                 }
1274               /* Make a new list entry.  */
1275               MAKE_SPACE (datalen);
1276               *c.pos++ = ST_DATA;
1277               STORE_LEN (c.pos, datalen);
1278               memcpy (c.pos, p + 1, datalen);
1279               c.pos += datalen;
1280               n -= datalen;
1281               p += datalen;
1282             }
1283           else if (*p == '\"')
1284             {
1285               digptr = NULL; /* We ignore the optional length.  */
1286               quoted = p;
1287               quoted_esc = 0;
1288             }
1289           else if (*p == '#')
1290             {
1291               digptr = NULL; /* We ignore the optional length.  */
1292               hexfmt = p;
1293               hexcount = 0;
1294             }
1295           else if (*p == '|')
1296             {
1297               digptr = NULL; /* We ignore the optional length.  */
1298               base64 = p;
1299             }
1300           else
1301             {
1302               *erroff = p - buffer;
1303               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1304               goto leave;
1305             }
1306         }
1307       else if (percent)
1308         {
1309           if (*p == 'm' || *p == 'M')
1310             {
1311               /* Insert an MPI.  */
1312               gcry_mpi_t m;
1313               size_t nm = 0;
1314               int mpifmt = *p == 'm'? GCRYMPI_FMT_STD: GCRYMPI_FMT_USG;
1315
1316               ARG_NEXT (m, gcry_mpi_t);
1317
1318               if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
1319                 {
1320                   void *mp;
1321                   unsigned int nbits;
1322
1323                   mp = gcry_mpi_get_opaque (m, &nbits);
1324                   nm = (nbits+7)/8;
1325                   if (mp && nm)
1326                     {
1327                       MAKE_SPACE (nm);
1328                       if (!gcry_is_secure (c.sexp->d)
1329                           && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
1330                         {
1331                           /* We have to switch to secure allocation.  */
1332                           gcry_sexp_t newsexp;
1333                           byte *newhead;
1334
1335                           newsexp = gcry_malloc_secure (sizeof *newsexp
1336                                                         + c.allocated - 1);
1337                           if (!newsexp)
1338                             {
1339                               err = gpg_err_code_from_errno (errno);
1340                               goto leave;
1341                             }
1342                           newhead = newsexp->d;
1343                           memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1344                           c.pos = newhead + (c.pos - c.sexp->d);
1345                           gcry_free (c.sexp);
1346                           c.sexp = newsexp;
1347                         }
1348
1349                       *c.pos++ = ST_DATA;
1350                       STORE_LEN (c.pos, nm);
1351                       memcpy (c.pos, mp, nm);
1352                       c.pos += nm;
1353                     }
1354                 }
1355               else
1356                 {
1357                   if (gcry_mpi_print (mpifmt, NULL, 0, &nm, m))
1358                     BUG ();
1359
1360                   MAKE_SPACE (nm);
1361                   if (!gcry_is_secure (c.sexp->d)
1362                       && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
1363                     {
1364                       /* We have to switch to secure allocation.  */
1365                       gcry_sexp_t newsexp;
1366                       byte *newhead;
1367
1368                       newsexp = gcry_malloc_secure (sizeof *newsexp
1369                                                     + c.allocated - 1);
1370                       if (!newsexp)
1371                         {
1372                           err = gpg_err_code_from_errno (errno);
1373                           goto leave;
1374                         }
1375                       newhead = newsexp->d;
1376                       memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1377                       c.pos = newhead + (c.pos - c.sexp->d);
1378                       gcry_free (c.sexp);
1379                       c.sexp = newsexp;
1380                     }
1381
1382                   *c.pos++ = ST_DATA;
1383                   STORE_LEN (c.pos, nm);
1384                   if (gcry_mpi_print (mpifmt, c.pos, nm, &nm, m))
1385                     BUG ();
1386                   c.pos += nm;
1387                 }
1388             }
1389           else if (*p == 's')
1390             {
1391               /* Insert an string.  */
1392               const char *astr;
1393               size_t alen;
1394
1395               ARG_NEXT (astr, const char *);
1396               alen = strlen (astr);
1397
1398               MAKE_SPACE (alen);
1399               *c.pos++ = ST_DATA;
1400               STORE_LEN (c.pos, alen);
1401               memcpy (c.pos, astr, alen);
1402               c.pos += alen;
1403             }
1404           else if (*p == 'b')
1405             {
1406               /* Insert a memory buffer.  */
1407               const char *astr;
1408               int alen;
1409
1410               ARG_NEXT (alen, int);
1411               ARG_NEXT (astr, const char *);
1412
1413               MAKE_SPACE (alen);
1414               if (alen
1415                   && !gcry_is_secure (c.sexp->d)
1416                   && gcry_is_secure (astr))
1417               {
1418                   /* We have to switch to secure allocation.  */
1419                   gcry_sexp_t newsexp;
1420                   byte *newhead;
1421
1422                   newsexp = gcry_malloc_secure (sizeof *newsexp
1423                                                 + c.allocated - 1);
1424                   if (!newsexp)
1425                     {
1426                       err = gpg_err_code_from_errno (errno);
1427                       goto leave;
1428                     }
1429                   newhead = newsexp->d;
1430                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1431                   c.pos = newhead + (c.pos - c.sexp->d);
1432                   gcry_free (c.sexp);
1433                   c.sexp = newsexp;
1434                 }
1435
1436               *c.pos++ = ST_DATA;
1437               STORE_LEN (c.pos, alen);
1438               memcpy (c.pos, astr, alen);
1439               c.pos += alen;
1440             }
1441           else if (*p == 'd')
1442             {
1443               /* Insert an integer as string.  */
1444               int aint;
1445               size_t alen;
1446               char buf[35];
1447
1448               ARG_NEXT (aint, int);
1449               sprintf (buf, "%d", aint);
1450               alen = strlen (buf);
1451               MAKE_SPACE (alen);
1452               *c.pos++ = ST_DATA;
1453               STORE_LEN (c.pos, alen);
1454               memcpy (c.pos, buf, alen);
1455               c.pos += alen;
1456             }
1457           else if (*p == 'u')
1458             {
1459               /* Insert an unsigned integer as string.  */
1460               unsigned int aint;
1461               size_t alen;
1462               char buf[35];
1463
1464               ARG_NEXT (aint, unsigned int);
1465               sprintf (buf, "%u", aint);
1466               alen = strlen (buf);
1467               MAKE_SPACE (alen);
1468               *c.pos++ = ST_DATA;
1469               STORE_LEN (c.pos, alen);
1470               memcpy (c.pos, buf, alen);
1471               c.pos += alen;
1472             }
1473           else if (*p == 'S')
1474             {
1475               /* Insert a gcry_sexp_t.  */
1476               gcry_sexp_t asexp;
1477               size_t alen, aoff;
1478
1479               ARG_NEXT (asexp, gcry_sexp_t);
1480               alen = get_internal_buffer (asexp, &aoff);
1481               if (alen)
1482                 {
1483                   MAKE_SPACE (alen);
1484                   memcpy (c.pos, asexp->d + aoff, alen);
1485                   c.pos += alen;
1486                 }
1487             }
1488           else
1489             {
1490               *erroff = p - buffer;
1491               /* Invalid format specifier.  */
1492               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1493               goto leave;
1494             }
1495           percent = NULL;
1496         }
1497       else if (*p == '(')
1498         {
1499           if (disphint)
1500             {
1501               *erroff = p - buffer;
1502               /* Open display hint.  */
1503               err = GPG_ERR_SEXP_UNMATCHED_DH;
1504               goto leave;
1505             }
1506           MAKE_SPACE (0);
1507           *c.pos++ = ST_OPEN;
1508           level++;
1509         }
1510       else if (*p == ')')
1511         {
1512           /* Walk up.  */
1513           if (disphint)
1514             {
1515               *erroff = p - buffer;
1516               /* Open display hint.  */
1517               err = GPG_ERR_SEXP_UNMATCHED_DH;
1518               goto leave;
1519             }
1520           MAKE_SPACE (0);
1521           *c.pos++ = ST_CLOSE;
1522           level--;
1523         }
1524       else if (*p == '\"')
1525         {
1526           quoted = p;
1527           quoted_esc = 0;
1528         }
1529       else if (*p == '#')
1530         {
1531           hexfmt = p;
1532           hexcount = 0;
1533         }
1534       else if (*p == '|')
1535         base64 = p;
1536       else if (*p == '[')
1537         {
1538           if (disphint)
1539             {
1540               *erroff = p - buffer;
1541               /* Open display hint.  */
1542               err = GPG_ERR_SEXP_NESTED_DH;
1543               goto leave;
1544             }
1545           disphint = p;
1546         }
1547       else if (*p == ']')
1548         {
1549           if (!disphint)
1550             {
1551               *erroff = p - buffer;
1552               /* Open display hint.  */
1553               err = GPG_ERR_SEXP_UNMATCHED_DH;
1554               goto leave;
1555             }
1556           disphint = NULL;
1557         }
1558       else if (digitp (p))
1559         {
1560           if (*p == '0')
1561             {
1562               /* A length may not begin with zero.  */
1563               *erroff = p - buffer;
1564               err = GPG_ERR_SEXP_ZERO_PREFIX;
1565               goto leave;
1566             }
1567           digptr = p;
1568         }
1569       else if (strchr (tokenchars, *p))
1570         tokenp = p;
1571       else if (whitespacep (p))
1572         ;
1573       else if (*p == '{')
1574         {
1575           /* fixme: handle rescanning: we can do this by saving our
1576              current state and start over at p+1 -- Hmmm. At this
1577              point here we are in a well defined state, so we don't
1578              need to save it.  Great.  */
1579           *erroff = p - buffer;
1580           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1581           goto leave;
1582         }
1583       else if (strchr ("&\\", *p))
1584         {
1585           /* Reserved punctuation.  */
1586           *erroff = p - buffer;
1587           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1588           goto leave;
1589         }
1590       else if (argflag && (*p == '%'))
1591         percent = p;
1592       else
1593         {
1594           /* Bad or unavailable.  */
1595           *erroff = p - buffer;
1596           err = GPG_ERR_SEXP_BAD_CHARACTER;
1597           goto leave;
1598         }
1599     }
1600   MAKE_SPACE (0);
1601   *c.pos++ = ST_STOP;
1602
1603   if (level && !err)
1604     err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1605
1606  leave:
1607   if (err)
1608     {
1609       /* Error -> deallocate.  */
1610       if (c.sexp)
1611         {
1612           /* Extra paranoid wipe on error. */
1613           if (gcry_is_secure (c.sexp))
1614             wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
1615           gcry_free (c.sexp);
1616         }
1617       /* This might be expected by existing code...  */
1618       *retsexp = NULL;
1619     }
1620   else
1621     *retsexp = normalize (c.sexp);
1622
1623   return gcry_error (err);
1624 #undef MAKE_SPACE
1625 #undef STORE_LEN
1626 }
1627
1628
1629 static gcry_error_t
1630 sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1631             const char *buffer, size_t length, int argflag,
1632             void **arg_list, ...)
1633 {
1634   gcry_error_t rc;
1635   va_list arg_ptr;
1636
1637   va_start (arg_ptr, arg_list);
1638   rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
1639                     arg_list, arg_ptr);
1640   va_end (arg_ptr);
1641
1642   return rc;
1643 }
1644
1645
1646 gcry_error_t
1647 gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
1648 {
1649   gcry_error_t rc;
1650   va_list arg_ptr;
1651
1652   va_start (arg_ptr, format);
1653   rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1654                     NULL, arg_ptr);
1655   va_end (arg_ptr);
1656
1657   return rc;
1658 }
1659
1660
1661 gcry_error_t
1662 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
1663                    const char *format, va_list arg_ptr)
1664 {
1665   return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1666                       NULL, arg_ptr);
1667 }
1668
1669
1670 /* Like gcry_sexp_build, but uses an array instead of variable
1671    function arguments.  */
1672 gcry_error_t
1673 gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1674                        const char *format, void **arg_list)
1675 {
1676   return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
1677 }
1678
1679
1680 gcry_error_t
1681 gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1682                  const char *buffer, size_t length)
1683 {
1684   return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
1685 }
1686
1687 \f
1688 /* Figure out a suitable encoding for BUFFER of LENGTH.
1689    Returns: 0 = Binary
1690             1 = String possible
1691             2 = Token possible
1692 */
1693 static int
1694 suitable_encoding (const unsigned char *buffer, size_t length)
1695 {
1696   const unsigned char *s;
1697   int maybe_token = 1;
1698
1699   if (!length)
1700     return 1;
1701
1702   for (s=buffer; length; s++, length--)
1703     {
1704       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1705            && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1706         return 0; /*binary*/
1707       if ( maybe_token
1708            && !alphap (s) && !digitp (s)  && !strchr (TOKEN_SPECIALS, *s))
1709         maybe_token = 0;
1710     }
1711   s = buffer;
1712   if ( maybe_token && !digitp (s) )
1713     return 2;
1714   return 1;
1715 }
1716
1717
1718 static int
1719 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1720 {
1721   int i;
1722
1723   if (dest)
1724     {
1725       *dest++ = '#';
1726       for (i=0; i < len; i++, dest += 2 )
1727         sprintf (dest, "%02X", src[i]);
1728       *dest++ = '#';
1729     }
1730   return len*2+2;
1731 }
1732
1733 static int
1734 convert_to_string (const unsigned char *s, size_t len, char *dest)
1735 {
1736   if (dest)
1737     {
1738       char *p = dest;
1739       *p++ = '\"';
1740       for (; len; len--, s++ )
1741         {
1742           switch (*s)
1743             {
1744             case '\b': *p++ = '\\'; *p++ = 'b';  break;
1745             case '\t': *p++ = '\\'; *p++ = 't';  break;
1746             case '\v': *p++ = '\\'; *p++ = 'v';  break;
1747             case '\n': *p++ = '\\'; *p++ = 'n';  break;
1748             case '\f': *p++ = '\\'; *p++ = 'f';  break;
1749             case '\r': *p++ = '\\'; *p++ = 'r';  break;
1750             case '\"': *p++ = '\\'; *p++ = '\"';  break;
1751             case '\'': *p++ = '\\'; *p++ = '\'';  break;
1752             case '\\': *p++ = '\\'; *p++ = '\\';  break;
1753             default:
1754               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1755                 {
1756                   sprintf (p, "\\x%02x", *s);
1757                   p += 4;
1758                 }
1759               else
1760                 *p++ = *s;
1761             }
1762         }
1763       *p++ = '\"';
1764       return p - dest;
1765     }
1766   else
1767     {
1768       int count = 2;
1769       for (; len; len--, s++ )
1770         {
1771           switch (*s)
1772             {
1773             case '\b':
1774             case '\t':
1775             case '\v':
1776             case '\n':
1777             case '\f':
1778             case '\r':
1779             case '\"':
1780             case '\'':
1781             case '\\': count += 2; break;
1782             default:
1783               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1784                 count += 4;
1785               else
1786                 count++;
1787             }
1788         }
1789       return count;
1790     }
1791 }
1792
1793
1794
1795 static int
1796 convert_to_token (const unsigned char *src, size_t len, char *dest)
1797 {
1798   if (dest)
1799     memcpy (dest, src, len);
1800   return len;
1801 }
1802
1803
1804 /****************
1805  * Print SEXP to buffer using the MODE.  Returns the length of the
1806  * SEXP in buffer or 0 if the buffer is too short (We have at least an
1807  * empty list consisting of 2 bytes).  If a buffer of NULL is provided,
1808  * the required length is returned.
1809  */
1810 size_t
1811 gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1812                   void *buffer, size_t maxlength )
1813 {
1814   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1815   const unsigned char *s;
1816   char *d;
1817   DATALEN n;
1818   char numbuf[20];
1819   size_t len = 0;
1820   int i, indent = 0;
1821
1822   s = list? list->d : empty;
1823   d = buffer;
1824   while ( *s != ST_STOP )
1825     {
1826       switch ( *s )
1827         {
1828         case ST_OPEN:
1829           s++;
1830           if ( mode != GCRYSEXP_FMT_CANON )
1831             {
1832               if (indent)
1833                 len++;
1834               len += indent;
1835             }
1836           len++;
1837           if ( buffer )
1838             {
1839               if ( len >= maxlength )
1840                 return 0;
1841               if ( mode != GCRYSEXP_FMT_CANON )
1842                 {
1843                   if (indent)
1844                     *d++ = '\n';
1845                   for (i=0; i < indent; i++)
1846                     *d++ = ' ';
1847                 }
1848               *d++ = '(';
1849             }
1850           indent++;
1851           break;
1852         case ST_CLOSE:
1853           s++;
1854           len++;
1855           if ( buffer )
1856             {
1857               if ( len >= maxlength )
1858                 return 0;
1859               *d++ = ')';
1860             }
1861           indent--;
1862           if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
1863             {
1864               len++;
1865               len += indent;
1866               if (buffer)
1867                 {
1868                   if (len >= maxlength)
1869                     return 0;
1870                   *d++ = '\n';
1871                   for (i=0; i < indent; i++)
1872                     *d++ = ' ';
1873                 }
1874             }
1875           break;
1876         case ST_DATA:
1877           s++;
1878           memcpy ( &n, s, sizeof n ); s += sizeof n;
1879           if (mode == GCRYSEXP_FMT_ADVANCED)
1880             {
1881               int type;
1882               size_t nn;
1883
1884               switch ( (type=suitable_encoding (s, n)))
1885                 {
1886                 case 1: nn = convert_to_string (s, n, NULL); break;
1887                 case 2: nn = convert_to_token (s, n, NULL); break;
1888                 default: nn = convert_to_hex (s, n, NULL); break;
1889                 }
1890               len += nn;
1891               if (buffer)
1892                 {
1893                   if (len >= maxlength)
1894                     return 0;
1895                   switch (type)
1896                     {
1897                     case 1: convert_to_string (s, n, d); break;
1898                     case 2: convert_to_token (s, n, d); break;
1899                     default: convert_to_hex (s, n, d); break;
1900                     }
1901                   d += nn;
1902                 }
1903               if (s[n] != ST_CLOSE)
1904                 {
1905                   len++;
1906                   if (buffer)
1907                     {
1908                       if (len >= maxlength)
1909                         return 0;
1910                       *d++ = ' ';
1911                     }
1912                 }
1913             }
1914           else
1915             {
1916               sprintf (numbuf, "%u:", (unsigned int)n );
1917               len += strlen (numbuf) + n;
1918               if ( buffer )
1919                 {
1920                   if ( len >= maxlength )
1921                     return 0;
1922                   d = stpcpy ( d, numbuf );
1923                   memcpy ( d, s, n ); d += n;
1924                 }
1925             }
1926           s += n;
1927           break;
1928         default:
1929           BUG ();
1930         }
1931     }
1932   if ( mode != GCRYSEXP_FMT_CANON )
1933     {
1934       len++;
1935       if (buffer)
1936         {
1937           if ( len >= maxlength )
1938             return 0;
1939           *d++ = '\n';
1940         }
1941     }
1942   if (buffer)
1943     {
1944       if ( len >= maxlength )
1945         return 0;
1946       *d++ = 0; /* for convenience we make a C string */
1947     }
1948   else
1949     len++; /* we need one byte more for this */
1950
1951   return len;
1952 }
1953
1954
1955 /* Scan a canonical encoded buffer with implicit length values and
1956    return the actual length this S-expression uses.  For a valid S-Exp
1957    it should never return 0.  If LENGTH is not zero, the maximum
1958    length to scan is given - this can be used for syntax checks of
1959    data passed from outside. errorcode and erroff may both be passed as
1960    NULL.  */
1961 size_t
1962 gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
1963                      size_t *erroff, gcry_error_t *errcode)
1964 {
1965   const unsigned char *p;
1966   const unsigned char *disphint = NULL;
1967   unsigned int datalen = 0;
1968   size_t dummy_erroff;
1969   gcry_error_t dummy_errcode;
1970   size_t count = 0;
1971   int level = 0;
1972
1973   if (!erroff)
1974     erroff = &dummy_erroff;
1975   if (!errcode)
1976     errcode = &dummy_errcode;
1977
1978   *errcode = gcry_error (GPG_ERR_NO_ERROR);
1979   *erroff = 0;
1980   if (!buffer)
1981     return 0;
1982   if (*buffer != '(')
1983     {
1984       *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
1985       return 0;
1986     }
1987
1988   for (p=buffer; ; p++, count++ )
1989     {
1990       if (length && count >= length)
1991         {
1992           *erroff = count;
1993           *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1994           return 0;
1995         }
1996
1997       if (datalen)
1998         {
1999           if (*p == ':')
2000             {
2001               if (length && (count+datalen) >= length)
2002                 {
2003                   *erroff = count;
2004                   *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
2005                   return 0;
2006                 }
2007               count += datalen;
2008               p += datalen;
2009               datalen = 0;
2010             }
2011           else if (digitp(p))
2012             datalen = datalen*10 + atoi_1(p);
2013           else
2014             {
2015               *erroff = count;
2016               *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
2017               return 0;
2018             }
2019         }
2020       else if (*p == '(')
2021         {
2022           if (disphint)
2023             {
2024               *erroff = count;
2025               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
2026               return 0;
2027             }
2028           level++;
2029         }
2030       else if (*p == ')')
2031         { /* walk up */
2032           if (!level)
2033             {
2034               *erroff = count;
2035               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
2036               return 0;
2037             }
2038           if (disphint)
2039             {
2040               *erroff = count;
2041               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
2042               return 0;
2043             }
2044           if (!--level)
2045             return ++count; /* ready */
2046         }
2047       else if (*p == '[')
2048         {
2049           if (disphint)
2050             {
2051               *erroff = count;
2052               *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
2053               return 0;
2054             }
2055           disphint = p;
2056         }
2057       else if (*p == ']')
2058         {
2059           if ( !disphint )
2060             {
2061               *erroff = count;
2062               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
2063               return 0;
2064             }
2065           disphint = NULL;
2066         }
2067       else if (digitp (p) )
2068         {
2069           if (*p == '0')
2070             {
2071               *erroff = count;
2072               *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
2073               return 0;
2074             }
2075           datalen = atoi_1 (p);
2076         }
2077       else if (*p == '&' || *p == '\\')
2078         {
2079           *erroff = count;
2080           *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
2081           return 0;
2082         }
2083       else
2084         {
2085           *erroff = count;
2086           *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
2087           return 0;
2088         }
2089     }
2090 }