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