diff --git a/cipher/ChangeLog b/cipher/ChangeLog index 1d793ec34..38045bb1c 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,10 @@ +2000-10-09 Werner Koch + + * arcfour.c, arcfour.h: New. + * cipher.c (cipher_encrypt, cipher_decrypt): Add stream mode. + (setup_cipher_table): Add Arcfour. + (gcry_cipher_open): Kludge to allow stream mode. + Wed Oct 4 13:16:18 CEST 2000 Werner Koch * sha1.c (transform): Use rol() macro. Actually this is not needed diff --git a/cipher/Makefile.am b/cipher/Makefile.am index 6feea1563..0a9b10b4c 100644 --- a/cipher/Makefile.am +++ b/cipher/Makefile.am @@ -42,6 +42,7 @@ libcipher_la_SOURCES = cipher.c \ blowfish.h \ cast5.c \ cast5.h \ + arcfour.c arcfour.h \ elgamal.c \ elgamal.h \ primegen.c \ diff --git a/cipher/blowfish.h b/cipher/blowfish.h index 7c34bab3c..bed034c73 100644 --- a/cipher/blowfish.h +++ b/cipher/blowfish.h @@ -41,4 +41,14 @@ twofish_get_info( int algo, size_t *keylen, void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) ); +/* this is just a kludge for the time we have not yet chnaged the cipher + * stuff to the scheme we use for random and digests */ +const char * +rijndael_get_info( int algo, size_t *keylen, + size_t *blocksize, size_t *contextsize, + int (**setkeyf)( void *c, byte *key, unsigned keylen ), + void (**encryptf)( void *c, byte *outbuf, byte *inbuf ), + void (**decryptf)( void *c, byte *outbuf, byte *inbuf ) + ); + #endif /*G10_BLOWFISH_H*/ diff --git a/cipher/cipher.c b/cipher/cipher.c index d36db6652..ad36bfb02 100644 --- a/cipher/cipher.c +++ b/cipher/cipher.c @@ -30,10 +30,11 @@ #include "des.h" #include "blowfish.h" #include "cast5.h" +#include "arcfour.h" #include "dynload.h" #define MAX_BLOCKSIZE 16 -#define TABLE_SIZE 12 +#define TABLE_SIZE 14 #define CTX_MAGIC_NORMAL 0x24091964 #define CTX_MAGIC_SECURE 0x46919042 @@ -46,6 +47,8 @@ struct cipher_table_s { int (*setkey)( void *c, byte *key, unsigned keylen ); void (*encrypt)( void *c, byte *outbuf, byte *inbuf ); void (*decrypt)( void *c, byte *outbuf, byte *inbuf ); + void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n ); + void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n ); }; static struct cipher_table_s cipher_table[TABLE_SIZE]; @@ -63,6 +66,8 @@ struct gcry_cipher_handle { int (*setkey)( void *c, byte *key, unsigned keylen ); void (*encrypt)( void *c, byte *outbuf, byte *inbuf ); void (*decrypt)( void *c, byte *outbuf, byte *inbuf ); + void (*stencrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n ); + void (*stdecrypt)( void *c, byte *outbuf, byte *inbuf, unsigned int n ); PROPERLY_ALIGNED_TYPE context; }; @@ -73,6 +78,12 @@ static void dummy_encrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); } static void dummy_decrypt_block( void *c, byte *outbuf, byte *inbuf ) { BUG(); } +static void +dummy_encrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n ) +{ BUG(); } +static void +dummy_decrypt_stream( void *c, byte *outbuf, byte *inbuf, unsigned int n ) +{ BUG(); } @@ -84,6 +95,13 @@ setup_cipher_table(void) { int i; + for (i=0; i < TABLE_SIZE; i++ ) { + cipher_table[i].encrypt = dummy_encrypt_block; + cipher_table[i].decrypt = dummy_decrypt_block; + cipher_table[i].stencrypt = dummy_encrypt_stream; + cipher_table[i].stdecrypt = dummy_decrypt_stream; + } + i = 0; cipher_table[i].algo = GCRY_CIPHER_RIJNDAEL; cipher_table[i].name = rijndael_get_info( cipher_table[i].algo, @@ -162,14 +180,23 @@ setup_cipher_table(void) if( !cipher_table[i].name ) BUG(); i++; + cipher_table[i].algo = GCRY_CIPHER_ARCFOUR; + cipher_table[i].name = arcfour_get_info( cipher_table[i].algo, + &cipher_table[i].keylen, + &cipher_table[i].blocksize, + &cipher_table[i].contextsize, + &cipher_table[i].setkey, + &cipher_table[i].stencrypt, + &cipher_table[i].stdecrypt ); + if( !cipher_table[i].name ) + BUG(); + i++; cipher_table[i].algo = CIPHER_ALGO_DUMMY; cipher_table[i].name = "DUMMY"; cipher_table[i].blocksize = 8; cipher_table[i].keylen = 128; cipher_table[i].contextsize = 0; cipher_table[i].setkey = dummy_setkey; - cipher_table[i].encrypt = dummy_encrypt_block; - cipher_table[i].decrypt = dummy_decrypt_block; i++; for( ; i < TABLE_SIZE; i++ ) @@ -411,12 +438,24 @@ gcry_cipher_open( int algo, int mode, unsigned int flags ) case GCRY_CIPHER_MODE_ECB: case GCRY_CIPHER_MODE_CBC: case GCRY_CIPHER_MODE_CFB: + if ( cipher_table[idx].encrypt == dummy_encrypt_block + || cipher_table[idx].decrypt == dummy_decrypt_block ) { + set_lasterr( GCRYERR_INV_CIPHER_MODE ); + return NULL; + } + break; + case GCRY_CIPHER_MODE_STREAM: + if ( cipher_table[idx].stencrypt == dummy_encrypt_stream + || cipher_table[idx].stdecrypt == dummy_decrypt_stream ) { + set_lasterr( GCRYERR_INV_CIPHER_MODE ); + return NULL; + } break; case GCRY_CIPHER_MODE_NONE: /* FIXME: issue a warning when this mode is used */ break; default: - set_lasterr( GCRYERR_INV_CIPHER_ALGO ); + set_lasterr( GCRYERR_INV_CIPHER_MODE ); return NULL; } @@ -426,7 +465,7 @@ gcry_cipher_open( int algo, int mode, unsigned int flags ) + cipher_table[idx].contextsize - sizeof(PROPERLY_ALIGNED_TYPE) ) : g10_calloc( 1, sizeof *h + cipher_table[idx].contextsize - - sizeof(PROPERLY_ALIGNED_TYPE) ); + - sizeof(PROPERLY_ALIGNED_TYPE) ); if( !h ) { set_lasterr( GCRYERR_NO_MEM ); return NULL; @@ -439,6 +478,8 @@ gcry_cipher_open( int algo, int mode, unsigned int flags ) h->setkey = cipher_table[idx].setkey; h->encrypt = cipher_table[idx].encrypt; h->decrypt = cipher_table[idx].decrypt; + h->stencrypt = cipher_table[idx].stencrypt; + h->stdecrypt = cipher_table[idx].stdecrypt; return h; } @@ -550,7 +591,8 @@ do_cbc_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nblo static void -do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const 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; @@ -594,7 +636,8 @@ do_cfb_encrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt } static void -do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbytes ) +do_cfb_decrypt( GCRY_CIPHER_HD c, + byte *outbuf, const byte *inbuf, unsigned nbytes ) { byte *ivp; ulong temp; @@ -651,14 +694,16 @@ do_cfb_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, unsigned nbyt } + + /**************** * Encrypt INBUF to OUTBUF with the mode selected at open. * inbuf and outbuf may overlap or be the same. - * Depending on the mode some some contraints apply to NBYTES. + * Depending on the mode some contraints apply to NBYTES. */ static void cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf, - const byte *inbuf, unsigned nbytes ) + const byte *inbuf, unsigned int nbytes ) { switch( c->mode ) { case GCRY_CIPHER_MODE_ECB: @@ -672,6 +717,10 @@ cipher_encrypt( GCRY_CIPHER_HD c, byte *outbuf, case GCRY_CIPHER_MODE_CFB: do_cfb_encrypt(c, outbuf, inbuf, nbytes ); break; + case GCRY_CIPHER_MODE_STREAM: + (*c->stencrypt)( &c->context.c, + outbuf, (byte*)/*arggg*/inbuf, nbytes ); + break; case GCRY_CIPHER_MODE_NONE: if( inbuf != outbuf ) memmove( outbuf, inbuf, nbytes ); @@ -729,6 +778,10 @@ cipher_decrypt( GCRY_CIPHER_HD c, byte *outbuf, const byte *inbuf, case GCRY_CIPHER_MODE_CFB: do_cfb_decrypt(c, outbuf, inbuf, nbytes ); break; + case GCRY_CIPHER_MODE_STREAM: + (*c->stdecrypt)( &c->context.c, + outbuf, (byte*)/*arggg*/inbuf, nbytes ); + break; case GCRY_CIPHER_MODE_NONE: if( inbuf != outbuf ) memmove( outbuf, inbuf, nbytes ); diff --git a/g10/ChangeLog b/g10/ChangeLog index 127e54fa9..6f73abf96 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,19 @@ +2000-10-09 Werner Koch + + * keygen.c (do_generate_keypair): Removed the keyblock locking. + + * ringedit.c (enum_keyblocks): Replaced by ... + (enum_keyblocks_begin): New. + (enum_keyblocks_next): New. + (enum_keyblocks_end): New. And changed all callers. + + * import.c (import_one): Removed keyblock locking becuase this is + now done inside of insert_keyblock(). Removed get_keyblock_handle + because insert_keyblock() now decides what is the default keyring. + (import_secret_one): Ditto. + (import_revoke_cert): Ditto. + (import_one): Ditto. + Fri Oct 6 14:29:16 CEST 2000 Werner Koch Started to rework the whole getkey/ringedit stuff to make diff --git a/g10/delkey.c b/g10/delkey.c index 91413edd8..f4bfd01e4 100644 --- a/g10/delkey.c +++ b/g10/delkey.c @@ -142,6 +142,7 @@ delete_key( const char *username, int secret ) if( okay ) { + #warning MUST FIX THIS!!! rc = delete_keyblock( &kbpos ); if( rc ) { log_error("delete_keyblock failed: %s\n", gpg_errstr(rc) ); diff --git a/g10/export.c b/g10/export.c index 8b8ba489a..9a9cd9859 100644 --- a/g10/export.c +++ b/g10/export.c @@ -124,10 +124,10 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) iobuf_push_filter( out, compress_filter, &zfx ); if( all ) { - rc = enum_keyblocks( secret?5:0, &kbpos, &keyblock ); + rc = enum_keyblocks_begin( &kbpos, secret ); if( rc ) { if( rc != -1 ) - log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) ); + log_error("enum_keyblocks_begin failed: %s\n", gpg_errstr(rc)); goto leave; } all = 2; @@ -137,11 +137,11 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) * NULL pointers :-) */ for( sl=strlist_last(users); sl || all ; sl=strlist_prev( users, sl )) { if( all ) { /* get the next user */ - rc = enum_keyblocks( 1, &kbpos, &keyblock ); + rc = enum_keyblocks_next( kbpos, 1, &keyblock ); if( rc == -1 ) /* EOF */ break; if( rc ) { - log_error("enum_keyblocks(read) failed: %s\n", gpg_errstr(rc)); + log_error("enum_keyblocks_next failed: %s\n", gpg_errstr(rc)); break; } } @@ -219,7 +219,7 @@ do_export_stream( IOBUF out, STRLIST users, int secret, int onlyrfc, int *any ) leave: if( all == 2 ) - enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ + enum_keyblocks_end( kbpos ); release_kbnode( keyblock ); if( !*any ) log_info(_("WARNING: nothing exported\n")); diff --git a/g10/getkey.c b/g10/getkey.c index a0fa44580..8f38c4a34 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -862,17 +862,13 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist, } } - if (!rc ) - log_debug ( "pk_byname: kbpos %s %lu %p\n", - ctx->kbpos.valid? "valid":"", - ctx->kbpos.offset, ctx->kbpos.fp ); release_kbnode ( help_kb ); if( retctx ) /* caller wants the context */ *retctx = ctx; else { /* Hmmm, why not get_pubkey-end here?? */ - enum_keyblocks( 2, &ctx->kbpos, NULL ); /* close */ + enum_keyblocks_end( ctx->kbpos ); ctx->kbpos = NULL; for(n=0; n < ctx->nitems; n++ ) gcry_free( ctx->items[n].namebuf ); gcry_free( ctx ); @@ -920,7 +916,7 @@ get_pubkey_end( GETKEY_CTX ctx ) if( ctx ) { int n; - enum_keyblocks( 2, &ctx->kbpos, NULL ); /* close */ + enum_keyblocks_end( ctx->kbpos ); ctx->kbpos = NULL; for(n=0; n < ctx->nitems; n++ ) gcry_free( ctx->items[n].namebuf ); if( !ctx->not_allocated ) @@ -976,7 +972,7 @@ find_kblocation_bypk( void *re_opaque, PKT_public_key *pk ) rc = get_pubkey_byname( &ctx, dummy_pk, ufpr, NULL ); free_public_key(dummy_pk); if ( !rc ) - ringedit_copy_kbpos( re_opaque, &ctx->kbpos ); + ringedit_copy_kbpos( re_opaque, ctx->kbpos ); get_pubkey_end( ctx ); return rc; @@ -2212,11 +2208,11 @@ lookup( GETKEY_CTX ctx, KBNODE *ret_keyblock, int secmode ) KBNODE secblock = NULL; /* helper */ if( !ctx->count ) /* first time */ - rc = enum_keyblocks( secmode?5:0, &ctx->kbpos, &ctx->keyblock ); + rc = enum_keyblocks_begin( &ctx->kbpos, secmode ); else rc = 0; if( !rc ) { - while( !(rc = enum_keyblocks( 1, &ctx->kbpos, &ctx->keyblock )) ) { + while( !(rc = enum_keyblocks_next( ctx->kbpos, 1, &ctx->keyblock )) ) { int n; getkey_item_t *item; diff --git a/g10/import.c b/g10/import.c index fa21fbc34..7e2e5bc18 100644 --- a/g10/import.c +++ b/g10/import.c @@ -361,7 +361,6 @@ import_one( const char *fname, KBNODE keyblock, int fast ) PKT_public_key *pk_orig; KBNODE node, uidnode; KBNODE keyblock_orig = NULL; - KBPOS kbpos; u32 keyid[2]; int rc = 0; int new_key = 0; @@ -425,22 +424,14 @@ import_one( const char *fname, KBNODE keyblock, int fast ) stats.skipped_new_keys++; } else if( rc ) { /* insert this key */ - /* get default resource */ - if( get_keyblock_handle( NULL, 0, &kbpos ) ) { - log_error(_("no default public keyring\n")); - return GPGERR_GENERAL; - } +#if 0 /* we don't know wehre we are going to write */ if( opt.verbose > 1 ) log_info( _("writing to `%s'\n"), - keyblock_resource_name(&kbpos) ); - if( (rc=lock_keyblock( &kbpos )) ) - log_error(_("can't lock keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - else if( (rc=insert_keyblock( keyblock )) ) - log_error( _("error writing keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - unlock_keyblock( &kbpos ); - /* we are ready */ + keyblock_resource_name(kbpos) ); +#endif + if( (rc=insert_keyblock( keyblock )) ) + log_error( _("error writing key: %s\n"), gpg_errstr(rc) ); + /* we are ready */ if( !opt.quiet ) log_info( _("key %08lX: public key imported\n"), (ulong)keyid[1]); if( is_status_enabled() ) { @@ -485,13 +476,8 @@ import_one( const char *fname, KBNODE keyblock, int fast ) if( n_uids || n_sigs || n_subk ) { mod_key = 1; /* keyblock_orig has been updated; write */ - if( (rc=lock_keyblock( &kbpos )) ) - log_error( _("can't lock keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - else if( (rc=update_keyblock( keyblock_orig )) ) - log_error( _("error writing keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - unlock_keyblock( &kbpos ); + if( (rc=update_keyblock( keyblock_orig )) ) + log_error( _("error writing key: %s\n"), gpg_errstr(rc) ); /* we are ready */ if( !opt.quiet ) { if( n_uids == 1 ) @@ -555,7 +541,6 @@ import_secret_one( const char *fname, KBNODE keyblock ) { PKT_secret_key *sk; KBNODE node, uidnode; - KBPOS kbpos; u32 keyid[2]; int rc = 0; @@ -588,19 +573,9 @@ import_secret_one( const char *fname, KBNODE keyblock ) /* do we have this key already in one of our secrings ? */ rc = seckey_available( keyid ); - if( rc == GPGERR_NO_SECKEY && !opt.merge_only ) { /* simply insert this key */ - /* get default resource */ - if( get_keyblock_handle( NULL, 1, &kbpos ) ) { - log_error("no default secret keyring\n"); - return GPGERR_GENERAL; - } - if( (rc=lock_keyblock( &kbpos )) ) - log_error( _("can't lock keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - else if( (rc=insert_keyblock( keyblock )) ) - log_error( _("error writing keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - unlock_keyblock( &kbpos ); + if( rc == GPGERR_NO_SECKEY && !opt.merge_only ) { /*just insert this key*/ + if( (rc=insert_keyblock( keyblock )) ) + log_error( _("error writing key: %s\n"), gpg_errstr(rc) ); /* we are ready */ if( !opt.quiet ) log_info( _("key %08lX: secret key imported\n"), (ulong)keyid[1]); @@ -627,7 +602,6 @@ import_revoke_cert( const char *fname, KBNODE node ) { PKT_public_key *pk=NULL; KBNODE onode, keyblock = NULL; - KBPOS kbpos; u32 keyid[2]; int rc = 0; @@ -689,13 +663,8 @@ import_revoke_cert( const char *fname, KBNODE node ) insert_kbnode( keyblock, clone_kbnode(node), 0 ); /* and write the keyblock back */ - if( (rc=lock_keyblock( &kbpos )) ) - log_error( _("can't lock keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - else if( (rc=update_keyblock( keyblock )) ) - log_error( _("error writing keyring `%s': %s\n"), - keyblock_resource_name(&kbpos), gpg_errstr(rc) ); - unlock_keyblock( &kbpos ); + if( (rc=update_keyblock( keyblock )) ) + log_error( _("error writing key: %s\n"), gpg_errstr(rc) ); /* we are ready */ if( !opt.quiet ) log_info( _("key %08lX: revocation certificate imported\n"), diff --git a/g10/kbxfile.c b/g10/kbxfile.c index 457fb1716..94ef13f83 100644 --- a/g10/kbxfile.c +++ b/g10/kbxfile.c @@ -265,14 +265,14 @@ export_as_kbxfile(void) KBNODE keyblock = NULL; int rc=0; - rc = enum_keyblocks( 0, &kbpos, &keyblock ); + rc = enum_keyblocks_begin( &kbpos, 0 ); if( rc ) { if( rc != -1 ) log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) ); goto leave; } - while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) { + while( !(rc = enum_keyblocks_next( kbpos, 1, &keyblock )) ) { KBXBLOB blob; const char *p; size_t n; @@ -292,7 +292,7 @@ export_as_kbxfile(void) log_error("enum_keyblocks(read) failed: %s\n", gpg_errstr(rc)); leave: - enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ + enum_keyblocks_end( kbpos ); release_kbnode( keyblock ); } diff --git a/g10/keydb.h b/g10/keydb.h index 95d369ed4..c2131ada7 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -192,7 +192,9 @@ int add_keyblock_resource( const char *resname, int force, int secret ); const char *keyblock_resource_name( KBPOS kbpos ); int get_keyblock_handle( const char *filename, int secret, KBPOS kbpos ); char *get_writable_keyblock_file( int secret ); -int enum_keyblocks( int mode, KBPOS kbpos, KBNODE *ret_root ); +int enum_keyblocks_begin( KBPOS *kbpos, int mode ); +int enum_keyblocks_next( KBPOS kbpos, int mode, KBNODE *ret_root ); +void enum_keyblocks_end( KBPOS kbpos ); int insert_keyblock( KBNODE keyblock ); int delete_keyblock( KBNODE keyblock ); int update_keyblock( KBNODE keyblock ); diff --git a/g10/keygen.c b/g10/keygen.c index d3887dd7d..415c54a2a 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -1748,10 +1748,6 @@ do_generate_keypair( struct para_data_s *para, if( rc ) ; - else if( (rc=rc1=lock_keyblock( &pub_kbpos )) ) - log_error("can't lock public keyring: %s\n", gpg_errstr(rc) ); - else if( (rc=rc2=lock_keyblock( &sec_kbpos )) ) - log_error("can't lock secret keyring: %s\n", gpg_errstr(rc) ); else if( (rc=insert_keyblock( pub_root )) ) log_error("can't write public key: %s\n", gpg_errstr(rc) ); else if( (rc=insert_keyblock( sec_root )) ) @@ -1770,10 +1766,6 @@ do_generate_keypair( struct para_data_s *para, } } - if( !rc1 ) - unlock_keyblock( &pub_kbpos ); - if( !rc2 ) - unlock_keyblock( &sec_kbpos ); } if( rc ) { diff --git a/g10/keylist.c b/g10/keylist.c index 4109968c0..89691873a 100644 --- a/g10/keylist.c +++ b/g10/keylist.c @@ -72,7 +72,7 @@ list_all( int secret ) int rc=0; int lastresno; - rc = enum_keyblocks( secret? 5:0, &kbpos, &keyblock ); + rc = enum_keyblocks_begin( &kbpos, secret ); if( rc ) { if( rc != -1 ) log_error("enum_keyblocks(open) failed: %s\n", gpg_errstr(rc) ); @@ -80,12 +80,12 @@ list_all( int secret ) } lastresno = -1; - while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) { - if( lastresno != kbpos.resno ) { - const char *s = keyblock_resource_name( &kbpos ); + while( !(rc = enum_keyblocks_next( kbpos, 1, &keyblock )) ) { + if( 1 /*lastresno != kbpos.resno FIXME!!! */ ) { + const char *s = "foo" /*keyblock_resource_name( &kbpos ) */; int i; - lastresno = kbpos.resno; + /* FIXME lastresno = kbpos.resno*/ printf("%s\n", s ); for(i=strlen(s); i; i-- ) putchar('-'); @@ -100,7 +100,7 @@ list_all( int secret ) log_error("enum_keyblocks(read) failed: %s\n", gpg_errstr(rc)); leave: - enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ + enum_keyblocks_end( kbpos ); release_kbnode( keyblock ); } diff --git a/g10/ringedit.c b/g10/ringedit.c index de05ba6e2..6d5b3e0e4 100644 --- a/g10/ringedit.c +++ b/g10/ringedit.c @@ -460,112 +460,152 @@ unlock_keyblock( KBPOS kbpos ) } -/**************** - * This functions can be used to read through a complete keyring. - * Mode is: 0 = open - * 1 = read - * 2 = close - * 5 = open secret keyrings - * 11 = read but skip signature and comment packets. - * all others are reserved! - */ -int -enum_keyblocks( int mode, KBPOS kbpos, KBNODE *ret_root ) +static int +enum_keyrings_open_helper( KBPOS kbpos, int where ) { - int rc = 0; + int i = where; RESTBL *rentry; - if( !mode || mode == 5 || mode == 100 ) { - int i; - - kbpos->fp = NULL; - kbpos->rt = rt_UNKNOWN; - if( !mode ) { - kbpos->secret = 0; - i = 0; - } - else if( mode == 5 ) { - kbpos->secret = 1; - mode = 0; - i = 0; - } - else - i = kbpos->resno+1; - for(; i < MAX_RESOURCES; i++ ) - if( resource_table[i].used - && !resource_table[i].secret == !kbpos->secret ) - break; - if( i == MAX_RESOURCES ) - return -1; /* no resources */ - kbpos->resno = i; - rentry = check_pos( kbpos ); - kbpos->rt = resource_table[i].rt; - kbpos->valid = 0; - switch( kbpos->rt ) { - case rt_RING: - case rt_KBXF: - kbpos->fp = iobuf_open( rentry->fname ); - if( !kbpos->fp ) { - log_error("can't open `%s'\n", rentry->fname ); - return GPGERR_OPEN_FILE; - } - break; - - default: BUG(); - } - kbpos->pkt = NULL; + for(; i < MAX_RESOURCES; i++ ) + if( resource_table[i].used + && !resource_table[i].secret == !kbpos->secret ) + break; + if( i == MAX_RESOURCES ) + return -1; /* no resources */ + kbpos->resno = i; + rentry = check_pos( kbpos ); + kbpos->rt = resource_table[i].rt; + kbpos->valid = 0; + switch( kbpos->rt ) { + case rt_RING: + case rt_KBXF: + kbpos->fp = iobuf_open( rentry->fname ); + if ( !kbpos->fp ) { + log_error("can't open `%s'\n", rentry->fname ); + return GPGERR_OPEN_FILE; + } + break; + + default: BUG(); } - else if( mode == 1 || mode == 11 ) { - int cont; - do { - cont = 0; - switch( kbpos->rt ) { - case rt_RING: - if( !kbpos->fp ) - return GPGERR_GENERAL; - rc = keyring_enum( kbpos, ret_root, mode == 11 ); - break; - case rt_KBXF: - if( !kbpos->fp ) - return GPGERR_GENERAL; - rc = do_kbxf_enum( kbpos, ret_root, mode == 11 ); - break; - default: BUG(); - } + kbpos->pkt = NULL; + return 0; +} - if( rc == -1 ) { - assert( !kbpos->pkt ); - rentry = check_pos( kbpos ); - assert(rentry); - /* close */ - enum_keyblocks(2, kbpos, ret_root ); - /* and open the next one */ - rc = enum_keyblocks(100, kbpos, ret_root ); - if( !rc ) - cont = 1; - } - } while(cont); + +/**************** + * This set of functions is used to scan over all keyrings. + * The mode in enum_keyblocks_next() is used liek this: + * Mode is: 1 = read + * 11 = read but skip signature and comment packets. + */ +int +enum_keyblocks_begin( KBPOS *rkbpos, int use_secret ) +{ + int rc, i; + KBPOS kbpos; + + *rkbpos = NULL; + + kbpos = gcry_xcalloc( 1, sizeof *kbpos ); + kbpos->fp = NULL; + kbpos->rt = rt_UNKNOWN; + if( !use_secret ) { + kbpos->secret = 0; + i = 0; } else { - switch( kbpos->rt ) { - case rt_RING: - case rt_KBXF: - if( kbpos->fp ) { - iobuf_close( kbpos->fp ); - kbpos->fp = NULL; - } - break; - case rt_UNKNOWN: - /* this happens when we have no keyring at all */ - return rc; - - default: - BUG(); - } - /* release pending packet */ - free_packet( kbpos->pkt ); - gcry_free( kbpos->pkt ); + kbpos->secret = 1; + i = 0; } + + rc = enum_keyrings_open_helper( kbpos, i ); + if ( rc ) { + gcry_free( kbpos ); + return rc; + } + /* return the handle */ + *rkbpos = kbpos; + return 0; +} + +void +enum_keyblocks_end( KBPOS kbpos ) +{ + if ( !kbpos ) + return; + switch( kbpos->rt ) { + case rt_RING: + case rt_KBXF: + if( kbpos->fp ) { + iobuf_close( kbpos->fp ); + kbpos->fp = NULL; + } + break; + case rt_UNKNOWN: + /* this happens when we have no keyring at all */ + gcry_free( kbpos ); + return; + + default: + BUG(); + } + /* release pending packet */ + free_packet( kbpos->pkt ); + gcry_free( kbpos->pkt ); + gcry_free( kbpos ); +} + +int +enum_keyblocks_next( KBPOS kbpos, int mode, KBNODE *ret_root ) +{ + int cont, rc = 0; + RESTBL *rentry; + + if( mode != 1 && mode != 11 ) + return GPGERR_INV_ARG; + + do { + cont = 0; + switch( kbpos->rt ) { + case rt_RING: + if( !kbpos->fp ) + return GPGERR_GENERAL; + rc = keyring_enum( kbpos, ret_root, mode == 11 ); + break; + case rt_KBXF: + if( !kbpos->fp ) + return GPGERR_GENERAL; + rc = do_kbxf_enum( kbpos, ret_root, mode == 11 ); + break; + default: BUG(); + } + + if( rc == -1 ) { + RESTBL *rentry; + int i; + + assert( !kbpos->pkt ); + rentry = check_pos( kbpos ); + assert(rentry); + i = kbpos->resno+1; + /* first close */ + if( kbpos->fp ) { + iobuf_close( kbpos->fp ); + kbpos->fp = NULL; + } + free_packet( kbpos->pkt ); + gcry_free( kbpos->pkt ); + kbpos->pkt = NULL; + /* and then open the next one */ + rc = enum_keyrings_open_helper( kbpos, i ); + if ( !rc ) + cont = 1; + /* hmm, that is not really correct: if we got an error kbpos + * might be not well anymore */ + } + } while(cont); + return rc; } @@ -632,7 +672,7 @@ int update_keyblock( KBNODE root ) { int rc; - struct WORK WORK WORK KBPOS kbpos; + struct keyblock_pos_struct kbpos; /* We need to get the file position of original keyblock first */ if ( root->pkt->pkttype == PKT_PUBLIC_KEY ) @@ -668,7 +708,7 @@ update_keyblock( KBNODE root ) ****************************************************************/ static int -keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ) +keyring_enum( KBPOS kbpos, KBNODE *ret_root, int skipsigs ) { PACKET *pkt; int rc; @@ -767,7 +807,7 @@ keyring_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ) * 3 = update */ static int -keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) +keyring_copy( KBPOS kbpos, int mode, KBNODE root ) { RESTBL *rentry; IOBUF fp, newfp; @@ -1003,7 +1043,7 @@ keyring_copy( KBPOS *kbpos, int mode, KBNODE root ) ****************************************************************/ static int -do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ) +do_kbxf_enum( KBPOS kbpos, KBNODE *ret_root, int skipsigs ) { PACKET *pkt; int rc; @@ -1092,7 +1132,7 @@ do_kbxf_enum( KBPOS *kbpos, KBNODE *ret_root, int skipsigs ) * 3 = update */ static int -do_kbxf_copy( KBPOS *kbpos, int mode, KBNODE root ) +do_kbxf_copy( KBPOS kbpos, int mode, KBNODE root ) { RESTBL *rentry; IOBUF fp, newfp; diff --git a/g10/trustdb.c b/g10/trustdb.c index f3fcd4649..1fd2383c0 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -1778,11 +1778,11 @@ update_trustdb() return; init_trustdb(); - rc = enum_keyblocks( 0, &kbpos, &keyblock ); + rc = enum_keyblocks_begin( &kbpos, 0 ); if( !rc ) { ulong count=0, err_count=0, new_count=0; - while( !(rc = enum_keyblocks( 1, &kbpos, &keyblock )) ) { + while( !(rc = enum_keyblocks_next( kbpos, 1, &keyblock )) ) { /*int modified;*/ TRUSTREC drec; PKT_public_key *pk = find_kbnode( keyblock, PKT_PUBLIC_KEY ) @@ -1825,7 +1825,7 @@ update_trustdb() if( rc && rc != -1 ) log_error(_("enumerate keyblocks failed: %s\n"), gpg_errstr(rc)); - enum_keyblocks( 2, &kbpos, &keyblock ); /* close */ + enum_keyblocks_end( kbpos ); release_kbnode( keyblock ); } diff --git a/tools/ChangeLog b/tools/ChangeLog index 136caf56b..2faf8de06 100644 --- a/tools/ChangeLog +++ b/tools/ChangeLog @@ -1,3 +1,7 @@ +2000-10-10 Werner Koch + + * bftest.c (main): Allow selection of cipher mode. + Mon Sep 18 16:35:45 CEST 2000 Werner Koch * ring-a-party: substr starts at offset 1 not 0. Many thanks to Mike diff --git a/tools/bftest.c b/tools/bftest.c index 1902703f7..6b1e09117 100644 --- a/tools/bftest.c +++ b/tools/bftest.c @@ -34,7 +34,7 @@ static void my_usage(void) { - fprintf(stderr, "usage: bftest [-e][-d] algo key\n"); + fprintf(stderr, "usage: bftest [-e][-d] algo mode key\n"); exit(1); } @@ -59,9 +59,10 @@ main(int argc, char **argv) int encode=0; GCRY_CIPHER_HD hd; char buf[4096]; - int n, size=4096; - int algo; - + int rc, n, size=4096; + int algo, mode; + const char *s; + #ifdef HAVE_DOSISH_SYSTEM setmode( fileno(stdin), O_BINARY ); setmode( fileno(stdout), O_BINARY ); @@ -84,14 +85,34 @@ main(int argc, char **argv) argc--; argv++; size = 10; } - if( argc != 3 ) + if( argc != 4 ) my_usage(); argc--; argv++; algo = gcry_cipher_map_name( *argv ); argc--; argv++; + s = *argv; argc--; argv++; + if ( !strcasecmp( s, "cfb" ) ) + mode = GCRY_CIPHER_MODE_CFB; + else if ( !strcasecmp( s, "cbc" ) ) + mode = GCRY_CIPHER_MODE_CBC; + else if ( !strcasecmp( s, "ebc" ) ) + mode = GCRY_CIPHER_MODE_ECB; + else if ( !strcasecmp( s, "none" ) ) + mode = GCRY_CIPHER_MODE_NONE; + else if ( !strcasecmp( s, "stream" ) ) + mode = GCRY_CIPHER_MODE_STREAM; + else { + fprintf( stderr, + "wrong mode; use one of: none, ecb, cbc, cfb, stream\n"); + return 1; + } - hd = gcry_cipher_open( algo, GCRY_CIPHER_MODE_CFB, 0 ); - gcry_cipher_setkey( hd, *argv, strlen(*argv) ); + hd = gcry_cipher_open( algo, mode, 0 ); + if (!hd ) + log_fatal("cipher open failed: %s\n", gcry_strerror(-1) ); + rc = gcry_cipher_setkey( hd, *argv, strlen(*argv) ); + if ( rc ) + log_fatal("setkey failed: %s\n", gcry_strerror(rc) ); gcry_cipher_setiv( hd, NULL, 0 ); while( (n = fread( buf, 1, size, stdin )) > 0 ) { if( encode ) @@ -105,3 +126,15 @@ main(int argc, char **argv) return 0; } + + + + + + + + + + + +