mirror of
git://git.gnupg.org/gnupg.git
synced 2025-01-02 12:01:32 +01:00
extensions are now working and fixed a lot of bugs
This commit is contained in:
parent
e662bf708b
commit
6e1ca6b80f
10
NEWS
10
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
|
Noteworthy changes in version 0.2.19
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
|
@ -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)
|
Sat Jun 13 14:16:57 1998 Werner Koch (wk@isil.d.shuttle.de)
|
||||||
|
|
||||||
* pubkey.c: Major changes to allow extensions. Changed the inteface
|
* pubkey.c: Major changes to allow extensions. Changed the inteface
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl -I../intl
|
||||||
|
|
||||||
|
EXTRA_DIST = tiger.c
|
||||||
noinst_LIBRARIES = libcipher.a
|
noinst_LIBRARIES = libcipher.a
|
||||||
|
|
||||||
|
|
||||||
@ -15,7 +16,6 @@ libcipher_a_SOURCES = cipher.c \
|
|||||||
blowfish.h \
|
blowfish.h \
|
||||||
cast5.c \
|
cast5.c \
|
||||||
cast5.h \
|
cast5.h \
|
||||||
des.h \
|
|
||||||
elgamal.c \
|
elgamal.c \
|
||||||
elgamal.h \
|
elgamal.h \
|
||||||
md5.c \
|
md5.c \
|
||||||
@ -29,8 +29,6 @@ libcipher_a_SOURCES = cipher.c \
|
|||||||
rand-dummy.c \
|
rand-dummy.c \
|
||||||
rmd.h \
|
rmd.h \
|
||||||
rmd160.c \
|
rmd160.c \
|
||||||
tiger.h \
|
|
||||||
tiger.c \
|
|
||||||
sha1.h \
|
sha1.h \
|
||||||
sha1.c \
|
sha1.c \
|
||||||
dsa.h \
|
dsa.h \
|
||||||
|
@ -31,7 +31,6 @@
|
|||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
#include "blowfish.h"
|
#include "blowfish.h"
|
||||||
#include "cast5.h"
|
#include "cast5.h"
|
||||||
#include "des.h"
|
|
||||||
#include "dynload.h"
|
#include "dynload.h"
|
||||||
|
|
||||||
|
|
||||||
@ -64,7 +63,6 @@ struct cipher_handle_s {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
dummy_setkey( void *c, byte *key, unsigned keylen ) { }
|
dummy_setkey( void *c, byte *key, unsigned keylen ) { }
|
||||||
static void
|
static void
|
||||||
|
@ -25,7 +25,13 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "types.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] = {
|
static const int IP[64] = {
|
||||||
|
37
cipher/des.h
37
cipher/des.h
@ -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*/
|
|
@ -359,7 +359,8 @@ dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
DSA_public_key pk;
|
||||||
|
|
||||||
|
@ -23,7 +23,8 @@
|
|||||||
int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
|
int dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors );
|
||||||
int dsa_check_secret_key( int algo, MPI *skey );
|
int dsa_check_secret_key( int algo, MPI *skey );
|
||||||
int dsa_sign( int algo, MPI *resarr, MPI data, 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 );
|
unsigned dsa_get_nbits( int algo, MPI *pkey );
|
||||||
const char *dsa_get_info( int algo, int *npkey, int *nskey,
|
const char *dsa_get_info( int algo, int *npkey, int *nskey,
|
||||||
int *nenc, int *nsig, int *usage );
|
int *nenc, int *nsig, int *usage );
|
||||||
|
@ -221,7 +221,8 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
|
|||||||
int (**encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey ),
|
int (**encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey ),
|
||||||
int (**decrypt)( int algo, MPI *result, MPI *data, MPI *skey ),
|
int (**decrypt)( int algo, MPI *result, MPI *data, MPI *skey ),
|
||||||
int (**sign)( int algo, MPI *resarr, 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 ) )
|
unsigned (**get_nbits)( int algo, MPI *pkey ) )
|
||||||
{
|
{
|
||||||
EXTLIST r;
|
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 (**)( int, MPI *, MPI , MPI * ),
|
||||||
int (**)( int, MPI , MPI *, MPI * ),
|
int (**)( int, MPI , MPI *, MPI *,
|
||||||
|
int (*)(void*,MPI), void *),
|
||||||
unsigned (**)( int , MPI * ) );
|
unsigned (**)( int , MPI * ) );
|
||||||
|
|
||||||
if( !*enum_context ) { /* init context */
|
if( !*enum_context ) { /* init context */
|
||||||
|
@ -36,7 +36,8 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo,
|
|||||||
int (**encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey ),
|
int (**encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey ),
|
||||||
int (**decrypt)( int algo, MPI *result, MPI *data, MPI *skey ),
|
int (**decrypt)( int algo, MPI *result, MPI *data, MPI *skey ),
|
||||||
int (**sign)( int algo, MPI *resarr, 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 ) );
|
unsigned (**get_nbits)( int algo, MPI *pkey ) );
|
||||||
|
|
||||||
#endif /*G10_CIPHER_DYNLOAD_H*/
|
#endif /*G10_CIPHER_DYNLOAD_H*/
|
||||||
|
@ -476,7 +476,8 @@ elg_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||||||
}
|
}
|
||||||
|
|
||||||
int
|
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;
|
ELG_public_key pk;
|
||||||
|
|
||||||
|
@ -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_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
|
||||||
int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
|
int elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
|
||||||
int elg_sign( int algo, MPI *resarr, 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 );
|
unsigned elg_get_nbits( int algo, MPI *pkey );
|
||||||
const char *elg_get_info( int algo, int *npkey, int *nskey,
|
const char *elg_get_info( int algo, int *npkey, int *nskey,
|
||||||
int *nenc, int *nsig, int *usage );
|
int *nenc, int *nsig, int *usage );
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
#define _g10lib_INTERNAL 1
|
#define _g10lib_INTERNAL 1
|
||||||
#include "g10lib.h"
|
#include "g10lib.h"
|
||||||
|
|
||||||
|
const char *g10c_revision_string(int dummy) { return "$Revision$"; }
|
||||||
|
|
||||||
MPI
|
MPI
|
||||||
g10c_generate_secret_prime( unsigned nbits )
|
g10c_generate_secret_prime( unsigned nbits )
|
||||||
|
35
cipher/md.c
35
cipher/md.c
@ -38,7 +38,6 @@ static struct { const char *name; int algo;} digest_names[] = {
|
|||||||
{ "RMD160", DIGEST_ALGO_RMD160 },
|
{ "RMD160", DIGEST_ALGO_RMD160 },
|
||||||
{ "RMD-160", DIGEST_ALGO_RMD160 },
|
{ "RMD-160", DIGEST_ALGO_RMD160 },
|
||||||
{ "RIPE-MD-160", DIGEST_ALGO_RMD160 },
|
{ "RIPE-MD-160", DIGEST_ALGO_RMD160 },
|
||||||
{ "TIGER", DIGEST_ALGO_TIGER },
|
|
||||||
{NULL} };
|
{NULL} };
|
||||||
|
|
||||||
|
|
||||||
@ -79,9 +78,6 @@ int
|
|||||||
check_digest_algo( int algo )
|
check_digest_algo( int algo )
|
||||||
{
|
{
|
||||||
switch( algo ) {
|
switch( algo ) {
|
||||||
#ifdef WITH_TIGER_HASH
|
|
||||||
case DIGEST_ALGO_TIGER:
|
|
||||||
#endif
|
|
||||||
case DIGEST_ALGO_MD5:
|
case DIGEST_ALGO_MD5:
|
||||||
case DIGEST_ALGO_RMD160:
|
case DIGEST_ALGO_RMD160:
|
||||||
case DIGEST_ALGO_SHA1:
|
case DIGEST_ALGO_SHA1:
|
||||||
@ -134,13 +130,6 @@ md_enable( MD_HANDLE h, int algo )
|
|||||||
sha1_init( &h->sha1 );
|
sha1_init( &h->sha1 );
|
||||||
h->use_sha1 = 1;
|
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
|
else
|
||||||
log_bug("md_enable(%d)", algo );
|
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, a->buffer, a->bufcount );
|
||||||
sha1_write( &a->sha1, inbuf, inlen );
|
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 ) {
|
if( a->use_md5 ) {
|
||||||
md5_write( &a->md5, a->buffer, a->bufcount );
|
md5_write( &a->md5, a->buffer, a->bufcount );
|
||||||
md5_write( &a->md5, inbuf, inlen );
|
md5_write( &a->md5, inbuf, inlen );
|
||||||
@ -210,10 +193,6 @@ md_final(MD_HANDLE a)
|
|||||||
rmd160_final( &a->rmd160 );
|
rmd160_final( &a->rmd160 );
|
||||||
if( a->use_sha1 )
|
if( a->use_sha1 )
|
||||||
sha1_final( &a->sha1 );
|
sha1_final( &a->sha1 );
|
||||||
#ifdef WITH_TIGER_HASH
|
|
||||||
if( a->use_tiger )
|
|
||||||
tiger_final( &a->tiger );
|
|
||||||
#endif
|
|
||||||
if( a->use_md5 )
|
if( a->use_md5 )
|
||||||
md5_final( &a->md5 );
|
md5_final( &a->md5 );
|
||||||
}
|
}
|
||||||
@ -230,10 +209,6 @@ md_read( MD_HANDLE a, int algo )
|
|||||||
return rmd160_read( &a->rmd160 );
|
return rmd160_read( &a->rmd160 );
|
||||||
if( a->use_sha1 )
|
if( a->use_sha1 )
|
||||||
return sha1_read( &a->sha1 );
|
return sha1_read( &a->sha1 );
|
||||||
#ifdef WITH_TIGER_HASH
|
|
||||||
if( a->use_tiger )
|
|
||||||
return tiger_read( &a->tiger );
|
|
||||||
#endif
|
|
||||||
if( a->use_md5 )
|
if( a->use_md5 )
|
||||||
return md5_read( &a->md5 );
|
return md5_read( &a->md5 );
|
||||||
}
|
}
|
||||||
@ -242,10 +217,6 @@ md_read( MD_HANDLE a, int algo )
|
|||||||
return rmd160_read( &a->rmd160 );
|
return rmd160_read( &a->rmd160 );
|
||||||
if( algo == DIGEST_ALGO_SHA1 )
|
if( algo == DIGEST_ALGO_SHA1 )
|
||||||
return sha1_read( &a->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 )
|
if( algo == DIGEST_ALGO_MD5 )
|
||||||
return md5_read( &a->md5 );
|
return md5_read( &a->md5 );
|
||||||
}
|
}
|
||||||
@ -259,10 +230,6 @@ md_get_algo( MD_HANDLE a )
|
|||||||
return DIGEST_ALGO_RMD160;
|
return DIGEST_ALGO_RMD160;
|
||||||
if( a->use_sha1 )
|
if( a->use_sha1 )
|
||||||
return DIGEST_ALGO_SHA1;
|
return DIGEST_ALGO_SHA1;
|
||||||
#ifdef WITH_TIGER_HASH
|
|
||||||
if( a->use_tiger )
|
|
||||||
return DIGEST_ALGO_TIGER;
|
|
||||||
#endif
|
|
||||||
if( a->use_md5 )
|
if( a->use_md5 )
|
||||||
return DIGEST_ALGO_MD5;
|
return DIGEST_ALGO_MD5;
|
||||||
return 0;
|
return 0;
|
||||||
@ -275,8 +242,6 @@ int
|
|||||||
md_digest_length( int algo )
|
md_digest_length( int algo )
|
||||||
{
|
{
|
||||||
switch( algo ) {
|
switch( algo ) {
|
||||||
case DIGEST_ALGO_TIGER:
|
|
||||||
return 24;
|
|
||||||
case DIGEST_ALGO_RMD160:
|
case DIGEST_ALGO_RMD160:
|
||||||
case DIGEST_ALGO_SHA1:
|
case DIGEST_ALGO_SHA1:
|
||||||
return 20;
|
return 20;
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "rmd.h"
|
#include "rmd.h"
|
||||||
#include "sha1.h"
|
#include "sha1.h"
|
||||||
#include "md5.h"
|
#include "md5.h"
|
||||||
#include "tiger.h"
|
|
||||||
|
|
||||||
#define MD_BUFFER_SIZE 512
|
#define MD_BUFFER_SIZE 512
|
||||||
|
|
||||||
|
@ -28,6 +28,8 @@
|
|||||||
#include "errors.h"
|
#include "errors.h"
|
||||||
#include "mpi.h"
|
#include "mpi.h"
|
||||||
#include "cipher.h"
|
#include "cipher.h"
|
||||||
|
#include "elgamal.h"
|
||||||
|
#include "dsa.h"
|
||||||
#include "dynload.h"
|
#include "dynload.h"
|
||||||
|
|
||||||
|
|
||||||
@ -46,7 +48,8 @@ struct pubkey_table_s {
|
|||||||
int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
|
int (*encrypt)( int algo, MPI *resarr, MPI data, MPI *pkey );
|
||||||
int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey );
|
int (*decrypt)( int algo, MPI *result, MPI *data, MPI *skey );
|
||||||
int (*sign)( int algo, MPI *resarr, 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 );
|
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; }
|
{ log_bug("no sign() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||||
|
|
||||||
static int
|
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; }
|
{ log_bug("no verify() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; }
|
||||||
|
|
||||||
static unsigned
|
static unsigned
|
||||||
@ -523,7 +527,8 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey )
|
|||||||
* Return 0 if the signature is good
|
* Return 0 if the signature is good
|
||||||
*/
|
*/
|
||||||
int
|
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;
|
int i, rc;
|
||||||
|
|
||||||
@ -531,7 +536,8 @@ pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey )
|
|||||||
do {
|
do {
|
||||||
for(i=0; pubkey_table[i].name; i++ )
|
for(i=0; pubkey_table[i].name; i++ )
|
||||||
if( pubkey_table[i].algo == algo ) {
|
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;
|
goto ready;
|
||||||
}
|
}
|
||||||
} while( load_pubkey_modules() );
|
} while( load_pubkey_modules() );
|
||||||
|
@ -25,9 +25,15 @@
|
|||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "memory.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.
|
* Okay, okay, this is not the fastest code - improvements are welcome.
|
||||||
@ -845,5 +851,3 @@ tiger_final( TIGER_CONTEXT *hd )
|
|||||||
#undef X
|
#undef X
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif /* WITH_TIGER_HASH */
|
|
||||||
|
|
||||||
|
@ -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*/
|
|
@ -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)
|
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
|
which is now stored in an array and not anaymore in a union of
|
||||||
algorithm specific structures. These is needed to make the system
|
algorithm specific structures. These is needed to make the system
|
||||||
more extendable and makes a lot of stuff much simpler. Changed
|
more extendable and makes a lot of stuff much simpler. Changed
|
||||||
|
18
g10/g10.c
18
g10/g10.c
@ -164,6 +164,7 @@ static ARGPARSE_OPTS opts[] = {
|
|||||||
{ 553, "skip-verify",0, "@" },
|
{ 553, "skip-verify",0, "@" },
|
||||||
{ 557, "compress-keys",0, "@"},
|
{ 557, "compress-keys",0, "@"},
|
||||||
{ 559, "always-trust", 0, "@"},
|
{ 559, "always-trust", 0, "@"},
|
||||||
|
{ 562, "emulate-checksum-bug", 0, "@"},
|
||||||
|
|
||||||
{0} };
|
{0} };
|
||||||
|
|
||||||
@ -310,11 +311,6 @@ wrong_args( const char *text)
|
|||||||
static void
|
static void
|
||||||
set_debug(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 )
|
if( opt.debug & DBG_MEMORY_VALUE )
|
||||||
memory_debug_mode = 1;
|
memory_debug_mode = 1;
|
||||||
if( opt.debug & DBG_MEMSTAT_VALUE )
|
if( opt.debug & DBG_MEMSTAT_VALUE )
|
||||||
@ -598,6 +594,7 @@ main( int argc, char **argv )
|
|||||||
case 559: opt.always_trust = 1; break;
|
case 559: opt.always_trust = 1; break;
|
||||||
case 560: register_cipher_extension(pargs.r.ret_str); break;
|
case 560: register_cipher_extension(pargs.r.ret_str); break;
|
||||||
case 561: opt.rfc1991 = 1; break;
|
case 561: opt.rfc1991 = 1; break;
|
||||||
|
case 562: opt.emulate_bugs |= 1; break;
|
||||||
default : errors++; pargs.err = configfp? 1:2; 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_MD5 );
|
||||||
md_enable( md, DIGEST_ALGO_SHA1 );
|
md_enable( md, DIGEST_ALGO_SHA1 );
|
||||||
md_enable( md, DIGEST_ALGO_RMD160 );
|
md_enable( md, DIGEST_ALGO_RMD160 );
|
||||||
#ifdef WITH_TIGER_HASH
|
if( !check_digest_algo(DIGEST_ALGO_TIGER) )
|
||||||
md_enable( md, DIGEST_ALGO_TIGER );
|
md_enable( md, DIGEST_ALGO_TIGER );
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
while( (n=fread( buf, 1, DIM(buf), fp )) )
|
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 );
|
print_hex(md_read(md, DIGEST_ALGO_SHA1), 20 );
|
||||||
printf("\n%sRMD160 = ", fname?pname:"" );
|
printf("\n%sRMD160 = ", fname?pname:"" );
|
||||||
print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
|
print_hex(md_read(md, DIGEST_ALGO_RMD160), 20 );
|
||||||
#ifdef WITH_TIGER_HASH
|
if( !check_digest_algo(DIGEST_ALGO_TIGER) ) {
|
||||||
printf("\n%s TIGER = ", fname?pname:"" );
|
printf("\n%s TIGER = ", fname?pname:"" );
|
||||||
print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
|
print_hex(md_read(md, DIGEST_ALGO_TIGER), 24 );
|
||||||
#endif
|
}
|
||||||
}
|
}
|
||||||
putchar('\n');
|
putchar('\n');
|
||||||
}
|
}
|
||||||
|
@ -129,7 +129,7 @@ set_debug(void)
|
|||||||
if( opt.debug & DBG_MPI_VALUE )
|
if( opt.debug & DBG_MPI_VALUE )
|
||||||
mpi_debug_mode = 1;
|
mpi_debug_mode = 1;
|
||||||
if( opt.debug & DBG_CIPHER_VALUE )
|
if( opt.debug & DBG_CIPHER_VALUE )
|
||||||
cipher_debug_mode = 1;
|
g10c_debug_mode = 1;
|
||||||
if( opt.debug & DBG_IOBUF_VALUE )
|
if( opt.debug & DBG_IOBUF_VALUE )
|
||||||
iobuf_debug_mode = 1;
|
iobuf_debug_mode = 1;
|
||||||
}
|
}
|
||||||
|
15
g10/keygen.c
15
g10/keygen.c
@ -168,7 +168,7 @@ gen_elg(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek,
|
|||||||
skc->is_protected = 0;
|
skc->is_protected = 0;
|
||||||
skc->protect.algo = 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 */
|
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
|
||||||
*ret_skc = copy_secret_cert( NULL, 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_p = sk.p;
|
||||||
skc->d.rsa.rsa_q = sk.q;
|
skc->d.rsa.rsa_q = sk.q;
|
||||||
skc->d.rsa.rsa_u = sk.u;
|
skc->d.rsa.rsa_u = sk.u;
|
||||||
skc->d.rsa.csum = checksum_mpi( skc->d.rsa.rsa_d );
|
skc->d.rsa.csum = checksum_mpi_counted_nbits( skc->d.rsa.rsa_d );
|
||||||
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_p );
|
skc->d.rsa.csum += checksum_mpi_counted_nbits( skc->d.rsa.rsa_p );
|
||||||
skc->d.rsa.csum += checksum_mpi( skc->d.rsa.rsa_q );
|
skc->d.rsa.csum += checksum_mpi_counted_nbits( 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_u );
|
||||||
|
|
||||||
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
|
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
|
||||||
*ret_skc = copy_secret_cert( NULL, 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.is_protected = 1;
|
||||||
skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
|
skc->d.rsa.protect_algo = CIPHER_ALGO_BLOWFISH;
|
||||||
randomize_buffer( skc->d.rsa.protect.blowfish.iv, 8, 1);
|
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 );
|
rc = protect_secret_key( skc, dek );
|
||||||
if( rc ) {
|
if( rc ) {
|
||||||
log_error("protect_secret_key failed: %s\n", g10_errstr(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->is_protected = 0;
|
||||||
skc->protect.algo = 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 */
|
if( ret_skc ) /* not a subkey: return an unprotected version of the skc */
|
||||||
*ret_skc = copy_secret_cert( NULL, skc );
|
*ret_skc = copy_secret_cert( NULL, skc );
|
||||||
|
|
||||||
|
@ -49,6 +49,7 @@ void trap_unaligned(void);
|
|||||||
u16 checksum_u16( unsigned n );
|
u16 checksum_u16( unsigned n );
|
||||||
u16 checksum( byte *p, unsigned n );
|
u16 checksum( byte *p, unsigned n );
|
||||||
u16 checksum_mpi( MPI a );
|
u16 checksum_mpi( MPI a );
|
||||||
|
u16 checksum_mpi_counted_nbits( MPI a );
|
||||||
|
|
||||||
/*-- encode.c --*/
|
/*-- encode.c --*/
|
||||||
int encode_symmetric( const char *filename );
|
int encode_symmetric( const char *filename );
|
||||||
@ -85,7 +86,8 @@ IOBUF open_sigfile( const char *iname );
|
|||||||
/*-- seskey.c --*/
|
/*-- seskey.c --*/
|
||||||
void make_session_key( DEK *dek );
|
void make_session_key( DEK *dek );
|
||||||
MPI encode_session_key( DEK *dek, unsigned nbits );
|
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 --*/
|
/*-- comment.c --*/
|
||||||
KBNODE make_comment_node( const char *s );
|
KBNODE make_comment_node( const char *s );
|
||||||
|
@ -246,7 +246,8 @@ proc_plaintext( CTX c, PACKET *pkt )
|
|||||||
/*md_start_debug(c->mfx.md, "proc_plaintext");*/
|
/*md_start_debug(c->mfx.md, "proc_plaintext");*/
|
||||||
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
|
md_enable( c->mfx.md, DIGEST_ALGO_SHA1 );
|
||||||
md_enable( c->mfx.md, DIGEST_ALGO_MD5 );
|
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 );
|
rc = handle_plaintext( pt, &c->mfx );
|
||||||
if( rc )
|
if( rc )
|
||||||
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
|
log_error( "handle plaintext failed: %s\n", g10_errstr(rc));
|
||||||
|
58
g10/misc.c
58
g10/misc.c
@ -28,7 +28,15 @@
|
|||||||
#endif
|
#endif
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
#include "main.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__)
|
#if defined(__linux__) && defined(__alpha__)
|
||||||
@ -63,7 +71,22 @@ checksum_u16( unsigned n )
|
|||||||
u16 a;
|
u16 a;
|
||||||
|
|
||||||
a = (n >> 8) & 0xff;
|
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;
|
return a;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,12 +106,43 @@ checksum_mpi( MPI a )
|
|||||||
u16 csum;
|
u16 csum;
|
||||||
byte *buffer;
|
byte *buffer;
|
||||||
unsigned nbytes;
|
unsigned nbytes;
|
||||||
|
unsigned nbits;
|
||||||
|
|
||||||
buffer = mpi_get_buffer( a, &nbytes, NULL );
|
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 );
|
csum += checksum( buffer, nbytes );
|
||||||
m_free( buffer );
|
m_free( buffer );
|
||||||
return csum;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -48,6 +48,7 @@ struct {
|
|||||||
int compress_keys;
|
int compress_keys;
|
||||||
int always_trust;
|
int always_trust;
|
||||||
int rfc1991;
|
int rfc1991;
|
||||||
|
unsigned emulate_bugs; /* bug emulation flags */
|
||||||
} opt;
|
} opt;
|
||||||
|
|
||||||
|
|
||||||
|
@ -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,
|
static int parse_encrypted( IOBUF inp, int pkttype, unsigned long pktlen,
|
||||||
PACKET *packet );
|
PACKET *packet );
|
||||||
|
|
||||||
|
|
||||||
static unsigned short
|
static unsigned short
|
||||||
read_16(IOBUF inp)
|
read_16(IOBUF inp)
|
||||||
{
|
{
|
||||||
@ -1006,9 +1007,6 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
|
|
||||||
cert->csum = read_16(inp); pktlen -= 2;
|
cert->csum = read_16(inp); pktlen -= 2;
|
||||||
if( list_mode ) {
|
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"
|
printf("\t[secret value x is not shown]\n"
|
||||||
"\tchecksum: %04hx\n", cert->csum);
|
"\tchecksum: %04hx\n", cert->csum);
|
||||||
}
|
}
|
||||||
@ -1174,8 +1172,7 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
|
|||||||
printf(" %02x", temp[i] );
|
printf(" %02x", temp[i] );
|
||||||
putchar('\n');
|
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 */
|
/* old version, we don't have a S2K, so we fake one */
|
||||||
cert->protect.s2k.mode = 0;
|
cert->protect.s2k.mode = 0;
|
||||||
cert->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
|
cert->protect.s2k.hash_algo = DIGEST_ALGO_MD5;
|
||||||
|
@ -39,7 +39,7 @@ do_check( PKT_secret_cert *cert )
|
|||||||
{
|
{
|
||||||
byte *buffer;
|
byte *buffer;
|
||||||
u16 csum=0;
|
u16 csum=0;
|
||||||
int res;
|
int i, res;
|
||||||
unsigned nbytes;
|
unsigned nbytes;
|
||||||
|
|
||||||
if( cert->is_protected ) { /* remove the protection */
|
if( cert->is_protected ) { /* remove the protection */
|
||||||
@ -60,60 +60,34 @@ do_check( PKT_secret_cert *cert )
|
|||||||
CIPHER_MODE_AUTO_CFB, 1);
|
CIPHER_MODE_AUTO_CFB, 1);
|
||||||
cipher_setkey( cipher_hd, dek->key, dek->keylen );
|
cipher_setkey( cipher_hd, dek->key, dek->keylen );
|
||||||
cipher_setiv( cipher_hd, NULL );
|
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 );
|
save_cert = copy_secret_cert( NULL, cert );
|
||||||
memcpy(save_iv, cert->protect.iv, 8 );
|
memcpy(save_iv, cert->protect.iv, 8 );
|
||||||
cipher_decrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
|
cipher_decrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
|
||||||
switch( cert->pubkey_algo ) {
|
csum = 0;
|
||||||
case PUBKEY_ALGO_ELGAMAL:
|
for(i=pubkey_get_npkey(cert->pubkey_algo);
|
||||||
case PUBKEY_ALGO_ELGAMAL_E:
|
i < pubkey_get_nskey(cert->pubkey_algo); i++ ) {
|
||||||
/* FIXME: removed ELG knowledge from this function */
|
buffer = mpi_get_secure_buffer( cert->skey[i], &nbytes, NULL );
|
||||||
buffer = mpi_get_secure_buffer( cert->skey[3], &nbytes, NULL );
|
cipher_sync( cipher_hd );
|
||||||
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
|
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
|
||||||
mpi_set_buffer( cert->skey[3], buffer, nbytes, 0 );
|
mpi_set_buffer( cert->skey[i], buffer, nbytes, 0 );
|
||||||
csum = checksum_mpi( cert->skey[3] );
|
csum += checksum_mpi( cert->skey[i] );
|
||||||
m_free( buffer );
|
m_free( buffer );
|
||||||
break;
|
}
|
||||||
case PUBKEY_ALGO_DSA:
|
if( opt.emulate_bugs & 1 ) {
|
||||||
buffer = mpi_get_secure_buffer( cert->skey[4], &nbytes, NULL );
|
log_debug("secret key csum is=%04hx should=%04hx algos=%d/%d\n",
|
||||||
cipher_decrypt( cipher_hd, buffer, buffer, nbytes );
|
csum, cert->csum, cert->pubkey_algo,cert->protect.algo );
|
||||||
mpi_set_buffer( cert->skey[4], buffer, nbytes, 0 );
|
csum = cert->csum;
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
cipher_close( cipher_hd );
|
cipher_close( cipher_hd );
|
||||||
/* now let's see whether we have used the right passphrase */
|
/* now let's see whether we have used the right passphrase */
|
||||||
if( csum != cert->csum ) {
|
if( csum != cert->csum ) {
|
||||||
if( csum != cert->csum ) {
|
copy_secret_cert( cert, save_cert );
|
||||||
copy_secret_cert( cert, save_cert );
|
free_secret_cert( save_cert );
|
||||||
free_secret_cert( save_cert );
|
memcpy( cert->protect.iv, save_iv, 8 );
|
||||||
memcpy( cert->protect.iv, save_iv, 8 );
|
return G10ERR_BAD_PASS;
|
||||||
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 );
|
res = pubkey_check_secret_key( cert->pubkey_algo, cert->skey );
|
||||||
if( res ) {
|
if( res ) {
|
||||||
copy_secret_cert( cert, save_cert );
|
copy_secret_cert( cert, save_cert );
|
||||||
@ -124,37 +98,11 @@ do_check( PKT_secret_cert *cert )
|
|||||||
free_secret_cert( save_cert );
|
free_secret_cert( save_cert );
|
||||||
cert->is_protected = 0;
|
cert->is_protected = 0;
|
||||||
}
|
}
|
||||||
else { /* not protected */
|
else { /* not protected, assume it is okay if the checksum is okay */
|
||||||
switch( cert->pubkey_algo ) {
|
csum = 0;
|
||||||
case PUBKEY_ALGO_ELGAMAL_E:
|
for(i=pubkey_get_npkey(cert->pubkey_algo);
|
||||||
case PUBKEY_ALGO_ELGAMAL:
|
i < pubkey_get_nskey(cert->pubkey_algo); i++ ) {
|
||||||
csum = checksum_mpi( cert->skey[3] );
|
csum += checksum_mpi( cert->skey[i] );
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
if( csum != cert->csum )
|
if( csum != cert->csum )
|
||||||
return G10ERR_CHECKSUM;
|
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
|
* Protect the secret key certificate with the passphrase from DEK
|
||||||
@ -247,7 +167,10 @@ do_protect( void (*fnc)(CIPHER_HANDLE, byte *, byte *, unsigned),
|
|||||||
int
|
int
|
||||||
protect_secret_key( PKT_secret_cert *cert, DEK *dek )
|
protect_secret_key( PKT_secret_cert *cert, DEK *dek )
|
||||||
{
|
{
|
||||||
int rc=0;
|
int i, rc = 0;
|
||||||
|
byte *buffer;
|
||||||
|
unsigned nbytes;
|
||||||
|
u16 csum;
|
||||||
|
|
||||||
if( !dek )
|
if( !dek )
|
||||||
return 0;
|
return 0;
|
||||||
@ -263,8 +186,21 @@ protect_secret_key( PKT_secret_cert *cert, DEK *dek )
|
|||||||
cipher_setkey( cipher_hd, dek->key, dek->keylen );
|
cipher_setkey( cipher_hd, dek->key, dek->keylen );
|
||||||
cipher_setiv( cipher_hd, NULL );
|
cipher_setiv( cipher_hd, NULL );
|
||||||
cipher_encrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
|
cipher_encrypt( cipher_hd, cert->protect.iv, cert->protect.iv, 8 );
|
||||||
if( !do_protect( &cipher_encrypt, cipher_hd, cert ) )
|
/* NOTE: we always recalculate the checksum because there are some
|
||||||
cert->is_protected = 1;
|
* 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 );
|
cipher_close( cipher_hd );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
18
g10/seskey.c
18
g10/seskey.c
@ -144,13 +144,25 @@ do_encode_md( MD_HANDLE md, int algo, size_t len, unsigned nbits,
|
|||||||
|
|
||||||
|
|
||||||
MPI
|
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);
|
int algo = hash_algo? hash_algo : md_get_algo(md);
|
||||||
const byte *asn;
|
const byte *asn;
|
||||||
size_t asnlen, mdlen;
|
size_t asnlen, mdlen;
|
||||||
|
MPI frame;
|
||||||
|
|
||||||
asn = md_asn_oid( algo, &asnlen, &mdlen );
|
if( pubkey_algo == PUBKEY_ALGO_DSA ) {
|
||||||
return do_encode_md( md, algo, mdlen, nbits, asn, asnlen );
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
284
g10/sig-check.c
284
g10/sig-check.c
@ -32,6 +32,11 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "status.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,
|
static int do_check( PKT_public_cert *pkc, PKT_signature *sig,
|
||||||
MD_HANDLE digest );
|
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
|
static int
|
||||||
do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest )
|
||||||
{
|
{
|
||||||
MPI result = NULL;
|
MPI result = NULL;
|
||||||
int rc=0;
|
int rc=0;
|
||||||
|
struct cmp_help_context_s ctx;
|
||||||
|
|
||||||
if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
|
if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) {
|
||||||
log_info("this is a PGP generated "
|
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 )
|
if( pkc->timestamp > sig->timestamp )
|
||||||
return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */
|
return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */
|
||||||
|
|
||||||
if( is_ELGAMAL(pkc->pubkey_algo) ) {
|
if( (rc=check_digest_algo(sig->digest_algo)) )
|
||||||
if( (rc=check_digest_algo(sig->digest_algo)) )
|
return rc;
|
||||||
goto leave;
|
if( (rc=check_pubkey_algo(sig->pubkey_algo)) )
|
||||||
/* make sure the digest algo is enabled (in case of a detached
|
return rc;
|
||||||
* signature */
|
|
||||||
md_enable( digest, sig->digest_algo );
|
/* make sure the digest algo is enabled (in case of a detached signature)*/
|
||||||
/* complete the digest */
|
md_enable( digest, sig->digest_algo );
|
||||||
md_putc( digest, sig->sig_class );
|
|
||||||
{ u32 a = sig->timestamp;
|
/* complete the digest */
|
||||||
md_putc( digest, (a >> 24) & 0xff );
|
if( sig->version >= 4 )
|
||||||
md_putc( digest, (a >> 16) & 0xff );
|
md_putc( digest, sig->version );
|
||||||
md_putc( digest, (a >> 8) & 0xff );
|
md_putc( digest, sig->sig_class );
|
||||||
md_putc( digest, a & 0xff );
|
if( sig->version < 4 ) {
|
||||||
}
|
u32 a = sig->timestamp;
|
||||||
md_final( digest );
|
md_putc( digest, (a >> 24) & 0xff );
|
||||||
result = encode_md_value( digest, sig->digest_algo,
|
md_putc( digest, (a >> 16) & 0xff );
|
||||||
mpi_get_nbits(pkc->pkey[0]));
|
md_putc( digest, (a >> 8) & 0xff );
|
||||||
if( DBG_CIPHER )
|
md_putc( digest, a & 0xff );
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else {
|
else {
|
||||||
/*log_debug("signature_check: unsupported pubkey algo %d\n",
|
byte buf[6];
|
||||||
pkc->pubkey_algo );*/
|
size_t n;
|
||||||
rc = G10ERR_PUBKEY_ALGO;
|
md_putc( digest, sig->pubkey_algo );
|
||||||
goto leave;
|
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 = encode_md_value( pkc->pubkey_algo, digest, sig->digest_algo,
|
||||||
leave:
|
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 );
|
mpi_free( result );
|
||||||
|
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
g10/sign.c
10
g10/sign.c
@ -53,14 +53,8 @@ do_sign( PKT_secret_cert *skc, PKT_signature *sig,
|
|||||||
sig->digest_algo = digest_algo;
|
sig->digest_algo = digest_algo;
|
||||||
sig->digest_start[0] = dp[0];
|
sig->digest_start[0] = dp[0];
|
||||||
sig->digest_start[1] = dp[1];
|
sig->digest_start[1] = dp[1];
|
||||||
if( skc->pubkey_algo == PUBKEY_ALGO_DSA ) {
|
frame = encode_md_value( skc->pubkey_algo, md,
|
||||||
frame = mpi_alloc( (md_digest_length(digest_algo)+BYTES_PER_MPI_LIMB-1)
|
digest_algo, mpi_get_nbits(skc->skey[0]));
|
||||||
/ 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]));
|
|
||||||
rc = pubkey_sign( skc->pubkey_algo, sig->data, frame, skc->skey );
|
rc = pubkey_sign( skc->pubkey_algo, sig->data, frame, skc->skey );
|
||||||
mpi_free(frame);
|
mpi_free(frame);
|
||||||
if( rc )
|
if( rc )
|
||||||
|
@ -29,11 +29,6 @@
|
|||||||
|
|
||||||
#include "mpi.h"
|
#include "mpi.h"
|
||||||
#include "../cipher/md.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"
|
#include "../cipher/random.h"
|
||||||
|
|
||||||
|
|
||||||
@ -57,9 +52,7 @@
|
|||||||
#define DIGEST_ALGO_MD5 1
|
#define DIGEST_ALGO_MD5 1
|
||||||
#define DIGEST_ALGO_SHA1 2
|
#define DIGEST_ALGO_SHA1 2
|
||||||
#define DIGEST_ALGO_RMD160 3
|
#define DIGEST_ALGO_RMD160 3
|
||||||
#ifdef WITH_TIGER_HASH
|
|
||||||
#define DIGEST_ALGO_TIGER 6
|
#define DIGEST_ALGO_TIGER 6
|
||||||
#endif
|
|
||||||
|
|
||||||
#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
|
#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \
|
||||||
|| (a)==PUBKEY_ALGO_RSA_S )
|
|| (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_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey );
|
||||||
int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
|
int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );
|
||||||
int pubkey_sign( int algo, MPI *resarr, MPI hash, 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 --*/
|
/*-- smallprime.c --*/
|
||||||
extern ushort small_prime_numbers[];
|
extern ushort small_prime_numbers[];
|
||||||
|
@ -79,6 +79,10 @@ unsigned g10m_get_size( MPI a );
|
|||||||
******* miscellaneous functions *******
|
******* 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 );
|
MPI g10c_generate_secret_prime( unsigned nbits );
|
||||||
unsigned char g10c_get_random_byte( int level );
|
unsigned char g10c_get_random_byte( int level );
|
||||||
|
|
||||||
|
@ -55,6 +55,7 @@ typedef struct mpi_struct {
|
|||||||
#define MPI_NULL NULL
|
#define MPI_NULL NULL
|
||||||
|
|
||||||
#define mpi_get_nlimbs(a) ((a)->nlimbs)
|
#define mpi_get_nlimbs(a) ((a)->nlimbs)
|
||||||
|
#define mpi_get_nbit_info(a) ((a)->nbits)
|
||||||
#define mpi_is_neg(a) ((a)->sign)
|
#define mpi_is_neg(a) ((a)->sign)
|
||||||
|
|
||||||
/*-- mpiutil.c --*/
|
/*-- mpiutil.c --*/
|
||||||
|
@ -25,6 +25,9 @@
|
|||||||
#define _g10lib_INTERNAL 1
|
#define _g10lib_INTERNAL 1
|
||||||
#include "g10lib.h"
|
#include "g10lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char *g10m_revision_string(int dummy) { return "$Revision$"; }
|
||||||
|
|
||||||
MPI
|
MPI
|
||||||
g10m_new( unsigned nbits )
|
g10m_new( unsigned nbits )
|
||||||
{
|
{
|
||||||
|
@ -252,6 +252,7 @@ mpi_copy( MPI a )
|
|||||||
b->nlimbs = a->nlimbs;
|
b->nlimbs = a->nlimbs;
|
||||||
b->sign = a->sign;
|
b->sign = a->sign;
|
||||||
b->secure = a->secure;
|
b->secure = a->secure;
|
||||||
|
b->nbits = a->nbits;
|
||||||
for(i=0; i < b->nlimbs; i++ )
|
for(i=0; i < b->nlimbs; i++ )
|
||||||
b->d[i] = a->d[i];
|
b->d[i] = a->d[i];
|
||||||
}
|
}
|
||||||
@ -273,6 +274,7 @@ mpi_set( MPI w, MPI u)
|
|||||||
up = u->d;
|
up = u->d;
|
||||||
MPN_COPY( wp, up, usize );
|
MPN_COPY( wp, up, usize );
|
||||||
w->nlimbs = usize;
|
w->nlimbs = usize;
|
||||||
|
w->nbits = u->nbits;
|
||||||
w->sign = usign;
|
w->sign = usign;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -284,6 +286,7 @@ mpi_set_ui( MPI w, unsigned long u)
|
|||||||
w->d[0] = u;
|
w->d[0] = u;
|
||||||
w->nlimbs = u? 1:0;
|
w->nlimbs = u? 1:0;
|
||||||
w->sign = 0;
|
w->sign = 0;
|
||||||
|
w->nbits = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -25,6 +25,10 @@
|
|||||||
#define _g10lib_INTERNAL 1
|
#define _g10lib_INTERNAL 1
|
||||||
#include "g10lib.h"
|
#include "g10lib.h"
|
||||||
|
|
||||||
|
|
||||||
|
const char *g10u_revision_string(int dummy) { return "$Revision$"; }
|
||||||
|
|
||||||
|
|
||||||
void *g10_malloc( size_t n ) { return m_alloc( n ); }
|
void *g10_malloc( size_t n ) { return m_alloc( n ); }
|
||||||
void *g10_calloc( size_t n ) { return m_alloc_clear( n ); }
|
void *g10_calloc( size_t n ) { return m_alloc_clear( n ); }
|
||||||
void *g10_malloc_secure( size_t n ) { return m_alloc_secure( n ); }
|
void *g10_malloc_secure( size_t n ) { return m_alloc_secure( n ); }
|
||||||
|
@ -127,7 +127,7 @@ add_entry( byte *p, unsigned n, int mode, const char *info, const char *by )
|
|||||||
index = memtbl_len++;
|
index = memtbl_len++;
|
||||||
else {
|
else {
|
||||||
struct memtbl_entry *e;
|
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
|
* so that freed entries remain as long as possible in the table
|
||||||
* (free appends a new one)
|
* (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",
|
log_fatal("out of %s memory while allocating %u bytes\n",
|
||||||
secure? "secure":"" ,(unsigned)n );
|
secure? "secure":"" ,(unsigned)n );
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************
|
/****************
|
||||||
|
@ -91,7 +91,7 @@ POSUB = po
|
|||||||
RANLIB = ranlib
|
RANLIB = ranlib
|
||||||
USE_INCLUDED_LIBINTL = yes
|
USE_INCLUDED_LIBINTL = yes
|
||||||
USE_NLS = yes
|
USE_NLS = yes
|
||||||
VERSION = 0.2.19a
|
VERSION = 0.2.19b
|
||||||
ZLIBS =
|
ZLIBS =
|
||||||
l =
|
l =
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user