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