See ChangeLog: Tue Jul 13 17:39:25 CEST 1999 Werner Koch
authorWerner Koch <wk@gnupg.org>
Tue, 13 Jul 1999 15:41:11 +0000 (15:41 +0000)
committerWerner Koch <wk@gnupg.org>
Tue, 13 Jul 1999 15:41:11 +0000 (15:41 +0000)
THANKS
mpi/Makefile.am
src/gcrypt.h
src/mpiapi.c
src/pkapi.c
src/sexp.c

diff --git a/THANKS b/THANKS
index 04de29a..4f91cee 100644 (file)
--- a/THANKS
+++ b/THANKS
@@ -20,6 +20,7 @@ David Ellement                ellement@sdd.hp.com
 Detlef Lannert         lannert@lannert.rz.uni-duesseldorf.de
 Dirk Lattermann        dlatt@t-online.de
 Ed Boraas              ecxjo@esperanto.org
+Enzo Michelangeli      em@MailAndNews.com
 Ernst Molitor          ernst.molitor@uni-bonn.de
 Fabio Coatti           cova@felix.unife.it
 Felix von Leitner      leitner@amdiv.de
@@ -97,7 +98,7 @@ Wim Vandeputte                bunbun@reptile.rug.ac.be
                        nbecker@hns.com
 
 Thanks to the German Unix User Group for providing FTP space,
-Martin Hamilton for hosting the mailing list and hsp for
+Martin Hamilton for hosting the mailing list and HSP for
 hosting gnupg.org.
 
 Many thanks to my wife Gerlinde for having so much patience with
index fc25bbb..e5c241a 100644 (file)
@@ -9,10 +9,8 @@ DISTCLEANFILES = mpih-add1.S mpih-mul1.S mpih-mul2.S mpih-mul3.S  \
                 mpih-lshift.S mpih-rshift.S mpih-sub1.S asm-syntax.h sysdep.h
 CLEANFILES = tmp-*.s
 
-
 noinst_LTLIBRARIES = libmpi.la
 
-
 libmpi_la_LDFLAGS =
 libmpi_la_SOURCES = longlong.h    \
              mpi-add.c      \
index d96fbff..f26e34c 100644 (file)
@@ -76,10 +76,10 @@ struct gcry_sexp;
 typedef struct gcry_sexp *GCRY_SEXP;
 
 enum gcry_sexp_format {
-    GCRY_SEXP_FMT_DEFAULT   = 0,
-    GCRY_SEXP_FMT_CANON     = 1,
-    GCRY_SEXP_FMT_BASE64    = 2,
-    GCRY_SEXP_FMT_ADVANCED  = 3,
+    GCRYSEXP_FMT_DEFAULT   = 0,
+    GCRYSEXP_FMT_CANON    = 1,
+    GCRYSEXP_FMT_BASE64    = 2,
+    GCRYSEXP_FMT_ADVANCED  = 3,
 };
 
 
@@ -106,9 +106,11 @@ size_t gcry_sexp_sprint( GCRY_SEXP sexp, int mode, char *buffer,
  *******************************************/
 
 enum gcry_mpi_format {
-    GCRYMPI_FMT_STD = 0,    /* As used by OpenPGP */
-    GCRYMPI_FMT_SSH = 1,    /* As used by SSH */
-    GCRYMPI_FMT_HEX = 2,    /* hex format */
+    GCRYMPI_FMT_STD = 0,    /* twos complement stored without length */
+    GCRYMPI_FMT_PGP = 1,    /* As used by OpenPGP */
+    GCRYMPI_FMT_SSH = 2,    /* As used by SSH (same as 0 but with length)*/
+    GCRYMPI_FMT_HEX = 3,    /* hex format */
+    GCRYMPI_FMT_USG = 4,    /* like STD but this is an unsigned one */
 };
 
 struct gcry_mpi;
index acf5c5a..2884165 100644 (file)
@@ -108,8 +108,40 @@ gcry_mpi_scan( struct gcry_mpi **ret_mpi, enum gcry_mpi_format format,
 
     len = nbytes? *nbytes : strlen(buffer);
 
-    /* TODO: add formats to allocate the MPI in secure memory */
+    /* TODO: add a way to allocate the MPI in secure memory
+     * Hmmm: maybe it is better to retrieve this information from
+     * the provided buffer. */
     if( format == GCRYMPI_FMT_STD ) {
+       const byte *s = buffer;
+
+       a = mpi_alloc( (len+BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
+       if( len ) { /* not zero */
+           a->sign = *s & 0x80;
+           if( a->sign ) {
+               /* FIXME: we have to convert from 2compl to magnitude format */
+               mpi_free(a);
+               return GCRYERR_INTERNAL;
+           }
+           else
+               mpi_set_buffer( a, s, len, 0 );
+       }
+       if( ret_mpi )
+           *ret_mpi = a;
+       else
+           mpi_free(a);
+       return 0;
+    }
+    else if( format == GCRYMPI_FMT_USG ) {
+       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 )
+           *ret_mpi = a;
+       else
+           mpi_free(a);
+       return 0;
+    }
+    else if( format == GCRYMPI_FMT_PGP ) {
        a = mpi_read_from_buffer( (char*)buffer, &len, 0 );
        if( nbytes )
            *nbytes = len;
@@ -182,6 +214,33 @@ gcry_mpi_print( enum gcry_mpi_format format, char *buffer, size_t *nbytes,
 
     len = *nbytes;
     if( format == GCRYMPI_FMT_STD ) {
+       byte *s = buffer;
+       char *tmp;
+       int extra = 0;
+       unsigned int n;
+
+       if( a->sign )
+           return GCRYERR_INTERNAL; /* can't handle it yet */
+
+       tmp = mpi_get_buffer( a, &n, NULL );
+       if( n && (*tmp & 0x80) ) {
+           n++;
+           extra=1;
+       }
+
+       if( n > len ) {
+           m_free(tmp);
+           return GCRYERR_TOO_SHORT;  /* the provided buffer is too short */
+       }
+       if( extra )
+           *s++ = 0;
+
+       memcpy( s, tmp, n-extra );
+       m_free(tmp);
+       *nbytes = n;
+       return 0;
+    }
+    else if( format == GCRYMPI_FMT_PGP ) {
        unsigned int n = (nbits + 7)/8;
        byte *s = buffer;
        char *tmp;
index e3d900a..8457ef1 100644 (file)
 
 
 
+
+
+
+int
+gcry_pk_encrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey )
+{
+}
+
+int
+gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey )
+{
+}
+
+int
+gcry_pk_sign( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey )
+{
+    GCRY_SEXP s;
+    /* get the secret key */
+    s = gcry_sexp_find_token( skey, "private-key", 0 );
+    if( !s )
+       return -1; /* no private key */
+    ...
+
+}
+
+int
+gcry_pk_verify( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey )
+{
+}
+
index c9dfdd0..4b13174 100644 (file)
@@ -87,7 +87,9 @@ dump_mpi( GCRY_MPI a )
     char buffer[1000];
     size_t n = 1000;
 
-    if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
+    if( !a )
+       fputs("[no MPI]", stderr );
+    else if( gcry_mpi_print( GCRYMPI_FMT_HEX, buffer, &n, a ) )
        fputs("[MPI too large to print]", stderr );
     else
        fputs( buffer, stderr );
@@ -134,7 +136,7 @@ dump_sexp( NODE node )
  * Create a new SEXP element (data)
  */
 GCRY_SEXP
-gcry_sexp_new( const char *buffer, size_t length )
+gcry_sexp_new_data( const char *buffer, size_t length )
 {
     NODE node;
 
@@ -200,6 +202,7 @@ gcry_sexp_vlist( GCRY_SEXP a, ... )
 }
 
 
+
 /****************
  * Locate data in a list. Data must be the first item in the list.
  * Returns: The sublist with that Data (don't modify it!)
@@ -209,6 +212,9 @@ gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
 {
     NODE node;
 
+    if( !toklen )
+       toklen = strlen(tok);
+
     for( node=list ; node; node = node->next )
       {
        switch( node->type ) {
@@ -236,7 +242,7 @@ gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
 
 
 /****************
- * Enumerate all objects in the list.  Ther firts time you call this, pass
+ * 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
@@ -247,10 +253,12 @@ gcry_sexp_find_token( GCRY_SEXP list, const char *tok, size_t toklen )
  * Note that this function returns only lists and not single objects.
  */
 GCRY_SEXP
-gcry_sexp_enum_lists( GCRY_SEXP list, void **context )
+gcry_sexp_enum( GCRY_SEXP list, void **context, int mode )
 {
     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 */
@@ -259,35 +267,97 @@ gcry_sexp_enum_lists( GCRY_SEXP list, void **context )
     }
     if( !*context )  /* start enumeration */
        node = list;
-    else
+    else {
        node = *context;
-
+       node = node->next;
+    }
 
     for( ; node; node = node->next ) {
-       if( node->type == ntLIST ) {
-           node = node->u.list;
-           *context = node; /* store our context */
-           return node;
-       }
+       *context = node; /* store our context */
+       if( node->type == ntLIST )
+           return node->u.list;
+       return node;
     }
 
     /* release resources and return nil */
-    return gcry_sexp_enum_lists( NULL, context );
+    return gcry_sexp_enum( NULL, context, mode );
+}
+
+
+
+/****************
+ * Get data from the car
+ */
+const char *
+gcry_sexp_car_data( GCRY_SEXP list, size_t *datalen )
+{
+    if( list && list->type == ntDATA ) {
+       *datalen = list->u.data.len;
+       return list->u.data.d;
+    }
+
+    return NULL;
+}
+
+/****************
+ * Get data from the cdr assuming this is a pair
+ */
+const char *
+gcry_sexp_cdr_data( GCRY_SEXP list, size_t *datalen )
+{
+    if( list && (list = list->next) && list->type == ntDATA ) {
+       *datalen = list->u.data.len;
+       return list->u.data.d;
+    }
+
+    return NULL;
 }
 
 
 /****************
  * cdr the mpi from the list or NULL if there is no MPI.
  * This function tries to convert plain data to an MPI.
+ * Actually this funtion returns only the second item of the list
+ * and ignores any further arguments.
  */
 MPI
-gcry_sexp_cdr_mpi( GCRY_SEXP list )
+gcry_sexp_cdr_mpi( GCRY_SEXP list, int mpifmt )
 {
+    NODE node = list;
 
+    if( !node || !(node = node->next) || node == ntLIST )
+       return NULL;
+    if( node->type == ntDATA ) {
+       MPI a;
+       size_t n = node->u.data.len;
+       if( gcry_mpi_scan( &a, mpifmt, node->u.data.d, &n ) )
+           return NULL;
+       return a;
+    }
+    else if( node->type == ntMPI )
+       return gcry_mpi_copy( node->u.mpi );
+    else
+       return NULL;
 }
 
 
 /****************
+ * Check wether the car is equal to data
+ */
+#if 0 /* not tested */
+int
+gcry_sexp_eqp_car( GCRY_SEXP list, const char *data, size_t datalen )
+{
+    if( list && list->type == ntDATA
+       && list->u.data.len == datalen
+       && !memcmp( list->u.data.d, list, listlen ) )
+       return 1;
+
+    return 0;
+}
+#endif
+
+/****************
  * Scan the provided buffer and return the S expression in our internal
  * format.  Returns a newly allocated expression.  If erroff is not NULL and
  * a parsing error has occured, the offset into buffer will be returned.
@@ -512,7 +582,7 @@ gcry_sexp_sscan( GCRY_SEXP *retsexp, const char *buffer,
        }
 
     }
-    dump_sexp( head );
+    *retsexp = head;
     return 0;
 }
 
@@ -548,18 +618,15 @@ main(int argc, char **argv)
     FILE *fp;
     GCRY_SEXP s_pk, s_dsa, s_p, s_q, s_g, sexp;
 
-  #if 0
-    if( argc > 1 ) {
-       fp = fopen( argv[1], "r" );
-       if( !fp )
-           exit(1);
-       n = fread(buffer, 1, 5000, fp );
-       fprintf(stderr,"read %d bytes\n", n );
-       rc = gcry_sexp_sscan( NULL, buffer, n, &erroff );
-       fprintf(stderr, "read: rc=%d  erroff=%u\n", rc, erroff );
+  #if 1
+    fp = stdin;
+    n = fread(buffer, 1, 5000, fp );
+    rc = gcry_sexp_sscan( &sexp, buffer, n, &erroff );
+    if( rc ) {
+       fprintf(stderr, "parse error %d at offset %u\n", rc, erroff );
+       exit(1);
     }
-  #endif
-
+  #else
     s_pk = SEXP_NEW( "public-key", 10 );
     fputs("pk:\n",stderr);dump_sexp( s_pk );
     s_dsa = SEXP_NEW( "dsa", 3 );
@@ -572,7 +639,9 @@ main(int argc, char **argv)
                                             s_q,
                                             s_g,
                                             NULL ));
-    fputs("all:\n",stderr);dump_sexp( sexp );
+    fputs("Here is what we have:\n",stderr);
+    dump_sexp( sexp );
+  #endif
 
     /* now find something */
     if( argc > 1 )
@@ -589,6 +658,54 @@ main(int argc, char **argv)
            fprintf(stderr, "found `%s':\n", argv[1] );
            dump_sexp( s1 );
          }
+
+
+       if( argc > 2 ) /* get the MPI out of the list */
+       #if 0
+         {
+           GCRY_SEXP s2;
+           MPI a;
+
+           s2 = gcry_sexp_find_token( s1, argv[2], strlen(argv[2]) );
+           if( !s1 )
+           {
+              fprintf(stderr, "didn't found `%s'\n", argv[2] );
+              exit(1);
+           }
+
+           a = gcry_sexp_cdr_mpi( s2, GCRYMPI_FMT_USG );
+           if( a ) {
+               fprintf(stderr, "MPI: ");
+               dump_mpi( a );
+               fprintf(stderr, "\n");
+           }
+           else
+               fprintf(stderr, "cannot cdr a mpi\n" );
+         }
+        #else
+         {    /* print all MPIs */
+           void *ctx = NULL;
+           GCRY_SEXP s2;
+           MPI a;
+
+           while( (s2 = gcry_sexp_enum( s1, &ctx, 0 )) )
+             {
+               const char *car_d;
+               size_t car_n;
+
+               car_d = gcry_sexp_car_data( s2, &car_n );
+               if( car_d ) {
+                  fprintf(stderr, "CAR: %.*s=", (int)car_n, car_d );
+                  a = gcry_sexp_cdr_mpi( s2, GCRYMPI_FMT_USG );
+                  dump_mpi( a );
+                  fprintf(stderr, "\n");
+
+               }
+               else
+                   fprintf(stderr, "no CAR\n");
+             }
+         }
+        #endif
       }
     return 0;
 }