Finished RSA X9.31 key generation.
[libgcrypt.git] / src / sexp.c
1 /* sexp.c  -  S-Expression handling
2  * Copyright (C) 1999, 2000, 2001, 2002, 2003,
3  *               2004, 2006, 2007, 2008  Free Software Foundation, Inc.
4  *
5  * This file is part of Libgcrypt.
6  *
7  * Libgcrypt is free software; you can redistribute it and/or modify
8  * it under the terms of the GNU Lesser general Public License as
9  * published by the Free Software Foundation; either version 2.1 of
10  * the License, or (at your option) any later version.
11  *
12  * Libgcrypt is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this program; if not, write to the Free Software
19  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
20  */
21
22
23 #include <config.h>
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <ctype.h>
29 #include <errno.h>
30
31 #define GCRYPT_NO_MPI_MACROS 1
32 #include "g10lib.h"
33 #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 canonical 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 /* Return the internal lengths offset of LIST.  That is the size of
496    the buffer from the first ST_OPEN, which is retruned at R_OFF, to
497    the corresponding ST_CLOSE inclusive.  */
498 static size_t
499 get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
500 {
501   const unsigned char *p;
502   DATALEN n;
503   int type;
504   int level = 0;
505   
506   *r_off = 0;
507   if (list)
508     {
509       p = list->d;
510       while ( (type=*p) != ST_STOP ) 
511         {
512           p++;
513           if (type == ST_DATA) 
514             {
515               memcpy (&n, p, sizeof n);
516               p += sizeof n + n;
517             }
518           else if (type == ST_OPEN)
519             {
520               if (!level)
521                 *r_off = (p-1) - list->d;
522               level++;
523             }
524           else if ( type == ST_CLOSE )
525             {
526               level--;
527               if (!level)
528                 return p - list->d;
529             }
530         }
531     }
532   return 0; /* Not a proper list.  */
533 }
534
535
536
537 /* Extract the CAR of the given list.  May return NULL for bad lists
538    or memory failure.  */
539 gcry_sexp_t
540 gcry_sexp_nth( const gcry_sexp_t list, int number )
541 {
542     const byte *p;
543     DATALEN n;
544     gcry_sexp_t newlist;
545     byte *d;
546     int level = 0;
547
548     if ( !list || list->d[0] != ST_OPEN )
549         return NULL;
550     p = list->d;
551
552     while ( number > 0 ) {
553         p++;
554         if ( *p == ST_DATA ) {
555             memcpy ( &n, ++p, sizeof n );
556             p += sizeof n + n;
557             p--;
558             if ( !level )
559                 number--;
560         }
561         else if ( *p == ST_OPEN ) {
562             level++;
563         }
564         else if ( *p == ST_CLOSE ) {
565             level--;
566             if ( !level )
567                 number--;
568         }
569         else if ( *p == ST_STOP ) {
570             return NULL;
571         }
572     }
573     p++;
574
575     if ( *p == ST_DATA ) {
576         memcpy ( &n, p, sizeof n ); p += sizeof n;
577         newlist = gcry_malloc ( sizeof *newlist + n + 1 );
578         if (!newlist)
579           return NULL;
580         d = newlist->d;
581         memcpy ( d, p, n ); d += n;
582         *d++ = ST_STOP;
583     }
584     else if ( *p == ST_OPEN ) {
585         const byte *head = p;
586
587         level = 1;
588         do {
589             p++;
590             if ( *p == ST_DATA ) {
591                 memcpy ( &n, ++p, sizeof n );
592                 p += sizeof n + n;
593                 p--;
594             }
595             else if ( *p == ST_OPEN ) {
596                 level++;
597             }
598             else if ( *p == ST_CLOSE ) {
599                 level--;
600             }
601             else if ( *p == ST_STOP ) {
602                 BUG ();
603             }
604         } while ( level );
605         n = p + 1 - head;
606
607         newlist = gcry_malloc ( sizeof *newlist + n );
608         if (!newlist)
609           return NULL;
610         d = newlist->d;
611         memcpy ( d, head, n ); d += n;
612         *d++ = ST_STOP;
613     }
614     else
615         newlist = NULL;
616
617     return normalize (newlist);
618 }
619
620 gcry_sexp_t
621 gcry_sexp_car( const gcry_sexp_t list )
622 {
623     return gcry_sexp_nth ( list, 0 );
624 }
625
626
627 /* Helper to get data from the car.  The returned value is valid as
628    long as the list is not modified. */
629 static const char *
630 sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
631 {
632   const byte *p;
633   DATALEN n;
634   int level = 0;
635   
636   *datalen = 0;
637   if ( !list ) 
638     return NULL;
639
640   p = list->d;
641   if ( *p == ST_OPEN )
642     p++;             /* Yep, a list. */
643   else if (number)
644     return NULL;     /* Not a list but N > 0 requested. */
645
646   /* Skip over N elements. */
647   while ( number > 0 ) 
648     {
649       if ( *p == ST_DATA ) 
650         {
651           memcpy ( &n, ++p, sizeof n );
652           p += sizeof n + n;
653           p--;
654           if ( !level )
655             number--;
656         }
657       else if ( *p == ST_OPEN ) 
658         {
659           level++;
660         }
661       else if ( *p == ST_CLOSE ) 
662         {
663           level--;
664           if ( !level )
665             number--;
666         }
667       else if ( *p == ST_STOP ) 
668         {
669           return NULL;
670         }
671       p++;
672     }
673
674   /* If this is data, return it.  */
675   if ( *p == ST_DATA )
676     {
677       memcpy ( &n, ++p, sizeof n );
678       *datalen = n;
679       return (const char*)p + sizeof n;
680     }
681   
682   return NULL;
683 }
684
685
686 /* Get data from the car.  The returned value is valid as long as the
687    list is not modified.  */
688 const char *
689 gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
690 {
691   return sexp_nth_data (list, number, datalen);
692 }
693
694
695 /* Get a string from the car.  The returned value is a malloced string
696    and needs to be freed by the caller.  */
697 char *
698 gcry_sexp_nth_string (const gcry_sexp_t list, int number)
699 {
700   const char *s;
701   size_t n;
702   char *buf;
703
704   s = sexp_nth_data (list, number, &n);
705   if (!s || n < 1 || (n+1) < 1)
706     return NULL;
707   buf = gcry_malloc (n+1);
708   if (!buf)
709     return NULL;
710   memcpy (buf, s, n);
711   buf[n] = 0;
712   return buf;
713 }
714
715 /*
716  * Get a MPI from the car
717  */
718 gcry_mpi_t
719 gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
720 {
721   const char *s;
722   size_t n;
723   gcry_mpi_t a;
724
725   if ( !mpifmt )
726     mpifmt = GCRYMPI_FMT_STD;
727
728   s = sexp_nth_data (list, number, &n);
729   if (!s)
730     return NULL;
731
732   if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
733     return NULL;
734
735   return a;
736 }
737
738
739 /****************
740  * Get the CDR
741  */
742 gcry_sexp_t
743 gcry_sexp_cdr( const gcry_sexp_t list )
744 {
745     const byte *p;
746     const byte *head;
747     DATALEN n;
748     gcry_sexp_t newlist;
749     byte *d;
750     int level = 0;
751     int skip = 1;
752
753     if ( !list || list->d[0] != ST_OPEN )
754         return NULL;
755     p = list->d;
756
757     while ( skip > 0 ) {
758         p++;
759         if ( *p == ST_DATA ) {
760             memcpy ( &n, ++p, sizeof n );
761             p += sizeof n + n;
762             p--;
763             if ( !level )
764                 skip--;
765         }
766         else if ( *p == ST_OPEN ) {
767             level++;
768         }
769         else if ( *p == ST_CLOSE ) {
770             level--;
771             if ( !level )
772                 skip--;
773         }
774         else if ( *p == ST_STOP ) {
775             return NULL;
776         }
777     }
778     p++;
779
780     head = p;
781     level = 0;
782     do {
783         if ( *p == ST_DATA ) {
784             memcpy ( &n, ++p, sizeof n );
785             p += sizeof n + n;
786             p--;
787         }
788         else if ( *p == ST_OPEN ) {
789             level++;
790         }
791         else if ( *p == ST_CLOSE ) {
792             level--;
793         }
794         else if ( *p == ST_STOP ) {
795             return NULL;
796         }
797         p++;
798     } while ( level );
799     n = p - head;
800
801     newlist = gcry_malloc ( sizeof *newlist + n + 2 );
802     if (!newlist)
803       return NULL;
804     d = newlist->d;
805     *d++ = ST_OPEN;
806     memcpy ( d, head, n ); d += n;
807     *d++ = ST_CLOSE;
808     *d++ = ST_STOP;
809
810     return normalize (newlist);
811 }
812
813 gcry_sexp_t
814 gcry_sexp_cadr ( const gcry_sexp_t list )
815 {
816     gcry_sexp_t a, b;
817
818     a = gcry_sexp_cdr ( list );
819     b = gcry_sexp_car ( a );
820     gcry_sexp_release ( a );
821     return b;
822 }
823
824
825
826 static int
827 hextobyte( const byte *s )
828 {
829     int c=0;
830
831     if( *s >= '0' && *s <= '9' )
832         c = 16 * (*s - '0');
833     else if( *s >= 'A' && *s <= 'F' )
834         c = 16 * (10 + *s - 'A');
835     else if( *s >= 'a' && *s <= 'f' ) {
836         c = 16 * (10 + *s - 'a');
837     }
838     s++;
839     if( *s >= '0' && *s <= '9' )
840         c += *s - '0';
841     else if( *s >= 'A' && *s <= 'F' )
842         c += 10 + *s - 'A';
843     else if( *s >= 'a' && *s <= 'f' ) {
844         c += 10 + *s - 'a';
845     }
846     return c;
847 }
848
849 struct make_space_ctx {
850     gcry_sexp_t sexp;
851     size_t allocated;
852     byte *pos;
853 };
854
855 static gpg_err_code_t
856 make_space ( struct make_space_ctx *c, size_t n )
857 {
858   size_t used = c->pos - c->sexp->d;
859   
860   if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
861     {
862       gcry_sexp_t newsexp;
863       byte *newhead;
864       size_t newsize;
865       
866       newsize = c->allocated + 2*(n+sizeof(DATALEN)+1);
867       if (newsize <= c->allocated)
868         return GPG_ERR_TOO_LARGE;
869       newsexp = gcry_realloc ( c->sexp, sizeof *newsexp + newsize - 1);
870       if (!newsexp)
871         return gpg_err_code_from_errno (errno);
872       c->allocated = newsize;
873       newhead = newsexp->d;
874       c->pos = newhead + used;
875       c->sexp = newsexp;
876     }
877   return 0;
878 }
879
880
881 /* Unquote STRING of LENGTH and store it into BUF.  The surrounding
882    quotes are must already be removed from STRING.  We assume that the
883    quoted string is syntacillay correct.  */
884 static size_t
885 unquote_string (const char *string, size_t length, unsigned char *buf)
886 {
887   int esc = 0;
888   const unsigned char *s = (const unsigned char*)string;
889   unsigned char *d = buf;
890   size_t n = length;
891
892   for (; n; n--, s++)
893     {
894       if (esc)
895         {
896           switch (*s)
897             {
898             case 'b':  *d++ = '\b'; break;
899             case 't':  *d++ = '\t'; break;
900             case 'v':  *d++ = '\v'; break;
901             case 'n':  *d++ = '\n'; break;
902             case 'f':  *d++ = '\f'; break;
903             case 'r':  *d++ = '\r'; break;
904             case '"':  *d++ = '\"'; break;
905             case '\'': *d++ = '\''; break;
906             case '\\': *d++ = '\\'; break;
907
908             case '\r':  /* ignore CR[,LF] */
909               if (n>1 && s[1] == '\n')
910                 {
911                   s++; n--;
912                 }
913               esc = 0;
914               break;
915               
916             case '\n':  /* ignore LF[,CR] */
917               if (n>1 && s[1] == '\r')
918                 {
919                   s++; n--;
920                 }
921               break;
922
923             case 'x': /* hex value */
924               if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
925                 {
926                   s++; n--;
927                   *d++ = xtoi_2 (s);
928                   s++; n--;
929                 }
930               break;
931
932             default:
933               if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
934                 {
935                   *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
936                   s += 2;
937                   n -= 2;
938                 }
939               break;
940             }
941           esc = 0;
942         }
943       else if( *s == '\\' )
944         esc = 1;
945       else
946         *d++ = *s;
947     } 
948
949   return d - buf;
950 }
951
952 /****************
953  * Scan the provided buffer and return the S expression in our internal
954  * format.  Returns a newly allocated expression.  If erroff is not NULL and
955  * a parsing error has occured, the offset into buffer will be returned.
956  * If ARGFLAG is true, the function supports some printf like
957  * expressions.
958  *  These are:
959  *      %m - MPI
960  *      %s - string (no autoswitch to secure allocation)
961  *      %d - integer stored as string (no autoswitch to secure allocation)
962  *      %b - memory buffer; this takes _two_ arguments: an integer with the 
963  *           length of the buffer and a pointer to the buffer.
964  *      %S - Copy an gcry_sexp_t here.  The S-expression needs to be a
965  *           regular one, starting with a parenthesis. 
966  *           (no autoswitch to secure allocation)
967  *  all other format elements are currently not defined and return an error.
968  *  this includes the "%%" sequence becauce the percent sign is not an
969  *  allowed character.
970  * FIXME: We should find a way to store the secure-MPIs not in the string
971  * but as reference to somewhere - this can help us to save huge amounts
972  * of secure memory.  The problem is, that if only one element is secure, all
973  * other elements are automagicaly copied to secure memory too, so the most
974  * common operation gcry_sexp_cdr_mpi() will always return a secure MPI
975  * regardless whether it is needed or not.
976  */
977 static gcry_error_t
978 sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
979             const char *buffer, size_t length, int argflag,
980             va_list arg_ptr, void **arg_list)
981 {
982   gcry_err_code_t err = 0;
983   static const char tokenchars[] =
984     "abcdefghijklmnopqrstuvwxyz"
985     "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
986     "0123456789-./_:*+=";
987   const char *p;
988   size_t n;
989   const char *digptr = NULL;
990   const char *quoted = NULL;
991   const char *tokenp = NULL;
992   const char *hexfmt = NULL;
993   const char *base64 = NULL;
994   const char *disphint = NULL;
995   const char *percent = NULL;
996   int hexcount = 0;
997   int quoted_esc = 0;
998   int datalen = 0;
999   size_t dummy_erroff;
1000   struct make_space_ctx c;
1001   int arg_counter = 0;
1002   int level = 0;
1003
1004   if (!erroff)
1005     erroff = &dummy_erroff;
1006
1007   /* Depending on wether ARG_LIST is non-zero or not, this macro gives
1008      us the next argument, either from the variable argument list as
1009      specified by ARG_PTR or from the argument array ARG_LIST.  */
1010 #define ARG_NEXT(storage, type)                          \
1011   do                                                     \
1012     {                                                    \
1013       if (!arg_list)                                     \
1014         storage = va_arg (arg_ptr, type);                \
1015       else                                               \
1016         storage = *((type *) (arg_list[arg_counter++])); \
1017     }                                                    \
1018   while (0)
1019
1020   /* The MAKE_SPACE macro is used before each store operation to
1021      ensure that the buffer is large enough.  It requires a global
1022      context named C and jumps out to the label LEAVE on error! It
1023      also sets ERROFF using the variables BUFFER and P.  */
1024 #define MAKE_SPACE(n)  do {                                                \
1025                             gpg_err_code_t _ms_err = make_space (&c, (n)); \
1026                             if (_ms_err)                                   \
1027                               {                                            \
1028                                 err = _ms_err;                             \
1029                                 *erroff = p - buffer;                      \
1030                                 goto leave;                                \
1031                               }                                            \
1032                        } while (0)
1033
1034   /* The STORE_LEN macro is used to store the length N at buffer P. */
1035 #define STORE_LEN(p,n) do {                                                \
1036                             DATALEN ashort = (n);                          \
1037                             memcpy ( (p), &ashort, sizeof(ashort) );       \
1038                             (p) += sizeof (ashort);                        \
1039                         } while (0)
1040
1041   /* We assume that the internal representation takes less memory than
1042      the provided one.  However, we add space for one extra datalen so
1043      that the code which does the ST_CLOSE can use MAKE_SPACE */
1044   c.allocated = length + sizeof(DATALEN);
1045   if (buffer && length && gcry_is_secure (buffer))
1046     c.sexp = gcry_malloc_secure (sizeof *c.sexp + c.allocated - 1);
1047   else
1048     c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
1049   if (!c.sexp)
1050     {
1051       err = gpg_err_code_from_errno (errno);
1052       *erroff = 0;
1053       goto leave;
1054     }
1055   c.pos = c.sexp->d;
1056
1057   for (p = buffer, n = length; n; p++, n--)
1058     {
1059       if (tokenp && !hexfmt)
1060         {
1061           if (strchr (tokenchars, *p))
1062             continue;
1063           else
1064             {
1065               datalen = p - tokenp;
1066               MAKE_SPACE (datalen);
1067               *c.pos++ = ST_DATA;
1068               STORE_LEN (c.pos, datalen);
1069               memcpy (c.pos, tokenp, datalen);
1070               c.pos += datalen;
1071               tokenp = NULL;
1072             }
1073         }
1074
1075       if (quoted)
1076         {
1077           if (quoted_esc)
1078             {
1079               switch (*p)
1080                 {
1081                 case 'b': case 't': case 'v': case 'n': case 'f':
1082                 case 'r': case '"': case '\'': case '\\':
1083                   quoted_esc = 0;
1084                   break;
1085
1086                 case '0': case '1': case '2': case '3': case '4':
1087                 case '5': case '6': case '7':
1088                   if (!((n > 2)
1089                         && (p[1] >= '0') && (p[1] <= '7')
1090                         && (p[2] >= '0') && (p[2] <= '7')))
1091                     {
1092                       *erroff = p - buffer;
1093                       /* Invalid octal value.  */
1094                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1095                       goto leave;
1096                     }
1097                   p += 2;
1098                   n -= 2;
1099                   quoted_esc = 0;
1100                   break;
1101                   
1102                 case 'x':
1103                   if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
1104                     {
1105                       *erroff = p - buffer;
1106                       /* Invalid hex value.  */
1107                       err = GPG_ERR_SEXP_BAD_QUOTATION;
1108                       goto leave;
1109                     }
1110                   p += 2;
1111                   n -= 2;
1112                   quoted_esc = 0;
1113                   break;
1114
1115                 case '\r':
1116                   /* ignore CR[,LF] */
1117                   if (n && (p[1] == '\n'))
1118                     {
1119                       p++;
1120                       n--;
1121                     }
1122                   quoted_esc = 0;
1123                   break;
1124
1125                 case '\n':
1126                   /* ignore LF[,CR] */
1127                   if (n && (p[1] == '\r'))
1128                     {
1129                       p++;
1130                       n--;
1131                     }
1132                   quoted_esc = 0;
1133                   break;
1134
1135                 default:
1136                   *erroff = p - buffer;
1137                   /* Invalid quoted string escape.  */
1138                   err = GPG_ERR_SEXP_BAD_QUOTATION;
1139                   goto leave;
1140                 }
1141             }
1142           else if (*p == '\\')
1143             quoted_esc = 1;
1144           else if (*p == '\"')
1145             {
1146               /* Keep it easy - we know that the unquoted string will
1147                  never be larger. */
1148               unsigned char *save;
1149               size_t len;
1150               
1151               quoted++; /* Skip leading quote.  */
1152               MAKE_SPACE (p - quoted);
1153               *c.pos++ = ST_DATA;
1154               save = c.pos;
1155               STORE_LEN (c.pos, 0); /* Will be fixed up later.  */
1156               len = unquote_string (quoted, p - quoted, c.pos);
1157               c.pos += len;
1158               STORE_LEN (save, len);
1159               quoted = NULL;
1160             }
1161         }
1162       else if (hexfmt)
1163         {
1164           if (isxdigit (*p))
1165             hexcount++;
1166           else if (*p == '#')
1167             {
1168               if ((hexcount & 1))
1169                 {
1170                   *erroff = p - buffer;
1171                   err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
1172                   goto leave;
1173                 }
1174
1175               datalen = hexcount / 2;
1176               MAKE_SPACE (datalen);
1177               *c.pos++ = ST_DATA;
1178               STORE_LEN (c.pos, datalen);
1179               for (hexfmt++; hexfmt < p; hexfmt++)
1180                 {
1181                   if (whitespacep (hexfmt))
1182                     continue;
1183                   *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
1184                   hexfmt++;
1185                 }
1186               hexfmt = NULL;
1187             }
1188           else if (!whitespacep (p))
1189             {
1190               *erroff = p - buffer;
1191               err = GPG_ERR_SEXP_BAD_HEX_CHAR;
1192               goto leave;
1193             }
1194         }
1195       else if (base64)
1196         {
1197           if (*p == '|')
1198             base64 = NULL;
1199         }
1200       else if (digptr)
1201         {
1202           if (digitp (p))
1203             ;
1204           else if (*p == ':')
1205             {
1206               datalen = atoi (digptr); /* FIXME: check for overflow.  */
1207               digptr = NULL;
1208               if (datalen > n - 1)
1209                 {
1210                   *erroff = p - buffer;
1211                   /* Buffer too short.  */
1212                   err = GPG_ERR_SEXP_STRING_TOO_LONG;
1213                   goto leave;
1214                 }
1215               /* Make a new list entry.  */
1216               MAKE_SPACE (datalen);
1217               *c.pos++ = ST_DATA;
1218               STORE_LEN (c.pos, datalen);
1219               memcpy (c.pos, p + 1, datalen);
1220               c.pos += datalen;
1221               n -= datalen;
1222               p += datalen;
1223             }
1224           else if (*p == '\"')
1225             {
1226               digptr = NULL; /* We ignore the optional length.  */
1227               quoted = p;
1228               quoted_esc = 0;
1229             }
1230           else if (*p == '#')
1231             {
1232               digptr = NULL; /* We ignore the optional length.  */
1233               hexfmt = p;
1234               hexcount = 0;
1235             }
1236           else if (*p == '|')
1237             {
1238               digptr = NULL; /* We ignore the optional length.  */
1239               base64 = p;
1240             }
1241           else
1242             {
1243               *erroff = p - buffer;
1244               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1245               goto leave;
1246             }
1247         }
1248       else if (percent)
1249         {
1250           if (*p == 'm')
1251             {
1252               /* Insert an MPI.  */
1253               gcry_mpi_t m;
1254               size_t nm = 0;
1255
1256               ARG_NEXT (m, gcry_mpi_t);
1257               
1258               if (gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &nm, m))
1259                 BUG ();
1260
1261               MAKE_SPACE (nm);
1262               if (!gcry_is_secure (c.sexp->d)
1263                   && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
1264                 {
1265                   /* We have to switch to secure allocation.  */
1266                   gcry_sexp_t newsexp;
1267                   byte *newhead;
1268
1269                   newsexp = gcry_malloc_secure (sizeof *newsexp
1270                                                 + c.allocated - 1);
1271                   if (!newsexp)
1272                     {
1273                       err = gpg_err_code_from_errno (errno);
1274                       goto leave;
1275                     }
1276                   newhead = newsexp->d;
1277                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1278                   c.pos = newhead + (c.pos - c.sexp->d);
1279                   gcry_free (c.sexp);
1280                   c.sexp = newsexp;
1281                 }
1282
1283               *c.pos++ = ST_DATA;
1284               STORE_LEN (c.pos, nm);
1285               if (gcry_mpi_print (GCRYMPI_FMT_STD, c.pos, nm, &nm, m))
1286                 BUG ();
1287               c.pos += nm;
1288             }
1289           else if (*p == 's')
1290             {
1291               /* Insert an string.  */
1292               const char *astr;
1293               size_t alen;
1294
1295               ARG_NEXT (astr, const char *);
1296               alen = strlen (astr);
1297               
1298               MAKE_SPACE (alen);
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 == 'b')
1305             {
1306               /* Insert a memory buffer.  */
1307               const char *astr;
1308               int alen;
1309
1310               ARG_NEXT (alen, int);
1311               ARG_NEXT (astr, const char *);
1312               
1313               MAKE_SPACE (alen);
1314               if (alen
1315                   && !gcry_is_secure (c.sexp->d)
1316                   && gcry_is_secure (astr))
1317               {
1318                   /* We have to switch to secure allocation.  */
1319                   gcry_sexp_t newsexp;
1320                   byte *newhead;
1321
1322                   newsexp = gcry_malloc_secure (sizeof *newsexp
1323                                                 + c.allocated - 1);
1324                   if (!newsexp)
1325                     {
1326                       err = gpg_err_code_from_errno (errno);
1327                       goto leave;
1328                     }
1329                   newhead = newsexp->d;
1330                   memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1331                   c.pos = newhead + (c.pos - c.sexp->d);
1332                   gcry_free (c.sexp);
1333                   c.sexp = newsexp;
1334                 }
1335
1336               *c.pos++ = ST_DATA;
1337               STORE_LEN (c.pos, alen);
1338               memcpy (c.pos, astr, alen);
1339               c.pos += alen;
1340             }
1341           else if (*p == 'd')
1342             {
1343               /* Insert an integer as string.  */
1344               int aint;
1345               size_t alen;
1346               char buf[20];
1347               
1348               ARG_NEXT (aint, int);
1349               sprintf (buf, "%d", aint);
1350               alen = strlen (buf);
1351               MAKE_SPACE (alen);
1352               *c.pos++ = ST_DATA;
1353               STORE_LEN (c.pos, alen);
1354               memcpy (c.pos, buf, alen);
1355               c.pos += alen;
1356             }
1357           else if (*p == 'S')
1358             {
1359               /* Insert a gcry_sexp_t.  */
1360               gcry_sexp_t asexp;
1361               size_t alen, aoff;
1362
1363               ARG_NEXT (asexp, gcry_sexp_t);
1364               alen = get_internal_buffer (asexp, &aoff);
1365               if (alen)
1366                 {
1367                   MAKE_SPACE (alen);
1368                   memcpy (c.pos, asexp->d + aoff, alen);
1369                   c.pos += alen;
1370                 }
1371             }
1372           else
1373             {
1374               *erroff = p - buffer;
1375               /* Invalid format specifier.  */
1376               err = GPG_ERR_SEXP_INV_LEN_SPEC;
1377               goto leave;
1378             }
1379           percent = NULL;
1380         }
1381       else if (*p == '(')
1382         {
1383           if (disphint)
1384             {
1385               *erroff = p - buffer;
1386               /* Open display hint.  */
1387               err = GPG_ERR_SEXP_UNMATCHED_DH;
1388               goto leave;
1389             }
1390           MAKE_SPACE (0);
1391           *c.pos++ = ST_OPEN;
1392           level++;
1393         }
1394       else if (*p == ')')
1395         {
1396           /* Walk up.  */
1397           if (disphint)
1398             {
1399               *erroff = p - buffer;
1400               /* Open display hint.  */
1401               err = GPG_ERR_SEXP_UNMATCHED_DH;
1402               goto leave;
1403             }
1404           MAKE_SPACE (0);
1405           *c.pos++ = ST_CLOSE;
1406           level--;
1407         }
1408       else if (*p == '\"')
1409         {
1410           quoted = p;
1411           quoted_esc = 0;
1412         }
1413       else if (*p == '#')
1414         {
1415           hexfmt = p;
1416           hexcount = 0;
1417         }
1418       else if (*p == '|')
1419         base64 = p;
1420       else if (*p == '[')
1421         {
1422           if (disphint)
1423             {
1424               *erroff = p - buffer;
1425               /* Open display hint.  */
1426               err = GPG_ERR_SEXP_NESTED_DH;
1427               goto leave;
1428             }
1429           disphint = p;
1430         }
1431       else if (*p == ']')
1432         {
1433           if (!disphint)
1434             {
1435               *erroff = p - buffer;
1436               /* Open display hint.  */
1437               err = GPG_ERR_SEXP_UNMATCHED_DH;
1438               goto leave;
1439             }
1440           disphint = NULL;
1441         }
1442       else if (digitp (p))
1443         {
1444           if (*p == '0')
1445             {
1446               /* A length may not begin with zero.  */
1447               *erroff = p - buffer;
1448               err = GPG_ERR_SEXP_ZERO_PREFIX;
1449               goto leave;
1450             }
1451           digptr = p;
1452         }
1453       else if (strchr (tokenchars, *p))
1454         tokenp = p;
1455       else if (whitespacep (p))
1456         ;
1457       else if (*p == '{')
1458         {
1459           /* fixme: handle rescanning: we can do this by saving our
1460              current state and start over at p+1 -- Hmmm. At this
1461              point here we are in a well defined state, so we don't
1462              need to save it.  Great.  */
1463           *erroff = p - buffer;
1464           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1465           goto leave;
1466         }
1467       else if (strchr ("&\\", *p))
1468         {
1469           /* Reserved punctuation.  */
1470           *erroff = p - buffer;
1471           err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1472           goto leave;
1473         }
1474       else if (argflag && (*p == '%'))
1475         percent = p;
1476       else
1477         {
1478           /* Bad or unavailable.  */
1479           *erroff = p - buffer;
1480           err = GPG_ERR_SEXP_BAD_CHARACTER;
1481           goto leave;
1482         }
1483     }
1484   MAKE_SPACE (0);
1485   *c.pos++ = ST_STOP;
1486
1487   if (level && !err)
1488     err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1489
1490  leave:
1491   if (err)
1492     {
1493       /* Error -> deallocate.  */
1494       if (c.sexp)
1495         {
1496           /* Extra paranoid wipe on error. */
1497           if (gcry_is_secure (c.sexp))
1498             wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
1499           gcry_free (c.sexp);
1500         }
1501       /* This might be expected by existing code...  */
1502       *retsexp = NULL;
1503     }
1504   else
1505     *retsexp = normalize (c.sexp);
1506
1507   return gcry_error (err);
1508 #undef MAKE_SPACE
1509 #undef STORE_LEN
1510 }
1511
1512 gcry_error_t
1513 gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
1514 {
1515   gcry_error_t rc;
1516   va_list arg_ptr;
1517   
1518   va_start (arg_ptr, format);
1519   rc = sexp_sscan (retsexp, erroff, format, strlen(format), 1,
1520                    arg_ptr, NULL);
1521   va_end (arg_ptr);
1522   
1523   return rc;
1524 }
1525
1526
1527 gcry_error_t
1528 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff, 
1529                    const char *format, va_list arg_ptr)
1530 {
1531   return sexp_sscan (retsexp, erroff, format, strlen(format), 1,
1532                      arg_ptr, NULL);
1533 }
1534
1535 /* Like gcry_sexp_build, but uses an array instead of variable
1536    function arguments.  */
1537 gcry_error_t
1538 gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1539                        const char *format, void **arg_list)
1540 {
1541   /* We don't need the va_list because it is controlled by the
1542      following flag, however we have to pass it but can't initialize
1543      it as there is no portable way to do so.  volatile is needed to
1544      suppress the compiler warning */
1545   volatile va_list dummy_arg_ptr;
1546   
1547   gcry_error_t rc;
1548
1549   rc = sexp_sscan (retsexp, erroff, format, strlen(format), 1,
1550                    dummy_arg_ptr, arg_list);
1551
1552   return rc;
1553 }
1554
1555 gcry_error_t
1556 gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1557                  const char *buffer, size_t length)
1558 {
1559   /* We don't need the va_list because it is controlled by the
1560      following flag, however we have to pass it but can't initialize
1561      it as there is no portable way to do so.  volatile is needed to
1562      suppress the compiler warning */
1563   volatile va_list dummy_arg_ptr;
1564
1565   return sexp_sscan (retsexp, erroff, buffer, length, 0,
1566                      dummy_arg_ptr, NULL);
1567 }
1568
1569 \f
1570 /* Figure out a suitable encoding for BUFFER of LENGTH.
1571    Returns: 0 = Binary
1572             1 = String possible
1573             2 = Token possible
1574 */
1575 static int
1576 suitable_encoding (const unsigned char *buffer, size_t length)
1577 {
1578   const unsigned char *s;
1579   int maybe_token = 1;
1580
1581   if (!length)
1582     return 1;
1583   
1584   for (s=buffer; length; s++, length--)
1585     {
1586       if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1587            && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1588         return 0; /*binary*/
1589       if ( maybe_token
1590            && !alphap (s) && !digitp (s)  && !strchr (TOKEN_SPECIALS, *s))
1591         maybe_token = 0;
1592     }
1593   s = buffer;
1594   if ( maybe_token && !digitp (s) )
1595     return 2;
1596   return 1;
1597 }
1598
1599
1600 static int
1601 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1602 {
1603   int i;
1604
1605   if (dest)
1606     {
1607       *dest++ = '#';
1608       for (i=0; i < len; i++, dest += 2 )
1609         sprintf (dest, "%02X", src[i]);
1610       *dest++ = '#';
1611     }
1612   return len*2+2;
1613 }
1614
1615 static int
1616 convert_to_string (const unsigned char *s, size_t len, char *dest)
1617 {
1618   if (dest)
1619     {
1620       char *p = dest;
1621       *p++ = '\"';
1622       for (; len; len--, s++ )
1623         {
1624           switch (*s)
1625             {
1626             case '\b': *p++ = '\\'; *p++ = 'b';  break;
1627             case '\t': *p++ = '\\'; *p++ = 't';  break;
1628             case '\v': *p++ = '\\'; *p++ = 'v';  break;
1629             case '\n': *p++ = '\\'; *p++ = 'n';  break;
1630             case '\f': *p++ = '\\'; *p++ = 'f';  break;
1631             case '\r': *p++ = '\\'; *p++ = 'r';  break;
1632             case '\"': *p++ = '\\'; *p++ = '\"';  break;
1633             case '\'': *p++ = '\\'; *p++ = '\'';  break;
1634             case '\\': *p++ = '\\'; *p++ = '\\';  break;
1635             default: 
1636               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1637                 {
1638                   sprintf (p, "\\x%02x", *s); 
1639                   p += 4;
1640                 }
1641               else
1642                 *p++ = *s;
1643             }
1644         }
1645       *p++ = '\"';
1646       return p - dest;
1647     }
1648   else
1649     {
1650       int count = 2;
1651       for (; len; len--, s++ )
1652         {
1653           switch (*s)
1654             {
1655             case '\b': 
1656             case '\t': 
1657             case '\v': 
1658             case '\n': 
1659             case '\f': 
1660             case '\r': 
1661             case '\"':
1662             case '\'':
1663             case '\\': count += 2; break;
1664             default: 
1665               if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1666                 count += 4;
1667               else
1668                 count++;
1669             }
1670         }
1671       return count;
1672     }
1673 }
1674
1675
1676
1677 static int
1678 convert_to_token (const unsigned char *src, size_t len, char *dest)
1679 {
1680   if (dest)
1681     memcpy (dest, src, len);
1682   return len;
1683 }
1684
1685
1686 /****************
1687  * Print SEXP to buffer using the MODE.  Returns the length of the
1688  * SEXP in buffer or 0 if the buffer is too short (We have at least an
1689  * empty list consisting of 2 bytes).  If a buffer of NULL is provided,
1690  * the required length is returned.
1691  */
1692 size_t
1693 gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1694                   void *buffer, size_t maxlength )
1695 {
1696   static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1697   const unsigned char *s;
1698   char *d;
1699   DATALEN n;
1700   char numbuf[20];
1701   size_t len = 0;
1702   int i, indent = 0;
1703   
1704   s = list? list->d : empty;
1705   d = buffer;
1706   while ( *s != ST_STOP )
1707     {
1708       switch ( *s )
1709         {
1710         case ST_OPEN:
1711           s++;
1712           if ( mode != GCRYSEXP_FMT_CANON )
1713             {
1714               if (indent)
1715                 len++; 
1716               len += indent;
1717             }
1718           len++;
1719           if ( buffer ) 
1720             {
1721               if ( len >= maxlength )
1722                 return 0;
1723               if ( mode != GCRYSEXP_FMT_CANON )
1724                 {
1725                   if (indent)
1726                     *d++ = '\n'; 
1727                   for (i=0; i < indent; i++)
1728                     *d++ = ' ';
1729                 }
1730               *d++ = '(';
1731             }
1732           indent++;
1733           break;
1734         case ST_CLOSE:
1735           s++;
1736           len++;
1737           if ( buffer ) 
1738             {
1739               if ( len >= maxlength )
1740                 return 0;
1741               *d++ = ')';
1742             }
1743           indent--;
1744           if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
1745             {
1746               len++;
1747               len += indent;
1748               if (buffer)
1749                 {
1750                   if (len >= maxlength)
1751                     return 0;
1752                   *d++ = '\n';
1753                   for (i=0; i < indent; i++)
1754                     *d++ = ' ';
1755                 }
1756             }
1757           break;
1758         case ST_DATA:
1759           s++;
1760           memcpy ( &n, s, sizeof n ); s += sizeof n;
1761           if (mode == GCRYSEXP_FMT_ADVANCED)
1762             {
1763               int type;
1764               size_t nn;
1765
1766               switch ( (type=suitable_encoding (s, n)))
1767                 {
1768                 case 1: nn = convert_to_string (s, n, NULL); break;
1769                 case 2: nn = convert_to_token (s, n, NULL); break;
1770                 default: nn = convert_to_hex (s, n, NULL); break;
1771                 }
1772               len += nn;
1773               if (buffer)
1774                 {
1775                   if (len >= maxlength)
1776                     return 0;
1777                   switch (type)
1778                     {
1779                     case 1: convert_to_string (s, n, d); break;
1780                     case 2: convert_to_token (s, n, d); break;
1781                     default: convert_to_hex (s, n, d); break;
1782                     }
1783                   d += nn;
1784                 }
1785               if (s[n] != ST_CLOSE)
1786                 {
1787                   len++;
1788                   if (buffer)
1789                     {
1790                       if (len >= maxlength)
1791                         return 0;
1792                       *d++ = ' ';
1793                     }
1794                 }
1795             }
1796           else
1797             {
1798               sprintf (numbuf, "%u:", (unsigned int)n );
1799               len += strlen (numbuf) + n;
1800               if ( buffer ) 
1801                 {
1802                   if ( len >= maxlength )
1803                     return 0;
1804                   d = stpcpy ( d, numbuf );
1805                   memcpy ( d, s, n ); d += n;
1806                 }
1807             }
1808           s += n;
1809           break;
1810         default:
1811           BUG ();
1812         }
1813     }
1814   if ( mode != GCRYSEXP_FMT_CANON )
1815     {
1816       len++;
1817       if (buffer)
1818         {
1819           if ( len >= maxlength )
1820             return 0;
1821           *d++ = '\n'; 
1822         }
1823     }
1824   if (buffer) 
1825     {
1826       if ( len >= maxlength )
1827         return 0;
1828       *d++ = 0; /* for convenience we make a C string */
1829     }
1830   else
1831     len++; /* we need one byte more for this */
1832
1833   return len;
1834 }
1835
1836
1837 /* Scan a cannocial encoded buffer with implicit length values and
1838    return the actual length this S-expression uses.  For a valid S-Exp
1839    it should never return 0.  If LENGTH is not zero, the maximum
1840    length to scan is given - this can be used for syntax checks of
1841    data passed from outside. errorcode and erroff may both be passed as
1842    NULL.  */
1843 size_t
1844 gcry_sexp_canon_len (const unsigned char *buffer, size_t length, 
1845                      size_t *erroff, gcry_error_t *errcode)
1846 {
1847   const unsigned char *p;
1848   const unsigned char *disphint = NULL;
1849   unsigned int datalen = 0;
1850   size_t dummy_erroff;
1851   gcry_error_t dummy_errcode;
1852   size_t count = 0;
1853   int level = 0;
1854
1855   if (!erroff)
1856     erroff = &dummy_erroff;
1857   if (!errcode)
1858     errcode = &dummy_errcode;
1859
1860   *errcode = gcry_error (GPG_ERR_NO_ERROR);
1861   *erroff = 0;
1862   if (!buffer)
1863     return 0;
1864   if (*buffer != '(')
1865     {
1866       *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
1867       return 0;
1868     }
1869
1870   for (p=buffer; ; p++, count++ )
1871     {
1872       if (length && count >= length)
1873         {
1874           *erroff = count;
1875           *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1876           return 0;
1877         }
1878       
1879       if (datalen)
1880         {
1881           if (*p == ':')
1882             {
1883               if (length && (count+datalen) >= length)
1884                 {
1885                   *erroff = count;
1886                   *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1887                   return 0;
1888                 }
1889               count += datalen;
1890               p += datalen;
1891               datalen = 0;
1892             }
1893           else if (digitp(p))
1894             datalen = datalen*10 + atoi_1(p);
1895           else 
1896             {
1897               *erroff = count;
1898               *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
1899               return 0;
1900             }
1901         }
1902       else if (*p == '(')
1903         {
1904           if (disphint)
1905             {
1906               *erroff = count;
1907               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1908               return 0;
1909             }
1910           level++;
1911         }
1912       else if (*p == ')')
1913         { /* walk up */
1914           if (!level)
1915             {
1916               *erroff = count;
1917               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
1918               return 0;
1919             }
1920           if (disphint)
1921             {
1922               *erroff = count;
1923               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1924               return 0;
1925             }
1926           if (!--level)
1927             return ++count; /* ready */
1928         }
1929       else if (*p == '[')
1930         {
1931           if (disphint) 
1932             {
1933               *erroff = count;
1934               *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
1935               return 0;
1936             }
1937           disphint = p;
1938         }
1939       else if (*p == ']')
1940         {
1941           if ( !disphint ) 
1942             {
1943               *erroff = count;
1944               *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1945               return 0;
1946             }
1947           disphint = NULL;
1948         }
1949       else if (digitp (p) )
1950         {
1951           if (*p == '0')
1952             { 
1953               *erroff = count;
1954               *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
1955               return 0;
1956             }
1957           datalen = atoi_1 (p);
1958         }
1959       else if (*p == '&' || *p == '\\')
1960         {
1961           *erroff = count;
1962           *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
1963           return 0;
1964         }
1965       else
1966         { 
1967           *erroff = count;
1968           *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);
1969           return 0;
1970         }
1971     }
1972 }