summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNikos Mavrogiannopoulos <nmav@redhat.com>2016-10-21 17:07:13 +0200
committerNikos Mavrogiannopoulos <nmav@redhat.com>2016-10-21 17:09:27 +0200
commit575aa73a47cd7a591ce7fb242231ba88b3e1dea9 (patch)
tree89efc600d511bd02eed61d949bf2b0a5c482f0a1
parent6c1598869729a2ffeafcd690eaa041a6f7656a0d (diff)
downloadgnutls-575aa73a47cd7a591ce7fb242231ba88b3e1dea9.tar.gz
Restrict the allowed signature algorithms for SKE to the enabled ones
On the other hand, allow the client to sign even with non-enabled algorithms if necessary. That allows to sign for example with DSA-SHA1 as client even if we do not allow DSA-SHA1 as signature algorithm for server's certificate. This allows to use a deprecated certificate without enabling deprecated algorithms globally. Issue reported by Hubert Kario.
-rw-r--r--lib/ext_signature.c11
-rw-r--r--lib/ext_signature.h2
-rw-r--r--lib/gnutls_sig.c4
3 files changed, 12 insertions, 5 deletions
diff --git a/lib/ext_signature.c b/lib/ext_signature.c
index 3e81fa0e5e..6092814715 100644
--- a/lib/ext_signature.c
+++ b/lib/ext_signature.c
@@ -292,7 +292,7 @@ unsigned int hash_len;
* to return the second choice etc.
*/
gnutls_sign_algorithm_t
-_gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert)
+_gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert, unsigned client_cert)
{
unsigned i;
int ret;
@@ -310,7 +310,10 @@ _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert)
|| priv->sign_algorithms_size == 0)
/* none set, allow SHA-1 only */
{
- return _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, GNUTLS_DIG_SHA1);
+ ret = _gnutls_x509_pk_to_sign (cert->subject_pk_algorithm, GNUTLS_DIG_SHA1);
+ if (!client_cert && _gnutls_session_sign_algo_enabled(session, ret) < 0)
+ goto fail;
+ return ret;
}
for (i = 0; i < priv->sign_algorithms_size; i++)
@@ -320,10 +323,14 @@ _gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert)
if (cert_compatible_with_sig(cert, ver, priv->sign_algorithms[i]) < 0)
continue;
+ if (!client_cert && _gnutls_session_sign_algo_enabled(session, priv->sign_algorithms[i]) < 0)
+ continue;
+
return priv->sign_algorithms[i];
}
}
+ fail:
return GNUTLS_SIGN_UNKNOWN;
}
diff --git a/lib/ext_signature.h b/lib/ext_signature.h
index b566842431..3e570e4fe5 100644
--- a/lib/ext_signature.h
+++ b/lib/ext_signature.h
@@ -33,7 +33,7 @@
extern extension_entry_st ext_mod_sig;
gnutls_sign_algorithm_t
-_gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert);
+_gnutls_session_get_sign_algo (gnutls_session_t session, gnutls_cert* cert, unsigned client_cert);
int _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
const opaque * data, size_t data_size, unsigned cert_verify);
int _gnutls_sign_algorithm_write_params (gnutls_session_t session,
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index 9542925db3..c32d9c3325 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -72,7 +72,7 @@ _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
gnutls_digest_algorithm_t hash_algo;
*sign_algo =
- _gnutls_session_get_sign_algo (session, cert);
+ _gnutls_session_get_sign_algo (session, cert, 0);
if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
{
gnutls_assert ();
@@ -611,7 +611,7 @@ _gnutls_handshake_sign_cert_vrfy12 (gnutls_session_t session,
digest_hd_st *handshake_td;
sign_algo =
- _gnutls_session_get_sign_algo (session, cert);
+ _gnutls_session_get_sign_algo (session, cert, 1);
if (sign_algo == GNUTLS_SIGN_UNKNOWN)
{
gnutls_assert ();