aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/gpg.texi17
-rw-r--r--doc/gpgv.texi8
-rw-r--r--g10/gpg.c7
-rw-r--r--g10/gpgv.c5
-rw-r--r--g10/main.h9
-rw-r--r--g10/misc.c38
-rw-r--r--g10/options.h1
-rw-r--r--g10/sig-check.c25
8 files changed, 92 insertions, 18 deletions
diff --git a/doc/gpg.texi b/doc/gpg.texi
index 93baf16e1..fd6508349 100644
--- a/doc/gpg.texi
+++ b/doc/gpg.texi
@@ -2610,9 +2610,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
diff --git a/doc/gpgv.texi b/doc/gpgv.texi
index 0cb2360f8..7172a8cad 100644
--- a/doc/gpgv.texi
+++ b/doc/gpgv.texi
@@ -115,6 +115,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 ce33e12d4..0095d3475 100644
--- a/g10/gpg.c
+++ b/g10/gpg.c
@@ -377,6 +377,7 @@ enum cmd_and_opt_values
oAllowMultipleMessages,
oNoAllowMultipleMessages,
oAllowWeakDigestAlgos,
+ oWeakDigest,
oNoop
};
@@ -689,6 +690,7 @@ static ARGPARSE_OPTS opts[] = {
{ oPersonalCipherPreferences, "personal-cipher-preferences", 2, "@"},
{ oPersonalDigestPreferences, "personal-digest-preferences", 2, "@"},
{ oPersonalCompressPreferences, "personal-compress-preferences", 2, "@"},
+ { oWeakDigest, "weak-digest", 2, "@"},
/* Aliases. I constantly mistype these, and assume other people
do as well. */
{ oPersonalCipherPreferences, "personal-cipher-prefs", 2, "@"},
@@ -1923,6 +1925,8 @@ main (int argc, char **argv )
#endif
opt.disable_keypad = 1; /* No keypad support; use gpg2 instead. */
#endif /*ENABLE_CARD_SUPPORT*/
+ opt.weak_digests = NULL;
+ additional_weak_digest("MD5");
/* check whether we have a config file on the commandline */
orig_argc = argc;
@@ -2793,6 +2797,9 @@ main (int argc, char **argv )
case oDisplay: opt.display = pargs.r.ret_str; break;
case oTTYname: opt.ttyname = pargs.r.ret_str; break;
case oTTYtype: opt.ttytype = pargs.r.ret_str; break;
+ case oWeakDigest:
+ additional_weak_digest(pargs.r.ret_str);
+ break;
case oLCctype: opt.lc_ctype = pargs.r.ret_str; break;
case oLCmessages: opt.lc_messages = pargs.r.ret_str; break;
case oGroup: add_group(pargs.r.ret_str); break;
diff --git a/g10/gpgv.c b/g10/gpgv.c
index b67985397..b2721bae9 100644
--- a/g10/gpgv.c
+++ b/g10/gpgv.c
@@ -60,6 +60,7 @@ enum cmd_and_opt_values { aNull = 0,
oStatusFD,
oLoggerFD,
oHomedir,
+ oWeakDigest,
aTest };
@@ -75,6 +76,7 @@ static ARGPARSE_OPTS opts[] = {
{ oStatusFD, "status-fd" ,1, N_("|FD|write status info to this FD") },
{ oLoggerFD, "logger-fd",1, "@" },
{ oHomedir, "homedir", 2, "@" }, /* defaults to "~/.gnupg" */
+ { oWeakDigest, "weak-digest", 2, "@" }, /* defaults to "~/.gnupg" */
{0} };
@@ -143,6 +145,7 @@ main( int argc, char **argv )
opt.keyserver_options.options|=KEYSERVER_AUTO_KEY_RETRIEVE;
opt.trust_model = TM_ALWAYS;
opt.batch = 1;
+ opt.weak_digests = NULL;
opt.homedir = default_homedir ();
@@ -151,6 +154,7 @@ main( int argc, char **argv )
dotlock_disable ();
set_native_charset (NULL); /* Try to auto set the character set */
+ additional_weak_digest("MD5");
pargs.argc = &argc;
pargs.argv = &argv;
@@ -164,6 +168,7 @@ main( int argc, char **argv )
case oStatusFD: set_status_fd( pargs.r.ret_int ); break;
case oLoggerFD: log_set_logfile( NULL, pargs.r.ret_int ); 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 = 2; break;
}
diff --git a/g10/main.h b/g10/main.h
index 21ec1f077..a0b96f984 100644
--- a/g10/main.h
+++ b/g10/main.h
@@ -60,6 +60,14 @@ struct groupitem
struct groupitem *next;
};
+struct weakhash
+{
+ int algo;
+ int rejection_shown;
+ struct weakhash *next;
+};
+
+
/*-- gpg.c --*/
extern int g10_errors_seen;
@@ -71,6 +79,7 @@ extern int g10_errors_seen;
void print_pubkey_algo_note( int algo );
void print_cipher_algo_note( int algo );
void print_digest_algo_note( int algo );
+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 2b38a8fcc..c863be43c 100644
--- a/g10/misc.c
+++ b/g10/misc.c
@@ -332,6 +332,8 @@ print_cipher_algo_note( int algo )
void
print_digest_algo_note( int algo )
{
+ const struct weakhash *weak;
+
if(algo >= 100 && algo <= 110)
{
static int warn=0;
@@ -342,8 +344,11 @@ print_digest_algo_note( int algo )
digest_algo_to_string(algo));
}
}
- else if(algo==DIGEST_ALGO_MD5)
- md5_digest_warn (1);
+ else
+ for (weak = opt.weak_digests; weak; weak = weak->next)
+ if (weak->algo == algo)
+ log_info (_("WARNING: digest algorithm %s is deprecated\n"),
+ digest_algo_to_string(algo));
}
/* Return a string which is used as a kind of process ID */
@@ -1310,3 +1315,32 @@ path_access(const char *file,int mode)
}
#endif /*ndef __VMS*/
+
+/* Ignore signatures and certifications made over certain digest
+ * algorithms. This allows users to deprecate support for algorithms
+ * they are not willing to rely on.
+ */
+void
+additional_weak_digest (const char* digestname)
+{
+ struct weakhash *weak = NULL;
+ const int algo = string_to_digest_algo(digestname);
+
+ if (algo == 0)
+ {
+ log_error(_("Unknown weak digest '%s'\n"), digestname);
+ return;
+ }
+
+ /* Check to ensure it's not already present. */
+ for (weak = opt.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->rejection_shown = 0;
+ weak->next = opt.weak_digests;
+ opt.weak_digests = weak;
+}
diff --git a/g10/options.h b/g10/options.h
index 26d65e560..5aa3a048d 100644
--- a/g10/options.h
+++ b/g10/options.h
@@ -164,6 +164,7 @@ struct
prefitem_t *personal_cipher_prefs;
prefitem_t *personal_digest_prefs;
prefitem_t *personal_compress_prefs;
+ struct weakhash *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 94f0cc5ff..6bac63034 100644
--- a/g10/sig-check.c
+++ b/g10/sig-check.c
@@ -239,26 +239,25 @@ do_check( PKT_public_key *pk, PKT_signature *sig, MD_HANDLE digest,
{
MPI result = NULL;
int rc=0;
+ struct weakhash *weak;
if( (rc=do_check_messages(pk,sig,r_expired,r_revoked)) )
return rc;
- if (sig->digest_algo == DIGEST_ALGO_MD5
- && !opt.flags.allow_weak_digest_algos)
- {
- static int shown;
-
- if (!shown)
+ if (!opt.flags.allow_weak_digest_algos)
+ for (weak = opt.weak_digests; weak; weak = weak->next)
+ if (sig->digest_algo == weak->algo)
{
- log_info
- (_("Note: signatures using the %s algorithm are rejected\n"),
- "MD5");
- shown = 1;
+ if (!weak->rejection_shown)
+ {
+ log_info
+ (_("Note: signatures using the %s algorithm are rejected\n"),
+ digest_algo_to_string(sig->digest_algo));
+ weak->rejection_shown = 1;
+ }
+ return G10ERR_DIGEST_ALGO;
}
- return G10ERR_DIGEST_ALGO;
- }
-
/* make sure the digest algo is enabled (in case of a detached signature)*/
md_enable( digest, sig->digest_algo );