diff --git a/g10/ChangeLog b/g10/ChangeLog index 2929230fa..a7c84d1fd 100644 --- a/g10/ChangeLog +++ b/g10/ChangeLog @@ -1,5 +1,13 @@ 2004-02-12 David Shaw + * import.c (check_prefs): New function to check preferences on a + public key to ensure that it does not advertise any that we cannot + fulfill. Use the keyedit command list function to optionally + rewrite the prefs. + (import_one, import_secret_one): Use it here when importing a + public key that we have the secret half of, or when importing a + secret key that we have the public half of. + * main.h, keyedit.c (keyedit_menu): Remove sign_mode and enhance the more general command list functionality to replace it. diff --git a/g10/import.c b/g10/import.c index 75f94908e..d57ae6c9e 100644 --- a/g10/import.c +++ b/g10/import.c @@ -531,6 +531,114 @@ print_import_check (PKT_public_key * pk, PKT_user_id * id) m_free (buf); } +static void +check_prefs(KBNODE keyblock) +{ + KBNODE node; + u32 keyid[2]; + int problem=0; + + merge_keys_and_selfsig(keyblock); + keyid_from_pk(keyblock->pkt->pkt.public_key,keyid); + + for(node=keyblock;node;node=node->next) + { + if(node->pkt->pkttype==PKT_USER_ID + && node->pkt->pkt.user_id->created + && node->pkt->pkt.user_id->prefs) + { + PKT_user_id *uid=node->pkt->pkt.user_id; + prefitem_t *prefs=uid->prefs; + char *user=utf8_to_native(uid->name,strlen(uid->name),0); + + for(;prefs->type;prefs++) + { + char num[10]; /* prefs->value is a byte, so we're over + safe here */ + + sprintf(num,"%u",prefs->value); + + if(prefs->type==PREFTYPE_SYM) + { + if(check_cipher_algo(prefs->value)) + { + const char *algo=cipher_algo_to_string(prefs->value); + if(!problem) + log_info(_("WARNING: key %08lX contains preferences" + " for unavailable algorithms:\n"), + (ulong)keyid[1]); + log_info(_(" \"%s\": preference for cipher" + " algorithm %s\n"),user,algo?algo:num); + problem=1; + } + } + else if(prefs->type==PREFTYPE_HASH) + { + if(check_digest_algo(prefs->value)) + { + const char *algo=digest_algo_to_string(prefs->value); + if(!problem) + log_info(_("WARNING: key %08lX contains preferences" + " for unavailable algorithms:\n"), + (ulong)keyid[1]); + log_info(_(" \"%s\": preference for digest" + " algorithm %s\n"),user,algo?algo:num); + problem=1; + } + } + else if(prefs->type==PREFTYPE_ZIP) + { + if(check_compress_algo(prefs->value)) + { + const char *algo=compress_algo_to_string(prefs->value); + if(!problem) + log_info(_("WARNING: key %08lX contains preferences" + " for unavailable algorithms:\n"), + (ulong)keyid[1]); + log_info(_(" \"%s\": preference for compression" + " algorithm %s\n"),user,algo?algo:num); + problem=1; + } + } + } + + m_free(user); + } + } + + if(problem) + { + log_info(_("It strongly suggested that you update" + " your preferences and re-distribute\n")); + log_info(_("this key to avoid potential algorithm" + " mismatch problems.\n")); + + if(!opt.batch) + { + STRLIST sl=NULL,locusr=NULL; + size_t fprlen=0; + byte fpr[MAX_FINGERPRINT_LEN],*p; + char username[(MAX_FINGERPRINT_LEN*2)+1]; + int i; + + p=fingerprint_from_pk(keyblock->pkt->pkt.public_key,fpr,&fprlen); + for(i=0;iunchanged++; - } + } + keydb_release (hd); hd = NULL; } leave: + + /* Now that the key is definitely incorporated into the keydb, we + need to check if a designated revocation is present or if the + prefs are not rational so we can warn the user. */ + if(mod_key) - revocation_present(keyblock_orig); + { + revocation_present(keyblock_orig); + if(seckey_available(keyid)==0) + check_prefs(keyblock_orig); + } else if(new_key) - revocation_present(keyblock); + { + revocation_present(keyblock); + if(seckey_available(keyid)==0) + check_prefs(keyblock); + } release_kbnode( keyblock_orig ); free_public_key( pk_orig ); @@ -941,6 +1066,15 @@ import_secret_one( const char *fname, KBNODE keyblock, release_kbnode(pub_keyblock); } + /* Now that the key is definitely incorporated into the keydb, + if we have the public part of this key, we need to check if + the prefs are rational. */ + node=get_pubkeyblock(keyid); + if(node) + { + check_prefs(node); + release_kbnode(node); + } } else if( !rc ) { /* we can't merge secret keys */ log_error( _("key %08lX: already in secret keyring\n"),