diff options
author | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-07-25 10:06:10 +0200 |
---|---|---|
committer | Nikos Mavrogiannopoulos <nmav@redhat.com> | 2017-08-03 11:57:52 +0200 |
commit | d3fee4c49e38ea8e703820d59e4de0a4b758b612 (patch) | |
tree | b9baafcfd05d27aad4ce5b6cb126b3dcb29cfc8c /lib/pubkey.c | |
parent | 99d23828658add34245f4128289ae35e96041f3e (diff) | |
download | gnutls-d3fee4c49e38ea8e703820d59e4de0a4b758b612.tar.gz |
_gnutls_pubkey_compatible_with_sig: enforce RSA-PSS requirements
That is require that parameters in an RSA-PSS key which has them
explicitly set, are respected with regards to signature algorithm
negotiation.
Signed-off-by: Nikos Mavrogiannopoulos <nmav@redhat.com>
Diffstat (limited to 'lib/pubkey.c')
-rw-r--r-- | lib/pubkey.c | 26 |
1 files changed, 20 insertions, 6 deletions
diff --git a/lib/pubkey.c b/lib/pubkey.c index 2ddded82a3..670282f929 100644 --- a/lib/pubkey.c +++ b/lib/pubkey.c @@ -1718,6 +1718,11 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session, unsigned int hash_size = 0; unsigned int sig_hash_size; const mac_entry_st *me; + const gnutls_sign_entry_st *se; + + se = _gnutls_sign_to_entry(sign); + if (se == NULL && _gnutls_version_has_selectable_sighash(ver)) + return gnutls_assert_val(GNUTLS_E_INVALID_REQUEST); if (pubkey->pk_algorithm == GNUTLS_PK_DSA) { me = _gnutls_dsa_q_to_hash(pubkey->pk_algorithm, @@ -1729,9 +1734,8 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session, return gnutls_assert_val (GNUTLS_E_INCOMPAT_DSA_KEY_WITH_TLS_PROTOCOL); - } else if (sign != GNUTLS_SIGN_UNKNOWN) { - me = hash_to_entry(gnutls_sign_get_hash_algorithm - (sign)); + } else if (se != NULL) { + me = hash_to_entry(se->hash); sig_hash_size = _gnutls_hash_get_algo_len(me); if (sig_hash_size < hash_size) _gnutls_audit_log(session, @@ -1742,13 +1746,13 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session, } else if (pubkey->pk_algorithm == GNUTLS_PK_EC) { if (_gnutls_version_has_selectable_sighash(ver) - && sign != GNUTLS_SIGN_UNKNOWN) { + && se != NULL) { + _gnutls_dsa_q_to_hash(pubkey->pk_algorithm, &pubkey->params, &hash_size); - me = hash_to_entry(gnutls_sign_get_hash_algorithm - (sign)); + me = hash_to_entry(se->hash); sig_hash_size = _gnutls_hash_get_algo_len(me); if (sig_hash_size < hash_size) @@ -1758,6 +1762,16 @@ int _gnutls_pubkey_compatible_with_sig(gnutls_session_t session, hash_size); } + } else if (pubkey->pk_algorithm == GNUTLS_PK_RSA_PSS) { + if (!_gnutls_version_has_selectable_sighash(ver)) + /* this should not have happened */ + return gnutls_assert_val(GNUTLS_E_INTERNAL_ERROR); + + /* RSA PSS public keys are restricted to a single digest, i.e., signature */ + + if (pubkey->params.spki.rsa_pss_dig && pubkey->params.spki.rsa_pss_dig != se->hash) { + return gnutls_assert_val(GNUTLS_E_CONSTRAINT_ERROR); + } } return 0; |