From f3f1015f6a82482dd6075343d41f4aca1e795e48 Mon Sep 17 00:00:00 2001 From: David Shaw Date: Thu, 26 Dec 2002 22:22:50 +0000 Subject: [PATCH] * keydb.h, getkey.c (key_byname): Flag to enable or disable including disabled keys. Keys specified via keyid (i.e. 0x...) are always included. * getkey.c (get_pubkey_byname, get_seckey_byname2, get_seckey_bynames), keyedit.c (keyedit_menu, menu_addrevoker): Include disabled keys in these functions. * pkclist.c (build_pk_list): Do not include disabled keys for -r or the key prompt. Do include disabled keys for the default key and --encrypt-to. * trustdb.h, trustdb.c (is_disabled): New skipfnc for skipping disabled keys. * gpgv.c (is_disabled): Stub. * keygen.c (keygen_add_key_expire): Properly handle updating a key expiration to a no-expiration value. * keyedit.c (enable_disable_key): Comment. * import.c (import_one): When in interactive mode and --verbose, don't repeat some key information twice. --- g10/ChangeLog | 27 +++++++++++++++++++++++++++ g10/getkey.c | 23 ++++++++++++++++------- g10/gpgv.c | 7 +++++++ g10/import.c | 2 +- g10/keydb.h | 3 ++- g10/keyedit.c | 9 ++++++--- g10/keygen.c | 6 ++++++ g10/pkclist.c | 10 ++++++---- g10/trustdb.c | 38 ++++++++++++++++++++++++++++++++++++++ g10/trustdb.h | 1 + 10 files changed, 110 insertions(+), 16 deletions(-) diff --git a/g10/ChangeLog b/g10/ChangeLog index 526664306..3943b8e52 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,3 +1,30 @@ +2002-12-26 David Shaw + + * keydb.h, getkey.c (key_byname): Flag to enable or disable + including disabled keys. Keys specified via keyid (i.e. 0x...) + are always included. + + * getkey.c (get_pubkey_byname, get_seckey_byname2, + get_seckey_bynames), keyedit.c (keyedit_menu, menu_addrevoker): + Include disabled keys in these functions. + + * pkclist.c (build_pk_list): Do not include disabled keys for -r + or the key prompt. Do include disabled keys for the default key + and --encrypt-to. + + * trustdb.h, trustdb.c (is_disabled): New skipfnc for skipping + disabled keys. + + * gpgv.c (is_disabled): Stub. + + * keygen.c (keygen_add_key_expire): Properly handle updating a key + expiration to a no-expiration value. + + * keyedit.c (enable_disable_key): Comment. + + * import.c (import_one): When in interactive mode and --verbose, + don't repeat some key information twice. + 2002-12-22 Timo Schulz * import.c (print_import_check): New. diff --git a/g10/getkey.c b/g10/getkey.c index ffd5042bc..8df9af58a 100644 --- a/g10/getkey.c +++ b/g10/getkey.c @@ -743,7 +743,8 @@ classify_user_id (const char *name, KEYDB_SEARCH_DESC *desc) static int key_byname( GETKEY_CTX *retctx, STRLIST namelist, - PKT_public_key *pk, PKT_secret_key *sk, int secmode, + PKT_public_key *pk, PKT_secret_key *sk, + int secmode, int include_disabled, KBNODE *ret_kb, KEYDB_HANDLE *ret_kdbhd ) { int rc = 0; @@ -776,6 +777,13 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist, m_free (ctx); return G10ERR_INV_USER_ID; } + if(!include_disabled + && ctx->items[n].mode!=KEYDB_SEARCH_MODE_SHORT_KID + && ctx->items[n].mode!=KEYDB_SEARCH_MODE_LONG_KID + && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR16 + && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR20 + && ctx->items[n].mode!=KEYDB_SEARCH_MODE_FPR) + ctx->items[n].skipfnc=is_disabled; } ctx->kr_handle = keydb_new (secmode); @@ -826,13 +834,14 @@ key_byname( GETKEY_CTX *retctx, STRLIST namelist, int get_pubkey_byname (PKT_public_key *pk, const char *name, KBNODE *ret_keyblock, - KEYDB_HANDLE *ret_kdbhd ) + KEYDB_HANDLE *ret_kdbhd, int include_disabled ) { int rc; STRLIST namelist = NULL; add_to_strlist( &namelist, name ); - rc = key_byname( NULL, namelist, pk, NULL, 0, ret_keyblock, ret_kdbhd); + rc = key_byname( NULL, namelist, pk, NULL, 0, + include_disabled, ret_keyblock, ret_kdbhd); free_strlist( namelist ); return rc; } @@ -841,7 +850,7 @@ int get_pubkey_bynames( GETKEY_CTX *retctx, PKT_public_key *pk, STRLIST names, KBNODE *ret_keyblock ) { - return key_byname( retctx, names, pk, NULL, 0, ret_keyblock, NULL); + return key_byname( retctx, names, pk, NULL, 0, 1, ret_keyblock, NULL); } int @@ -998,7 +1007,7 @@ get_seckey_byname2( GETKEY_CTX *retctx, if( !name && opt.def_secret_key && *opt.def_secret_key ) { add_to_strlist( &namelist, opt.def_secret_key ); - rc = key_byname( retctx, namelist, NULL, sk, 1, retblock, NULL ); + rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL ); } else if( !name ) { /* use the first one as default key */ struct getkey_ctx_s ctx; @@ -1019,7 +1028,7 @@ get_seckey_byname2( GETKEY_CTX *retctx, } else { add_to_strlist( &namelist, name ); - rc = key_byname( retctx, namelist, NULL, sk, 1, retblock, NULL ); + rc = key_byname( retctx, namelist, NULL, sk, 1, 1, retblock, NULL ); } free_strlist( namelist ); @@ -1041,7 +1050,7 @@ int get_seckey_bynames( GETKEY_CTX *retctx, PKT_secret_key *sk, STRLIST names, KBNODE *ret_keyblock ) { - return key_byname( retctx, names, NULL, sk, 1, ret_keyblock, NULL ); + return key_byname( retctx, names, NULL, sk, 1, 1, ret_keyblock, NULL ); } diff --git a/g10/gpgv.c b/g10/gpgv.c index 4ed71b8c7..389cb40f8 100644 --- a/g10/gpgv.c +++ b/g10/gpgv.c @@ -231,6 +231,13 @@ check_signatures_trust( PKT_signature *sig ) * We don't have the trustdb , so we have to provide some stub functions * instead */ + +int +is_disabled(void *dummy,u32 *keyid) +{ + return 0; +} + int get_validity_info (PKT_public_key *pk, const byte *namehash ) { diff --git a/g10/import.c b/g10/import.c index f06799df0..46e4b2530 100644 --- a/g10/import.c +++ b/g10/import.c @@ -614,7 +614,7 @@ import_one( const char *fname, KBNODE keyblock, log_info(_("NOTE: Elgamal primary key detected - " "this may take some time to import\n")); - if( opt.verbose ) { + if( opt.verbose && !opt.interactive ) { log_info( "pub %4u%c/%08lX %s ", nbits_from_pk( pk ), pubkey_letter( pk->pubkey_algo ), diff --git a/g10/keydb.h b/g10/keydb.h index a3d48508c..d43604a22 100644 --- a/g10/keydb.h +++ b/g10/keydb.h @@ -198,7 +198,8 @@ int get_pubkey( PKT_public_key *pk, u32 *keyid ); int get_pubkey_fast ( PKT_public_key *pk, u32 *keyid ); KBNODE get_pubkeyblock( u32 *keyid ); int get_pubkey_byname( PKT_public_key *pk, const char *name, - KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd); + KBNODE *ret_keyblock, KEYDB_HANDLE *ret_kdbhd, + int include_disabled ); int get_pubkey_bynames( GETKEY_CTX *rx, PKT_public_key *pk, STRLIST names, KBNODE *ret_keyblock ); int get_pubkey_next( GETKEY_CTX ctx, PKT_public_key *pk, KBNODE *ret_keyblock ); diff --git a/g10/keyedit.c b/g10/keyedit.c index e25debf90..87830e2cc 100644 --- a/g10/keyedit.c +++ b/g10/keyedit.c @@ -1105,7 +1105,7 @@ keyedit_menu( const char *username, STRLIST locusr, STRLIST commands, } /* get the public key */ - rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd); + rc = get_pubkey_byname (NULL, username, &keyblock, &kdbhd, 1); if( rc ) goto leave; if( fix_keyblock( keyblock ) ) @@ -2478,7 +2478,7 @@ menu_addrevoker( KBNODE pub_keyblock, KBNODE sec_keyblock, int sensitive ) if(answer[0]=='\0' || answer[0]=='\004') goto fail; - rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL); + rc=get_pubkey_byname(revoker_pk,answer,NULL,NULL,1); if(rc) { @@ -3376,7 +3376,10 @@ menu_revkey( KBNODE pub_keyblock, KBNODE sec_keyblock ) return changed; } - +/* Note that update_ownertrust is going to mark the trustdb dirty when + enabling or disabling a key. This is arguably sub-optimal as + disabled keys are still counted in the web of trust, but perhaps + not worth adding extra complexity to change. -ds */ static int enable_disable_key( KBNODE keyblock, int disable ) { diff --git a/g10/keygen.c b/g10/keygen.c index 82d11303f..c1a6ee540 100644 --- a/g10/keygen.c +++ b/g10/keygen.c @@ -163,6 +163,12 @@ keygen_add_key_expire( PKT_signature *sig, void *opaque ) buf[3] = u & 0xff; build_sig_subpkt( sig, SIGSUBPKT_KEY_EXPIRE, buf, 4 ); } + else + { + /* Make sure we don't leave a key expiration subpacket lying + around */ + delete_sig_subpkt (sig->hashed, SIGSUBPKT_KEY_EXPIRE); + } return 0; } diff --git a/g10/pkclist.c b/g10/pkclist.c index 9ed8ef3a4..f5c596027 100644 --- a/g10/pkclist.c +++ b/g10/pkclist.c @@ -826,7 +826,8 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) else if( (use & PUBKEY_USAGE_ENC) && !opt.no_encrypt_to ) { pk = m_alloc_clear( sizeof *pk ); pk->req_usage = use; - if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL )) ) { + /* We can encrypt-to a disabled key */ + if( (rc = get_pubkey_byname( pk, rov->d, NULL, NULL, 1 )) ) { free_public_key( pk ); pk = NULL; log_error(_("%s: skipped: %s\n"), rov->d, g10_errstr(rc) ); write_status_text_and_buffer (STATUS_INV_RECP, "0 ", @@ -908,7 +909,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) free_public_key( pk ); pk = m_alloc_clear( sizeof *pk ); pk->req_usage = use; - rc = get_pubkey_byname( pk, answer, NULL, NULL ); + rc = get_pubkey_byname( pk, answer, NULL, NULL, 0 ); if( rc ) tty_printf(_("No such user ID.\n")); else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { @@ -981,7 +982,8 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) else if( !any_recipients && (def_rec = default_recipient()) ) { pk = m_alloc_clear( sizeof *pk ); pk->req_usage = use; - rc = get_pubkey_byname( pk, def_rec, NULL, NULL ); + /* The default recipient may be disabled */ + rc = get_pubkey_byname( pk, def_rec, NULL, NULL, 1 ); if( rc ) log_error(_("unknown default recipient `%s'\n"), def_rec ); else if( !(rc=check_pubkey_algo2(pk->pubkey_algo, use)) ) { @@ -1014,7 +1016,7 @@ build_pk_list( STRLIST rcpts, PK_LIST *ret_pk_list, unsigned use ) pk = m_alloc_clear( sizeof *pk ); pk->req_usage = use; - if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL )) ) { + if( (rc = get_pubkey_byname( pk, remusr->d, NULL, NULL, 0 )) ) { free_public_key( pk ); pk = NULL; log_error(_("%s: skipped: %s\n"), remusr->d, g10_errstr(rc) ); write_status_text_and_buffer (STATUS_INV_RECP, "0 ", diff --git a/g10/trustdb.c b/g10/trustdb.c index c3041370c..ed0ccd15d 100644 --- a/g10/trustdb.c +++ b/g10/trustdb.c @@ -893,6 +893,44 @@ clear_validity (PKT_public_key *pk) ********* Query trustdb values ************** ***********************************************/ +/* Return true if key is disabled */ +int +is_disabled(void *dummy,u32 *keyid) +{ + int rc; + TRUSTREC trec; + int disabled=0; /* default to not disabled */ + PKT_public_key *pk=m_alloc_clear(sizeof(PKT_public_key)); + + init_trustdb (); + + /* Note that get_pubkey returns the main key if keyid points to a + subkey. That's a good thing here. */ + rc = get_pubkey(pk, keyid); + if(rc) + { + log_error("error checking disabled status of %08lX: %s\n", + (ulong)keyid[1],g10_errstr(rc)); + goto leave; + } + + rc = read_trust_record (pk, &trec); + if (rc && rc != -1) + { + tdbio_invalid (); + goto leave; + } + if (rc == -1) /* no record found, so assume not disabled */ + goto leave; + + if(trec.r.trust.ownertrust & TRUST_FLAG_DISABLED) + disabled=1; + + leave: + free_public_key(pk); + return disabled; +} + /* * Return the validity information for PK. If the namehash is not * NULL, the validity of the corresponsing user ID is returned, diff --git a/g10/trustdb.h b/g10/trustdb.h index 414543844..3ca674ece 100644 --- a/g10/trustdb.h +++ b/g10/trustdb.h @@ -51,6 +51,7 @@ const char *trust_string (unsigned int value); void revalidation_mark (void); int trustdb_pending_check(void); +int is_disabled(void *dummy,u32 *keyid); unsigned int get_validity (PKT_public_key *pk, const byte *namehash); int get_validity_info (PKT_public_key *pk, const byte *namehash);