From f410c3dbf1387395a6840919022b28ad4ee7cbf7 Mon Sep 17 00:00:00 2001 From: Nikos Mavrogiannopoulos Date: Mon, 13 Mar 2017 17:13:48 +0100 Subject: Introduced flag GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1 This allows performing a verification with only SHA1 allowed from the broken algorithms. This can be used to fine-tune verification in case default verification fails, to detect whether the failed algorithm was SHA1. Signed-off-by: Nikos Mavrogiannopoulos --- doc/cha-cert-auth.texi | 1 + doc/cha-gtls-app.texi | 3 +++ lib/includes/gnutls/x509.h | 5 ++++- lib/priority.c | 5 +++++ lib/priority_options.gperf | 1 + lib/x509/verify.c | 12 ++++++++++-- 6 files changed, 24 insertions(+), 3 deletions(-) diff --git a/doc/cha-cert-auth.texi b/doc/cha-cert-auth.texi index 75c118dedb..1da3ce3bd9 100644 --- a/doc/cha-cert-auth.texi +++ b/doc/cha-cert-auth.texi @@ -631,6 +631,7 @@ certificate chain, you can call @itemize @item @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2} @item @code{GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5} +@item @code{GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1} @item @code{GNUTLS_VERIFY_ALLOW_BROKEN} @end itemize as in the following example: diff --git a/doc/cha-gtls-app.texi b/doc/cha-gtls-app.texi index a205667a01..fb4a5aa2f5 100644 --- a/doc/cha-gtls-app.texi +++ b/doc/cha-gtls-app.texi @@ -1362,6 +1362,9 @@ SHA1) in certificate chains. @item %VERIFY_ALLOW_SIGN_RSA_MD5 @tab will allow RSA-MD5 signatures in certificate chains. +@item %VERIFY_ALLOW_SIGN_WITH_SHA1 @tab +will allow signatures with SHA1 hash algorithm in certificate chains. + @item %VERIFY_DISABLE_CRL_CHECKS @tab will disable CRL or OCSP checks in the verification of the certificate chain. diff --git a/lib/includes/gnutls/x509.h b/lib/includes/gnutls/x509.h index 1972c91140..e865d28f4f 100644 --- a/lib/includes/gnutls/x509.h +++ b/lib/includes/gnutls/x509.h @@ -891,6 +891,8 @@ int gnutls_x509_crl_set_number(gnutls_x509_crl_t crl, * using the broken MD2 algorithm. * @GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5: Allow certificates to be signed * using the broken MD5 algorithm. + * @GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1: Allow certificates to be signed + * using the broken SHA1 hash algorithm. * @GNUTLS_VERIFY_ALLOW_BROKEN: Allow certificates to be signed * using any broken algorithm. * @GNUTLS_VERIFY_DISABLE_TIME_CHECKS: Disable checking of activation @@ -923,7 +925,8 @@ typedef enum gnutls_certificate_verify_flags { GNUTLS_VERIFY_DO_NOT_ALLOW_UNSORTED_CHAIN = 1 << 11, GNUTLS_VERIFY_DO_NOT_ALLOW_WILDCARDS = 1 << 12, GNUTLS_VERIFY_USE_TLS1_RSA = 1 << 13, - GNUTLS_VERIFY_IGNORE_UNKNOWN_CRIT_EXTENSIONS = 1 << 14 + GNUTLS_VERIFY_IGNORE_UNKNOWN_CRIT_EXTENSIONS = 1 << 14, + GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1 = 1 << 15, /* cannot exceed 2^24 due to GNUTLS_PROFILE_TO_VFLAGS() */ } gnutls_certificate_verify_flags; diff --git a/lib/priority.c b/lib/priority.c index a80194fd88..3c9265c08f 100644 --- a/lib/priority.c +++ b/lib/priority.c @@ -862,6 +862,11 @@ static void enable_verify_allow_rsa_md5(gnutls_priority_t c) c->additional_verify_flags |= GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5; } +static void enable_verify_allow_sha1(gnutls_priority_t c) +{ + c->additional_verify_flags |= + GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1; +} static void enable_verify_allow_broken(gnutls_priority_t c) { c->additional_verify_flags |= diff --git a/lib/priority_options.gperf b/lib/priority_options.gperf index 0808ffc87a..9de43785bb 100644 --- a/lib/priority_options.gperf +++ b/lib/priority_options.gperf @@ -15,6 +15,7 @@ NO_SESSION_HASH, enable_no_ext_master_secret STATELESS_COMPRESSION, enable_stateless_compression VERIFY_ALLOW_BROKEN, enable_verify_allow_broken VERIFY_ALLOW_SIGN_RSA_MD5, enable_verify_allow_rsa_md5 +VERIFY_ALLOW_SIGN_WITH_SHA1, enable_verify_allow_sha1 VERIFY_DISABLE_CRL_CHECKS, disable_crl_checks SSL3_RECORD_VERSION, enable_ssl3_record_version LATEST_RECORD_VERSION, enable_latest_record_version diff --git a/lib/x509/verify.c b/lib/x509/verify.c index 2ba65aca50..638aa1e5a2 100644 --- a/lib/x509/verify.c +++ b/lib/x509/verify.c @@ -390,6 +390,12 @@ static unsigned int check_time_status(gnutls_x509_crt_t crt, time_t now) static int is_broken_allowed(gnutls_sign_algorithm_t sig, unsigned int flags) { + gnutls_digest_algorithm_t hash; + + /* we have a catch all */ + if ((flags & GNUTLS_VERIFY_ALLOW_BROKEN) == GNUTLS_VERIFY_ALLOW_BROKEN) + return 1; + /* the first two are for backwards compatibility */ if ((sig == GNUTLS_SIGN_RSA_MD2) && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD2)) @@ -397,9 +403,11 @@ int is_broken_allowed(gnutls_sign_algorithm_t sig, unsigned int flags) if ((sig == GNUTLS_SIGN_RSA_MD5) && (flags & GNUTLS_VERIFY_ALLOW_SIGN_RSA_MD5)) return 1; - /* we no longer have individual flags - but rather a catch all */ - if ((flags & GNUTLS_VERIFY_ALLOW_BROKEN) == GNUTLS_VERIFY_ALLOW_BROKEN) + + hash = gnutls_sign_get_hash_algorithm(sig); + if (hash == GNUTLS_DIG_SHA1 && (flags & GNUTLS_VERIFY_ALLOW_SIGN_WITH_SHA1)) return 1; + return 0; } -- cgit v1.2.1