From 4c181d51a6f1fd05b7f190a18769ba5e9f892f6a Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Mon, 2 Nov 2020 13:39:58 +0100 Subject: [PATCH] gpg: Do not use weak digest algos if selected by recipient prefs. * g10/misc.c (is_weak_digest): New. (print_digest_algo_note): Use it here. * g10/sig-check.c (check_signature_end_simple): Use it. * g10/sign.c (hash_for): Do not use recipient_digest_algo if it is in the least of weak digest algorithm. -- If a message is signed and encrypted to several recipients, the to be used digest algorithm is deduced from the preferences of the recipient. This is so that all recipients are able to check the the signature. However, if the sender has a declared an algorithm as week, that algorithm shall not be used - in this case we fallback to the standard way of selecting an algorithm. Note that a smarter way of selecting the algo is to check this while figuring out the algorithm - this needs more testing and thus we do it the simple way. Reported-by: Phil Pennock Signed-off-by: Werner Koch Backported-from-master: 15746d60d492f5792e4a179ab0a08801b4049695 --- g10/main.h | 1 + g10/misc.c | 34 +++++++++++++++++++++++----------- g10/sig-check.c | 12 +++++------- g10/sign.c | 13 ++++++++----- 4 files changed, 37 insertions(+), 23 deletions(-) diff --git a/g10/main.h b/g10/main.h index ce029063b..68360e218 100644 --- a/g10/main.h +++ b/g10/main.h @@ -95,6 +95,7 @@ void print_sha1_keysig_rejected_note (void); void print_reported_error (gpg_error_t err, gpg_err_code_t skip_if_ec); void print_further_info (const char *format, ...) GPGRT_ATTR_PRINTF(1,2); void additional_weak_digest (const char* digestname); +int is_weak_digest (digest_algo_t algo); /*-- armor.c --*/ char *make_radix64_string( const byte *data, size_t len ); diff --git a/g10/misc.c b/g10/misc.c index c344ff244..6577bb902 100644 --- a/g10/misc.c +++ b/g10/misc.c @@ -311,12 +311,11 @@ print_cipher_algo_note (cipher_algo_t algo) void print_digest_algo_note (digest_algo_t algo) { - const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo); - const struct weakhash *weak; - if(algo >= 100 && algo <= 110) { static int warn=0; + const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo); + if(!warn) { warn=1; @@ -325,14 +324,13 @@ print_digest_algo_note (digest_algo_t algo) gcry_md_algo_name (galgo)); } } - else - for (weak = opt.weak_digests; weak != NULL; weak = weak->next) - if (weak->algo == galgo) - { - es_fflush (es_stdout); - log_info (_("WARNING: digest algorithm %s is deprecated\n"), - gcry_md_algo_name (galgo)); - } + else if (is_weak_digest (algo)) + { + const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo); + es_fflush (es_stdout); + log_info (_("WARNING: digest algorithm %s is deprecated\n"), + gcry_md_algo_name (galgo)); + } } @@ -1860,3 +1858,17 @@ additional_weak_digest (const char* digestname) weak->next = opt.weak_digests; opt.weak_digests = weak; } + + +/* Return true if ALGO is in the list of weak digests. */ +int +is_weak_digest (digest_algo_t algo) +{ + const enum gcry_md_algos galgo = map_md_openpgp_to_gcry (algo); + const struct weakhash *weak; + + for (weak = opt.weak_digests; weak; weak = weak->next) + if (weak->algo == galgo) + return 1; + return 0; +} diff --git a/g10/sig-check.c b/g10/sig-check.c index e71e662c2..a1dfe3817 100644 --- a/g10/sig-check.c +++ b/g10/sig-check.c @@ -457,16 +457,14 @@ check_signature_end_simple (PKT_public_key *pk, PKT_signature *sig, { gcry_mpi_t result = NULL; int rc = 0; - const struct weakhash *weak; if (!opt.flags.allow_weak_digest_algos) { - for (weak = opt.weak_digests; weak; weak = weak->next) - if (sig->digest_algo == weak->algo) - { - print_digest_rejected_note(sig->digest_algo); - return GPG_ERR_DIGEST_ALGO; - } + if (is_weak_digest (sig->digest_algo)) + { + print_digest_rejected_note (sig->digest_algo); + return GPG_ERR_DIGEST_ALGO; + } } /* For key signatures check that the key has a cert usage. We may diff --git a/g10/sign.c b/g10/sign.c index 4793dd137..8d575a100 100644 --- a/g10/sign.c +++ b/g10/sign.c @@ -583,7 +583,7 @@ hash_for (PKT_public_key *pk) { return opt.def_digest_algo; } - else if (recipient_digest_algo) + else if (recipient_digest_algo && !is_weak_digest (recipient_digest_algo)) { return recipient_digest_algo; } @@ -1095,10 +1095,13 @@ sign_file (ctrl_t ctrl, strlist_t filenames, int detached, strlist_t locusr, single hash for all signatures. All this may well have to change as the cards add algorithms. */ - if (!smartcard || (smartcard && hint.digest_length==20)) - if ( (algo= - select_algo_from_prefs(pk_list,PREFTYPE_HASH,-1,&hint)) > 0) - recipient_digest_algo=algo; + if (!smartcard || (smartcard && hint.digest_length==20) + && (algo = select_algo_from_prefs(pk_list,PREFTYPE_HASH, + -1,&hint)) > 0) + { + /* Note that we later check that the algo is not weak. */ + recipient_digest_algo = algo; + } } }