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