aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/tls_handshake_state.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-08-31 19:09:22 -0400
committerJack Lloyd <[email protected]>2017-08-31 19:20:10 -0400
commitd42bbd3540f09dd154123e97032f5bfc0b110c4e (patch)
tree0f3676a25963544b06d7c6c339f9828d95f36363 /src/lib/tls/tls_handshake_state.cpp
parentc53cfda7b5e2f57927041c67be9db10b18b2ba8a (diff)
Enforce signature hash policy properly
Previously if the client did not send signature_algorithms, or if it only included algos not in the policy, we would just fallback to the hardcoded SHA-1 default of TLS v1.2 Instead check the policy before accepting anything.
Diffstat (limited to 'src/lib/tls/tls_handshake_state.cpp')
-rw-r--r--src/lib/tls/tls_handshake_state.cpp38
1 files changed, 21 insertions, 17 deletions
diff --git a/src/lib/tls/tls_handshake_state.cpp b/src/lib/tls/tls_handshake_state.cpp
index d87af7305..35973b359 100644
--- a/src/lib/tls/tls_handshake_state.cpp
+++ b/src/lib/tls/tls_handshake_state.cpp
@@ -372,11 +372,9 @@ KDF* Handshake_State::protocol_specific_prf() const
namespace {
std::string choose_hash(const std::string& sig_algo,
+ std::vector<std::pair<std::string, std::string>>& supported_algos,
Protocol_Version negotiated_version,
- const Policy& policy,
- bool for_client_auth,
- const Client_Hello* client_hello,
- const Certificate_Req* cert_req)
+ const Policy& policy)
{
if(!negotiated_version.supports_negotiable_signature_algorithms())
{
@@ -392,19 +390,15 @@ std::string choose_hash(const std::string& sig_algo,
throw Internal_Error("Unknown TLS signature algo " + sig_algo);
}
- const auto supported_algos = for_client_auth ?
- cert_req->supported_algos() :
- client_hello->supported_algos();
-
if(!supported_algos.empty())
{
- const auto hashes = policy.allowed_signature_hashes();
+ const std::vector<std::string> hashes = policy.allowed_signature_hashes();
/*
* Choose our most preferred hash that the counterparty supports
* in pairing with the signature algorithm we want to use.
*/
- for(auto hash : hashes)
+ for(std::string hash : hashes)
{
for(auto algo : supported_algos)
{
@@ -429,16 +423,26 @@ Handshake_State::choose_sig_format(const Private_Key& key,
{
const std::string sig_algo = key.algo_name();
- const std::string hash_algo =
- choose_hash(sig_algo,
- this->version(),
- policy,
- for_client_auth,
- client_hello(),
- cert_req());
+ std::vector<std::pair<std::string, std::string>> supported_algos =
+ (for_client_auth) ? cert_req()->supported_algos() : client_hello()->supported_algos();
+
+ const std::string hash_algo = choose_hash(sig_algo,
+ supported_algos,
+ this->version(),
+ policy);
if(this->version().supports_negotiable_signature_algorithms())
{
+ // We skip this check for v1.0 since you're stuck with SHA-1 regardless
+
+ std::vector<std::string> allowed_hashes = policy.allowed_signature_hashes();
+
+ if(!policy.allowed_signature_hash(hash_algo))
+ {
+ throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
+ "Policy refuses to accept signing with any hash supported by peer");
+ }
+
hash_algo_out = hash_algo;
sig_algo_out = sig_algo;
}