From 881e51323749ba797202d8a4119910e6f9d2f727 Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Sat, 13 Nov 1999 16:43:23 +0000 Subject: [PATCH] See ChangeLog: Sat Nov 13 17:44:23 CET 1999 Werner Koch --- BUGS | 12 +- checks/ChangeLog | 4 + checks/genkey1024.test | 2 +- cipher/ChangeLog | 43 +++++ cipher/Makefile.am | 1 - cipher/blowfish.c | 6 +- cipher/cast5.c | 6 +- cipher/cipher.c | 51 ++--- cipher/des.c | 10 +- cipher/dsa.c | 31 +-- cipher/dynload.c | 25 +-- cipher/elgamal.c | 41 ++-- cipher/g10c.c | 46 ----- cipher/md.c | 66 +++++-- cipher/primegen.c | 25 +-- cipher/pubkey.c | 426 +++++++++++++++++++++++++++++++++++------ cipher/random.c | 40 ++-- cipher/random.h | 1 - cipher/rndegd.c | 3 +- cipher/rndunix.c | 2 + cipher/rndw32.c | 3 +- cipher/twofish.c | 6 +- g10/ChangeLog | 43 +++++ g10/Makefile.am | 4 +- g10/build-packet.c | 1 + g10/cipher.c | 2 +- g10/encode.c | 2 +- g10/encr-data.c | 1 - g10/free-packet.c | 1 + g10/g10.c | 27 ++- g10/getkey.c | 29 +-- g10/gpgd.c | 2 +- g10/import.c | 4 +- g10/keyedit.c | 2 +- g10/keygen.c | 26 +-- g10/keyid.c | 18 +- g10/keylist.c | 5 +- g10/main.h | 8 +- g10/mainproc.c | 9 +- g10/misc.c | 57 ++++-- g10/packet.h | 14 +- g10/passphrase.c | 2 +- g10/pkclist.c | 11 +- g10/pubkey-enc.c | 10 +- g10/seckey-cert.c | 5 +- g10/seskey.c | 10 +- g10/sig-check.c | 84 +++++++- g10/sign.c | 77 +++++++- g10/skclist.c | 36 +--- g10/trustdb.c | 5 +- include/cipher.h | 2 + include/errors.h | 105 +++++----- include/g10lib.h | 189 ++++-------------- util/ChangeLog | 6 + util/Makefile.am | 2 +- util/errors.c | 9 +- util/g10u.c | 40 ---- 57 files changed, 1067 insertions(+), 631 deletions(-) delete mode 100644 cipher/g10c.c delete mode 100644 util/g10u.c diff --git a/BUGS b/BUGS index 79eb95438..be82aa6ec 100644 --- a/BUGS +++ b/BUGS @@ -47,7 +47,7 @@ and after about half a day in the rsync snapshots. [ *] #23 1999-09-03 0.9.11 Only the first signature of a cleartext sig seems to be verified. Can't fix it in 1.0 because the code is semi-frozen. - HMMM: Can't reprodude the bug here - it just works. Check wehther + HMMM: Can't reprodude the bug here - it just works. [ *] #24 1999-09-05 0.9.11 Does not link libc and libz expect when removing all "-lc -lz" except @@ -60,5 +60,13 @@ and after about half a day in the rsync snapshots. validity) is used in all other cases. The Edit menu does not have a way to disbly user ID based validity. +[ *] #26 1999-11-11 + gpg still does not take UTF8 strings to select a UID. + FIX: 1999-11-12 -Next #26 +[ **] #27 1999-11-12 + Unknown packets (type 17 - photo ID?) mess up the checking + of self-signature becuase they are simply ignored. + + +Next #28 diff --git a/checks/ChangeLog b/checks/ChangeLog index cfd6083d3..9be8600e9 100644 --- a/checks/ChangeLog +++ b/checks/ChangeLog @@ -1,3 +1,7 @@ +Sat Nov 13 17:44:23 CET 1999 Werner Koch + + * genkey1024.test: Does not use --quick-random anymore. + Thu Oct 28 16:17:46 CEST 1999 Werner Koch * Makefile.am (GPG_DEARMOR): New and use --no-options. diff --git a/checks/genkey1024.test b/checks/genkey1024.test index 81cb24fce..42a1000c0 100755 --- a/checks/genkey1024.test +++ b/checks/genkey1024.test @@ -17,7 +17,7 @@ expect - </dev/null #set timeout -1 set timeout 8 match_max 100000 -spawn ../g10/gpg --no-batch --quick-random --homedir . --gen-key +spawn ../g10/gpg --no-batch --homedir . --gen-key expect { -exact "Please select what kind of key you want:\r (1) DSA and ElGamal (default)\r diff --git a/cipher/ChangeLog b/cipher/ChangeLog index ea23ca182..6aed450dd 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,46 @@ +Sat Nov 13 17:44:23 CET 1999 Werner Koch + + * pubkey.c (disable_pubkey_algo): Made static. + (gcry_pk_ctl): New. + + * random.c (get_random_bits): Renamed to ... + (get_random_bytes): ... this and made static. + (gcry_random_bytes): New. + (gcry_random_bytes_secure): New. + (randomize_buffer): Renamed to ... + (gcry_randomize): ...this. + + * md.c (gcry_md_hash_buffer): New. + + * pubkey.c (gcry_pk_algo_info): 4 new commands. + (pubkey_get_npkey): Made static. + (pubkey_get_nskey): Made static. + (pubkey_get_nsig): Made static. + (pubkey_get_nenc): Made static. + + * pubkey.c: Removed all G10ERR_xxx. + * cipher.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_CIPHER_ALGO. + * md.c: Changed all GCRYERR_INV_ALGO to GCRYERR_INV_MD_ALGO. + * cast5.c (cast_setkey): Changed errocodes to GCRYERR_xxx. + * blowfish.c: Ditto. + * des.c: Ditto. + * twofish.c: Ditto. + * dsa.c: Ditto. + * elgamal.c: Ditto. + + * g10c.c: Removed + + * cipher.c (gcry_cipher_open): Replaced alloc functions and return NULL + if we are out of core. + * dynload.c: Replaced all memory allocation functions. + * md.c: Ditto. + * primegen.c: Ditto. + * pubkey.c: Ditto. + * random.c: Ditto. + * rndw32.c: Ditto. + * elgamal.c: Ditto. + * dsa.c: Ditto. + Tue Oct 26 14:10:21 CEST 1999 Werner Koch * elgamal.c (sign): Hugh found strange code here. Replaced by BUG(). diff --git a/cipher/Makefile.am b/cipher/Makefile.am index e68ee19fc..23142d9cb 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -57,7 +57,6 @@ libcipher_la_SOURCES = cipher.c \ rmd.h \ dsa.h \ dsa.c \ - g10c.c \ smallprime.c \ construct.c diff --git a/cipher/blowfish.c b/cipher/blowfish.c index 5a829d413..e7f047ff5 100644 --- a/cipher/blowfish.c +++ b/cipher/blowfish.c @@ -35,7 +35,7 @@ #include #include #include "types.h" -#include "errors.h" +#include "g10lib.h" #include "blowfish.h" #include "dynload.h" @@ -498,7 +498,7 @@ bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) fprintf(stderr,"%s\n", selftest_failed ); } if( selftest_failed ) - return G10ERR_SELFTEST_FAILED; + return GCRYERR_SELFTEST; for(i=0; i < BLOWFISH_ROUNDS+2; i++ ) c->p[i] = ps[i]; @@ -559,7 +559,7 @@ bf_setkey( BLOWFISH_context *c, byte *key, unsigned keylen ) for( j=i+1; j < 256; j++) { if( (c->s0[i] == c->s0[j]) || (c->s1[i] == c->s1[j]) || (c->s2[i] == c->s2[j]) || (c->s3[i] == c->s3[j]) ) - return G10ERR_WEAK_KEY; + return GCRYERR_WEAK_KEY; } } diff --git a/cipher/cast5.c b/cipher/cast5.c index 0e602bd2e..aaa0a42ef 100644 --- a/cipher/cast5.c +++ b/cipher/cast5.c @@ -39,8 +39,8 @@ #include #include #include +#include "g10lib.h" #include "types.h" -#include "errors.h" #include "cast5.h" @@ -566,10 +566,10 @@ cast_setkey( CAST5_context *c, byte *key, unsigned keylen ) fprintf(stderr,"CAST5 selftest failed (%s).\n", selftest_failed ); } if( selftest_failed ) - return G10ERR_SELFTEST_FAILED; + return GCRYERR_SELFTEST; if( keylen != 16 ) - return G10ERR_WRONG_KEYLEN; + return GCRYERR_INV_KEYLEN; x[0] = key[0] << 24 | key[1] << 16 | key[2] << 8 | key[3]; x[1] = key[4] << 24 | key[5] << 16 | key[6] << 8 | key[7]; diff --git a/cipher/cipher.c b/cipher/cipher.c index 277dd13f0..0a1ad604f 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -27,7 +27,6 @@ #include "g10lib.h" #include "util.h" -#include "errors.h" #include "cipher.h" #include "des.h" #include "blowfish.h" @@ -289,12 +288,12 @@ check_cipher_algo( int algo ) if( cipher_table[i].algo == algo ) { for(i=0; i < DIM(disabled_algos); i++ ) { if( disabled_algos[i] == algo ) - return G10ERR_CIPHER_ALGO; + return GCRYERR_INV_CIPHER_ALGO; } return 0; /* okay */ } } while( load_cipher_modules() ); - return G10ERR_CIPHER_ALGO; + return GCRYERR_INV_CIPHER_ALGO; } @@ -356,13 +355,13 @@ gcry_cipher_open( int algo, int mode, unsigned int flags ) /* check whether the algo is available */ if( check_cipher_algo( algo ) ) { - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); return NULL; } /* check flags */ if( (flags & ~(GCRY_CIPHER_SECURE|GCRY_CIPHER_ENABLE_SYNC)) ) { - set_lasterr( GCRYERR_INV_ARG ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); return NULL; } @@ -386,17 +385,21 @@ gcry_cipher_open( int algo, int mode, unsigned int flags ) /* FIXME: issue a warning when this mode is used */ break; default: - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); return NULL; } /* ? perform selftest here and mark this with a flag in cipher_table ? */ - h = secure ? m_alloc_secure_clear( sizeof *h + h = secure ? g10_calloc_secure( 1, sizeof *h + cipher_table[idx].contextsize - sizeof(PROPERLY_ALIGNED_TYPE) ) - : m_alloc_clear( sizeof *h + cipher_table[idx].contextsize + : g10_calloc( 1, sizeof *h + cipher_table[idx].contextsize - sizeof(PROPERLY_ALIGNED_TYPE) ); + if( !h ) { + set_lasterr( GCRYERR_NO_MEM ); + return NULL; + } h->magic = secure ? CTX_MAGIC_SECURE : CTX_MAGIC_NORMAL; h->algo = algo; h->mode = mode; @@ -420,7 +423,7 @@ gcry_cipher_close( GCRY_CIPHER_HD h ) return; } h->magic = 0; - m_free(h); + g10_free(h); } @@ -449,7 +452,7 @@ cipher_setiv( GCRY_CIPHER_HD c, const byte *iv, unsigned ivlen ) static void -do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks ) { unsigned n; @@ -461,7 +464,7 @@ do_ecb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) } static void -do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks ) { unsigned n; @@ -473,7 +476,7 @@ do_ecb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) } static void -do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks ) { unsigned int n; byte *ivp; @@ -494,7 +497,7 @@ do_cbc_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) } static void -do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) +do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblocks ) { unsigned int n; byte *ivp; @@ -517,7 +520,7 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nblocks ) static void -do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) +do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes ) { byte *ivp; size_t blocksize = c->blocksize; @@ -561,7 +564,7 @@ do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) } static void -do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) +do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes ) { byte *ivp; ulong temp; @@ -624,7 +627,8 @@ do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) * Depending on the mode some some contraints apply to NBYTES. */ static void -cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) +cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf, + const byte *inbuf, unsigned nbytes ) { switch( c->mode ) { case GCRY_CIPHER_MODE_ECB: @@ -680,7 +684,8 @@ gcry_cipher_encrypt( GCRY_CIPHER_HD h, byte *out, size_t outsize, * Depending on the mode some some contraints apply to NBYTES. */ static void -cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, byte *inbuf, unsigned nbytes ) +cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, + unsigned nbytes ) { switch( c->mode ) { case GCRY_CIPHER_MODE_ECB: @@ -760,7 +765,7 @@ gcry_cipher_ctl( GCRY_CIPHER_HD h, int cmd, void *buffer, size_t buflen) * integer with the algo number. */ if( h || !buffer || buflen != sizeof(int) ) - return set_lasterr( GCRYERR_INV_ARG ); + return set_lasterr( GCRYERR_INV_CIPHER_ALGO ); disable_cipher_algo( *(int*)buffer ); break; @@ -819,26 +824,26 @@ gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes) switch( what ) { case GCRYCTL_GET_KEYLEN: if( buffer || nbytes ) { - set_lasterr( GCRYERR_INV_ARG ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); break; } ui = cipher_get_keylen( algo ); if( ui > 0 && ui <= 512 ) return (int)ui/8; /* the only reason is an invalid algo or a strange blocksize */ - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); break; case GCRYCTL_GET_BLKLEN: if( buffer || nbytes ) { - set_lasterr( GCRYERR_INV_ARG ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); break; } ui = cipher_get_blocksize( algo ); if( ui > 0 && ui < 10000 ) return (int)ui; /* the only reason is an invalid algo or a strange blocksize */ - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); break; case GCRYCTL_TEST_ALGO: @@ -847,7 +852,7 @@ gcry_cipher_algo_info( int algo, int what, void *buffer, size_t *nbytes) break; } if( check_cipher_algo( algo ) ) { - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_CIPHER_ALGO ); break; } return 0; diff --git a/cipher/des.c b/cipher/des.c index c2ca3f848..af5b5845b 100644 --- a/cipher/des.c +++ b/cipher/des.c @@ -116,7 +116,7 @@ #include #include /* memcpy, memcmp */ #include "types.h" /* for byte and u32 typedefs */ -#include "errors.h" +#include "g10lib.h" #include "des.h" #if defined(__GNUC__) && defined(__GNU_LIBRARY__) @@ -558,7 +558,7 @@ des_setkey (struct _des_ctx *ctx, const byte * key) int i; if( selftest_failed ) - return G10ERR_SELFTEST_FAILED; + return GCRYERR_SELFTEST; des_key_schedule (key, ctx->encrypt_subkeys); @@ -944,14 +944,14 @@ static int do_tripledes_setkey ( struct _tripledes_ctx *ctx, byte *key, unsigned keylen ) { if( selftest_failed ) - return G10ERR_SELFTEST_FAILED; + return GCRYERR_SELFTEST; if( keylen != 24 ) - return G10ERR_WRONG_KEYLEN; + return GCRYERR_INV_KEYLEN; tripledes_set3keys ( ctx, key, key+8, key+16); if( is_weak_key( key ) || is_weak_key( key+8 ) || is_weak_key( key+16 ) ) - return G10ERR_WEAK_KEY; + return GCRYERR_WEAK_KEY; return 0; } diff --git a/cipher/dsa.c b/cipher/dsa.c index 5828b9508..5a356c9c2 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -23,6 +23,7 @@ #include #include #include +#include "g10lib.h" #include "util.h" #include "mpi.h" #include "cipher.h" @@ -77,7 +78,7 @@ gen_k( MPI q ) progress('.'); if( !rndbuf || nbits < 32 ) { - m_free(rndbuf); + g10_free(rndbuf); rndbuf = get_random_bits( nbits, 1, 1 ); } else { /* change only some of the higher bits */ @@ -86,7 +87,7 @@ gen_k( MPI q ) * maybe it is easier to do this directly in random.c */ char *pp = get_random_bits( 32, 1, 1 ); memcpy( rndbuf,pp, 4 ); - m_free(pp); + g10_free(pp); } mpi_set_buffer( k, rndbuf, nbytes, 0 ); if( mpi_test_bit( k, nbits-1 ) ) @@ -108,7 +109,7 @@ gen_k( MPI q ) } break; /* okay */ } - m_free(rndbuf); + g10_free(rndbuf); if( DBG_CIPHER ) progress('\n'); @@ -131,7 +132,7 @@ test_keys( DSA_secret_key *sk, unsigned qbits ) /*mpi_set_bytes( test, qbits, get_random_byte, 0 );*/ { char *p = get_random_bits( qbits, 0, 0 ); mpi_set_buffer( test, p, (qbits+7)/8, 0 ); - m_free(p); + g10_free(p); } sign( out1_a, out1_b, test, sk ); @@ -202,12 +203,12 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) else { /* change only some of the higher bits (= 2 bytes)*/ char *r = get_random_bits( 16, 2, 1 ); memcpy(rndbuf, r, 16/8 ); - m_free(r); + g10_free(r); } mpi_set_buffer( x, rndbuf, (qbits+7)/8, 0 ); mpi_clear_highbit( x, qbits+1 ); } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, h )<0 ) ); - m_free(rndbuf); + g10_free(rndbuf); mpi_free( e ); mpi_free( h ); @@ -347,7 +348,7 @@ dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) DSA_secret_key sk; if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; generate( &sk, nbits, retfactors ); skey[0] = sk.p; @@ -365,9 +366,9 @@ dsa_check_secret_key( int algo, MPI *skey ) DSA_secret_key sk; if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; sk.p = skey[0]; sk.q = skey[1]; @@ -375,7 +376,7 @@ dsa_check_secret_key( int algo, MPI *skey ) sk.y = skey[3]; sk.x = skey[4]; if( !check_secret_key( &sk ) ) - return G10ERR_BAD_SECKEY; + return GCRYERR_BAD_SECRET_KEY; return 0; } @@ -388,9 +389,9 @@ dsa_sign( int algo, MPI *resarr, MPI data, MPI *skey ) DSA_secret_key sk; if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] || !skey[4] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; sk.p = skey[0]; sk.q = skey[1]; @@ -410,17 +411,17 @@ dsa_verify( int algo, MPI hash, MPI *data, MPI *pkey, DSA_public_key pk; if( algo != PUBKEY_ALGO_DSA ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2] || !pkey[3] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; pk.p = pkey[0]; pk.q = pkey[1]; pk.g = pkey[2]; pk.y = pkey[3]; if( !verify( data[0], data[1], hash, &pk ) ) - return G10ERR_BAD_SIGN; + return GCRYERR_BAD_SIGNATURE; return 0; } diff --git a/cipher/dynload.c b/cipher/dynload.c index e2c988e02..962b398a4 100644 --- a/cipher/dynload.c +++ b/cipher/dynload.c @@ -31,6 +31,7 @@ #include #include #endif +#include "g10lib.h" #include "util.h" #include "cipher.h" #include "dynload.h" @@ -131,12 +132,12 @@ register_cipher_extension( const char *mainpgm, const char *fname ) tmp = make_filename(fname, NULL); else tmp = make_filename(GNUPG_LIBDIR, fname, NULL); - el = m_alloc_clear( sizeof *el + strlen(tmp) ); + el = g10_xcalloc( 1, sizeof *el + strlen(tmp) ); strcpy(el->name, tmp ); - m_free(tmp); + g10_free(tmp); } else { - el = m_alloc_clear( sizeof *el + strlen(fname) ); + el = g10_xcalloc( 1, sizeof *el + strlen(fname) ); strcpy(el->name, fname ); } /* check whether we have a class hint */ @@ -152,7 +153,7 @@ register_cipher_extension( const char *mainpgm, const char *fname ) for(r = extensions; r; r = r->next ) { if( !compare_filenames(r->name, el->name) ) { log_info("extension `%s' already registered\n", el->name ); - m_free(el); + g10_free(el); return; } else if( r->internal ) @@ -180,7 +181,7 @@ register_internal_cipher_extension( { EXTLIST r, el; - el = m_alloc_clear( sizeof *el + strlen(module_id) ); + el = g10_xcalloc( 1, sizeof *el + strlen(module_id) ); strcpy(el->name, module_id ); el->internal = 1; @@ -188,7 +189,7 @@ register_internal_cipher_extension( for(r = extensions; r; r = r->next ) { if( !compare_filenames(r->name, el->name) ) { log_info("extension `%s' already registered\n", el->name ); - m_free(el); + g10_free(el); return; } } @@ -350,13 +351,13 @@ enum_gnupgext_digests( void **enum_context, ENUMCONTEXT *ctx; if( !*enum_context ) { /* init context */ - ctx = m_alloc_clear( sizeof( *ctx ) ); + ctx = g10_xcalloc( 1, sizeof( *ctx ) ); ctx->r = extensions; ctx->reqalgo = *algo; *enum_context = ctx; } else if( !algo ) { /* release the context */ - m_free(*enum_context); + g10_free(*enum_context); *enum_context = NULL; return 0; } @@ -411,12 +412,12 @@ enum_gnupgext_ciphers( void **enum_context, int *algo, void (**)( void *, byte *, byte *)); if( !*enum_context ) { /* init context */ - ctx = m_alloc_clear( sizeof( *ctx ) ); + ctx = g10_xcalloc( 1, sizeof( *ctx ) ); ctx->r = extensions; *enum_context = ctx; } else if( !algo ) { /* release the context */ - m_free(*enum_context); + g10_free(*enum_context); *enum_context = NULL; return NULL; } @@ -485,12 +486,12 @@ enum_gnupgext_pubkeys( void **enum_context, int *algo, unsigned (**)( int , MPI * ) ); if( !*enum_context ) { /* init context */ - ctx = m_alloc_clear( sizeof( *ctx ) ); + ctx = g10_xcalloc( 1, sizeof( *ctx ) ); ctx->r = extensions; *enum_context = ctx; } else if( !algo ) { /* release the context */ - m_free(*enum_context); + g10_free(*enum_context); *enum_context = NULL; return NULL; } diff --git a/cipher/elgamal.c b/cipher/elgamal.c index 9f98ce2e0..48fe22ac8 100644 --- a/cipher/elgamal.c +++ b/cipher/elgamal.c @@ -26,6 +26,7 @@ #include #include #include +#include "g10lib.h" #include "util.h" #include "mpi.h" #include "cipher.h" @@ -79,7 +80,7 @@ test_keys( ELG_secret_key *sk, unsigned nbits ) /*mpi_set_bytes( test, nbits, get_random_byte, 0 );*/ { char *p = get_random_bits( nbits, 0, 0 ); mpi_set_buffer( test, p, (nbits+7)/8, 0 ); - m_free(p); + g10_free(p); } encrypt( out1_a, out1_b, test, &pk ); @@ -119,7 +120,7 @@ gen_k( MPI p ) if( DBG_CIPHER ) progress('.'); if( !rndbuf || nbits < 32 ) { - m_free(rndbuf); + g10_free(rndbuf); rndbuf = get_random_bits( nbits, 1, 1 ); } else { /* change only some of the higher bits */ @@ -128,7 +129,7 @@ gen_k( MPI p ) * maybe it is easier to do this directly in random.c */ char *pp = get_random_bits( 32, 1, 1 ); memcpy( rndbuf,pp, 4 ); - m_free(pp); + g10_free(pp); } mpi_set_buffer( k, rndbuf, nbytes, 0 ); @@ -156,7 +157,7 @@ gen_k( MPI p ) } } found: - m_free(rndbuf); + g10_free(rndbuf); if( DBG_CIPHER ) progress('\n'); mpi_free(p_1); @@ -212,13 +213,13 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors ) progress('.'); if( rndbuf ) { /* change only some of the higher bits */ if( nbits < 16 ) {/* should never happen ... */ - m_free(rndbuf); + g10_free(rndbuf); rndbuf = get_random_bits( nbits, 2, 1 ); } else { char *r = get_random_bits( 16, 2, 1 ); memcpy(rndbuf, r, 16/8 ); - m_free(r); + g10_free(r); } } else @@ -226,7 +227,7 @@ generate( ELG_secret_key *sk, unsigned nbits, MPI **ret_factors ) mpi_set_buffer( x, rndbuf, (nbits+7)/8, 0 ); mpi_clear_highbit( x, nbits+1 ); } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) ); - m_free(rndbuf); + g10_free(rndbuf); y = mpi_alloc(nbits/BITS_PER_MPI_LIMB); mpi_powm( y, g, x, p ); @@ -443,7 +444,7 @@ elg_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) ELG_secret_key sk; if( !is_ELGAMAL(algo) ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; generate( &sk, nbits, retfactors ); skey[0] = sk.p; @@ -460,16 +461,16 @@ elg_check_secret_key( int algo, MPI *skey ) ELG_secret_key sk; if( !is_ELGAMAL(algo) ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !skey[0] || !skey[1] || !skey[2] || !skey[3] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; sk.p = skey[0]; sk.g = skey[1]; sk.y = skey[2]; sk.x = skey[3]; if( !check_secret_key( &sk ) ) - return G10ERR_BAD_SECKEY; + return GCRYERR_BAD_SECRET_KEY; return 0; } @@ -482,9 +483,9 @@ elg_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) ELG_public_key pk; if( !is_ELGAMAL(algo) ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !data || !pkey[0] || !pkey[1] || !pkey[2] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; pk.p = pkey[0]; pk.g = pkey[1]; @@ -501,10 +502,10 @@ elg_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) ELG_secret_key sk; if( !is_ELGAMAL(algo) ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !data[0] || !data[1] || !skey[0] || !skey[1] || !skey[2] || !skey[3] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; sk.p = skey[0]; sk.g = skey[1]; @@ -521,9 +522,9 @@ elg_sign( int algo, MPI *resarr, MPI data, MPI *skey ) ELG_secret_key sk; if( !is_ELGAMAL(algo) ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !data || !skey[0] || !skey[1] || !skey[2] || !skey[3] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; sk.p = skey[0]; sk.g = skey[1]; @@ -542,16 +543,16 @@ elg_verify( int algo, MPI hash, MPI *data, MPI *pkey, ELG_public_key pk; if( !is_ELGAMAL(algo) ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; if( !data[0] || !data[1] || !hash || !pkey[0] || !pkey[1] || !pkey[2] ) - return G10ERR_BAD_MPI; + return GCRYERR_BAD_MPI; pk.p = pkey[0]; pk.g = pkey[1]; pk.y = pkey[2]; if( !verify( data[0], data[1], hash, &pk ) ) - return G10ERR_BAD_SIGN; + return GCRYERR_BAD_SIGNATURE; return 0; } diff --git a/cipher/g10c.c b/cipher/g10c.c deleted file mode 100644 index de6a09c96..000000000 --- a/cipher/g10c.c +++ /dev/null @@ -1,46 +0,0 @@ -/* g10c.c - Wrapper for cipher functions - * 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 - */ - -#include -#include -#include -#include "mpi.h" -#include "random.h" -#include "cipher.h" - - -/* FIXME: The modules should use functions from libgcrypt */ - - -const char *g10c_revision_string(int dummy) { return "$Revision$"; } - -MPI -g10c_generate_secret_prime( unsigned nbits ) -{ - return generate_secret_prime( nbits ); -} - - -char * -g10c_get_random_bits( unsigned nbits, int level, int secure ) -{ - return (char*)get_random_bits( nbits, level, secure ); -} - diff --git a/cipher/md.c b/cipher/md.c index f0dc9394e..bb179b679 100644 --- a/cipher/md.c +++ b/cipher/md.c @@ -28,7 +28,6 @@ #include "g10lib.h" #include "util.h" #include "cipher.h" -#include "errors.h" #include "dynload.h" #include "rmd.h" @@ -93,13 +92,13 @@ new_list_item( int algo, { struct md_digest_list_s *r; - r = m_alloc_clear( sizeof *r ); + r = g10_xcalloc( 1, sizeof *r ); r->algo = algo, r->name = (*get_info)( algo, &r->contextsize, &r->asnoid, &r->asnlen, &r->mdlen, &r->init, &r->write, &r->final, &r->read ); if( !r->name ) { - m_free(r); + g10_free(r); r = NULL; } return r; @@ -230,7 +229,7 @@ check_digest_algo( int algo ) if( r->algo == algo ) return 0; } while( !r && load_digest_module(algo) ); - return G10ERR_DIGEST_ALGO; + return GCRYERR_INV_MD_ALGO; } @@ -267,8 +266,13 @@ md_open( int algo, int secure ) / sizeof(PROPERLY_ALIGNED_TYPE) ) * sizeof(PROPERLY_ALIGNED_TYPE); /* allocate and set the Context pointer to the private data */ - hd = secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) ) - : m_alloc( n + sizeof( struct gcry_md_context ) ); + hd = secure ? g10_malloc_secure( n + sizeof( struct gcry_md_context ) ) + : g10_malloc( n + sizeof( struct gcry_md_context ) ); + if( !hd ) { + set_lasterr( GCRYERR_NO_MEM ); + return NULL; + } + hd->ctx = ctx = (struct gcry_md_context*)( (char*)hd + n ); /* setup the globally visible data (bctl in the diagram)*/ hd->bufsize = n - sizeof( struct gcry_md_handle ) + 1; @@ -315,13 +319,16 @@ md_enable( GCRY_MD_HD hd, int algo ) } while( !r && load_digest_module( algo ) ); if( !r ) { log_debug("md_enable: algorithm %d not available\n", algo ); - return set_lasterr( GCRYERR_INV_ALGO ); + return set_lasterr( GCRYERR_INV_MD_ALGO ); } /* and allocate a new list entry */ - ac = h->secure? m_alloc_secure( sizeof *ac + r->contextsize + ac = h->secure? g10_malloc_secure( sizeof *ac + r->contextsize - sizeof(r->context) ) - : m_alloc( sizeof *ac + r->contextsize + : g10_malloc( sizeof *ac + r->contextsize - sizeof(r->context) ); + if( !rc ) + return set_lasterr( GCRYERR_NO_MEM ); + *ac = *r; ac->next = h->list; h->list = ac; @@ -350,8 +357,13 @@ md_copy( GCRY_MD_HD ahd ) md_write( ahd, NULL, 0 ); n = (char*)ahd->ctx - (char*)ahd; - bhd = a->secure ? m_alloc_secure( n + sizeof( struct gcry_md_context ) ) - : m_alloc( n + sizeof( struct gcry_md_context ) ); + bhd = a->secure ? g10_malloc_secure( n + sizeof( struct gcry_md_context ) ) + : g10_malloc( n + sizeof( struct gcry_md_context ) ); + if( !bhd ) { + set_lasterr( GCRYERR_NO_MEM ); + return NULL; + } + bhd->ctx = b = (struct gcry_md_context*)( (char*)bhd + n ); /* no need to copy the buffer due to the write above */ assert( ahd->bufsize == (n - sizeof( struct gcry_md_handle ) + 1) ); @@ -363,9 +375,9 @@ md_copy( GCRY_MD_HD ahd ) /* and now copy the complete list of algorithms */ /* I know that the copied list is reversed, but that doesn't matter */ for( ar=a->list; ar; ar = ar->next ) { - br = a->secure ? m_alloc_secure( sizeof *br + ar->contextsize + br = a->secure ? g10_xmalloc_secure( sizeof *br + ar->contextsize - sizeof(ar->context) ) - : m_alloc( sizeof *br + ar->contextsize + : g10_xmalloc( sizeof *br + ar->contextsize - sizeof(ar->context) ); memcpy( br, ar, sizeof(*br) + ar->contextsize - sizeof(ar->context) ); @@ -412,9 +424,9 @@ md_close(GCRY_MD_HD a) md_stop_debug(a); for(r=a->ctx->list; r; r = r2 ) { r2 = r->next; - m_free(r); + g10_free(r); } - m_free(a); + g10_free(a); } @@ -555,8 +567,8 @@ md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen ) /* I don't want to change the interface, so I simply work on a copy * of the context (extra overhead - should be fixed)*/ - context = a->ctx->secure ? m_alloc_secure( r->contextsize ) - : m_alloc( r->contextsize ); + context = a->ctx->secure ? g10_xmalloc_secure( r->contextsize ) + : g10_xmalloc( r->contextsize ); memcpy( context, r->context.c, r->contextsize ); (*r->final)( context ); digest = (*r->read)( context ); @@ -565,7 +577,7 @@ md_digest( GCRY_MD_HD a, int algo, byte *buffer, int buflen ) buflen = r->mdlen; memcpy( buffer, digest, buflen ); - m_free(context); + g10_free(context); return buflen; } #endif @@ -581,6 +593,20 @@ gcry_md_get( GCRY_MD_HD hd, int algo, byte *buffer, int buflen ) } +/**************** + * Shortcut function to hash a buffer with a given algo. The only supported + * algorithm is RIPE-MD. The supplied digest buffer must be large enough + * to store the resulting hash. No error is returned, the function will + * abort on an invalite algo. DISABLED_ALGOS are ignored here. + */ +void +gcry_md_hash_buffer( int algo, char *digest, const char *buffer, size_t length) +{ + if( algo == GCRY_MD_RMD160 ) + rmd160_hash_buffer( digest, buffer, length ); + else + BUG(); +} static int md_get_algo( GCRY_MD_HD a ) @@ -636,7 +662,7 @@ gcry_md_get_algo_dlen( int algo ) default: { int len = md_digest_length( algo ); if( !len ) - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_MD_ALGO ); return 0; } } @@ -695,7 +721,7 @@ gcry_md_algo_info( int algo, int what, void *buffer, size_t *nbytes) return -1; } if( check_digest_algo( algo ) ) { - set_lasterr( GCRYERR_INV_ALGO ); + set_lasterr( GCRYERR_INV_MD_ALGO ); return -1; } break; diff --git a/cipher/primegen.c b/cipher/primegen.c index 9bf108531..ca8e3ee9f 100644 --- a/cipher/primegen.c +++ b/cipher/primegen.c @@ -28,6 +28,7 @@ #include #include #include +#include "g10lib.h" #include "util.h" #include "mpi.h" #include "cipher.h" @@ -121,7 +122,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits, q_factor = mode==1? gen_prime( req_qbits, 0, 1 ) : NULL; /* allocate an array to hold the factors + 2 for later usage */ - factors = m_alloc_clear( (n+2) * sizeof *factors ); + factors = g10_xcalloc_clear( n+2, sizeof *factors ); /* make a pool of 3n+5 primes (this is an arbitrary value) */ m = n*3+5; @@ -129,7 +130,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits, m += 5; /* need some more for DSA */ if( m < 25 ) m = 25; - pool = m_alloc_clear( m * sizeof *pool ); + pool = g10_xcalloc( m , sizeof *pool ); /* permutate over the pool of primes */ count1=count2=0; @@ -142,7 +143,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits, pool[i] = NULL; } /* init m_out_of_n() */ - perms = m_alloc_clear( m ); + perms = g10_xcalloc( 1, m ); for(i=0; i < n; i++ ) { perms[i] = 1; pool[i] = gen_prime( fbits, 0, 1 ); @@ -158,7 +159,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits, factors[j++] = pool[i]; } if( i == n ) { - m_free(perms); perms = NULL; + g10_free(perms); perms = NULL; progress('!'); goto next_try; /* allocate new primes */ } @@ -213,7 +214,7 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits, } if( ret_factors ) { /* caller wants the factors */ - *ret_factors = m_alloc_clear( (n+2) * sizeof **ret_factors); + *ret_factors = g10_xcalloc( n+2 , sizeof **ret_factors); if( mode == 1 ) { i = 0; (*ret_factors)[i++] = mpi_copy( q_factor ); @@ -264,11 +265,11 @@ generate_elg_prime( int mode, unsigned pbits, unsigned qbits, if( !DBG_CIPHER ) progress('\n'); - m_free( factors ); /* (factors are shallow copies) */ + g10_free( factors ); /* (factors are shallow copies) */ for(i=0; i < m; i++ ) mpi_free( pool[i] ); - m_free( pool ); - m_free(perms); + g10_free( pool ); + g10_free(perms); mpi_free(val_2); return prime; } @@ -292,7 +293,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel ) for(i=0; small_prime_numbers[i]; i++ ) no_of_small_prime_numbers++; } - mods = m_alloc( no_of_small_prime_numbers * sizeof *mods ); + mods = g10_xmalloc( no_of_small_prime_numbers * sizeof *mods ); /* make nbits fit into MPI implementation */ nlimbs = (nbits + BITS_PER_MPI_LIMB - 1) / BITS_PER_MPI_LIMB; val_2 = mpi_alloc_set_ui( 2 ); @@ -308,7 +309,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel ) /* generate a random number */ { char *p = get_random_bits( nbits, randomlevel, secret ); mpi_set_buffer( prime, p, (nbits+7)/8, 0 ); - m_free(p); + g10_free(p); } /* set high order bit to 1, set low order bit to 1 */ @@ -352,7 +353,7 @@ gen_prime( unsigned nbits, int secret, int randomlevel ) mpi_free(result); mpi_free(pminus1); mpi_free(prime); - m_free(mods); + g10_free(mods); return ptest; } } @@ -436,7 +437,7 @@ is_prime( MPI n, int steps, int *count ) /*mpi_set_bytes( x, nbits-1, get_random_byte, 0 );*/ { char *p = get_random_bits( nbits, 0, 0 ); mpi_set_buffer( x, p, (nbits+7)/8, 0 ); - m_free(p); + g10_free(p); } /* make sure that the number is smaller than the prime * and keep the randomness of the high bit */ diff --git a/cipher/pubkey.c b/cipher/pubkey.c index 4561f2ffa..8d00d95a4 100644 --- a/cipher/pubkey.c +++ b/cipher/pubkey.c @@ -27,13 +27,13 @@ #include "g10lib.h" #include "util.h" -#include "errors.h" #include "mpi.h" #include "cipher.h" #include "elgamal.h" #include "dsa.h" #include "dynload.h" +/* FIXME: use set_lasterr() */ #define TABLE_SIZE 10 @@ -58,31 +58,72 @@ struct pubkey_table_s { static struct pubkey_table_s pubkey_table[TABLE_SIZE]; static int disabled_algos[TABLE_SIZE]; +static struct { const char* name; int algo; + const char* common_elements; + const char* public_elements; + const char* secret_elements; +} algo_info_table[] = { + { "dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x" }, + { "rsa" , PUBKEY_ALGO_RSA , "ne", "", "dpqu" }, + { "elg" , PUBKEY_ALGO_ELGAMAL , "pgy", "", "x" }, + { "openpgp-dsa" , PUBKEY_ALGO_DSA , "pqgy", "", "x" }, + { "openpgp-rsa" , PUBKEY_ALGO_RSA , "pqgy", "", "x" }, + { "openpgp-elg" , PUBKEY_ALGO_ELGAMAL_E , "pgy", "", "x" }, + { "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "pgy", "", "x" }, + { NULL }}; + +static struct { + const char* name; int algo; + const char* elements; +} sig_info_table[] = { + { "dsa" , PUBKEY_ALGO_DSA , "rs" }, + { "rsa" , PUBKEY_ALGO_RSA , "s" }, + { "elg" , PUBKEY_ALGO_ELGAMAL , "rs" }, + { "openpgp-dsa" , PUBKEY_ALGO_DSA , "rs" }, + { "openpgp-rsa" , PUBKEY_ALGO_RSA , "s" }, + { "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "rs" }, + { NULL }}; + +static struct { + const char* name; int algo; + const char* elements; +} enc_info_table[] = { + { "elg" , PUBKEY_ALGO_ELGAMAL , "ab" }, + { "rsa" , PUBKEY_ALGO_RSA , "a" }, + { "openpgp-rsa" , PUBKEY_ALGO_RSA , "a" }, + { "openpgp-elg" , PUBKEY_ALGO_ELGAMAL_E , "ab" }, + { "openpgp-elg-sig", PUBKEY_ALGO_ELGAMAL , "ab" }, + { NULL }}; + + +static int pubkey_sign( int algo, MPI *resarr, MPI hash, MPI *skey ); +static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, + int (*cmp)(void *, MPI), void *opaque ); static int dummy_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) -{ log_bug("no generate() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } +{ log_bug("no generate() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; } static int dummy_check_secret_key( int algo, MPI *skey ) -{ log_bug("no check_secret_key() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } +{ log_bug("no check_secret_key() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; } static int dummy_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) -{ log_bug("no encrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } +{ log_bug("no encrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; } static int dummy_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) -{ log_bug("no decrypt() for %d\n", algo ); return G10ERR_PUBKEY_ALGO; } +{ log_bug("no decrypt() for %d\n", algo ); return GCRYERR_INV_PK_ALGO; } static int 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 GCRYERR_INV_PK_ALGO; } static int 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 GCRYERR_INV_PK_ALGO; } static unsigned dummy_get_nbits( int algo, MPI *pkey ) @@ -269,7 +310,7 @@ gcry_pk_algo_name( int algo ) } -void +static void disable_pubkey_algo( int algo ) { int i; @@ -284,38 +325,32 @@ disable_pubkey_algo( int algo ) } -int -check_pubkey_algo( int algo ) -{ - return check_pubkey_algo2( algo, 0 ); -} - /**************** * a use of 0 means: don't care */ -int -check_pubkey_algo2( int algo, unsigned use ) +static int +check_pubkey_algo( int algo, unsigned use ) { int i; do { for(i=0; pubkey_table[i].name; i++ ) if( pubkey_table[i].algo == algo ) { - if( (use & PUBKEY_USAGE_SIG) - && !(pubkey_table[i].use & PUBKEY_USAGE_SIG) ) - return G10ERR_WR_PUBKEY_ALGO; - if( (use & PUBKEY_USAGE_ENC) - && !(pubkey_table[i].use & PUBKEY_USAGE_ENC) ) - return G10ERR_WR_PUBKEY_ALGO; + if( (use & GCRY_PK_USAGE_SIGN) + && !(pubkey_table[i].use & GCRY_PK_USAGE_SIGN) ) + return GCRYERR_WRONG_PK_ALGO; + if( (use & GCRY_PK_USAGE_ENCR) + && !(pubkey_table[i].use & GCRY_PK_USAGE_ENCR) ) + return GCRYERR_WRONG_PK_ALGO; for(i=0; i < DIM(disabled_algos); i++ ) { if( disabled_algos[i] == algo ) - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; } return 0; /* okay */ } } while( load_pubkey_modules() ); - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; } @@ -324,7 +359,7 @@ check_pubkey_algo2( int algo, unsigned use ) /**************** * Return the number of public key material numbers */ -int +static int pubkey_get_npkey( int algo ) { int i; @@ -341,7 +376,7 @@ pubkey_get_npkey( int algo ) /**************** * Return the number of secret key material numbers */ -int +static int pubkey_get_nskey( int algo ) { int i; @@ -358,7 +393,7 @@ pubkey_get_nskey( int algo ) /**************** * Return the number of signature material numbers */ -int +static int pubkey_get_nsig( int algo ) { int i; @@ -375,7 +410,7 @@ pubkey_get_nsig( int algo ) /**************** * Return the number of encryption material numbers */ -int +static int pubkey_get_nenc( int algo ) { int i; @@ -391,6 +426,9 @@ pubkey_get_nenc( int algo ) /**************** * Get the number of nbits from the public key + * FIXME: This should also take a S-Expt but must be optimized in + * some way becuase it is used in keylistsings ans such (store it with the + * S-Exp as some private data?) */ unsigned pubkey_nbits( int algo, MPI *pkey ) @@ -419,7 +457,7 @@ pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) return (*pubkey_table[i].generate)( algo, nbits, skey, retfactors ); } while( load_pubkey_modules() ); - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; } @@ -433,7 +471,7 @@ pubkey_check_secret_key( int algo, MPI *skey ) if( pubkey_table[i].algo == algo ) return (*pubkey_table[i].check_secret_key)( algo, skey ); } while( load_pubkey_modules() ); - return G10ERR_PUBKEY_ALGO; + return GCRYERR_INV_PK_ALGO; } @@ -462,7 +500,7 @@ pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ) goto ready; } } while( load_pubkey_modules() ); - rc = G10ERR_PUBKEY_ALGO; + rc = GCRYERR_INV_PK_ALGO; ready: if( !rc && DBG_CIPHER ) { for(i=0; i < pubkey_get_nenc(algo); i++ ) @@ -501,7 +539,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) goto ready; } } while( load_pubkey_modules() ); - rc = G10ERR_PUBKEY_ALGO; + rc = GCRYERR_INV_PK_ALGO; ready: if( !rc && DBG_CIPHER ) { log_mpidump(" plain:", *result ); @@ -516,7 +554,7 @@ pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey ) * should be an array of MPIs of size PUBKEY_MAX_NSIG (or less if the * algorithm allows this - check with pubkey_get_nsig() ) */ -int +static int pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey ) { int i, rc; @@ -535,7 +573,7 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey ) goto ready; } } while( load_pubkey_modules() ); - rc = G10ERR_PUBKEY_ALGO; + rc = GCRYERR_INV_PK_ALGO; ready: if( !rc && DBG_CIPHER ) { for(i=0; i < pubkey_get_nsig(algo); i++ ) @@ -548,7 +586,7 @@ pubkey_sign( int algo, MPI *resarr, MPI data, MPI *skey ) * Verify a public key signature. * Return 0 if the signature is good */ -int +static int pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, int (*cmp)(void *, MPI), void *opaquev ) { @@ -562,12 +600,171 @@ pubkey_verify( int algo, MPI hash, MPI *data, MPI *pkey, goto ready; } } while( load_pubkey_modules() ); - rc = G10ERR_PUBKEY_ALGO; + rc = GCRYERR_INV_PK_ALGO; ready: return rc; } +static void +release_mpi_array( MPI *array ) +{ + for( ; *array; array++ ) { + mpi_free(*array); + *array = NULL; + } +} + +/**************** + * Convert a S-Exp with either a private or a public key to our + * internal format. Currently we do only support the following + * algorithms: + * dsa + * rsa + * openpgp-dsa + * openpgp-rsa + * openpgp-elg + * openpgp-elg-sig + * Provide a SE with the first element be either "private-key" or + * or "public-key". the followed by a list with its first element + * be one of the above algorithm identifiers and the following + * elements are pairs with parameter-id and value. + * NOTE: we look through the list to find a list beginning with + * "private-key" or "public-key" - the first one found is used. + * + * FIXME: Allow for encrypted secret keys here. + * + * Returns: A pointer to an allocated array of MPIs if the return value is + * zero; the caller has to release this array. + */ +static int +sexp_to_key( GCRY_SEXP sexp, int want_private, MPI **retarray, int *retalgo) +{ + GCRY_SEXP list, l2; + const char *name; + const char *s; + size_t n; + int i, idx; + int algo; + const char *elems1, *elems2; + GCRY_MPI *array; + + /* check that the first element is valid */ + list = gcry_sexp_find_token( sexp, want_private? "private-key" + :"public-key", 0 ); + if( !list ) + return GCRYERR_INV_OBJ; /* Does not contain a public- or private-key object */ + list = gcry_sexp_cdr( list ); + if( !list ) + return GCRYERR_NO_OBJ; /* no cdr for the key object */ + name = gcry_sexp_car_data( list, &n ); + if( !name ) + return GCRYERR_INV_OBJ; /* invalid structure of object */ + for(i=0; (s=algo_info_table[i].name); i++ ) { + if( strlen(s) == n && !memcmp( s, name, n ) ) + break; + } + if( !s ) + return GCRYERR_INV_PK_ALGO; /* unknown algorithm */ + algo = algo_info_table[i].algo; + elems1 = algo_info_table[i].common_elements; + elems2 = want_private? algo_info_table[i].secret_elements + : algo_info_table[i].public_elements; + array = g10_calloc( (strlen(elems1)+strlen(elems2)+1, sizeof *array ); + if( !array ) + return GCRYERR_NO_MEM; + + idx = 0; + for(s=elems1; *s; s++, idx++ ) { + l2 = gcry_sexp_find_token( list, s, 1 ); + if( !l2 ) { + g10_free( array ); + return GCRYERR_NO_OBJ; /* required parameter not found */ + } + array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG ); + if( !array[idx] ) { + g10_free( array ); + return GCRYERR_INV_OBJ; /* required parameter is invalid */ + } + } + for(s=elems2; *s; s++, idx++ ) { + l2 = gcry_sexp_find_token( list, s, 1 ); + if( !l2 ) { + g10_free( array ); + return GCRYERR_NO_OBJ; /* required parameter not found */ + } + /* FIXME: put the MPI in secure memory when needed */ + array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG ); + if( !array[idx] ) { + g10_free( array ); + return GCRYERR_INV_OBJ; /* required parameter is invalid */ + } + } + + *retarray = array; + *retalgo = algo; + + return 0; +} + +static int +sexp_to_sig( GCRY_SEXP sexp, MPI **retarray, int *retalgo) +{ + GCRY_SEXP list, l2; + const char *name; + const char *s; + size_t n; + int i, idx; + int algo; + const char *elems; + GCRY_MPI *array; + + /* check that the first element is valid */ + list = gcry_sexp_find_token( sexp, "sig-val" , 0 ); + if( !list ) + return GCRYERR_INV_OBJ; /* Does not contain a signature value object */ + list = gcry_sexp_cdr( list ); + if( !list ) + return GCRYERR_NO_OBJ; /* no cdr for the sig object */ + name = gcry_sexp_car_data( list, &n ); + if( !name ) + return GCRYERR_INV_OBJ; /* invalid structure of object */ + for(i=0; (s=sig_info_table[i].name); i++ ) { + if( strlen(s) == n && !memcmp( s, name, n ) ) + break; + } + if( !s ) + return GCRYERR_INV_PK_ALGO; /* unknown algorithm */ + algo = sig_info_table[i].algo; + elems = sig_info_table[i].elements; + array = g10_calloc( (strlen(elems)+1) , sizeof *array ); + if( !array ) + return GCRYERR_NO_MEM; + + idx = 0; + for(s=elems; *s; s++, idx++ ) { + l2 = gcry_sexp_find_token( list, s, 1 ); + if( !l2 ) { + g10_free( array ); + return GCRYERR_NO_OBJ; /* required parameter not found */ + } + array[idx] = gcry_sexp_cdr_mpi( l2, GCRYMPI_FMT_USG ); + if( !array[idx] ) { + g10_free( array ); + return GCRYERR_INV_OBJ; /* required parameter is invalid */ + } + } + + *retarray = array; + *retalgo = algo; + + return 0; +} + + + + + int gcry_pk_encrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ) { @@ -582,34 +779,146 @@ gcry_pk_decrypt( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ) return 0; } + + +/**************** + * Create a signature. + * + * Caller has to provide a secret kez as the SEXP skey and data expressed + * as a SEXP list hash with only one emelennt which should instantly be + * available as a MPI. Later versions of this functions may provide padding + * and other things depending on data. + * + * Returns: 0 or an errorcode. + * In case of 0 the function returns a new SEXP with the + * signature value; the structure of this signature depends on the + * other arguments but is always suitable to be passed to + * gcry_pk_verify + */ int -gcry_pk_sign( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP skey ) +gcry_pk_sign( GCRY_SEXP *r_sig, GCRY_SEXP s_hash, GCRY_SEXP s_skey ) { + MPI *skey, hash; + MPI *result; + int i, algo, rc; + const char *algo_name, *algo_elems; GCRY_SEXP s; - /* get the secret key */ - s = NULL; /*gcry_sexp_find_token( skey, "private-key", 0 );*/ - if( !s ) - return -1; /* no private key */ - /* ... */ + + rc = sexp_to_key( s_skey, 1, &skey, &algo ); + if( rc ) + return rc; + + /* get the name and the required size of the result array */ + for(i=0; (algo_name = sig_info_table[i].name); i++ ) { + if( sig_info_table[i].algo == algo ) + break; + } + if( !algo_name ) { + release_mpi_array( skey ); + return -4; /* oops: unknown algorithm */ + } + algo_elems = sig_info_table[i].elements; + + /* get the stuff we want to sign */ + hash = gcry_sexp_car_mpi( s_hash, 0 ); + if( !hash ) { + release_mpi_array( skey ); + return -1; /* fixme: get a real errorcode for this */ + } + result = g10_xcalloc_clear( (strlen(algo_elems)+1) , sizeof *result ); + rc = pubkey_sign( algo, result, hash, skey ); + release_mpi_array( skey ); + mpi_free( hash ); + if( rc ) { + g10_free( result ); + return rc; + } + + s = SEXP_NEW( algo_name, 0 ); + for(i=0; algo_elems[i]; i++ ) { + char tmp[2]; + tmp[0] = algo_elems[i]; + tmp[1] = 0; + s = gcry_sexp_append( s, gcry_sexp_new_name_mpi( tmp, result[i] ) ); + } + g10_free( result ); + *r_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ), s ); + gcry_sexp_dump( *r_sig ); return 0; } + +/**************** + * Verify a sgnature. Caller has to supply the public key pkey, + * the signature sig and his hashvalue data. Public key has to be + * a standard public key given as an S-Exp, sig is a S-Exp as returned + * from gcry_pk_sign and data must be an S-Exp like the one in sign too. + */ +int +gcry_pk_verify( GCRY_SEXP s_sig, GCRY_SEXP s_hash, GCRY_SEXP s_pkey ) +{ + MPI *pkey, hash, *sig; + int algo, sigalgo; + int rc; + + rc = sexp_to_key( s_pkey, 0, &pkey, &algo ); + if( rc ) + return rc; + rc = sexp_to_sig( s_sig, &sig, &sigalgo ); + if( rc ) { + release_mpi_array( pkey ); + return rc; + } + if( algo != sigalgo ) { + release_mpi_array( pkey ); + release_mpi_array( sig ); + return -1; /* fixme: add real errornumber - algo does not match */ + } + + hash = gcry_sexp_car_mpi( s_hash, 0 ); + if( !hash ) { + release_mpi_array( pkey ); + release_mpi_array( sig ); + return -1; /* fixme: get a real errorcode for this */ + } + + rc = pubkey_verify( algo, hash, sig, pkey, NULL, NULL ); + release_mpi_array( pkey ); + release_mpi_array( sig ); + mpi_free(hash); + + return rc; +} + + int -gcry_pk_verify( GCRY_SEXP *result, GCRY_SEXP data, GCRY_SEXP pkey ) +gcry_pk_ctl( int cmd, void *buffer, size_t buflen) { - /* ... */ + switch( cmd ) { + case GCRYCTL_DISABLE_ALGO: + /* this one expects a buffer pointing to an + * integer with the algo number. + */ + if( !buffer || buflen != sizeof(int) ) + return set_lasterr( GCRYERR_INV_CIPHER_ALGO ); + disable_pubkey_algo( *(int*)buffer ); + break; + + default: + return set_lasterr( GCRYERR_INV_OP ); + } return 0; } - - /**************** * Return information about the given algorithm * WHAT select the kind of information returned: * GCRYCTL_TEST_ALGO: * Returns 0 when the specified algorithm is available for use. - * buffer and nbytes must be zero. + * Buffer must be NULL, nbytes may have the address of a variable + * with the required usage of the algorithm. It may be 0 for don't + * care or a combination of the GCRY_PK_USAGE_xxx flags; * * On error the value -1 is returned and the error reason may be * retrieved by gcry_errno(). @@ -623,17 +932,24 @@ int gcry_pk_algo_info( int algo, int what, void *buffer, size_t *nbytes) { switch( what ) { - case GCRYCTL_TEST_ALGO: - if( buffer || nbytes ) { - set_lasterr( GCRYERR_INV_ARG ); - return -1; - } - if( check_pubkey_algo( algo ) ) { - set_lasterr( GCRYERR_INV_ALGO ); - return -1; + case GCRYCTL_TEST_ALGO: { + int use = nbytes? *nbytes: 0; + if( buffer ) { + set_lasterr( GCRYERR_INV_ARG ); + return -1; + } + if( check_pubkey_algo( algo, use ) ) { + set_lasterr( GCRYERR_INV_PK_ALGO ); + return -1; + } } break; + case GCRYCTL_GET_ALGO_NPKEY: return pubkey_get_npkey( algo ); + case GCRYCTL_GET_ALGO_NSKEY: return pubkey_get_nskey( algo ); + case GCRYCTL_GET_ALGO_NSIGN: return pubkey_get_nsig( algo ); + case GCRYCTL_GET_ALGO_NENCR: return pubkey_get_nenc( algo ); + default: set_lasterr( GCRYERR_INV_OP ); return -1; diff --git a/cipher/random.c b/cipher/random.c index 8ade26c11..b8a09bb5d 100644 --- a/cipher/random.c +++ b/cipher/random.c @@ -45,6 +45,7 @@ #ifdef HAVE_GETRUSAGE #include #endif +#include "g10lib.h" #include "util.h" #include "rmd.h" #include "ttyio.h" @@ -97,6 +98,7 @@ static int quick_test; static int faked_rng; +static byte *get_random_bytes( size_t nbytes, int level, int secure ); static void read_pool( byte *buffer, size_t length, int level ); static void add_randomness( const void *buffer, size_t length, int source ); static void random_poll(void); @@ -123,10 +125,10 @@ initialize(void) /* The data buffer is allocated somewhat larger, so that * we can use this extra space (which is allocated in secure memory) * as a temporary hash buffer */ - rndpool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN) - : m_alloc_clear(POOLSIZE+BLOCKLEN); - keypool = secure_alloc ? m_alloc_secure_clear(POOLSIZE+BLOCKLEN) - : m_alloc_clear(POOLSIZE+BLOCKLEN); + rndpool = secure_alloc ? g10_xcalloc_secure(1,POOLSIZE+BLOCKLEN) + : g10_xcalloc(1,POOLSIZE+BLOCKLEN); + keypool = secure_alloc ? g10_xcalloc_secure(1,POOLSIZE+BLOCKLEN) + : g10_xcalloc(1,POOLSIZE+BLOCKLEN); is_initialized = 1; cipher_modules_constructor(); } @@ -170,11 +172,11 @@ quick_random_gen( int onoff ) * for most usage, 2 is good for key generation stuff but may be very slow. */ void -randomize_buffer( byte *buffer, size_t length, int level ) +gcry_randomize( byte *buffer, size_t length, enum gcry_random_level level ) { - char *p = get_random_bits( length*8, level, 1 ); + char *p = get_random_bytes( length, level, 1 ); memcpy( buffer, p, length ); - m_free(p); + g10_free(p); } @@ -191,11 +193,10 @@ random_is_faked() * caller must free the buffer. * Note: The returned value is rounded up to bytes. */ -byte * -get_random_bits( size_t nbits, int level, int secure ) +static byte * +get_random_bytes( size_t nbytes, int level, int secure ) { byte *buf, *p; - size_t nbytes = (nbits+7)/8; if( quick_test && level > 1 ) level = 1; @@ -209,7 +210,8 @@ get_random_bits( size_t nbits, int level, int secure ) rndstats.ngetbytes2++; } - buf = secure && secure_alloc ? m_alloc_secure( nbytes ) : m_alloc( nbytes ); + buf = secure && secure_alloc ? g10_xmalloc_secure( nbytes ) + : g10_xmalloc( nbytes ); for( p = buf; nbytes > 0; ) { size_t n = nbytes > POOLSIZE? POOLSIZE : nbytes; read_pool( p, n, level ); @@ -219,6 +221,18 @@ get_random_bits( size_t nbits, int level, int secure ) return buf; } +void * +gcry_random_bytes( size_t nbytes, enum gcry_random_level level ) +{ + return get_random_bytes( nbytes, level, 0 ); +} + +void * +gcry_random_bytes_secure( size_t nbytes, enum gcry_random_level level ) +{ + return get_random_bytes( nbytes, level, 1 ); +} + /**************** * Mix the pool @@ -461,7 +475,7 @@ gather_faked( void (*add)(const void*, size_t, int), int requester, #endif } - p = buffer = m_alloc( length ); + p = buffer = g10_xmalloc( length ); n = length; #ifdef HAVE_RAND while( n-- ) @@ -471,7 +485,7 @@ gather_faked( void (*add)(const void*, size_t, int), int requester, *p++ = ((unsigned)(1 + (int) (256.0*random()/(RAND_MAX+1.0)))-1); #endif add_randomness( buffer, length, requester ); - m_free(buffer); + g10_free(buffer); return 0; /* okay */ } diff --git a/cipher/random.h b/cipher/random.h index 649325c58..9a7dd8f68 100644 --- a/cipher/random.h +++ b/cipher/random.h @@ -27,7 +27,6 @@ void random_dump_stats(void); void secure_random_alloc(void); int quick_random_gen( int onoff ); int random_is_faked(void); -void randomize_buffer( byte *buffer, size_t length, int level ); byte *get_random_bits( size_t nbits, int level, int secure ); void fast_random_poll( void ); diff --git a/cipher/rndegd.c b/cipher/rndegd.c index 7f2598f60..87d75cf89 100644 --- a/cipher/rndegd.c +++ b/cipher/rndegd.c @@ -31,6 +31,7 @@ #include #include #include "types.h" +#include "g10lib.h" #include "util.h" #include "ttyio.h" #include "dynload.h" @@ -126,7 +127,7 @@ gather_random( void (*add)(const void*, size_t, int), int requester, if( connect( fd, (struct sockaddr*)&addr, addr_len) == -1 ) g10_log_fatal("can't connect to `%s': %s\n", name, strerror(errno) ); - m_free(name); + g10_free(name); } do_restart = 0; diff --git a/cipher/rndunix.c b/cipher/rndunix.c index 46f80eab2..36482dfae 100644 --- a/cipher/rndunix.c +++ b/cipher/rndunix.c @@ -44,6 +44,8 @@ code base to be maintained */ + /* Fixme: We use plain mallocs here beucase it may be used as a module + * should be changed. * /* General includes */ diff --git a/cipher/rndw32.c b/cipher/rndw32.c index 032d666ad..d7801e391 100644 --- a/cipher/rndw32.c +++ b/cipher/rndw32.c @@ -28,6 +28,7 @@ #include #include "types.h" +#include "g10lib.h" #include "util.h" #include "dynload.h" @@ -126,7 +127,7 @@ load_and_init_winseed( void ) g10_log_info("fast buffer size=%u\n", n2); entropy_buffer_size = n1 > n2? n1: n2; - entropy_buffer = m_alloc( entropy_buffer_size ); + entropy_buffer = g10_xmalloc( entropy_buffer_size ); g10_log_info("using a buffer of size=%u\n", entropy_buffer_size ); return; diff --git a/cipher/twofish.c b/cipher/twofish.c index 182f18c49..42eed8bf2 100644 --- a/cipher/twofish.c +++ b/cipher/twofish.c @@ -27,8 +27,8 @@ #include /* for memcmp() */ #include "types.h" /* for byte and u32 typedefs */ +#include "g10lib.h" #include "util.h" -#include "errors.h" #include "dynload.h" @@ -574,7 +574,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen) /* Check key length. */ if( ( ( keylen - 16 ) | 16 ) != 16 ) - return G10ERR_WRONG_KEYLEN; + return GCRYERR_INV_KEYLEN; /* Do self-test if necessary. */ if (!initialized) { @@ -584,7 +584,7 @@ twofish_setkey (TWOFISH_context *ctx, const byte *key, const unsigned keylen) fprintf(stderr, "%s\n", selftest_failed ); } if( selftest_failed ) - return G10ERR_SELFTEST_FAILED; + return GCRYERR_SELFTEST; /* Compute the first two words of the S vector. The magic numbers are * the entries of the RS matrix, preprocessed through poly_to_exp. The diff --git a/g10/ChangeLog b/g10/ChangeLog index c7c3dc204..3ae1255af 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,46 @@ +Sat Nov 13 17:44:23 CET 1999 Werner Koch + + * mainproc.c (list_node): Print the PK algo in the --with-colon mode. + * keylist.c (list_keyblock): Ditto. + + * misc.c (pull_in_libs): Removed pull in of g10c. + + * misc.c (map_gcry_rc): Removed here and chnaged all users. + + * getkey.c: Replaced check_pubkey_algo by openpgp_pk_test_algo. + * import.c (delete_inv_parts): Ditto. + * pkclist.c: Ditto. + * skclist.c: Ditto. + * pubkey-enc.c: Ditto. + + * g10.c (main): Replaced the function to diable PK algos. + + * g10.c (main): Replaced get_random_bits by gcry_random_bytes. + * seskey.c (encode_session_key): Likewise. + (make_session_key): Renamed randomize_buffer to gcry_randomize + and use the GCRY_xxx_RANDOM constants. + * cipher.c (write_header): Ditto. + * passphrase.c (hash_passphrase): Ditto. + * seckey-cert.c (protect_secret_key): Ditto. + + * getkey.c (find_by_name): Replaced rmd160_hash_buffer + by gcry_md_hash_buffer. + * keyedit.c (show_prefs): Ditto. + * keylist.c (list_keyblock): Ditto. + * trustdb.c (print_uid_from_keyblock): Ditto. + (make_uid_records): Ditto. + + * skclist.c (build_sk_list): Removed the test on faked RNGs. + (is_insecure): Removed. + * g10.c (--quick-random): Removed this option. + + * Replaced all PUBKEY_ALGO_xxx by GCRY_PK_xxxx. + + * misc.c (pubkey_algo_npkey): New as a wrapper around the gcry fucntion. + (pubkey_algo_nskey): Ditto. + (pubkey_algo_nsig): Ditto. + (pubkey_algo_nenc): Ditto. + Tue Oct 26 20:03:44 CEST 1999 Werner Koch * Makefile.am (basicdefs.h): Added. diff --git a/g10/Makefile.am b/g10/Makefile.am index 8e0ac443f..299ea5131 100644 --- a/g10/Makefile.am +++ b/g10/Makefile.am @@ -4,8 +4,8 @@ INCLUDES = -I$(top_srcdir)/include -I$(top_srcdir)/intl EXTRA_DIST = OPTIONS pubring.asc options.skel OMIT_DEPENDENCIES = zlib.h zconf.h LDFLAGS = @LDFLAGS@ @DYNLINK_LDFLAGS@ -needed_libs = ../cipher/libcipher.la ../mpi/libmpi.la ../util/libutil.la \ - ../gcrypt/libgcrypt.la +##needed_libs = ../util/libutil.la ../gcrypt/libgcrypt.la +needed_libs = #noinst_PROGRAMS = gpgd bin_PROGRAMS = gpg diff --git a/g10/build-packet.c b/g10/build-packet.c index 5e56c2048..eb2608a44 100644 --- a/g10/build-packet.c +++ b/g10/build-packet.c @@ -32,6 +32,7 @@ #include "cipher.h" #include "memory.h" #include "options.h" +#include "main.h" static int do_comment( IOBUF out, int ctb, PKT_comment *rem ); diff --git a/g10/cipher.c b/g10/cipher.c index c0f10ff19..162bbc35f 100644 --- a/g10/cipher.c +++ b/g10/cipher.c @@ -69,7 +69,7 @@ write_header( cipher_filter_context_t *cfx, IOBUF a ) if( blocksize < 8 || blocksize > 16 ) log_fatal("unsupported blocksize %d\n", blocksize ); nprefix = blocksize; - randomize_buffer( temp, nprefix, 1 ); + gcry_randomize( temp, nprefix, GCRY_STRONG_RANDOM ); temp[nprefix] = temp[nprefix-2]; temp[nprefix+1] = temp[nprefix-1]; print_cipher_algo_note( cfx->dek->algo ); diff --git a/g10/encode.c b/g10/encode.c index fe054fdab..e87616d70 100644 --- a/g10/encode.c +++ b/g10/encode.c @@ -252,7 +252,7 @@ encode_crypt( const char *filename, STRLIST remusr ) memset( &tfx, 0, sizeof tfx); init_packet(&pkt); - if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC)) ) + if( (rc=build_pk_list( remusr, &pk_list, GCRY_PK_USAGE_ENCR)) ) return rc; /* prepare iobufs */ diff --git a/g10/encr-data.c b/g10/encr-data.c index 1dd6e0e77..7f5b16392 100644 --- a/g10/encr-data.c +++ b/g10/encr-data.c @@ -104,7 +104,6 @@ decrypt_data( void *procctx, PKT_encrypted *ed, DEK *dek ) } else if( rc ) { log_error("key setup failed: %s\n", gcry_strerror(rc) ); - rc = map_gcry_rc(rc); goto leave; } diff --git a/g10/free-packet.c b/g10/free-packet.c index 0a61e222c..4c533d859 100644 --- a/g10/free-packet.c +++ b/g10/free-packet.c @@ -31,6 +31,7 @@ #include "cipher.h" #include "memory.h" #include "options.h" +#include "main.h" void free_symkey_enc( PKT_symkey_enc *enc ) diff --git a/g10/g10.c b/g10/g10.c index e1e8d885a..8ab8493c3 100644 --- a/g10/g10.c +++ b/g10/g10.c @@ -131,7 +131,6 @@ enum cmd_and_opt_values { aNull = 0, oDigestAlgo, oCompressAlgo, oPasswdFD, - oQuickRandom, oNoVerbose, oTrustDBName, oNoSecmemWarn, @@ -301,7 +300,6 @@ static ARGPARSE_OPTS opts[] = { { oKOption, NULL, 0, "@"}, { oPasswdFD, "passphrase-fd",1, "@" }, { aDeleteSecretKey, "delete-secret-key",0, "@" }, - { oQuickRandom, "quick-random", 0, "@"}, { oNoVerbose, "no-verbose", 0, "@"}, { oTrustDBName, "trustdb-name", 2, "@" }, { oNoSecmemWarn, "no-secmem-warning", 0, "@" }, /* used only by regression tests */ @@ -362,6 +360,13 @@ static void print_mds( const char *fname, int algo ); static void add_notation_data( const char *string ); static int check_policy_url( const char *s ); +static int +our_pk_test_algo( int algo ) +{ + return openpgp_pk_test_algo( algo, 0 ); +} + + const char * strusage( int level ) { @@ -395,7 +400,7 @@ strusage( int level ) case 33: if( !pubkeys ) pubkeys = build_list("Pubkey: ", gcry_pk_algo_name, - openpgp_pk_test_algo ); + our_pk_test_algo ); p = pubkeys; break; case 34: @@ -745,7 +750,6 @@ main( int argc, char **argv ) case oNoGreeting: nogreeting = 1; break; case oNoVerbose: g10_opt_verbose = 0; opt.verbose = 0; opt.list_sigs=0; break; - case oQuickRandom: quick_random_gen(1); break; case oNoComment: opt.no_comment=1; break; case oNoVersion: opt.no_version=1; break; case oEmitVersion: opt.no_version=0; break; @@ -858,8 +862,11 @@ main( int argc, char **argv ) &algo, sizeof algo ); } break; - case oDisablePubkeyAlgo: - disable_pubkey_algo( gcry_pk_map_name(pargs.r.ret_str) ); + case oDisablePubkeyAlgo: { + int algo = gcry_pk_map_name(pargs.r.ret_str); + gcry_pk_ctl( GCRYCTL_DISABLE_ALGO, + &algo, sizeof algo ); + } break; case oAllowNonSelfsignedUID: opt.allow_non_selfsigned_uid = 1; @@ -1274,6 +1281,7 @@ main( int argc, char **argv ) case aPrimegen: { int mode = argc < 2 ? 0 : atoi(*argv); + #if 0 /* FIXME: disabled until we have an API to create primes */ if( mode == 1 && argc == 2 ) { mpi_print( stdout, generate_public_prime( atoi(argv[1]) ), 1); } @@ -1300,6 +1308,7 @@ main( int argc, char **argv ) mpi_free(g); } else + #endif wrong_args("--gen-prime mode bits [qbits] "); putchar('\n'); } @@ -1318,7 +1327,7 @@ main( int argc, char **argv ) byte *p; size_t n = !endless && count < 100? count : 100; - p = get_random_bits( n*8, level, 0); + p = gcry_random_bytes( n, level ); fwrite( p, n, 1, stdout ); m_free(p); if( !endless ) @@ -1457,10 +1466,10 @@ g10_exit( int rc ) { if( opt.debug & DBG_MEMSTAT_VALUE ) { m_print_stats("on exit"); - random_dump_stats(); + gcry_control( GCRYCTL_DUMP_RANDOM_STATS ); } if( opt.debug ) - secmem_dump_stats(); + gcry_control( GCRYCTL_DUMP_SECMEM_STATS ); secmem_term(); rc = rc? rc : log_get_errorcount(0)? 2 : g10_errors_seen? 1 : 0; diff --git a/g10/getkey.c b/g10/getkey.c index fb5f1bc3e..a94b5de48 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "util.h" #include "packet.h" #include "memory.h" @@ -185,7 +186,7 @@ cache_public_key( PKT_public_key *pk ) return; if( is_ELGAMAL(pk->pubkey_algo) - || pk->pubkey_algo == PUBKEY_ALGO_DSA + || pk->pubkey_algo == GCRY_PK_DSA || is_RSA(pk->pubkey_algo) ) { keyid_from_pk( pk, keyid ); } @@ -1269,7 +1270,7 @@ find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name, || pk->pubkey_algo == kk->pkt->pkt.public_key->pubkey_algo) && ( !pk->pubkey_usage - || !check_pubkey_algo2( + || !openpgp_pk_test_algo( kk->pkt->pkt.public_key->pubkey_algo, pk->pubkey_usage )) ) @@ -1279,7 +1280,7 @@ find_by_name( KBNODE keyblock, PKT_public_key *pk, const char *name, u32 aki[2]; keyid_from_pk( kk->pkt->pkt.public_key, aki ); cache_user_id( k->pkt->pkt.user_id, aki ); - rmd160_hash_buffer( namehash, + gcry_md_hash_buffer( GCRY_MD_RMD160, namehash, k->pkt->pkt.user_id->name, k->pkt->pkt.user_id->len ); *use_namehash = 1; @@ -1312,7 +1313,7 @@ find_by_name_sk( KBNODE keyblock, PKT_secret_key *sk, const char *name, || sk->pubkey_algo == kk->pkt->pkt.secret_key->pubkey_algo) && ( !sk->pubkey_usage - || !check_pubkey_algo2( + || !openpgp_pk_test_algo( kk->pkt->pkt.secret_key->pubkey_algo, sk->pubkey_usage )) ) @@ -1530,7 +1531,7 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash, } else { if( primary && pk->pubkey_usage - && check_pubkey_algo2( k->pkt->pkt.public_key->pubkey_algo, + && openpgp_pk_test_algo( k->pkt->pkt.public_key->pubkey_algo, pk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) { /* if the usage is not correct, try to use a subkey */ KBNODE save_k = k; @@ -1538,12 +1539,12 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash, k = NULL; /* kludge for pgp 5: which doesn't accept type 20: * try to use a type 16 subkey instead */ - if( pk->pubkey_usage == PUBKEY_USAGE_ENC ) { + if( pk->pubkey_usage == GCRY_PK_USAGE_ENCR ) { for( k = save_k; k; k = k->next ) { if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY && k->pkt->pkt.public_key->pubkey_algo - == PUBKEY_ALGO_ELGAMAL_E - && !check_pubkey_algo2( + == GCRY_PK_ELG_E + && !openpgp_pk_test_algo( k->pkt->pkt.public_key->pubkey_algo, pk->pubkey_usage ) ) break; @@ -1553,7 +1554,7 @@ finish_lookup( KBNODE keyblock, PKT_public_key *pk, KBNODE k, byte *namehash, if( !k ) { for(k = save_k ; k; k = k->next ) { if( k->pkt->pkttype == PKT_PUBLIC_SUBKEY - && !check_pubkey_algo2( + && !openpgp_pk_test_algo( k->pkt->pkt.public_key->pubkey_algo, pk->pubkey_usage ) ) break; @@ -1586,7 +1587,7 @@ finish_lookup_sk( KBNODE keyblock, PKT_secret_key *sk, KBNODE k, int primary ) } else { if( primary && sk->pubkey_usage - && check_pubkey_algo2( k->pkt->pkt.secret_key->pubkey_algo, + && openpgp_pk_test_algo( k->pkt->pkt.secret_key->pubkey_algo, sk->pubkey_usage ) == G10ERR_WR_PUBKEY_ALGO ) { /* if the usage is not correct, try to use a subkey */ KBNODE save_k = k; @@ -1594,12 +1595,12 @@ finish_lookup_sk( KBNODE keyblock, PKT_secret_key *sk, KBNODE k, int primary ) k = NULL; /* kludge for pgp 5: which doesn't accept type 20: * try to use a type 16 subkey instead */ - if( sk->pubkey_usage == PUBKEY_USAGE_ENC ) { + if( sk->pubkey_usage == GCRY_PK_USAGE_ENCR ) { for( k = save_k; k; k = k->next ) { if( k->pkt->pkttype == PKT_SECRET_SUBKEY && k->pkt->pkt.secret_key->pubkey_algo - == PUBKEY_ALGO_ELGAMAL_E - && !check_pubkey_algo2( + == GCRY_PK_ELG_E + && !openpgp_pk_test_algo( k->pkt->pkt.secret_key->pubkey_algo, sk->pubkey_usage ) ) break; @@ -1609,7 +1610,7 @@ finish_lookup_sk( KBNODE keyblock, PKT_secret_key *sk, KBNODE k, int primary ) if( !k ) { for(k = save_k ; k; k = k->next ) { if( k->pkt->pkttype == PKT_SECRET_SUBKEY - && !check_pubkey_algo2( + && !openpgp_pk_test_algo( k->pkt->pkt.secret_key->pubkey_algo, sk->pubkey_usage ) ) break; diff --git a/g10/gpgd.c b/g10/gpgd.c index 8f99a0533..d68e5a843 100644 --- a/g10/gpgd.c +++ b/g10/gpgd.c @@ -85,7 +85,7 @@ strusage( int level ) case 33: if( !pubkeys ) pubkeys = build_list("Supported pubkeys: ", pubkey_algo_to_string, - check_pubkey_algo ); + openpgp_pk_test_algo ); p = pubkeys; break; case 34: diff --git a/g10/import.c b/g10/import.c index 92cd93c24..368ea8b75 100644 --- a/g10/import.c +++ b/g10/import.c @@ -831,8 +831,8 @@ delete_inv_parts( const char *fname, KBNODE keyblock, u32 *keyid ) } } else if( node->pkt->pkttype == PKT_SIGNATURE - && check_pubkey_algo( node->pkt->pkt.signature->pubkey_algo) - && node->pkt->pkt.signature->pubkey_algo != PUBKEY_ALGO_RSA ) + && openpgp_pk_test_algo( node->pkt->pkt.signature->pubkey_algo, 0) + && node->pkt->pkt.signature->pubkey_algo != GCRY_PK_RSA ) delete_kbnode( node ); /* build_packet() can't handle this */ else if( node->pkt->pkttype == PKT_SIGNATURE && (p = parse_sig_subpkt2( node->pkt->pkt.signature, diff --git a/g10/keyedit.c b/g10/keyedit.c index 8daa7c4f5..91bba4723 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1005,7 +1005,7 @@ show_prefs( KBNODE keyblock, PKT_user_id *uid ) return; } - rmd160_hash_buffer( namehash, uid->name, uid->len ); + gcry_md_hash_buffer( GCRY_MD_RMD160, namehash, uid->name, uid->len ); p = get_pref_data( pk->local_id, namehash, &n ); if( !p ) diff --git a/g10/keygen.c b/g10/keygen.c index 0ed07e690..b4da909f8 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -280,7 +280,7 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, if( nbits > 1024 ) nbits = 1024; - rc = pubkey_generate( PUBKEY_ALGO_DSA, nbits, skey, &factors ); + rc = pubkey_generate( GCRY_PK_DSA, nbits, skey, &factors ); if( rc ) { log_error("pubkey_generate failed: %s\n", g10_errstr(rc) ); return rc; @@ -293,7 +293,7 @@ gen_dsa(unsigned nbits, KBNODE pub_root, KBNODE sec_root, DEK *dek, if( expireval ) { sk->expiredate = pk->expiredate = sk->timestamp + expireval; } - sk->pubkey_algo = pk->pubkey_algo = PUBKEY_ALGO_DSA; + sk->pubkey_algo = pk->pubkey_algo = GCRY_PK_DSA; pk->pkey[0] = mpi_copy( skey[0] ); pk->pkey[1] = mpi_copy( skey[1] ); pk->pkey[2] = mpi_copy( skey[2] ); @@ -407,21 +407,21 @@ ask_algo( int *ret_v4, int addmode ) else if( algo == 4 ) { if( cpr_get_answer_is_yes("keygen.algo.elg_se",_( "Do you really want to create a sign and encrypt key? "))) { - algo = PUBKEY_ALGO_ELGAMAL; + algo = GCRY_PK_ELG; break; } } else if( algo == 3 && addmode ) { - algo = PUBKEY_ALGO_ELGAMAL_E; + algo = GCRY_PK_ELG_E; break; } else if( algo == 2 ) { - algo = PUBKEY_ALGO_DSA; + algo = GCRY_PK_DSA; break; } #if 0 else if( algo == 5 ) { - algo = PUBKEY_ALGO_ELGAMAL_E; + algo = GCRY_PK_ELG_E; *ret_v4 = 0; break; } @@ -450,7 +450,7 @@ ask_keysize( int algo ) cpr_kill_prompt(); nbits = *answer? atoi(answer): 1024; m_free(answer); - if( algo == PUBKEY_ALGO_DSA && (nbits < 512 || nbits > 1024) ) + if( algo == GCRY_PK_DSA && (nbits < 512 || nbits > 1024) ) tty_printf(_("DSA only allows keysizes from 512 to 1024\n")); else if( nbits < 768 ) tty_printf(_("keysize too small; 768 is smallest value allowed.\n")); @@ -487,7 +487,7 @@ ask_keysize( int algo ) break; } tty_printf(_("Requested keysize is %u bits\n"), nbits ); - if( algo == PUBKEY_ALGO_DSA && (nbits % 64) ) { + if( algo == GCRY_PK_DSA && (nbits % 64) ) { nbits = ((nbits + 63) / 64) * 64; tty_printf(_("rounded up to %u bits\n"), nbits ); } @@ -788,10 +788,10 @@ do_create( int algo, unsigned nbits, KBNODE pub_root, KBNODE sec_root, "disks) during the prime generation; this gives the random number\n" "generator a better chance to gain enough entropy.\n") ); - if( algo == PUBKEY_ALGO_ELGAMAL || algo == PUBKEY_ALGO_ELGAMAL_E ) + if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) rc = gen_elg(algo, nbits, pub_root, sec_root, dek, s2k, sk, expiredate, v4_packet? 4:3 ); - else if( algo == PUBKEY_ALGO_DSA ) + else if( algo == GCRY_PK_DSA ) rc = gen_dsa(nbits, pub_root, sec_root, dek, s2k, sk, expiredate); else BUG(); @@ -859,7 +859,7 @@ generate_keypair() algo = ask_algo( &v4, 0 ); if( !algo ) { - algo = PUBKEY_ALGO_ELGAMAL_E; + algo = GCRY_PK_ELG_E; both = 1; tty_printf(_("DSA keypair will have 1024 bits.\n")); } @@ -890,7 +890,7 @@ generate_keypair() sec_root = make_comment_node("#"); delete_kbnode(sec_root); if( both ) - rc = do_create( PUBKEY_ALGO_DSA, 1024, pub_root, sec_root, + rc = do_create( GCRY_PK_DSA, 1024, pub_root, sec_root, dek, s2k, &sk, expire, 1); else rc = do_create( algo, nbits, pub_root, sec_root, @@ -956,7 +956,7 @@ generate_keypair() log_error("can't write secret key: %s\n", g10_errstr(rc) ); else { tty_printf(_("public and secret key created and signed.\n") ); - if( algo == PUBKEY_ALGO_DSA ) + if( algo == GCRY_PK_DSA ) tty_printf(_("Note that this key cannot be used for " "encryption. You may want to use\n" "the command \"--edit-key\" to generate a " diff --git a/g10/keyid.c b/g10/keyid.c index b4d745a7c..0c82aa193 100644 --- a/g10/keyid.c +++ b/g10/keyid.c @@ -38,12 +38,12 @@ int pubkey_letter( int algo ) { switch( algo ) { - case PUBKEY_ALGO_RSA: return 'R' ; - case PUBKEY_ALGO_RSA_E: return 'r' ; - case PUBKEY_ALGO_RSA_S: return 's' ; - case PUBKEY_ALGO_ELGAMAL_E: return 'g'; - case PUBKEY_ALGO_ELGAMAL: return 'G' ; - case PUBKEY_ALGO_DSA: return 'D' ; + case GCRY_PK_RSA: return 'R' ; + case GCRY_PK_RSA_E: return 'r' ; + case GCRY_PK_RSA_S: return 's' ; + case GCRY_PK_ELG_E: return 'g'; + case GCRY_PK_ELG: return 'G' ; + case GCRY_PK_DSA: return 'D' ; default: return '?'; } } @@ -54,9 +54,9 @@ do_fingerprint_md( PKT_public_key *pk ) { GCRY_MD_HD md; unsigned n; - unsigned nb[PUBKEY_MAX_NPKEY]; - unsigned nn[PUBKEY_MAX_NPKEY]; - byte *pp[PUBKEY_MAX_NPKEY]; + unsigned nb[GNUPG_MAX_NPKEY]; + unsigned nn[GNUPG_MAX_NPKEY]; + byte *pp[GNUPG_MAX_NPKEY]; int i; int npkey = pubkey_get_npkey( pk->pubkey_algo ); diff --git a/g10/keylist.c b/g10/keylist.c index 91a13afaf..53e88f468 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -243,7 +243,7 @@ list_keyblock( KBNODE keyblock, int secret ) byte namehash[20]; if( pk && !ulti_hack ) { - rmd160_hash_buffer( namehash, + gcry_md_hash_buffer( GCRY_MD_RMD160, namehash, node->pkt->pkt.user_id->name, node->pkt->pkt.user_id->len ); trustletter = query_trust_info( pk, namehash ); @@ -394,7 +394,8 @@ list_keyblock( KBNODE keyblock, int secret ) putchar(':'); if( sigrc != ' ' ) putchar(sigrc); - printf(":::%08lX%08lX:%s::::", (ulong)sig->keyid[0], + printf("::%d:%08lX%08lX:%s::::", sig->pubkey_algo, + (ulong)sig->keyid[0], (ulong)sig->keyid[1], datestr_from_sig(sig)); } else diff --git a/g10/main.h b/g10/main.h index 4ccc2f658..dc5eb32c7 100644 --- a/g10/main.h +++ b/g10/main.h @@ -56,9 +56,15 @@ u16 checksum_mpi_counted_nbits( MPI a ); u32 buffer_to_u32( const byte *buffer ); int openpgp_cipher_test_algo( int algo ); -int openpgp_pk_test_algo( int algo ); +int openpgp_pk_test_algo( int algo, unsigned int usage_flags ); int openpgp_md_test_algo( int algo ); +int pubkey_get_npkey( int algo ); +int pubkey_get_nskey( int algo ); +int pubkey_get_nsig( int algo ); +int pubkey_get_nenc( int algo ); + + /*-- helptext.c --*/ void display_online_help( const char *keyword ); diff --git a/g10/mainproc.c b/g10/mainproc.c index 98034bec3..db43e50b3 100644 --- a/g10/mainproc.c +++ b/g10/mainproc.c @@ -1,4 +1,4 @@ -/* maPPPPinproc.c - handle packets +/* mainproc.c - handle packets * Copyright (C) 1998, 1999 Free Software Foundation, Inc. * * This file is part of GnuPG. @@ -221,7 +221,7 @@ proc_pubkey_enc( CTX c, PACKET *pkt ) if( is_ELGAMAL(enc->pubkey_algo) - || enc->pubkey_algo == PUBKEY_ALGO_DSA + || enc->pubkey_algo == GCRY_PK_DSA || is_RSA(enc->pubkey_algo) ) { if ( !c->dek && ((!enc->keyid[0] && !enc->keyid[1]) || !seckey_available( enc->keyid )) ) { @@ -830,7 +830,8 @@ list_node( CTX c, KBNODE node ) putchar(':'); if( sigrc != ' ' ) putchar(sigrc); - printf(":::%08lX%08lX:%s::::", (ulong)sig->keyid[0], + printf("::%d:%08lX%08lX:%s::::", sig->pubkey_algo, + (ulong)sig->keyid[0], (ulong)sig->keyid[1], datestr_from_sig(sig)); } else @@ -1194,7 +1195,7 @@ proc_tree( CTX c, KBNODE node ) BUG(); } else if( sig->digest_algo == DIGEST_ALGO_SHA1 - && sig->pubkey_algo == PUBKEY_ALGO_DSA + && sig->pubkey_algo == GCRY_PK_DSA && sig->sig_class == 0x01 ) { /* enable the workaround also for pgp5 when the detached * signature has been created in textmode */ diff --git a/g10/misc.c b/g10/misc.c index fb9d62f1f..a3ed841db 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -49,7 +49,6 @@ volatile pull_in_libs(void) { g10m_revision_string(0); - g10c_revision_string(0); g10u_revision_string(0); } @@ -253,20 +252,6 @@ print_digest_algo_note( int algo ) } - -/**************** - * Map errors retuned by libgcrypt to those used by GnuPG. - */ -int -map_gcry_rc( int rc ) -{ - switch( rc ) { - case 0: return 0; - default: return G10ERR_GENERAL; - } -} - - /**************** * Wrapper around the libgcrypt function with addional checks on * openPGP contrainst for the algo ID. @@ -275,23 +260,55 @@ int openpgp_cipher_test_algo( int algo ) { if( algo < 0 || algo > 110 ) - return GCRYERR_INV_ALGO; + return GCRYERR_INV_CIPHER_ALGO; return gcry_cipher_test_algo(algo); } int -openpgp_pk_test_algo( int algo ) +openpgp_pk_test_algo( int algo, unsigned int usage_flags ) { + size_t n = usage_flags; + if( algo < 0 || algo > 110 ) - return GCRYERR_INV_ALGO; - return gcry_pk_test_algo(algo); + return GCRYERR_INV_PK_ALGO; + return gcry_pk_algo_info( algo, GCRYCTL_TEST_ALGO, NULL, &n ); } + int openpgp_md_test_algo( int algo ) { if( algo < 0 || algo > 110 ) - return GCRYERR_INV_ALGO; + return GCRYERR_INV_MD_ALGO; return gcry_md_test_algo(algo); } + +int +pubkey_get_npkey( int algo ) +{ + int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NPKEY, NULL, 0 ); + return n > 0? n : 0; +} + +int +pubkey_get_nskey( int algo ) +{ + int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSKEY, NULL, 0 ); + return n > 0? n : 0; +} + +int +pubkey_get_nsig( int algo ) +{ + int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NSIGN, NULL, 0 ); + return n > 0? n : 0; +} + +int +pubkey_get_nenc( int algo ) +{ + int n = gcry_pk_algo_info( algo, GCRYCTL_GET_ALGO_NENCR, NULL, 0 ); + return n > 0? n : 0; +} + diff --git a/g10/packet.h b/g10/packet.h index f3f8cbd9d..17893875f 100644 --- a/g10/packet.h +++ b/g10/packet.h @@ -27,6 +27,12 @@ #include "cipher.h" #include "filter.h" + +#define GNUPG_MAX_NPKEY 4 +#define GNUPG_MAX_NSKEY 6 +#define GNUPG_MAX_NSIG 2 +#define GNUPG_MAX_NENC 2 + #define DEBUG_PARSE_PACKET 1 typedef enum { @@ -72,7 +78,7 @@ typedef struct { byte version; byte pubkey_algo; /* algorithm used for public key scheme */ byte throw_keyid; - MPI data[PUBKEY_MAX_NENC]; + MPI data[GNUPG_MAX_NENC]; } PKT_pubkey_enc; @@ -102,7 +108,7 @@ typedef struct { byte *hashed_data; /* all subpackets with hashed data (v4 only) */ byte *unhashed_data; /* ditto for unhashed data */ byte digest_start[2]; /* first 2 bytes of the digest */ - MPI data[PUBKEY_MAX_NSIG]; + MPI data[GNUPG_MAX_NSIG]; } PKT_signature; @@ -122,7 +128,7 @@ typedef struct { ulong local_id; /* internal use, valid if > 0 */ u32 keyid[2]; /* calculated by keyid_from_pk() */ byte *namehash; /* if != NULL: found by this name */ - MPI pkey[PUBKEY_MAX_NPKEY]; + MPI pkey[GNUPG_MAX_NPKEY]; } PKT_public_key; typedef struct { @@ -143,7 +149,7 @@ typedef struct { byte ivlen; /* used length of the iv */ byte iv[16]; /* initialization vector for CFB mode */ } protect; - MPI skey[PUBKEY_MAX_NSKEY]; + MPI skey[GNUPG_MAX_NSKEY]; u16 csum; /* checksum */ } PKT_secret_key; diff --git a/g10/passphrase.c b/g10/passphrase.c index 46527d8f5..49b7a60c2 100644 --- a/g10/passphrase.c +++ b/g10/passphrase.c @@ -254,7 +254,7 @@ hash_passphrase( DEK *dek, char *pw, STRING2KEY *s2k, int create ) ulong count = len2; if( create && !pass ) { - randomize_buffer(s2k->salt, 8, 1); + gcry_randomize(s2k->salt, 8, GCRY_STRONG_RANDOM ); if( s2k->mode == 3 ) s2k->count = 96; /* 65536 iterations */ } diff --git a/g10/pkclist.c b/g10/pkclist.c index 7559b1145..6eae1f024 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -24,6 +24,7 @@ #include #include #include +#include #include "options.h" #include "packet.h" @@ -687,14 +688,14 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) for( rov = remusr; rov; rov = rov->next ) { if( !(rov->flags & 1) ) any_recipients = 1; - else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { + else if( (use & GCRY_PK_USAGE_ENCR) && !opt.no_encrypt_to ) { pk = m_alloc_clear( sizeof *pk ); pk->pubkey_usage = use; if( (rc = get_pubkey_byname( NULL, pk, rov->d, NULL )) ) { free_public_key( pk ); pk = NULL; log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) { + else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) { /* Skip the actual key if the key is already present * in the list */ @@ -750,7 +751,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) rc = get_pubkey_byname( NULL, pk, answer, NULL ); if( rc ) tty_printf(_("No such user ID.\n")); - else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { + else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) { if( have_def_rec ) { if (key_present_in_pk_list(pk_list, pk) == 0) { free_public_key(pk); pk = NULL; @@ -815,7 +816,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) rc = get_pubkey_byname( NULL, pk, def_rec, NULL ); if( rc ) log_error(_("unknown default recipient `%s'\n"), def_rec ); - else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { + else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use)) ) { PK_LIST r = m_alloc( sizeof *r ); r->pk = pk; pk = NULL; r->next = pk_list; @@ -841,7 +842,7 @@ build_pk_list( STRLIST remusr, PK_LIST *ret_pk_list, unsigned use ) free_public_key( pk ); pk = NULL; log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use )) ) { + else if( !(rc=openpgp_pk_test_algo(pk->pubkey_algo, use )) ) { int trustlevel; rc = check_trust( pk, &trustlevel, NULL, NULL, NULL ); diff --git a/g10/pubkey-enc.c b/g10/pubkey-enc.c index 67bb50994..f11e6f12a 100644 --- a/g10/pubkey-enc.c +++ b/g10/pubkey-enc.c @@ -51,7 +51,7 @@ get_session_key( PKT_pubkey_enc *k, DEK *dek ) if( is_RSA(k->pubkey_algo) ) /* warn about that */ write_status(STATUS_RSA_OR_IDEA); - rc = check_pubkey_algo( k->pubkey_algo ); + rc = openpgp_pk_test_algo( k->pubkey_algo, 0 ); if( rc ) goto leave; @@ -149,7 +149,7 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid ) dek->keylen = nframe - (n+1) - 2; dek->algo = frame[n++]; - if( dek->algo == CIPHER_ALGO_IDEA ) + if( dek->algo == GCRY_CIPHER_IDEA ) write_status(STATUS_RSA_OR_IDEA); rc = openpgp_cipher_test_algo( dek->algo ); if( rc ) { @@ -180,14 +180,14 @@ get_it( PKT_pubkey_enc *k, DEK *dek, PKT_secret_key *sk, u32 *keyid ) log_error("public key problem: %s\n", g10_errstr(rc) ); else if( !pk->local_id && query_trust_record(pk) ) log_error("can't check algorithm against preferences\n"); - else if( dek->algo != CIPHER_ALGO_3DES + else if( dek->algo != GCRY_CIPHER_3DES && !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, dek->algo ) ) { /* Don't print a note while we are not on verbose mode, * the cipher is blowfish and the preferences have twofish * listed */ - if( opt.verbose || dek->algo != CIPHER_ALGO_BLOWFISH + if( opt.verbose || dek->algo != GCRY_CIPHER_BLOWFISH || !is_algo_in_prefs( pk->local_id, PREFTYPE_SYM, - CIPHER_ALGO_TWOFISH ) ) + GCRY_CIPHER_TWOFISH ) ) log_info(_( "NOTE: cipher algorithm %d not found in preferences\n"), dek->algo ); diff --git a/g10/seckey-cert.c b/g10/seckey-cert.c index c153782bf..a0e41eea9 100644 --- a/g10/seckey-cert.c +++ b/g10/seckey-cert.c @@ -258,10 +258,11 @@ protect_secret_key( PKT_secret_key *sk, DEK *dek ) } assert( sk->protect.ivlen <= DIM(sk->protect.iv) ); - randomize_buffer(sk->protect.iv, sk->protect.ivlen, 1); + gcry_randomize(sk->protect.iv, sk->protect.ivlen, + GCRY_STRONG_RANDOM); gcry_cipher_setiv( cipher_hd, sk->protect.iv, sk->protect.ivlen ); if( sk->version >= 4 ) { - #define NMPIS (PUBKEY_MAX_NSKEY - PUBKEY_MAX_NPKEY) + #define NMPIS (GNUPG_MAX_NSKEY - GNUPG_MAX_NPKEY) byte *bufarr[NMPIS]; unsigned narr[NMPIS]; unsigned nbits[NMPIS]; diff --git a/g10/seskey.c b/g10/seskey.c index db8f6c62c..19f40636f 100644 --- a/g10/seskey.c +++ b/g10/seskey.c @@ -51,7 +51,7 @@ make_session_key( DEK *dek ) BUG(); } - randomize_buffer( dek->key, dek->keylen, 1 ); + gcry_randomize( dek->key, dek->keylen, GCRY_STRONG_RANDOM ); for(i=0; i < 16; i++ ) { rc = gcry_cipher_setkey( chd, dek->key, dek->keylen ); if( !rc ) { @@ -62,7 +62,7 @@ make_session_key( DEK *dek ) BUG(); log_info(_("weak key created - retrying\n") ); /* Renew the session key until we get a non-weak key. */ - randomize_buffer( dek->key, dek->keylen, 1 ); + gcry_randomize( dek->key, dek->keylen, GCRY_STRONG_RANDOM ); } log_fatal(_( "cannot avoid weak key for symmetric cipher; tried %d times!\n"), @@ -116,7 +116,7 @@ encode_session_key( DEK *dek, unsigned nbits ) frame[n++] = 2; i = nframe - 6 - dek->keylen; assert( i > 0 ); - p = get_random_bits( i*8, 1, 1 ); + p = gcry_random_bytes_secure( i, GCRY_STRONG_RANDOM ); /* replace zero bytes by new values */ for(;;) { int j, k; @@ -129,7 +129,7 @@ encode_session_key( DEK *dek, unsigned nbits ) if( !k ) break; /* okay: no zero bytes */ k += k/128; /* better get some more */ - pp = get_random_bits( k*8, 1, 1); + pp = gcry_random_bytes_secure( k, GCRY_STRONG_RANDOM); for(j=0; j < i && k ; j++ ) if( !p[j] ) p[j] = pp[--k]; @@ -197,7 +197,7 @@ encode_md_value( int pubkey_algo, GCRY_MD_HD md, int hash_algo, unsigned nbits ) int algo = hash_algo? hash_algo : gcry_md_get_algo(md); MPI frame; - if( pubkey_algo == PUBKEY_ALGO_DSA ) { + if( pubkey_algo == GCRY_PK_DSA ) { frame = gcry_md_is_secure(md)? mpi_alloc_secure( (gcry_md_get_algo_dlen(hash_algo) +BYTES_PER_MPI_LIMB-1) / BYTES_PER_MPI_LIMB ) diff --git a/g10/sig-check.c b/g10/sig-check.c index 972c8778d..03477b537 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -46,6 +46,84 @@ static int do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest ); +/**************** + * Emulate our old PK interface here - sometime in the future we might + * change the internal design to directly fit to libgcrypt. + */ +static int +pk_verify( int algo, MPI hash, MPI *data, MPI *pkey, + int (*cmp)(void *, MPI), void *opaque ) +{ + GCRY_SEXP s_sig, s_hash, s_pkey; + int rc; + + /* forget about cmp and opaque - we never used it */ + + /* make a sexp from pkey */ + if( algo == GCRY_PK_DSA ) { + s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 10 ), + gcry_sexp_vlist( SEXP_NEW( "dsa", 3 ), + gcry_sexp_new_name_mpi( "p", pkey[0] ), + gcry_sexp_new_name_mpi( "q", pkey[1] ), + gcry_sexp_new_name_mpi( "g", pkey[2] ), + gcry_sexp_new_name_mpi( "y", pkey[3] ), + NULL )); + } + else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) { + s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 10 ), + gcry_sexp_vlist( SEXP_NEW( "elg", 3 ), + gcry_sexp_new_name_mpi( "p", pkey[0] ), + gcry_sexp_new_name_mpi( "g", pkey[1] ), + gcry_sexp_new_name_mpi( "y", pkey[2] ), + NULL )); + } + else if( algo == GCRY_PK_RSA ) { + s_pkey = SEXP_CONS( SEXP_NEW( "public-key", 10 ), + gcry_sexp_vlist( SEXP_NEW( "rsa", 3 ), + gcry_sexp_new_name_mpi( "n", pkey[0] ), + gcry_sexp_new_name_mpi( "e", pkey[1] ), + NULL )); + } + else + return G10ERR_PUBKEY_ALGO; + + /* put hash into a S-Exp s_hash */ + s_hash = gcry_sexp_new_mpi( hash ); + + /* put data into a S-Exp s_sig */ + if( algo == GCRY_PK_DSA ) { + s_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ), + gcry_sexp_vlist( SEXP_NEW( "dsa", 0 ), + gcry_sexp_new_name_mpi( "r", data[0] ), + gcry_sexp_new_name_mpi( "s", data[1] ), + NULL )); + } + else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) { + s_sig = SEXP_CONS( SEXP_NEW( "sig-val", 0 ), + gcry_sexp_vlist( SEXP_NEW( "elg", 0 ), + gcry_sexp_new_name_mpi( "r", data[0] ), + gcry_sexp_new_name_mpi( "s", data[1] ), + NULL )); + } + else if( algo == GCRY_PK_RSA ) { + s_sig = SEXP_CONS( SEXP_NEW( "public-key", 10 ), + gcry_sexp_vlist( SEXP_NEW( "rsa", 3 ), + gcry_sexp_new_name_mpi( "s", data[0] ), + NULL )); + } + else + BUG(); + + + rc = gcry_pk_verify( s_sig, s_hash, s_pkey ); + gcry_sexp_release( s_sig ); + gcry_sexp_release( s_hash ); + gcry_sexp_release( s_pkey ); + return rc; +} + + + /**************** * Check the signature which is contained in SIG. * The GCRY_MD_HD should be currently open, so that this function @@ -293,7 +371,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest ) struct cmp_help_context_s ctx; u32 cur_time; - if( pk->version == 4 && pk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { + if( pk->version == 4 && pk->pubkey_algo == GCRY_PK_ELG_E ) { log_info(_("this is a PGP generated " "ElGamal key which is NOT secure for signatures!\n")); return G10ERR_PUBKEY_ALGO; @@ -327,7 +405,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest ) if( (rc=openpgp_md_test_algo(sig->digest_algo)) ) return rc; - if( (rc=openpgp_pk_test_algo(sig->pubkey_algo)) ) + if( (rc=openpgp_pk_test_algo(sig->pubkey_algo, 0)) ) return rc; /* make sure the digest algo is enabled (in case of a detached signature)*/ @@ -372,7 +450,7 @@ do_check( PKT_public_key *pk, PKT_signature *sig, GCRY_MD_HD digest ) ctx.sig = sig; ctx.md = digest; - rc = pubkey_verify( pk->pubkey_algo, result, sig->data, pk->pkey, + rc = pk_verify( pk->pubkey_algo, result, sig->data, pk->pkey, cmp_help, &ctx ); mpi_free( result ); if( !rc && sig->flags.unknown_critical ) { diff --git a/g10/sign.c b/g10/sign.c index 1f577bef2..3ec430d2f 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -40,6 +40,63 @@ #include "i18n.h" +/**************** + * Emulate our old PK interface here - sometime in the future we might + * change the internal design to directly fit to libgcrypt. + */ +static int +pk_sign( int algo, MPI *data, MPI hash, MPI *skey ) +{ + GCRY_SEXP s_sig, s_hash, s_skey, list; + int rc; + + /* make a sexp from skey */ + if( algo == GCRY_PK_DSA ) { + s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ), + gcry_sexp_vlist( SEXP_NEW( "dsa", 3 ), + gcry_sexp_new_name_mpi( "p", skey[0] ), + gcry_sexp_new_name_mpi( "q", skey[1] ), + gcry_sexp_new_name_mpi( "g", skey[2] ), + gcry_sexp_new_name_mpi( "y", skey[3] ), + gcry_sexp_new_name_mpi( "x", skey[4] ), + NULL )); + } + else if( algo == GCRY_PK_ELG || algo == GCRY_PK_ELG_E ) { + s_skey = SEXP_CONS( SEXP_NEW( "private-key", 0 ), + gcry_sexp_vlist( SEXP_NEW( "elg", 3 ), + gcry_sexp_new_name_mpi( "p", skey[0] ), + gcry_sexp_new_name_mpi( "g", skey[1] ), + gcry_sexp_new_name_mpi( "y", skey[2] ), + gcry_sexp_new_name_mpi( "x", skey[3] ), + NULL )); + } + else + return G10ERR_PUBKEY_ALGO; + + /* put hash into a S-Exp s_hash */ + s_hash = gcry_sexp_new_mpi( hash ); + + rc = gcry_pk_sign( &s_sig, s_hash, s_skey ); + gcry_sexp_release( s_hash ); + gcry_sexp_release( s_skey ); + + if( rc ) + ; + else { + list = gcry_sexp_find_token( s_sig, "r" , 0 ); + assert( list ); + data[0] = gcry_sexp_cdr_mpi( list, 0 ); + assert( data[0] ); + list = gcry_sexp_find_token( s_sig, "s" , 0 ); + assert( list ); + data[1] = gcry_sexp_cdr_mpi( list, 0 ); + assert( data[1] ); + } + + + gcry_sexp_release( s_sig ); + return rc; +} /**************** * Create a notation. It is assumed that the stings in STRLIST @@ -123,7 +180,7 @@ do_sign( PKT_secret_key *sk, PKT_signature *sig, sig->digest_start[1] = dp[1]; frame = encode_md_value( sk->pubkey_algo, md, digest_algo, mpi_get_nbits(sk->skey[0])); - rc = pubkey_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); + rc = pk_sign( sk->pubkey_algo, sig->data, frame, sk->skey ); mpi_free(frame); if( rc ) log_error(_("signing failed: %s\n"), g10_errstr(rc) ); @@ -159,9 +216,9 @@ hash_for(int pubkey_algo ) { if( opt.def_digest_algo ) return opt.def_digest_algo; - if( pubkey_algo == PUBKEY_ALGO_DSA ) + if( pubkey_algo == GCRY_PK_DSA ) return DIGEST_ALGO_SHA1; - if( pubkey_algo == PUBKEY_ALGO_RSA ) + if( pubkey_algo == GCRY_PK_RSA ) return DIGEST_ALGO_MD5; return DEFAULT_DIGEST_ALGO; } @@ -175,7 +232,7 @@ only_old_style( SK_LIST sk_list ) /* if there are only old style capable key we use the old sytle */ for( sk_rover = sk_list; sk_rover; sk_rover = sk_rover->next ) { PKT_secret_key *sk = sk_rover->sk; - if( sk->pubkey_algo == PUBKEY_ALGO_RSA && sk->version < 4 ) + if( sk->pubkey_algo == GCRY_PK_RSA && sk->version < 4 ) old_style = 1; else return 0; @@ -237,13 +294,13 @@ 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_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) + if( (rc=build_sk_list( locusr, &sk_list, 1, GCRY_PK_USAGE_SIGN )) ) goto leave; if( !old_style ) old_style = only_old_style( sk_list ); if( encrypt ) { - if( (rc=build_pk_list( remusr, &pk_list, PUBKEY_USAGE_ENC )) ) + if( (rc=build_pk_list( remusr, &pk_list, GCRY_PK_USAGE_ENCR )) ) goto leave; if( !old_style ) compr_algo = select_algo_from_prefs( pk_list, PREFTYPE_COMPR ); @@ -559,7 +616,7 @@ clearsign_file( const char *fname, STRLIST locusr, const char *outfile ) memset( &afx, 0, sizeof afx); init_packet( &pkt ); - if( (rc=build_sk_list( locusr, &sk_list, 1, PUBKEY_USAGE_SIG )) ) + if( (rc=build_sk_list( locusr, &sk_list, 1, GCRY_PK_USAGE_SIGN )) ) goto leave; if( !old_style ) old_style = only_old_style( sk_list ); @@ -756,9 +813,9 @@ make_keysig_packet( PKT_signature **ret_sig, PKT_public_key *pk, || sigclass == 0x30 || sigclass == 0x28 ); if( !digest_algo ) { switch( sk->pubkey_algo ) { - case PUBKEY_ALGO_DSA: digest_algo = DIGEST_ALGO_SHA1; break; - case PUBKEY_ALGO_RSA_S: - case PUBKEY_ALGO_RSA: digest_algo = DIGEST_ALGO_MD5; break; + case GCRY_PK_DSA: digest_algo = DIGEST_ALGO_SHA1; break; + case GCRY_PK_RSA_S: + case GCRY_PK_RSA: digest_algo = DIGEST_ALGO_MD5; break; default: digest_algo = DIGEST_ALGO_RMD160; break; } } diff --git a/g10/skclist.c b/g10/skclist.c index df8b683f3..381601e90 100644 --- a/g10/skclist.c +++ b/g10/skclist.c @@ -25,6 +25,7 @@ #include #include +#include #include "options.h" #include "packet.h" #include "errors.h" @@ -33,6 +34,7 @@ #include "util.h" #include "i18n.h" #include "cipher.h" +#include "main.h" void @@ -48,18 +50,6 @@ release_sk_list( SK_LIST sk_list ) } -/* Check that we are only using keys which don't have - * the string "(insecure!)" or "not secure" or "do not use" - * in one of the user ids - */ -static int -is_insecure( PKT_secret_key *sk ) -{ - - return 0; /* FIXME!! */ -} - - int build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, unsigned use ) @@ -76,19 +66,14 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, free_secret_key( sk ); sk = NULL; log_error("no default secret key: %s\n", g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo2(sk->pubkey_algo, use)) ) { + else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) { SK_LIST r; - if( sk->version == 4 && (use & PUBKEY_USAGE_SIG) - && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { + if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN) + && sk->pubkey_algo == GCRY_PK_ELG_E ) { log_info("this is a PGP generated " "ElGamal key which is NOT secure for signatures!\n"); free_secret_key( sk ); sk = NULL; } - else if( random_is_faked() && !is_insecure( sk ) ) { - log_info(_("key is not flagged as insecure - " - "can't use it with the faked RNG!\n")); - free_secret_key( sk ); sk = NULL; - } else { r = m_alloc( sizeof *r ); r->sk = sk; sk = NULL; @@ -112,20 +97,15 @@ build_sk_list( STRLIST locusr, SK_LIST *ret_sk_list, int unlock, free_secret_key( sk ); sk = NULL; log_error(_("skipped `%s': %s\n"), locusr->d, g10_errstr(rc) ); } - else if( !(rc=check_pubkey_algo2(sk->pubkey_algo, use)) ) { + else if( !(rc=openpgp_pk_test_algo(sk->pubkey_algo, use)) ) { SK_LIST r; - if( sk->version == 4 && (use & PUBKEY_USAGE_SIG) - && sk->pubkey_algo == PUBKEY_ALGO_ELGAMAL_E ) { + if( sk->version == 4 && (use & GCRY_PK_USAGE_SIGN) + && sk->pubkey_algo == GCRY_PK_ELG_E ) { log_info(_("skipped `%s': this is a PGP generated " "ElGamal key which is not secure for signatures!\n"), locusr->d ); free_secret_key( sk ); sk = NULL; } - else if( random_is_faked() && !is_insecure( sk ) ) { - log_info(_("key is not flagged as insecure - " - "can't use it with the faked RNG!\n")); - free_secret_key( sk ); sk = NULL; - } else { r = m_alloc( sizeof *r ); r->sk = sk; sk = NULL; diff --git a/g10/trustdb.c b/g10/trustdb.c index 830316931..263bac261 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -683,7 +683,8 @@ print_uid_from_keyblock( FILE *fp, KBNODE keyblock, ulong urecno ) if( node->pkt->pkttype == PKT_USER_ID ) { PKT_user_id *uidpkt = node->pkt->pkt.user_id; - rmd160_hash_buffer( uhash, uidpkt->name, uidpkt->len ); + gcry_md_hash_buffer( GCRY_MD_RMD160, uhash, + uidpkt->name, uidpkt->len ); if( !memcmp( uhash, urec.r.uid.namehash, 20 ) ) { print_string( fp, uidpkt->name, uidpkt->len, ':' ); return; @@ -1334,7 +1335,7 @@ make_uid_records( KBNODE keyblock, ulong lid, u32 *keyid, u32 *min_expire ) if( node->pkt->pkttype != PKT_USER_ID ) continue; uid = node->pkt->pkt.user_id; - rmd160_hash_buffer( uidhash, uid->name, uid->len ); + gcry_md_hash_buffer( GCRY_MD_RMD160, uidhash, uid->name, uid->len ); /* create the uid record */ u = m_alloc_clear( sizeof *u ); diff --git a/include/cipher.h b/include/cipher.h index 9e1fba874..aaab08d55 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -45,8 +45,10 @@ #define PUBKEY_ALGO_DSA 17 #define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */ +#if 0 #define PUBKEY_USAGE_SIG 1 /* key is good for signatures */ #define PUBKEY_USAGE_ENC 2 /* key is good for encryption */ +#endif #define DIGEST_ALGO_MD5 1 #define DIGEST_ALGO_SHA1 2 diff --git a/include/errors.h b/include/errors.h index 247951271..a126e2636 100644 --- a/include/errors.h +++ b/include/errors.h @@ -20,57 +20,60 @@ #ifndef G10_ERRORS_H #define G10_ERRORS_H -#define G10ERR_GENERAL 1 -#define G10ERR_UNKNOWN_PACKET 2 -#define G10ERR_UNKNOWN_VERSION 3 /* Unknown version (in packet) */ -#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */ -#define G10ERR_DIGEST_ALGO 5 /* Unknown digest algorithm */ -#define G10ERR_BAD_PUBKEY 6 /* Bad public key */ -#define G10ERR_BAD_SECKEY 7 /* Bad secret key */ -#define G10ERR_BAD_SIGN 8 /* Bad signature */ -#define G10ERR_NO_PUBKEY 9 /* public key not found */ -#define G10ERR_CHECKSUM 10 /* checksum error */ -#define G10ERR_BAD_PASS 11 /* Bad passphrase */ -#define G10ERR_CIPHER_ALGO 12 /* Unknown cipher algorithm */ -#define G10ERR_KEYRING_OPEN 13 -#define G10ERR_INVALID_PACKET 14 -#define G10ERR_INVALID_ARMOR 15 -#define G10ERR_NO_USER_ID 16 -#define G10ERR_NO_SECKEY 17 /* secret key not available */ -#define G10ERR_WRONG_SECKEY 18 /* wrong seckey used */ -#define G10ERR_UNSUPPORTED 19 -#define G10ERR_BAD_KEY 20 /* bad (session) key */ -#define G10ERR_READ_FILE 21 -#define G10ERR_WRITE_FILE 22 -#define G10ERR_COMPR_ALGO 23 /* Unknown compress algorithm */ -#define G10ERR_OPEN_FILE 24 -#define G10ERR_CREATE_FILE 25 -#define G10ERR_PASSPHRASE 26 /* invalid passphrase */ -#define G10ERR_NI_PUBKEY 27 -#define G10ERR_NI_CIPHER 28 -#define G10ERR_SIG_CLASS 29 -#define G10ERR_BAD_MPI 30 -#define G10ERR_RESOURCE_LIMIT 31 -#define G10ERR_INV_KEYRING 32 -#define G10ERR_TRUSTDB 33 /* a problem with the trustdb */ -#define G10ERR_BAD_CERT 34 /* bad certicate */ -#define G10ERR_INV_USER_ID 35 -#define G10ERR_CLOSE_FILE 36 -#define G10ERR_RENAME_FILE 37 -#define G10ERR_DELETE_FILE 38 -#define G10ERR_UNEXPECTED 39 -#define G10ERR_TIME_CONFLICT 40 -#define G10ERR_WR_PUBKEY_ALGO 41 /* unusabe pubkey algo */ -#define G10ERR_FILE_EXISTS 42 -#define G10ERR_WEAK_KEY 43 /* NOTE: hardcoded into the cipher modules */ -#define G10ERR_WRONG_KEYLEN 44 /* NOTE: hardcoded into the cipher modules */ -#define G10ERR_INV_ARG 45 -#define G10ERR_BAD_URI 46 /* syntax error in URI */ -#define G10ERR_INVALID_URI 47 /* e.g. unsupported scheme */ -#define G10ERR_NETWORK 48 /* general network error */ -#define G10ERR_UNKNOWN_HOST 49 -#define G10ERR_SELFTEST_FAILED 50 -#define G10ERR_NOT_ENCRYPTED 51 + +/* FIXME: some constants have to be the same as the ones from + * libgcrypt - include gcrypt.h and use those constants */ +#define G10ERR_GENERAL 101 +#define G10ERR_UNKNOWN_PACKET 102 +#define G10ERR_UNKNOWN_VERSION 103 /* Unknown version (in packet) */ +#define G10ERR_PUBKEY_ALGO 4 /* Unknown pubkey algorithm */ +#define G10ERR_DIGEST_ALGO 5 /* Unknown digest algorithm */ +#define G10ERR_BAD_PUBKEY 6 /* Bad public key */ +#define G10ERR_BAD_SECKEY 7 /* Bad secret key */ +#define G10ERR_BAD_SIGN 8 /* Bad signature */ +#define G10ERR_NO_PUBKEY 109 /* public key not found */ +#define G10ERR_CHECKSUM 110 /* checksum error */ +#define G10ERR_BAD_PASS 111 /* Bad passphrase */ +#define G10ERR_CIPHER_ALGO 12 /* Unknown cipher algorithm */ +#define G10ERR_KEYRING_OPEN 113 +#define G10ERR_INVALID_PACKET 114 +#define G10ERR_INVALID_ARMOR 115 +#define G10ERR_NO_USER_ID 116 +#define G10ERR_NO_SECKEY 117 /* secret key not available */ +#define G10ERR_WRONG_SECKEY 118 /* wrong seckey used */ +#define G10ERR_UNSUPPORTED 119 +#define G10ERR_BAD_KEY 120 /* bad (session) key */ +#define G10ERR_READ_FILE 121 +#define G10ERR_WRITE_FILE 122 +#define G10ERR_COMPR_ALGO 123 /* Unknown compress algorithm */ +#define G10ERR_OPEN_FILE 124 +#define G10ERR_CREATE_FILE 125 +#define G10ERR_PASSPHRASE 126 /* invalid passphrase */ +#define G10ERR_NI_PUBKEY 127 +#define G10ERR_NI_CIPHER 128 +#define G10ERR_SIG_CLASS 129 +#define G10ERR_BAD_MPI 30 +#define G10ERR_RESOURCE_LIMIT 131 +#define G10ERR_INV_KEYRING 132 +#define G10ERR_TRUSTDB 133 /* a problem with the trustdb */ +#define G10ERR_BAD_CERT 134 /* bad certicate */ +#define G10ERR_INV_USER_ID 135 +#define G10ERR_CLOSE_FILE 136 +#define G10ERR_RENAME_FILE 137 +#define G10ERR_DELETE_FILE 138 +#define G10ERR_UNEXPECTED 139 +#define G10ERR_TIME_CONFLICT 140 +#define G10ERR_WR_PUBKEY_ALGO 41 /* unusabe pubkey algo */ +#define G10ERR_FILE_EXISTS 142 +#define G10ERR_WEAK_KEY 43 /* NOTE: hardcoded into the cipher modules */ +#define G10ERR_WRONG_KEYLEN 44 /* NOTE: hardcoded into the cipher modules */ +#define G10ERR_INV_ARG 145 +#define G10ERR_BAD_URI 146 /* syntax error in URI */ +#define G10ERR_INVALID_URI 147 /* e.g. unsupported scheme */ +#define G10ERR_NETWORK 148 /* general network error */ +#define G10ERR_UNKNOWN_HOST 149 +#define G10ERR_SELFTEST_FAILED 50 +#define G10ERR_NOT_ENCRYPTED 151 #ifndef HAVE_STRERROR char *strerror( int n ); diff --git a/include/g10lib.h b/include/g10lib.h index 38bd63128..ee04b655c 100644 --- a/include/g10lib.h +++ b/include/g10lib.h @@ -41,172 +41,51 @@ /*-- gcrypt/global.c --*/ int set_lasterr( int ec ); + +void *g10_malloc( size_t n ); +void *g10_calloc( size_t n, size_t m ); +void *g10_malloc_secure( size_t n ); +void *g10_calloc_secure( size_t n, size_t m ); +void *g10_realloc( void *a, size_t n ); +char *g10_strdup( const char * a); +void *g10_xmalloc( size_t n ); +void *g10_xcalloc( size_t n, size_t m ); +void *g10_xmalloc_secure( size_t n ); +void *g10_xcalloc_secure( size_t n, size_t m ); +void *g10_xrealloc( void *a, size_t n ); +char *g10_xstrdup( const char * a); +void g10_free( void *p ); + + /*-- gcrypt/misc.c --*/ const char *g10_gettext( const char *key ); int fatal_invalid_arg(const char *text); -#if 0 -/* This used to be the old include/g10lib.h */ -#include "mpi.h" +/*-- cipher/pubkey.c --*/ -int g10c_debug_mode; -int g10_opt_verbose; - -/******************************** - ******* math functions ******* - ********************************/ -MPI g10m_new( unsigned nbits ); -MPI g10m_new_secure( unsigned nbits ); -void g10m_release( MPI a ); -void g10m_resize( MPI a, unsigned nbits ); -MPI g10m_copy( MPI a ); -void g10m_swap( MPI a, MPI b); -void g10m_set( MPI w, MPI u); -void g10m_set_ui( MPI w, unsigned long u); -void g10m_set_bytes( MPI a, unsigned nbits, unsigned char (*fnc)(int), int opaque ); -int g10m_cmp( MPI u, MPI v ); -int g10m_cmp_ui( MPI u, unsigned long v ); - - -void g10m_add(MPI w, MPI u, MPI v); -void g10m_add_ui(MPI w, MPI u, unsigned long v ); -void g10m_sub( MPI w, MPI u, MPI v); -void g10m_sub_ui(MPI w, MPI u, unsigned long v ); - -void g10m_mul_ui(MPI w, MPI u, unsigned long v ); -void g10m_mul_2exp( MPI w, MPI u, unsigned long cnt); -void g10m_mul( MPI w, MPI u, MPI v); -void g10m_mulm( MPI w, MPI u, MPI v, MPI m); - -void g10m_fdiv_q( MPI quot, MPI dividend, MPI divisor ); - -void g10m_powm( MPI res, MPI base, MPI exp, MPI mod); - -int g10m_gcd( MPI g, MPI a, MPI b ); -int g10m_invm( MPI x, MPI u, MPI v ); - -unsigned g10m_get_nbits( MPI a ); -unsigned g10m_get_size( MPI a ); - -void g10m_set_buffer( MPI a, const char *buffer, unsigned nbytes, int sign ); - - -/******************************************** - ******* symmetric cipher functions ******* - ********************************************/ - - - -/********************************************* - ******* asymmetric cipher functions ******* - *********************************************/ - - - - -/********************************************* - ******* cryptograhic hash 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 ); -char *g10c_get_random_bits( unsigned nbits, int level, int secure ); - - -void *g10_malloc( size_t n ); -void *g10_calloc( size_t n ); -void *g10_malloc_secure( size_t n ); -void *g10_calloc_secure( size_t n ); -void *g10_realloc( void *a, size_t n ); -void g10_free( void *p ); -char *g10_strdup( const char * a); - -void g10_log_bug( const char *fmt, ... ); -void g10_log_bug0( const char *, int ); -void g10_log_fatal( const char *fmt, ... ); -void g10_log_error( const char *fmt, ... ); -void g10_log_info( const char *fmt, ... ); -void g10_log_debug( const char *fmt, ... ); -void g10_log_hexdump( const char *text, char *buf, size_t len ); -void g10_log_mpidump( const char *text, MPI a ); - - -/*************************** - ******* constants ******* - **************************/ -#define CIPHER_ALGO_NONE 0 -#define CIPHER_ALGO_IDEA 1 -#define CIPHER_ALGO_3DES 2 -#define CIPHER_ALGO_CAST5 3 -#define CIPHER_ALGO_BLOWFISH 4 /* blowfish 128 bit key */ -#define CIPHER_ALGO_SAFER_SK128 5 -#define CIPHER_ALGO_DES_SK 6 -#define CIPHER_ALGO_BLOWFISH160 42 /* blowfish 160 bit key (not in OpenPGP)*/ -#define CIPHER_ALGO_DUMMY 110 /* no encryption at all */ - -#define PUBKEY_ALGO_RSA 1 -#define PUBKEY_ALGO_RSA_E 2 /* RSA encrypt only */ -#define PUBKEY_ALGO_RSA_S 3 /* RSA sign only */ -#define PUBKEY_ALGO_ELGAMAL_E 16 /* encrypt only ElGamal (but not vor v3)*/ -#define PUBKEY_ALGO_DSA 17 -#define PUBKEY_ALGO_ELGAMAL 20 /* sign and encrypt elgamal */ - -#define DIGEST_ALGO_MD5 1 -#define DIGEST_ALGO_SHA1 2 -#define DIGEST_ALGO_RMD160 3 -#define DIGEST_ALGO_TIGER 6 - -#define is_RSA(a) ((a)==PUBKEY_ALGO_RSA || (a)==PUBKEY_ALGO_RSA_E \ - || (a)==PUBKEY_ALGO_RSA_S ) -#define is_ELGAMAL(a) ((a)==PUBKEY_ALGO_ELGAMAL || (a)==PUBKEY_ALGO_ELGAMAL_E) - -#define G10ERR_GENERAL 1 -#define G10ERR_PUBKEY_ALGO 4 -#define G10ERR_DIGEST_ALGO 5 -#define G10ERR_BAD_PUBKEY 6 -#define G10ERR_BAD_SECKEY 7 -#define G10ERR_BAD_SIGN 8 -#define G10ERR_CIPHER_ALGO 12 -#define G10ERR_WRONG_SECKEY 18 -#define G10ERR_UNSUPPORTED 19 -#define G10ERR_NI_PUBKEY 27 -#define G10ERR_NI_CIPHER 28 -#define G10ERR_BAD_MPI 30 -#define G10ERR_WR_PUBKEY_ALGO 41 - - -/*********************************** - ******* some handy macros ******* - ***********************************/ - -#ifndef BUG - #define BUG() g10_log_bug0( __FILE__ , __LINE__ ) +#ifndef DID_MPI_TYPEDEF + typedef struct gcry_mpi * MPI; + #define DID_MPI_TYPEDEF #endif -#ifndef STR - #define STR(v) #v - #define STR2(v) STR(v) -#endif - -#ifndef DIM - #define DIM(v) (sizeof(v)/sizeof((v)[0])) - #define DIMof(type,member) DIM(((type *)0)->member) -#endif +int string_to_pubkey_algo( const char *string ); +const char * pubkey_algo_to_string( int algo ); +unsigned pubkey_nbits( int algo, MPI *pkey ); +int pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +int pubkey_check_secret_key( int algo, MPI *skey ); +int pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ); +int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey ); -#define DBG_CIPHER g10c_debug_mode -#define OPT_VERBOSE g10_opt_verbose -#endif /* if 0 */ + +/*-- primegen.c --*/ +MPI generate_secret_prime( unsigned nbits ); +MPI generate_public_prime( unsigned nbits ); +MPI generate_elg_prime( int mode, unsigned pbits, unsigned qbits, + MPI g, MPI **factors ); + #endif /* G10LIB_H */ diff --git a/util/ChangeLog b/util/ChangeLog index 84fd83c62..ff2e09e38 100644 --- a/util/ChangeLog +++ b/util/ChangeLog @@ -1,3 +1,9 @@ +Sat Nov 13 17:44:23 CET 1999 Werner Koch + + * g10u.c: Removed. + + * errors.c (g10_errstr): Use gcry_strerror as fallback + Tue Oct 26 14:10:21 CEST 1999 Werner Koch * simple-gettext.c (set_gettext_file): Check charset and do diff --git a/util/Makefile.am b/util/Makefile.am index 95096c7e7..c695db586 100644 --- a/util/Makefile.am +++ b/util/Makefile.am @@ -6,7 +6,7 @@ noinst_LTLIBRARIES = libutil.la libutil_la_LDFLAGS = -libutil_la_SOURCES = g10u.c logger.c fileutil.c miscutil.c strgutil.c \ +libutil_la_SOURCES = logger.c fileutil.c miscutil.c strgutil.c \ ttyio.c argparse.c memory.c secmem.c errors.c iobuf.c \ dotlock.c http.c simple-gettext.c diff --git a/util/errors.c b/util/errors.c index 0590f8ed8..d92892c12 100644 --- a/util/errors.c +++ b/util/errors.c @@ -23,6 +23,7 @@ #include #include +#include #include "errors.h" #include "i18n.h" @@ -100,7 +101,13 @@ g10_errstr( int err ) X(NETWORK ,N_("network error")) X(SELFTEST_FAILED,"selftest failed") X(NOT_ENCRYPTED ,N_("not encrypted")) - default: p = buf; sprintf(buf, "g10err=%d", err); break; + default: /* pass on to libgcrypt */ + if( err >= 0 ) /* pass on to libgcrypt */ + p = gcry_strerror(err); /* fimxe: how do we handle i18n? */ + else { + p = buf; sprintf(buf, "g10err=%d", err); break; + } + break; } #undef X return _(p); diff --git a/util/g10u.c b/util/g10u.c deleted file mode 100644 index 2ce3a4e36..000000000 --- a/util/g10u.c +++ /dev/null @@ -1,40 +0,0 @@ -/* g10u.c - Wrapper for utility functions - * 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 - */ - -#include -#include -#include -#include "mpi.h" -#include "util.h" - - -/* FIXME: The modules should use functions from libgcrypt */ - -const char *g10u_revision_string(int dummy) { return "$Revision$"; } - - -void *g10_malloc( size_t n ) { return m_alloc( n ); } -void *g10_calloc( size_t n ) { return m_alloc_clear( n ); } -void *g10_malloc_secure( size_t n ) { return m_alloc_secure( n ); } -void *g10_calloc_secure( size_t n ) { return m_alloc_secure_clear( n ); } -void *g10_realloc( void *a, size_t n ) { return m_realloc( a, n ); } -void g10_free( void *p ) { m_free( p ); } -char *g10_strdup( const char * a) { return m_strdup( a ); } -