aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--doc/gpg.texi17
-rw-r--r--doc/gpgv.texi8
-rw-r--r--g10/gpg.c6
-rw-r--r--g10/gpgv.c5
-rw-r--r--g10/main.h7
-rw-r--r--g10/misc.c51
-rw-r--r--g10/options.h1
-rw-r--r--g10/sig-check.c11
8 files changed, 96 insertions, 10 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index a70204043..ffd7a976e 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2789,9 +2789,20 @@ message was tampered with intentionally by an attacker.
@item --allow-weak-digest-algos
@opindex allow-weak-digest-algos
-Signatures made with the broken MD5 algorithm are normally rejected
-with an ``invalid digest algorithm'' message. This option allows the
-verification of signatures made with such weak algorithms.
+Signatures made with known-weak digest algorithms are normally
+rejected with an ``invalid digest algorithm'' message. This option
+allows the verification of signatures made with such weak algorithms.
+MD5 is the only digest algorithm considered weak by default. See also
+@option{--weak-digest} to reject other digest algorithms.
+
+@item --weak-digest @code{name}
+@opindex weak-digest
+Treat the specified digest algorithm as weak. Signatures made over
+weak digests algorithms are normally rejected. This option can be
+supplied multiple times if multiple algorithms should be considered
+weak. See also @option{--allow-weak-digest-algos} to disable
+rejection of weak digests. MD5 is always considered weak, and does
+not need to be listed explicitly.
@item --no-default-keyring
@opindex no-default-keyring
diff --git a/doc/gpgv.texi b/doc/gpgv.texi
index 6bcbc0add..280966bf8 100644
--- a/doc/gpgv.texi
+++ b/doc/gpgv.texi
@@ -118,6 +118,14 @@ checks into warnings.
@include opt-homedir.texi
+@item --weak-digest @code{name}
+@opindex weak-digest
+Treat the specified digest algorithm as weak. Signatures made over
+weak digests algorithms are normally rejected. This option can be
+supplied multiple times if multiple algorithms should be considered
+weak. MD5 is always considered weak, and does not need to be listed
+explicitly.
+
@end table
@mansect return value
diff --git a/g10/gpg.c b/g10/gpg.c
index ada913c0a..cb610a11b 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -389,6 +389,7 @@ enum cmd_and_opt_values
oPrintDANERecords,
oTOFUDefaultPolicy,
oTOFUDBFormat,
+ oWeakDigest,
oNoop
};
@@ -749,6 +750,7 @@ static ARGPARSE_OPTS opts[] = {
ARGPARSE_s_s (oPersonalCompressPreferences,
"personal-compress-preferences", "@"),
ARGPARSE_s_s (oFakedSystemTime, "faked-system-time", "@"),
+ ARGPARSE_s_s (oWeakDigest, "weak-digest","@"),
/* Aliases. I constantly mistype these, and assume other people do
as well. */
@@ -2208,6 +2210,7 @@ main (int argc, char **argv)
set_homedir (default_homedir ());
opt.passphrase_repeat = 1;
opt.emit_version = 1; /* Limit to the major number. */
+ opt.additional_weak_digests = NULL;
/* Check whether we have a config file on the command line. */
orig_argc = argc;
@@ -3124,6 +3127,9 @@ main (int argc, char **argv)
break;
case oAgentProgram: opt.agent_program = pargs.r.ret_str; break;
case oDirmngrProgram: opt.dirmngr_program = pargs.r.ret_str; break;
+ case oWeakDigest:
+ additional_weak_digest(pargs.r.ret_str);
+ break;
case oDisplay:
set_opt_session_env ("DISPLAY", pargs.r.ret_str);
diff --git a/g10/gpgv.c b/g10/gpgv.c
index 0807622a6..23e761047 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -61,6 +61,7 @@ enum cmd_and_opt_values {
oStatusFD,
oLoggerFD,
oHomedir,
+ oWeakDigest,
aTest
};
@@ -78,6 +79,7 @@ static ARGPARSE_OPTS opts[] = {
N_("|FD|write status info to this FD")),
ARGPARSE_s_i (oLoggerFD, "logger-fd", "@"),
ARGPARSE_s_s (oHomedir, "homedir", "@"),
+ ARGPARSE_s_s (oWeakDigest, "weak-digest", "@"),
ARGPARSE_end ()
};
@@ -192,6 +194,9 @@ main( int argc, char **argv )
log_set_fd (translate_sys2libc_fd_int (pargs.r.ret_int, 1));
break;
case oHomedir: opt.homedir = pargs.r.ret_str; break;
+ case oWeakDigest:
+ additional_weak_digest(pargs.r.ret_str);
+ break;
case oIgnoreTimeConflict: opt.ignore_time_conflict = 1; break;
default : pargs.err = ARGPARSE_PRINT_ERROR; break;
}
diff --git a/g10/main.h b/g10/main.h
index c9521ad1d..0226c6418 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -69,6 +69,12 @@ struct groupitem
struct groupitem *next;
};
+struct weakhash
+{
+ enum gcry_md_algos algo;
+ struct weakhash *next;
+};
+
/*-- gpg.c --*/
extern int g10_errors_seen;
@@ -82,6 +88,7 @@ void print_pubkey_algo_note (pubkey_algo_t algo);
void print_cipher_algo_note (cipher_algo_t algo);
void print_digest_algo_note (digest_algo_t algo);
void print_md5_rejected_note (void);
+void additional_weak_digest (const char* digestname);
/*-- armor.c --*/
char *make_radix64_string( const byte *data, size_t len );
diff --git a/g10/misc.c b/g10/misc.c
index 9134b2823..c135059d8 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -307,6 +307,10 @@ print_cipher_algo_note (cipher_algo_t algo)
void
print_digest_algo_note (digest_algo_t algo)
{
+ int deprecated = 0;
+ 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;
@@ -315,14 +319,21 @@ print_digest_algo_note (digest_algo_t algo)
warn=1;
es_fflush (es_stdout);
log_info (_("WARNING: using experimental digest algorithm %s\n"),
- gcry_md_algo_name (algo));
+ gcry_md_algo_name (galgo));
}
}
- else if(algo==DIGEST_ALGO_MD5)
+ else if(algo == DIGEST_ALGO_MD5)
+ deprecated = 1;
+ else
+ for (weak = opt.additional_weak_digests; weak != NULL; weak = weak->next)
+ if (weak->algo == galgo)
+ deprecated = 1;
+
+ if (deprecated)
{
es_fflush (es_stdout);
log_info (_("WARNING: digest algorithm %s is deprecated\n"),
- gcry_md_algo_name (algo));
+ gcry_md_algo_name (galgo));
}
}
@@ -1676,3 +1687,37 @@ ecdsa_qbits_from_Q (unsigned int qbits)
qbits /= 2;
return qbits;
}
+
+
+/* Ignore signatures and certifications made over certain digest
+ * algorithms by default, MD5 is considered weak. This allows users
+ * to deprecate support for other algorithms as well.
+ */
+void
+additional_weak_digest (const char* digestname)
+{
+ struct weakhash *weak = NULL;
+ const enum gcry_md_algos algo = string_to_digest_algo(digestname);
+
+ if (algo == GCRY_MD_MD5)
+ return; /* MD5 is always considered weak, no need to add it. */
+
+ if (algo == GCRY_MD_NONE)
+ {
+ log_error(_("Unknown weak digest '%s'\n"), digestname);
+ return;
+ }
+
+ /* Check to ensure it's not already present. */
+ for (weak = opt.additional_weak_digests; weak != NULL; weak = weak->next)
+ {
+ if (algo == weak->algo)
+ return;
+ }
+
+ /* Add it to the head of the list. */
+ weak = xmalloc(sizeof(*weak));
+ weak->algo = algo;
+ weak->next = opt.additional_weak_digests;
+ opt.additional_weak_digests = weak;
+}
diff --git a/g10/options.h b/g10/options.h
index 2135aa0b9..c1ea9ddd8 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -170,6 +170,7 @@ struct
prefitem_t *personal_cipher_prefs;
prefitem_t *personal_digest_prefs;
prefitem_t *personal_compress_prefs;
+ struct weakhash *additional_weak_digests;
int no_perm_warn;
int no_mdc_warn;
char *temp_dir;
diff --git a/g10/sig-check.c b/g10/sig-check.c
index d45a9f378..84930d615 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -274,15 +274,18 @@ do_check( PKT_public_key *pk, PKT_signature *sig, gcry_md_hd_t digest,
{
gcry_mpi_t result = NULL;
int rc = 0;
+ const struct weakhash *weak;
if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
return rc;
- if (sig->digest_algo == GCRY_MD_MD5
- && !opt.flags.allow_weak_digest_algos)
+ if (!opt.flags.allow_weak_digest_algos)
{
- print_md5_rejected_note ();
- return GPG_ERR_DIGEST_ALGO;
+ if (sig->digest_algo == GCRY_MD_MD5)
+ return GPG_ERR_DIGEST_ALGO;
+ for (weak = opt.additional_weak_digests; weak; weak = weak->next)
+ if (sig->digest_algo == weak->algo)
+ return GPG_ERR_DIGEST_ALGO;
}
/* Make sure the digest algo is enabled (in case of a detached