aboutsummaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
Diffstat (limited to 'g10')
-rw-r--r--g10/Makefile.am4
-rw-r--r--g10/Makefile.in21
-rw-r--r--g10/build-packet.c38
-rw-r--r--g10/compress.c7
-rw-r--r--g10/encode.c59
-rw-r--r--g10/filter.h1
-rw-r--r--g10/free-packet.c15
-rw-r--r--g10/g10.c47
-rw-r--r--g10/getkey.c150
-rw-r--r--g10/keydb.h1
-rw-r--r--g10/keygen.c15
-rw-r--r--g10/main.h7
-rw-r--r--g10/mainproc.c35
-rw-r--r--g10/mdfilter.c15
-rw-r--r--g10/openfile.c (renamed from g10/overwrite.c)42
-rw-r--r--g10/packet.h10
-rw-r--r--g10/parse-packet.c10
-rw-r--r--g10/passphrase.c12
-rw-r--r--g10/plaintext.c16
-rw-r--r--g10/pubkey-enc.c3
-rw-r--r--g10/seckey-cert.c38
-rw-r--r--g10/seskey.c41
-rw-r--r--g10/sig-check.c64
23 files changed, 415 insertions, 236 deletions
diff --git a/g10/Makefile.am b/g10/Makefile.am
index 22a38898c..a8d13eaec 100644
--- a/g10/Makefile.am
+++ b/g10/Makefile.am
@@ -20,7 +20,7 @@ g10_SOURCES = g10.c \
mdfilter.c \
cipher.c \
options.h \
- overwrite.c \
+ openfile.c \
packet.h \
parse-packet.c \
passphrase.c \
@@ -28,6 +28,8 @@ g10_SOURCES = g10.c \
pubkey-enc.c \
seckey-cert.c \
seskey.c \
+ sign.c \
+ comment.c \
sig-check.c
diff --git a/g10/Makefile.in b/g10/Makefile.in
index ed387218a..d7b08551d 100644
--- a/g10/Makefile.in
+++ b/g10/Makefile.in
@@ -58,7 +58,7 @@ g10_SOURCES = g10.c \
mdfilter.c \
cipher.c \
options.h \
- overwrite.c \
+ openfile.c \
packet.h \
parse-packet.c \
passphrase.c \
@@ -66,6 +66,8 @@ g10_SOURCES = g10.c \
pubkey-enc.c \
seckey-cert.c \
seskey.c \
+ sign.c \
+ comment.c \
sig-check.c
LDADD = -L ../cipher -L ../mpi -L ../util -lcipher -lmpi -lutil -lz
@@ -88,8 +90,8 @@ COMPILE = $(CC) -c $(DEFS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS)
LINK = $(CC) $(LDFLAGS) -o $@
g10_OBJECTS = g10.o build-packet.o compress.o encode.o encr-data.o \
free-packet.o getkey.o keygen.o mainproc.o armor.o mdfilter.o cipher.o \
-overwrite.o parse-packet.o passphrase.o plaintext.o pubkey-enc.o \
-seckey-cert.o seskey.o sig-check.o
+openfile.o parse-packet.o passphrase.o plaintext.o pubkey-enc.o \
+seckey-cert.o seskey.o sign.o comment.o sig-check.o
EXTRA_g10_SOURCES =
g10_LDADD = $(LDADD)
DIST_COMMON = Makefile.am Makefile.in
@@ -105,15 +107,16 @@ DEP_DISTFILES = $(DIST_COMMON) $(SOURCES) $(BUILT_SOURCES) $(HEADERS) \
TAR = tar
DEP_FILES = $(srcdir)/.deps/armor.P $(srcdir)/.deps/build-packet.P \
-$(srcdir)/.deps/cipher.P $(srcdir)/.deps/compress.P \
-$(srcdir)/.deps/encode.P $(srcdir)/.deps/encr-data.P \
-$(srcdir)/.deps/free-packet.P $(srcdir)/.deps/g10.P \
-$(srcdir)/.deps/getkey.P $(srcdir)/.deps/keygen.P \
+$(srcdir)/.deps/cipher.P $(srcdir)/.deps/comment.P \
+$(srcdir)/.deps/compress.P $(srcdir)/.deps/encode.P \
+$(srcdir)/.deps/encr-data.P $(srcdir)/.deps/free-packet.P \
+$(srcdir)/.deps/g10.P $(srcdir)/.deps/getkey.P $(srcdir)/.deps/keygen.P \
$(srcdir)/.deps/mainproc.P $(srcdir)/.deps/mdfilter.P \
-$(srcdir)/.deps/overwrite.P $(srcdir)/.deps/parse-packet.P \
+$(srcdir)/.deps/openfile.P $(srcdir)/.deps/parse-packet.P \
$(srcdir)/.deps/passphrase.P $(srcdir)/.deps/plaintext.P \
$(srcdir)/.deps/pubkey-enc.P $(srcdir)/.deps/seckey-cert.P \
-$(srcdir)/.deps/seskey.P $(srcdir)/.deps/sig-check.P
+$(srcdir)/.deps/seskey.P $(srcdir)/.deps/sig-check.P \
+$(srcdir)/.deps/sign.P
SOURCES = $(g10_SOURCES)
OBJECTS = $(g10_OBJECTS)
diff --git a/g10/build-packet.c b/g10/build-packet.c
index 945758e98..5bda607b9 100644
--- a/g10/build-packet.c
+++ b/g10/build-packet.c
@@ -43,6 +43,7 @@ static u32 calc_plaintext( PKT_plaintext *pt );
static int do_plaintext( IOBUF out, int ctb, PKT_plaintext *pt );
static int do_encr_data( IOBUF out, int ctb, PKT_encr_data *ed );
static int do_compressed( IOBUF out, int ctb, PKT_compressed *cd );
+static int do_signature( IOBUF out, int ctb, PKT_signature *sig );
static int calc_header_length( u32 len );
static int write_16(IOBUF inp, u16 a);
@@ -92,6 +93,8 @@ build_packet( IOBUF out, PACKET *pkt )
rc = do_compressed( out, ctb, pkt->pkt.compressed );
break;
case PKT_SIGNATURE:
+ rc = do_signature( out, ctb, pkt->pkt.signature );
+ break;
case PKT_RING_TRUST:
default:
log_bug("invalid packet type in build_packet()");
@@ -255,6 +258,9 @@ do_pubkey_enc( IOBUF out, int ctb, PKT_pubkey_enc *enc )
}
+
+
+
static u32
calc_plaintext( PKT_plaintext *pt )
{
@@ -323,6 +329,38 @@ do_compressed( IOBUF out, int ctb, PKT_compressed *cd )
}
+static int
+do_signature( IOBUF out, int ctb, PKT_signature *sig )
+{
+ int rc = 0;
+ IOBUF a = iobuf_temp();
+
+ write_version( a, ctb );
+ iobuf_put(a, 5 ); /* constant */
+ iobuf_put(a, sig->sig_class );
+ write_32(a, sig->timestamp );
+ write_32(a, sig->keyid[0] );
+ write_32(a, sig->keyid[1] );
+ iobuf_put(a, sig->pubkey_algo );
+ if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
+ iobuf_put(a, sig->d.rsa.digest_algo );
+ iobuf_put(a, sig->d.rsa.digest_start[0] );
+ iobuf_put(a, sig->d.rsa.digest_start[1] );
+ mpi_encode(a, sig->d.rsa.rsa_integer );
+ }
+ else {
+ rc = G10ERR_PUBKEY_ALGO;
+ goto leave;
+ }
+
+ write_header(out, ctb, iobuf_get_temp_length(a) );
+ if( iobuf_write_temp( out, a ) )
+ rc = G10ERR_WRITE_FILE;
+
+ leave:
+ iobuf_close(a);
+ return rc;
+}
static int
diff --git a/g10/compress.c b/g10/compress.c
index a4fc48f88..980f5f976 100644
--- a/g10/compress.c
+++ b/g10/compress.c
@@ -124,6 +124,7 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
IOBUF a, size_t *ret_len )
{
int zrc;
+ int rc=0;
size_t n;
byte *p;
int c;
@@ -147,7 +148,9 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
if( DBG_FILTER )
log_debug("inflate returned: avail_in=%u, avail_out=%u, zrc=%d\n",
(unsigned)zs->avail_in, (unsigned)zs->avail_out, zrc);
- if( zrc != Z_OK && zrc != Z_STREAM_END ) {
+ if( zrc == Z_STREAM_END )
+ rc = -1; /* eof */
+ else if( zrc != Z_OK ) {
if( zs->msg )
log_fatal("zlib inflate problem: %s\n", zs->msg );
else
@@ -157,7 +160,7 @@ do_uncompress( compress_filter_context_t *zfx, z_stream *zs,
*ret_len = zfx->outbufsize - zs->avail_out;
if( DBG_FILTER )
log_debug("do_uncompress: returning %u bytes\n", (unsigned)*ret_len );
- return 0;
+ return rc;
}
diff --git a/g10/encode.c b/g10/encode.c
index 272462d47..9ef2c1099 100644
--- a/g10/encode.c
+++ b/g10/encode.c
@@ -1,4 +1,4 @@
-/* encode.c - encode/sign data
+/* encode.c - encode data
* Copyright (c) 1997 by Werner Koch (dd9jn)
*
* This file is part of G10.
@@ -39,7 +39,6 @@
static int encode_simple( const char *filename, int mode );
-static IOBUF open_outfile( const char *iname );
/****************
@@ -62,22 +61,6 @@ encode_store( const char *filename )
return encode_simple( filename, 0 );
}
-static void
-write_comment( IOBUF out, const char *s )
-{
- PACKET pkt;
- size_t n = strlen(s);
- int rc;
-
- pkt.pkttype = PKT_COMMENT;
- pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n - 1 );
- pkt.pkt.comment->len = n;
- strcpy(pkt.pkt.comment->data, s);
- if( (rc = build_packet( out, &pkt )) )
- log_error("build_packet(comment) failed: %s\n", g10_errstr(rc) );
- free_packet( &pkt );
-}
-
static int
encode_simple( const char *filename, int mode )
@@ -335,44 +318,4 @@ encode_crypt( const char *filename, STRLIST remusr )
}
-/****************
- * Make an output filename for the inputfile INAME.
- * Returns an
- */
-static IOBUF
-open_outfile( const char *iname )
-{
- IOBUF a = NULL;
- int rc;
-
- if( (!iname && !opt.outfile) || opt.outfile_is_stdout ) {
- if( !(a = iobuf_create(NULL)) )
- log_error("can't open [stdout]: %s\n", strerror(errno) );
- else if( opt.verbose )
- log_info("writing to stdout\n");
- }
- else {
- char *buf=NULL;
- const char *name;
-
- if( opt.outfile )
- name = opt.outfile;
- else {
- buf = m_alloc(strlen(iname)+4+1);
- strcpy(stpcpy(buf,iname), ".g10");
- name = buf;
- }
- if( !(rc=overwrite_filep( name )) ) {
- if( !(a = iobuf_create( name )) )
- log_error("can't create %s: %s\n", name, strerror(errno) );
- else if( opt.verbose )
- log_info("writing to '%s'\n", name );
- }
- else if( rc != -1 )
- log_error("oops: overwrite_filep(%s): %s\n", name, g10_errstr(rc) );
- m_free(buf);
- }
- return a;
-}
-
diff --git a/g10/filter.h b/g10/filter.h
index 3ca222186..acbb4ca25 100644
--- a/g10/filter.h
+++ b/g10/filter.h
@@ -61,6 +61,7 @@ typedef struct {
/*-- mdfilter.c --*/
int md_filter( void *opaque, int control, IOBUF a, byte *buf, size_t *ret_len);
+void free_md_filter_context( md_filter_context_t *mfx );
/*-- armor.c --*/
int armor_filter( void *opaque, int control,
diff --git a/g10/free-packet.c b/g10/free-packet.c
index f4f38baa4..7d6eb4aaa 100644
--- a/g10/free-packet.c
+++ b/g10/free-packet.c
@@ -89,6 +89,21 @@ free_seckey_cert( PKT_seckey_cert *cert )
m_free(cert);
}
+PKT_seckey_cert *
+copy_seckey_cert( PKT_seckey_cert *d, PKT_seckey_cert *s )
+{
+ if( !d )
+ d = m_alloc(sizeof *d);
+ memcpy( d, s, sizeof *d );
+ d->d.rsa.rsa_n = mpi_copy( s->d.rsa.rsa_n );
+ d->d.rsa.rsa_e = mpi_copy( s->d.rsa.rsa_e );
+ d->d.rsa.rsa_d = mpi_copy( s->d.rsa.rsa_d );
+ d->d.rsa.rsa_p = mpi_copy( s->d.rsa.rsa_p );
+ d->d.rsa.rsa_q = mpi_copy( s->d.rsa.rsa_q );
+ d->d.rsa.rsa_u = mpi_copy( s->d.rsa.rsa_u );
+ return d;
+}
+
void
free_comment( PKT_comment *rem )
{
diff --git a/g10/g10.c b/g10/g10.c
index 89f0c84a3..496fda348 100644
--- a/g10/g10.c
+++ b/g10/g10.c
@@ -77,6 +77,8 @@ set_debug(void)
mpi_debug_mode = 1;
if( opt.debug & DBG_CIPHER_VALUE )
cipher_debug_mode = 1;
+ if( opt.debug & DBG_IOBUF_VALUE )
+ iobuf_debug_mode = 1;
}
@@ -116,10 +118,10 @@ main( int argc, char **argv )
ARGPARSE_ARGS pargs = { &argc, &argv, 0 };
IOBUF a;
int rc;
- enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen,
+ enum { aNull, aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
} action = aNull;
const char *fname, *fname_print;
- STRLIST sl, remusr= NULL;
+ STRLIST sl, remusr= NULL, locusr=NULL;
int nrings=0;
armor_filter_context_t afx;
@@ -131,13 +133,26 @@ main( int argc, char **argv )
opt.compress = pargs.r.ret_int;
break;
case 'a': opt.armor = 1; break;
+ case 'b': opt.batch = 1; break;
case 'c': action = aSym; break;
- case 'e': action = aEncr; break;
case 'o': opt.outfile = pargs.r.ret_str;
if( opt.outfile[0] == '-' && !opt.outfile[1] )
opt.outfile_is_stdout = 1;
break;
- case 'b': opt.batch = 1; break;
+ case 'e': action = action == aSign? aSignEncr : aEncr; break;
+ case 's': action = action == aEncr? aSignEncr : aSign; break;
+ case 'l': /* store the local users */
+ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
+ strcpy(sl->d, pargs.r.ret_str);
+ sl->next = locusr;
+ locusr = sl;
+ break;
+ case 'r': /* store the remote users */
+ sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
+ strcpy(sl->d, pargs.r.ret_str);
+ sl->next = remusr;
+ remusr = sl;
+ break;
case 501: opt.answer_yes = 1; break;
case 502: opt.answer_no = 1; break;
case 507: action = aStore; break;
@@ -146,12 +161,6 @@ main( int argc, char **argv )
case 510: opt.debug |= pargs.r.ret_ulong; break;
case 511: opt.debug = ~0; break;
case 512: opt.cache_all = 1; break;
- case 'r': /* store the remote users */
- sl = m_alloc( sizeof *sl + strlen(pargs.r.ret_str));
- strcpy(sl->d, pargs.r.ret_str);
- sl->next = remusr;
- remusr = sl;
- break;
case 513: action = aPrimegen; break;
case 514: action = aKeygen; break;
default : pargs.err = 2; break;
@@ -187,16 +196,25 @@ main( int argc, char **argv )
if( argc > 1 )
usage(1);
if( (rc = encode_symmetric(fname)) )
- log_error("encode_symmetric('%s'): %s\n",
- fname_print, g10_errstr(rc) );
+ log_error("encode_symmetric('%s'): %s\n", fname_print, g10_errstr(rc) );
break;
case aEncr: /* encrypt the given file */
if( argc > 1 )
usage(1);
if( (rc = encode_crypt(fname,remusr)) )
- log_error("encode_crypt('%s'): %s\n",
- fname_print, g10_errstr(rc) );
+ log_error("encode_crypt('%s'): %s\n", fname_print, g10_errstr(rc) );
+ break;
+
+ case aSign: /* sign the given file */
+ if( argc > 1 )
+ usage(1);
+ if( (rc = sign_file(fname, 0, locusr)) )
+ log_error("sign_file('%s'): %s\n", fname_print, g10_errstr(rc) );
+ break;
+
+ case aSignEncr: /* sign and encrypt the given file */
+ usage(1); /* FIXME */
break;
case aPrimegen:
@@ -227,6 +245,7 @@ main( int argc, char **argv )
/* cleanup */
FREE_STRLIST(remusr);
+ FREE_STRLIST(locusr);
return 0;
}
diff --git a/g10/getkey.c b/g10/getkey.c
index 0e3c3b2f3..8ca462210 100644
--- a/g10/getkey.c
+++ b/g10/getkey.c
@@ -61,7 +61,8 @@ static int pkc_cache_entries; /* number of entries in pkc cache */
static int scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
const char *name, const char *filename );
-static int scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename);
+static int scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid,
+ const char *name, const char *filename);
void
@@ -254,10 +255,10 @@ int
get_seckey( RSA_secret_key *skey, u32 *keyid )
{
int rc=0;
- PACKET pkt;
+ PKT_seckey_cert skc;
- init_packet( &pkt );
- if( !(rc=scan_secret_keyring( &pkt, keyid, "../keys/secring.g10" ) ) )
+ memset( &skc, 0, sizeof skc );
+ if( !(rc=scan_secret_keyring( &skc, keyid, NULL, "../keys/secring.g10" ) ) )
goto found;
/* fixme: look at other places */
goto leave;
@@ -266,30 +267,46 @@ get_seckey( RSA_secret_key *skey, u32 *keyid )
/* get the secret key (this may prompt for a passprase to
* unlock the secret key
*/
- if( (rc = check_secret_key( pkt.pkt.seckey_cert )) )
+ if( (rc = check_secret_key( &skc )) )
goto leave;
- if( pkt.pkt.seckey_cert->pubkey_algo != PUBKEY_ALGO_RSA ) {
+ if( skc.pubkey_algo != PUBKEY_ALGO_RSA ) {
rc = G10ERR_PUBKEY_ALGO; /* unsupport algorithm */
goto leave;
}
/* copy the stuff to SKEY. skey is then the owner */
- skey->e = pkt.pkt.seckey_cert->d.rsa.rsa_e;
- skey->n = pkt.pkt.seckey_cert->d.rsa.rsa_n;
- skey->p = pkt.pkt.seckey_cert->d.rsa.rsa_p;
- skey->q = pkt.pkt.seckey_cert->d.rsa.rsa_q;
- skey->d = pkt.pkt.seckey_cert->d.rsa.rsa_d;
- skey->u = pkt.pkt.seckey_cert->d.rsa.rsa_u;
- /* set all these to NULL, so that free_packet will not destroy
- * these integers. */
- pkt.pkt.seckey_cert->d.rsa.rsa_e = NULL;
- pkt.pkt.seckey_cert->d.rsa.rsa_n = NULL;
- pkt.pkt.seckey_cert->d.rsa.rsa_p = NULL;
- pkt.pkt.seckey_cert->d.rsa.rsa_q = NULL;
- pkt.pkt.seckey_cert->d.rsa.rsa_d = NULL;
- pkt.pkt.seckey_cert->d.rsa.rsa_u = NULL;
+ skey->e = skc.d.rsa.rsa_e;
+ skey->n = skc.d.rsa.rsa_n;
+ skey->p = skc.d.rsa.rsa_p;
+ skey->q = skc.d.rsa.rsa_q;
+ skey->d = skc.d.rsa.rsa_d;
+ skey->u = skc.d.rsa.rsa_u;
+
+ leave:
+ memset( &skc, 0, sizeof skc );
+ return rc;
+}
+
+/****************
+ * Get a secret key by name and store it into skc
+ */
+int
+get_seckey_by_name( PKT_seckey_cert *skc, const char *name )
+{
+ int rc=0;
+
+ if( !(rc=scan_secret_keyring( skc, NULL, name, "../keys/secring.g10" ) ) )
+ goto found;
+ /* fixme: look at other places */
+ goto leave;
+
+ found:
+ /* get the secret key (this may prompt for a passprase to
+ * unlock the secret key
+ */
+ if( (rc = check_secret_key( skc )) )
+ goto leave;
leave:
- free_packet(&pkt);
return rc;
}
@@ -416,11 +433,18 @@ scan_keyring( PKT_pubkey_cert *pkc, u32 *keyid,
* PKT returns the secret key certificate.
*/
static int
-scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename )
+scan_secret_keyring( PKT_seckey_cert *skc, u32 *keyid,
+ const char *name, const char *filename )
{
+ int rc=0;
+ int found = 0;
IOBUF a;
- int save_mode, rc;
+ PACKET pkt;
+ int save_mode;
u32 akeyid[2];
+ PKT_seckey_cert *last_pk = NULL;
+
+ assert( !keyid || !name );
if( !(a = iobuf_open( filename ) ) ) {
log_debug("scan_secret_keyring: can't open '%s'\n", filename );
@@ -428,28 +452,84 @@ scan_secret_keyring( PACKET *pkt, u32 *keyid, const char *filename )
}
save_mode = set_packet_list_mode(0);
- init_packet(pkt);
- while( (rc=parse_packet(a, pkt)) != -1 ) {
+ init_packet(&pkt);
+ while( (rc=parse_packet(a, &pkt)) != -1 ) {
if( rc )
- ;
- else if( pkt->pkttype == PKT_SECKEY_CERT ) {
- mpi_get_keyid( pkt->pkt.seckey_cert->d.rsa.rsa_n , akeyid );
- if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
- iobuf_close(a);
- set_packet_list_mode(save_mode);
- return 0; /* got it */
+ ; /* e.g. unknown packet */
+ else if( keyid && found && pkt.pkttype == PKT_SECKEY_CERT ) {
+ log_error("Hmmm, seckey without an user id in '%s'\n", filename);
+ goto leave;
+ }
+ else if( keyid && pkt.pkttype == PKT_SECKEY_CERT ) {
+ switch( pkt.pkt.seckey_cert->pubkey_algo ) {
+ case PUBKEY_ALGO_RSA:
+ mpi_get_keyid( pkt.pkt.seckey_cert->d.rsa.rsa_n , akeyid );
+ if( akeyid[0] == keyid[0] && akeyid[1] == keyid[1] ) {
+ copy_seckey_cert( skc, pkt.pkt.seckey_cert );
+ found++;
+ }
+ break;
+ default:
+ log_error("cannot handle pubkey algo %d\n",
+ pkt.pkt.seckey_cert->pubkey_algo);
+ }
+ }
+ else if( keyid && found && pkt.pkttype == PKT_USER_ID ) {
+ goto leave;
+ }
+ else if( name && pkt.pkttype == PKT_SECKEY_CERT ) {
+ if( last_pk )
+ free_seckey_cert(last_pk);
+ last_pk = pkt.pkt.seckey_cert;
+ pkt.pkt.seckey_cert = NULL;
+ }
+ else if( name && pkt.pkttype == PKT_USER_ID ) {
+ if( memistr( pkt.pkt.user_id->name, pkt.pkt.user_id->len, name )) {
+ if( !last_pk )
+ log_error("Ooops: no seckey for userid '%.*s'\n",
+ pkt.pkt.user_id->len, pkt.pkt.user_id->name);
+ else if( skc->pubkey_algo &&
+ skc->pubkey_algo != last_pk->pubkey_algo )
+ log_info("skipping id '%.*s': want algo %d, found %d\n",
+ pkt.pkt.user_id->len, pkt.pkt.user_id->name,
+ skc->pubkey_algo, last_pk->pubkey_algo );
+ else {
+ copy_seckey_cert( skc, last_pk );
+ goto leave;
+ }
}
}
- free_packet(pkt);
+ else if( !keyid && !name && pkt.pkttype == PKT_SECKEY_CERT ) {
+ if( last_pk )
+ free_seckey_cert(last_pk);
+ last_pk = pkt.pkt.seckey_cert;
+ pkt.pkt.seckey_cert = NULL;
+ }
+ else if( !keyid && !name && pkt.pkttype == PKT_USER_ID ) {
+ if( !last_pk )
+ log_error("Ooops: no seckey for userid '%.*s'\n",
+ pkt.pkt.user_id->len, pkt.pkt.user_id->name);
+ else {
+ if( last_pk->pubkey_algo == PUBKEY_ALGO_RSA ) {
+ mpi_get_keyid( last_pk->d.rsa.rsa_n , akeyid );
+ cache_user_id( pkt.pkt.user_id, akeyid );
+ }
+ }
+ }
+ free_packet(&pkt);
}
+ rc = G10ERR_NO_SECKEY;
+ leave:
+ if( last_pk )
+ free_seckey_cert(last_pk);
+ free_packet(&pkt);
iobuf_close(a);
set_packet_list_mode(save_mode);
- return G10ERR_NO_SECKEY;
+ return rc;
}
-
/****************
* Return a string with a printable representation of the user_id.
* this string must be freed by m_free.
diff --git a/g10/keydb.h b/g10/keydb.h
index 641cd4cbc..62c6abe36 100644
--- a/g10/keydb.h
+++ b/g10/keydb.h
@@ -36,6 +36,7 @@ void cache_user_id( PKT_user_id *uid, u32 *keyid );
int get_pubkey( PKT_pubkey_cert *pkc, u32 *keyid );
int get_pubkey_by_name( PKT_pubkey_cert *pkc, const char *name );
int get_seckey( RSA_secret_key *skey, u32 *keyid );
+int get_seckey_by_name( PKT_seckey_cert *skc, const char *name );
char*get_user_id_string( u32 *keyid );
diff --git a/g10/keygen.c b/g10/keygen.c
index 1f174498c..866824c1c 100644
--- a/g10/keygen.c
+++ b/g10/keygen.c
@@ -44,21 +44,6 @@ answer_is_yes( const char *s )
}
-static void
-write_comment( IOBUF out, const char *s )
-{
- PACKET pkt;
- size_t n = strlen(s);
- int rc;
-
- pkt.pkttype = PKT_COMMENT;
- pkt.pkt.comment = m_alloc( sizeof *pkt.pkt.comment + n - 1 );
- pkt.pkt.comment->len = n;
- strcpy(pkt.pkt.comment->data, s);
- if( (rc = build_packet( out, &pkt )) )
- log_error("build_packet(comment) failed: %s\n", g10_errstr(rc) );
- free_packet( &pkt );
-}
static void
write_uid( IOBUF out, const char *s )
diff --git a/g10/main.h b/g10/main.h
index 398dc40f1..9d0f07a89 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -20,16 +20,21 @@
#ifndef G10_MAIN_H
#define G10_MAIN_H
#include "types.h"
+#include "iobuf.h"
/*-- encode.c --*/
int encode_symmetric( const char *filename );
int encode_store( const char *filename );
int encode_crypt( const char *filename, STRLIST remusr );
+/*-- sign.c --*/
+int sign_file( const char *filename, int detached, STRLIST locusr );
+
/*-- keygen.c --*/
void generate_keypair(void);
-/*-- overwrite.c --*/
+/*-- openfile.c --*/
int overwrite_filep( const char *fname );
+IOBUF open_outfile( const char *fname );
#endif /*G10_MAIN_H*/
diff --git a/g10/mainproc.c b/g10/mainproc.c
index 0055200b4..45cb8fbbd 100644
--- a/g10/mainproc.c
+++ b/g10/mainproc.c
@@ -29,7 +29,7 @@
#include "util.h"
#include "cipher.h"
#include "keydb.h"
-
+#include "filter.h"
static int opt_list=1; /* and list the data packets to stdout */
@@ -48,7 +48,9 @@ proc_packets( IOBUF a )
int lvl0, lvl1;
int last_was_pubkey_enc = 0;
u32 keyid[2];
+ md_filter_context_t mfx;
+ memset( &mfx, 0, sizeof mfx );
lvl0 = opt.check_sigs? 1:0; /* stdout or /dev/null */
lvl1 = opt.check_sigs? 1:3; /* stdout or error */
pkt = m_alloc( sizeof *pkt );
@@ -135,7 +137,14 @@ proc_packets( IOBUF a )
sig = pkt->pkt.signature;
ustr = get_user_id_string(sig->keyid);
result = -1;
- if( sig->sig_class != 0x10 )
+ if( sig->sig_class == 0x00 ) {
+ if( mfx.rmd160 )
+ result = 0;
+ else
+ printstr(lvl1,"sig?: %s: no plaintext for signature\n",
+ ustr);
+ }
+ else if( sig->sig_class != 0x10 )
printstr(lvl1,"sig?: %s: unknown signature class %02x\n",
ustr, sig->sig_class);
else if( !pkt->pkc_parent || !pkt->user_parent )
@@ -145,20 +154,25 @@ proc_packets( IOBUF a )
if( result )
;
- else if( !opt.check_sigs ) {
+ else if( !opt.check_sigs && sig->sig_class != 0x00 ) {
result = -1;
printstr(lvl0, "sig: from %s\n", ustr );
}
else if(sig->pubkey_algo == PUBKEY_ALGO_RSA ) {
md_handle.algo = sig->d.rsa.digest_algo;
if( sig->d.rsa.digest_algo == DIGEST_ALGO_RMD160 ) {
- md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
- rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
- pkt->user_parent->len);
+ if( sig->sig_class == 0x00 )
+ md_handle.u.rmd = rmd160_copy( mfx.rmd160 );
+ else {
+ md_handle.u.rmd = rmd160_copy(pkt->pkc_parent->mfx.rmd160);
+ rmd160_write(md_handle.u.rmd, pkt->user_parent->name,
+ pkt->user_parent->len);
+ }
result = signature_check( sig, md_handle );
rmd160_close(md_handle.u.rmd);
}
- else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5 ) {
+ else if( sig->d.rsa.digest_algo == DIGEST_ALGO_MD5
+ && sig->sig_class != 0x00 ) {
md_handle.u.md5 = md5_copy(pkt->pkc_parent->mfx.md5);
md5_write(md_handle.u.md5, pkt->user_parent->name,
pkt->user_parent->len);
@@ -173,6 +187,8 @@ proc_packets( IOBUF a )
if( result == -1 )
;
+ else if( !result && sig->sig_class == 0x00 )
+ printstr(1, "sig: good signature from %s\n", ustr );
else if( !result )
printstr(lvl0, "sig: good signature from %s\n", ustr );
else
@@ -235,7 +251,9 @@ proc_packets( IOBUF a )
else if( pkt->pkttype == PKT_PLAINTEXT ) {
PKT_plaintext *pt = pkt->pkt.plaintext;
printf("txt: plain text data name='%.*s'\n", pt->namelen, pt->name);
- result = handle_plaintext( pt );
+ free_md_filter_context( &mfx );
+ mfx.rmd160 = rmd160_open(0);
+ result = handle_plaintext( pt, &mfx );
if( !result )
fputs( " okay",stdout);
else
@@ -269,6 +287,7 @@ proc_packets( IOBUF a )
m_free(dek);
free_packet( pkt );
m_free( pkt );
+ free_md_filter_context( &mfx );
return 0;
}
diff --git a/g10/mdfilter.c b/g10/mdfilter.c
index b6cd86110..5a77c9012 100644
--- a/g10/mdfilter.c
+++ b/g10/mdfilter.c
@@ -45,7 +45,7 @@ md_filter( void *opaque, int control,
int i, c, rc=0;
if( control == IOBUFCTRL_UNDERFLOW ) {
- if( size > mfx->maxbuf_size )
+ if( mfx->maxbuf_size && size > mfx->maxbuf_size )
size = mfx->maxbuf_size;
for(i=0; i < size; i++ ) {
if( (c = iobuf_get(a)) == -1 )
@@ -68,3 +68,16 @@ md_filter( void *opaque, int control,
return rc;
}
+
+void
+free_md_filter_context( md_filter_context_t *mfx )
+{
+ if( mfx->md5 )
+ md5_close(mfx->md5);
+ mfx->md5 = NULL;
+ if( mfx->rmd160 )
+ rmd160_close(mfx->rmd160);
+ mfx->rmd160 = NULL;
+ mfx->maxbuf_size = 0;
+}
+
diff --git a/g10/overwrite.c b/g10/openfile.c
index a98dd3be7..1a840f19c 100644
--- a/g10/overwrite.c
+++ b/g10/openfile.c
@@ -1,4 +1,4 @@
-/* overwrite.c
+/* openfile.c
* Copyright (c) 1997 by Werner Koch (dd9jn)
*
* This file is part of G10.
@@ -77,3 +77,43 @@ overwrite_filep( const char *fname )
}
+/****************
+ * Make an output filename for the inputfile INAME.
+ * Returns an IOBUF
+ */
+IOBUF
+open_outfile( const char *iname )
+{
+ IOBUF a = NULL;
+ int rc;
+
+ if( (!iname && !opt.outfile) || opt.outfile_is_stdout ) {
+ if( !(a = iobuf_create(NULL)) )
+ log_error("can't open [stdout]: %s\n", strerror(errno) );
+ else if( opt.verbose )
+ log_info("writing to stdout\n");
+ }
+ else {
+ char *buf=NULL;
+ const char *name;
+
+ if( opt.outfile )
+ name = opt.outfile;
+ else {
+ buf = m_alloc(strlen(iname)+4+1);
+ strcpy(stpcpy(buf,iname), ".g10");
+ name = buf;
+ }
+ if( !(rc=overwrite_filep( name )) ) {
+ if( !(a = iobuf_create( name )) )
+ log_error("can't create %s: %s\n", name, strerror(errno) );
+ else if( opt.verbose )
+ log_info("writing to '%s'\n", name );
+ }
+ else if( rc != -1 )
+ log_error("oops: overwrite_filep(%s): %s\n", name, g10_errstr(rc) );
+ m_free(buf);
+ }
+ return a;
+}
+
diff --git a/g10/packet.h b/g10/packet.h
index 93336bcb4..f57dce172 100644
--- a/g10/packet.h
+++ b/g10/packet.h
@@ -103,9 +103,6 @@ typedef struct {
byte iv[8]; /* initialization vector for CFB mode */
/* when protected, the MPIs above are pointers
* to plain storage */
- } idea;
- struct {
- byte iv[8];
} blowfish;
} protect;
} rsa;
@@ -190,6 +187,7 @@ void free_user_id( PKT_user_id *uid );
void free_comment( PKT_comment *rem );
void free_packet( PACKET *pkt );
PKT_pubkey_cert *copy_pubkey_cert( PKT_pubkey_cert *d, PKT_pubkey_cert *s );
+PKT_seckey_cert *copy_seckey_cert( PKT_seckey_cert *d, PKT_seckey_cert *s );
/*-- sig-check.c --*/
@@ -209,6 +207,10 @@ int decrypt_data( PKT_encr_data *ed, DEK *dek );
int encrypt_data( PKT_encr_data *ed, DEK *dek );
/*-- plaintext.c --*/
-int handle_plaintext( PKT_plaintext *pt );
+int handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx );
+
+/*-- comment.c --*/
+int write_comment( IOBUF out, const char *s );
+
#endif /*G10_PACKET_H*/
diff --git a/g10/parse-packet.c b/g10/parse-packet.c
index 33cfda38f..35fc6d766 100644
--- a/g10/parse-packet.c
+++ b/g10/parse-packet.c
@@ -157,7 +157,6 @@ parse_packet( IOBUF inp, PACKET *pkt )
case PKT_SIGNATURE:
pkt->pkt.signature = m_alloc_clear(sizeof *pkt->pkt.signature );
rc = parse_signature(inp, pkttype, pktlen, pkt->pkt.signature );
- m_check(pkt->pkt.signature);
break;
case PKT_USER_ID:
rc = parse_user_id(inp, pkttype, pktlen, pkt );
@@ -266,14 +265,12 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
log_error("packet(%d) with unknown version %d\n", pkttype, version);
goto leave;
}
- m_check(sig);
md5_len = iobuf_get_noeof(inp); pktlen--;
sig->sig_class = iobuf_get_noeof(inp); pktlen--;
sig->timestamp = read_32(inp); pktlen -= 4;
sig->keyid[0] = read_32(inp); pktlen -= 4;
sig->keyid[1] = read_32(inp); pktlen -= 4;
sig->pubkey_algo = iobuf_get_noeof(inp); pktlen--;
- m_check(sig);
if( list_mode )
printf(":signature packet: keyid %08lX%08lX\n"
"\tversion %d, created %lu, md5len %d, sigclass %02x\n",
@@ -284,11 +281,9 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
log_error("packet(%d) too short\n", pkttype);
goto leave;
}
- m_check(sig);
sig->d.rsa.digest_algo = iobuf_get_noeof(inp); pktlen--;
sig->d.rsa.digest_start[0] = iobuf_get_noeof(inp); pktlen--;
sig->d.rsa.digest_start[1] = iobuf_get_noeof(inp); pktlen--;
- m_check(sig);
n = pktlen;
sig->d.rsa.rsa_integer = mpi_decode(inp, &n ); pktlen -=n;
if( list_mode ) {
@@ -302,7 +297,6 @@ parse_signature( IOBUF inp, int pkttype, unsigned long pktlen,
}
else if( list_mode )
printf("\tunknown algorithm %d\n", sig->pubkey_algo );
- m_check(sig);
leave:
@@ -395,9 +389,7 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen,
printf(" %02x", temp[i] );
putchar('\n');
}
- if( cert->d.rsa.protect_algo == CIPHER_ALGO_IDEA )
- memcpy(cert->d.rsa.protect.idea.iv, temp, 8 );
- else if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
+ if( cert->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH )
memcpy(cert->d.rsa.protect.blowfish.iv, temp, 8 );
}
else
diff --git a/g10/passphrase.c b/g10/passphrase.c
index c95b27bbd..5a45f49bd 100644
--- a/g10/passphrase.c
+++ b/g10/passphrase.c
@@ -100,17 +100,7 @@ hash_passphrase( DEK *dek, char *pw )
int rc = 0;
dek->keylen = 0;
- if( dek->algo == CIPHER_ALGO_IDEA ) {
- MD5HANDLE md5;
-
- md5 = md5_open(1);
- md5_write( md5, pw, strlen(pw) );
- md5_final( md5 );
- dek->keylen = 16;
- memcpy( dek->key, md5_read(md5), dek->keylen );
- md5_close(md5);
- }
- else if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
+ if( dek->algo == CIPHER_ALGO_BLOWFISH ) {
RMDHANDLE rmd;
rmd = rmd160_open(1);
diff --git a/g10/plaintext.c b/g10/plaintext.c
index be8047bd0..d317fd789 100644
--- a/g10/plaintext.c
+++ b/g10/plaintext.c
@@ -28,13 +28,17 @@
#include "options.h"
#include "packet.h"
#include "ttyio.h"
+#include "filter.h"
/****************
- * Handle a plaintext packet
+ * Handle a plaintext packet. If MFX is not NULL, update the MDs
+ * Note: we should use the filter stuff here, but we have to add some
+ * easy mimic to set a read limit, so we calculate only the
+ * bytes from the plaintext.
*/
int
-handle_plaintext( PKT_plaintext *pt )
+handle_plaintext( PKT_plaintext *pt, md_filter_context_t *mfx )
{
char *fname;
FILE *fp = NULL;
@@ -78,6 +82,10 @@ handle_plaintext( PKT_plaintext *pt )
rc = G10ERR_READ_FILE;
goto leave;
}
+ if( mfx->rmd160 )
+ rmd160_putchar(mfx->rmd160, c );
+ if( mfx->md5 )
+ md5_putchar(mfx->md5, c );
if( putc( c, fp ) == EOF ) {
log_error("Error writing to '%s': %s\n", fname, strerror(errno) );
rc = G10ERR_WRITE_FILE;
@@ -87,6 +95,10 @@ handle_plaintext( PKT_plaintext *pt )
}
else {
while( (c = iobuf_get(pt->buf)) != -1 ) {
+ if( mfx->rmd160 )
+ rmd160_putchar(mfx->rmd160, c );
+ if( mfx->md5 )
+ md5_putchar(mfx->md5, c );
if( putc( c, fp ) == EOF ) {
log_error("Error writing to '%s': %s\n",
fname, strerror(errno) );
diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c
index 18c737c2d..93bdff9da 100644
--- a/g10/pubkey-enc.c
+++ b/g10/pubkey-enc.c
@@ -68,9 +68,8 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek )
* 0 2 RND(n bytes) 0 A DEK(k bytes) CSUM(2 bytes)
*
* RND are non-zero randow bytes.
- * A is the cipher algorithm ( 1 for IDEA, 42 for blowfish )
+ * A is the cipher algorithm
* DEK is the encryption key (session key) with length k
- * (16 for idea, 42 for blowfish)
* CSUM
*/
if( DBG_CIPHER )
diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c
index 3cae571ab..c103de5c7 100644
--- a/g10/seckey-cert.c
+++ b/g10/seckey-cert.c
@@ -50,7 +50,6 @@ checksum( byte *p )
int
check_secret_key( PKT_seckey_cert *cert )
{
- IDEA_context idea_ctx; /* FIXME: allocate this in secure space ! */
byte iv[8];
byte *mpibuf;
u16 n;
@@ -58,7 +57,7 @@ check_secret_key( PKT_seckey_cert *cert )
int res;
u32 keyid[2];
-#if IDEA_BLOCKSIZE != 8 || BLOWFISH_BLOCKSIZE != 8
+#if BLOWFISH_BLOCKSIZE != 8
#error unsupportted blocksize
#endif
@@ -73,37 +72,23 @@ check_secret_key( PKT_seckey_cert *cert )
case CIPHER_ALGO_NONE:
log_bug("unprotect seckey_cert is flagged protected\n");
break;
- case CIPHER_ALGO_IDEA:
case CIPHER_ALGO_BLOWFISH:
mpi_get_keyid( cert->d.rsa.rsa_n , keyid );
dek = get_passphrase_hash( keyid, NULL );
- /* idea_setkey( &idea_ctx, dpw );*/
m_free(dek); /* pw is in secure memory, so m_free() burns it */
memset( iv, 0, BLOWFISH_BLOCKSIZE );
- if( cert->d.rsa.protect_algo == CIPHER_ALGO_IDEA ) {
- idea_setiv( &idea_ctx, iv );
- /* fixme: is it save to leave the IV unencrypted in the
- * certificate or should we move it to secure storage? */
- idea_decode_cfb( &idea_ctx, cert->d.rsa.protect.idea.iv,
- cert->d.rsa.protect.idea.iv, 8 );
- }
- else {
- blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
- blowfish_setiv( blowfish_ctx, iv );
- blowfish_decode_cfb( blowfish_ctx,
- cert->d.rsa.protect.blowfish.iv,
- cert->d.rsa.protect.blowfish.iv, 8 );
- }
+ blowfish_ctx = m_alloc_secure( sizeof *blowfish_ctx );
+ blowfish_setiv( blowfish_ctx, iv );
+ blowfish_decode_cfb( blowfish_ctx,
+ cert->d.rsa.protect.blowfish.iv,
+ cert->d.rsa.protect.blowfish.iv, 8 );
cert->d.rsa.calc_csum = 0;
#define X(a) do { \
mpibuf = (byte*)cert->d.rsa.rsa_##a; \
n = ((mpibuf[0] << 8) | mpibuf[1])-2; \
- if( blowfish_ctx ) \
- blowfish_decode_cfb( blowfish_ctx, \
- mpibuf+4, mpibuf+4, n ); \
- else \
- idea_decode_cfb( &idea_ctx, mpibuf+4, mpibuf+4, n );\
+ blowfish_decode_cfb( blowfish_ctx, \
+ mpibuf+4, mpibuf+4, n ); \
cert->d.rsa.calc_csum += checksum( mpibuf ); \
cert->d.rsa.rsa_##a = mpi_decode_buffer( mpibuf ); \
m_free( mpibuf ); \
@@ -120,12 +105,7 @@ check_secret_key( PKT_seckey_cert *cert )
mpi_print(stdout, cert->d.rsa.rsa_##a, 1 ); \
putchar('\n'); \
} while(0)
- X(n);
- X(e);
- X(d);
- X(p);
- X(q);
- X(u);
+ X(n); X(e); X(d); X(p); X(q); X(u);
#undef X
#endif
/* now let's see wether we have used the right passphrase */
diff --git a/g10/seskey.c b/g10/seskey.c
index d81697296..317623ec8 100644
--- a/g10/seskey.c
+++ b/g10/seskey.c
@@ -1,4 +1,4 @@
-/* seskey.c - make sesssion keys
+/* seskey.c - make sesssion keys etc.
* Copyright (c) 1997 by Werner Koch (dd9jn)
*
* This file is part of G10.
@@ -99,3 +99,42 @@ encode_session_key( DEK *dek, unsigned nbits )
return frame;
}
+/****************
+ * Encode a ripemd160 message digest of LEN bytes into NBITS.
+ * returns: A mpi with the session key (caller must free)
+ */
+MPI
+encode_rmd160_value( byte *md, unsigned len, unsigned nbits )
+{
+ static byte asn[18] = /* stored reverse FIXME: need other values*/
+ { 0x30, 0x20, 0x30, 0x0c, 0x06, 0x08, 0x2a, 0x86,0x48,
+ 0x86, 0xf7, 0x0d, 0x02, 0x05, 0x05, 0x00, 0x04, 0x10 };
+ int nframe = (nbits+7) / 8;
+ byte *p;
+ MPI frame;
+ int i,n,c;
+
+ if( (nbits % BITS_PER_MPI_LIMB) || nframe < 42 || len != 20 )
+ log_bug("can't encode a %d bit MD into a %d bits frame\n",len*8, nbits);
+
+ /* We encode the MD in this way:
+ *
+ * 0 42 PAD(n bytes) 0 ASN(18 bytes) MD(20 bytes)
+ *
+ * PAD consists of FF bytes.
+ */
+ frame = mpi_alloc_secure( nframe / BYTES_PER_MPI_LIMB );
+ n = 0;
+ for(i=20-1; i >= 0; i--, n++ )
+ mpi_putbyte(frame, n, md[i] );
+ for( i=18-1; i >= 0; i--, n++ )
+ mpi_putbyte(frame, n, asn[i] );
+ mpi_putbyte(frame, n++, 0 );
+ while( n < nframe-2 )
+ mpi_putbyte(frame, n++, 0xff );
+ mpi_putbyte(frame, n++, DIGEST_ALGO_RMD160 );
+ mpi_putbyte(frame, n++, 0 );
+ assert( n == nframe );
+ return frame;
+}
+
diff --git a/g10/sig-check.c b/g10/sig-check.c
index 41ac89341..75e800693 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -115,28 +115,27 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
{ 0x10, 0x04, 0x00, 0x05, 0x05, 0x02, 0x0d, 0xf7, 0x86,
0x48, 0x86, 0x2a, 0x08, 0x06, 0x0c, 0x30, 0x20, 0x30 };
- for(i=20,j=0; j < 18 && (c=mpi_getbyte(result, i)) != -1; i++, j++ )
+ for(i=20,j=0; (c=mpi_getbyte(result, i)) != -1 && j < 18; i++, j++ )
if( asn[j] != c )
break;
- if( j != 18 ) { /* ASN is wrong */
+ if( j != 18 || c ) { /* ASN is wrong */
rc = G10ERR_BAD_PUBKEY;
goto leave;
}
- if( !c ) {
- for(; (c=mpi_getbyte(result, i)) != -1; i++ )
- if( c != 0xff )
- break;
- if( c != 42 || mpi_getbyte(result, i) ) {
- /* Padding or leading bytes in signature is wrong */
- rc = G10ERR_BAD_PUBKEY;
- goto leave;
- }
- if( mpi_getbyte(result, 19) != sig->d.rsa.digest_start[0]
- || mpi_getbyte(result, 18) != sig->d.rsa.digest_start[1] ) {
- /* Wrong key used to check the signature */
- rc = G10ERR_BAD_PUBKEY;
- goto leave;
- }
+ for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
+ if( c != 0xff )
+ break;
+ i++;
+ if( c != DIGEST_ALGO_RMD160 || mpi_getbyte(result, i) ) {
+ /* Padding or leading bytes in signature is wrong */
+ rc = G10ERR_BAD_PUBKEY;
+ goto leave;
+ }
+ if( mpi_getbyte(result, 19) != sig->d.rsa.digest_start[0]
+ || mpi_getbyte(result, 18) != sig->d.rsa.digest_start[1] ) {
+ /* Wrong key used to check the signature */
+ rc = G10ERR_BAD_PUBKEY;
+ goto leave;
}
/* complete the digest */
@@ -162,25 +161,24 @@ signature_check( PKT_signature *sig, MD_HANDLE digest )
for(i=16,j=0; j < 18 && (c=mpi_getbyte(result, i)) != -1; i++, j++ )
if( asn[j] != c )
break;
- if( j != 18 ) { /* ASN is wrong */
+ if( j != 18 || c ) { /* ASN is wrong */
rc = G10ERR_BAD_PUBKEY;
goto leave;
}
- if( !c ) {
- for(; (c=mpi_getbyte(result, i)) != -1; i++ )
- if( c != 0xff )
- break;
- if( c != 1 || mpi_getbyte(result, i) ) {
- /* Padding or leading bytes in signature is wrong */
- rc = G10ERR_BAD_PUBKEY;
- goto leave;
- }
- if( mpi_getbyte(result, 15) != sig->d.rsa.digest_start[0]
- || mpi_getbyte(result, 14) != sig->d.rsa.digest_start[1] ) {
- /* Wrong key used to check the signature */
- rc = G10ERR_BAD_PUBKEY;
- goto leave;
- }
+ for(i++; (c=mpi_getbyte(result, i)) != -1; i++ )
+ if( c != 0xff )
+ break;
+ i++;
+ if( c != DIGEST_ALGO_MD5 || mpi_getbyte(result, i) ) {
+ /* Padding or leading bytes in signature is wrong */
+ rc = G10ERR_BAD_PUBKEY;
+ goto leave;
+ }
+ if( mpi_getbyte(result, 15) != sig->d.rsa.digest_start[0]
+ || mpi_getbyte(result, 14) != sig->d.rsa.digest_start[1] ) {
+ /* Wrong key used to check the signature */
+ rc = G10ERR_BAD_PUBKEY;
+ goto leave;
}
/* complete the digest */