extensions are now working and fixed a lot of bugs
authorWerner Koch <wk@gnupg.org>
Mon, 15 Jun 1998 15:41:04 +0000 (15:41 +0000)
committerWerner Koch <wk@gnupg.org>
Mon, 15 Jun 1998 15:41:04 +0000 (15:41 +0000)
40 files changed:
NEWS
VERSION
cipher/ChangeLog
cipher/Makefile.am
cipher/cipher.c
cipher/des.c
cipher/des.h [deleted file]
cipher/dsa.c
cipher/dsa.h
cipher/dynload.c
cipher/dynload.h
cipher/elgamal.c
cipher/elgamal.h
cipher/g10c.c
cipher/md.c
cipher/md.h
cipher/pubkey.c
cipher/tiger.c
cipher/tiger.h [deleted file]
g10/ChangeLog
g10/g10.c
g10/gpgd.c
g10/keygen.c
g10/main.h
g10/mainproc.c
g10/misc.c
g10/options.h
g10/parse-packet.c
g10/seckey-cert.c
g10/seskey.c
g10/sig-check.c
g10/sign.c
include/cipher.h
include/g10lib.h
include/mpi.h
mpi/g10m.c
mpi/mpiutil.c
util/g10u.c
util/memory.c
zlib/Makefile

diff --git a/NEWS b/NEWS
index a820a8e..01e8751 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,13 @@
+Noteworthy changes in version 0.3.0
+-----------------------------------
+    * New option --emulate-checksum-bug.  If your passphrase does not
+      work anymore, use this option and --change-passphrase to rewrite
+      your passphrase.
+
+
+
+
+
 Noteworthy changes in version 0.2.19
 ------------------------------------
 
diff --git a/VERSION b/VERSION
index 3c51615..5983944 100644 (file)
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.19a
+0.2.19b
index 760f52d..3542064 100644 (file)
@@ -1,3 +1,7 @@
+Mon Jun 15 14:40:48 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * tiger.c: Removed from dis, will reappear as dynload module
+
 Sat Jun 13 14:16:57 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
        * pubkey.c: Major changes to allow extensions. Changed the inteface
index 04d1ef8..2cb4ddc 100644 (file)
@@ -2,6 +2,7 @@
 
 INCLUDES =  -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
 
+EXTRA_DIST = tiger.c
 noinst_LIBRARIES = libcipher.a
 
 
@@ -15,7 +16,6 @@ libcipher_a_SOURCES = cipher.c        \
                 blowfish.h     \
                 cast5.c        \
                 cast5.h        \
-                des.h          \
                 elgamal.c      \
                 elgamal.h      \
                 md5.c          \
@@ -29,8 +29,6 @@ libcipher_a_SOURCES = cipher.c        \
                 rand-dummy.c   \
                 rmd.h          \
                 rmd160.c       \
-                tiger.h        \
-                tiger.c        \
                 sha1.h         \
                 sha1.c         \
                 dsa.h          \
index 0649478..cedcb37 100644 (file)
@@ -31,7 +31,6 @@
 #include "cipher.h"
 #include "blowfish.h"
 #include "cast5.h"
-#include "des.h"
 #include "dynload.h"
 
 
@@ -64,7 +63,6 @@ struct cipher_handle_s {
 };
 
 
-
 static void
 dummy_setkey( void *c, byte *key, unsigned keylen ) { }
 static void
index 53afbc3..3864b22 100644 (file)
 #include <assert.h>
 #include "util.h"
 #include "types.h"
-#include "des.h"
+
+#define DES_BLOCKSIZE 8
+#define DES_ROUNDS 16
+
+typedef struct {
+    int tripledes;
+} DES_context;
 
 
 static const int IP[64] = {
diff --git a/cipher/des.h b/cipher/des.h
deleted file mode 100644 (file)
index 55a9277..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-/* des.h
- *     Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GNUPG.
- *
- * GNUPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GNUPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_DES_H
-#define G10_DES_H
-
-#include "types.h"
-
-#define DES_BLOCKSIZE 8
-#define DES_ROUNDS 16
-
-typedef struct {
-    int tripledes;
-} DES_context;
-
-void des_setkey( DES_context *c, byte *key, unsigned keylen );
-void des_3des_setkey( DES_context *c, byte *key, unsigned keylen );
-void des_encrypt_block( DES_context *bc, byte *outbuf, byte *inbuf );
-void des_decrypt_block( DES_context *bc, byte *outbuf, byte *inbuf );
-
-#endif /*G10_DES_H*/
index 20011da..19a59d9 100644 (file)
@@ -359,7 +359,8 @@ dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
 }
 
 int
-dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey )
+dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev )
 {
     DSA_public_key pk;
 
index fe977a6..dda32bd 100644 (file)
@@ -23,7 +23,8 @@
 int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
 int dsa_check_secret_key( int algo, MPI *skey );
 int dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey );
-int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey );
+int dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev );
 unsigned dsa_get_nbits( int algo, MPI *pkey );
 const char *dsa_get_info( int algo, int *npkey, int *nskey,
                                    int *nenc, int *nsig, int *usage );
index e0b2e77..71f0d19 100644 (file)
@@ -221,7 +221,8 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
     int (**encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey ),
     int (**decrypt)( int algo, MPI *result, MPI *data, MPI *skey ),
     int (**sign)( int algo, MPI *resarr, MPI data, MPI *skey ),
-    int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey ),
+    int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev ),
     unsigned (**get_nbits)( int algo, MPI *pkey ) )
 {
     EXTLIST r;
@@ -232,7 +233,8 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
                           int (**)( int, MPI *, MPI , MPI * ),
                           int (**)( int, MPI *, MPI *, MPI * ),
                           int (**)( int, MPI *, MPI , MPI * ),
-                          int (**)( int, MPI , MPI *, MPI * ),
+                          int (**)( int, MPI , MPI *, MPI *,
+                                           int (*)(void*,MPI), void *),
                           unsigned (**)( int , MPI * ) );
 
     if( !*enum_context ) { /* init context */
index 69b5d8f..2d829c7 100644 (file)
@@ -36,7 +36,8 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
     int (**encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey ),
     int (**decrypt)( int algo, MPI *result, MPI *data, MPI *skey ),
     int (**sign)( int algo, MPI *resarr, MPI data, MPI *skey ),
-    int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey ),
+    int (**verify)( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev ),
     unsigned (**get_nbits)( int algo, MPI *pkey ) );
 
 #endif /*G10_CIPHER_DYNLOAD_H*/
index b37c756..bcaaa20 100644 (file)
@@ -476,7 +476,8 @@ elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
 }
 
 int
-elg_verify( int algo, MPI hash, MPI *data, MPI *pkey )
+elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev )
 {
     ELG_public_key pk;
 
index a4668ff..672f077 100644 (file)
@@ -25,7 +25,8 @@ int elg_check_secret_key( int algo, MPI *skey );
 int elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
 int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
 int elg_sign( int algo, MPI *resarr, MPI data, MPI *skey );
-int elg_verify( int algo, MPI hash, MPI *data, MPI *pkey );
+int elg_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev );
 unsigned elg_get_nbits( int algo, MPI *pkey );
 const char *elg_get_info( int algo, int *npkey, int *nskey,
                                    int *nenc, int *nsig, int *usage );
index c6f9402..5bf0eb6 100644 (file)
@@ -27,6 +27,7 @@
 #define _g10lib_INTERNAL 1
 #include "g10lib.h"
 
+const char *g10c_revision_string(int dummy) { return "$Revision$"; }
 
 MPI
 g10c_generate_secret_prime( unsigned nbits )
index 30d7e25..b116dd9 100644 (file)
@@ -38,7 +38,6 @@ static struct { const char *name; int algo;} digest_names[] = {
     { "RMD160",        DIGEST_ALGO_RMD160 },
     { "RMD-160",       DIGEST_ALGO_RMD160 },
     { "RIPE-MD-160",   DIGEST_ALGO_RMD160 },
-    { "TIGER",         DIGEST_ALGO_TIGER  },
     {NULL} };
 
 
@@ -79,9 +78,6 @@ int
 check_digest_algo( int algo )
 {
     switch( algo ) {
-    #ifdef WITH_TIGER_HASH
-      case DIGEST_ALGO_TIGER:
-    #endif
       case DIGEST_ALGO_MD5:
       case DIGEST_ALGO_RMD160:
       case DIGEST_ALGO_SHA1:
@@ -134,13 +130,6 @@ md_enable( MD_HANDLE h, int algo )
            sha1_init( &h->sha1 );
        h->use_sha1 = 1;
     }
-  #ifdef WITH_TIGER_HASH
-    else if( algo == DIGEST_ALGO_TIGER ) {
-       if( !h->use_tiger )
-           tiger_init( &h->tiger );
-       h->use_tiger = 1;
-    }
-  #endif
     else
        log_bug("md_enable(%d)", algo );
 }
@@ -186,12 +175,6 @@ md_write( MD_HANDLE a, byte *inbuf, size_t inlen)
        sha1_write( &a->sha1, a->buffer, a->bufcount );
        sha1_write( &a->sha1, inbuf, inlen  );
     }
-  #ifdef WITH_TIGER_HASH
-    if( a->use_tiger ) {
-       tiger_write( &a->tiger, a->buffer, a->bufcount );
-       tiger_write( &a->tiger, inbuf, inlen  );
-    }
-  #endif
     if( a->use_md5 ) {
        md5_write( &a->md5, a->buffer, a->bufcount );
        md5_write( &a->md5, inbuf, inlen  );
@@ -210,10 +193,6 @@ md_final(MD_HANDLE a)
        rmd160_final( &a->rmd160 );
     if( a->use_sha1 )
        sha1_final( &a->sha1 );
-  #ifdef WITH_TIGER_HASH
-    if( a->use_tiger )
-       tiger_final( &a->tiger );
-  #endif
     if( a->use_md5 )
        md5_final( &a->md5 );
 }
@@ -230,10 +209,6 @@ md_read( MD_HANDLE a, int algo )
            return rmd160_read( &a->rmd160 );
        if( a->use_sha1 )
            return sha1_read( &a->sha1 );
-      #ifdef WITH_TIGER_HASH
-       if( a->use_tiger )
-           return tiger_read( &a->tiger );
-      #endif
        if( a->use_md5 )
            return md5_read( &a->md5 );
     }
@@ -242,10 +217,6 @@ md_read( MD_HANDLE a, int algo )
            return rmd160_read( &a->rmd160 );
        if( algo == DIGEST_ALGO_SHA1 )
            return sha1_read( &a->sha1 );
-      #ifdef WITH_TIGER_HASH
-       if( algo == DIGEST_ALGO_TIGER )
-           return tiger_read( &a->tiger );
-      #endif
        if( algo == DIGEST_ALGO_MD5 )
            return md5_read( &a->md5 );
     }
@@ -259,10 +230,6 @@ md_get_algo( MD_HANDLE a )
        return DIGEST_ALGO_RMD160;
     if( a->use_sha1 )
        return DIGEST_ALGO_SHA1;
-  #ifdef WITH_TIGER_HASH
-    if( a->use_tiger )
-       return DIGEST_ALGO_TIGER;
-  #endif
     if( a->use_md5 )
        return DIGEST_ALGO_MD5;
     return 0;
@@ -275,8 +242,6 @@ int
 md_digest_length( int algo )
 {
     switch( algo ) {
-      case DIGEST_ALGO_TIGER:
-       return 24;
       case DIGEST_ALGO_RMD160:
       case DIGEST_ALGO_SHA1:
        return 20;
index 2d45a12..b4d6907 100644 (file)
@@ -25,7 +25,6 @@
 #include "rmd.h"
 #include "sha1.h"
 #include "md5.h"
-#include "tiger.h"
 
 #define MD_BUFFER_SIZE 512
 
index 3357ae1..b18f1c3 100644 (file)
@@ -28,6 +28,8 @@
 #include "errors.h"
 #include "mpi.h"
 #include "cipher.h"
+#include "elgamal.h"
+#include "dsa.h"
 #include "dynload.h"
 
 
@@ -46,7 +48,8 @@ struct pubkey_table_s {
     int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
     int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey );
     int (*sign)( int algo, MPI *resarr, MPI data, MPI *skey );
-    int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey );
+    int (*verify)( int algo, MPI hash, MPI *data, MPI *pkey,
+                  int (*cmp)(void *, MPI), void *opaquev );
     unsigned (*get_nbits)( int algo, MPI *pkey );
 };
 
@@ -75,7 +78,8 @@ dummy_sign( int algo, MPI *resarr, MPI data, MPI *skey )
 { log_bug("no sign() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
 
 static int
-dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey )
+dummy_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+               int (*cmp)(void *, MPI), void *opaquev )
 { log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
 
 static unsigned
@@ -523,7 +527,8 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
  * Return 0 if the signature is good
  */
 int
-pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey )
+pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+                   int (*cmp)(void *, MPI), void *opaquev )
 {
     int i, rc;
 
@@ -531,7 +536,8 @@ pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey )
     do {
        for(i=0; pubkey_table[i].name; i++ )
            if( pubkey_table[i].algo == algo ) {
-               rc = (*pubkey_table[i].verify)( algo, hash, data, pkey );
+               rc = (*pubkey_table[i].verify)( algo, hash, data, pkey,
+                                                           cmp, opaquev );
                goto ready;
            }
     } while( load_pubkey_modules() );
index c432264..11c11b4 100644 (file)
 #include <assert.h>
 #include "util.h"
 #include "memory.h"
-#include "tiger.h"
 
-#ifdef WITH_TIGER_HASH
+
+typedef struct {
+    u64  a, b, c;
+    u32  nblocks;
+    byte buf[64];
+    int  count;
+} TIGER_CONTEXT;
+
 
 /*********************************
  * Okay, okay, this is not the fastest code - improvements are welcome.
@@ -845,5 +851,3 @@ tiger_final( TIGER_CONTEXT *hd )
   #undef X
 }
 
-#endif /* WITH_TIGER_HASH */
-
diff --git a/cipher/tiger.h b/cipher/tiger.h
deleted file mode 100644 (file)
index 9069092..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-/* tiger.h  - TIGER hash function
- *     Copyright (C) 1998 Free Software Foundation, Inc.
- *
- * This file is part of GNUPG.
- *
- * GNUPG is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * GNUPG is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
- */
-#ifndef G10_TIGER_H
-#define G10_TIGER_H
-
-#include "types.h"
-
-#ifdef HAVE_U64_TYPEDEF
-
-#define WITH_TIGER_HASH 1
-
-typedef struct {
-    u64  a, b, c;
-    u32  nblocks;
-    byte buf[64];
-    int  count;
-} TIGER_CONTEXT;
-
-
-void tiger_init( TIGER_CONTEXT *c );
-void tiger_write( TIGER_CONTEXT *hd, byte *inbuf, size_t inlen);
-void tiger_final(TIGER_CONTEXT *hd);
-#define tiger_read(h) ( (h)->buf )
-
-#endif /* HAVE_TIGER_HASH */
-
-#endif /*G10_TIGER_H*/
index d6ed0cc..15fd2c8 100644 (file)
@@ -1,6 +1,13 @@
+Sun Jun 14 21:28:31 1998  Werner Koch  (wk@isil.d.shuttle.de)
+
+       * misc.c (checksum_u16): Fixed a stupid bug which caused a
+       wrong checksum calculation for the secret key protection and
+       add a backward compatibility option.
+       * g10.c (main): Add option --emulate-checksum-bug.
+
 Thu Jun 11 13:26:44 1998  Werner Koch  (wk@isil.d.shuttle.de)
 
-       * packet.h: Mjor chnages to the structure of public key material
+       * packet.h: Major changes to the structure of public key material
        which is now stored in an array and not anaymore in a union of
        algorithm specific structures.  These is needed to make the system
        more extendable and makes a lot of stuff much simpler. Changed
index 8f65f2e..828fef2 100644 (file)
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -164,6 +164,7 @@ static ARGPARSE_OPTS opts[] = {
     { 553, "skip-verify",0, "@" },
     { 557, "compress-keys",0, "@"},
     { 559, "always-trust", 0, "@"},
+    { 562, "emulate-checksum-bug", 0, "@"},
 
 {0} };
 
@@ -310,11 +311,6 @@ wrong_args( const char *text)
 static void
 set_debug(void)
 {
-    volatile char *p = g10_malloc(1);
-    volatile MPI a = g10m_new(1);
-    *p = g10c_get_random_byte( 0 );
-
-
     if( opt.debug & DBG_MEMORY_VALUE )
        memory_debug_mode = 1;
     if( opt.debug & DBG_MEMSTAT_VALUE )
@@ -598,6 +594,7 @@ main( int argc, char **argv )
          case 559: opt.always_trust = 1; break;
          case 560: register_cipher_extension(pargs.r.ret_str); break;
          case 561: opt.rfc1991 = 1; break;
+         case 562: opt.emulate_bugs |= 1; break;
          default : errors++; pargs.err = configfp? 1:2; break;
        }
     }
@@ -1111,9 +1108,8 @@ print_mds( const char *fname, int algo )
        md_enable( md, DIGEST_ALGO_MD5 );
        md_enable( md, DIGEST_ALGO_SHA1 );
        md_enable( md, DIGEST_ALGO_RMD160 );
-      #ifdef WITH_TIGER_HASH
-       md_enable( md, DIGEST_ALGO_TIGER );
-      #endif
+       if( !check_digest_algo(DIGEST_ALGO_TIGER) )
+           md_enable( md, DIGEST_ALGO_TIGER );
     }
 
     while( (n=fread( buf, 1, DIM(buf), fp )) )
@@ -1134,10 +1130,10 @@ print_mds( const char *fname, int algo )
                            print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
            printf("\n%sRMD160 = ", fname?pname:""  );
                            print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
-         #ifdef WITH_TIGER_HASH
-           printf("\n%s TIGER = ", fname?pname:""  );
+           if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
+               printf("\n%s TIGER = ", fname?pname:""  );
                            print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
-         #endif
+           }
        }
        putchar('\n');
     }
index 72fcade..34158b7 100644 (file)
@@ -129,7 +129,7 @@ set_debug(void)
     if( opt.debug & DBG_MPI_VALUE )
        mpi_debug_mode = 1;
     if( opt.debug & DBG_CIPHER_VALUE )
-       cipher_debug_mode = 1;
+       g10c_debug_mode = 1;
     if( opt.debug & DBG_IOBUF_VALUE )
        iobuf_debug_mode = 1;
 }
index 8ad30bb..21c388b 100644 (file)
@@ -168,7 +168,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     skc->is_protected = 0;
     skc->protect.algo = 0;
 
-    skc->csum = checksum_mpi( skc->skey[3] );
+    skc->csum = checksum_mpi_counted_nbits( skc->skey[3] );
     if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
        *ret_skc = copy_secret_cert( NULL, skc );
 
@@ -232,10 +232,10 @@ gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     skc->d.rsa.rsa_p = sk.p;
     skc->d.rsa.rsa_q = sk.q;
     skc->d.rsa.rsa_u = sk.u;
-    skc->d.rsa.csum  = checksum_mpi( skc->d.rsa.rsa_d );
-    skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
-    skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
-    skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_u );
+    skc->d.rsa.csum  = checksum_mpi_counted_nbits( skc->d.rsa.rsa_d );
+    skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_p );
+    skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_q );
+    skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_u );
 
     if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
        *ret_skc = copy_secret_cert( NULL, skc );
@@ -244,7 +244,8 @@ gen_rsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
        skc->d.rsa.is_protected = 1;
        skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
        randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
-       skc->d.rsa.csum += checksum( skc->d.rsa.protect.blowfish.iv, 8 );
+       skc->d.rsa.csum += checksum_counted_nbits(
+                                       skc->d.rsa.protect.blowfish.iv, 8 );
        rc = protect_secret_key( skc, dek );
        if( rc ) {
            log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
@@ -314,7 +315,7 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
     skc->is_protected = 0;
     skc->protect.algo = 0;
 
-    skc->csum = checksum_mpi( skc->skey[4] );
+    skc->csum = checksum_mpi_counted_nbits( skc->skey[4] );
     if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
         *ret_skc = copy_secret_cert( NULL, skc );
 
index 56fd3c9..0b30084 100644 (file)
@@ -49,6 +49,7 @@ void trap_unaligned(void);
 u16 checksum_u16( unsigned n );
 u16 checksum( byte *p, unsigned n );
 u16 checksum_mpi( MPI a );
+u16 checksum_mpi_counted_nbits( MPI a );
 
 /*-- encode.c --*/
 int encode_symmetric( const char *filename );
@@ -85,7 +86,8 @@ IOBUF open_sigfile( const char *iname );
 /*-- seskey.c --*/
 void make_session_key( DEK *dek );
 MPI encode_session_key( DEK *dek, unsigned nbits );
-MPI encode_md_value( MD_HANDLE md, int hash_algo, unsigned nbits );
+MPI encode_md_value( int pubkey_algo,  MD_HANDLE md,
+                    int hash_algo, unsigned nbits );
 
 /*-- comment.c --*/
 KBNODE make_comment_node( const char *s );
index 707272b..a807f85 100644 (file)
@@ -246,7 +246,8 @@ proc_plaintext( CTX c, PACKET *pkt )
     /*md_start_debug(c->mfx.md, "proc_plaintext");*/
     md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
     md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
-    md_enable( c->mfx.md, DIGEST_ALGO_TIGER );
+    if( !check_digest_algo(DIGEST_ALGO_TIGER) )
+       md_enable( c->mfx.md, DIGEST_ALGO_TIGER );
     rc = handle_plaintext( pt, &c->mfx );
     if( rc )
        log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
index 782b5cd..d1bacf6 100644 (file)
 #endif
 #include "util.h"
 #include "main.h"
+#include "options.h"
 
+volatile int
+pull_in_libs(void)
+{
+    g10m_revision_string(0);
+    g10c_revision_string(0);
+    g10u_revision_string(0);
+}
 
 
 #if defined(__linux__) && defined(__alpha__)
@@ -63,7 +71,22 @@ checksum_u16( unsigned n )
     u16 a;
 
     a  = (n >> 8) & 0xff;
-    a |= n & 0xff;
+    if( opt.emulate_bugs & 1 ) {
+       a |= n & 0xff;
+       log_debug("csum_u16 emulated for n=%u\n", n);
+    }
+    else
+       a += n & 0xff;
+    return a;
+}
+
+static u16
+checksum_u16_nobug( unsigned n )
+{
+    u16 a;
+
+    a  = (n >> 8) & 0xff;
+    a += n & 0xff;
     return a;
 }
 
@@ -83,12 +106,43 @@ checksum_mpi( MPI a )
     u16 csum;
     byte *buffer;
     unsigned nbytes;
+    unsigned nbits;
 
     buffer = mpi_get_buffer( a, &nbytes, NULL );
-    csum = checksum_u16( mpi_get_nbits(a) );
+    /* some versions of gpg encode wrong values for the length of an mpi
+     * so that mpi_get_nbits() which counts the mpi yields another (shorter)
+     * value than the one store with the mpi.  mpi_get_nbit_info() returns
+     * this stored value if it is still available.
+     */
+
+    if( opt.emulate_bugs & 1 )
+       nbits = 0;
+    else
+       nbits = mpi_get_nbit_info(a);
+    if( !nbits )
+       nbits = mpi_get_nbits(a);
+    csum = checksum_u16( nbits );
     csum += checksum( buffer, nbytes );
     m_free( buffer );
     return csum;
 }
 
+/****************
+ * This is the correct function
+ */
+u16
+checksum_mpi_counted_nbits( MPI a )
+{
+    u16 csum;
+    byte *buffer;
+    unsigned nbytes;
+    unsigned nbits;
+
+    buffer = mpi_get_buffer( a, &nbytes, NULL );
+    nbits = mpi_get_nbits(a);
+    csum = checksum_u16_nobug( nbits );
+    csum += checksum( buffer, nbytes );
+    m_free( buffer );
+    return csum;
+}
 
index 4b32b52..1e34ced 100644 (file)
@@ -48,6 +48,7 @@ struct {
     int compress_keys;
     int always_trust;
     int rfc1991;
+    unsigned emulate_bugs; /* bug emulation flags */
 } opt;
 
 
index 0cd4238..9e469b6 100644 (file)
@@ -64,6 +64,7 @@ static int  parse_compressed( IOBUF inp, int pkttype, unsigned long pktlen,
 static int  parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
                                                           PACKET *packet );
 
+
 static unsigned short
 read_16(IOBUF inp)
 {
@@ -1006,9 +1007,6 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
 
            cert->csum = read_16(inp); pktlen -= 2;
            if( list_mode ) {
-           printf("\telg x: ");
-           mpi_print(stdout, cert->skey[3], mpi_print_mode  );
-           putchar('\n');
                printf("\t[secret value x is not shown]\n"
                       "\tchecksum: %04hx\n", cert->csum);
            }
@@ -1174,8 +1172,7 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
                        printf(" %02x", temp[i] );
                    putchar('\n');
                }
-               if( cert->protect.algo == CIPHER_ALGO_BLOWFISH160 )
-                   memcpy(cert->protect.iv, temp, 8 );
+               memcpy(cert->protect.iv, temp, 8 );
                /* old version, we don't have a S2K, so we fake one */
                cert->protect.s2k.mode = 0;
                cert->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
index 9ac19c8..f30e5d0 100644 (file)
@@ -39,7 +39,7 @@ do_check( PKT_secret_cert *cert )
 {
     byte *buffer;
     u16 csum=0;
-    int res;
+    int i, res;
     unsigned nbytes;
 
     if( cert->is_protected ) { /* remove the protection */
@@ -60,60 +60,34 @@ do_check( PKT_secret_cert *cert )
                                 CIPHER_MODE_AUTO_CFB, 1);
        cipher_setkey( cipher_hd, dek->key, dek->keylen );
        cipher_setiv( cipher_hd, NULL );
-       m_free(dek); /* pw is in secure memory, so m_free() burns it */
+       m_free(dek);
        save_cert = copy_secret_cert( NULL, cert );
        memcpy(save_iv, cert->protect.iv, 8 );
        cipher_decrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
-       switch( cert->pubkey_algo ) {
-         case PUBKEY_ALGO_ELGAMAL:
-         case PUBKEY_ALGO_ELGAMAL_E:
-           /* FIXME: removed ELG knowledge from this function */
-           buffer = mpi_get_secure_buffer( cert->skey[3], &nbytes, NULL );
+       csum = 0;
+       for(i=pubkey_get_npkey(cert->pubkey_algo);
+               i < pubkey_get_nskey(cert->pubkey_algo); i++ ) {
+           buffer = mpi_get_secure_buffer( cert->skey[i], &nbytes, NULL );
+           cipher_sync( cipher_hd );
            cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
-           mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
-           csum = checksum_mpi( cert->skey[3] );
+           mpi_set_buffer( cert->skey[i], buffer, nbytes, 0 );
+           csum += checksum_mpi( cert->skey[i] );
            m_free( buffer );
-           break;
-         case PUBKEY_ALGO_DSA:
-           buffer = mpi_get_secure_buffer( cert->skey[4], &nbytes, NULL );
-           cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
-           mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
-           csum = checksum_mpi( cert->skey[4] );
-           m_free( buffer );
-           break;
-         case PUBKEY_ALGO_RSA:
-         case PUBKEY_ALGO_RSA_E:
-         case PUBKEY_ALGO_RSA_S:
-           csum = 0;
-           #define X(a) do { \
-               buffer = mpi_get_secure_buffer( cert->skey[(a)],     \
-                                               &nbytes, NULL );     \
-               csum += checksum_u16( nbytes*8 );                    \
-               cipher_decrypt( cipher_hd, buffer, buffer, nbytes ); \
-               csum += checksum( buffer, nbytes );                  \
-               mpi_set_buffer(cert->skey[(a)], buffer, nbytes, 0 ); \
-               m_free( buffer );                                    \
-              } while(0)
-           X(2);
-           X(3);
-           X(4);
-           X(5);
-           #undef X
-           break;
-
-         default: BUG();
+       }
+       if( opt.emulate_bugs & 1 ) {
+          log_debug("secret key csum is=%04hx should=%04hx algos=%d/%d\n",
+                    csum, cert->csum, cert->pubkey_algo,cert->protect.algo );
+          csum = cert->csum;
        }
        cipher_close( cipher_hd );
        /* now let's see whether we have used the right passphrase */
        if( csum != cert->csum ) {
-           if( csum != cert->csum ) {
-               copy_secret_cert( cert, save_cert );
-               free_secret_cert( save_cert );
-               memcpy( cert->protect.iv, save_iv, 8 );
-               return G10ERR_BAD_PASS;
-           }
+           copy_secret_cert( cert, save_cert );
+           free_secret_cert( save_cert );
+           memcpy( cert->protect.iv, save_iv, 8 );
+           return G10ERR_BAD_PASS;
        }
-
+       /* the checksum may fail, so we also check the key itself */
        res = pubkey_check_secret_key( cert->pubkey_algo, cert->skey );
        if( res ) {
            copy_secret_cert( cert, save_cert );
@@ -124,37 +98,11 @@ do_check( PKT_secret_cert *cert )
        free_secret_cert( save_cert );
        cert->is_protected = 0;
     }
-    else { /* not protected */
-       switch( cert->pubkey_algo ) {
-         case PUBKEY_ALGO_ELGAMAL_E:
-         case PUBKEY_ALGO_ELGAMAL:
-           csum = checksum_mpi( cert->skey[3] );
-           break;
-         case PUBKEY_ALGO_DSA:
-           csum = checksum_mpi( cert->skey[4] );
-           break;
-         case PUBKEY_ALGO_RSA_E:
-         case PUBKEY_ALGO_RSA_S:
-         case PUBKEY_ALGO_RSA:
-           csum =0;
-           buffer = mpi_get_buffer( cert->skey[2], &nbytes, NULL );
-           csum += checksum_u16( nbytes*8 );
-           csum += checksum( buffer, nbytes );
-           m_free( buffer );
-           buffer = mpi_get_buffer( cert->skey[3], &nbytes, NULL );
-           csum += checksum_u16( nbytes*8 );
-           csum += checksum( buffer, nbytes );
-           m_free( buffer );
-           buffer = mpi_get_buffer( cert->skey[4], &nbytes, NULL );
-           csum += checksum_u16( nbytes*8 );
-           csum += checksum( buffer, nbytes );
-           m_free( buffer );
-           buffer = mpi_get_buffer( cert->skey[5], &nbytes, NULL );
-           csum += checksum_u16( nbytes*8 );
-           csum += checksum( buffer, nbytes );
-           m_free( buffer );
-           break;
-         default: BUG();
+    else { /* not protected, assume it is okay if the checksum is okay */
+       csum = 0;
+       for(i=pubkey_get_npkey(cert->pubkey_algo);
+               i < pubkey_get_nskey(cert->pubkey_algo); i++ ) {
+           csum += checksum_mpi( cert->skey[i] );
        }
        if( csum != cert->csum )
            return G10ERR_CHECKSUM;
@@ -212,34 +160,6 @@ is_secret_key_protected( PKT_secret_cert *cert )
 }
 
 
-static int
-do_protect( void (*fnc)(CIPHER_HANDLE, byte *, byte *, unsigned),
-           CIPHER_HANDLE fnc_hd, PKT_secret_cert *cert )
-{
-    byte *buffer;
-    unsigned nbytes;
-
-    switch( cert->pubkey_algo ) {
-      case PUBKEY_ALGO_ELGAMAL_E:
-      case PUBKEY_ALGO_ELGAMAL:
-       buffer = mpi_get_buffer( cert->skey[3], &nbytes, NULL );
-       (*fnc)( fnc_hd, buffer, buffer, nbytes );
-       mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
-       m_free( buffer );
-       break;
-
-      case PUBKEY_ALGO_DSA:
-       buffer = mpi_get_buffer( cert->skey[4], &nbytes, NULL );
-       (*fnc)( fnc_hd, buffer, buffer, nbytes );
-       mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
-       m_free( buffer );
-       break;
-
-      default: return G10ERR_PUBKEY_ALGO;
-    }
-    return 0;
-}
-
 
 /****************
  * Protect the secret key certificate with the passphrase from DEK
@@ -247,7 +167,10 @@ do_protect( void (*fnc)(CIPHER_HANDLE, byte *, byte *, unsigned),
 int
 protect_secret_key( PKT_secret_cert *cert, DEK *dek )
 {
-    int rc=0;
+    int i, rc = 0;
+    byte *buffer;
+    unsigned nbytes;
+    u16 csum;
 
     if( !dek )
        return 0;
@@ -263,8 +186,21 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek )
            cipher_setkey( cipher_hd, dek->key, dek->keylen );
            cipher_setiv( cipher_hd, NULL );
            cipher_encrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
-           if( !do_protect( &cipher_encrypt, cipher_hd, cert ) )
-               cert->is_protected = 1;
+           /* NOTE: we always recalculate the checksum because there are some
+            * test releases which calculated it wrong */
+           csum = 0;
+           for(i=pubkey_get_npkey(cert->pubkey_algo);
+                   i < pubkey_get_nskey(cert->pubkey_algo); i++ ) {
+               csum += checksum_mpi_counted_nbits( cert->skey[i] );
+               buffer = mpi_get_buffer( cert->skey[i], &nbytes, NULL );
+          log_debug("protecing i=%d csum=%04hx nbytes=%u\n", i, csum, nbytes );
+               cipher_sync( cipher_hd );
+               cipher_encrypt( cipher_hd, buffer, buffer, nbytes );
+               mpi_set_buffer( cert->skey[i], buffer, nbytes, 0 );
+               m_free( buffer );
+           }
+           cert->csum = csum;
+           cert->is_protected = 1;
            cipher_close( cipher_hd );
        }
     }
index 2581990..5b271a2 100644 (file)
@@ -144,13 +144,25 @@ do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits,
 
 
 MPI
-encode_md_value( MD_HANDLE md, int hash_algo, unsigned nbits )
+encode_md_value( int pubkey_algo, MD_HANDLE md, int hash_algo, unsigned nbits )
 {
     int algo = hash_algo? hash_algo : md_get_algo(md);
     const byte *asn;
     size_t asnlen, mdlen;
-
-    asn = md_asn_oid( algo, &asnlen, &mdlen );
-    return do_encode_md( md, algo, mdlen, nbits, asn, asnlen );
+    MPI frame;
+
+    if( pubkey_algo == PUBKEY_ALGO_DSA ) {
+       frame = md_is_secure(md)? mpi_alloc_secure((md_digest_length(hash_algo)
+                                +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB )
+                               : mpi_alloc((md_digest_length(hash_algo)
+                                +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
+       mpi_set_buffer( frame, md_read(md, hash_algo),
+                              md_digest_length(hash_algo), 0 );
+    }
+    else {
+       asn = md_asn_oid( algo, &asnlen, &mdlen );
+       frame = do_encode_md( md, algo, mdlen, nbits, asn, asnlen );
+    }
+    return frame;
 }
 
index 0ef69b7..76f0aac 100644 (file)
 #include "main.h"
 #include "status.h"
 
+struct cmp_help_context_s {
+    PKT_signature *sig;
+    MD_HANDLE md;
+};
+
 
 static int do_check( PKT_public_cert *pkc, PKT_signature *sig,
                                                MD_HANDLE digest );
@@ -62,11 +67,87 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
 }
 
 
+/****************
+ * This function gets called by pubkey_verify() if the algorithm needs it.
+ */
+static int
+cmp_help( void *opaque, MPI result )
+{
+  #if 0 /* we do not use this anymore */
+    int rc=0, i, j, c, old_enc;
+    byte *dp;
+    const byte *asn;
+    size_t mdlen, asnlen;
+    struct cmp_help_context_s *ctx = opaque;
+    PKT_signature *sig = ctx->sig;
+    MD_HANDLE digest = ctx->md;
+
+    old_enc = 0;
+    for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
+       if( !j ) {
+           if( !i && c != 1 )
+               break;
+           else if( i && c == 0xff )
+               ; /* skip the padding */
+           else if( i && !c )
+               j++;
+           else
+               break;
+       }
+       else if( ++j == 18 && c != 1 )
+           break;
+       else if( j == 19 && c == 0 ) {
+           old_enc++;
+           break;
+       }
+    }
+    if( old_enc ) {
+       log_error("old encoding scheme is not supported\n");
+       return G10ERR_GENERAL;
+    }
+
+    if( (rc=check_digest_algo(sig->digest_algo)) )
+       return rc; /* unsupported algo */
+    asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
+
+    for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
+                                                          i++, j-- )
+       if( asn[j] != c )
+           break;
+    if( j != -1 || mpi_getbyte(result, i) )
+       return G10ERR_BAD_PUBKEY;  /* ASN is wrong */
+    for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
+       if( c != 0xff  )
+           break;
+    i++;
+    if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
+       /* Padding or leading bytes in signature is wrong */
+       return G10ERR_BAD_PUBKEY;
+    }
+    if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
+       || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
+       /* Wrong key used to check the signature */
+       return G10ERR_BAD_PUBKEY;
+    }
+
+    dp = md_read( digest, sig->digest_algo );
+    for(i=mdlen-1; i >= 0; i--, dp++ ) {
+       if( mpi_getbyte( result, i ) != *dp )
+           return G10ERR_BAD_SIGN;
+    }
+    return 0;
+  #else
+    return -1;
+  #endif
+}
+
+
 static int
 do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
 {
     MPI result = NULL;
     int rc=0;
+    struct cmp_help_context_s ctx;
 
     if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
        log_info("this is a PGP generated "
@@ -77,169 +158,56 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
     if( pkc->timestamp > sig->timestamp )
        return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */
 
-    if( is_ELGAMAL(pkc->pubkey_algo) ) {
-       if( (rc=check_digest_algo(sig->digest_algo)) )
-           goto leave;
-       /* make sure the digest algo is enabled (in case of a detached
-        * signature */
-       md_enable( digest, sig->digest_algo );
-       /* complete the digest */
-       md_putc( digest, sig->sig_class );
-       {   u32 a = sig->timestamp;
-           md_putc( digest, (a >> 24) & 0xff );
-           md_putc( digest, (a >> 16) & 0xff );
-           md_putc( digest, (a >>  8) & 0xff );
-           md_putc( digest,  a        & 0xff );
-       }
-       md_final( digest );
-       result = encode_md_value( digest, sig->digest_algo,
-                                         mpi_get_nbits(pkc->pkey[0]));
-       if( DBG_CIPHER )
-           log_mpidump("calc sig frame (elg): ", result);
-       rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey );
-    }
-    else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       if( (rc=check_digest_algo(sig->digest_algo)) )
-           goto leave;
-       /* make sure the digest algo is enabled (in case of a detached
-        * signature */
-       md_enable( digest, sig->digest_algo );
-
-       /* complete the digest */
-       if( sig->version >= 4 )
-           md_putc( digest, sig->version );
-       md_putc( digest, sig->sig_class );
-       if( sig->version < 4 ) {
-           u32 a = sig->timestamp;
-           md_putc( digest, (a >> 24) & 0xff );
-           md_putc( digest, (a >> 16) & 0xff );
-           md_putc( digest, (a >>  8) & 0xff );
-           md_putc( digest,  a        & 0xff );
-       }
-       else {
-           byte buf[6];
-           size_t n;
-           md_putc( digest, sig->pubkey_algo );
-           md_putc( digest, sig->digest_algo );
-           if( sig->hashed_data ) {
-               n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
-               md_write( digest, sig->hashed_data, n+2 );
-               n += 6;
-           }
-           else
-               n = 6;
-           /* add some magic */
-           buf[0] = sig->version;
-           buf[1] = 0xff;
-           buf[2] = n >> 24;
-           buf[3] = n >> 16;
-           buf[4] = n >>  8;
-           buf[5] = n;
-           md_write( digest, buf, 6 );
-       }
-       md_final( digest );
-
-       result = mpi_alloc( (md_digest_length(sig->digest_algo)
-                            +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB );
-       mpi_set_buffer( result, md_read(digest, sig->digest_algo),
-                               md_digest_length(sig->digest_algo), 0 );
-       if( DBG_CIPHER )
-           log_mpidump("calc sig frame: ", result);
-       rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey );
-    }
-  #if 0 /* WORK!!! */
-    else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA
-            || pkc->pubkey_algo == PUBKEY_ALGO_RSA_S ) {
-       int i, j, c, old_enc;
-       byte *dp;
-       const byte *asn;
-       size_t mdlen, asnlen;
-
-       result = mpi_alloc(40);
-       rsa_public( result, sig->d.rsa.rsa_integer, &pkc->d.rsa );
-
-       old_enc = 0;
-       for(i=j=0; (c=mpi_getbyte(result, i)) != -1; i++ ) {
-           if( !j ) {
-               if( !i && c != 1 )
-                   break;
-               else if( i && c == 0xff )
-                   ; /* skip the padding */
-               else if( i && !c )
-                   j++;
-               else
-                   break;
-           }
-           else if( ++j == 18 && c != 1 )
-               break;
-           else if( j == 19 && c == 0 ) {
-               old_enc++;
-               break;
-           }
-       }
-       if( old_enc ) {
-           log_error("old encoding scheme is not supported\n");
-           rc = G10ERR_GENERAL;
-           goto leave;
-       }
-
-       if( (rc=check_digest_algo(sig->digest_algo)) )
-           goto leave; /* unsupported algo */
-       md_enable( digest, sig->digest_algo );
-       asn = md_asn_oid( sig->digest_algo, &asnlen, &mdlen );
-
-       for(i=mdlen,j=asnlen-1; (c=mpi_getbyte(result, i)) != -1 && j >= 0;
-                                                              i++, j-- )
-           if( asn[j] != c )
-               break;
-       if( j != -1 || mpi_getbyte(result, i) ) { /* ASN is wrong */
-           rc = G10ERR_BAD_PUBKEY;
-           goto leave;
-       }
-       for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
-           if( c != 0xff  )
-               break;
-       i++;
-       if( c != sig->digest_algo || mpi_getbyte(result, i) ) {
-           /* Padding or leading bytes in signature is wrong */
-           rc = G10ERR_BAD_PUBKEY;
-           goto leave;
-       }
-       if( mpi_getbyte(result, mdlen-1) != sig->digest_start[0]
-           || mpi_getbyte(result, mdlen-2) != sig->digest_start[1] ) {
-           /* Wrong key used to check the signature */
-           rc = G10ERR_BAD_PUBKEY;
-           goto leave;
-       }
+    if( (rc=check_digest_algo(sig->digest_algo)) )
+       return rc;
+    if( (rc=check_pubkey_algo(sig->pubkey_algo)) )
+       return rc;
 
-       /* complete the digest */
-       md_putc( digest, sig->sig_class );
-       {   u32 a = sig->timestamp;
-           md_putc( digest, (a >> 24) & 0xff );
-           md_putc( digest, (a >> 16) & 0xff );
-           md_putc( digest, (a >>  8) & 0xff );
-           md_putc( digest,  a        & 0xff );
-       }
-       md_final( digest );
-       dp = md_read( digest, sig->digest_algo );
-       for(i=mdlen-1; i >= 0; i--, dp++ ) {
-           if( mpi_getbyte( result, i ) != *dp ) {
-               rc = G10ERR_BAD_SIGN;
-               goto leave;
-           }
-       }
+    /* make sure the digest algo is enabled (in case of a detached signature)*/
+    md_enable( digest, sig->digest_algo );
+
+    /* complete the digest */
+    if( sig->version >= 4 )
+       md_putc( digest, sig->version );
+    md_putc( digest, sig->sig_class );
+    if( sig->version < 4 ) {
+       u32 a = sig->timestamp;
+       md_putc( digest, (a >> 24) & 0xff );
+       md_putc( digest, (a >> 16) & 0xff );
+       md_putc( digest, (a >>  8) & 0xff );
+       md_putc( digest,  a        & 0xff );
     }
-  #endif
     else {
-       /*log_debug("signature_check: unsupported pubkey algo %d\n",
-                       pkc->pubkey_algo );*/
-       rc = G10ERR_PUBKEY_ALGO;
-       goto leave;
+       byte buf[6];
+       size_t n;
+       md_putc( digest, sig->pubkey_algo );
+       md_putc( digest, sig->digest_algo );
+       if( sig->hashed_data ) {
+           n = (sig->hashed_data[0] << 8) | sig->hashed_data[1];
+           md_write( digest, sig->hashed_data, n+2 );
+           n += 6;
+       }
+       else
+           n = 6;
+       /* add some magic */
+       buf[0] = sig->version;
+       buf[1] = 0xff;
+       buf[2] = n >> 24;
+       buf[3] = n >> 16;
+       buf[4] = n >>  8;
+       buf[5] = n;
+       md_write( digest, buf, 6 );
     }
-
-
-  leave:
+    md_final( digest );
+
+    result = encode_md_value( pkc->pubkey_algo, digest, sig->digest_algo,
+                                     mpi_get_nbits(pkc->pkey[0]));
+    ctx.sig = sig;
+    ctx.md = digest;
+    rc = pubkey_verify( pkc->pubkey_algo, result, sig->data, pkc->pkey,
+                       cmp_help, &ctx );
     mpi_free( result );
+
     return rc;
 }
 
index a85f1f9..2505526 100644 (file)
@@ -53,14 +53,8 @@ do_sign( PKT_secret_cert *skc, PKT_signature *sig,
     sig->digest_algo = digest_algo;
     sig->digest_start[0] = dp[0];
     sig->digest_start[1] = dp[1];
-    if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
-       frame = mpi_alloc( (md_digest_length(digest_algo)+BYTES_PER_MPI_LIMB-1)
-                          / BYTES_PER_MPI_LIMB );
-       mpi_set_buffer( frame, md_read(md, digest_algo),
-                              md_digest_length(digest_algo), 0 );
-    }
-    else
-       frame = encode_md_value( md, digest_algo, mpi_get_nbits(skc->skey[0]));
+    frame = encode_md_value( skc->pubkey_algo, md,
+                            digest_algo, mpi_get_nbits(skc->skey[0]));
     rc = pubkey_sign( skc->pubkey_algo, sig->data, frame, skc->skey );
     mpi_free(frame);
     if( rc )
index 7913e4a..6481cee 100644 (file)
 
 #include "mpi.h"
 #include "../cipher/md.h"
-#ifdef HAVE_RSA_CIPHER
-  #include "../cipher/rsa.h"
-#endif
-#include "../cipher/elgamal.h"
-#include "../cipher/dsa.h"
 #include "../cipher/random.h"
 
 
@@ -57,9 +52,7 @@
 #define DIGEST_ALGO_MD5       1
 #define DIGEST_ALGO_SHA1      2
 #define DIGEST_ALGO_RMD160    3
-#ifdef WITH_TIGER_HASH
 #define DIGEST_ALGO_TIGER     6
-#endif
 
 #define is_RSA(a)     ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
                       || (a)==PUBKEY_ALGO_RSA_S )
@@ -123,7 +116,8 @@ int pubkey_check_secret_key( int algo, MPI *skey );
 int pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
 int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
 int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey );
-int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey );
+int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey,
+                     int (*cmp)(void *, MPI), void *opaque );
 
 /*-- smallprime.c --*/
 extern ushort small_prime_numbers[];
index 12e846c..3387378 100644 (file)
@@ -79,6 +79,10 @@ unsigned g10m_get_size( MPI a );
  *******  miscellaneous functions  *******
  *****************************************/
 
+const char *g10m_revision_string(int mode);
+const char *g10c_revision_string(int mode);
+const char *g10u_revision_string(int mode);
+
 MPI          g10c_generate_secret_prime( unsigned nbits );
 unsigned char g10c_get_random_byte( int level );
 
index 0725b7d..9d93d85 100644 (file)
@@ -55,6 +55,7 @@ typedef struct mpi_struct {
 #define MPI_NULL NULL
 
 #define mpi_get_nlimbs(a)     ((a)->nlimbs)
+#define mpi_get_nbit_info(a)  ((a)->nbits)
 #define mpi_is_neg(a)        ((a)->sign)
 
 /*-- mpiutil.c --*/
index 79d5714..6cad795 100644 (file)
@@ -25,6 +25,9 @@
 #define _g10lib_INTERNAL 1
 #include "g10lib.h"
 
+
+const char *g10m_revision_string(int dummy) { return "$Revision$"; }
+
 MPI
 g10m_new( unsigned nbits )
 {
index 2227cfc..7c66109 100644 (file)
@@ -252,6 +252,7 @@ mpi_copy( MPI a )
        b->nlimbs = a->nlimbs;
        b->sign = a->sign;
        b->secure = a->secure;
+       b->nbits = a->nbits;
        for(i=0; i < b->nlimbs; i++ )
            b->d[i] = a->d[i];
     }
@@ -273,6 +274,7 @@ mpi_set( MPI w, MPI u)
     up = u->d;
     MPN_COPY( wp, up, usize );
     w->nlimbs = usize;
+    w->nbits = u->nbits;
     w->sign = usign;
 }
 
@@ -284,6 +286,7 @@ mpi_set_ui( MPI w, unsigned long u)
     w->d[0] = u;
     w->nlimbs = u? 1:0;
     w->sign = 0;
+    w->nbits = 0;
 }
 
 
index 1b0bc9d..16e235e 100644 (file)
 #define _g10lib_INTERNAL 1
 #include "g10lib.h"
 
+
+const char *g10u_revision_string(int dummy) { return "$Revision$"; }
+
+
 void *g10_malloc( size_t n )        { return m_alloc( n ); }
 void *g10_calloc( size_t n )        { return m_alloc_clear( n ); }
 void *g10_malloc_secure( size_t n )  { return m_alloc_secure( n ); }
index e3f45be..013bd55 100644 (file)
@@ -127,7 +127,7 @@ add_entry( byte *p, unsigned n, int mode, const char *info, const char *by )
        index = memtbl_len++;
     else {
        struct memtbl_entry *e;
-       /* look for a used entry in the table.  We take the first one,
+       /* look for a used entry in the table.  We take the first one,
         * so that freed entries remain as long as possible in the table
         * (free appends a new one)
         */
@@ -338,6 +338,7 @@ out_of_core(size_t n, int secure)
 {
     log_fatal("out of %s memory while allocating %u bytes\n",
                        secure? "secure":"" ,(unsigned)n );
+
 }
 
 /****************
index 0330f59..e3aa756 100644 (file)
@@ -91,7 +91,7 @@ POSUB = po
 RANLIB = ranlib
 USE_INCLUDED_LIBINTL = yes
 USE_NLS = yes
-VERSION = 0.2.19a
+VERSION = 0.2.19b
 ZLIBS = 
 l =