diff options
author | Jack Lloyd <[email protected]> | 2017-08-31 19:09:22 -0400 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-08-31 19:20:10 -0400 |
commit | d42bbd3540f09dd154123e97032f5bfc0b110c4e (patch) | |
tree | 0f3676a25963544b06d7c6c339f9828d95f36363 /src/lib/tls/tls_handshake_state.cpp | |
parent | c53cfda7b5e2f57927041c67be9db10b18b2ba8a (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.cpp | 38 |
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; } |