summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--NEWS10
-rw-r--r--VERSION2
-rw-r--r--cipher/ChangeLog4
-rw-r--r--cipher/Makefile.am4
-rw-r--r--cipher/cipher.c2
-rw-r--r--cipher/des.c8
-rw-r--r--cipher/des.h37
-rw-r--r--cipher/dsa.c3
-rw-r--r--cipher/dsa.h3
-rw-r--r--cipher/dynload.c6
-rw-r--r--cipher/dynload.h3
-rw-r--r--cipher/elgamal.c3
-rw-r--r--cipher/elgamal.h3
-rw-r--r--cipher/g10c.c1
-rw-r--r--cipher/md.c35
-rw-r--r--cipher/md.h1
-rw-r--r--cipher/pubkey.c14
-rw-r--r--cipher/tiger.c12
-rw-r--r--cipher/tiger.h44
-rw-r--r--g10/ChangeLog9
-rw-r--r--g10/g10.c18
-rw-r--r--g10/gpgd.c2
-rw-r--r--g10/keygen.c15
-rw-r--r--g10/main.h4
-rw-r--r--g10/mainproc.c3
-rw-r--r--g10/misc.c58
-rw-r--r--g10/options.h1
-rw-r--r--g10/parse-packet.c7
-rw-r--r--g10/seckey-cert.c150
-rw-r--r--g10/seskey.c20
-rw-r--r--g10/sig-check.c284
-rw-r--r--g10/sign.c10
-rw-r--r--include/cipher.h10
-rw-r--r--include/g10lib.h4
-rw-r--r--include/mpi.h1
-rw-r--r--mpi/g10m.c3
-rw-r--r--mpi/mpiutil.c3
-rw-r--r--util/g10u.c4
-rw-r--r--util/memory.c3
-rw-r--r--zlib/Makefile2
40 files changed, 351 insertions, 455 deletions
diff --git a/NEWS b/NEWS
index a820a8eb4..01e875110 100644
--- 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 3c516158d..598394464 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.2.19a
+0.2.19b
diff --git a/cipher/ChangeLog b/cipher/ChangeLog
index 760f52d40..354206462 100644
--- a/cipher/ChangeLog
+++ b/cipher/ChangeLog
@@ -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
diff --git a/cipher/Makefile.am b/cipher/Makefile.am
index 04d1ef8ed..2cb4ddc41 100644
--- a/cipher/Makefile.am
+++ b/cipher/Makefile.am
@@ -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 \
diff --git a/cipher/cipher.c b/cipher/cipher.c
index 064947865..cedcb37af 100644
--- a/cipher/cipher.c
+++ b/cipher/cipher.c
@@ -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
diff --git a/cipher/des.c b/cipher/des.c
index 53afbc3ca..3864b2214 100644
--- a/cipher/des.c
+++ b/cipher/des.c
@@ -25,7 +25,13 @@
#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
index 55a927703..000000000
--- a/cipher/des.h
+++ /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*/
diff --git a/cipher/dsa.c b/cipher/dsa.c
index 20011da38..19a59d909 100644
--- a/cipher/dsa.c
+++ b/cipher/dsa.c
@@ -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;
diff --git a/cipher/dsa.h b/cipher/dsa.h
index fe977a645..dda32bd6d 100644
--- a/cipher/dsa.h
+++ b/cipher/dsa.h
@@ -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 );
diff --git a/cipher/dynload.c b/cipher/dynload.c
index e0b2e77e3..71f0d1959 100644
--- a/cipher/dynload.c
+++ b/cipher/dynload.c
@@ -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 */
diff --git a/cipher/dynload.h b/cipher/dynload.h
index 69b5d8fa9..2d829c717 100644
--- a/cipher/dynload.h
+++ b/cipher/dynload.h
@@ -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*/
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index b37c756cf..bcaaa20ba 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -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;
diff --git a/cipher/elgamal.h b/cipher/elgamal.h
index a4668ff9d..672f07704 100644
--- a/cipher/elgamal.h
+++ b/cipher/elgamal.h
@@ -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 );
diff --git a/cipher/g10c.c b/cipher/g10c.c
index c6f94022b..5bf0eb61f 100644
--- a/cipher/g10c.c
+++ b/cipher/g10c.c
@@ -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 )
diff --git a/cipher/md.c b/cipher/md.c
index 30d7e255d..b116dd975 100644
--- a/cipher/md.c
+++ b/cipher/md.c
@@ -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;
diff --git a/cipher/md.h b/cipher/md.h
index 2d45a1273..b4d690793 100644
--- a/cipher/md.h
+++ b/cipher/md.h
@@ -25,7 +25,6 @@
#include "rmd.h"
#include "sha1.h"
#include "md5.h"
-#include "tiger.h"
#define MD_BUFFER_SIZE 512
diff --git a/cipher/pubkey.c b/cipher/pubkey.c
index 3357ae12c..b18f1c316 100644
--- a/cipher/pubkey.c
+++ b/cipher/pubkey.c
@@ -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() );
diff --git a/cipher/tiger.c b/cipher/tiger.c
index c43226445..11c11b461 100644
--- a/cipher/tiger.c
+++ b/cipher/tiger.c
@@ -25,9 +25,15 @@
#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
index 906909269..000000000
--- a/cipher/tiger.h
+++ /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*/
diff --git a/g10/ChangeLog b/g10/ChangeLog
index d6ed0cc6d..15fd2c81b 100644
--- a/g10/ChangeLog
+++ b/g10/ChangeLog
@@ -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
diff --git a/g10/g10.c b/g10/g10.c
index 8f65f2efc..828fef2ff 100644
--- 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');
}
diff --git a/g10/gpgd.c b/g10/gpgd.c
index 72fcade8d..34158b7f9 100644
--- a/g10/gpgd.c
+++ b/g10/gpgd.c
@@ -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;
}
diff --git a/g10/keygen.c b/g10/keygen.c
index 8ad30bb9b..21c388bfc 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -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 );
diff --git a/g10/main.h b/g10/main.h
index 56fd3c9d5..0b30084e3 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -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 );
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 707272be0..a807f85d9 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -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));
diff --git a/g10/misc.c b/g10/misc.c
index 782b5cd10..d1bacf694 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -28,7 +28,15 @@
#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;
+}
diff --git a/g10/options.h b/g10/options.h
index 4b32b524c..1e34ced08 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -48,6 +48,7 @@ struct {
int compress_keys;
int always_trust;
int rfc1991;
+ unsigned emulate_bugs; /* bug emulation flags */
} opt;
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 0cd4238ad..9e469b644 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -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;
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 9ac19c89c..f30e5d0e9 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -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 );
}
}
diff --git a/g10/seskey.c b/g10/seskey.c
index 25819909c..5b271a2d4 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -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;
}
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 0ef69b7d5..76f0aaca7 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -32,6 +32,11 @@
#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;
}
diff --git a/g10/sign.c b/g10/sign.c
index a85f1f952..2505526ce 100644
--- a/g10/sign.c
+++ b/g10/sign.c
@@ -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 )
diff --git a/include/cipher.h b/include/cipher.h
index 7913e4a33..6481ceeda 100644
--- a/include/cipher.h
+++ b/include/cipher.h
@@ -29,11 +29,6 @@
#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[];
diff --git a/include/g10lib.h b/include/g10lib.h
index 12e846ca8..338737831 100644
--- a/include/g10lib.h
+++ b/include/g10lib.h
@@ -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 );
diff --git a/include/mpi.h b/include/mpi.h
index 0725b7d6b..9d93d8505 100644
--- a/include/mpi.h
+++ b/include/mpi.h
@@ -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 --*/
diff --git a/mpi/g10m.c b/mpi/g10m.c
index 79d571462..6cad79587 100644
--- a/mpi/g10m.c
+++ b/mpi/g10m.c
@@ -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 )
{
diff --git a/mpi/mpiutil.c b/mpi/mpiutil.c
index 2227cfc19..7c661094f 100644
--- a/mpi/mpiutil.c
+++ b/mpi/mpiutil.c
@@ -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;
}
diff --git a/util/g10u.c b/util/g10u.c
index 1b0bc9d4c..16e235e09 100644
--- a/util/g10u.c
+++ b/util/g10u.c
@@ -25,6 +25,10 @@
#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 ); }
diff --git a/util/memory.c b/util/memory.c
index e3f45be5b..013bd55cc 100644
--- a/util/memory.c
+++ b/util/memory.c
@@ -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 );
+
}
/****************
diff --git a/zlib/Makefile b/zlib/Makefile
index 0330f59c5..e3aa756ed 100644
--- a/zlib/Makefile
+++ b/zlib/Makefile
@@ -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 =