fixes for msvc compiler
[libgcrypt.git] / src / sexp.c
1 /* sexp.c  -  S-Expression handling
2  * Copyright (C) 1999, 2000, 2001, 2002, 2003,
3  *               2004, 2006, 2007, 2008  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         p++;
479         if ( type == ST_DATA ) {
480             memcpy ( &n, p, sizeof n );
481             p += sizeof n + n;
482             if ( level == 1 )
483                 length++;
484         }
485         else if ( type == ST_OPEN ) {
486             if ( level == 1 )
487                 length++;
488             level++;
489         }
490         else if ( type == ST_CLOSE ) {
491             level--;
492         }
493     }
494     return length;
495 }
496
497
498 /* Return the internal lengths offset of LIST.  That is the size of
499    the buffer from the first ST_OPEN, which is retruned at R_OFF, to
500    the corresponding ST_CLOSE inclusive.  */
501 static size_t
502 get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
503 {
504   const unsigned char *p;
505   DATALEN n;
506   int type;
507   int level = 0;
508   
509   *r_off = 0;
510   if (list)
511     {
512       p = list->d;
513       while ( (type=*p) != ST_STOP ) 
514         {
515           p++;
516           if (type == ST_DATA) 
517             {
518               memcpy (&n, p, sizeof n);
519               p += sizeof n + n;
520             }
521           else if (type == ST_OPEN)
522             {
523               if (!level)
524                 *r_off = (p-1) - list->d;
525               level++;
526             }
527           else if ( type == ST_CLOSE )
528             {
529               level--;
530               if (!level)
531                 return p - list->d;
532             }
533         }
534     }
535   return 0; /* Not a proper list.  */
536 }
537
538
539
540 /* Extract the CAR of the given list.  May return NULL for bad lists
541    or memory failure.  */
542 gcry_sexp_t
543 gcry_sexp_nth( const gcry_sexp_t list, int number )
544 {
545     const byte *p;
546     DATALEN n;
547     gcry_sexp_t newlist;
548     byte *d;
549     int level = 0;
550
551     if ( !list || list->d[0] != ST_OPEN )
552         return NULL;
553     p = list->d;
554
555     while ( number > 0 ) {
556         p++;
557         if ( *p == ST_DATA ) {
558             memcpy ( &n, ++p, sizeof n );
559             p += sizeof n + n;
560             p--;
561             if ( !level )
562                 number--;
563         }
564         else if ( *p == ST_OPEN ) {
565             level++;
566         }
567         else if ( *p == ST_CLOSE ) {
568             level--;
569             if ( !level )
570                 number--;
571         }
572         else if ( *p == ST_STOP ) {
573             return NULL;
574         }
575     }
576     p++;
577
578     if ( *p == ST_DATA ) {
579         memcpy ( &n, p, sizeof n ); p += sizeof n;
580         newlist = gcry_malloc ( sizeof *newlist + n + 1 );
581         if (!newlist)
582           return NULL;
583         d = newlist->d;
584         memcpy ( d, p, n ); d += n;
585         *d++ = ST_STOP;
586     }
587     else if ( *p == ST_OPEN ) {
588         const byte *head = p;
589
590         level = 1;
591         do {
592             p++;
593             if ( *p == ST_DATA ) {
594                 memcpy ( &n, ++p, sizeof n );
595                 p += sizeof n + n;
596                 p--;
597             }
598             else if ( *p == ST_OPEN ) {
599                 level++;
600             }
601             else if ( *p == ST_CLOSE ) {
602                 level--;
603             }
604             else if ( *p == ST_STOP ) {
605                 BUG ();
606             }
607         } while ( level );
608         n = p + 1 - head;
609
610         newlist = gcry_malloc ( sizeof *newlist + n );
611         if (!newlist)
612           return NULL;
613         d = newlist->d;
614         memcpy ( d, head, n ); d += n;
615         *d++ = ST_STOP;
616     }
617     else
618         newlist = NULL;
619
620     return normalize (newlist);
621 }
622
623 gcry_sexp_t
624 gcry_sexp_car( const gcry_sexp_t list )
625 {
626     return gcry_sexp_nth ( list, 0 );
627 }
628
629
630 /* Helper to get data from the car.  The returned value is valid as
631    long as the list is not modified. */
632 static const char *
633 sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
634 {
635   const byte *p;
636   DATALEN n;
637   int level = 0;
638   
639   *datalen = 0;
640   if ( !list ) 
641     return NULL;
642
643   p = list->d;
644   if ( *p == ST_OPEN )
645     p++;             /* Yep, a list. */
646   else if (number)
647     return NULL;     /* Not a list but N > 0 requested. */
648
649   /* Skip over N elements. */
650   while ( number > 0 ) 
651     {
652       if ( *p == ST_DATA ) 
653         {
654           memcpy ( &n, ++p, sizeof n );
655           p += sizeof n + n;
656           p--;
657           if ( !level )
658             number--;
659         }
660       else if ( *p == ST_OPEN ) 
661         {
662           level++;
663         }
664       else if ( *p == ST_CLOSE ) 
665         {
666           level--;
667           if ( !level )
668             number--;
669         }
670       else if ( *p == ST_STOP ) 
671         {
672           return NULL;
673         }
674       p++;
675     }
676
677   /* If this is data, return it.  */
678   if ( *p == ST_DATA )
679     {
680       memcpy ( &n, ++p, sizeof n );
681       *datalen = n;
682       return (const char*)p + sizeof n;
683     }
684   
685   return NULL;
686 }
687
688
689 /* Get data from the car.  The returned value is valid as long as the
690    list is not modified.  */
691 const char *
692 gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
693 {
694   return sexp_nth_data (list, number, datalen);
695 }
696
697
698 /* Get a string from the car.  The returned value is a malloced string
699    and needs to be freed by the caller.  */
700 char *
701 gcry_sexp_nth_string (const gcry_sexp_t list, int number)
702 {
703   const char *s;
704   size_t n;
705   char *buf;
706
707   s = sexp_nth_data (list, number, &n);
708   if (!s || n < 1 || (n+1) < 1)
709     return NULL;
710   buf = gcry_malloc (n+1);
711   if (!buf)
712     return NULL;
713   memcpy (buf, s, n);
714   buf[n] = 0;
715   return buf;
716 }
717
718 /*
719  * Get a MPI from the car
720  */
721 gcry_mpi_t
722 gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
723 {
724   const char *s;
725   size_t n;
726   gcry_mpi_t a;
727
728   if ( !mpifmt )
729     mpifmt = GCRYMPI_FMT_STD;
730
731   s = sexp_nth_data (list, number, &n);
732   if (!s)
733     return NULL;
734
735   if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
736     return NULL;
737
738   return a;
739 }
740
741
742 /****************
743  * Get the CDR
744  */
745 gcry_sexp_t
746 gcry_sexp_cdr( const gcry_sexp_t list )
747 {
748     const byte *p;
749     const byte *head;
750     DATALEN n;
751     gcry_sexp_t newlist;
752     byte *d;
753     int level = 0;
754     int skip = 1;
755
756     if ( !list || list->d[0] != ST_OPEN )
757         return NULL;
758     p = list->d;
759
760     while ( skip > 0 ) {
761         p++;
762         if ( *p == ST_DATA ) {
763             memcpy ( &n, ++p, sizeof n );
764             p += sizeof n + n;
765             p--;
766             if ( !level )
767                 skip--;
768         }
769         else if ( *p == ST_OPEN ) {
770             level++;
771         }
772         else if ( *p == ST_CLOSE ) {
773             level--;
774             if ( !level )
775                 skip--;
776         }
777         else if ( *p == ST_STOP ) {
778             return NULL;
779         }
780     }
781     p++;
782
783     head = p;
784     level = 0;
785     do {
786         if ( *p == ST_DATA ) {
787             memcpy ( &n, ++p, sizeof n );
788             p += sizeof n + n;
789             p--;
790         }
791         else if ( *p == ST_OPEN ) {
792             level++;
793         }
794         else if ( *p == ST_CLOSE ) {
795             level--;
796         }
797         else if ( *p == ST_STOP ) {
798             return NULL;
799         }
800         p++;
801     } while ( level );
802     n = p - head;
803
804     newlist = gcry_malloc ( sizeof *newlist + n + 2 );
805     if (!newlist)
806       return NULL;
807     d = newlist->d;
808     *d++ = ST_OPEN;
809     memcpy ( d, head, n ); d += n;
810     *d++ = ST_CLOSE;
811     *d++ = ST_STOP;
812
813     return normalize (newlist);
814 }
815
816 gcry_sexp_t
817 gcry_sexp_cadr ( const gcry_sexp_t list )
818 {
819     gcry_sexp_t a, b;
820
821     a = gcry_sexp_cdr ( list );
822     b = gcry_sexp_car ( a );
823     gcry_sexp_release ( a );
824     return b;
825 }
826
827
828
829 static int
830 hextobyte( const byte *s )
831 {
832     int c=0;
833
834     if( *s >= '0' && *s <= '9' )
835         c = 16 * (*s - '0');
836     else if( *s >= 'A' && *s <= 'F' )
837         c = 16 * (10 + *s - 'A');
838     else if( *s >= 'a' && *s <= 'f' ) {
839         c = 16 * (10 + *s - 'a');
840     }
841     s++;
842     if( *s >= '0' && *s <= '9' )
843         c += *s - '0';
844     else if( *s >= 'A' && *s <= 'F' )
845         c += 10 + *s - 'A';
846     else if( *s >= 'a' && *s <= 'f' ) {
847         c += 10 + *s - 'a';
848     }
849     return c;
850 }
851
852 struct make_space_ctx {
853     gcry_sexp_t sexp;
854     size_t allocated;
855     byte *pos;
856 };
857
858 static gpg_err_code_t
859 make_space ( struct make_space_ctx *c, size_t n )
860 {
861   size_t used = c->pos - c->sexp->d;
862   
863   if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
864     {
865       gcry_sexp_t newsexp;
866       byte *newhead;
867       size_t newsize;
868       
869       newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
870       if (newsize <= c->allocated)
871         return GPG_ERR_TOO_LARGE;
872       newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
873       if (!newsexp)
874         return gpg_err_code_from_errno (errno);
875       c->allocated = newsize;
876       newhead = newsexp->d;
877       c->pos = newhead + used;
878       c->sexp = newsexp;
879     }
880   return 0;
881 }
882
883
884 /* Unquote STRING of LENGTH and store it into BUF.  The surrounding
885    quotes are must already be removed from STRING.  We assume that the
886    quoted string is syntacillay correct.  */
887 static size_t
888 unquote_string (const char *string, size_t length, unsigned char *buf)
889 {
890   int esc = 0;
891   const unsigned char *s = (const unsigned char*)string;
892   unsigned char *d = buf;
893   size_t n = length;
894
895   for (; n; n--, s++)
896     {
897       if (esc)
898         {
899           switch (*s)
900             {
901             case 'b':  *d++ = '\b'; break;
902             case 't':  *d++ = '\t'; break;
903             case 'v':  *d++ = '\v'; break;
904             case 'n':  *d++ = '\n'; break;
905             case 'f':  *d++ = '\f'; break;
906             case 'r':  *d++ = '\r'; break;
907             case '"':  *d++ = '\"'; break;
908             case '\'': *d++ = '\''; break;
909             case '\\': *d++ = '\\'; break;
910
911             case '\r':  /* ignore CR[,LF] */
912               if (n>1 && s[1] == '\n')
913                 {
914                   s++; n--;
915                 }
916               break;
917               
918             case '\n':  /* ignore LF[,CR] */
919               if (n>1 && s[1] == '\r')
920                 {
921                   s++; n--;
922                 }
923               break;
924
925             case 'x': /* hex value */
926               if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
927                 {
928                   s++; n--;
929                   *d++ = xtoi_2 (s);
930                   s++; n--;
931                 }
932               break;
933
934             default:
935               if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
936                 {
937                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
938                   s += 2;
939                   n -= 2;
940                 }
941               break;
942             }
943           esc = 0;
944         }
945       else if( *s == '\\' )
946         esc = 1;
947       else
948         *d++ = *s;
949     } 
950
951   return d - buf;
952 }
953
954 /****************
955  * Scan the provided buffer and return the S expression in our internal
956  * format.  Returns a newly allocated expression.  If erroff is not NULL and
957  * a parsing error has occurred, the offset into buffer will be returned.
958  * If ARGFLAG is true, the function supports some printf like
959  * expressions.
960  *  These are:
961  *      %m - MPI
962  *      %s - string (no autoswitch to secure allocation)
963  *      %d - integer stored as string (no autoswitch to secure allocation)
964  *      %b - memory buffer; this takes _two_ arguments: an integer with the 
965  *           length of the buffer and a pointer to the buffer.
966  *      %S - Copy an gcry_sexp_t here.  The S-expression needs to be a
967  *           regular one, starting with a parenthesis. 
968  *           (no autoswitch to secure allocation)
969  *  all other format elements are currently not defined and return an error.
970  *  this includes the "%%" sequence becauce the percent sign is not an
971  *  allowed character.
972  * FIXME: We should find a way to store the secure-MPIs not in the string
973  * but as reference to somewhere - this can help us to save huge amounts
974  * of secure memory.  The problem is, that if only one element is secure, all
975  * other elements are automagicaly copied to secure memory too, so the most
976  * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
977  * regardless whether it is needed or not.
978  */
979 static gcry_error_t
980 vsexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
981              const char *buffer, size_t length, int argflag,
982              void **arg_list, va_list arg_ptr)
983 {
984   gcry_err_code_t err = 0;
985   static const char tokenchars[] =
986     "abcdefghijklmnopqrstuvwxyz"
987     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
988     "0123456789-./_:*+=";
989   const char *p;
990   size_t n;
991   const char *digptr = NULL;
992   const char *quoted = NULL;
993   const char *tokenp = NULL;
994   const char *hexfmt = NULL;
995   const char *base64 = NULL;
996   const char *disphint = NULL;
997   const char *percent = NULL;
998   int hexcount = 0;
999   int quoted_esc = 0;
1000   int datalen = 0;
1001   size_t dummy_erroff;
1002   struct make_space_ctx c;
1003   int arg_counter = 0;
1004   int level = 0;
1005
1006   if (!erroff)
1007     erroff = &dummy_erroff;
1008
1009   /* Depending on whether ARG_LIST is non-zero or not, this macro gives
1010      us the next argument, either from the variable argument list as
1011      specified by ARG_PTR or from the argument array ARG_LIST.  */
1012 #define ARG_NEXT(storage, type)                          \
1013   do                                                     \
1014     {                                                    \
1015       if (!arg_list)                                     \
1016         storage = va_arg (arg_ptr, type);                \
1017       else                                               \
1018         storage = *((type *) (arg_list[arg_counter++])); \
1019     }                                                    \
1020   while (0)
1021
1022   /* The MAKE_SPACE macro is used before each store operation to
1023      ensure that the buffer is large enough.  It requires a global
1024      context named C and jumps out to the label LEAVE on error! It
1025      also sets ERROFF using the variables BUFFER and P.  */
1026 #define MAKE_SPACE(n)  do {                                                \
1027                             gpg_err_code_t _ms_err = make_space (&c, (n)); \
1028                             if (_ms_err)                                   \
1029                               {                                            \
1030                                 err = _ms_err;                             \
1031                                 *erroff = p - buffer;                      \
1032                                 goto leave;                                \
1033                               }                                            \
1034                        } while (0)
1035
1036   /* The STORE_LEN macro is used to store the length N at buffer P. */
1037 #define STORE_LEN(p,n) do {                                                \
1038                             DATALEN ashort = (n);                          \
1039                             memcpy ( (p), &ashort, sizeof(ashort) );       \
1040                             (p) += sizeof (ashort);                        \
1041                         } while (0)
1042
1043   /* We assume that the internal representation takes less memory than
1044      the provided one.  However, we add space for one extra datalen so
1045      that the code which does the ST_CLOSE can use MAKE_SPACE */
1046   c.allocated = length + sizeof(DATALEN);
1047   if (buffer && length && gcry_is_secure (buffer))
1048     c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
1049   else
1050     c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
1051   if (!c.sexp)
1052     {
1053       err = gpg_err_code_from_errno (errno);
1054       *erroff = 0;
1055       goto leave;
1056     }
1057   c.pos = c.sexp->d;
1058
1059   for (p = buffer, n = length; n; p++, n--)
1060     {
1061       if (tokenp && !hexfmt)
1062         {
1063           if (strchr (tokenchars, *p))
1064             continue;
1065           else
1066             {
1067               datalen = p - tokenp;
1068               MAKE_SPACE (datalen);
1069               *c.pos++ = ST_DATA;
1070               STORE_LEN (c.pos, datalen);
1071               memcpy (c.pos, tokenp, datalen);
1072               c.pos += datalen;
1073               tokenp = NULL;
1074             }
1075         }
1076
1077       if (quoted)
1078         {
1079           if (quoted_esc)
1080             {
1081               switch (*p)
1082                 {
1083                 case 'b': case 't': case 'v': case 'n': case 'f':
1084                 case 'r': case '"': case '\'': case '\\':
1085                   quoted_esc = 0;
1086                   break;
1087
1088                 case '0': case '1': case '2': case '3': case '4':
1089                 case '5': case '6': case '7':
1090                   if (!((n > 2)
1091                         && (p[1] >= '0') && (p[1] <= '7')
1092                         && (p[2] >= '0') && (p[2] <= '7')))
1093                     {
1094                       *erroff = p - buffer;
1095                       /* Invalid octal value.  */
1096                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1097                       goto leave;
1098                     }
1099                   p += 2;
1100                   n -= 2;
1101                   quoted_esc = 0;
1102                   break;
1103                   
1104                 case 'x':
1105                   if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
1106                     {
1107                       *erroff = p - buffer;
1108                       /* Invalid hex value.  */
1109                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1110                       goto leave;
1111                     }
1112                   p += 2;
1113                   n -= 2;
1114                   quoted_esc = 0;
1115                   break;
1116
1117                 case '\r':
1118                   /* ignore CR[,LF] */
1119                   if (n && (p[1] == '\n'))
1120                     {
1121                       p++;
1122                       n--;
1123                     }
1124                   quoted_esc = 0;
1125                   break;
1126
1127                 case '\n':
1128                   /* ignore LF[,CR] */
1129                   if (n && (p[1] == '\r'))
1130                     {
1131                       p++;
1132                       n--;
1133                     }
1134                   quoted_esc = 0;
1135                   break;
1136
1137                 default:
1138                   *erroff = p - buffer;
1139                   /* Invalid quoted string escape.  */
1140                   err = GPG_ERR_SEXP_BAD_QUOTATION;
1141                   goto leave;
1142                 }
1143             }
1144           else if (*p == '\\')
1145             quoted_esc = 1;
1146           else if (*p == '\"')
1147             {
1148               /* Keep it easy - we know that the unquoted string will
1149                  never be larger. */
1150               unsigned char *save;
1151               size_t len;
1152               
1153               quoted++; /* Skip leading quote.  */
1154               MAKE_SPACE (p - quoted);
1155               *c.pos++ = ST_DATA;
1156               save = c.pos;
1157               STORE_LEN (c.pos, 0); /* Will be fixed up later.  */
1158               len = unquote_string (quoted, p - quoted, c.pos);
1159               c.pos += len;
1160               STORE_LEN (save, len);
1161               quoted = NULL;
1162             }
1163         }
1164       else if (hexfmt)
1165         {
1166           if (isxdigit (*p))
1167             hexcount++;
1168           else if (*p == '#')
1169             {
1170               if ((hexcount & 1))
1171                 {
1172                   *erroff = p - buffer;
1173                   err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
1174                   goto leave;
1175                 }
1176
1177               datalen = hexcount / 2;
1178               MAKE_SPACE (datalen);
1179               *c.pos++ = ST_DATA;
1180               STORE_LEN (c.pos, datalen);
1181               for (hexfmt++; hexfmt < p; hexfmt++)
1182                 {
1183                   if (whitespacep (hexfmt))
1184                     continue;
1185                   *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
1186                   hexfmt++;
1187                 }
1188               hexfmt = NULL;
1189             }
1190           else if (!whitespacep (p))
1191             {
1192               *erroff = p - buffer;
1193               err = GPG_ERR_SEXP_BAD_HEX_CHAR;
1194               goto leave;
1195             }
1196         }
1197       else if (base64)
1198         {
1199           if (*p == '|')
1200             base64 = NULL;
1201         }
1202       else if (digptr)
1203         {
1204           if (digitp (p))
1205             ;
1206           else if (*p == ':')
1207             {
1208               datalen = atoi (digptr); /* FIXME: check for overflow.  */
1209               digptr = NULL;
1210               if (datalen > n - 1)
1211                 {
1212                   *erroff = p - buffer;
1213                   /* Buffer too short.  */
1214                   err = GPG_ERR_SEXP_STRING_TOO_LONG;
1215                   goto leave;
1216                 }
1217               /* Make a new list entry.  */
1218               MAKE_SPACE (datalen);
1219               *c.pos++ = ST_DATA;
1220               STORE_LEN (c.pos, datalen);
1221               memcpy (c.pos, p + 1, datalen);
1222               c.pos += datalen;
1223               n -= datalen;
1224               p += datalen;
1225             }
1226           else if (*p == '\"')
1227             {
1228               digptr = NULL; /* We ignore the optional length.  */
1229               quoted = p;
1230               quoted_esc = 0;
1231             }
1232           else if (*p == '#')
1233             {
1234               digptr = NULL; /* We ignore the optional length.  */
1235               hexfmt = p;
1236               hexcount = 0;
1237             }
1238           else if (*p == '|')
1239             {
1240               digptr = NULL; /* We ignore the optional length.  */
1241               base64 = p;
1242             }
1243           else
1244             {
1245               *erroff = p - buffer;
1246               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1247               goto leave;
1248             }
1249         }
1250       else if (percent)
1251         {
1252           if (*p == 'm')
1253             {
1254               /* Insert an MPI.  */
1255               gcry_mpi_t m;
1256               size_t nm = 0;
1257
1258               ARG_NEXT (m, gcry_mpi_t);
1259               
1260               if (gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &nm, m))
1261                 BUG ();
1262
1263               MAKE_SPACE (nm);
1264               if (!gcry_is_secure (c.sexp->d)
1265                   && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
1266                 {
1267                   /* We have to switch to secure allocation.  */
1268                   gcry_sexp_t newsexp;
1269                   byte *newhead;
1270
1271                   newsexp = gcry_malloc_secure (sizeof *newsexp
1272                                                 + c.allocated - 1);
1273                   if (!newsexp)
1274                     {
1275                       err = gpg_err_code_from_errno (errno);
1276                       goto leave;
1277                     }
1278                   newhead = newsexp->d;
1279                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1280                   c.pos = newhead + (c.pos - c.sexp->d);
1281                   gcry_free (c.sexp);
1282                   c.sexp = newsexp;
1283                 }
1284
1285               *c.pos++ = ST_DATA;
1286               STORE_LEN (c.pos, nm);
1287               if (gcry_mpi_print (GCRYMPI_FMT_STD, c.pos, nm, &nm, m))
1288                 BUG ();
1289               c.pos += nm;
1290             }
1291           else if (*p == 's')
1292             {
1293               /* Insert an string.  */
1294               const char *astr;
1295               size_t alen;
1296
1297               ARG_NEXT (astr, const char *);
1298               alen = strlen (astr);
1299               
1300               MAKE_SPACE (alen);
1301               *c.pos++ = ST_DATA;
1302               STORE_LEN (c.pos, alen);
1303               memcpy (c.pos, astr, alen);
1304               c.pos += alen;
1305             }
1306           else if (*p == 'b')
1307             {
1308               /* Insert a memory buffer.  */
1309               const char *astr;
1310               int alen;
1311
1312               ARG_NEXT (alen, int);
1313               ARG_NEXT (astr, const char *);
1314               
1315               MAKE_SPACE (alen);
1316               if (alen
1317                   && !gcry_is_secure (c.sexp->d)
1318                   && gcry_is_secure (astr))
1319               {
1320                   /* We have to switch to secure allocation.  */
1321                   gcry_sexp_t newsexp;
1322                   byte *newhead;
1323
1324                   newsexp = gcry_malloc_secure (sizeof *newsexp
1325                                                 + c.allocated - 1);
1326                   if (!newsexp)
1327                     {
1328                       err = gpg_err_code_from_errno (errno);
1329                       goto leave;
1330                     }
1331                   newhead = newsexp->d;
1332                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1333                   c.pos = newhead + (c.pos - c.sexp->d);
1334                   gcry_free (c.sexp);
1335                   c.sexp = newsexp;
1336                 }
1337
1338               *c.pos++ = ST_DATA;
1339               STORE_LEN (c.pos, alen);
1340               memcpy (c.pos, astr, alen);
1341               c.pos += alen;
1342             }
1343           else if (*p == 'd')
1344             {
1345               /* Insert an integer as string.  */
1346               int aint;
1347               size_t alen;
1348               char buf[20];
1349               
1350               ARG_NEXT (aint, int);
1351               sprintf (buf, "%d", aint);
1352               alen = strlen (buf);
1353               MAKE_SPACE (alen);
1354               *c.pos++ = ST_DATA;
1355               STORE_LEN (c.pos, alen);
1356               memcpy (c.pos, buf, alen);
1357               c.pos += alen;
1358             }
1359           else if (*p == 'S')
1360             {
1361               /* Insert a gcry_sexp_t.  */
1362               gcry_sexp_t asexp;
1363               size_t alen, aoff;
1364
1365               ARG_NEXT (asexp, gcry_sexp_t);
1366               alen = get_internal_buffer (asexp, &aoff);
1367               if (alen)
1368                 {
1369                   MAKE_SPACE (alen);
1370                   memcpy (c.pos, asexp->d + aoff, alen);
1371                   c.pos += alen;
1372                 }
1373             }
1374           else
1375             {
1376               *erroff = p - buffer;
1377               /* Invalid format specifier.  */
1378               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1379               goto leave;
1380             }
1381           percent = NULL;
1382         }
1383       else if (*p == '(')
1384         {
1385           if (disphint)
1386             {
1387               *erroff = p - buffer;
1388               /* Open display hint.  */
1389               err = GPG_ERR_SEXP_UNMATCHED_DH;
1390               goto leave;
1391             }
1392           MAKE_SPACE (0);
1393           *c.pos++ = ST_OPEN;
1394           level++;
1395         }
1396       else if (*p == ')')
1397         {
1398           /* Walk up.  */
1399           if (disphint)
1400             {
1401               *erroff = p - buffer;
1402               /* Open display hint.  */
1403               err = GPG_ERR_SEXP_UNMATCHED_DH;
1404               goto leave;
1405             }
1406           MAKE_SPACE (0);
1407           *c.pos++ = ST_CLOSE;
1408           level--;
1409         }
1410       else if (*p == '\"')
1411         {
1412           quoted = p;
1413           quoted_esc = 0;
1414         }
1415       else if (*p == '#')
1416         {
1417           hexfmt = p;
1418           hexcount = 0;
1419         }
1420       else if (*p == '|')
1421         base64 = p;
1422       else if (*p == '[')
1423         {
1424           if (disphint)
1425             {
1426               *erroff = p - buffer;
1427               /* Open display hint.  */
1428               err = GPG_ERR_SEXP_NESTED_DH;
1429               goto leave;
1430             }
1431           disphint = p;
1432         }
1433       else if (*p == ']')
1434         {
1435           if (!disphint)
1436             {
1437               *erroff = p - buffer;
1438               /* Open display hint.  */
1439               err = GPG_ERR_SEXP_UNMATCHED_DH;
1440               goto leave;
1441             }
1442           disphint = NULL;
1443         }
1444       else if (digitp (p))
1445         {
1446           if (*p == '0')
1447             {
1448               /* A length may not begin with zero.  */
1449               *erroff = p - buffer;
1450               err = GPG_ERR_SEXP_ZERO_PREFIX;
1451               goto leave;
1452             }
1453           digptr = p;
1454         }
1455       else if (strchr (tokenchars, *p))
1456         tokenp = p;
1457       else if (whitespacep (p))
1458         ;
1459       else if (*p == '{')
1460         {
1461           /* fixme: handle rescanning: we can do this by saving our
1462              current state and start over at p+1 -- Hmmm. At this
1463              point here we are in a well defined state, so we don't
1464              need to save it.  Great.  */
1465           *erroff = p - buffer;
1466           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1467           goto leave;
1468         }
1469       else if (strchr ("&\\", *p))
1470         {
1471           /* Reserved punctuation.  */
1472           *erroff = p - buffer;
1473           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1474           goto leave;
1475         }
1476       else if (argflag && (*p == '%'))
1477         percent = p;
1478       else
1479         {
1480           /* Bad or unavailable.  */
1481           *erroff = p - buffer;
1482           err = GPG_ERR_SEXP_BAD_CHARACTER;
1483           goto leave;
1484         }
1485     }
1486   MAKE_SPACE (0);
1487   *c.pos++ = ST_STOP;
1488
1489   if (level && !err)
1490     err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1491
1492  leave:
1493   if (err)
1494     {
1495       /* Error -> deallocate.  */
1496       if (c.sexp)
1497         {
1498           /* Extra paranoid wipe on error. */
1499           if (gcry_is_secure (c.sexp))
1500             wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
1501           gcry_free (c.sexp);
1502         }
1503       /* This might be expected by existing code...  */
1504       *retsexp = NULL;
1505     }
1506   else
1507     *retsexp = normalize (c.sexp);
1508
1509   return gcry_error (err);
1510 #undef MAKE_SPACE
1511 #undef STORE_LEN
1512 }
1513
1514
1515 static gcry_error_t
1516 sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1517             const char *buffer, size_t length, int argflag,
1518             void **arg_list, ...)
1519 {
1520   gcry_error_t rc;
1521   va_list arg_ptr;
1522   
1523   va_start (arg_ptr, arg_list);
1524   rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
1525                     arg_list, arg_ptr);
1526   va_end (arg_ptr);
1527   
1528   return rc;
1529 }
1530
1531
1532 gcry_error_t
1533 gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
1534 {
1535   gcry_error_t rc;
1536   va_list arg_ptr;
1537   
1538   va_start (arg_ptr, format);
1539   rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1540                     NULL, arg_ptr);
1541   va_end (arg_ptr);
1542   
1543   return rc;
1544 }
1545
1546
1547 gcry_error_t
1548 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff, 
1549                    const char *format, va_list arg_ptr)
1550 {
1551   return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1552                       NULL, arg_ptr);
1553 }
1554
1555
1556 /* Like gcry_sexp_build, but uses an array instead of variable
1557    function arguments.  */
1558 gcry_error_t
1559 gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1560                        const char *format, void **arg_list)
1561 {
1562   return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
1563 }
1564
1565
1566 gcry_error_t
1567 gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1568                  const char *buffer, size_t length)
1569 {
1570   return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
1571 }
1572
1573 \f
1574 /* Figure out a suitable encoding for BUFFER of LENGTH.
1575    Returns: 0 = Binary
1576             1 = String possible
1577             2 = Token possible
1578 */
1579 static int
1580 suitable_encoding (const unsigned char *buffer, size_t length)
1581 {
1582   const unsigned char *s;
1583   int maybe_token = 1;
1584
1585   if (!length)
1586     return 1;
1587   
1588   for (s=buffer; length; s++, length--)
1589     {
1590       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1591            && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1592         return 0; /*binary*/
1593       if ( maybe_token
1594            && !alphap (s) && !digitp (s)  && !strchr (TOKEN_SPECIALS, *s))
1595         maybe_token = 0;
1596     }
1597   s = buffer;
1598   if ( maybe_token && !digitp (s) )
1599     return 2;
1600   return 1;
1601 }
1602
1603
1604 static int
1605 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1606 {
1607   int i;
1608
1609   if (dest)
1610     {
1611       *dest++ = '#';
1612       for (i=0; i < len; i++, dest += 2 )
1613         sprintf (dest, "%02X", src[i]);
1614       *dest++ = '#';
1615     }
1616   return len*2+2;
1617 }
1618
1619 static int
1620 convert_to_string (const unsigned char *s, size_t len, char *dest)
1621 {
1622   if (dest)
1623     {
1624       char *p = dest;
1625       *p++ = '\"';
1626       for (; len; len--, s++ )
1627         {
1628           switch (*s)
1629             {
1630             case '\b': *p++ = '\\'; *p++ = 'b';  break;
1631             case '\t': *p++ = '\\'; *p++ = 't';  break;
1632             case '\v': *p++ = '\\'; *p++ = 'v';  break;
1633             case '\n': *p++ = '\\'; *p++ = 'n';  break;
1634             case '\f': *p++ = '\\'; *p++ = 'f';  break;
1635             case '\r': *p++ = '\\'; *p++ = 'r';  break;
1636             case '\"': *p++ = '\\'; *p++ = '\"';  break;
1637             case '\'': *p++ = '\\'; *p++ = '\'';  break;
1638             case '\\': *p++ = '\\'; *p++ = '\\';  break;
1639             default: 
1640               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1641                 {
1642                   sprintf (p, "\\x%02x", *s); 
1643                   p += 4;
1644                 }
1645               else
1646                 *p++ = *s;
1647             }
1648         }
1649       *p++ = '\"';
1650       return p - dest;
1651     }
1652   else
1653     {
1654       int count = 2;
1655       for (; len; len--, s++ )
1656         {
1657           switch (*s)
1658             {
1659             case '\b': 
1660             case '\t': 
1661             case '\v': 
1662             case '\n': 
1663             case '\f': 
1664             case '\r': 
1665             case '\"':
1666             case '\'':
1667             case '\\': count += 2; break;
1668             default: 
1669               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1670                 count += 4;
1671               else
1672                 count++;
1673             }
1674         }
1675       return count;
1676     }
1677 }
1678
1679
1680
1681 static int
1682 convert_to_token (const unsigned char *src, size_t len, char *dest)
1683 {
1684   if (dest)
1685     memcpy (dest, src, len);
1686   return len;
1687 }
1688
1689
1690 /****************
1691  * Print SEXP to buffer using the MODE.  Returns the length of the
1692  * SEXP in buffer or 0 if the buffer is too short (We have at least an
1693  * empty list consisting of 2 bytes).  If a buffer of NULL is provided,
1694  * the required length is returned.
1695  */
1696 size_t
1697 gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1698                   void *buffer, size_t maxlength )
1699 {
1700   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1701   const unsigned char *s;
1702   char *d;
1703   DATALEN n;
1704   char numbuf[20];
1705   size_t len = 0;
1706   int i, indent = 0;
1707   
1708   s = list? list->d : empty;
1709   d = buffer;
1710   while ( *s != ST_STOP )
1711     {
1712       switch ( *s )
1713         {
1714         case ST_OPEN:
1715           s++;
1716           if ( mode != GCRYSEXP_FMT_CANON )
1717             {
1718               if (indent)
1719                 len++; 
1720               len += indent;
1721             }
1722           len++;
1723           if ( buffer ) 
1724             {
1725               if ( len >= maxlength )
1726                 return 0;
1727               if ( mode != GCRYSEXP_FMT_CANON )
1728                 {
1729                   if (indent)
1730                     *d++ = '\n'; 
1731                   for (i=0; i < indent; i++)
1732                     *d++ = ' ';
1733                 }
1734               *d++ = '(';
1735             }
1736           indent++;
1737           break;
1738         case ST_CLOSE:
1739           s++;
1740           len++;
1741           if ( buffer ) 
1742             {
1743               if ( len >= maxlength )
1744                 return 0;
1745               *d++ = ')';
1746             }
1747           indent--;
1748           if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
1749             {
1750               len++;
1751               len += indent;
1752               if (buffer)
1753                 {
1754                   if (len >= maxlength)
1755                     return 0;
1756                   *d++ = '\n';
1757                   for (i=0; i < indent; i++)
1758                     *d++ = ' ';
1759                 }
1760             }
1761           break;
1762         case ST_DATA:
1763           s++;
1764           memcpy ( &n, s, sizeof n ); s += sizeof n;
1765           if (mode == GCRYSEXP_FMT_ADVANCED)
1766             {
1767               int type;
1768               size_t nn;
1769
1770               switch ( (type=suitable_encoding (s, n)))
1771                 {
1772                 case 1: nn = convert_to_string (s, n, NULL); break;
1773                 case 2: nn = convert_to_token (s, n, NULL); break;
1774                 default: nn = convert_to_hex (s, n, NULL); break;
1775                 }
1776               len += nn;
1777               if (buffer)
1778                 {
1779                   if (len >= maxlength)
1780                     return 0;
1781                   switch (type)
1782                     {
1783                     case 1: convert_to_string (s, n, d); break;
1784                     case 2: convert_to_token (s, n, d); break;
1785                     default: convert_to_hex (s, n, d); break;
1786                     }
1787                   d += nn;
1788                 }
1789               if (s[n] != ST_CLOSE)
1790                 {
1791                   len++;
1792                   if (buffer)
1793                     {
1794                       if (len >= maxlength)
1795                         return 0;
1796                       *d++ = ' ';
1797                     }
1798                 }
1799             }
1800           else
1801             {
1802               sprintf (numbuf, "%u:", (unsigned int)n );
1803               len += strlen (numbuf) + n;
1804               if ( buffer ) 
1805                 {
1806                   if ( len >= maxlength )
1807                     return 0;
1808                   d = stpcpy ( d, numbuf );
1809                   memcpy ( d, s, n ); d += n;
1810                 }
1811             }
1812           s += n;
1813           break;
1814         default:
1815           BUG ();
1816         }
1817     }
1818   if ( mode != GCRYSEXP_FMT_CANON )
1819     {
1820       len++;
1821       if (buffer)
1822         {
1823           if ( len >= maxlength )
1824             return 0;
1825           *d++ = '\n'; 
1826         }
1827     }
1828   if (buffer) 
1829     {
1830       if ( len >= maxlength )
1831         return 0;
1832       *d++ = 0; /* for convenience we make a C string */
1833     }
1834   else
1835     len++; /* we need one byte more for this */
1836
1837   return len;
1838 }
1839
1840
1841 /* Scan a canonical encoded buffer with implicit length values and
1842    return the actual length this S-expression uses.  For a valid S-Exp
1843    it should never return 0.  If LENGTH is not zero, the maximum
1844    length to scan is given - this can be used for syntax checks of
1845    data passed from outside. errorcode and erroff may both be passed as
1846    NULL.  */
1847 size_t
1848 gcry_sexp_canon_len (const unsigned char *buffer, size_t length, 
1849                      size_t *erroff, gcry_error_t *errcode)
1850 {
1851   const unsigned char *p;
1852   const unsigned char *disphint = NULL;
1853   unsigned int datalen = 0;
1854   size_t dummy_erroff;
1855   gcry_error_t dummy_errcode;
1856   size_t count = 0;
1857   int level = 0;
1858
1859   if (!erroff)
1860     erroff = &dummy_erroff;
1861   if (!errcode)
1862     errcode = &dummy_errcode;
1863
1864   *errcode = gcry_error (GPG_ERR_NO_ERROR);
1865   *erroff = 0;
1866   if (!buffer)
1867     return 0;
1868   if (*buffer != '(')
1869     {
1870       *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
1871       return 0;
1872     }
1873
1874   for (p=buffer; ; p++, count++ )
1875     {
1876       if (length && count >= length)
1877         {
1878           *erroff = count;
1879           *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1880           return 0;
1881         }
1882       
1883       if (datalen)
1884         {
1885           if (*p == ':')
1886             {
1887               if (length && (count+datalen) >= length)
1888                 {
1889                   *erroff = count;
1890                   *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1891                   return 0;
1892                 }
1893               count += datalen;
1894               p += datalen;
1895               datalen = 0;
1896             }
1897           else if (digitp(p))
1898             datalen = datalen*10 + atoi_1(p);
1899           else 
1900             {
1901               *erroff = count;
1902               *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
1903               return 0;
1904             }
1905         }
1906       else if (*p == '(')
1907         {
1908           if (disphint)
1909             {
1910               *erroff = count;
1911               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1912               return 0;
1913             }
1914           level++;
1915         }
1916       else if (*p == ')')
1917         { /* walk up */
1918           if (!level)
1919             {
1920               *erroff = count;
1921               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
1922               return 0;
1923             }
1924           if (disphint)
1925             {
1926               *erroff = count;
1927               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1928               return 0;
1929             }
1930           if (!--level)
1931             return ++count; /* ready */
1932         }
1933       else if (*p == '[')
1934         {
1935           if (disphint) 
1936             {
1937               *erroff = count;
1938               *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
1939               return 0;
1940             }
1941           disphint = p;
1942         }
1943       else if (*p == ']')
1944         {
1945           if ( !disphint ) 
1946             {
1947               *erroff = count;
1948               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1949               return 0;
1950             }
1951           disphint = NULL;
1952         }
1953       else if (digitp (p) )
1954         {
1955           if (*p == '0')
1956             { 
1957               *erroff = count;
1958               *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
1959               return 0;
1960             }
1961           datalen = atoi_1 (p);
1962         }
1963       else if (*p == '&' || *p == '\\')
1964         {
1965           *erroff = count;
1966           *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
1967           return 0;
1968         }
1969       else
1970         { 
1971           *erroff = count;
1972           *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
1973           return 0;
1974         }
1975     }
1976 }