1 /* sexp.c - S-Expression handling
2 * Copyright (C) 1999, 2000, 2001, 2002, 2003,
3 * 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
5 * This file is part of Libgcrypt.
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.
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.
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
31 #define GCRYPT_NO_MPI_MACROS 1
34 typedef struct gcry_sexp *NODE;
35 typedef unsigned short DATALEN;
43 #define ST_DATA 1 /* datalen follows */
44 #define ST_HINT 2 /* datalen follows */
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))
54 #define TOKEN_SPECIALS "-./_:*+="
57 vsexp_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);
62 sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
63 const char *buffer, size_t length, int argflag,
64 void **arg_list, ...);
66 /* Return true if P points to a byte containing a whitespace according
67 to the S-expressions definition. */
69 static GPG_ERR_INLINE int
70 whitespacep (const char *p)
74 case ' ': case '\t': case '\v': case '\f': case '\r': case '\n': return 1;
82 dump_mpi( gcry_mpi_t 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 );
92 fputs( buffer, stderr );
97 dump_string (const byte *p, size_t n, int delim )
101 if ((*p & 0x80) || iscntrl( *p ) || *p == delim )
105 else if( *p == '\r' )
107 else if( *p == '\f' )
109 else if( *p == '\v' )
111 else if( *p == '\b' )
116 log_printf ("\\x%02x", *p );
119 log_printf ("%c", *p);
125 gcry_sexp_dump (const gcry_sexp_t a)
133 log_printf ( "[nil]\n");
138 while ( (type = *p) != ST_STOP )
144 log_printf ("%*s[open]\n", 2*indent, "");
150 log_printf ("%*s[close]\n", 2*indent, "");
154 memcpy ( &n, p, sizeof n );
156 log_printf ("%*s[data=\"", 2*indent, "" );
157 dump_string (p, n, '\"' );
158 log_printf ("\"]\n");
163 log_printf ("%*s[unknown tag %d]\n", 2*indent, "", type);
170 * Pass list through except when it is an empty list - in that case
171 * return NULL and release the passed list.
174 normalize ( gcry_sexp_t list )
184 gcry_sexp_release ( list );
187 if ( *p == ST_OPEN && p[1] == ST_CLOSE )
190 gcry_sexp_release ( list );
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().
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.
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. */
213 gcry_sexp_create (gcry_sexp_t *retsexp, void *buffer, size_t length,
214 int autodetect, void (*freefnc)(void*) )
216 gcry_error_t errcode;
220 return gcry_error (GPG_ERR_INV_ARG);
222 if (autodetect < 0 || autodetect > 1 || !buffer)
223 return gcry_error (GPG_ERR_INV_ARG);
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);
232 else if (!length && autodetect)
233 { /* buffer is a string */
234 length = strlen ((char *)buffer);
237 errcode = sexp_sscan (&se, NULL, buffer, length, 0, NULL);
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. */
251 return gcry_error (GPG_ERR_NO_ERROR);
254 /* Same as gcry_sexp_create but don't transfer ownership */
256 gcry_sexp_new (gcry_sexp_t *retsexp, const void *buffer, size_t length,
259 return gcry_sexp_create (retsexp, (void *)buffer, length, autodetect, NULL);
264 * Release resource of the given SEXP object.
267 gcry_sexp_release( gcry_sexp_t sexp )
271 if (gcry_is_secure (sexp))
273 /* Extra paranoid wiping. */
274 const byte *p = sexp->d;
277 while ( (type = *p) != ST_STOP )
289 memcpy ( &n, p, sizeof n );
298 wipememory (sexp->d, p - sexp->d);
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.
311 gcry_sexp_cons( const gcry_sexp_t a, const gcry_sexp_t b )
316 /* NYI: Implementation should be quite easy with our new data
324 * Make a list from all items in the array the end of the array is marked
328 gcry_sexp_alist( const gcry_sexp_t *array )
332 /* NYI: Implementation should be quite easy with our new data
339 * Make a list from all items, the end of list is indicated by a NULL
342 gcry_sexp_vlist( const gcry_sexp_t a, ... )
345 /* NYI: Implementation should be quite easy with our new data
353 * Append n to the list a
354 * Returns: a new ist (which maybe a)
357 gcry_sexp_append( const gcry_sexp_t a, const gcry_sexp_t n )
361 /* NYI: Implementation should be quite easy with our new data
368 gcry_sexp_prepend( const gcry_sexp_t a, const gcry_sexp_t n )
372 /* NYI: Implementation should be quite easy with our new data
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.
385 gcry_sexp_find_token( const gcry_sexp_t list, const char *tok, size_t toklen )
394 toklen = strlen(tok);
397 while ( *p != ST_STOP )
399 if ( *p == ST_OPEN && p[1] == ST_DATA )
401 const byte *head = p;
404 memcpy ( &n, p, sizeof n );
406 if ( n == toklen && !memcmp( p, tok, toklen ) )
412 /* Look for the end of the list. */
413 for ( p += n; level; p++ )
417 memcpy ( &n, ++p, sizeof n );
419 p--; /* Compensate for later increment. */
421 else if ( *p == ST_OPEN )
425 else if ( *p == ST_CLOSE )
429 else if ( *p == ST_STOP )
436 newlist = gcry_malloc ( sizeof *newlist + n );
439 /* No way to return an error code, so we can only
444 memcpy ( d, head, n ); d += n;
446 return normalize ( newlist );
450 else if ( *p == ST_DATA )
452 memcpy ( &n, ++p, sizeof n ); p += sizeof n;
462 * Return the length of the given list
465 gcry_sexp_length( const gcry_sexp_t list )
477 while ( (type=*p) != ST_STOP ) {
479 if ( type == ST_DATA ) {
480 memcpy ( &n, p, sizeof n );
485 else if ( type == ST_OPEN ) {
490 else if ( type == ST_CLOSE ) {
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. */
502 get_internal_buffer (const gcry_sexp_t list, size_t *r_off)
504 const unsigned char *p;
513 while ( (type=*p) != ST_STOP )
518 memcpy (&n, p, sizeof n);
521 else if (type == ST_OPEN)
524 *r_off = (p-1) - list->d;
527 else if ( type == ST_CLOSE )
535 return 0; /* Not a proper list. */
540 /* Extract the CAR of the given list. May return NULL for bad lists
541 or memory failure. */
543 gcry_sexp_nth( const gcry_sexp_t list, int number )
551 if ( !list || list->d[0] != ST_OPEN )
555 while ( number > 0 ) {
557 if ( *p == ST_DATA ) {
558 memcpy ( &n, ++p, sizeof n );
564 else if ( *p == ST_OPEN ) {
567 else if ( *p == ST_CLOSE ) {
572 else if ( *p == ST_STOP ) {
578 if ( *p == ST_DATA ) {
579 memcpy ( &n, p, sizeof n ); p += sizeof n;
580 newlist = gcry_malloc ( sizeof *newlist + n + 1 );
584 memcpy ( d, p, n ); d += n;
587 else if ( *p == ST_OPEN ) {
588 const byte *head = p;
593 if ( *p == ST_DATA ) {
594 memcpy ( &n, ++p, sizeof n );
598 else if ( *p == ST_OPEN ) {
601 else if ( *p == ST_CLOSE ) {
604 else if ( *p == ST_STOP ) {
610 newlist = gcry_malloc ( sizeof *newlist + n );
614 memcpy ( d, head, n ); d += n;
620 return normalize (newlist);
624 gcry_sexp_car( const gcry_sexp_t list )
626 return gcry_sexp_nth ( list, 0 );
630 /* Helper to get data from the car. The returned value is valid as
631 long as the list is not modified. */
633 sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen)
645 p++; /* Yep, a list. */
647 return NULL; /* Not a list but N > 0 requested. */
649 /* Skip over N elements. */
654 memcpy ( &n, ++p, sizeof n );
660 else if ( *p == ST_OPEN )
664 else if ( *p == ST_CLOSE )
670 else if ( *p == ST_STOP )
677 /* If this is data, return it. */
680 memcpy ( &n, ++p, sizeof n );
682 return (const char*)p + sizeof n;
689 /* Get data from the car. The returned value is valid as long as the
690 list is not modified. */
692 gcry_sexp_nth_data (const gcry_sexp_t list, int number, size_t *datalen )
694 return sexp_nth_data (list, number, datalen);
698 /* Get a string from the car. The returned value is a malloced string
699 and needs to be freed by the caller. */
701 gcry_sexp_nth_string (const gcry_sexp_t list, int number)
707 s = sexp_nth_data (list, number, &n);
708 if (!s || n < 1 || (n+1) < 1)
710 buf = gcry_malloc (n+1);
719 * Get a MPI from the car
722 gcry_sexp_nth_mpi( gcry_sexp_t list, int number, int mpifmt )
729 mpifmt = GCRYMPI_FMT_STD;
731 s = sexp_nth_data (list, number, &n);
735 if ( gcry_mpi_scan ( &a, mpifmt, s, n, NULL ) )
746 gcry_sexp_cdr( const gcry_sexp_t list )
756 if ( !list || list->d[0] != ST_OPEN )
762 if ( *p == ST_DATA ) {
763 memcpy ( &n, ++p, sizeof n );
769 else if ( *p == ST_OPEN ) {
772 else if ( *p == ST_CLOSE ) {
777 else if ( *p == ST_STOP ) {
786 if ( *p == ST_DATA ) {
787 memcpy ( &n, ++p, sizeof n );
791 else if ( *p == ST_OPEN ) {
794 else if ( *p == ST_CLOSE ) {
797 else if ( *p == ST_STOP ) {
804 newlist = gcry_malloc ( sizeof *newlist + n + 2 );
809 memcpy ( d, head, n ); d += n;
813 return normalize (newlist);
817 gcry_sexp_cadr ( const gcry_sexp_t list )
821 a = gcry_sexp_cdr ( list );
822 b = gcry_sexp_car ( a );
823 gcry_sexp_release ( a );
830 hextobyte( const byte *s )
834 if( *s >= '0' && *s <= '9' )
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');
842 if( *s >= '0' && *s <= '9' )
844 else if( *s >= 'A' && *s <= 'F' )
846 else if( *s >= 'a' && *s <= 'f' ) {
852 struct make_space_ctx {
858 static gpg_err_code_t
859 make_space ( struct make_space_ctx *c, size_t n )
861 size_t used = c->pos - c->sexp->d;
863 if ( used + n + sizeof(DATALEN) + 1 >= c->allocated )
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);
874 return gpg_err_code_from_errno (errno);
875 c->allocated = newsize;
876 newhead = newsexp->d;
877 c->pos = newhead + used;
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. */
888 unquote_string (const char *string, size_t length, unsigned char *buf)
891 const unsigned char *s = (const unsigned char*)string;
892 unsigned char *d = buf;
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;
911 case '\r': /* ignore CR[,LF] */
912 if (n>1 && s[1] == '\n')
918 case '\n': /* ignore LF[,CR] */
919 if (n>1 && s[1] == '\r')
925 case 'x': /* hex value */
926 if (n>2 && hexdigitp (s+1) && hexdigitp (s+2))
935 if (n>2 && octdigitp (s) && octdigitp (s+1) && octdigitp (s+2))
937 *d++ = (atoi_1 (s)*64) + (atoi_1 (s+1)*8) + atoi_1 (s+2);
945 else if( *s == '\\' )
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
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
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.
980 vsexp_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)
984 gcry_err_code_t err = 0;
985 static const char tokenchars[] =
986 "abcdefghijklmnopqrstuvwxyz"
987 "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
988 "0123456789-./_:*+=";
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;
1001 size_t dummy_erroff;
1002 struct make_space_ctx c;
1003 int arg_counter = 0;
1007 erroff = &dummy_erroff;
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) \
1016 storage = va_arg (arg_ptr, type); \
1018 storage = *((type *) (arg_list[arg_counter++])); \
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)); \
1031 *erroff = p - buffer; \
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); \
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);
1050 c.sexp = gcry_malloc (sizeof *c.sexp + c.allocated - 1);
1053 err = gpg_err_code_from_errno (errno);
1059 for (p = buffer, n = length; n; p++, n--)
1061 if (tokenp && !hexfmt)
1063 if (strchr (tokenchars, *p))
1067 datalen = p - tokenp;
1068 MAKE_SPACE (datalen);
1070 STORE_LEN (c.pos, datalen);
1071 memcpy (c.pos, tokenp, datalen);
1083 case 'b': case 't': case 'v': case 'n': case 'f':
1084 case 'r': case '"': case '\'': case '\\':
1088 case '0': case '1': case '2': case '3': case '4':
1089 case '5': case '6': case '7':
1091 && (p[1] >= '0') && (p[1] <= '7')
1092 && (p[2] >= '0') && (p[2] <= '7')))
1094 *erroff = p - buffer;
1095 /* Invalid octal value. */
1096 err = GPG_ERR_SEXP_BAD_QUOTATION;
1105 if (!((n > 2) && hexdigitp (p+1) && hexdigitp (p+2)))
1107 *erroff = p - buffer;
1108 /* Invalid hex value. */
1109 err = GPG_ERR_SEXP_BAD_QUOTATION;
1118 /* ignore CR[,LF] */
1119 if (n && (p[1] == '\n'))
1128 /* ignore LF[,CR] */
1129 if (n && (p[1] == '\r'))
1138 *erroff = p - buffer;
1139 /* Invalid quoted string escape. */
1140 err = GPG_ERR_SEXP_BAD_QUOTATION;
1144 else if (*p == '\\')
1146 else if (*p == '\"')
1148 /* Keep it easy - we know that the unquoted string will
1150 unsigned char *save;
1153 quoted++; /* Skip leading quote. */
1154 MAKE_SPACE (p - quoted);
1157 STORE_LEN (c.pos, 0); /* Will be fixed up later. */
1158 len = unquote_string (quoted, p - quoted, c.pos);
1160 STORE_LEN (save, len);
1172 *erroff = p - buffer;
1173 err = GPG_ERR_SEXP_ODD_HEX_NUMBERS;
1177 datalen = hexcount / 2;
1178 MAKE_SPACE (datalen);
1180 STORE_LEN (c.pos, datalen);
1181 for (hexfmt++; hexfmt < p; hexfmt++)
1183 if (whitespacep (hexfmt))
1185 *c.pos++ = hextobyte ((const unsigned char*)hexfmt);
1190 else if (!whitespacep (p))
1192 *erroff = p - buffer;
1193 err = GPG_ERR_SEXP_BAD_HEX_CHAR;
1208 datalen = atoi (digptr); /* FIXME: check for overflow. */
1210 if (datalen > n - 1)
1212 *erroff = p - buffer;
1213 /* Buffer too short. */
1214 err = GPG_ERR_SEXP_STRING_TOO_LONG;
1217 /* Make a new list entry. */
1218 MAKE_SPACE (datalen);
1220 STORE_LEN (c.pos, datalen);
1221 memcpy (c.pos, p + 1, datalen);
1226 else if (*p == '\"')
1228 digptr = NULL; /* We ignore the optional length. */
1234 digptr = NULL; /* We ignore the optional length. */
1240 digptr = NULL; /* We ignore the optional length. */
1245 *erroff = p - buffer;
1246 err = GPG_ERR_SEXP_INV_LEN_SPEC;
1254 /* Insert an MPI. */
1258 ARG_NEXT (m, gcry_mpi_t);
1260 if (gcry_mpi_get_flag (m, GCRYMPI_FLAG_OPAQUE))
1265 mp = gcry_mpi_get_opaque (m, &nbits);
1270 if (!gcry_is_secure (c.sexp->d)
1271 && gcry_mpi_get_flag (m, GCRYMPI_FLAG_SECURE))
1273 /* We have to switch to secure allocation. */
1274 gcry_sexp_t newsexp;
1277 newsexp = gcry_malloc_secure (sizeof *newsexp
1281 err = gpg_err_code_from_errno (errno);
1284 newhead = newsexp->d;
1285 memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1286 c.pos = newhead + (c.pos - c.sexp->d);
1292 STORE_LEN (c.pos, nm);
1293 memcpy (c.pos, mp, nm);
1299 if (gcry_mpi_print (GCRYMPI_FMT_STD, NULL, 0, &nm, m))
1303 if (!gcry_is_secure (c.sexp->d)
1304 && gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE))
1306 /* We have to switch to secure allocation. */
1307 gcry_sexp_t newsexp;
1310 newsexp = gcry_malloc_secure (sizeof *newsexp
1314 err = gpg_err_code_from_errno (errno);
1317 newhead = newsexp->d;
1318 memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1319 c.pos = newhead + (c.pos - c.sexp->d);
1325 STORE_LEN (c.pos, nm);
1326 if (gcry_mpi_print (GCRYMPI_FMT_STD, c.pos, nm, &nm, m))
1333 /* Insert an string. */
1337 ARG_NEXT (astr, const char *);
1338 alen = strlen (astr);
1342 STORE_LEN (c.pos, alen);
1343 memcpy (c.pos, astr, alen);
1348 /* Insert a memory buffer. */
1352 ARG_NEXT (alen, int);
1353 ARG_NEXT (astr, const char *);
1357 && !gcry_is_secure (c.sexp->d)
1358 && gcry_is_secure (astr))
1360 /* We have to switch to secure allocation. */
1361 gcry_sexp_t newsexp;
1364 newsexp = gcry_malloc_secure (sizeof *newsexp
1368 err = gpg_err_code_from_errno (errno);
1371 newhead = newsexp->d;
1372 memcpy (newhead, c.sexp->d, (c.pos - c.sexp->d));
1373 c.pos = newhead + (c.pos - c.sexp->d);
1379 STORE_LEN (c.pos, alen);
1380 memcpy (c.pos, astr, alen);
1385 /* Insert an integer as string. */
1390 ARG_NEXT (aint, int);
1391 sprintf (buf, "%d", aint);
1392 alen = strlen (buf);
1395 STORE_LEN (c.pos, alen);
1396 memcpy (c.pos, buf, alen);
1401 /* Insert a gcry_sexp_t. */
1405 ARG_NEXT (asexp, gcry_sexp_t);
1406 alen = get_internal_buffer (asexp, &aoff);
1410 memcpy (c.pos, asexp->d + aoff, alen);
1416 *erroff = p - buffer;
1417 /* Invalid format specifier. */
1418 err = GPG_ERR_SEXP_INV_LEN_SPEC;
1427 *erroff = p - buffer;
1428 /* Open display hint. */
1429 err = GPG_ERR_SEXP_UNMATCHED_DH;
1441 *erroff = p - buffer;
1442 /* Open display hint. */
1443 err = GPG_ERR_SEXP_UNMATCHED_DH;
1447 *c.pos++ = ST_CLOSE;
1450 else if (*p == '\"')
1466 *erroff = p - buffer;
1467 /* Open display hint. */
1468 err = GPG_ERR_SEXP_NESTED_DH;
1477 *erroff = p - buffer;
1478 /* Open display hint. */
1479 err = GPG_ERR_SEXP_UNMATCHED_DH;
1484 else if (digitp (p))
1488 /* A length may not begin with zero. */
1489 *erroff = p - buffer;
1490 err = GPG_ERR_SEXP_ZERO_PREFIX;
1495 else if (strchr (tokenchars, *p))
1497 else if (whitespacep (p))
1501 /* fixme: handle rescanning: we can do this by saving our
1502 current state and start over at p+1 -- Hmmm. At this
1503 point here we are in a well defined state, so we don't
1504 need to save it. Great. */
1505 *erroff = p - buffer;
1506 err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1509 else if (strchr ("&\\", *p))
1511 /* Reserved punctuation. */
1512 *erroff = p - buffer;
1513 err = GPG_ERR_SEXP_UNEXPECTED_PUNC;
1516 else if (argflag && (*p == '%'))
1520 /* Bad or unavailable. */
1521 *erroff = p - buffer;
1522 err = GPG_ERR_SEXP_BAD_CHARACTER;
1530 err = GPG_ERR_SEXP_UNMATCHED_PAREN;
1535 /* Error -> deallocate. */
1538 /* Extra paranoid wipe on error. */
1539 if (gcry_is_secure (c.sexp))
1540 wipememory (c.sexp, sizeof (struct gcry_sexp) + c.allocated - 1);
1543 /* This might be expected by existing code... */
1547 *retsexp = normalize (c.sexp);
1549 return gcry_error (err);
1556 sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1557 const char *buffer, size_t length, int argflag,
1558 void **arg_list, ...)
1563 va_start (arg_ptr, arg_list);
1564 rc = vsexp_sscan (retsexp, erroff, buffer, length, argflag,
1573 gcry_sexp_build (gcry_sexp_t *retsexp, size_t *erroff, const char *format, ...)
1578 va_start (arg_ptr, format);
1579 rc = vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1588 _gcry_sexp_vbuild (gcry_sexp_t *retsexp, size_t *erroff,
1589 const char *format, va_list arg_ptr)
1591 return vsexp_sscan (retsexp, erroff, format, strlen(format), 1,
1596 /* Like gcry_sexp_build, but uses an array instead of variable
1597 function arguments. */
1599 gcry_sexp_build_array (gcry_sexp_t *retsexp, size_t *erroff,
1600 const char *format, void **arg_list)
1602 return sexp_sscan (retsexp, erroff, format, strlen(format), 1, arg_list);
1607 gcry_sexp_sscan (gcry_sexp_t *retsexp, size_t *erroff,
1608 const char *buffer, size_t length)
1610 return sexp_sscan (retsexp, erroff, buffer, length, 0, NULL);
1614 /* Figure out a suitable encoding for BUFFER of LENGTH.
1620 suitable_encoding (const unsigned char *buffer, size_t length)
1622 const unsigned char *s;
1623 int maybe_token = 1;
1628 for (s=buffer; length; s++, length--)
1630 if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0))
1631 && !strchr ("\b\t\v\n\f\r\"\'\\", *s))
1632 return 0; /*binary*/
1634 && !alphap (s) && !digitp (s) && !strchr (TOKEN_SPECIALS, *s))
1638 if ( maybe_token && !digitp (s) )
1645 convert_to_hex (const unsigned char *src, size_t len, char *dest)
1652 for (i=0; i < len; i++, dest += 2 )
1653 sprintf (dest, "%02X", src[i]);
1660 convert_to_string (const unsigned char *s, size_t len, char *dest)
1666 for (; len; len--, s++ )
1670 case '\b': *p++ = '\\'; *p++ = 'b'; break;
1671 case '\t': *p++ = '\\'; *p++ = 't'; break;
1672 case '\v': *p++ = '\\'; *p++ = 'v'; break;
1673 case '\n': *p++ = '\\'; *p++ = 'n'; break;
1674 case '\f': *p++ = '\\'; *p++ = 'f'; break;
1675 case '\r': *p++ = '\\'; *p++ = 'r'; break;
1676 case '\"': *p++ = '\\'; *p++ = '\"'; break;
1677 case '\'': *p++ = '\\'; *p++ = '\''; break;
1678 case '\\': *p++ = '\\'; *p++ = '\\'; break;
1680 if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1682 sprintf (p, "\\x%02x", *s);
1695 for (; len; len--, s++ )
1707 case '\\': count += 2; break;
1709 if ( (*s < 0x20 || (*s >= 0x7f && *s <= 0xa0)))
1722 convert_to_token (const unsigned char *src, size_t len, char *dest)
1725 memcpy (dest, src, len);
1731 * Print SEXP to buffer using the MODE. Returns the length of the
1732 * SEXP in buffer or 0 if the buffer is too short (We have at least an
1733 * empty list consisting of 2 bytes). If a buffer of NULL is provided,
1734 * the required length is returned.
1737 gcry_sexp_sprint (const gcry_sexp_t list, int mode,
1738 void *buffer, size_t maxlength )
1740 static unsigned char empty[3] = { ST_OPEN, ST_CLOSE, ST_STOP };
1741 const unsigned char *s;
1748 s = list? list->d : empty;
1750 while ( *s != ST_STOP )
1756 if ( mode != GCRYSEXP_FMT_CANON )
1765 if ( len >= maxlength )
1767 if ( mode != GCRYSEXP_FMT_CANON )
1771 for (i=0; i < indent; i++)
1783 if ( len >= maxlength )
1788 if (*s != ST_OPEN && *s != ST_STOP && mode != GCRYSEXP_FMT_CANON)
1794 if (len >= maxlength)
1797 for (i=0; i < indent; i++)
1804 memcpy ( &n, s, sizeof n ); s += sizeof n;
1805 if (mode == GCRYSEXP_FMT_ADVANCED)
1810 switch ( (type=suitable_encoding (s, n)))
1812 case 1: nn = convert_to_string (s, n, NULL); break;
1813 case 2: nn = convert_to_token (s, n, NULL); break;
1814 default: nn = convert_to_hex (s, n, NULL); break;
1819 if (len >= maxlength)
1823 case 1: convert_to_string (s, n, d); break;
1824 case 2: convert_to_token (s, n, d); break;
1825 default: convert_to_hex (s, n, d); break;
1829 if (s[n] != ST_CLOSE)
1834 if (len >= maxlength)
1842 sprintf (numbuf, "%u:", (unsigned int)n );
1843 len += strlen (numbuf) + n;
1846 if ( len >= maxlength )
1848 d = stpcpy ( d, numbuf );
1849 memcpy ( d, s, n ); d += n;
1858 if ( mode != GCRYSEXP_FMT_CANON )
1863 if ( len >= maxlength )
1870 if ( len >= maxlength )
1872 *d++ = 0; /* for convenience we make a C string */
1875 len++; /* we need one byte more for this */
1881 /* Scan a canonical encoded buffer with implicit length values and
1882 return the actual length this S-expression uses. For a valid S-Exp
1883 it should never return 0. If LENGTH is not zero, the maximum
1884 length to scan is given - this can be used for syntax checks of
1885 data passed from outside. errorcode and erroff may both be passed as
1888 gcry_sexp_canon_len (const unsigned char *buffer, size_t length,
1889 size_t *erroff, gcry_error_t *errcode)
1891 const unsigned char *p;
1892 const unsigned char *disphint = NULL;
1893 unsigned int datalen = 0;
1894 size_t dummy_erroff;
1895 gcry_error_t dummy_errcode;
1900 erroff = &dummy_erroff;
1902 errcode = &dummy_errcode;
1904 *errcode = gcry_error (GPG_ERR_NO_ERROR);
1910 *errcode = gcry_error (GPG_ERR_SEXP_NOT_CANONICAL);
1914 for (p=buffer; ; p++, count++ )
1916 if (length && count >= length)
1919 *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1927 if (length && (count+datalen) >= length)
1930 *errcode = gcry_error (GPG_ERR_SEXP_STRING_TOO_LONG);
1938 datalen = datalen*10 + atoi_1(p);
1942 *errcode = gcry_error (GPG_ERR_SEXP_INV_LEN_SPEC);
1951 *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1961 *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_PAREN);
1967 *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1971 return ++count; /* ready */
1978 *errcode = gcry_error (GPG_ERR_SEXP_NESTED_DH);
1988 *errcode = gcry_error (GPG_ERR_SEXP_UNMATCHED_DH);
1993 else if (digitp (p) )
1998 *errcode = gcry_error (GPG_ERR_SEXP_ZERO_PREFIX);
2001 datalen = atoi_1 (p);
2003 else if (*p == '&' || *p == '\\')
2006 *errcode = gcry_error (GPG_ERR_SEXP_UNEXPECTED_PUNC);
2012 *errcode = gcry_error (GPG_ERR_SEXP_BAD_CHARACTER);