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