1
0
Fork 0
mirror of git://git.gnupg.org/gnupg.git synced 2025-07-02 22:46:30 +02:00

Bug in blowfish behoben

This commit is contained in:
Werner Koch 1998-01-06 21:01:36 +00:00
parent 6e0fd3df65
commit 0d9ffec5ef
15 changed files with 467 additions and 164 deletions

View file

@ -230,12 +230,13 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
mpi_write(a, skc->d.elg.p );
mpi_write(a, skc->d.elg.g );
mpi_write(a, skc->d.elg.y );
iobuf_put(a, skc->d.elg.protect_algo );
if( skc->d.elg.protect_algo ) {
assert( skc->d.elg.is_protected == 1 );
if( skc->d.elg.is_protected ) {
assert( skc->d.elg.protect_algo == CIPHER_ALGO_BLOWFISH );
iobuf_put(a, skc->d.elg.protect_algo );
iobuf_write(a, skc->d.elg.protect.blowfish.iv, 8 );
}
else
iobuf_put(a, 0 );
mpi_write(a, skc->d.elg.x );
write_16(a, skc->d.elg.csum );
@ -243,12 +244,13 @@ do_secret_cert( IOBUF out, int ctb, PKT_secret_cert *skc )
else if( skc->pubkey_algo == PUBKEY_ALGO_RSA ) {
mpi_write(a, skc->d.rsa.rsa_n );
mpi_write(a, skc->d.rsa.rsa_e );
iobuf_put(a, skc->d.rsa.protect_algo );
if( skc->d.rsa.protect_algo ) {
assert( skc->d.rsa.is_protected == 1 );
if( skc->d.rsa.is_protected ) {
assert( skc->d.rsa.protect_algo == CIPHER_ALGO_BLOWFISH );
iobuf_put(a, skc->d.rsa.protect_algo );
iobuf_write(a, skc->d.rsa.protect.blowfish.iv, 8 );
}
else
iobuf_put(a, 0 );
mpi_write(a, skc->d.rsa.rsa_d );
mpi_write(a, skc->d.rsa.rsa_p );
mpi_write(a, skc->d.rsa.rsa_q );

View file

@ -38,7 +38,7 @@
enum cmd_values { aNull = 0,
aSym, aStore, aEncr, aPrimegen, aKeygen, aSign, aSignEncr,
aPrintMDs, aSignKey, aClearsig, aListPackets, aEditSig,
aKMode, aKModeC,
aKMode, aKModeC, aChangePass,
aTest };
@ -158,7 +158,6 @@ main( int argc, char **argv )
{ 512, "cache-all" ,0, "hold everything in memory"},
{ 513, "gen-prime" , 0, "\r" },
{ 514, "test" , 0, "\r" },
{ 515, "change-passphrase", 0, "change the passphrase of your secret keyring"},
{ 515, "fingerprint", 0, "show the fingerprints"},
{ 516, "print-mds" , 0, "print all message digests"},
{ 517, "secret-keyring" ,2, "add this secret keyring to the list" },
@ -169,6 +168,7 @@ main( int argc, char **argv )
{ 522, "no-greeting", 0, "\r" },
{ 523, "passphrase-fd",1, "\r" },
{ 524, "edit-sig" ,0, "edit a key signature" },
{ 525, "change-passphrase", 0, "change the passphrase of your secret keyring"},
{0} };
ARGPARSE_ARGS pargs;
@ -297,6 +297,7 @@ main( int argc, char **argv )
case 522: greeting = 0; break;
case 523: set_passphrase_fd( pargs.r.ret_int ); break;
case 524: set_cmd( &cmd, aEditSig); break;
case 525: set_cmd( &cmd, aChangePass); break;
default : errors++; pargs.err = configfp? 1:2; break;
}
}
@ -406,6 +407,15 @@ main( int argc, char **argv )
log_error("edit_keysig('%s'): %s\n", fname_print, g10_errstr(rc) );
break;
case aChangePass: /* Chnage the passphrase */
if( argc > 1 ) /* no arg: use default, 1 arg use this one */
usage(1);
/* note: fname is the user id! */
if( (rc = change_passphrase(fname)) )
log_error("change_passphrase('%s'): %s\n", fname_print,
g10_errstr(rc) );
break;
case aKMode: /* list keyring */
if( !argc ) { /* list the default public keyrings */
int i, seq=0;

View file

@ -83,7 +83,7 @@ add_keyring( const char *name )
* combine it with the keyblock stuff from ringedit.c
* For now we will simple add the filename as keyblock resource
*/
rc = add_keyblock_resource( name, 0 );
rc = add_keyblock_resource( name, 0, 0 );
if( rc )
log_error("keyblock resource '%s': %s\n", name, g10_errstr(rc) );
}
@ -115,6 +115,14 @@ add_secret_keyring( const char *name )
strcpy(sl->d, name );
sl->next = secret_keyrings;
secret_keyrings = sl;
/* FIXME: We should remove much out of this mpdule and
* combine it with the keyblock stuff from ringedit.c
* For now we will simple add the filename as keyblock resource
*/
rc = add_keyblock_resource( name, 0, 1 );
if( rc )
log_error("secret keyblock resource '%s': %s\n", name, g10_errstr(rc) );
}

View file

@ -125,10 +125,11 @@ KBNODE walk_kbtree2( KBNODE root, KBNODE *context, int all );
void clear_kbnode_flags( KBNODE n );
/*-- ringedit.c --*/
int add_keyblock_resource( const char *filename, int force );
int get_keyblock_handle( const char *filename, KBPOS *kbpos );
int search_keyblock( PACKET *pkt, KBPOS *kbpos );
int add_keyblock_resource( const char *filename, int force, int secret );
int get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos );
int search_keyblock( PACKET *pkt, KBPOS *kbpos, int secret );
int search_keyblock_byname( KBPOS *kbpos, const char *username );
int search_secret_keyblock_byname( KBPOS *kbpos, const char *username );
int lock_keyblock( KBPOS *kbpos );
void unlock_keyblock( KBPOS *kbpos );
int read_keyblock( KBPOS *kbpos, KBNODE *ret_root );

View file

@ -507,24 +507,24 @@ generate_keypair()
/* we can now write the certificates */
/* FIXME: should we check wether the user-id already exists? */
if( get_keyblock_handle( pub_fname, &pub_kbpos ) ) {
if( add_keyblock_resource( pub_fname, 1 ) ) {
if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
if( add_keyblock_resource( pub_fname, 1, 0 ) ) {
log_error("can add keyblock file '%s'\n", pub_fname );
rc = G10ERR_CREATE_FILE;
}
else if( get_keyblock_handle( pub_fname, &pub_kbpos ) ) {
else if( get_keyblock_handle( pub_fname, 0, &pub_kbpos ) ) {
log_error("can get keyblock handle for '%s'\n", pub_fname );
rc = G10ERR_CREATE_FILE;
}
}
if( rc )
;
else if( get_keyblock_handle( sec_fname, &sec_kbpos ) ) {
if( add_keyblock_resource( sec_fname, 1 ) ) {
else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
if( add_keyblock_resource( sec_fname, 1, 1 ) ) {
log_error("can add keyblock file '%s'\n", sec_fname );
rc = G10ERR_CREATE_FILE;
}
else if( get_keyblock_handle( sec_fname, &sec_kbpos ) ) {
else if( get_keyblock_handle( sec_fname, 1, &sec_kbpos ) ) {
log_error("can get keyblock handle for '%s'\n", sec_fname );
rc = G10ERR_CREATE_FILE;
}

View file

@ -49,6 +49,7 @@ int sign_file( const char *filename, int detached, STRLIST locusr,
int encrypt, STRLIST remusr );
int sign_key( const char *username, STRLIST locusr );
int edit_keysigs( const char *username );
int change_passphrase( const char *username );
/*-- sig-check.c --*/
int check_key_signature( KBNODE root, KBNODE node );

View file

@ -238,6 +238,7 @@ PKT_secret_cert *copy_secret_cert( PKT_secret_cert *d, PKT_secret_cert *s );
int signature_check( PKT_signature *sig, MD_HANDLE *digest );
/*-- seckey-cert.c --*/
int is_secret_key_protected( PKT_secret_cert *cert );
int check_secret_key( PKT_secret_cert *cert );
int protect_secret_key( PKT_secret_cert *cert, DEK *dek );

View file

@ -58,6 +58,7 @@
struct resource_table_struct {
int used;
int secret; /* this is a secret keyring */
char *fname;
IOBUF iobuf;
};
@ -94,7 +95,7 @@ check_pos( KBPOS *kbpos )
* Register a resource (which currently may ionly be a keyring file).
*/
int
add_keyblock_resource( const char *filename, int force )
add_keyblock_resource( const char *filename, int force, int secret )
{
IOBUF iobuf;
int i;
@ -109,6 +110,7 @@ add_keyblock_resource( const char *filename, int force )
if( !iobuf && !force )
return G10ERR_OPEN_FILE;
resource_table[i].used = 1;
resource_table[i].secret = !!secret;
resource_table[i].fname = m_strdup(filename);
resource_table[i].iobuf = iobuf;
return 0;
@ -120,12 +122,12 @@ add_keyblock_resource( const char *filename, int force )
* to get a handle for insert_keyblock for a new keyblock.
*/
int
get_keyblock_handle( const char *filename, KBPOS *kbpos )
get_keyblock_handle( const char *filename, int secret, KBPOS *kbpos )
{
int i;
for(i=0; i < MAX_RESOURCES; i++ )
if( resource_table[i].used ) {
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
/* fixme: dos needs case insensitive file compare */
if( !strcmp( resource_table[i].fname, filename ) ) {
memset( kbpos, 0, sizeof *kbpos );
@ -148,12 +150,12 @@ get_keyblock_handle( const char *filename, KBPOS *kbpos )
* Returns: 0 if found, -1 if not found or an errorcode.
*/
int
search_keyblock( PACKET *pkt, KBPOS *kbpos )
search_keyblock( PACKET *pkt, KBPOS *kbpos, int secret )
{
int i, rc, last_rc=-1;
for(i=0; i < MAX_RESOURCES; i++ ) {
if( resource_table[i].used ) {
if( resource_table[i].used && !resource_table[i].secret == !secret ) {
/* note: here we have to add different search functions,
* depending on the type of the resource */
rc = keyring_search( pkt, kbpos, resource_table[i].iobuf );
@ -192,11 +194,36 @@ search_keyblock_byname( KBPOS *kbpos, const char *username )
init_packet( &pkt );
pkt.pkttype = PKT_PUBLIC_CERT;
pkt.pkt.public_cert = pkc;
rc = search_keyblock( &pkt, kbpos );
rc = search_keyblock( &pkt, kbpos, 0 );
free_public_cert(pkc);
return rc;
}
/****************
* Combined function to search for a username and get the position
* of the keyblock. This function does not unprotect the secret key.
*/
int
search_secret_keyblock_byname( KBPOS *kbpos, const char *username )
{
PACKET pkt;
PKT_secret_cert *skc = m_alloc_clear( sizeof *skc );
int rc;
rc = get_seckey_byname( skc, username, 0 );
if( rc ) {
free_secret_cert(skc);
return rc;
}
init_packet( &pkt );
pkt.pkttype = PKT_SECRET_CERT;
pkt.pkt.secret_cert = skc;
rc = search_keyblock( &pkt, kbpos, 1 );
free_secret_cert(skc);
return rc;
}
/****************
* Lock the keyblock; wait until it's available

View file

@ -284,6 +284,23 @@ check_secret_key( PKT_secret_cert *cert )
return rc;
}
/****************
* check wether the secret key is protected.
* Returns: 0 not protected, -1 on error or the protection algorithm
*/
int
is_secret_key_protected( PKT_secret_cert *cert )
{
if( cert->pubkey_algo == PUBKEY_ALGO_ELGAMAL )
return cert->d.elg.is_protected? cert->d.elg.protect_algo : 0;
#ifdef HAVE_RSA_CIPHER
else if( cert->pubkey_algo == PUBKEY_ALGO_RSA )
return cert->d.rsa.is_protected? cert->d.rsa.protect_algo : 0;
#endif
else
return -1; /* unsupported */
}
/****************
* Protect the secret key certificate with the passphrase from DEK

View file

@ -695,6 +695,129 @@ edit_keysigs( const char *username )
}
int
change_passphrase( const char *username )
{
int rc = 0;
KBNODE keyblock = NULL;
KBNODE kbctx, node;
KBPOS kbpos;
PKT_secret_cert *skc;
int any;
u32 skc_keyid[2];
char *answer;
int changed=0;
/* search the userid */
rc = search_secret_keyblock_byname( &kbpos, username );
if( rc ) {
log_error("secret key for user '%s' not found\n", username );
goto leave;
}
/* read the keyblock */
rc = read_keyblock( &kbpos, &keyblock );
if( rc ) {
log_error("error reading the certificate: %s\n", g10_errstr(rc) );
goto leave;
}
/* get the keyid from the keyblock */
for( kbctx=NULL; (node=walk_kbtree( keyblock, &kbctx)) ; ) {
if( node->pkt->pkttype == PKT_SECRET_CERT )
break;
}
if( !node ) {
log_error("Oops; secret key not found anymore!\n");
rc = G10ERR_GENERAL;
goto leave;
}
skc = node->pkt->pkt.secret_cert;
keyid_from_skc( skc, skc_keyid );
tty_printf("sec %4u%c/%08lX %s ",
nbits_from_skc( skc ),
pubkey_letter( skc->pubkey_algo ),
skc_keyid[1], datestr_from_skc(skc) );
{
size_t n;
char *p = get_user_id( skc_keyid, &n );
tty_print_string( p, n );
m_free(p);
tty_printf("\n");
}
clear_kbnode_flags( keyblock );
switch( is_secret_key_protected( skc ) ) {
case -1:
rc = G10ERR_PUBKEY_ALGO;
break;
case 0:
tty_printf("This key is not protected.\n");
break;
default:
tty_printf("Key is protected.\n");
rc = check_secret_key( skc );
break;
}
if( rc )
tty_printf("Can't edit this key: %s\n", g10_errstr(rc));
else {
DEK *dek = m_alloc_secure( sizeof *dek );
tty_printf( "Enter the new passphrase for this secret key.\n\n" );
for(;;) {
dek->algo = CIPHER_ALGO_BLOWFISH;
rc = make_dek_from_passphrase( dek , 2 );
if( rc == -1 ) {
rc = 0;
tty_printf( "You don't want a passphrase -"
" this is probably a *bad* idea!\n\n");
answer = tty_get("Do you really want to do this? ");
tty_kill_prompt();
if( answer_is_yes(answer) )
changed++;
m_free(answer);
break;
}
else if( rc == G10ERR_PASSPHRASE ) {
tty_printf("passphrase not correctly repeated; try again.\n");
}
else if( rc ) {
m_free(dek); dek = NULL;
log_error("Error getting the passphrase: %s\n", g10_errstr(rc));
break;
}
else { /* okay */
skc->d.elg.protect_algo = CIPHER_ALGO_BLOWFISH;
randomize_buffer(skc->d.elg.protect.blowfish.iv, 8, 1);
rc = protect_secret_key( skc, dek );
if( rc )
log_error("protect_secret_key failed: %s\n", g10_errstr(rc) );
else
changed++;
break;
}
}
m_free(dek);
}
if( changed ) {
rc = update_keyblock( &kbpos, keyblock );
if( rc ) {
log_error("update_keyblock failed: %s\n", g10_errstr(rc) );
goto leave;
}
}
leave:
release_kbnode( keyblock );
return rc;
}
/****************
* Create a signature packet for the given public key certificate