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