dab2b5482c0cafb4a33857e7721f15a331eea6c8
[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 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  * Get data from the car.  The returned value is valid as long as the list
587  * is not modified.
588  */
589 const char *
590 gcry_sexp_nth_data( const gcry_sexp_t list, int number, size_t *datalen )
591 {
592     const byte *p;
593     DATALEN n;
594     int level = 0;
595
596     *datalen = 0;
597     if ( !list ) {
598         return NULL;
599     }
600     p = list->d;
601     if ( *p == ST_OPEN )
602         p++;         /* yep, a list */
603     else if (number )
604         return NULL; /* not a list but an n > 0 element requested */
605
606     /* skip n elements */
607     while ( number > 0 ) {
608         if ( *p == ST_DATA ) {
609             memcpy ( &n, ++p, sizeof n );
610             p += sizeof n + n;
611             p--;
612             if ( !level )
613                 number--;
614         }
615         else if ( *p == ST_OPEN ) {
616             level++;
617         }
618         else if ( *p == ST_CLOSE ) {
619             level--;
620             if ( !level )
621                 number--;
622         }
623         else if ( *p == ST_STOP ) {
624             return NULL;
625         }
626         p++;
627     }
628
629
630     if ( *p == ST_DATA ) {
631         memcpy ( &n, ++p, sizeof n );
632         *datalen = n;
633         return (const char*)p + sizeof n;
634     }
635
636     return NULL;
637 }
638
639 /****************
640  * Get a MPI from the car
641  */
642 gcry_mpi_t
643 gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
644 {
645     const byte *p;
646     DATALEN n;
647     int level = 0;
648
649     if ( !list )
650         return NULL;
651     if ( !mpifmt )
652         mpifmt = GCRYMPI_FMT_STD;
653
654     p = list->d;
655     if ( *p == ST_OPEN )
656         p++;         /* yep, a list */
657     else if (number )
658         return NULL; /* not a list but an n > 0 element requested */
659
660     /* skip n elements */
661     while ( number > 0 ) {
662         if ( *p == ST_DATA ) {
663             memcpy ( &n, ++p, sizeof n );
664             p += sizeof n + n;
665             p--;
666             if ( !level )
667                 number--;
668         }
669         else if ( *p == ST_OPEN ) {
670             level++;
671         }
672         else if ( *p == ST_CLOSE ) {
673             level--;
674             if ( !level )
675                 number--;
676         }
677         else if ( *p == ST_STOP ) {
678             return NULL;
679         }
680         p++;
681     }
682
683     if ( *p == ST_DATA ) {
684         gcry_mpi_t a;
685         size_t nbytes;
686
687         memcpy ( &n, ++p, sizeof n );
688         p += sizeof n;
689         nbytes = n;
690         if( !gcry_mpi_scan( &a, mpifmt, p, n, &nbytes ) )
691             return a;
692     }
693
694     return NULL;
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 /* Like gcry_sexp_build, but uses an array instead of variable
1468    function arguments.  */
1469 gcry_error_t
1470 gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1471                        const char *format, void **arg_list)
1472 {
1473   /* We don't need the va_list because it is controlled by the
1474      following flag, however we have to pass it but can't initialize
1475      it as there is no portable way to do so.  volatile is needed to
1476      suppress the compiler warning */
1477   volatile va_list dummy_arg_ptr;
1478   
1479   gcry_error_t rc;
1480
1481   rc = sexp_sscan (retsexp, erroff, format, strlen(format), 1,
1482                    dummy_arg_ptr, arg_list);
1483
1484   return rc;
1485 }
1486
1487 gcry_error_t
1488 gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1489                  const char *buffer, size_t length)
1490 {
1491   /* We don't need the va_list because it is controlled by the
1492      following flag, however we have to pass it but can't initialize
1493      it as there is no portable way to do so.  volatile is needed to
1494      suppress the compiler warning */
1495   volatile va_list dummy_arg_ptr;
1496
1497   return sexp_sscan (retsexp, erroff, buffer, length, 0,
1498                      dummy_arg_ptr, NULL);
1499 }
1500
1501 \f
1502 /* Figure out a suitable encoding for BUFFER of LENGTH.
1503    Returns: 0 = Binary
1504             1 = String possible
1505             2 = Token possible
1506 */
1507 static int
1508 suitable_encoding (const unsigned char *buffer, size_t length)
1509 {
1510   const unsigned char *s;
1511   int maybe_token = 1;
1512
1513   if (!length)
1514     return 1;
1515   
1516   for (s=buffer; length; s++, length--)
1517     {
1518       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1519            && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1520         return 0; /*binary*/
1521       if ( maybe_token
1522            && !alphap (s) && !digitp (s)  && !strchr (TOKEN_SPECIALS, *s))
1523         maybe_token = 0;
1524     }
1525   s = buffer;
1526   if ( maybe_token && !digitp (s) )
1527     return 2;
1528   return 1;
1529 }
1530
1531
1532 static int
1533 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1534 {
1535   int i;
1536
1537   if (dest)
1538     {
1539       *dest++ = '#';
1540       for (i=0; i < len; i++, dest += 2 )
1541         sprintf (dest, "%02X", src[i]);
1542       *dest++ = '#';
1543     }
1544   return len*2+2;
1545 }
1546
1547 static int
1548 convert_to_string (const unsigned char *s, size_t len, char *dest)
1549 {
1550   if (dest)
1551     {
1552       char *p = dest;
1553       *p++ = '\"';
1554       for (; len; len--, s++ )
1555         {
1556           switch (*s)
1557             {
1558             case '\b': *p++ = '\\'; *p++ = 'b';  break;
1559             case '\t': *p++ = '\\'; *p++ = 't';  break;
1560             case '\v': *p++ = '\\'; *p++ = 'v';  break;
1561             case '\n': *p++ = '\\'; *p++ = 'n';  break;
1562             case '\f': *p++ = '\\'; *p++ = 'f';  break;
1563             case '\r': *p++ = '\\'; *p++ = 'r';  break;
1564             case '\"': *p++ = '\\'; *p++ = '\"';  break;
1565             case '\'': *p++ = '\\'; *p++ = '\'';  break;
1566             case '\\': *p++ = '\\'; *p++ = '\\';  break;
1567             default: 
1568               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1569                 {
1570                   sprintf (p, "\\x%02x", *s); 
1571                   p += 4;
1572                 }
1573               else
1574                 *p++ = *s;
1575             }
1576         }
1577       *p++ = '\"';
1578       return p - dest;
1579     }
1580   else
1581     {
1582       int count = 2;
1583       for (; len; len--, s++ )
1584         {
1585           switch (*s)
1586             {
1587             case '\b': 
1588             case '\t': 
1589             case '\v': 
1590             case '\n': 
1591             case '\f': 
1592             case '\r': 
1593             case '\"':
1594             case '\'':
1595             case '\\': count += 2; break;
1596             default: 
1597               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1598                 count += 4;
1599               else
1600                 count++;
1601             }
1602         }
1603       return count;
1604     }
1605 }
1606
1607
1608
1609 static int
1610 convert_to_token (const unsigned char *src, size_t len, char *dest)
1611 {
1612   if (dest)
1613     memcpy (dest, src, len);
1614   return len;
1615 }
1616
1617
1618 /****************
1619  * Print SEXP to buffer using the MODE.  Returns the length of the
1620  * SEXP in buffer or 0 if the buffer is too short (We have at least an
1621  * empty list consisting of 2 bytes).  If a buffer of NULL is provided,
1622  * the required length is returned.
1623  */
1624 size_t
1625 gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1626                   void *buffer, size_t maxlength )
1627 {
1628   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1629   const unsigned char *s;
1630   char *d;
1631   DATALEN n;
1632   char numbuf[20];
1633   size_t len = 0;
1634   int i, indent = 0;
1635   
1636   s = list? list->d : empty;
1637   d = buffer;
1638   while ( *s != ST_STOP )
1639     {
1640       switch ( *s )
1641         {
1642         case ST_OPEN:
1643           s++;
1644           if ( mode != GCRYSEXP_FMT_CANON )
1645             {
1646               if (indent)
1647                 len++; 
1648               len += indent;
1649             }
1650           len++;
1651           if ( buffer ) 
1652             {
1653               if ( len >= maxlength )
1654                 return 0;
1655               if ( mode != GCRYSEXP_FMT_CANON )
1656                 {
1657                   if (indent)
1658                     *d++ = '\n'; 
1659                   for (i=0; i < indent; i++)
1660                     *d++ = ' ';
1661                 }
1662               *d++ = '(';
1663             }
1664           indent++;
1665           break;
1666         case ST_CLOSE:
1667           s++;
1668           len++;
1669           if ( buffer ) 
1670             {
1671               if ( len >= maxlength )
1672                 return 0;
1673               *d++ = ')';
1674             }
1675           indent--;
1676           if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
1677             {
1678               len++;
1679               len += indent;
1680               if (buffer)
1681                 {
1682                   if (len >= maxlength)
1683                     return 0;
1684                   *d++ = '\n';
1685                   for (i=0; i < indent; i++)
1686                     *d++ = ' ';
1687                 }
1688             }
1689           break;
1690         case ST_DATA:
1691           s++;
1692           memcpy ( &n, s, sizeof n ); s += sizeof n;
1693           if (mode == GCRYSEXP_FMT_ADVANCED)
1694             {
1695               int type;
1696               size_t nn;
1697
1698               switch ( (type=suitable_encoding (s, n)))
1699                 {
1700                 case 1: nn = convert_to_string (s, n, NULL); break;
1701                 case 2: nn = convert_to_token (s, n, NULL); break;
1702                 default: nn = convert_to_hex (s, n, NULL); break;
1703                 }
1704               len += nn;
1705               if (buffer)
1706                 {
1707                   if (len >= maxlength)
1708                     return 0;
1709                   switch (type)
1710                     {
1711                     case 1: convert_to_string (s, n, d); break;
1712                     case 2: convert_to_token (s, n, d); break;
1713                     default: convert_to_hex (s, n, d); break;
1714                     }
1715                   d += nn;
1716                 }
1717               if (s[n] != ST_CLOSE)
1718                 {
1719                   len++;
1720                   if (buffer)
1721                     {
1722                       if (len >= maxlength)
1723                         return 0;
1724                       *d++ = ' ';
1725                     }
1726                 }
1727             }
1728           else
1729             {
1730               sprintf (numbuf, "%u:", (unsigned int)n );
1731               len += strlen (numbuf) + n;
1732               if ( buffer ) 
1733                 {
1734                   if ( len >= maxlength )
1735                     return 0;
1736                   d = stpcpy ( d, numbuf );
1737                   memcpy ( d, s, n ); d += n;
1738                 }
1739             }
1740           s += n;
1741           break;
1742         default:
1743           BUG ();
1744         }
1745     }
1746   if ( mode != GCRYSEXP_FMT_CANON )
1747     {
1748       len++;
1749       if (buffer)
1750         {
1751           if ( len >= maxlength )
1752             return 0;
1753           *d++ = '\n'; 
1754         }
1755     }
1756   if (buffer) 
1757     {
1758       if ( len >= maxlength )
1759         return 0;
1760       *d++ = 0; /* for convenience we make a C string */
1761     }
1762   else
1763     len++; /* we need one byte more for this */
1764
1765   return len;
1766 }
1767
1768
1769 /* Scan a cannocial encoded buffer with implicit length values and
1770    return the actual length this S-expression uses.  For a valid S-Exp
1771    it should never return 0.  If LENGTH is not zero, the maximum
1772    length to scan is given - this can be used for syntax checks of
1773    data passed from outside. errorcode and erroff may both be passed as
1774    NULL.  */
1775 size_t
1776 gcry_sexp_canon_len (const unsigned char *buffer, size_t length, 
1777                      size_t *erroff, gcry_error_t *errcode)
1778 {
1779   const unsigned char *p;
1780   const unsigned char *disphint = NULL;
1781   unsigned int datalen = 0;
1782   size_t dummy_erroff;
1783   gcry_error_t dummy_errcode;
1784   size_t count = 0;
1785   int level = 0;
1786
1787   if (!erroff)
1788     erroff = &dummy_erroff;
1789   if (!errcode)
1790     errcode = &dummy_errcode;
1791
1792   *errcode = gcry_error (GPG_ERR_NO_ERROR);
1793   *erroff = 0;
1794   if (!buffer)
1795     return 0;
1796   if (*buffer != '(')
1797     {
1798       *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
1799       return 0;
1800     }
1801
1802   for (p=buffer; ; p++, count++ )
1803     {
1804       if (length && count >= length)
1805         {
1806           *erroff = count;
1807           *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1808           return 0;
1809         }
1810       
1811       if (datalen)
1812         {
1813           if (*p == ':')
1814             {
1815               if (length && (count+datalen) >= length)
1816                 {
1817                   *erroff = count;
1818                   *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1819                   return 0;
1820                 }
1821               count += datalen;
1822               p += datalen;
1823               datalen = 0;
1824             }
1825           else if (digitp(p))
1826             datalen = datalen*10 + atoi_1(p);
1827           else 
1828             {
1829               *erroff = count;
1830               *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
1831               return 0;
1832             }
1833         }
1834       else if (*p == '(')
1835         {
1836           if (disphint)
1837             {
1838               *erroff = count;
1839               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1840               return 0;
1841             }
1842           level++;
1843         }
1844       else if (*p == ')')
1845         { /* walk up */
1846           if (!level)
1847             {
1848               *erroff = count;
1849               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
1850               return 0;
1851             }
1852           if (disphint)
1853             {
1854               *erroff = count;
1855               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1856               return 0;
1857             }
1858           if (!--level)
1859             return ++count; /* ready */
1860         }
1861       else if (*p == '[')
1862         {
1863           if (disphint) 
1864             {
1865               *erroff = count;
1866               *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
1867               return 0;
1868             }
1869           disphint = p;
1870         }
1871       else if (*p == ']')
1872         {
1873           if ( !disphint ) 
1874             {
1875               *erroff = count;
1876               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1877               return 0;
1878             }
1879           disphint = NULL;
1880         }
1881       else if (digitp (p) )
1882         {
1883           if (*p == '0')
1884             { 
1885               *erroff = count;
1886               *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
1887               return 0;
1888             }
1889           datalen = atoi_1 (p);
1890         }
1891       else if (*p == '&' || *p == '\\')
1892         {
1893           *erroff = count;
1894           *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
1895           return 0;
1896         }
1897       else
1898         { 
1899           *erroff = count;
1900           *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
1901           return 0;
1902         }
1903     }
1904 }