diff options
-rw-r--r-- | lib/ext_signature.c | 7 | ||||
-rw-r--r-- | lib/ext_signature.h | 4 | ||||
-rw-r--r-- | lib/gnutls_pk.c | 4 | ||||
-rw-r--r-- | lib/gnutls_sig.c | 58 |
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]); |