diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-10-21 17:07:13 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2016-10-21 17:09:27 +0200 |
commit | 575aa73a47cd7a591ce7fb242231ba88b3e1dea9 (patch) | |
tree | 89efc600d511bd02eed61d949bf2b0a5c482f0a1 | |
parent | 6c1598869729a2ffeafcd690eaa041a6f7656a0d (diff) | |
download | gnutls-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.c | 11 | ||||
-rw-r--r-- | lib/ext_signature.h | 2 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 4 |
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 (); |