summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/ext_signature.c7
-rw-r--r--lib/ext_signature.h4
-rw-r--r--lib/gnutls_pk.c4
-rw-r--r--lib/gnutls_sig.c58
4 files changed, 52 insertions, 21 deletions
diff --git a/lib/ext_signature.c b/lib/ext_signature.c
index 29f63eaf9e..35178292e1 100644
--- a/lib/ext_signature.c
+++ b/lib/ext_signature.c
@@ -247,8 +247,7 @@ _gnutls_signature_algorithm_send_params (gnutls_session_t session,
*/
gnutls_sign_algorithm_t
_gnutls_session_get_sign_algo (gnutls_session_t session,
- gnutls_pk_algorithm_t pk,
- gnutls_digest_algorithm_t * hash)
+ gnutls_pk_algorithm_t pk)
{
unsigned i;
int ret;
@@ -266,15 +265,13 @@ _gnutls_session_get_sign_algo (gnutls_session_t session,
|| priv->sign_algorithms_size == 0)
/* none set, allow all */
{
- *hash = GNUTLS_DIG_SHA1;
- return _gnutls_x509_pk_to_sign (pk, *hash);
+ return _gnutls_x509_pk_to_sign (pk, GNUTLS_DIG_SHA1);
}
for (i = 0; i < priv->sign_algorithms_size; i++)
{
if (_gnutls_sign_get_pk_algorithm (priv->sign_algorithms[i]) == pk)
{
- *hash = _gnutls_sign_get_hash_algorithm (priv->sign_algorithms[i]);
return priv->sign_algorithms[i];
}
}
diff --git a/lib/ext_signature.h b/lib/ext_signature.h
index 9d507ed816..b56c772174 100644
--- a/lib/ext_signature.h
+++ b/lib/ext_signature.h
@@ -37,9 +37,7 @@ int _gnutls_session_sign_algo_requested (gnutls_session_t session,
gnutls_sign_algorithm_t _gnutls_session_get_sign_algo (gnutls_session_t
session,
gnutls_pk_algorithm_t
- pk,
- gnutls_digest_algorithm_t
- * hash);
+ pk);
int _gnutls_sign_algorithm_parse_data (gnutls_session_t session,
const opaque * data, size_t data_size);
int _gnutls_sign_algorithm_write_params (gnutls_session_t session,
diff --git a/lib/gnutls_pk.c b/lib/gnutls_pk.c
index ee4fb03779..9fa032601b 100644
--- a/lib/gnutls_pk.c
+++ b/lib/gnutls_pk.c
@@ -501,8 +501,8 @@ _gnutls_dsa_verify (const gnutls_datum_t * vdata,
pk_params.params[i] = params[i];
pk_params.params_nr = params_len;
- if (vdata->size > 20)
- { /* SHA1 or better only */
+ if (vdata->size < 20)
+ { /* SHA1 or better only */
gnutls_assert ();
return GNUTLS_E_PK_SIG_VERIFY_FAILED;
}
diff --git a/lib/gnutls_sig.c b/lib/gnutls_sig.c
index f32661c087..a4c3f20c4f 100644
--- a/lib/gnutls_sig.c
+++ b/lib/gnutls_sig.c
@@ -121,7 +121,40 @@ _gnutls_rsa_encode_sig (gnutls_mac_algorithm_t algo,
return 0;
}
+static int
+get_hash_algo(gnutls_session_t session, gnutls_cert* cert,
+ gnutls_sign_algorithm_t sign_algo,
+ gnutls_digest_algorithm_t *hash_algo)
+{
+int ret;
+gnutls_protocol_t ver = gnutls_protocol_get_version (session);
+ if (cert->subject_pk_algorithm == GNUTLS_PK_DSA)
+ { /* override */
+ *hash_algo = _gnutls_dsa_q_to_hash (cert->params[1]);
+
+ if (!_gnutls_version_has_selectable_sighash (ver) && *hash_algo != GNUTLS_DIG_SHA1)
+ {
+ /* In TLS < 1.2 one cannot use anything but SHA1
+ */
+ gnutls_assert();
+ return GNUTLS_E_INVALID_REQUEST;
+ }
+
+ ret = _gnutls_session_sign_algo_requested(session, _gnutls_x509_pk_to_sign (GNUTLS_PK_DSA, *hash_algo));
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+ }
+ else
+ {
+ if (sign_algo == GNUTLS_SIGN_UNKNOWN)
+ *hash_algo = GNUTLS_DIG_SHA1;
+ else
+ *hash_algo = _gnutls_sign_get_hash_algorithm (sign_algo);
+ }
+
+ return 0;
+}
/* Generates a signature of all the random data and the parameters.
* Used in DHE_* ciphersuites.
@@ -140,14 +173,17 @@ _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->subject_pk_algorithm,
- &hash_algo);
+ _gnutls_session_get_sign_algo (session, cert->subject_pk_algorithm);
if (*sign_algo == GNUTLS_SIGN_UNKNOWN)
{
gnutls_assert ();
return GNUTLS_E_UNKNOWN_PK_ALGORITHM;
}
-
+
+ ret = get_hash_algo(session, cert, *sign_algo, &hash_algo);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
+
_gnutls_handshake_log("HSK[%p]: hash from highest priority sigalgorithm: %s (%d)\n",
session, gnutls_mac_get_name(hash_algo), hash_algo);
@@ -167,7 +203,7 @@ _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
switch (cert->subject_pk_algorithm)
{
case GNUTLS_PK_RSA:
- if (!_gnutls_version_has_selectable_prf (ver))
+ if (!_gnutls_version_has_selectable_sighash (ver))
{
digest_hd_st td_md5;
@@ -223,7 +259,6 @@ _gnutls_handshake_sign_data (gnutls_session_t session, gnutls_cert * cert,
return GNUTLS_E_INTERNAL_ERROR;
}
-fprintf(stderr, "asking to sign: %d bytes\n", dconcat.size);
ret = _gnutls_tls_sign (session, cert, pkey, &dconcat, signature);
if (ret < 0)
{
@@ -397,7 +432,7 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
digest_hd_st td_sha;
opaque concat[MAX_SIG_SIZE];
gnutls_protocol_t ver = gnutls_protocol_get_version (session);
- gnutls_digest_algorithm_t hash_algo = GNUTLS_DIG_SHA1;
+ gnutls_digest_algorithm_t hash_algo;
ret = _gnutls_session_sign_algo_enabled (session, algo);
if (ret < 0)
@@ -406,7 +441,7 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
return ret;
}
- if (!_gnutls_version_has_selectable_prf (ver))
+ if (!_gnutls_version_has_selectable_sighash (ver))
{
ret = _gnutls_hash_init (&td_md5, GNUTLS_MAC_MD5);
if (ret < 0)
@@ -422,14 +457,15 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
_gnutls_hash (&td_md5, params->data, params->size);
}
- if (algo != GNUTLS_SIGN_UNKNOWN)
- hash_algo = _gnutls_sign_get_hash_algorithm (algo);
+ ret = get_hash_algo(session, cert, algo, &hash_algo);
+ if (ret < 0)
+ return gnutls_assert_val(ret);
ret = _gnutls_hash_init (&td_sha, hash_algo);
if (ret < 0)
{
gnutls_assert ();
- if (!_gnutls_version_has_selectable_prf (ver))
+ if (!_gnutls_version_has_selectable_sighash (ver))
_gnutls_hash_deinit (&td_md5, NULL);
return ret;
}
@@ -440,7 +476,7 @@ _gnutls_handshake_verify_data (gnutls_session_t session, gnutls_cert * cert,
GNUTLS_RANDOM_SIZE);
_gnutls_hash (&td_sha, params->data, params->size);
- if (!_gnutls_version_has_selectable_prf (ver))
+ if (!_gnutls_version_has_selectable_sighash (ver))
{
_gnutls_hash_deinit (&td_md5, concat);
_gnutls_hash_deinit (&td_sha, &concat[16]);