diff --git a/NEWS b/NEWS index 2e110e64c..e2861de38 100644 --- a/NEWS +++ b/NEWS @@ -9,6 +9,9 @@ Noteworthy changes in version 0.2.15 * CAST5 works (using the PGP's special CFB mode). + * Now more PGP 5 compatible. + + * Some new test cases Noteworthy changes in version 0.2.14 ------------------------------------ diff --git a/THANKS b/THANKS index 6a7845279..cbbf7a3e6 100644 --- a/THANKS +++ b/THANKS @@ -20,6 +20,7 @@ Peter Gutmann pgut001@cs.auckland.ac.nz Ralph Gillen gillen@theochem.uni-duesseldorf.de Thomas Roessler roessler@guug.de Tomas Fasth tomas.fasth@twinspot.net +Ulf Möller 3umoelle@informatik.uni-hamburg.de Walter Koch walterk@ddorf.rhein-ruhr.de Werner Koch werner.koch@guug.de Wim Vandeputte bunbun@reptile.rug.ac.be diff --git a/TODO b/TODO index 897bb6093..a6d5b59ef 100644 --- a/TODO +++ b/TODO @@ -49,12 +49,7 @@ * fix the problems with "\v" in gettext - * calculation of cechksums for secret keys is wrong. We used a - the complete chunk length instead of the real number of bits. - The problme ist that it is how to stay compatible to old - keys? - Do wee need a kludge to calculate both versions of - checksums???? (keygen.c, seckey-cert.c) - + * replace getkey.c#enum_secret_keys diff --git a/VERSION b/VERSION index 160dadac6..ebe5042ff 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.2.14a +0.2.14b diff --git a/cipher/ChangeLog b/cipher/ChangeLog index e1bc0b8ec..bc9261b75 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,7 @@ +Wed Apr 8 14:57:11 1998 Werner Koch (wk@isil.d.shuttle.de) + + * misc.c (check_pubkey_algo2): New. + Tue Apr 7 18:46:49 1998 Werner Koch (wk@isil.d.shuttle.de) * cipher.c: New diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 9e3c2bdcc..466e8da67 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -396,35 +396,17 @@ blowfish_encrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) { u32 d1, d2; - #ifdef BIG_ENDIAN_HOST - d1 = ((u32*)inbuf)[0]; /* fixme: this may not be aligned */ - d2 = ((u32*)inbuf)[1]; - #else - ((byte*)&d1)[3] = inbuf[0]; - ((byte*)&d1)[2] = inbuf[1]; - ((byte*)&d1)[1] = inbuf[2]; - ((byte*)&d1)[0] = inbuf[3]; - ((byte*)&d2)[3] = inbuf[4]; - ((byte*)&d2)[2] = inbuf[5]; - ((byte*)&d2)[1] = inbuf[6]; - ((byte*)&d2)[0] = inbuf[7]; - #endif - + d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; encrypt( bc, &d1, &d2 ); - - #ifdef BIG_ENDIAN_HOST - ((u32*)outbuf)[0] = d1; - ((u32*)outbuf)[1] = d2; - #else - outbuf[0] = ((byte*)&d1)[3]; - outbuf[1] = ((byte*)&d1)[2]; - outbuf[2] = ((byte*)&d1)[1]; - outbuf[3] = ((byte*)&d1)[0]; - outbuf[4] = ((byte*)&d2)[3]; - outbuf[5] = ((byte*)&d2)[2]; - outbuf[6] = ((byte*)&d2)[1]; - outbuf[7] = ((byte*)&d2)[0]; - #endif + outbuf[0] = (d1 >> 24) & 0xff; + outbuf[1] = (d1 >> 16) & 0xff; + outbuf[2] = (d1 >> 8) & 0xff; + outbuf[3] = d1 & 0xff; + outbuf[4] = (d2 >> 24) & 0xff; + outbuf[5] = (d2 >> 16) & 0xff; + outbuf[6] = (d2 >> 8) & 0xff; + outbuf[7] = d2 & 0xff; } @@ -433,35 +415,17 @@ blowfish_decrypt_block( BLOWFISH_context *bc, byte *outbuf, byte *inbuf ) { u32 d1, d2; - #ifdef BIG_ENDIAN_HOST - d1 = ((u32*)inbuf)[0]; /* fixme: this may not be aligned */ - d2 = ((u32*)inbuf)[1]; - #else - ((byte*)&d1)[3] = inbuf[0]; - ((byte*)&d1)[2] = inbuf[1]; - ((byte*)&d1)[1] = inbuf[2]; - ((byte*)&d1)[0] = inbuf[3]; - ((byte*)&d2)[3] = inbuf[4]; - ((byte*)&d2)[2] = inbuf[5]; - ((byte*)&d2)[1] = inbuf[6]; - ((byte*)&d2)[0] = inbuf[7]; - #endif - + d1 = inbuf[0] << 24 | inbuf[1] << 16 | inbuf[2] << 8 | inbuf[3]; + d2 = inbuf[4] << 24 | inbuf[5] << 16 | inbuf[6] << 8 | inbuf[7]; decrypt( bc, &d1, &d2 ); - - #ifdef BIG_ENDIAN_HOST - ((u32*)outbuf)[0] = d1; - ((u32*)outbuf)[1] = d2; - #else - outbuf[0] = ((byte*)&d1)[3]; - outbuf[1] = ((byte*)&d1)[2]; - outbuf[2] = ((byte*)&d1)[1]; - outbuf[3] = ((byte*)&d1)[0]; - outbuf[4] = ((byte*)&d2)[3]; - outbuf[5] = ((byte*)&d2)[2]; - outbuf[6] = ((byte*)&d2)[1]; - outbuf[7] = ((byte*)&d2)[0]; - #endif + outbuf[0] = (d1 >> 24) & 0xff; + outbuf[1] = (d1 >> 16) & 0xff; + outbuf[2] = (d1 >> 8) & 0xff; + outbuf[3] = d1 & 0xff; + outbuf[4] = (d2 >> 24) & 0xff; + outbuf[5] = (d2 >> 16) & 0xff; + outbuf[6] = (d2 >> 8) & 0xff; + outbuf[7] = d2 & 0xff; } diff --git a/cipher/cipher.c b/cipher/cipher.c index 6e2bcce08..1f24c6b0e 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -225,8 +225,7 @@ do_cfb_encrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) if( nbytes <= c->unused ) { /* short enough to be encoded by the remaining XOR mask */ /* XOR the input with the IV and store input into IV */ - c->unused -= nbytes; - for(ivp=c->iv+STD_BLOCKSIZE - c->unused; nbytes; nbytes-- ) + for(ivp=c->iv+STD_BLOCKSIZE - c->unused; nbytes; nbytes--, c->unused-- ) *outbuf++ = (*ivp++ ^= *inbuf++); return; } @@ -271,8 +270,7 @@ do_cfb_decrypt( CIPHER_HANDLE c, byte *outbuf, byte *inbuf, unsigned nbytes ) if( nbytes <= c->unused ) { /* short enough to be encoded by the remaining XOR mask */ /* XOR the input with the IV and store input into IV */ - c->unused -= nbytes; - for(ivp=c->iv+STD_BLOCKSIZE - c->unused; nbytes; nbytes-- ) { + for(ivp=c->iv+STD_BLOCKSIZE - c->unused; nbytes; nbytes--,c->unused--){ temp = *inbuf++; *outbuf++ = *ivp ^ temp; *ivp++ = temp; diff --git a/cipher/misc.c b/cipher/misc.c index 35761e4f5..3016b8e56 100644 --- a/cipher/misc.c +++ b/cipher/misc.c @@ -114,18 +114,31 @@ digest_algo_to_string( int algo ) - - int check_pubkey_algo( int algo ) +{ + return check_pubkey_algo2( algo, 0 ); +} + +/**************** + * a usage of 0 means: don't care + */ +int +check_pubkey_algo2( int algo, unsigned usage ) { switch( algo ) { - case PUBKEY_ALGO_ELGAMAL: case PUBKEY_ALGO_DSA: + if( usage & 2 ) + return G10ERR_WR_PUBKEY_ALGO; + return 0; + + case PUBKEY_ALGO_ELGAMAL: + return 0; + #ifdef HAVE_RSA_CIPHER case PUBKEY_ALGO_RSA: - #endif return 0; + #endif default: return G10ERR_PUBKEY_ALGO; } diff --git a/g10/ChangeLog b/g10/ChangeLog index d3e06d2b7..94617fcc6 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,23 @@ +Wed Apr 8 16:19:39 1998 Werner Koch (wk@isil.d.shuttle.de) + + * packet.h: packet structs now uses structs from the pubkey, + removed all copy operations from packet to pubkey structs. + +Wed Apr 8 13:40:33 1998 Werner Koch (wk@isil.d.shuttle.de) + + * trustdb.c (verify_own_certs): Fixed "public key not found". + + * getkey.c (key_byname): New, combines public and secret key search. + + * pkclist.c (build_pkc_list): Add new arg usage, changed all callers. + * skclist.c (build_skc_list): Likewise. + + * ringedit.c (find_keyblock, keyring_search2): Removed. + +Wed Apr 8 09:47:21 1998 Werner Koch (wk@isil.d.shuttle.de) + + * sig-check.c (do_check): Applied small fix from Ulf Möller. + Tue Apr 7 19:28:07 1998 Werner Koch (wk@isil.d.shuttle.de) * cipher.c, encr-data.c, seckey-cert.c: Now uses cipher_xxxx diff --git a/g10/build-packet.c b/g10/build-packet.c index 4d0a7d69f..d1934e8c4 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -190,8 +190,8 @@ do_public_cert( IOBUF out, int ctb, PKT_public_cert *pkc ) mpi_write(a, pkc->d.dsa.y ); } else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { - mpi_write(a, pkc->d.rsa.rsa_n ); - mpi_write(a, pkc->d.rsa.rsa_e ); + mpi_write(a, pkc->d.rsa.n ); + mpi_write(a, pkc->d.rsa.e ); } else { rc = G10ERR_PUBKEY_ALGO; @@ -286,8 +286,8 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc ) write_16(a, skc->csum ); } else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { - mpi_write(a, skc->d.rsa.rsa_n ); - mpi_write(a, skc->d.rsa.rsa_e ); + mpi_write(a, skc->d.rsa.n ); + mpi_write(a, skc->d.rsa.e ); if( skc->is_protected ) { assert( skc->protect.algo == CIPHER_ALGO_BLOWFISH || skc->protect.algo == CIPHER_ALGO_CAST ); @@ -296,10 +296,10 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc ) } else iobuf_put(a, 0 ); - mpi_write(a, skc->d.rsa.rsa_d ); - mpi_write(a, skc->d.rsa.rsa_p ); - mpi_write(a, skc->d.rsa.rsa_q ); - mpi_write(a, skc->d.rsa.rsa_u ); + mpi_write(a, skc->d.rsa.d ); + mpi_write(a, skc->d.rsa.p ); + mpi_write(a, skc->d.rsa.q ); + mpi_write(a, skc->d.rsa.u ); write_16(a, skc->csum ); } else { diff --git a/g10/dsa.c b/g10/dsa.c index fa0cb271b..e8620ab25 100644 --- a/g10/dsa.c +++ b/g10/dsa.c @@ -39,7 +39,6 @@ void g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md, int digest_algo ) { - DSA_secret_key skey; MPI frame; byte *dp; @@ -58,12 +57,9 @@ g10_dsa_sign( PKT_secret_cert *skc, PKT_signature *sig, / BYTES_PER_MPI_LIMB ); mpi_set_buffer( frame, md_read(md, digest_algo), md_digest_length(digest_algo), 0 ); - skey.p = skc->d.elg.p; - skey.g = skc->d.elg.g; - skey.y = skc->d.elg.y; - skey.x = skc->d.elg.x; - dsa_sign( sig->d.dsa.r, sig->d.dsa.s, frame, &skey); - memset( &skey, 0, sizeof skey ); + if( DBG_CIPHER ) + log_mpidump("used sig frame: ", frame); + dsa_sign( sig->d.dsa.r, sig->d.dsa.s, frame, &skc->d.dsa ); mpi_free(frame); if( opt.verbose ) { char *ustr = get_user_id_string( sig->keyid ); diff --git a/g10/elg.c b/g10/elg.c index 329b762fe..bf6bf4361 100644 --- a/g10/elg.c +++ b/g10/elg.c @@ -37,7 +37,6 @@ void g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ) { - ELG_public_key pkey; MPI frame; assert( enc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ); @@ -46,12 +45,9 @@ g10_elg_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ) enc->d.elg.b = mpi_alloc( mpi_get_nlimbs(pkc->d.elg.p) ); keyid_from_pkc( pkc, enc->keyid ); frame = encode_session_key( dek, mpi_get_nbits(pkc->d.elg.p) ); - pkey.p = pkc->d.elg.p; - pkey.g = pkc->d.elg.g; - pkey.y = pkc->d.elg.y; if( DBG_CIPHER ) log_mpidump("Plain DEK frame: ", frame); - elg_encrypt( enc->d.elg.a, enc->d.elg.b, frame, &pkey); + elg_encrypt( enc->d.elg.a, enc->d.elg.b, frame, &pkc->d.elg ); mpi_free( frame ); if( DBG_CIPHER ) { log_mpidump("Encry DEK a: ", enc->d.elg.a ); @@ -69,7 +65,6 @@ void g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md, int digest_algo ) { - ELG_secret_key skey; MPI frame; byte *dp; @@ -85,12 +80,7 @@ g10_elg_sign( PKT_secret_cert *skc, PKT_signature *sig, sig->d.elg.a = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) ); sig->d.elg.b = mpi_alloc( mpi_get_nlimbs(skc->d.elg.p) ); frame = encode_md_value( md, mpi_get_nbits(skc->d.elg.p)); - skey.p = skc->d.elg.p; - skey.g = skc->d.elg.g; - skey.y = skc->d.elg.y; - skey.x = skc->d.elg.x; - elg_sign( sig->d.elg.a, sig->d.elg.b, frame, &skey); - memset( &skey, 0, sizeof skey ); + elg_sign( sig->d.elg.a, sig->d.elg.b, frame, &skc->d.elg ); mpi_free(frame); if( opt.verbose ) { char *ustr = get_user_id_string( sig->keyid ); diff --git a/g10/encode.c b/g10/encode.c index a7fa409c2..b73938070 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -172,7 +172,7 @@ encode_crypt( const char *filename, STRLIST remusr ) memset( &afx, 0, sizeof afx); memset( &zfx, 0, sizeof zfx); - if( (rc=build_pkc_list( remusr, &pkc_list)) ) + if( (rc=build_pkc_list( remusr, &pkc_list, 2)) ) return rc; /* prepare iobufs */ diff --git a/g10/free-packet.c b/g10/free-packet.c index eb90f51ef..8a484eb25 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -100,8 +100,8 @@ release_public_cert_parts( PKT_public_cert *cert ) mpi_free( cert->d.dsa.y ); cert->d.dsa.y = NULL; } else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) { - mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL; - mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL; + mpi_free( cert->d.rsa.n ); cert->d.rsa.n = NULL; + mpi_free( cert->d.rsa.e ); cert->d.rsa.e = NULL; } } @@ -130,8 +130,8 @@ copy_public_cert( PKT_public_cert *d, PKT_public_cert *s ) d->d.dsa.y = mpi_copy( s->d.dsa.y ); } else if( s->pubkey_algo == PUBKEY_ALGO_RSA ) { - 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.n = mpi_copy( s->d.rsa.n ); + d->d.rsa.e = mpi_copy( s->d.rsa.e ); } return d; } @@ -153,12 +153,12 @@ release_secret_cert_parts( PKT_secret_cert *cert ) mpi_free( cert->d.dsa.x ); cert->d.dsa.x = NULL; } else if( cert->pubkey_algo == PUBKEY_ALGO_RSA ) { - mpi_free( cert->d.rsa.rsa_n ); cert->d.rsa.rsa_n = NULL; - mpi_free( cert->d.rsa.rsa_e ); cert->d.rsa.rsa_e = NULL; - mpi_free( cert->d.rsa.rsa_d ); cert->d.rsa.rsa_d = NULL; - mpi_free( cert->d.rsa.rsa_p ); cert->d.rsa.rsa_p = NULL; - mpi_free( cert->d.rsa.rsa_q ); cert->d.rsa.rsa_q = NULL; - mpi_free( cert->d.rsa.rsa_u ); cert->d.rsa.rsa_u = NULL; + mpi_free( cert->d.rsa.n ); cert->d.rsa.n = NULL; + mpi_free( cert->d.rsa.e ); cert->d.rsa.e = NULL; + mpi_free( cert->d.rsa.d ); cert->d.rsa.d = NULL; + mpi_free( cert->d.rsa.p ); cert->d.rsa.p = NULL; + mpi_free( cert->d.rsa.q ); cert->d.rsa.q = NULL; + mpi_free( cert->d.rsa.u ); cert->d.rsa.u = NULL; } } @@ -189,12 +189,12 @@ copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s ) d->d.dsa.x = mpi_copy( s->d.dsa.x ); } else if( s->pubkey_algo == PUBKEY_ALGO_RSA ) { - 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 ); + d->d.rsa.n = mpi_copy( s->d.rsa.n ); + d->d.rsa.e = mpi_copy( s->d.rsa.e ); + d->d.rsa.d = mpi_copy( s->d.rsa.d ); + d->d.rsa.p = mpi_copy( s->d.rsa.p ); + d->d.rsa.q = mpi_copy( s->d.rsa.q ); + d->d.rsa.u = mpi_copy( s->d.rsa.u ); } return d; } @@ -337,9 +337,9 @@ cmp_public_certs( PKT_public_cert *a, PKT_public_cert *b ) return -1; } else if( a->pubkey_algo == PUBKEY_ALGO_RSA ) { - if( mpi_cmp( a->d.rsa.rsa_n , b->d.rsa.rsa_n ) ) + if( mpi_cmp( a->d.rsa.n , b->d.rsa.n ) ) return -1; - if( mpi_cmp( a->d.rsa.rsa_e , b->d.rsa.rsa_e ) ) + if( mpi_cmp( a->d.rsa.e , b->d.rsa.e ) ) return -1; } @@ -378,9 +378,9 @@ cmp_public_secret_cert( PKT_public_cert *pkc, PKT_secret_cert *skc ) return -1; } else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { - if( mpi_cmp( pkc->d.rsa.rsa_n , skc->d.rsa.rsa_n ) ) + if( mpi_cmp( pkc->d.rsa.n , skc->d.rsa.n ) ) return -1; - if( mpi_cmp( pkc->d.rsa.rsa_e , skc->d.rsa.rsa_e ) ) + if( mpi_cmp( pkc->d.rsa.e , skc->d.rsa.e ) ) return -1; } diff --git a/g10/getkey.c b/g10/getkey.c index 7868df951..966bc5d69 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -69,7 +69,8 @@ static int pkc_cache_entries; /* number of entries in pkc cache */ static int lookup( PKT_public_cert *pkc, - int mode, u32 *keyid, const char *name ); + int mode, u32 *keyid, const char *name, + KBNODE *ret_keyblock ); static int lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name ); @@ -238,7 +239,6 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid ) int rc = 0; pkc_cache_entry_t ce; - /* lets see wether we checked the keyid already */ for( kl = unknown_keyids; kl; kl = kl->next ) if( kl->keyid[0] == keyid[0] && kl->keyid[1] == keyid[1] ) @@ -259,7 +259,7 @@ get_pubkey( PKT_public_cert *pkc, u32 *keyid ) /* do a lookup */ - rc = lookup( pkc, 11, keyid, NULL ); + rc = lookup( pkc, 11, keyid, NULL, NULL ); if( !rc ) goto leave; @@ -329,8 +329,11 @@ hextobyte( const byte *s ) * - If the userid starts with a '*' a case insensitive substring search is * done (This is also the default). */ -int -get_pubkey_byname( PKT_public_cert *pkc, const char *name ) + + +static int +key_byname( int secret, + PKT_public_cert *pkc, PKT_secret_cert *skc, const char *name ) { int internal = 0; int rc = 0; @@ -424,23 +427,60 @@ get_pubkey_byname( PKT_public_cert *pkc, const char *name ) if( rc ) goto leave; - if( !pkc ) { - pkc = m_alloc_clear( sizeof *pkc ); - internal++; + if( secret ) { + if( !skc ) { + skc = m_alloc_clear( sizeof *skc ); + internal++; + } + rc = mode < 16? lookup_skc( skc, mode, keyid, name ) + : lookup_skc( skc, mode, keyid, fprint ); + } + else { + if( !pkc ) { + pkc = m_alloc_clear( sizeof *pkc ); + internal++; + } + rc = mode < 16? lookup( pkc, mode, keyid, name, NULL ) + : lookup( pkc, mode, keyid, fprint, NULL ); } - rc = mode < 16? lookup( pkc, mode, keyid, name ) - : lookup( pkc, mode, keyid, fprint ); leave: - if( internal ) - m_free(pkc); + if( internal && secret ) + m_free( skc ); + else if( internal ) + m_free( pkc ); return rc; } +int +get_pubkey_byname( PKT_public_cert *pkc, const char *name ) +{ + return key_byname( 0, pkc, NULL, name ); +} + + /**************** - * Get a secret key and store it into skey + * Search for a key with the given fingerprint and return the + * complete keyblock which may have more than only this key. + * The fingerprint should always be 20 bytes, fill with zeroes + * for 16 byte fprints. + */ +int +get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint ) +{ + int rc; + PKT_public_cert *pkc = m_alloc_clear( sizeof *pkc ); + + rc = lookup( pkc, 20, NULL, fprint, ret_keyblock ); + + free_public_cert( pkc ); + return rc; +} + +/**************** + * Get a secret key and store it into skc */ int get_seckey( PKT_secret_cert *skc, u32 *keyid ) @@ -486,8 +526,8 @@ get_seckey_byname( PKT_secret_cert *skc, const char *name, int unprotect ) { int rc; - /* fixme: add support for compare_name */ - rc = lookup_skc( skc, name? 2:15, NULL, name ); + rc = name ? key_byname( 1, NULL, skc, name ) + : lookup_skc( skc, 15, NULL, NULL ); if( !rc && unprotect ) rc = check_secret_key( skc ); @@ -547,9 +587,12 @@ compare_name( const char *uid, size_t uidlen, const char *name, int mode ) * 20 = lookup by 20 byte fingerprint which is stored in NAME * Caller must provide an empty PKC, if the pubkey_algo is filled in, only * a key of this algo will be returned. + * If ret_keyblock is not NULL, the complete keyblock is returned also + * and the caller must release it. */ static int -lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name ) +lookup( PKT_public_cert *pkc, int mode, u32 *keyid, + const char *name, KBNODE *ret_keyblock ) { int rc; KBNODE keyblock = NULL; @@ -593,12 +636,22 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name ) } } else { /* keyid or fingerprint lookup */ + if( DBG_CACHE && (mode== 10 || mode==11) ) { + log_debug("lookup keyid=%08lx%08lx req_algo=%d mode=%d\n", + (ulong)keyid[0], (ulong)keyid[1], + pkc->pubkey_algo, mode ); + } for(k=keyblock; k; k = k->next ) { if( k->pkt->pkttype == PKT_PUBLIC_CERT || k->pkt->pkttype == PKT_PUBKEY_SUBCERT ) { if( mode == 10 || mode == 11 ) { u32 aki[2]; keyid_from_pkc( k->pkt->pkt.public_cert, aki ); + if( DBG_CACHE ) { + log_debug(" aki=%08lx%08lx algo=%d\n", + (ulong)aki[0], (ulong)aki[1], + k->pkt->pkt.public_cert->pubkey_algo ); + } if( aki[1] == keyid[1] && ( mode == 10 || aki[0] == keyid[0] ) && ( !pkc->pubkey_algo @@ -643,6 +696,10 @@ lookup( PKT_public_cert *pkc, int mode, u32 *keyid, const char *name ) assert( k->pkt->pkttype == PKT_PUBLIC_CERT || k->pkt->pkttype == PKT_PUBKEY_SUBCERT ); copy_public_cert( pkc, k->pkt->pkt.public_cert ); + if( ret_keyblock ) { + *ret_keyblock = keyblock; + keyblock = NULL; + } break; /* enumeration */ } release_kbnode( keyblock ); @@ -708,12 +765,22 @@ lookup_skc( PKT_secret_cert *skc, int mode, u32 *keyid, const char *name ) } } else { /* keyid or fingerprint lookup */ + if( DBG_CACHE && (mode== 10 || mode==11) ) { + log_debug("lookup_skc keyid=%08lx%08lx req_algo=%d mode=%d\n", + (ulong)keyid[0], (ulong)keyid[1], + skc->pubkey_algo, mode ); + } for(k=keyblock; k; k = k->next ) { if( k->pkt->pkttype == PKT_SECRET_CERT || k->pkt->pkttype == PKT_SECKEY_SUBCERT ) { if( mode == 10 || mode == 11 ) { u32 aki[2]; keyid_from_skc( k->pkt->pkt.secret_cert, aki ); + if( DBG_CACHE ) { + log_debug(" aki=%08lx%08lx algo=%d\n", + (ulong)aki[0], (ulong)aki[1], + k->pkt->pkt.secret_cert->pubkey_algo ); + } if( aki[1] == keyid[1] && ( mode == 10 || aki[0] == keyid[0] ) && ( !skc->pubkey_algo @@ -825,7 +892,8 @@ enum_secret_keys( void **context, PKT_secret_cert *skc ) while( (rc=parse_packet(c->iobuf, &pkt)) != -1 ) { if( rc ) ; /* e.g. unknown packet */ - else if( pkt.pkttype == PKT_SECRET_CERT ) { + else if( pkt.pkttype == PKT_SECRET_CERT + || pkt.pkttype == PKT_SECKEY_SUBCERT ) { copy_secret_cert( skc, pkt.pkt.secret_cert ); set_packet_list_mode(save_mode); return 0; /* found */ diff --git a/g10/kbnode.c b/g10/kbnode.c index 11b0e46be..3780eb24a 100644 --- a/g10/kbnode.c +++ b/g10/kbnode.c @@ -275,7 +275,8 @@ dump_kbnode( KBNODE node ) fprintf(stderr, " keyid=%08lX\n", (ulong)node->pkt->pkt.signature->keyid[1] ); } - else if( node->pkt->pkttype == PKT_PUBLIC_CERT ) { + else if( node->pkt->pkttype == PKT_PUBLIC_CERT + || node->pkt->pkttype == PKT_PUBKEY_SUBCERT ) { fprintf(stderr, " keyid=%08lX\n", (ulong) keyid_from_pkc( node->pkt->pkt.public_cert, NULL )); } diff --git a/g10/keydb.h b/g10/keydb.h index 6a2425272..6618894a1 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -87,11 +87,12 @@ struct pubkey_find_info { /*-- pkclist.c --*/ void release_pkc_list( PKC_LIST pkc_list ); -int build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list ); +int build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list, unsigned usage ); /*-- skclist.c --*/ void release_skc_list( SKC_LIST skc_list ); -int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock ); +int build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, + int unlock, unsigned usage ); /*-- passphrase.h --*/ void set_passphrase_fd( int fd ); @@ -103,11 +104,10 @@ int make_dek_from_passphrase( DEK *dek, int mode, byte *salt ); void add_keyring( const char *name ); const char *get_keyring( int sequence ); void add_secret_keyring( const char *name ); -/*void cache_public_cert( PKT_public_cert *pkc ); -void cache_user_id( PKT_user_id *uid, u32 *keyid );*/ int get_pubkey( PKT_public_cert *pkc, u32 *keyid ); int get_pubkey_byname( PKT_public_cert *pkc, const char *name ); int get_seckey( PKT_secret_cert *skc, u32 *keyid ); +int get_keyblock_byfprint( KBNODE *ret_keyblock, const byte *fprint ); int seckey_available( u32 *keyid ); int get_seckey_byname( PKT_secret_cert *skc, const char *name, int unlock ); int enum_secret_keys( void **context, PKT_secret_cert *skc ); diff --git a/g10/keyid.c b/g10/keyid.c index 02e706fc2..5bbf6477a 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -262,7 +262,7 @@ keyid_from_skc( PKT_secret_cert *skc, u32 *keyid ) md_close(md); } else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { - lowbits = mpi_get_keyid( skc->d.rsa.rsa_n, keyid ); + lowbits = mpi_get_keyid( skc->d.rsa.n, keyid ); } else { keyid[0] = keyid[1] = lowbits = 0; @@ -311,7 +311,7 @@ keyid_from_pkc( PKT_public_cert *pkc, u32 *keyid ) md_close(md); } else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { - lowbits = mpi_get_keyid( pkc->d.rsa.rsa_n, keyid ); + lowbits = mpi_get_keyid( pkc->d.rsa.n, keyid ); } else { keyid[0] = keyid[1] = lowbits = 0; @@ -344,7 +344,7 @@ nbits_from_pkc( PKT_public_cert *pkc ) return mpi_get_nbits( pkc->d.dsa.p ); } else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { - return mpi_get_nbits( pkc->d.rsa.rsa_n ); + return mpi_get_nbits( pkc->d.rsa.n ); } else return 0; @@ -363,7 +363,7 @@ nbits_from_skc( PKT_secret_cert *skc ) return mpi_get_nbits( skc->d.dsa.p ); } else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) { - return mpi_get_nbits( skc->d.rsa.rsa_n ); + return mpi_get_nbits( skc->d.rsa.n ); } else return 0; @@ -442,8 +442,8 @@ fingerprint_from_skc( PKT_secret_cert *skc, size_t *ret_len ) pkc.d.dsa.y = skc->d.dsa.y; } else if( pkc.pubkey_algo == PUBKEY_ALGO_RSA ) { - pkc.d.rsa.rsa_n = skc->d.rsa.rsa_n; - pkc.d.rsa.rsa_e = skc->d.rsa.rsa_e; + pkc.d.rsa.n = skc->d.rsa.n; + pkc.d.rsa.e = skc->d.rsa.e; } p = fingerprint_from_pkc( &pkc, ret_len ); memset(&pkc, 0, sizeof pkc); /* not really needed */ @@ -489,10 +489,10 @@ fingerprint_from_pkc( PKT_public_cert *pkc, size_t *ret_len ) MD_HANDLE md; md = md_open( DIGEST_ALGO_MD5, 0); - p = buf = mpi_get_buffer( pkc->d.rsa.rsa_n, &n, NULL ); + p = buf = mpi_get_buffer( pkc->d.rsa.n, &n, NULL ); md_write( md, p, n ); m_free(buf); - p = buf = mpi_get_buffer( pkc->d.rsa.rsa_e, &n, NULL ); + p = buf = mpi_get_buffer( pkc->d.rsa.e, &n, NULL ); md_write( md, p, n ); m_free(buf); md_final(md); diff --git a/g10/mainproc.c b/g10/mainproc.c index 86a1716db..d8b4310a1 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -226,6 +226,7 @@ proc_plaintext( CTX c, PACKET *pkt ) * textmode filter (sigclass 0x01) */ c->mfx.md = md_open( DIGEST_ALGO_RMD160, 0); + md_enable( c->mfx.md, DIGEST_ALGO_SHA1 ); md_enable( c->mfx.md, DIGEST_ALGO_MD5 ); rc = handle_plaintext( pt, &c->mfx ); if( rc ) diff --git a/g10/packet.h b/g10/packet.h index 0e6a188c9..8b1e3c4c0 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -27,6 +27,12 @@ #include "cipher.h" #include "filter.h" +#ifndef HAVE_RSA_CIPHER +/* although we don't have RSA we need these structures to handle keyrings */ +typedef struct { MPI e, n; } RSA_public_key; +typedef struct { MPI e, n, p, q, d, u; } RSA_secret_key; +#endif + typedef enum { PKT_NONE =0, PKT_PUBKEY_ENC =1, /* public key encrypted packet */ @@ -106,21 +112,9 @@ typedef struct { byte pubkey_algo; /* algorithm used for public key scheme */ ulong local_id; /* internal use, valid if > 0 */ union { - struct { - MPI p; /* prime */ - MPI g; /* group generator */ - MPI y; /* g^x mod p */ - } elg; - struct { - MPI p; /* prime */ - MPI q; /* group order */ - MPI g; /* group generator */ - MPI y; /* g^x mod p */ - } dsa; - struct { - MPI rsa_n; /* public modulus */ - MPI rsa_e; /* public exponent */ - } rsa; + ELG_public_key elg; + DSA_public_key dsa; + RSA_public_key rsa; } d; } PKT_public_cert; @@ -143,27 +137,9 @@ typedef struct { byte iv[8]; /* initialization vector for CFB mode */ } protect; union { - struct { - MPI p; /* prime */ - MPI g; /* group generator */ - MPI y; /* g^x mod p */ - MPI x; /* secret exponent */ - } elg; - struct { - MPI p; /* prime */ - MPI q; /* group order */ - MPI g; /* group generator */ - MPI y; /* g^x mod p */ - MPI x; /* secret exponent */ - } dsa; - struct { - MPI rsa_n; /* public modulus */ - MPI rsa_e; /* public exponent */ - MPI rsa_d; /* secret descryption exponent */ - MPI rsa_p; /* secret first prime number */ - MPI rsa_q; /* secret second prime number */ - MPI rsa_u; /* secret multiplicative inverse */ - } rsa; + ELG_secret_key elg; + DSA_secret_key dsa; + RSA_secret_key rsa; } d; u16 csum; /* checksum */ } PKT_secret_cert; diff --git a/g10/parse-packet.c b/g10/parse-packet.c index 26c112244..b199ef21d 100644 --- a/g10/parse-packet.c +++ b/g10/parse-packet.c @@ -1084,15 +1084,15 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, putchar('\n'); } if( pkttype == PKT_PUBLIC_CERT || pkttype == PKT_PUBKEY_SUBCERT ) { - pkt->pkt.public_cert->d.rsa.rsa_n = rsa_pub_mod; - pkt->pkt.public_cert->d.rsa.rsa_e = rsa_pub_exp; + pkt->pkt.public_cert->d.rsa.n = rsa_pub_mod; + pkt->pkt.public_cert->d.rsa.e = rsa_pub_exp; } else { PKT_secret_cert *cert = pkt->pkt.secret_cert; byte temp[8]; - pkt->pkt.secret_cert->d.rsa.rsa_n = rsa_pub_mod; - pkt->pkt.secret_cert->d.rsa.rsa_e = rsa_pub_exp; + pkt->pkt.secret_cert->d.rsa.n = rsa_pub_mod; + pkt->pkt.secret_cert->d.rsa.e = rsa_pub_exp; cert->protect.algo = iobuf_get_noeof(inp); pktlen--; if( list_mode ) printf( "\tprotect algo: %d\n", cert->protect.algo); @@ -1112,22 +1112,22 @@ parse_certificate( IOBUF inp, int pkttype, unsigned long pktlen, else cert->is_protected = 0; /* (See comments at the code for elg keys) */ - n = pktlen; cert->d.rsa.rsa_d = mpi_read(inp, &n, 0 ); pktlen -=n; - n = pktlen; cert->d.rsa.rsa_p = mpi_read(inp, &n, 0 ); pktlen -=n; - n = pktlen; cert->d.rsa.rsa_q = mpi_read(inp, &n, 0 ); pktlen -=n; - n = pktlen; cert->d.rsa.rsa_u = mpi_read(inp, &n, 0 ); pktlen -=n; + n = pktlen; cert->d.rsa.d = mpi_read(inp, &n, 0 ); pktlen -=n; + n = pktlen; cert->d.rsa.p = mpi_read(inp, &n, 0 ); pktlen -=n; + n = pktlen; cert->d.rsa.q = mpi_read(inp, &n, 0 ); pktlen -=n; + n = pktlen; cert->d.rsa.u = mpi_read(inp, &n, 0 ); pktlen -=n; cert->csum = read_16(inp); pktlen -= 2; if( list_mode ) { printf("\t[secret values d,p,q,u are not shown]\n" "\tchecksum: %04hx\n", cert->csum); } - /* log_mpidump("rsa n=", cert->d.rsa.rsa_n ); - log_mpidump("rsa e=", cert->d.rsa.rsa_e ); - log_mpidump("rsa d=", cert->d.rsa.rsa_d ); - log_mpidump("rsa p=", cert->d.rsa.rsa_p ); - log_mpidump("rsa q=", cert->d.rsa.rsa_q ); - log_mpidump("rsa u=", cert->d.rsa.rsa_u ); */ + /* log_mpidump("rsa n=", cert->d.rsa.n ); + log_mpidump("rsa e=", cert->d.rsa.e ); + log_mpidump("rsa d=", cert->d.rsa.d ); + log_mpidump("rsa p=", cert->d.rsa.p ); + log_mpidump("rsa q=", cert->d.rsa.q ); + log_mpidump("rsa u=", cert->d.rsa.u ); */ } } else if( list_mode ) diff --git a/g10/pkclist.c b/g10/pkclist.c index d4e8133ae..8de95c3ab 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -291,7 +291,7 @@ release_pkc_list( PKC_LIST pkc_list ) } int -build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list ) +build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list, unsigned usage ) { PKC_LIST pkc_list = NULL; PKT_public_cert *pkc=NULL; @@ -316,7 +316,7 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list ) rc = get_pubkey_byname( pkc, answer ); if( rc ) tty_printf("No such user ID.\n"); - else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) { + else if( !(rc=check_pubkey_algo2(pkc->pubkey_algo, usage)) ) { int trustlevel; rc = check_trust( pkc, &trustlevel ); @@ -350,7 +350,7 @@ build_pkc_list( STRLIST remusr, PKC_LIST *ret_pkc_list ) free_public_cert( pkc ); pkc = NULL; log_error("skipped '%s': %s\n", remusr->d, g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo(pkc->pubkey_algo)) ) { + else if( !(rc=check_pubkey_algo2(pkc->pubkey_algo, usage )) ) { int trustlevel; rc = check_trust( pkc, &trustlevel ); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 7fd3101bd..0525f336f 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -50,36 +50,20 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) goto leave; if( k->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { - ELG_secret_key skey; - if( DBG_CIPHER ) { log_mpidump("Encr DEK a:", k->d.elg.a ); log_mpidump(" DEK b:", k->d.elg.b ); } - skey.p = skc->d.elg.p; - skey.g = skc->d.elg.g; - skey.y = skc->d.elg.y; - skey.x = skc->d.elg.x; - plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skey.p) ); - elg_decrypt( plain_dek, k->d.elg.a, k->d.elg.b, &skey ); - memset( &skey, 0, sizeof skey ); + plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skc->d.elg.p) ); + elg_decrypt( plain_dek, k->d.elg.a, k->d.elg.b, &skc->d.elg ); } #ifdef HAVE_RSA_CIPHER else if( k->pubkey_algo == PUBKEY_ALGO_RSA ) { - RSA_secret_key skey; - if( DBG_CIPHER ) log_mpidump("Encr DEK frame:", k->d.rsa.rsa_integer ); - 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; - plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skey.n) ); - rsa_secret( plain_dek, k->d.rsa.rsa_integer, &skey ); - memset( &skey, 0, sizeof skey ); + plain_dek = mpi_alloc_secure( mpi_get_nlimbs(skc->d.rsa.n) ); + rsa_secret( plain_dek, k->d.rsa.rsa_integer, &skc->d.rsa ); } #endif/*HAVE_RSA_CIPHER*/ else { diff --git a/g10/ringedit.c b/g10/ringedit.c index 8eade961a..3193b0012 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -75,8 +75,6 @@ static int search( PACKET *pkt, KBPOS *kbpos, int secret ); static int keyring_search( PACKET *pkt, KBPOS *kbpos, IOBUF iobuf, const char *fname ); -static int keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos, - const char *fname); static int keyring_read( KBPOS *kbpos, KBNODE *ret_root ); static int keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ); static int keyring_copy( KBPOS *kbpos, int mode, KBNODE root ); @@ -165,36 +163,6 @@ get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos ) } -/**************** - * Find a keyblock from the informations provided in INFO - * This can only be used fro public keys - */ -int -find_keyblock( PUBKEY_FIND_INFO info, KBPOS *kbpos ) -{ - int i, rc, last_rc=-1; - - for(i=0; i < MAX_RESOURCES; i++ ) { - if( resource_table[i].used && !resource_table[i].secret ) { - /* note: here we have to add different search functions, - * depending on the type of the resource */ - rc = keyring_search2( info, kbpos, resource_table[i].fname ); - if( !rc ) { - kbpos->resno = i; - kbpos->fp = NULL; - return 0; - } - if( rc != -1 ) { - log_error("error searching resource %d: %s\n", - i, g10_errstr(rc)); - last_rc = rc; - } - } - } - return last_rc; -} - - /**************** * Search a keyblock which starts with the given packet and put all @@ -535,9 +503,9 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname ) && !mpi_cmp( req_skc->d.dsa.x, skc->d.dsa.x ) ) || ( skc->pubkey_algo == PUBKEY_ALGO_RSA - && !mpi_cmp( req_skc->d.rsa.rsa_n, skc->d.rsa.rsa_n ) - && !mpi_cmp( req_skc->d.rsa.rsa_e, skc->d.rsa.rsa_e ) - && !mpi_cmp( req_skc->d.rsa.rsa_d, skc->d.rsa.rsa_d ) + && !mpi_cmp( req_skc->d.rsa.n, skc->d.rsa.n ) + && !mpi_cmp( req_skc->d.rsa.e, skc->d.rsa.e ) + && !mpi_cmp( req_skc->d.rsa.d, skc->d.rsa.d ) ) ) ) @@ -561,8 +529,8 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname ) && !mpi_cmp( req_pkc->d.dsa.y, pkc->d.dsa.y ) ) || ( pkc->pubkey_algo == PUBKEY_ALGO_RSA - && !mpi_cmp( req_pkc->d.rsa.rsa_n, pkc->d.rsa.rsa_n ) - && !mpi_cmp( req_pkc->d.rsa.rsa_e, pkc->d.rsa.rsa_e ) + && !mpi_cmp( req_pkc->d.rsa.n, pkc->d.rsa.n ) + && !mpi_cmp( req_pkc->d.rsa.e, pkc->d.rsa.e ) ) ) ) @@ -584,60 +552,6 @@ keyring_search( PACKET *req, KBPOS *kbpos, IOBUF iobuf, const char *fname ) return rc; } -/**************** - * search one keyring, return 0 if found, -1 if not found or an errorcode. - * this version uses the finger print and other informations - */ -static int -keyring_search2( PUBKEY_FIND_INFO info, KBPOS *kbpos, const char *fname ) -{ - int rc; - PACKET pkt; - int save_mode; - ulong offset; - IOBUF iobuf; - - init_packet(&pkt); - save_mode = set_packet_list_mode(0); - - iobuf = iobuf_open( fname ); - if( !iobuf ) { - log_error("can't open '%s'\n", fname ); - rc = G10ERR_OPEN_FILE; - goto leave; - } - - while( !(rc=search_packet(iobuf, &pkt, PKT_PUBLIC_CERT, &offset)) ) { - PKT_public_cert *pkc = pkt.pkt.public_cert; - u32 keyid[2]; - - assert( pkt.pkttype == PKT_PUBLIC_CERT ); - keyid_from_pkc( pkc, keyid ); - if( keyid[0] == info->keyid[0] && keyid[1] == info->keyid[1] - && pkc->pubkey_algo == info->pubkey_algo ) { - /* fixme: shall we check nbits too? (good for rsa keys) */ - /* fixme: check userid???? */ - size_t len; - byte *fp = fingerprint_from_pkc( pkc, &len ); - - if( !memcmp( fp, info->fingerprint, len ) ) { - m_free(fp); - break; /* found */ - } - m_free(fp); - } - free_packet(&pkt); - } - if( !rc ) - kbpos->offset = offset; - - leave: - iobuf_close(iobuf); - free_packet(&pkt); - set_packet_list_mode(save_mode); - return rc; -} - static int keyring_read( KBPOS *kbpos, KBNODE *ret_root ) diff --git a/g10/rsa.c b/g10/rsa.c index f1872b53a..ceba3fd1f 100644 --- a/g10/rsa.c +++ b/g10/rsa.c @@ -38,18 +38,14 @@ void g10_rsa_encrypt( PKT_public_cert *pkc, PKT_pubkey_enc *enc, DEK *dek ) { #ifdef HAVE_RSA_CIPHER - RSA_public_key pkey; - assert( enc->pubkey_algo == PUBKEY_ALGO_RSA ); keyid_from_pkc( pkc, enc->keyid ); enc->d.rsa.rsa_integer = encode_session_key( dek, mpi_get_nbits(pkc->d.rsa.rsa_n) ); - pkey.n = pkc->d.rsa.rsa_n; - pkey.e = pkc->d.rsa.rsa_e; if( DBG_CIPHER ) log_mpidump("Plain DEK frame: ", enc->d.rsa.rsa_integer); - rsa_public( enc->d.rsa.rsa_integer, enc->d.rsa.rsa_integer, &pkey); + rsa_public( enc->d.rsa.rsa_integer, enc->d.rsa.rsa_integer, &pkc->d.rsa); if( DBG_CIPHER ) log_mpidump("Encry DEK frame: ", enc->d.rsa.rsa_integer); if( opt.verbose ) { @@ -68,7 +64,6 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, MD_HANDLE md, int digest_algo ) { #ifdef HAVE_RSA_CIPHER - RSA_secret_key skey; byte *dp; assert( sig->pubkey_algo == PUBKEY_ALGO_RSA ); @@ -82,14 +77,7 @@ g10_rsa_sign( PKT_secret_cert *skc, PKT_signature *sig, sig->digest_start[1] = dp[1]; sig->d.rsa.rsa_integer = encode_md_value( md, mpi_get_nbits(skc->d.rsa.rsa_n)); - 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; - rsa_secret( sig->d.rsa.rsa_integer, sig->d.rsa.rsa_integer, &skey); - memset( &skey, 0, sizeof skey ); + rsa_secret( sig->d.rsa.rsa_integer, sig->d.rsa.rsa_integer, &skc->d.rsa ); if( opt.verbose ) { char *ustr = get_user_id_string( sig->keyid ); log_info("RSA signature from: %s\n", ustr ); diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index a4ce96206..d0e10b528 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -41,7 +41,6 @@ check_elg( PKT_secret_cert *cert ) int res; unsigned nbytes; u32 keyid[2]; - ELG_secret_key skey; char save_iv[8]; if( cert->is_protected ) { /* remove the protection */ @@ -93,12 +92,9 @@ check_elg( PKT_secret_cert *cert ) "\"--change-passphrase\" to convert.\n"); } - skey.p = cert->d.elg.p; - skey.g = cert->d.elg.g; - skey.y = cert->d.elg.y; - skey.x = test_x; - res = elg_check_secret_key( &skey ); - memset( &skey, 0, sizeof skey ); + mpi_swap( cert->d.elg.x, test_x ); + res = elg_check_secret_key( &cert->d.elg ); + mpi_swap( cert->d.elg.x, test_x ); if( !res ) { mpi_free(test_x); memcpy( cert->protect.iv, save_iv, 8 ); @@ -140,7 +136,6 @@ check_dsa( PKT_secret_cert *cert ) int res; unsigned nbytes; u32 keyid[2]; - DSA_secret_key skey; char save_iv[8]; if( cert->is_protected ) { /* remove the protection */ @@ -183,13 +178,9 @@ check_dsa( PKT_secret_cert *cert ) return G10ERR_BAD_PASS; } - skey.p = cert->d.dsa.p; - skey.q = cert->d.dsa.q; - skey.g = cert->d.dsa.g; - skey.y = cert->d.dsa.y; - skey.x = test_x; - res = dsa_check_secret_key( &skey ); - memset( &skey, 0, sizeof skey ); + mpi_swap( cert->d.dsa.x, test_x ); + res = dsa_check_secret_key( &cert->d.dsa ); + mpi_swap( cert->d.dsa.x, test_x ); if( !res ) { mpi_free(test_x); memcpy( cert->protect.iv, save_iv, 8 ); @@ -227,7 +218,6 @@ check_rsa( PKT_secret_cert *cert ) int res; unsigned nbytes; u32 keyid[2]; - RSA_secret_key skey; if( cert->is_protected ) { /* remove the protection */ DEK *dek = NULL; @@ -266,12 +256,7 @@ check_rsa( PKT_secret_cert *cert ) if( csum != cert->csum ) return G10ERR_BAD_PASS; - skey.d = cert->d.rsa.rsa_d; - skey.p = cert->d.rsa.rsa_p; - skey.q = cert->d.rsa.rsa_q; - skey.u = cert->d.rsa.rsa_u; - res = rsa_check_secret_key( &skey ); - memset( &skey, 0, sizeof skey ); + res = rsa_check_secret_key( &cert->d.rsa ); if( !res ) return G10ERR_BAD_PASS; break; diff --git a/g10/sig-check.c b/g10/sig-check.c index 2e0159348..d366267e7 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -63,13 +63,14 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) MPI result = NULL; int rc=0; + if( pkc->version == 4 && pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) + log_info("WARNING: This is probably a PGP generated " + "ElGamal key which is NOT secure for signatures!\n"); if( pkc->timestamp > sig->timestamp ) return G10ERR_TIME_CONFLICT; /* pubkey newer that signature */ if( pkc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) { - ELG_public_key pkey; - if( (rc=check_digest_algo(sig->digest_algo)) ) goto leave; /* make sure the digest algo is enabled (in case of a detached @@ -85,15 +86,10 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) } md_final( digest ); result = encode_md_value( digest, mpi_get_nbits(pkc->d.elg.p)); - pkey.p = pkc->d.elg.p; - pkey.g = pkc->d.elg.g; - pkey.y = pkc->d.elg.y; - if( !elg_verify( sig->d.elg.a, sig->d.elg.b, result, &pkey ) ) + if( !elg_verify( sig->d.elg.a, sig->d.elg.b, result, &pkc->d.elg ) ) rc = G10ERR_BAD_SIGN; } else if( pkc->pubkey_algo == PUBKEY_ALGO_DSA ) { - DSA_public_key pkey; - if( (rc=check_digest_algo(sig->digest_algo)) ) goto leave; /* make sure the digest algo is enabled (in case of a detached @@ -135,27 +131,22 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) 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, DIGEST_ALGO_SHA1), + mpi_set_buffer( result, md_read(digest, sig->digest_algo), md_digest_length(sig->digest_algo), 0 ); - pkey.p = pkc->d.dsa.p; - pkey.q = pkc->d.dsa.q; - pkey.g = pkc->d.dsa.g; - pkey.y = pkc->d.dsa.y; - if( !dsa_verify( sig->d.dsa.r, sig->d.dsa.s, result, &pkey ) ) + if( DBG_CIPHER ) + log_mpidump("calc sig frame: ", result); + if( !dsa_verify( sig->d.dsa.r, sig->d.dsa.s, result, &pkc->d.dsa ) ) rc = G10ERR_BAD_SIGN; } #ifdef HAVE_RSA_CIPHER else if( pkc->pubkey_algo == PUBKEY_ALGO_RSA ) { int i, j, c, old_enc; byte *dp; - RSA_public_key pkey; const byte *asn; size_t mdlen, asnlen; result = mpi_alloc(40); - pkey.n = pkc->d.rsa.rsa_n; - pkey.e = pkc->d.rsa.rsa_e; - rsa_public( result, sig->d.rsa.rsa_integer, &pkey ); + 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++ ) { @@ -204,8 +195,8 @@ do_check( PKT_public_cert *pkc, PKT_signature *sig, MD_HANDLE digest ) rc = G10ERR_BAD_PUBKEY; goto leave; } - if( mpi_getbyte(result, mdlen-1) != sig->d.rsa.digest_start[0] - || mpi_getbyte(result, mdlen-2) != sig->d.rsa.digest_start[1] ) { + 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; diff --git a/g10/sign.c b/g10/sign.c index 9f06680db..7e7921034 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -116,10 +116,10 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, if( fname && filenames->next && (!detached || encrypt) ) log_bug("multiple files can only be detached signed"); - if( (rc=build_skc_list( locusr, &skc_list, 1 )) ) + if( (rc=build_skc_list( locusr, &skc_list, 1, 1 )) ) goto leave; if( encrypt ) { - if( (rc=build_pkc_list( remusr, &pkc_list )) ) + if( (rc=build_pkc_list( remusr, &pkc_list, 2 )) ) goto leave; } @@ -150,7 +150,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, /* prepare to calculate the MD over the input */ if( opt.textmode && !outfile ) iobuf_push_filter( inp, text_filter, &tfx ); - mfx.md = md_open(DIGEST_ALGO_RMD160, 0); + mfx.md = md_open(opt.def_digest_algo, 0); if( !multifile ) iobuf_push_filter( inp, md_filter, &mfx ); @@ -176,7 +176,7 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, skc = skc_rover->skc; ops = m_alloc_clear( sizeof *ops ); ops->sig_class = opt.textmode && !outfile ? 0x01 : 0x00; - ops->digest_algo = DIGEST_ALGO_RMD160; + ops->digest_algo = opt.def_digest_algo; ops->pubkey_algo = skc->pubkey_algo; keyid_from_skc( skc, ops->keyid ); ops->last = !skc_rover->next; @@ -276,11 +276,11 @@ sign_file( STRLIST filenames, int detached, STRLIST locusr, md_final( md ); if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) - g10_elg_sign( skc, sig, md, DIGEST_ALGO_RMD160 ); + g10_elg_sign( skc, sig, md, opt.def_digest_algo ); else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) - g10_dsa_sign( skc, sig, md, DIGEST_ALGO_SHA1 ); + g10_dsa_sign( skc, sig, md, opt.def_digest_algo ); else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) - g10_rsa_sign( skc, sig, md, DIGEST_ALGO_RMD160 ); + g10_rsa_sign( skc, sig, md, opt.def_digest_algo ); else BUG(); @@ -369,7 +369,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) memset( &tfx, 0, sizeof tfx); init_packet( &pkt ); - if( (rc=build_skc_list( locusr, &skc_list, 1 )) ) + if( (rc=build_skc_list( locusr, &skc_list, 1, 1 )) ) goto leave; /* prepare iobufs */ @@ -397,7 +397,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) iobuf_writestr(out, "-----BEGIN PGP SIGNED MESSAGE-----\n" "Hash: RIPEMD160\n\n" ); - textmd = md_open(DIGEST_ALGO_RMD160, 0); + textmd = md_open(opt.def_digest_algo, 0); iobuf_push_filter( inp, text_filter, &tfx ); rc = write_dash_escaped( inp, out, textmd ); if( rc ) @@ -432,11 +432,11 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) md_final( md ); if( sig->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) - g10_elg_sign( skc, sig, md, DIGEST_ALGO_RMD160 ); + g10_elg_sign( skc, sig, md, opt.def_digest_algo ); else if( sig->pubkey_algo == PUBKEY_ALGO_DSA ) - g10_dsa_sign( skc, sig, md, DIGEST_ALGO_SHA1 ); + g10_dsa_sign( skc, sig, md, opt.def_digest_algo ); else if( sig->pubkey_algo == PUBKEY_ALGO_RSA ) - g10_rsa_sign( skc, sig, md, DIGEST_ALGO_RMD160 ); + g10_rsa_sign( skc, sig, md, opt.def_digest_algo ); else BUG(); @@ -682,7 +682,7 @@ sign_key( const char *username, STRLIST locusr ) } /* build a list of all signators */ - rc=build_skc_list( locusr, &skc_list, 0 ); + rc=build_skc_list( locusr, &skc_list, 0, 1 ); if( rc ) goto leave; diff --git a/g10/skclist.c b/g10/skclist.c index 53941cbfe..6d34b05bf 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -46,7 +46,8 @@ release_skc_list( SKC_LIST skc_list ) } int -build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock ) +build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock, + unsigned usage ) { SKC_LIST skc_list = NULL; int rc; @@ -59,8 +60,12 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock ) free_secret_cert( skc ); skc = NULL; log_error("no default secret key: %s\n", g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) { + else if( !(rc=check_pubkey_algo2(skc->pubkey_algo, usage)) ) { SKC_LIST r; + if( skc->version == 4 && (usage & 1) + && skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) + log_info("WARNING: This is probably a PGP generated " + "ElGamal key which is NOT secure for signatures!\n"); r = m_alloc( sizeof *r ); r->skc = skc; skc = NULL; r->next = skc_list; @@ -81,8 +86,12 @@ build_skc_list( STRLIST locusr, SKC_LIST *ret_skc_list, int unlock ) free_secret_cert( skc ); skc = NULL; log_error("skipped '%s': %s\n", locusr->d, g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo(skc->pubkey_algo)) ) { + else if( !(rc=check_pubkey_algo2(skc->pubkey_algo, usage)) ) { SKC_LIST r; + if( skc->version == 4 && (usage & 1) + && skc->pubkey_algo == PUBKEY_ALGO_ELGAMAL ) + log_info("WARNING: This is probably a PGP generated " + "ElGamal key which is NOT secure for signatures!\n"); r = m_alloc( sizeof *r ); r->skc = skc; skc = NULL; r->next = skc_list; diff --git a/g10/trustdb.c b/g10/trustdb.c index 8a9c959ed..321f7baa6 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -849,6 +849,7 @@ verify_own_certs() log_debug("checking secret key %08lX\n", (ulong)keyid[1] ); /* look wether we can access the public key of this secret key */ + memset( pkc, 0, sizeof *pkc ); rc = get_pubkey( pkc, keyid ); if( rc ) { log_error("keyid %08lX: secret key without public key\n", @@ -1146,8 +1147,6 @@ static int build_sigrecs( ulong pubkeyid ) { TRUSTREC rec, krec, rec2; - PUBKEY_FIND_INFO finfo=NULL; - KBPOS kbpos; KBNODE keyblock = NULL; KBNODE node; int rc=0; @@ -1163,23 +1162,13 @@ build_sigrecs( ulong pubkeyid ) log_error("%lu: build_sigrecs: can't read dir record\n", pubkeyid ); goto leave; } - finfo = m_alloc_clear( sizeof *finfo ); - finfo->keyid[0] = rec.r.dir.keyid[0]; - finfo->keyid[1] = rec.r.dir.keyid[1]; if( (rc=read_record( rec.r.dir.keyrec, &krec, RECTYPE_KEY )) ) { log_error("%lu: build_sigrecs: can't read key record\n", pubkeyid); goto leave; } - finfo->pubkey_algo = krec.r.key.pubkey_algo; - memcpy( finfo->fingerprint, krec.r.key.fingerprint, 20); - rc = find_keyblock( finfo, &kbpos ); + rc = get_keyblock_byfprint( &keyblock, krec.r.key.fingerprint ); if( rc ) { - log_error("build_sigrecs: find_keyblock failed\n" ); - goto leave; - } - rc = read_keyblock( &kbpos, &keyblock ); - if( rc ) { - log_error("build_sigrecs: read_keyblock failed\n" ); + log_error("build_sigrecs: get_keyblock_byfprint failed\n" ); goto leave; } /* check all key signatures */ @@ -1290,7 +1279,6 @@ build_sigrecs( ulong pubkeyid ) update_no_sigs( pubkeyid, revoked? 3:1 ); /* no signatures */ leave: - m_free( finfo ); release_kbnode( keyblock ); if( DBG_TRUST ) log_debug("trustdb: build_sigrecs: %s\n", g10_errstr(rc) ); diff --git a/include/cipher.h b/include/cipher.h index 0dfcf3e17..87440ef8d 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -97,6 +97,7 @@ int string_to_digest_algo( const char *string ); const char * pubkey_algo_to_string( int algo ); const char * digest_algo_to_string( int algo ); int check_pubkey_algo( int algo ); +int check_pubkey_algo2( int algo, unsigned usage ); int check_digest_algo( int algo ); /*-- smallprime.c --*/ diff --git a/include/errors.h b/include/errors.h index 4821a6bab..7f60b8715 100644 --- a/include/errors.h +++ b/include/errors.h @@ -60,5 +60,6 @@ #define G10ERR_DELETE_FILE 38 #define G10ERR_UNEXPECTED 39 #define G10ERR_TIME_CONFLICT 40 +#define G10ERR_WR_PUBKEY_ALGO 41 /* unusabe pubkey algo */ #endif /*G10_ERRORS_H*/ diff --git a/mpi/ChangeLog b/mpi/ChangeLog index ca01cb4d8..0a967df48 100644 --- a/mpi/ChangeLog +++ b/mpi/ChangeLog @@ -1,3 +1,7 @@ +Wed Apr 8 09:44:33 1998 Werner Koch (wk@isil.d.shuttle.de) + + * config.links: Applied small fix from Ulf Möller. + Mon Apr 6 12:38:52 1998 Werner Koch (wk@isil.d.shuttle.de) * mpicoder.c (mpi_get_buffer): Removed returned leading zeroes diff --git a/mpi/config.links b/mpi/config.links index 65331777a..fe9bda1c2 100644 --- a/mpi/config.links +++ b/mpi/config.links @@ -111,7 +111,7 @@ esac case "${target}" in - *-*-linuxaout* | *-*-linuxoldld*) + *-*-linuxaout* | *-*-linuxoldld* | *-*-linux-gnuoldld*) needs_underscore="y" ;; *-*-linux* | *-sysv* | *-solaris* | *-gnu*) diff --git a/util/errors.c b/util/errors.c index 59426e6e2..4436e78c0 100644 --- a/util/errors.c +++ b/util/errors.c @@ -72,6 +72,7 @@ g10_errstr( int err ) X(DELETE_FILE ,"File delete error") X(UNEXPECTED ,"Unexpected data") X(TIME_CONFLICT ,"Timestamp conflict") + X(WR_PUBKEY_ALGO ,"Unusable pubkey algorithm") default: p = buf; sprintf(buf, "g10err=%d", err); break; }