See ChangeLog: Wed Oct 4 13:16:18 CEST 2000 Werner Koch
authorWerner Koch <wk@gnupg.org>
Wed, 4 Oct 2000 11:16:19 +0000 (11:16 +0000)
committerWerner Koch <wk@gnupg.org>
Wed, 4 Oct 2000 11:16:19 +0000 (11:16 +0000)
29 files changed:
NEWS
TODO
checks/ChangeLog
checks/run-gpg
checks/run-gpg.patterns
cipher/ChangeLog
cipher/Makefile.am
cipher/cipher.c
cipher/md.c
cipher/random.h
cipher/rsa.c
cipher/sha1.c
doc/gcryptref-digest.sgml
doc/gcryptref-misc.sgml
g10/ChangeLog
g10/encode.c
g10/export.c
g10/getkey.c
g10/gpg.c
g10/keydb.h
g10/keygen.c
g10/keyid.c
g10/misc.c
g10/pkclist.c
g10/seckey-cert.c
g10/sign.c
g10/skclist.c
g10/status.c
include/ttyio.h

diff --git a/NEWS b/NEWS
index d5367ae..66d650a 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -3,6 +3,8 @@ Noteworthy changes in the current CVS HEAD
 
     THIS IS A DEVELOPMENT VERSION; see README-alpha
 
+    * Add Rijndael (AES) support.
+
     * Fixed problems with piping to/from other MS-Windows software
 
     * Expiration time of the primary key can be changed again.
diff --git a/TODO b/TODO
index 45d0667..da49089 100644 (file)
--- a/TODO
+++ b/TODO
@@ -7,11 +7,6 @@
 
   * Use --output for keylistings too.
 
-  * Add to the (EGD) docs that ~/.gnupg/entropy should be a symlink to the
-    real socket.
-
-  * Add a way to generate keys in batch mode with arbitrary parameters.
-
   * Never allocate packet memory with a m-alloc, but use a specific function.
 
   * Should we change names like mpi_write in g10/ so that we don't
@@ -28,8 +23,6 @@
 
   * Speed up calculation of key validation.
 
-  * print a warning when a revoked/expired _secret_ key is used.
-
   * --disable-asm should still assemble _udiv_qrnnd when needed
 
   * Skip RO keyrings when importing a key.
index 9be8600..b5c810b 100644 (file)
@@ -1,3 +1,7 @@
+Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * run-gpg: redirect fgrep output to stderr
+
 Sat Nov 13 17:44:23 CET 1999  Werner Koch  <wk@gnupg.de>
 
        * genkey1024.test: Does not use --quick-random anymore.
index a9e0e31..28d575e 100755 (executable)
@@ -1,6 +1,6 @@
 #!/bin/sh
 
-[ -n "$show_cmds" ] && echo "../g10/gpg --homedir . $*"
+[ -n "$show_cmds" ] && echo "../g10/gpg --homedir . $*" >&2
 
 if ../g10/gpg --homedir . $* 2>err.tmp.$$ ; then
     :
@@ -10,6 +10,6 @@ else
     rm err.tmp.$$
     exit 1
 fi
-fgrep -v -f $srcdir/run-gpg.patterns err.tmp.$$
+fgrep -v -f $srcdir/run-gpg.patterns err.tmp.$$ >&2
 rm err.tmp.$$
 
index 9eb355e..fde7bbb 100644 (file)
@@ -9,3 +9,6 @@ gpg: NOTE: secret key 439F02CA is NOT protected.
 gpg: WARNING: using insecure random number generator
 gpg: NOTE: signature key expired
 NOTE: this is a development version!
+secret key without public key - skipped
+gpg: using secondary key CB879DE9 instead of primary key 439F02CA
+
index 2e4ebe5..1d793ec 100644 (file)
@@ -1,3 +1,17 @@
+Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * sha1.c (transform): Use rol() macro.  Actually this is not needed
+        for a newer gcc but there are still aoter compilers.
+
+        * rsa.c (test_keys): Use new random function. 
+
+        * md.c (gcry_md_setkey): New function to overcome problems with
+        const conflics.  
+        (gcry_md_ctl): Pass set key to the new functions.
+
+        * rijndael.c: New.
+        * cipher.c: Add Rijndael support.
+
 Mon Sep 18 16:35:45 CEST 2000  Werner Koch  <wk@openit.de>
 
         * rndlinux.c (open_device): Loose random device checking.
index 26de925..6feea15 100644 (file)
@@ -36,6 +36,7 @@ libcipher_la_SOURCES = cipher.c  \
                 bithelp.h      \
                 des.c          \
                 des.h          \
+                rijndael.c     \
                 twofish.c      \
                 blowfish.c     \
                 blowfish.h     \
index 7808d87..d36db66 100644 (file)
@@ -33,7 +33,7 @@
 #include "dynload.h"
 
 #define MAX_BLOCKSIZE 16
-#define TABLE_SIZE 10
+#define TABLE_SIZE 12
 #define CTX_MAGIC_NORMAL 0x24091964
 #define CTX_MAGIC_SECURE 0x46919042
 
@@ -82,11 +82,43 @@ dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); }
 static void
 setup_cipher_table(void)
 {
-
     int i;
 
     i = 0;
-    cipher_table[i].algo = CIPHER_ALGO_TWOFISH;
+    cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL;
+    cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
+                                        &cipher_table[i].keylen,
+                                        &cipher_table[i].blocksize,
+                                        &cipher_table[i].contextsize,
+                                        &cipher_table[i].setkey,
+                                        &cipher_table[i].encrypt,
+                                        &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+       BUG();
+    i++;
+    cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL192;
+    cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
+                                        &cipher_table[i].keylen,
+                                        &cipher_table[i].blocksize,
+                                        &cipher_table[i].contextsize,
+                                        &cipher_table[i].setkey,
+                                        &cipher_table[i].encrypt,
+                                        &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+       BUG();
+    i++;
+    cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL256;
+    cipher_table[i].name = rijndael_get_info( cipher_table[i].algo,
+                                        &cipher_table[i].keylen,
+                                        &cipher_table[i].blocksize,
+                                        &cipher_table[i].contextsize,
+                                        &cipher_table[i].setkey,
+                                        &cipher_table[i].encrypt,
+                                        &cipher_table[i].decrypt     );
+    if( !cipher_table[i].name )
+       BUG();
+    i++;
+    cipher_table[i].algo = GCRY_CIPHER_TWOFISH;
     cipher_table[i].name = twofish_get_info( cipher_table[i].algo,
                                         &cipher_table[i].keylen,
                                         &cipher_table[i].blocksize,
@@ -97,7 +129,7 @@ setup_cipher_table(void)
     if( !cipher_table[i].name )
        BUG();
     i++;
-    cipher_table[i].algo = CIPHER_ALGO_BLOWFISH;
+    cipher_table[i].algo = GCRY_CIPHER_BLOWFISH;
     cipher_table[i].name = blowfish_get_info( cipher_table[i].algo,
                                         &cipher_table[i].keylen,
                                         &cipher_table[i].blocksize,
@@ -108,7 +140,7 @@ setup_cipher_table(void)
     if( !cipher_table[i].name )
        BUG();
     i++;
-    cipher_table[i].algo = CIPHER_ALGO_CAST5;
+    cipher_table[i].algo = GCRY_CIPHER_CAST5;
     cipher_table[i].name = cast5_get_info( cipher_table[i].algo,
                                         &cipher_table[i].keylen,
                                         &cipher_table[i].blocksize,
@@ -119,7 +151,7 @@ setup_cipher_table(void)
     if( !cipher_table[i].name )
        BUG();
     i++;
-    cipher_table[i].algo = CIPHER_ALGO_3DES;
+    cipher_table[i].algo = GCRY_CIPHER_3DES;
     cipher_table[i].name = des_get_info( cipher_table[i].algo,
                                         &cipher_table[i].keylen,
                                         &cipher_table[i].blocksize,
@@ -455,7 +487,7 @@ do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
     unsigned n;
 
     for(n=0; n < nblocks; n++ ) {
-       (*c->encrypt)( &c->context.c, outbuf, inbuf );
+       (*c->encrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
        inbuf  += c->blocksize;
        outbuf += c->blocksize;
     }
@@ -467,7 +499,7 @@ do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
     unsigned n;
 
     for(n=0; n < nblocks; n++ ) {
-       (*c->decrypt)( &c->context.c, outbuf, inbuf );
+       (*c->decrypt)( &c->context.c, outbuf, (byte*)/*arggg*/inbuf );
        inbuf  += c->blocksize;
        outbuf += c->blocksize;
     }
@@ -507,7 +539,7 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo
         * to save the original ciphertext block.  We use lastiv
         * for this here because it is not used otherwise */
        memcpy(c->lastiv, inbuf, blocksize );
-       (*c->decrypt)( &c->context.c, outbuf, inbuf );
+       (*c->decrypt)( &c->context.c, outbuf, (char*)/*argggg*/inbuf );
        for(ivp=c->iv,i=0; i < blocksize; i++ )
            outbuf[i] ^= *ivp++;
        memcpy(c->iv, c->lastiv, blocksize );
index e8ac8ac..29d6afe 100644 (file)
@@ -557,10 +557,7 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
     if( cmd == GCRYCTL_FINALIZE )
        md_final( hd );
     else if( cmd == GCRYCTL_SET_KEY ) {
-       if( !(hd->ctx->macpads ) )
-           rc = GCRYERR_CONFLICT;
-       else if ( !(rc = prepare_macpads( hd, buffer, buflen )) )
-           gcry_md_reset( hd );
+        rc = gcry_md_setkey ( hd, buffer, buflen );
     }
     else if( cmd == GCRYCTL_START_DUMP ) {
        md_start_debug( hd, buffer );
@@ -574,6 +571,20 @@ gcry_md_ctl( GCRY_MD_HD hd, int cmd, byte *buffer, size_t buflen)
 }
 
 
+int
+gcry_md_setkey( GCRY_MD_HD hd, const char *key, size_t keylen )
+{
+    int rc = 0;
+
+    if( !(hd->ctx->macpads ) )
+        rc = GCRYERR_CONFLICT;
+    else if ( !(rc = prepare_macpads( hd, key, keylen )) )
+        gcry_md_reset( hd );
+
+    return rc;
+}
+
+
 /****************
  * if ALGO is null get the digest for the used algo (which should be only one)
  */
index 9a7dd8f..d96cea7 100644 (file)
@@ -27,6 +27,8 @@ void random_dump_stats(void);
 void secure_random_alloc(void);
 int  quick_random_gen( int onoff );
 int  random_is_faked(void);
+void secure_random_alloc(void);
+void random_dump_stats(void);
 byte *get_random_bits( size_t nbits, int level, int secure );
 void fast_random_poll( void );
 
index 2bb4510..f342e3c 100644 (file)
@@ -67,10 +67,7 @@ test_keys( RSA_secret_key *sk, unsigned nbits )
 
     pk.n = sk->n;
     pk.e = sk->e;
-    {  char *p = get_random_bits( nbits, 0, 0 );
-       mpi_set_buffer( test, p, (nbits+7)/8, 0 );
-       g10_free(p);
-    }
+    gcry_mpi_randomize( test, nbits, GCRY_WEAK_RANDOM );
 
     public( out1, test, &pk );
     secret( out2, out1, sk );
index aa3ac09..a0438db 100644 (file)
@@ -108,7 +108,7 @@ transform( SHA1_CONTEXT *hd, byte *data )
 
 #define M(i) ( tm =   x[i&0x0f] ^ x[(i-14)&0x0f] \
                    ^ x[(i-8)&0x0f] ^ x[(i-3)&0x0f] \
-              , (x[i&0x0f] = (tm << 1) | (tm >> 31)) )
+              , (x[i&0x0f] = rol(tm, 1)) )
 
 #define R(a,b,c,d,e,f,k,m)  do { e += rol( a, 5 )     \
                                      + f( b, c, d )  \
index a123c9b..3b4dcd7 100644 (file)
@@ -68,7 +68,8 @@
   specified. It is possible to use these functions as MAC functons; therefore
   the flag <literal/GCRY_MD_FLAG_HMAC/ must be given along with the
   hash functions.  Other MAC algorithms than  HMAC are currently not
-  supported.  The key for the MAC must be set using the gcry_md_setkey macro.
+  supported.  The key for the MAC must be set using
+  the <function>gcry_md_setkey</> function.
   <function>gcry_md_close</function> releases all resources associated
   with the context.
   <function>gcry_md_enable</function> may be used to enable hash
     hash functions into MAC functions. The key may be any string
     of the speicified length.  The type of the MAC is determined
     by special flags set with the open function.
+    NEW:  There is now a function to do this
   </para>
 </refentry>
 
   </para>
 </refentry>
 
+
+<!-- FIXME: doc gcry_md_setkey */
+
index 31032d6..8b93ee7 100644 (file)
     Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
 -->
 
-<!--
-const char *gcry_check_version( const char *req_version );
+<refentry>
+  <refnamediv>
+    <refname>gcry_check_version</refname>
+    <refpurpose>get or check the version of libgcrypt</refpurpose>
+  </refnamediv>
 
-int gcry_errno(void);
-const char *gcry_strerror( int ec );
-int gcry_control( enum gcry_ctl_cmds, ... );
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>const char *<function>gcry_check_version</function></funcdef>
+       <paramdef>const char *<parameter>req_version</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_check_version</primary>
+            </indexterm>
+  <function>gcry_check_version</function> checks
+that the version of the library is at minimum the requested one
+and return the version string; NULL is returned if the condition is
+not met.  You may pass NULL as reqy_version to simply get the version
+string back without any checking.
+  </para>
+</refentry>
+
+<refentry>
+  <refnamediv>
+    <refname>gcry_errno</refname>
+    <refname>gcry_strerror</refname>
+    <refpurpose>Get the last error</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>int <function>gcry_errno</function></funcdef>
+      </funcprototype>
+      <funcprototype>
+       <funcdef>const char *<function>gcry_strerror</function></funcdef>
+       <paramdef>int<parameter>no</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_errno</primary></indexterm>
+  <indexterm><primary>gcry_strerror</primary></indexterm>
+  Both function are to be used like there Standard-C
+  counterparts.  However <function>gcry_errno</function> is a function
+  and not just a global variable.  If -1 is passed to
+  <function>gcry_strerror</>, <function>gcry_errno</> is implictly used.
+  </para>
+</refentry>
+
+
+<refentry>
+  <refnamediv>
+    <refname>gcry_control</refname>
+        <refpurpose>Multi purpose control function</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>int <function>gcry_control</function></funcdef>
+       <paramdef>enum gcry_ctl_cmds<parameter>cmd</parameter></paramdef>
+       <paramdef><parameter>...</parameter></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_control</primary></indexterm>
+  This function is used to control various aspects of &libgcrypt;
+  FIXME: Explain all commands here.
+  </para>
+</refentry>
+
+
+
+
+
+<refentry>
+  <refnamediv>
+    <refname>gcry_set_allocation_handler</refname>
+    <refname>gcry_set_outofcore_handler</refname>
+        <refpurpose>Use application defined malloc functions</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>void <function>gcry_set_allocation_handler</></funcdef>
+       <paramdef>void *(*<parameter>alloc_func</>)(size_t n)</paramdef>
+       <paramdef>void *(*<parameter>alloc_secure_func</>)(size_t n)</paramdef>
+       <paramdef>int (*<parameter>is_secure_func</>)(const void *p)</paramdef>
+       <paramdef>void *(*<parameter>realloc_func</>)(void *p, size_t n)</paramdef>
+       <paramdef>void (*<parameter>free_func</>)(void *p)</paramdef>
+      </funcprototype>
+      <funcprototype>
+       <funcdef>void <function>gcry_set_outofcore_handler</></funcdef>
+
+        <paramdef>int (*<parameter>h</>)( void*, size_t, unsigned int ),
+                                       void *opaque )</paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_set_allocation_handler</primary></indexterm>
+  <indexterm><primary>gcry_set_outofcore_handler</primary></indexterm>
+
+  FIXME
+  </para>
+</refentry>
+
+
+<refentry>
+  <refnamediv>
+    <refname>gcry_set_fatalerror_handler</refname>
+        <refpurpose>change the default fatal error handler</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>void <function>gcry_set_fatalerror_handler</></funcdef>
+       <paramdef>void (*<parameter>func</>)(
+             void *, int, const char*)</paramdef>
+        <paramdef>void *<parameter>opaque</></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_set_fatalerror_handler</primary></indexterm>
+  At certain places the &libgcrypt; may need to call a fatal error fucntion
+  which does terminate the process.  To allow an application to do
+  some emergency cleanup, it may register a fatal error handler with
+  the library.  This handler is assumed to terminate the application;
+  however if it returns &libgcrypt; will abort anyway.
+     </para>
+  <para>
+The handler is called with the opaque value registered here, an
+errorcode from &libgcrypt; and some descriptive text string.
+  </para>
+</refentry>
+
+
+<refentry>
+  <refnamediv>
+    <refname>gcry_set_gettext_handler</refname>
+        <refpurpose>Change the default gettext function</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>void <function>gcry_set_gettext_handler</></funcdef>
+       <paramdef>const char *(*<parameter>func</>)(const char*)</paramdef>
+        <paramdef>void *<parameter>opaque</></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_set_log_handler</primary></indexterm>
+  FIXME!!
+  </para>
+</refentry>
 
 
 
 
-void gcry_set_allocation_handler( void *(*new_alloc_func)(size_t n),
-                                 void *(*new_alloc_secure_func)(size_t n),
-                                 int (*new_is_secure_func)(const void*),
-                                 void *(*new_realloc_func)(void *p, size_t n),
-                                 void (*new_free_func)(void*) );
-void gcry_set_outofcore_handler( int (*h)( void*, size_t, unsigned int ),
-                                                               void *opaque );
-void gcry_set_fatalerror_handler( void (*fnc)(void*,int, const char*),
-                                                               void *opaque );
-void gcry_set_gettext_handler( const char *(*f)(const char*) );
 void gcry_set_log_handler( void (*f)(void*,int, const char*, va_list ),
                                                             void *opaque );
+<refentry>
+  <refnamediv>
+    <refname>gcry_set_log_handler</refname>
+        <refpurpose>Change the default logging function</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>void <function>gcry_set_log_handler</></funcdef>
+       <paramdef>void (*<parameter>func</>)
+         (void*, int, const char*, va_list)</paramdef>
+        <paramdef>void *<parameter>opaque</></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_set_log_handler</primary></indexterm>
+  &libgcrypt; has it;s own logging functions.  Applications which 
+  need to use their own, should provide a log function to &libgcrypt;
+so that it will use this function instead.
+
+Fixme: Describe how this is intended to work.
+  </para>
+</refentry>
+
 
 void *gcry_malloc( size_t n );
 void *gcry_calloc( size_t n, size_t m );
@@ -55,6 +265,53 @@ char *gcry_xstrdup( const char * a);
 void  gcry_free( void *a );
 int   gcry_is_secure( const void *a );
 
+<refentry>
+  <refnamediv>
+    <refname>gcry_malloc</refname>
+    <refname>gcry_calloc</refname>
+    <refname>gcry_malloc_secure</refname>
+    <refname>gcry_calloc_secure</refname>
+    <refname>gcry_realloc</refname>
+    <refname>gcry_xmalloc</refname>
+    <refname>gcry_xcalloc</refname>
+    <refname>gcry_xmalloc_secure</refname>
+    <refname>gcry_xcalloc_secure</refname>
+    <refname>gcry_xrealloc</refname>
+    <refname>gcry_xstrdup</refname>
+
+  WORk WORK
+    <refname>gcry_malloc</refname>
+    <refname>gcry_malloc</refname>
+    
+        <refpurpose>Change the default logging function</refpurpose>
+  </refnamediv>
+
+  <refsynopsisdiv>
+    <funcsynopsis>
+      <funcsynopsisinfo>
+      #include &lt;gcrypt.h&gt;
+      </funcsynopsisinfo>
+      <funcprototype>
+       <funcdef>void <function>gcry_set_log_handler</></funcdef>
+       <paramdef>void (*<parameter>func</>)
+         (void*, int, const char*, va_list)</paramdef>
+        <paramdef>void *<parameter>opaque</></paramdef>
+      </funcprototype>
+    </funcsynopsis>
+  </refsynopsisdiv>
+
+  <refsect1><title>Description</title>
+  <para>
+  <indexterm><primary>gcry_set_log_handler</primary></indexterm>
+  &libgcrypt; has it;s own logging functions.  Applications which 
+  need to use their own, should provide a log function to &libgcrypt;
+so that it will use this function instead.
+
+Fixme: Describe how this is intended to work.
+  </para>
+</refentry>
+
+
 
 void gcry_randomize( byte *buffer, size_t length,
                     enum gcry_random_level level );
@@ -65,3 +322,5 @@ void *gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level );
 
     -->
 
+
+
index 7cb0f17..fb25e7f 100644 (file)
@@ -1,3 +1,18 @@
+Wed Oct  4 13:16:18 CEST 2000  Werner Koch  <wk@openit.de>
+
+        * getkey.c (merge_selfsigs_main): Fixed for v3 keys.
+
+        * sign.c (hash_for): New arg to take packet version in account. Changed
+        all callers.
+        (write_one_sig): New. Moved the shared code from sign_file and
+        clearsign_file to here.
+        * skclist.c (build_sk_list): Fixed usage check.
+        * pkclist.c (build_pk_list): Ditto.
+
+        * encode.c (encode_crypt): Removed duplicated stuff by using
+        encrypt_filter as sign.c already did.  Removed already disabled
+        comment-packet code.
+
 Mon Sep 18 16:35:45 CEST 2000  Werner Koch  <wk@openit.de>
 
         * parse-packet.c (dump_sig_subpkt): Dump key flags.
index a817f90..f033c76 100644 (file)
@@ -293,18 +293,17 @@ encode_crypt( const char *filename, STRLIST remusr )
     PKT_plaintext *pt = NULL;
     int rc = 0;
     u32 filesize;
-    cipher_filter_context_t cfx;
     armor_filter_context_t afx;
     compress_filter_context_t zfx;
     text_filter_context_t tfx;
+    encrypt_filter_context_t efx;
     PK_LIST pk_list;
     int do_compress = opt.compress && !opt.rfc1991;
 
-
-    memset( &cfx, 0, sizeof cfx);
     memset( &afx, 0, sizeof afx);
     memset( &zfx, 0, sizeof zfx);
     memset( &tfx, 0, sizeof tfx);
+    memset( &efx, 0, sizeof efx);
     init_packet(&pkt);
 
     if( (rc=build_pk_list( remusr, &pk_list, GCRY_PK_USAGE_ENCR)) )
@@ -320,83 +319,67 @@ encode_crypt( const char *filename, STRLIST remusr )
     else if( opt.verbose )
        log_info(_("reading from `%s'\n"), filename? filename: "[stdin]");
 
+    /* If the user selected textmode, push the text filter onto the input */
     if( opt.textmode )
        iobuf_push_filter( inp, text_filter, &tfx );
 
+    /* Now we can create the outputfile */
     if( (rc = open_outfile( filename, opt.armor? 1:0, &out )) )
        goto leave;
 
-
+    /* The first thing we have to push on the output stream
+     * is the armor filter */
     if( opt.armor )
        iobuf_push_filter( out, armor_filter, &afx );
-  #ifdef ENABLE_COMMENT_PACKETS
-    else {
-       write_comment( out, "#created by GNUPG v" VERSION " ("
-                                           PRINTABLE_OS_NAME ")");
-       if( opt.comment_string )
-           write_comment( out, opt.comment_string );
-    }
-  #endif
-    /* create a session key */
-    cfx.dek = gcry_xmalloc_secure( sizeof *cfx.dek );
-    if( !opt.def_cipher_algo ) { /* try to get it from the prefs */
-       cfx.dek->algo = select_algo_from_prefs( pk_list, PREFTYPE_SYM );
-       if( cfx.dek->algo == -1 )
-           cfx.dek->algo = DEFAULT_CIPHER_ALGO;
-    }
-    else
-       cfx.dek->algo = opt.def_cipher_algo;
-    make_session_key( cfx.dek );
-    if( DBG_CIPHER )
-       log_hexdump("DEK is: ", cfx.dek->key, cfx.dek->keylen );
-
-    rc = write_pubkey_enc_from_list( pk_list, cfx.dek, out );
-    if( rc  )
-       goto leave;
-
-    if (!opt.no_literal) {
-       /* setup the inner packet */
-       if( filename || opt.set_filename ) {
-           char *s = make_basename( opt.set_filename ? opt.set_filename : filename );
-           pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
-           pt->namelen = strlen(s);
-           memcpy(pt->name, s, pt->namelen );
-           gcry_free(s);
-       }
-       else { /* no filename */
-           pt = gcry_xmalloc( sizeof *pt - 1 );
-           pt->namelen = 0;
-       }
-    }
-
-    if( filename && !opt.textmode ) {
-       if( !(filesize = iobuf_get_filelength(inp)) )
-           log_info(_("%s: WARNING: empty file\n"), filename );
-        /* we can't yet encode the length of very large files,
-         * so we switch to partial lengthn encoding in this case */
-        if ( filesize >= IOBUF_FILELENGTH_LIMIT )
-            filesize = 0;
-    }
-    else
-       filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
-
-    if (!opt.no_literal) {
-       pt->timestamp = make_timestamp();
-       pt->mode = opt.textmode ? 't' : 'b';
-       pt->len = filesize;
-       pt->new_ctb = !pt->len && !opt.rfc1991;
-       pt->buf = inp;
-       pkt.pkttype = PKT_PLAINTEXT;
-       pkt.pkt.plaintext = pt;
-       cfx.datalen = filesize && !do_compress? calc_packet_length( &pkt ) : 0;
-    }
-    else
-       cfx.datalen = filesize && !do_compress ? filesize : 0;
-
-    /* register the cipher filter */
-    iobuf_push_filter( out, cipher_filter, &cfx );
 
-    /* register the compress filter */
+    /* Prepare the plaintext packet */
+    {
+        if (!opt.no_literal) {
+            if( filename || opt.set_filename ) {
+                char *s = make_basename( opt.set_filename ?
+                                         opt.set_filename : filename );
+                pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
+                pt->namelen = strlen(s);
+                memcpy(pt->name, s, pt->namelen );
+                gcry_free(s);
+            }
+            else { /* no filename */
+                pt = gcry_xmalloc( sizeof *pt - 1 );
+                pt->namelen = 0;
+            }
+        }
+        
+        if( filename && !opt.textmode ) {
+            if( !(filesize = iobuf_get_filelength(inp)) )
+                log_info(_("%s: WARNING: empty file\n"), filename );
+            /* we can't yet encode the length of very large files,
+             * so we switch to partial lengthn encoding in this case */
+            if ( filesize >= IOBUF_FILELENGTH_LIMIT )
+                filesize = 0;
+        }
+        else
+            filesize = opt.set_filesize ? opt.set_filesize : 0; /* stdin */
+        
+        if (!opt.no_literal) {
+            pt->timestamp = make_timestamp();
+            pt->mode = opt.textmode ? 't' : 'b';
+            pt->len = filesize;
+            pt->new_ctb = !pt->len && !opt.rfc1991;
+            pt->buf = inp;
+            pkt.pkttype = PKT_PLAINTEXT;
+            pkt.pkt.plaintext = pt;
+            efx.cfx.datalen = filesize && !do_compress?
+                calc_packet_length( &pkt ) : 0;
+        }
+        else
+            efx.cfx.datalen = filesize && !do_compress ? filesize : 0;
+    }  /* end preparation of plaintext packet */
+        
+    /* push in the actual encryption filter */
+    efx.pk_list = pk_list;
+    iobuf_push_filter( out, encrypt_filter, &efx ); 
+
+    /* register the compress filter (so that it is done before encryption) */
     if( do_compress ) {
        int compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR );
        if( !compr_algo )
@@ -414,7 +397,8 @@ encode_crypt( const char *filename, STRLIST remusr )
            log_error("build_packet failed: %s\n", gpg_errstr(rc) );
     }
     else {
-       /* user requested not to create a literal packet, so we copy the plain data */
+       /* user requested not to create a literal packet,
+         * so we copy the plain data */
        byte copy_buffer[4096];
        int  bytes_copied;
        while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
@@ -423,7 +407,7 @@ encode_crypt( const char *filename, STRLIST remusr )
                log_error("copying input to output failed: %s\n", gpg_errstr(rc) );
                break;
            }
-       memset(copy_buffer, 0, 4096); /* burn buffer */
+       memset(copy_buffer, 0, DIM(copy_buffer)); /* burn buffer */
     }
 
     /* finish the stuff */
@@ -436,7 +420,8 @@ encode_crypt( const char *filename, STRLIST remusr )
     if( pt )
        pt->buf = NULL;
     free_packet(&pkt);
-    gcry_free(cfx.dek);
+    gcry_free(efx.cfx.dek); /* Hmmm, why does the encrypt filter does not 
+                             * take care about this? */
     release_pk_list( pk_list );
     return rc;
 }
@@ -445,7 +430,7 @@ encode_crypt( const char *filename, STRLIST remusr )
 
 
 /****************
- * Filter to do a complete public key encryption.
+ * Filter to handle the entire public key encryption.
  */
 int
 encrypt_filter( void *opaque, int control,
index 2de9f91..ddcc971 100644 (file)
@@ -162,7 +162,7 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any )
            log_error(_("certificate read problem: %s\n"), gpg_errstr(rc));
            goto leave;
        }
-
+      
 
        /* do not export keys which are incompatible with rfc2440 */
        if( onlyrfc && (node = find_kbnode( keyblock, PKT_PUBLIC_KEY )) ) {
index 17dc6fa..aa32dff 100644 (file)
@@ -795,12 +795,19 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
     ctx->nitems = n;
 
     for(n=0, r=namelist; r; r = r->next, n++ ) {
-       ctx->items[n].mode = classify_user_id( r->d,
-                                             ctx->items[n].keyid,
-                                             ctx->items[n].fprint,
-                                             &ctx->items[n].name,
-                                             NULL );
-       if( !ctx->items[n].mode ) {
+       int mode = classify_user_id( r->d,
+                                 ctx->items[n].keyid,
+                                 ctx->items[n].fprint,
+                                 &ctx->items[n].name,
+                                 NULL );
+
+        /* if we don't use one of the exact key specifications, we assume that
+         * the primary key is requested */
+        if ( mode != 10 && mode != 11 && mode != 16 && mode == 20 )
+            ctx->primary = 1; 
+
+       ctx->items[n].mode = mode;
+        if( !ctx->items[n].mode ) {
            gcry_free( ctx );
            return GPGERR_INV_USER_ID;
        }
@@ -810,8 +817,7 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist,
        }
     }
 
-    /* and call the lookup function */
-    ctx->primary = 1; /* we want to look for the primary key only */
+
 
     if ( !ret_kb ) 
         ret_kb = &help_kb;
@@ -1337,8 +1343,13 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
     pk->main_keyid[0] = kid[0];
     pk->main_keyid[1] = kid[1];
 
-    if ( pk->version < 4 ) 
-        return; /* nothing to do for old keys FIXME: This is wrong!!!!*/
+    if ( pk->version < 4 ) {
+        /* before v4 the key packet itself contains the expiration date
+         * and there was noway to change it.  So we also use only the
+         * one from the key packet */
+        key_expire = pk->expiredate;
+        key_expire_seen = 1;
+    }
 
     /* first pass: find the latest direct key self-signature.
      * We assume that the newest one overrides all others
@@ -1394,12 +1405,14 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
                 key_usage |= GCRY_PK_USAGE_ENCR;
         }
 
-        p = parse_sig_subpkt ( sig->hashed_data, SIGSUBPKT_KEY_EXPIRE, NULL);
-        if ( p ) {
-            key_expire = sig->timestamp + buffer_to_u32(p);
-            key_expire_seen = 1;
+        if ( pk->version > 3 ) {
+            p = parse_sig_subpkt ( sig->hashed_data,
+                                   SIGSUBPKT_KEY_EXPIRE, NULL);
+            if ( p ) {
+                key_expire = sig->timestamp + buffer_to_u32(p);
+                key_expire_seen = 1;
+            }
         }
-
         /* and set the created field */
         pk->created = sigdate;
         /* and mark that key as valid: one direct key signature should 
@@ -1518,8 +1531,8 @@ merge_selfsigs_main( KBNODE keyblock, int *r_revoked )
             }
        }
     }
-    if ( key_expire >= curtime )
-        pk->has_expired = key_expire;
+   
+    pk->has_expired = key_expire >= curtime? 0 : key_expire;
     /* FIXME: we should see how to get rid of the expiretime fields */
 
 
@@ -1651,7 +1664,7 @@ merge_selfsigs_subkey( KBNODE keyblock, KBNODE subnode )
         key_expire = sig->timestamp + buffer_to_u32(p);
     else
         key_expire = 0;
-    subpk->has_expired = key_expire >= curtime? key_expire : 0;
+    subpk->has_expired = key_expire >= curtime? 0 : key_expire;
 }
 
 
@@ -1711,7 +1724,7 @@ merge_selfsigs( KBNODE keyblock )
  * keys at all and have a way to store just the real secret parts
  * from the key.
  */
-static void
+void
 merge_public_with_secret ( KBNODE pubblock, KBNODE secblock )
 {
     KBNODE pub;
@@ -1942,8 +1955,8 @@ finish_lookup( GETKEY_CTX ctx,  KBNODE foundk )
             }
 
             if (DBG_CACHE)
-                log_debug( "\tconsidering key created %lu\n",
-                           (ulong)pk->created);
+                log_debug( "\tconsidering key %08lX\n",
+                           (ulong)keyid_from_pk( pk, NULL));
             if ( pk->created > latest_date ) {
                 latest_date = pk->created;
                 latest_key  = k;
@@ -1989,7 +2002,8 @@ finish_lookup( GETKEY_CTX ctx,  KBNODE foundk )
     }
 
     if (DBG_CACHE)
-        log_debug( "\tusing key created %lu\n", (ulong)latest_date );
+        log_debug( "\tusing key %08lX\n",
+                (ulong)keyid_from_pk( latest_key->pkt->pkt.public_key, NULL) );
 
     ctx->found_key = latest_key;
 
index be4ec98..6faeb07 100644 (file)
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -509,6 +509,10 @@ static void
 register_extension( const char *mainpgm, const char *fname )
 {
   #warning fixme add register cipher extension
+    /* Before we do so, we should design a beter API for this.
+     * I am currently thinking about using S-Exp to pass everything we 
+     * need from the module to gcrypt. I hope we are not going to 
+     * implement my-own-lisp-library-no-17000 */
   #if 0
     if( *fname != '/' ) { /* do tilde expansion etc */
        char *tmp;
index 830a7db..43c36e7 100644 (file)
@@ -166,6 +166,7 @@ int get_seckey_next( GETKEY_CTX ctx, PKT_secret_key *sk, KBNODE *ret_keyblock );
 void get_seckey_end( GETKEY_CTX ctx );
 int enum_secret_keys( void **context, PKT_secret_key *sk, int with_subkeys );
 void merge_keys_and_selfsig( KBNODE keyblock );
+void merge_public_with_secret ( KBNODE pubblock, KBNODE secblock );
 char*get_user_id_string( u32 *keyid );
 char*get_user_id_string_native( u32 *keyid );
 char*get_long_user_id_string( u32 *keyid );
index fc3b2cf..ef0064f 100644 (file)
@@ -294,7 +294,6 @@ gen_elg(int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
        STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
 {
     int rc;
-    int i;
     PACKET *pkt;
     PKT_secret_key *sk;
     PKT_public_key *pk;
@@ -407,7 +406,6 @@ gen_dsa(unsigned int nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
            STRING2KEY *s2k, PKT_secret_key **ret_sk, u32 expireval )
 {
     int rc;
-    int i;
     PACKET *pkt;
     PKT_secret_key *sk;
     PKT_public_key *pk;
@@ -948,7 +946,6 @@ ask_user_id( int mode )
 
        /* append a warning if we do not have dev/random
         * or it is switched into  quick testmode */
-       #warning quick_random_gen() not available
       #if 0
        if( quick_random_gen(-1) )
            strcpy(p, " (INSECURE!)" );
index fb652e7..a4acb16 100644 (file)
@@ -454,7 +454,7 @@ fingerprint_from_sk( PKT_secret_key *sk, byte *array, size_t *ret_len )
            int rc;
            size_t nbytes;
 
-           #warning Why is the hash sequence for secret keys different
+           /* FIXME: Why is the hash sequence for secret keys different */
            rc = gcry_mpi_print( GCRYMPI_FMT_USG, NULL, &nbytes, sk->skey[1] );
            assert( !rc );
            /* fixme: allocate it on the stack */
index a62a047..2348e46 100644 (file)
@@ -330,6 +330,7 @@ print_cipher_algo_note( int algo )
     else if(   algo == GCRY_CIPHER_3DES
             || algo == GCRY_CIPHER_CAST5
             || algo == GCRY_CIPHER_BLOWFISH
+             || algo == GCRY_CIPHER_RIJNDAEL
             || algo == GCRY_CIPHER_TWOFISH
           )
        ;
index d827ce6..d585880 100644 (file)
@@ -819,7 +819,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
                free_public_key( pk ); pk = NULL;
                log_error(_("%s: skipped: %s\n"), rov->d, gpg_errstr(rc) );
            }
-           else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
+           else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+                                               pk->pubkey_usage)) ) {
                /* Skip the actual key if the key is already present
                 * in the list */
                if (key_present_in_pk_list(pk_list, pk) == 0) {
@@ -874,7 +875,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
            rc = get_pubkey_byname( NULL, pk, answer, NULL );
            if( rc )
                tty_printf(_("No such user ID.\n"));
-           else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) {
+           else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+                                               pk->pubkey_usage)) ) {
                if( have_def_rec ) {
                    if (key_present_in_pk_list(pk_list, pk) == 0) {
                        free_public_key(pk); pk = NULL;
@@ -940,7 +942,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
        rc = get_pubkey_byname( NULL, pk, def_rec, NULL );
        if( rc )
            log_error(_("unknown default recipient `%s'\n"), def_rec );
-       else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) {
+       else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+                                           pk->pubkey_usage)) ) {
            PK_LIST r = gcry_xmalloc( sizeof *r );
            r->pk = pk; pk = NULL;
            r->next = pk_list;
@@ -966,7 +969,8 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use )
                free_public_key( pk ); pk = NULL;
                log_error(_("%s: skipped: %s\n"), remusr->d, gpg_errstr(rc) );
            }
-           else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) {
+           else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo,
+                                               pk->pubkey_usage)) ) {
                int trustlevel;
 
                rc = check_trust( pk, &trustlevel, pk->namehash, NULL, NULL );
index 0be514e..2adb9ef 100644 (file)
@@ -75,7 +75,6 @@ pk_check_secret_key( int algo, MPI *skey )
 static int
 do_check( PKT_secret_key *sk )
 {
-    byte *buffer;
     u16 csum=0;
     int i, res;
     unsigned nbytes;
@@ -324,7 +323,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
                                                         GCRY_STRONG_RANDOM);
            gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen );
 
-           #warning FIXME: replace set/get buffer
+           /* FIXME: replace set/get buffer */
            if( sk->version >= 4 ) {
                byte *bufarr[GNUPG_MAX_NSKEY];
                unsigned narr[GNUPG_MAX_NSKEY];
@@ -336,7 +335,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
                        i < pubkey_get_nskey(sk->pubkey_algo); i++, j++ ) {
                    assert( !gcry_mpi_get_flag( sk->skey[i], GCRYMPI_FLAG_OPAQUE ) );
 
-                   if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (char*)bufarr+j,
+                   if( gcry_mpi_aprint( GCRYMPI_FMT_USG, (void**)bufarr+j,
                                                          narr+j, sk->skey[i]))
                        BUG();
 
@@ -374,7 +373,7 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek )
            else {
                /* NOTE: we always recalculate the checksum because there
                 * are some test releases which calculated it wrong */
-              #warning FIXME:  Replace this code
+               /* FIXME: Replace this code -- Hmmm: why */
                csum = 0;
                for(i=pubkey_get_npkey(sk->pubkey_algo);
                        i < pubkey_get_nskey(sk->pubkey_algo); i++ ) {
index b53444b..bdc5b8a 100644 (file)
@@ -40,6 +40,8 @@
 #include "i18n.h"
 
 
+#define ENABLE_BETTER_PGP2_COMPAT 1
+
 #ifdef HAVE_DOSISH_SYSTEM
   #define LF "\r\n"
 #else
@@ -217,13 +219,13 @@ complete_sig( PKT_signature *sig, PKT_secret_key *sk, GCRY_MD_HD md )
 }
 
 static int
-hash_for(int pubkey_algo )
+hash_for(int pubkey_algo, int packet_version )
 {
     if( opt.def_digest_algo )
        return opt.def_digest_algo;
     if( pubkey_algo == GCRY_PK_DSA )
        return GCRY_MD_SHA1;
-    if( pubkey_algo == GCRY_PK_RSA )
+    if( pubkey_algo == GCRY_PK_RSA && packet_version < 4 )
        return GCRY_MD_MD5;
     return DEFAULT_DIGEST_ALGO;
 }
@@ -265,6 +267,94 @@ print_status_sig_created ( PKT_secret_key *sk, PKT_signature *sig, int what )
     write_status_text( STATUS_SIG_CREATED, buf );
 }
 
+static int
+write_one_signature( IOBUF out, PKT_secret_key *sk, int old_style,
+                     const char *outfile,
+                     GCRY_MD_HD datamd,
+                     int sig_class,
+                     int status_char )
+{
+    PKT_signature *sig;
+    GCRY_MD_HD md;
+    int rc;
+
+    /* build the signature packet */
+    /* fixme: this code is partly duplicated in make_keysig_packet */
+    sig = gcry_xcalloc( 1, sizeof *sig );
+    sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
+    keyid_from_sk( sk, sig->keyid );
+    sig->digest_algo = hash_for(sk->pubkey_algo, sk->version);
+    sig->pubkey_algo = sk->pubkey_algo;
+    sig->timestamp = make_timestamp();
+    sig->sig_class = sig_class;
+
+    md = gcry_md_copy( datamd );
+    if( !md )
+        BUG();
+    if( sig->version >= 4 ) {
+        build_sig_subpkt_from_sig( sig );
+        gcry_md_putc( md, sig->version );
+    }
+    
+    mk_notation_and_policy( sig );
+    
+    gcry_md_putc( md, sig->sig_class );
+    if( sig->version < 4 ) {
+        u32 a = sig->timestamp;
+        gcry_md_putc( md, (a >> 24) & 0xff );
+        gcry_md_putc( md, (a >> 16) & 0xff );
+        gcry_md_putc( md, (a >>  8) & 0xff );
+        gcry_md_putc( md,  a   & 0xff );
+    }
+    else {
+        byte buf[6];
+        size_t n;
+        
+        gcry_md_putc( md, sig->pubkey_algo );
+        gcry_md_putc( md, sig->digest_algo );
+        if( sig->hashed_data ) {
+            n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
+            gcry_md_write( md, sig->hashed_data, n+2 );
+            n += 6;
+        }
+        else {
+            gcry_md_putc( md, 0 );/* always hash the length of the subpacket*/
+            gcry_md_putc( md, 0 );
+            n = 6;
+        }
+        /* add some magic */
+        buf[0] = sig->version;
+        buf[1] = 0xff;
+        buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
+        buf[3] = n >> 16;
+        buf[4] = n >>  8;
+        buf[5] = n;
+        gcry_md_write( md, buf, 6 );
+    }
+    gcry_md_final( md );
+
+    rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo, sk->version) );
+    gcry_md_close( md );
+    /* Hmmm: Do we release sig in case of rc != 0? */
+    
+    if( !rc ) { /* and write it */
+        PACKET pkt;
+
+        init_packet(&pkt);
+        pkt.pkttype = PKT_SIGNATURE;
+        pkt.pkt.signature = sig;
+        rc = build_packet( out, &pkt );
+        if( !rc && is_status_enabled() ) {
+            print_status_sig_created ( sk, sig, status_char );       
+        }
+        free_packet( &pkt );
+        if( rc )
+            log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
+    }
+
+    return rc;
+}
+
 
 /****************
  * Sign the files whose names are in FILENAME.
@@ -360,7 +450,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
 
     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
        PKT_secret_key *sk = sk_rover->sk;
-       gcry_md_enable(mfx.md, hash_for(sk->pubkey_algo));
+       gcry_md_enable(mfx.md, hash_for(sk->pubkey_algo, sk->version ));
     }
 
     if( !multifile )
@@ -385,6 +475,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
        iobuf_push_filter( out, encrypt_filter, &efx );
     }
 
+    /* Select a compress algorithm */
     if( opt.compress && !outfile && ( !detached || opt.compress_sigs) ) {
        if( !compr_algo )
            ; /* don't use compression */
@@ -397,6 +488,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
        }
     }
 
+    /* Build one-pass signature packets when needed */
     if( !detached && !old_style ) {
        int skcount=0;
        /* loop over the secret certificates and build headers
@@ -417,7 +509,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
            sk = sk_rover->sk;
            ops = gcry_xcalloc( 1, sizeof *ops );
            ops->sig_class = opt.textmode && !outfile ? 0x01 : 0x00;
-           ops->digest_algo = hash_for(sk->pubkey_algo);
+           ops->digest_algo = hash_for(sk->pubkey_algo, sk->version);
            ops->pubkey_algo = sk->pubkey_algo;
            keyid_from_sk( sk, ops->keyid );
            ops->last = skcount == 1;
@@ -437,6 +529,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
 
     /* setup the inner packet */
     if( detached ) {
+        /* this is pretty much the same for old and new PGP.  So no
+         * need to cope with different packet ordering */
        if( multifile ) {
            STRLIST sl;
 
@@ -468,9 +562,11 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
        }
     }
     else {
+        /* get the filename to be stored into the literal datapacket */
        if (!opt.no_literal) {
            if( fname || opt.set_filename ) {
-               char *s = make_basename( opt.set_filename ? opt.set_filename : fname );
+               char *s = make_basename( opt.set_filename ?
+                                         opt.set_filename : fname );
                pt = gcry_xmalloc( sizeof *pt + strlen(s) - 1 );
                pt->namelen = strlen(s);
                memcpy(pt->name, s, pt->namelen );
@@ -490,7 +586,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
             if ( filesize >= IOBUF_FILELENGTH_LIMIT )
                 filesize = 0;
 
-           /* because the text_filter modifies the length of the
+           /* Because the text_filter modifies the length of the
             * data, it is not possible to know the used length
             * without a double read of the file - to avoid that
             * we simple use partial length packets.
@@ -511,7 +607,8 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
            pkt.pkt.plaintext = pt;
            /*cfx.datalen = filesize? calc_packet_length( &pkt ) : 0;*/
            if( (rc = build_packet( out, &pkt )) )
-               log_error("build_packet(PLAINTEXT) failed: %s\n", gpg_errstr(rc) );
+               log_error("build_packet(PLAINTEXT) failed: %s\n",
+                          gpg_errstr(rc) );
            pt->buf = NULL;
        }
        else {
@@ -520,100 +617,24 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
            while ((bytes_copied = iobuf_read(inp, copy_buffer, 4096)) != -1)
                if (iobuf_write(out, copy_buffer, bytes_copied) == -1) {
                    rc = GPGERR_WRITE_FILE;
-                   log_error("copying input to output failed: %s\n", gpg_errstr(rc));
+                   log_error("copying input to output failed: %s\n",
+                              gpg_errstr(rc));
                    break;
                }
            memset(copy_buffer, 0, 4096); /* burn buffer */
        }
     }
 
-    /* catch errors from above blocks */
+    /* catch errors from above */
     if (rc)
        goto leave;
 
-    /* loop over the secret certificates */
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-       PKT_secret_key *sk;
-       PKT_signature *sig;
-       GCRY_MD_HD md;
-
-       sk = sk_rover->sk;
-
-       /* build the signature packet */
-       /* fixme: this code is partly duplicated in make_keysig_packet */
-       sig = gcry_xcalloc( 1, sizeof *sig );
-       sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
-       keyid_from_sk( sk, sig->keyid );
-       sig->digest_algo = hash_for(sk->pubkey_algo);
-       sig->pubkey_algo = sk->pubkey_algo;
-       sig->timestamp = make_timestamp();
-       sig->sig_class = opt.textmode && !outfile? 0x01 : 0x00;
-
-       md = gcry_md_copy( mfx.md );
-       if( !md )
-           BUG();
-
-       if( sig->version >= 4 ) {
-           build_sig_subpkt_from_sig( sig );
-           gcry_md_putc( md, sig->version );
-       }
-
-       mk_notation_and_policy( sig );
-
-       gcry_md_putc( md, sig->sig_class );
-       if( sig->version < 4 ) {
-           u32 a = sig->timestamp;
-           gcry_md_putc( md, (a >> 24) & 0xff );
-           gcry_md_putc( md, (a >> 16) & 0xff );
-           gcry_md_putc( md, (a >>  8) & 0xff );
-           gcry_md_putc( md,  a        & 0xff );
-       }
-       else {
-           byte buf[6];
-           size_t n;
-
-           gcry_md_putc( md, sig->pubkey_algo );
-           gcry_md_putc( md, sig->digest_algo );
-           if( sig->hashed_data ) {
-               n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
-               gcry_md_write( md, sig->hashed_data, n+2 );
-               n += 6;
-           }
-           else {
-               gcry_md_putc( md, 0 );  /* always hash the length of the subpacket*/
-               gcry_md_putc( md, 0 );
-               n = 6;
-           }
-           /* add some magic */
-           buf[0] = sig->version;
-           buf[1] = 0xff;
-           buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
-           buf[3] = n >> 16;
-           buf[4] = n >>  8;
-           buf[5] = n;
-           gcry_md_write( md, buf, 6 );
-
-       }
-       gcry_md_final( md );
-
-       rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo) );
-       gcry_md_close( md );
-
-       if( !rc ) { /* and write it */
-           init_packet(&pkt);
-           pkt.pkttype = PKT_SIGNATURE;
-           pkt.pkt.signature = sig;
-           rc = build_packet( out, &pkt );
-           if( !rc && is_status_enabled() ) {
-               print_status_sig_created ( sk, sig, detached ? 'D':'S');
-           }
-           free_packet( &pkt );
-           if( rc )
-               log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
-       }
-       if( rc )
-           goto leave;
-
+    /* write all the signature packets */
+    for( sk_rover = sk_list; sk_rover && !rc ; sk_rover = sk_rover->next ) {
+        rc = write_one_signature( out, sk_rover->sk,
+                                  old_style, outfile, mfx.md,
+                                  opt.textmode && !outfile? 0x01 : 0x00,
+                                  detached ? 'D':'S' );
     }
 
 
@@ -626,6 +647,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr,
     gcry_md_close( mfx.md );
     release_sk_list( sk_list );
     release_pk_list( pk_list );
+    /* FIXME: Did we release the efx.cfx.dek ? */
     return rc;
 }
 
@@ -679,7 +701,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
 
     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
        PKT_secret_key *sk = sk_rover->sk;
-       if( hash_for(sk->pubkey_algo) == GCRY_MD_MD5 )
+       if( hash_for(sk->pubkey_algo, sk->version) == GCRY_MD_MD5 )
            only_md5 = 1;
        else {
            only_md5 = 0;
@@ -697,7 +719,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
        iobuf_writestr(out, "Hash: " );
        for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
            PKT_secret_key *sk = sk_rover->sk;
-           int i = hash_for(sk->pubkey_algo);
+           int i = hash_for(sk->pubkey_algo, sk->version);
 
            if( !hashs_seen[ i & 0xff ] ) {
                if( !openpgp_md_test_algo( i ) ) {
@@ -723,7 +745,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
        BUG();
     for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
        PKT_secret_key *sk = sk_rover->sk;
-       gcry_md_enable(textmd, hash_for(sk->pubkey_algo));
+       gcry_md_enable(textmd, hash_for(sk->pubkey_algo, sk->version));
     }
     if ( DBG_HASHING )
        gcry_md_start_debug( textmd, "clearsign" );
@@ -735,90 +757,14 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile )
     afx.what = 2;
     iobuf_push_filter( out, armor_filter, &afx );
 
-    /* loop over the secret certificates */
-    for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) {
-       PKT_secret_key *sk;
-       PKT_signature *sig;
-       GCRY_MD_HD md;
-
-       sk = sk_rover->sk;
-
-       /* build the signature packet */
-       /* fixme: this code is duplicated above */
-       sig = gcry_xcalloc( 1, sizeof *sig );
-       sig->version = old_style || opt.force_v3_sigs ? 3 : sk->version;
-       keyid_from_sk( sk, sig->keyid );
-       sig->digest_algo = hash_for(sk->pubkey_algo);
-       sig->pubkey_algo = sk->pubkey_algo;
-       sig->timestamp = make_timestamp();
-       sig->sig_class = 0x01;
-
-       md = gcry_md_copy( textmd );
-       if( !md )
-           BUG();
-       if( sig->version >= 4 ) {
-           build_sig_subpkt_from_sig( sig );
-           gcry_md_putc( md, sig->version );
-       }
-
-       mk_notation_and_policy( sig );
-
-       gcry_md_putc( md, sig->sig_class );
-       if( sig->version < 4 ) {
-           u32 a = sig->timestamp;
-           gcry_md_putc( md, (a >> 24) & 0xff );
-           gcry_md_putc( md, (a >> 16) & 0xff );
-           gcry_md_putc( md, (a >>  8) & 0xff );
-           gcry_md_putc( md,  a        & 0xff );
-       }
-       else {
-           byte buf[6];
-           size_t n;
-
-           gcry_md_putc( md, sig->pubkey_algo );
-           gcry_md_putc( md, sig->digest_algo );
-           if( sig->hashed_data ) {
-               n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
-               gcry_md_write( md, sig->hashed_data, n+2 );
-               n += 6;
-           }
-           else {
-               gcry_md_putc( md, 0 );  /* always hash the length of the subpacket*/
-               gcry_md_putc( md, 0 );
-               n = 6;
-           }
-           /* add some magic */
-           buf[0] = sig->version;
-           buf[1] = 0xff;
-           buf[2] = n >> 24; /* hmmm, n is only 16 bit, so this is always 0 */
-           buf[3] = n >> 16;
-           buf[4] = n >>  8;
-           buf[5] = n;
-           gcry_md_write( md, buf, 6 );
-
-       }
-       gcry_md_final( md );
-
-       rc = do_sign( sk, sig, md, hash_for(sig->pubkey_algo) );
-       gcry_md_close( md );
-
-       if( !rc ) { /* and write it */
-           init_packet(&pkt);
-           pkt.pkttype = PKT_SIGNATURE;
-           pkt.pkt.signature = sig;
-           rc = build_packet( out, &pkt );
-           if( !rc && is_status_enabled() ) {
-               print_status_sig_created ( sk, sig, 'C');
-           }
-           free_packet( &pkt );
-           if( rc )
-               log_error("build signature packet failed: %s\n", gpg_errstr(rc) );
-       }
-       if( rc )
-           goto leave;
+    /* write all the signature packets */
+    for( sk_rover = sk_list; sk_rover && !rc ; sk_rover = sk_rover->next ) {
+        rc = write_one_signature( out, sk_rover->sk,
+                                  old_style, outfile, textmd,
+                                  0x01,
+                                  'C' );
     }
 
-
   leave:
     if( rc )
        iobuf_cancel(out);
index 5c6d6fb..dceba71 100644 (file)
@@ -50,7 +50,7 @@ release_sk_list( SK_LIST sk_list )
 
 int
 build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
-                                                       unsigned use )
+               unsigned int use )
 {
     SK_LIST sk_list = NULL;
     int rc;
@@ -64,9 +64,11 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
            free_secret_key( sk ); sk = NULL;
            log_error("no default secret key: %s\n", gpg_errstr(rc) );
        }
-       else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
+       else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo,
+                                           sk->pubkey_usage)) ) {
            SK_LIST r;
-           if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN )
+            
+           if( sk->version == 4 && (sk->pubkey_usage & GCRY_PK_USAGE_SIGN )
                && sk->pubkey_algo == GCRY_PK_ELG_E ) {
                log_info("this is a PGP generated "
                    "ElGamal key which is NOT secure for signatures!\n");
@@ -95,9 +97,10 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock,
                free_secret_key( sk ); sk = NULL;
                log_error(_("skipped `%s': %s\n"), locusr->d, gpg_errstr(rc) );
            }
-           else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) {
+           else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo,
+                                               sk->pubkey_usage)) ) {
                SK_LIST r;
-               if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN)
+               if( sk->version == 4 && (sk->pubkey_usage & GCRY_PK_USAGE_SIGN)
                    && sk->pubkey_algo == GCRY_PK_ELG_E ) {
                    log_info(_("skipped `%s': this is a PGP generated "
                        "ElGamal key which is not secure for signatures!\n"),
index 2eb6724..d336ae3 100644 (file)
@@ -74,8 +74,9 @@ set_status_fd ( int newfd )
 {
     fd = newfd;
     if ( fd != -1 ) {
-      #if 0
        #warning fixme - progress functions
+        /* Has to be fixed in libgcrypt */
+      #if 0
        register_primegen_progress ( progress_cb, "primegen" );
        register_pk_dsa_progress ( progress_cb, "pk_dsa" );
        register_pk_elg_progress ( progress_cb, "pk_elg" );
index 0b44706..e81c659 100644 (file)
@@ -24,6 +24,7 @@ int tty_batchmode( int onoff );
 void tty_printf( const char *fmt, ... );
 void tty_print_string( byte *p, size_t n );
 void tty_print_utf8_string( byte *p, size_t n );
+void tty_print_utf8_string2( byte *p, size_t n, size_t max_n );
 char *tty_get( const char *prompt );
 char *tty_get_hidden( const char *prompt );
 void tty_kill_prompt(void);