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