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