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