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