summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cipher/pubkey.c24
-rw-r--r--mpi/ChangeLog4
-rw-r--r--mpi/mpicoder.c20
-rw-r--r--src/ChangeLog9
-rw-r--r--src/Makefile.am3
-rw-r--r--src/gcrypt.h37
-rw-r--r--src/sexp.c458
-rw-r--r--src/testapi.c23
8 files changed, 270 insertions, 308 deletions
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 7ef6f18b..15487ad6 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -701,16 +701,9 @@ sexp_to_key( GCRY_SEXP sexp, int want_private, MPI **retarray, int *retalgo)
:"public-key", 0 );
if( !list )
return GCRYERR_INV_OBJ; /* Does not contain a public- or private-key object */
- l2 = gcry_sexp_cdr( list );
- gcry_sexp_release ( list );
- list = l2;
- if( !list )
- return GCRYERR_NO_OBJ; /* no cdr for the key object */
- l2 = gcry_sexp_car( list );
+ l2 = gcry_sexp_cadr( list );
gcry_sexp_release ( list );
list = l2;
- if( !list )
- return GCRYERR_NO_OBJ; /* no car for the key object */
name = gcry_sexp_car_data( list, &n );
if( !name ) {
gcry_sexp_release ( list );
@@ -873,7 +866,7 @@ sexp_to_enc( GCRY_SEXP sexp, MPI **retarray, int *retalgo)
list = gcry_sexp_find_token( sexp, "enc-val" , 0 );
if( !list )
return GCRYERR_INV_OBJ; /* Does not contain a encrypted value object */
- l2 = gcry_sexp_cdr( list );
+ l2 = gcry_sexp_cadr( list );
gcry_sexp_release ( list );
list = l2;
if( !list ) {
@@ -1332,7 +1325,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
list = gcry_sexp_find_token( s_parms, "genkey", 0 );
if( !list )
return GCRYERR_INV_OBJ; /* Does not contain genkey data */
- l2 = gcry_sexp_cdr( list );
+ l2 = gcry_sexp_cadr( list );
gcry_sexp_release ( list );
list = l2;
if( !list )
@@ -1402,7 +1395,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
/* build the string */
nelem = 0;
string = p = g10_xmalloc ( needed );
- p = stpcpy ( p, "(key-data(" );
+ p = stpcpy ( p, "(key-data" );
p = stpcpy ( p, "(public-key(" );
p = stpcpy ( p, algo_name );
@@ -1412,7 +1405,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
p = stpcpy ( p, "%m)" );
mpis[nelem++] = skey[i];
}
- strcpy ( p, "))" );
+ p = stpcpy ( p, "))" );
p = stpcpy ( p, "(private-key(" );
p = stpcpy ( p, algo_name );
@@ -1422,14 +1415,14 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
p = stpcpy ( p, "%m)" );
mpis[nelem++] = skey[i];
}
- strcpy ( p, "))" );
+ p = stpcpy ( p, "))" );
p = stpcpy ( p, "(misc-key-info(pm1-factors" );
for(i=0; factors[i]; i++ ) {
p = stpcpy ( p, "%m" );
mpis[nelem++] = factors[i];
}
- strcpy ( p, "))" );
+ strcpy ( p, ")))" );
while ( nelem < DIM(mpis) )
mpis[nelem++] = NULL;
@@ -1439,6 +1432,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
* we have. which normally should be no problem as only those
* with a corresponding %m are used
*/
+ log_debug ("retstr=`%s'\n", string);
if ( gcry_sexp_build ( r_key, NULL, string,
mpis[0], mpis[1], mpis[2], mpis[3], mpis[4], mpis[5],
mpis[6], mpis[7], mpis[8], mpis[9], mpis[10], mpis[11],
@@ -1447,7 +1441,7 @@ gcry_pk_genkey( GCRY_SEXP *r_key, GCRY_SEXP s_parms )
mpis[24], mpis[25], mpis[26], mpis[27], mpis[28], mpis[29]
) )
BUG ();
- assert ( DIM(mpis) == 29 );
+ assert ( DIM(mpis) == 30 );
g10_free ( string );
}
release_mpi_array ( skey );
diff --git a/mpi/ChangeLog b/mpi/ChangeLog
index 6bdeaf25..97ae3cd2 100644
--- a/mpi/ChangeLog
+++ b/mpi/ChangeLog
@@ -1,3 +1,7 @@
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * mpicoder.c (gcry_mpi_scan): Normalize the returned MPI.
+
Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
* config.links: Support for powerpc--netbsd by Gabriel Rosenkoetter.
diff --git a/mpi/mpicoder.c b/mpi/mpicoder.c
index bd79aca5..9c68d7c9 100644
--- a/mpi/mpicoder.c
+++ b/mpi/mpicoder.c
@@ -355,8 +355,10 @@ gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
else
mpi_set_buffer( a, s, len, 0 );
}
- if( ret_mpi )
+ if( ret_mpi ) {
+ mpi_normalize ( a );
*ret_mpi = a;
+ }
else
mpi_free(a);
return 0;
@@ -365,8 +367,10 @@ gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
a = mpi_alloc( (len+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
if( len ) /* not zero */
mpi_set_buffer( a, buffer, len, 0 );
- if( ret_mpi )
+ if( ret_mpi ) {
+ mpi_normalize ( a );
*ret_mpi = a;
+ }
else
mpi_free(a);
return 0;
@@ -375,8 +379,10 @@ gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
a = mpi_read_from_buffer( (char*)buffer, &len, 0 );
if( nbytes )
*nbytes = len;
- if( ret_mpi )
+ if( ret_mpi ) {
+ mpi_normalize ( a );
*ret_mpi = a;
+ }
else
mpi_free(a);
return a? 0 : GCRYERR_INV_OBJ;
@@ -405,8 +411,10 @@ gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
}
if( nbytes )
*nbytes = n+4;
- if( ret_mpi )
+ if( ret_mpi ) {
+ mpi_normalize ( a );
*ret_mpi = a;
+ }
else
mpi_free(a);
return 0;
@@ -417,8 +425,10 @@ gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
a = mpi_alloc(0);
if( mpi_fromstr( a, buffer ) )
return GCRYERR_INV_OBJ;
- if( ret_mpi )
+ if( ret_mpi ) {
+ mpi_normalize ( a );
*ret_mpi = a;
+ }
else
mpi_free(a);
return 0;
diff --git a/src/ChangeLog b/src/ChangeLog
index e0818eb2..f7973e2d 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,12 @@
+Fri Jul 28 18:19:11 CEST 2000 Werner Koch <wk@openit.de>
+
+ * sexp.c (sexp_sscan): Fixed reallocation to secure memory.
+ (new_empty_list): Removed
+ (gcry_sexp_length): New.
+ (gcry_sexp_enum): Removed.
+ (normalize): New. Reworked the whole thing to use NULL for an empty list.
+ (make_space): New instead of the macro.
+
Tue Jul 25 17:44:15 CEST 2000 Werner Koch <wk@openit.de>
* sexp.c: Major rewrite.
diff --git a/src/Makefile.am b/src/Makefile.am
index fd1182c9..2c1aa9ad 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -32,7 +32,8 @@ libgcrypt_la_SOURCES = g10lib.h \
secmem.c \
secmem.h
-libgcrypt_la_DEPENDENCIES = libgcrypt.sym
+libgcrypt_la_DEPENDENCIES = libgcrypt.sym \
+ ../cipher/libcipher.la ../mpi/libmpi.la
libgcrypt_la_LIBADD = ../cipher/libcipher.la \
../mpi/libmpi.la
diff --git a/src/gcrypt.h b/src/gcrypt.h
index a362ec25..d11ea3fa 100644
--- a/src/gcrypt.h
+++ b/src/gcrypt.h
@@ -153,36 +153,29 @@ enum gcry_sexp_format {
void gcry_sexp_release( GCRY_SEXP sexp );
-void gcry_sexp_dump( GCRY_SEXP a );
-GCRY_SEXP gcry_sexp_cons( GCRY_SEXP a, GCRY_SEXP b );
-GCRY_SEXP gcry_sexp_alist( GCRY_SEXP *array );
-GCRY_SEXP gcry_sexp_vlist( GCRY_SEXP a, ... );
-GCRY_SEXP gcry_sexp_append( GCRY_SEXP a, GCRY_SEXP n );
-GCRY_SEXP gcry_sexp_prepend( GCRY_SEXP a, GCRY_SEXP n );
+void gcry_sexp_dump( const GCRY_SEXP a );
+GCRY_SEXP gcry_sexp_cons( const GCRY_SEXP a, const GCRY_SEXP b );
+GCRY_SEXP gcry_sexp_alist( const GCRY_SEXP *array );
+GCRY_SEXP gcry_sexp_vlist( const GCRY_SEXP a, ... );
+GCRY_SEXP gcry_sexp_append( const GCRY_SEXP a, const GCRY_SEXP n );
+GCRY_SEXP gcry_sexp_prepend( const GCRY_SEXP a, const GCRY_SEXP n );
int gcry_sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff,
const char *buffer, size_t length );
int gcry_sexp_build( GCRY_SEXP *retsexp, size_t *erroff,
const char *format, ... );
size_t gcry_sexp_sprint( GCRY_SEXP sexp, int mode, char *buffer,
size_t maxlength );
+int gcry_sexp_length( const GCRY_SEXP list );
GCRY_SEXP gcry_sexp_find_token( GCRY_SEXP list,
const char *tok, size_t toklen );
-GCRY_SEXP gcry_sexp_enum( GCRY_SEXP list, void **context, int mode );
-GCRY_SEXP gcry_sexp_car( GCRY_SEXP list );
-GCRY_SEXP gcry_sexp_cdr( GCRY_SEXP list );
-const char *gcry_sexp_car_data( GCRY_SEXP list, size_t *datalen );
-const char *gcry_sexp_cdr_data( GCRY_SEXP list, size_t *datalen );
-GCRY_MPI gcry_sexp_car_mpi( GCRY_SEXP list, int mpifmt );
-GCRY_MPI gcry_sexp_cdr_mpi( GCRY_SEXP list, int mpifmt );
-
-
-
-#ifndef GCRYPT_NO_SEXP_MACROS
-#define SEXP GCRY_SEXP
-#define SEXP_NEW(a,b) gcry_sexp_new_data( (a), (b) )
-#define SEXP_RELEASE(a) do { gcry_sexp_release( (a) ); (a)=NULL; } while(0)
-#define SEXP_CONS(a,b) gcry_sexp_cons((a),(b))
-#endif /*GCRYPT_NO_SEXP_MACROS*/
+GCRY_SEXP gcry_sexp_car( const GCRY_SEXP list );
+GCRY_SEXP gcry_sexp_cadr( const GCRY_SEXP list );
+GCRY_SEXP gcry_sexp_cdr( const GCRY_SEXP list );
+const char *gcry_sexp_car_data( const GCRY_SEXP list, size_t *datalen );
+const char *gcry_sexp_cdr_data( const GCRY_SEXP list, size_t *datalen );
+GCRY_MPI gcry_sexp_car_mpi( const GCRY_SEXP list, int mpifmt );
+GCRY_MPI gcry_sexp_cdr_mpi( const GCRY_SEXP list, int mpifmt );
+
/*******************************************
* *
diff --git a/src/sexp.c b/src/sexp.c
index e62ade9c..cc129197 100644
--- a/src/sexp.c
+++ b/src/sexp.c
@@ -64,7 +64,7 @@ static void
dump_string( FILE *fp, const byte *p, size_t n, int delim )
{
for( ; n; n--, p++ )
- if( iscntrl( *p ) || *p == delim ) {
+ if( (*p & 0x80) || iscntrl( *p ) || *p == delim ) {
putc('\\', fp);
if( *p == '\n' )
putc('n', fp);
@@ -87,7 +87,7 @@ dump_string( FILE *fp, const byte *p, size_t n, int delim )
void
-gcry_sexp_dump( GCRY_SEXP a )
+gcry_sexp_dump( const GCRY_SEXP a )
{
const byte *p;
DATALEN n;
@@ -95,7 +95,7 @@ gcry_sexp_dump( GCRY_SEXP a )
int type;
if ( !a ) {
- fputs ( "[NULL]\n", stderr );
+ fputs ( "[nil]\n", stderr );
return;
}
@@ -133,7 +133,30 @@ gcry_sexp_dump( GCRY_SEXP a )
}
}
+/****************
+ * Pass list thru expcept when it is an empty list in taht case
+ * return NULL and release the passed list.
+ */
+static GCRY_SEXP
+normalize ( GCRY_SEXP list )
+{
+ char *p;
+ if ( !list )
+ return NULL;
+ p = list->d;
+ if ( *p == ST_STOP ) {
+ /* this is "" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+ if( *p == ST_OPEN && p[1+sizeof(DATALEN)] == ST_CLOSE ) {
+ /* this is "()" */
+ gcry_sexp_release ( list );
+ return NULL;
+ }
+ return list;
+}
/****************
* Release resource of the given SEXP object.
@@ -145,30 +168,13 @@ gcry_sexp_release( GCRY_SEXP sexp )
}
-static GCRY_SEXP
-new_empty_list ( void )
-{
- GCRY_SEXP newlist;
- byte *p;
- DATALEN n;
-
- newlist = g10_xmalloc ( sizeof *newlist + 3 + sizeof(DATALEN) - 1 );
- p = newlist->d;
- *p++ = ST_OPEN;
- n = 1; /* the close is the only element */
- memcpy ( p, &n, sizeof n ); p += sizeof n;
- *p++ = ST_CLOSE;
- *p++ = ST_STOP;
- return newlist;
-}
-
/****************
* Make a pair from lists a and b, don't use a or b later on.
* Special behaviour: If one is a single element list we put the
* element straight into the new pair.
*/
GCRY_SEXP
-gcry_sexp_cons( GCRY_SEXP a, GCRY_SEXP b )
+gcry_sexp_cons( const GCRY_SEXP a, const GCRY_SEXP b )
{
/* NYI: Implementation should be quite easy with our new data representation */
BUG ();
@@ -181,7 +187,7 @@ gcry_sexp_cons( GCRY_SEXP a, GCRY_SEXP b )
* with a NULL. y a NULL
*/
GCRY_SEXP
-gcry_sexp_alist( GCRY_SEXP *array )
+gcry_sexp_alist( const GCRY_SEXP *array )
{
/* NYI: Implementaion should be quite easy with our new data representation */
BUG ();
@@ -192,7 +198,7 @@ gcry_sexp_alist( GCRY_SEXP *array )
* Make a list from all items, the end of list is indicated by a NULL
*/
GCRY_SEXP
-gcry_sexp_vlist( GCRY_SEXP a, ... )
+gcry_sexp_vlist( const GCRY_SEXP a, ... )
{
/* NYI: Implementaion should be quite easy with our new data representation */
BUG ();
@@ -205,7 +211,7 @@ gcry_sexp_vlist( GCRY_SEXP a, ... )
* Returns: a new ist (which maybe a)
*/
GCRY_SEXP
-gcry_sexp_append( GCRY_SEXP a, GCRY_SEXP n )
+gcry_sexp_append( const GCRY_SEXP a, const GCRY_SEXP n )
{
/* NYI: Implementaion should be quite easy with our new data representation */
BUG ();
@@ -213,7 +219,7 @@ gcry_sexp_append( GCRY_SEXP a, GCRY_SEXP n )
}
GCRY_SEXP
-gcry_sexp_prepend( GCRY_SEXP a, GCRY_SEXP n )
+gcry_sexp_prepend( const GCRY_SEXP a, const GCRY_SEXP n )
{
/* NYI: Implementaion should be quite easy with our new data representation */
BUG ();
@@ -227,16 +233,20 @@ gcry_sexp_prepend( GCRY_SEXP a, GCRY_SEXP n )
* Returns: A new list with this sublist or NULL if not found.
*/
GCRY_SEXP
-gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
+gcry_sexp_find_token( const GCRY_SEXP list, const char *tok, size_t toklen )
{
- byte *p = list->d;
+ const byte *p;
DATALEN n;
int type;
+ if ( !list )
+ return NULL;
+
if( !toklen )
toklen = strlen(tok);
+ p = list->d;
while ( (type=*p) != ST_STOP ) {
- byte *head = p;
+ const byte *head = p;
DATALEN headlen;
p++;
@@ -249,7 +259,7 @@ gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
headlen = n + 1 + sizeof(DATALEN);
if ( type == ST_OPEN ) {
int type2 = *p;
- byte *pp = p+1;
+ const byte *pp = p+1;
DATALEN nn;
memcpy ( &nn, pp, sizeof nn );
@@ -260,7 +270,7 @@ gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
memcpy ( sexp->d, head, headlen );
sexp->d[headlen] = ST_CLOSE;
sexp->d[headlen+1] = ST_STOP;
- return sexp;
+ return normalize ( sexp );
}
}
p = pp + nn;
@@ -272,51 +282,33 @@ gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
return NULL;
}
-
/****************
- * Enumerate all objects in the list. Ther first time you call this, pass
- * the address of a void pointer initialized to NULL. Then don't touch this
- * variable anymore but pass it verbatim to the function; you will get
- * all lists back in turn. End of lists is indicated by a returned NIL in
- * which case you should not continue to use this function
- * (it would wrap around). If you decide to cancel the operation before
- * the final NIL you have to release the context by calling the function
- * with a the context but a LIST set to NULL.
- * Note that this function returns only lists and not single objects.
+ * return the length of the given list
*/
-GCRY_SEXP
-gcry_sexp_enum( GCRY_SEXP list, void **context, int mode )
+int
+gcry_sexp_length( const GCRY_SEXP list )
{
- return NULL;
- #warning gcry_sexp_enum is not implemented
- #if 0
- NODE node;
-
- if( mode )
- return NULL; /* mode is reserved and must be 0 */
- if( !list ) {
- /* we are lucky that we can hold all information in the pointer
- * value ;-) - so there is no need to release any memory */
- *context = NULL;
- return NULL;
- }
- if( !*context ) /* start enumeration */
- node = list;
- else {
- node = *context;
- node = node->next;
- }
+ const byte *p;
+ DATALEN n;
+ int type;
+ int length = 0;
- for( ; node; node = node->next ) {
- *context = node; /* store our context */
- if( node->type == ntLIST )
- return node->u.list;
- return node;
- }
+ if ( !list )
+ return 0;
- /* release resources and return nil */
- return gcry_sexp_enum( NULL, context, mode );
- #endif
+ p = list->d;
+ while ( (type=*p) != ST_STOP ) {
+ p++;
+ if ( type == ST_CLOSE )
+ n = 0;
+ else {
+ memcpy ( &n, p, sizeof n );
+ p += sizeof n;
+ }
+ p += n;
+ length++;
+ }
+ return length;
}
@@ -325,7 +317,7 @@ gcry_sexp_enum( GCRY_SEXP list, void **context, int mode )
* Extract the CAR of the given list
*/
GCRY_SEXP
-gcry_sexp_car( GCRY_SEXP list )
+gcry_sexp_car( const GCRY_SEXP list )
{
const byte *p;
DATALEN n;
@@ -333,7 +325,7 @@ gcry_sexp_car( GCRY_SEXP list )
byte *d;
if ( !list || list->d[0] != ST_OPEN )
- return new_empty_list ();
+ return NULL;
p = list->d;
memcpy ( &n, ++p, sizeof n ); p += sizeof n;
@@ -343,7 +335,7 @@ gcry_sexp_car( GCRY_SEXP list )
if ( *p == ST_OPEN )
*d++ = ST_CLOSE;
*d++ = ST_STOP;
- return newlist;
+ return normalize (newlist);
}
/****************
@@ -351,11 +343,17 @@ gcry_sexp_car( GCRY_SEXP list )
* is not modified.
*/
const char *
-gcry_sexp_car_data( GCRY_SEXP list, size_t *datalen )
+gcry_sexp_car_data( const GCRY_SEXP list, size_t *datalen )
{
- byte *p = list->d;
+ const byte *p;
DATALEN n;
+ if ( !list ) {
+ *datalen = 0;
+ return NULL;
+ }
+ p = list->d;
+
if ( *p == ST_OPEN ) {
p += 1 + sizeof n;
}
@@ -366,6 +364,7 @@ gcry_sexp_car_data( GCRY_SEXP list, size_t *datalen )
return p + sizeof n;
}
+ *datalen = 0;
return NULL;
}
@@ -375,12 +374,15 @@ gcry_sexp_car_data( GCRY_SEXP list, size_t *datalen )
GCRY_MPI
gcry_sexp_car_mpi( GCRY_SEXP list, int mpifmt )
{
- byte *p = list->d;
+ const byte *p;
DATALEN n;
+ if ( !list )
+ return NULL;
if ( !mpifmt )
mpifmt = GCRYMPI_FMT_STD;
+ p = list->d;
if ( *p == ST_OPEN ) {
p += 1 + sizeof n;
}
@@ -399,11 +401,23 @@ gcry_sexp_car_mpi( GCRY_SEXP list, int mpifmt )
return NULL;
}
+GCRY_SEXP
+gcry_sexp_cadr ( const GCRY_SEXP list )
+{
+ GCRY_SEXP a, b;
+
+ a = gcry_sexp_cdr ( list );
+ b = gcry_sexp_car ( a );
+ gcry_sexp_release ( a );
+ return b;
+}
+
+
/****************
* Get the CDR
*/
GCRY_SEXP
-gcry_sexp_cdr( GCRY_SEXP list )
+gcry_sexp_cdr( const GCRY_SEXP list )
{
const byte *head, *p;
DATALEN n;
@@ -411,14 +425,14 @@ gcry_sexp_cdr( GCRY_SEXP list )
byte *d;
if ( !list || list->d[0] != ST_OPEN )
- return new_empty_list ();
+ return NULL;
p = list->d;
p++;
p += sizeof n; /* don't care about the length of the list */
if ( *p == ST_CLOSE )
- return new_empty_list (); /* cdr of an empty list is an empty list */
+ return NULL; /* cdr of an empty list is an empty list */
/* skip over the first element of the list */
if ( *p == ST_STOP )
@@ -446,7 +460,7 @@ gcry_sexp_cdr( GCRY_SEXP list )
memcpy ( d, head, n ); d += n;
*d++ = ST_CLOSE;
*d++ = ST_STOP;
- return newlist;
+ return normalize (newlist);
}
/****************
@@ -455,9 +469,15 @@ gcry_sexp_cdr( GCRY_SEXP list )
const char *
gcry_sexp_cdr_data( GCRY_SEXP list, size_t *datalen )
{
- byte *p = list->d;
+ const byte *p;
DATALEN n;
+ if ( !list ) {
+ *datalen = 0;
+ return NULL;
+ }
+
+ p = list->d;
if ( *p == ST_OPEN ) {
memcpy ( &n, ++p, sizeof n );
p += sizeof n;
@@ -476,6 +496,7 @@ gcry_sexp_cdr_data( GCRY_SEXP list, size_t *datalen )
return p;
}
}
+ *datalen = 0;
return NULL;
}
@@ -489,12 +510,16 @@ gcry_sexp_cdr_data( GCRY_SEXP list, size_t *datalen )
GCRY_MPI
gcry_sexp_cdr_mpi( GCRY_SEXP list, int mpifmt )
{
- byte *p = list->d;
+ const byte *p;
DATALEN n;
+ if ( !list )
+ return NULL;
+
if ( !mpifmt )
mpifmt = GCRYMPI_FMT_STD;
+ p = list->d;
if ( *p == ST_OPEN ) {
memcpy ( &n, ++p, sizeof n );
p += sizeof n;
@@ -547,6 +572,34 @@ hextobyte( const byte *s )
return c;
}
+struct make_space_ctx {
+ GCRY_SEXP sexp;
+ size_t allocated;
+ byte *pos;
+ byte **fixups;
+ int max_fixups;
+ int n_fixups;
+};
+
+static void
+make_space ( struct make_space_ctx *c, size_t n )
+{
+ size_t used = c->pos - c->sexp->d;
+
+ if ( used + n +sizeof(DATALEN) + 1 >= c->allocated ) {
+ GCRY_SEXP newsexp;
+ byte *newhead;
+ int i;
+
+ c->allocated += 2*(n+sizeof(DATALEN)+1);
+ newsexp = g10_xrealloc ( c->sexp, sizeof *newsexp + c->allocated - 1 );
+ newhead = newsexp->d;
+ c->pos = newhead + used;
+ for ( i=0; i < c->n_fixups; i++ )
+ c->fixups[i] = newhead + (c->fixups[i] - c->sexp->d );
+ c->sexp = newsexp;
+ }
+}
/****************
@@ -588,75 +641,42 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
int hexcount=0;
int quoted_esc=0;
int datalen=0;
- int first;
size_t dummy_erroff;
- byte *head, *pos, *tail;
- size_t allocated;
- byte **fixups = NULL;
- int max_fixups = 0;
- int n_fixups = 0;
+
+ struct make_space_ctx c;
if( !erroff )
erroff = &dummy_erroff;
/* FIXME: replace all the returns by a jump to the leave label
* and invent better error codes. Make sure that everything is cleaned up*/
-
- #define MAKE_SPACE(n) do {if ( pos + (n)+sizeof(DATALEN)+1 >= tail ) { \
- GCRY_SEXP newsexp; \
- byte *newhead; \
- int i; \
- allocated += 2*((n)+sizeof(DATALEN)+1); \
- newsexp = g10_xrealloc ( *retsexp, \
- sizeof *newsexp + allocated - 1 ); \
- newhead = newsexp->d; \
- pos = newhead + ( pos - head ); \
- for ( i=0; i < n_fixups; i++ ) \
- fixups[i] = newhead+(fixups[i]-head); \
- head = newhead; \
- *retsexp = newsexp; \
- tail = head + allocated; \
- } \
- } while (0)
+ #define MAKE_SPACE(n) do { make_space ( &c, (n) ); } while (0)
#define STORE_LEN(p,n) do { \
DATALEN ashort = (n); \
memcpy ( (p), &ashort, sizeof(ashort) ); \
(p) += sizeof (ashort); \
} while (0)
- #define PUSH_FIXUP(p) do { \
- if ( !fixups ) { \
- max_fixups = 3; \
- fixups = g10_xcalloc( max_fixups, \
- sizeof *fixups ); \
- n_fixups = 0; \
- } \
- if ( n_fixups >= max_fixups ) { \
- max_fixups += 10; \
- fixups = g10_xrealloc(fixups, max_fixups); \
- } \
- fixups[n_fixups++] = p; \
- } while (0)
-
/* We assume that the internal representation takes less memory
* than the provided one. However, we add space for one extra datalen
* so that the code which does the ST_CLOSE can use MAKE_SPACE */
- allocated = length + sizeof(DATALEN);
- *retsexp = g10_xmalloc ( sizeof **retsexp + allocated - 1 );
- head = pos = (*retsexp)->d;
- tail = head + allocated - 1;
+ c.allocated = length + sizeof(DATALEN);
+ c.sexp = g10_xmalloc ( sizeof *c.sexp + c.allocated - 1 );
+ c.pos = c.sexp->d;
+ c.fixups = NULL;
+ c.max_fixups = 0;
+ c.n_fixups = 0;
- first = 0;
for(p=buffer,n=length; n; p++, n-- ) {
if( tokenp && !hexfmt ) {
if( strchr( tokenchars, *p ) )
continue;
datalen = p - tokenp;
MAKE_SPACE ( datalen );
- *pos++ = ST_DATA;
- STORE_LEN ( pos, datalen );
- memcpy ( pos, tokenp, datalen );
- pos += datalen;
+ *c.pos++ = ST_DATA;
+ STORE_LEN ( c.pos, datalen );
+ memcpy ( c.pos, tokenp, datalen );
+ c.pos += datalen;
tokenp = NULL;
}
if( quoted ) {
@@ -719,12 +739,12 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
datalen = hexcount/2;
MAKE_SPACE (datalen);
- *pos++ = ST_DATA;
- STORE_LEN (pos, datalen);
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
for( hexfmt++; hexfmt < p; hexfmt++ ) {
if( isspace( *hexfmt ) )
continue;
- *pos++ = hextobyte( hexfmt );
+ *c.pos++ = hextobyte( hexfmt );
hexfmt++;
}
hexfmt = NULL;
@@ -742,10 +762,6 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
if( isdigit(*p) )
;
else if( *p == ':' ) {
- if( !head ) {
- *erroff = 0;
- return -4; /* not a list */
- }
datalen = atoi( digptr ); /* fixme: check for overflow */
digptr = NULL;
if( datalen > n-1 ) {
@@ -754,10 +770,10 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
}
/* make a new list entry */
MAKE_SPACE (datalen);
- *pos++ = ST_DATA;
- STORE_LEN (pos, datalen);
- memcpy (pos, p+1, datalen );
- pos += datalen;
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, datalen);
+ memcpy (c.pos, p+1, datalen );
+ c.pos += datalen;
n -= datalen;
p += datalen;
}
@@ -788,44 +804,36 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
if ( gcry_mpi_print( GCRYMPI_FMT_STD, NULL, &nm, m ) )
BUG ();
- if ( !g10_is_secure ( head )
+ MAKE_SPACE (nm);
+ if ( !g10_is_secure ( c.sexp->d )
&& gcry_mpi_get_flag ( m, GCRYMPI_FLAG_SECURE ) ) {
- /* we have to switch to secure allocation and while we
- * are already at it we check wether we have to increase
- * the size */
+ /* we have to switch to secure allocation */
GCRY_SEXP newsexp;
byte *newhead;
- if ( pos + nm+sizeof(DATALEN)+1 >= tail ) {
- allocated += nm+sizeof(DATALEN)+1;
- }
-
- newsexp = g10_xrealloc ( *retsexp,
- sizeof *newsexp + allocated - 1 );
+ newsexp = g10_xmalloc_secure ( sizeof *newsexp
+ + c.allocated - 1 );
newhead = newsexp->d;
- memcpy ( newhead, head, (pos - head) );
- pos = newhead + ( pos - head );
- g10_free ( head );
- head = newhead;
- *retsexp = newsexp;
- tail = head + allocated;
+ memcpy ( newhead, c.sexp->d, (c.pos - c.sexp->d) );
+ c.pos = newhead + ( c.pos - c.sexp->d );
+ g10_free ( c.sexp );
+ c.sexp = newsexp;
}
- MAKE_SPACE (nm);
- *pos++ = ST_DATA;
- STORE_LEN (pos, nm);
- if ( gcry_mpi_print( GCRYMPI_FMT_STD, pos, &nm, m ) )
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, nm);
+ if ( gcry_mpi_print( GCRYMPI_FMT_STD, c.pos, &nm, m ) )
BUG ();
- pos += nm;
+ c.pos += nm;
}
else if ( *p == 's' ) { /* insert an string */
const char *astr = va_arg (arg_ptr, const char *);
size_t alen = strlen ( astr );
MAKE_SPACE (alen);
- *pos++ = ST_DATA;
- STORE_LEN (pos, alen);
- memcpy ( pos, astr, alen );
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy ( c.pos, astr, alen );
}
else if ( *p == 'd' ) { /* insert an integer as string */
int aint = va_arg (arg_ptr, int);
@@ -835,10 +843,10 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
sprintf ( buf, "%d", aint );
alen = strlen ( buf );
MAKE_SPACE (alen);
- *pos++ = ST_DATA;
- STORE_LEN (pos, alen);
- memcpy ( pos, buf, alen );
- pos += alen;
+ *c.pos++ = ST_DATA;
+ STORE_LEN (c.pos, alen);
+ memcpy ( c.pos, buf, alen );
+ c.pos += alen;
}
else {
*erroff = p - buffer;
@@ -852,10 +860,21 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
return -9; /* open display hint */
}
MAKE_SPACE (0);
- *pos++ = ST_OPEN;
- PUSH_FIXUP ( pos );
- STORE_LEN ( pos, 0 ); /* reserve */
- first = 1;
+ *c.pos++ = ST_OPEN;
+
+ if ( !c.fixups ) {
+ c.max_fixups = 10;
+ c.fixups = g10_xcalloc( c.max_fixups, sizeof *c.fixups );
+ c.n_fixups = 0;
+ }
+ else if ( c.n_fixups >= c.max_fixups ) {
+ c.max_fixups += 10;
+ c.fixups = g10_xrealloc( c.fixups,
+ c.max_fixups * sizeof *c.fixups );
+ }
+ c.fixups[c.n_fixups++] = c.pos;
+
+ STORE_LEN ( c.pos, 0 ); /* reserve */
}
else if( *p == ')' ) { /* walk up */
byte *fixup;
@@ -864,14 +883,14 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
*erroff = p - buffer;
return -9; /* open display hint */
}
- if( !n_fixups ) {
+ if( !c.n_fixups ) {
*erroff = 0;
return -4; /* no open list */
}
MAKE_SPACE (0);
- fixup = fixups[--n_fixups];
- *pos++ = ST_CLOSE;
- STORE_LEN ( fixup, pos - fixup - sizeof(DATALEN) );
+ fixup = c.fixups[--c.n_fixups];
+ *c.pos++ = ST_CLOSE;
+ STORE_LEN ( fixup, c.pos - fixup - sizeof(DATALEN) );
}
else if( *p == '\"' ) {
quoted = p;
@@ -932,14 +951,13 @@ sexp_sscan( GCRY_SEXP *retsexp, size_t *erroff ,
}
MAKE_SPACE (0);
- *pos++ = ST_STOP;
+ *c.pos++ = ST_STOP;
- leave:
- g10_free ( fixups );
+ g10_free ( c.fixups );
+ *retsexp = normalize ( c.sexp );
return 0;
#undef MAKE_SPACE
#undef STORE_LEN
- #undef PUISH_FIXUP
}
int
@@ -988,88 +1006,6 @@ strusage( int level )
}
-#if 0
-static int
-sexp_to_pk( GCRY_SEXP sexp, int want_private, MPI **retarray, int *retalgo)
-{
- GCRY_SEXP list, l2;
- const char *name;
- const char *s;
- size_t n;
- int i, idx;
- int algo;
- const char *elems1, *elems2;
- GCRY_MPI *array;
- static struct { const char* name; int algo;
- const char* common_elements;
- const char* public_elements;
- const char* secret_elements;
- } algos[] = {
- { "dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x" },
- { "rsa" , PUBKEY_ALGO_RSA , "ne", "", "dpqu" },
- { "openpgp-dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x" },
- { "openpgp-rsa" , PUBKEY_ALGO_RSA , "pqgy", "", "x" },
- { "openpgp-elg" , PUBKEY_ALGO_ELGAMAL_E , "pgy", "", "x" },
- { "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "pgy", "", "x" },
- { NULL }};
-
- /* check that the first element is valid */
- list = gcry_sexp_find_token( sexp, want_private? "private-key"
- :"public-key", 0 );
- if( !list )
- return -1; /* Does not contain a public- or private-key object */
- list = gcry_sexp_cdr( list );
- if( !list )
- return -2; /* no cdr for the key object */
- name = gcry_sexp_car_data( list, &n );
- if( !name )
- return -3; /* invalid structure of object */
- fprintf(stderr, "algorithm name: `%.*s'\n", (int)n, name );
- for(i=0; (s=algos[i].name); i++ ) {
- if( strlen(s) == n && !memcmp( s, name, n ) )
- break;
- }
- if( !s )
- return -4; /* unknown algorithm */
- algo = algos[i].algo;
- elems1 = algos[i].common_elements;
- elems2 = want_private? algos[i].secret_elements : algos[i].public_elements;
- array = g10_xcalloc( (strlen(elems1)+strlen(elems2)+1) , sizeof *array );
- idx = 0;
- for(s=elems1; *s; s++, idx++ ) {
- l2 = gcry_sexp_find_token( list, s, 1 );
- if( !l2 ) {
- g10_free( array );
- return -5; /* required parameter not found */
- }
- array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG );
- if( !array[idx] ) {
- g10_free( array );
- return -6; /* required parameter is invalid */
- }
- }
- for(s=elems2; *s; s++, idx++ ) {
- l2 = gcry_sexp_find_token( list, s, 1 );
- if( !l2 ) {
- g10_free( array );
- return -5; /* required parameter not found */
- }
- /* FIXME: put the MPI in secure memory when needed */
- array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG );
- if( !array[idx] ) {
- g10_free( array );
- return -6; /* required parameter is invalid */
- }
- }
-
- *retarray = array;
- *retalgo = algo;
-
- return 0;
-}
-#endif
-
-
int
main(int argc, char **argv)
{
diff --git a/src/testapi.c b/src/testapi.c
index faa26ebd..e94b2d41 100644
--- a/src/testapi.c
+++ b/src/testapi.c
@@ -37,10 +37,6 @@ test_sexp ( int argc, char **argv )
rc = gcry_sexp_build ( &sexp, NULL,
"(public-key(elg(p%m)(g%m)(y%m)))",
key[0], key[1], key[2] );
- if (rc) {
- fprintf (stderr, "gcry_sexp_build failed: rc=%d\n", rc );
- return;
- }
fputs ( "DUMP of PK:\n", stderr );
gcry_sexp_dump ( sexp );
{ GCRY_SEXP x;
@@ -55,6 +51,23 @@ test_sexp ( int argc, char **argv )
}
+void
+test_genkey ( int argc, char **argv )
+{
+ int rc, nbits = 1024;
+ GCRY_SEXP s_parms, s_key;
+
+ rc = gcry_sexp_build ( &s_parms, NULL, "(genkey(dsa(nbits %d)))", nbits );
+ rc = gcry_pk_genkey( &s_key, s_parms );
+ if ( rc ) {
+ fprintf ( stderr, "genkey failed: %s\n", gcry_strerror (rc) );
+ return;
+ }
+ gcry_sexp_release( s_parms );
+ gcry_sexp_dump ( s_key );
+ gcry_sexp_release( s_key );
+}
+
int
main( int argc, char **argv )
{
@@ -64,6 +77,8 @@ main( int argc, char **argv )
printf("%s\n", gcry_check_version ( argc > 2 ? argv[2] : NULL ) );
else if ( !strcmp ( argv[1], "sexp" ) )
test_sexp ( argc-2, argv+2 );
+ else if ( !strcmp ( argv[1], "genkey" ) )
+ test_genkey ( argc-2, argv+2 );
else {
fprintf (stderr, "usage: testapi mode-string [mode-args]\n");
return 1;