diff options
-rw-r--r-- | src/tls/cert_ver.cpp | 3 | ||||
-rw-r--r-- | src/tls/s_kex.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_channel.cpp | 5 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 12 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 23 | ||||
-rw-r--r-- | src/tls/tls_extensions.cpp | 5 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.cpp | 23 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.h | 5 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 1 |
9 files changed, 58 insertions, 21 deletions
diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp index e6d90b060..ae00536df 100644 --- a/src/tls/cert_ver.cpp +++ b/src/tls/cert_ver.cpp @@ -21,13 +21,14 @@ namespace TLS { */ Certificate_Verify::Certificate_Verify(Record_Writer& writer, Handshake_State* state, + const Policy& policy, RandomNumberGenerator& rng, const Private_Key* priv_key) { BOTAN_ASSERT_NONNULL(priv_key); std::pair<std::string, Signature_Format> format = - state->choose_sig_format(priv_key, hash_algo, sig_algo, true); + state->choose_sig_format(priv_key, hash_algo, sig_algo, true, policy); PK_Signer signer(*priv_key, format.first, format.second); diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 7fc7daf2d..694462082 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -126,7 +126,7 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, BOTAN_ASSERT(signing_key, "No signing key set"); std::pair<std::string, Signature_Format> format = - state->choose_sig_format(signing_key, m_hash_algo, m_sig_algo, false); + state->choose_sig_format(signing_key, m_hash_algo, m_sig_algo, false, policy); PK_Signer signer(*signing_key, format.first, format.second); diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index 3f3677105..fe1376d6e 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -234,6 +234,11 @@ void Channel::send(const byte buf[], size_t buf_size) m_writer.send(APPLICATION_DATA, buf, buf_size); } +void Channel::send(const std::string& string) + { + this->send(reinterpret_cast<const byte*>(string.c_str()), string.size()); + } + void Channel::send_alert(const Alert& alert) { if(alert.is_valid() && !m_connection_closed) diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 1f4075b01..4551a377e 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -1,6 +1,6 @@ /* * TLS Channel -* (C) 2011 Jack Lloyd +* (C) 2011,2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -15,6 +15,7 @@ #include <botan/tls_session_manager.h> #include <botan/x509cert.h> #include <vector> +#include <string> namespace Botan { @@ -36,7 +37,12 @@ class BOTAN_DLL Channel /** * Inject plaintext intended for counterparty */ - virtual void send(const byte buf[], size_t buf_size); + void send(const byte buf[], size_t buf_size); + + /** + * Inject plaintext intended for counterparty + */ + void send(const std::string& string); /** * Send a close notification alert @@ -58,7 +64,7 @@ class BOTAN_DLL Channel * @param force_full_renegotiation if true, require a full renegotiation, * otherwise allow session resumption */ - virtual void renegotiate(bool force_full_renegotiation) = 0; + virtual void renegotiate(bool force_full_renegotiation = false) = 0; /** * Attempt to send a heartbeat message (if negotiated with counterparty) diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index 3dd6484db..0231b9c53 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -1,6 +1,6 @@ /* * TLS Client -* (C) 2004-2011 Jack Lloyd +* (C) 2004-2011,2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -328,9 +328,9 @@ void Client::process_handshake_msg(Handshake_Type type, m_state->set_expected_next(SERVER_HELLO_DONE); m_state->server_kex = new Server_Key_Exchange(contents, - m_state->suite.kex_algo(), - m_state->suite.sig_algo(), - m_state->version()); + m_state->suite.kex_algo(), + m_state->suite.sig_algo(), + m_state->version()); if(m_state->suite.sig_algo() != "") { @@ -361,8 +361,8 @@ void Client::process_handshake_msg(Handshake_Type type, m_hostname); m_state->client_certs = new Certificate(m_writer, - m_state->hash, - client_certs); + m_state->hash, + client_certs); } m_state->client_kex = @@ -374,8 +374,8 @@ void Client::process_handshake_msg(Handshake_Type type, m_rng); m_state->keys = Session_Keys(m_state, - m_state->client_kex->pre_master_secret(), - false); + m_state->client_kex->pre_master_secret(), + false); if(m_state->received_handshake_msg(CERTIFICATE_REQUEST) && !m_state->client_certs->empty()) @@ -386,9 +386,10 @@ void Client::process_handshake_msg(Handshake_Type type, m_hostname); m_state->client_verify = new Certificate_Verify(m_writer, - m_state, - m_rng, - private_key); + m_state, + m_policy, + m_rng, + private_key); } m_writer.send(CHANGE_CIPHER_SPEC, 1); diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index df25c40a5..d66b055c8 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -400,6 +400,8 @@ std::string Signature_Algorithms::hash_algo_name(byte code) { switch(code) { + case 1: + return "MD5"; // code 1 is MD5 - ignore it case 2: @@ -419,6 +421,9 @@ std::string Signature_Algorithms::hash_algo_name(byte code) byte Signature_Algorithms::hash_algo_code(const std::string& name) { + if(name == "MD5") + return 1; + if(name == "SHA-1") return 2; diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index 481e16e0d..48e587d03 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -197,6 +197,7 @@ namespace { std::string choose_hash(const std::string& sig_algo, Protocol_Version negotiated_version, + const Policy& policy, bool for_client_auth, Client_Hello* client_hello, Certificate_Req* cert_req) @@ -222,10 +223,22 @@ std::string choose_hash(const std::string& sig_algo, cert_req->supported_algos() : client_hello->supported_algos(); - for(auto algo : supported_algos) + if(!supported_algos.empty()) { - if(algo.second == sig_algo) - return algo.first; + const auto hashes = policy.allowed_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(auto algo : supported_algos) + { + if(algo.first == hash && algo.second == sig_algo) + return hash; + } + } } // TLS v1.2 default hash if the counterparty sent nothing @@ -238,13 +251,15 @@ std::pair<std::string, Signature_Format> Handshake_State::choose_sig_format(const Private_Key* key, std::string& hash_algo_out, std::string& sig_algo_out, - bool for_client_auth) + bool for_client_auth, + const Policy& policy) { 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); diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index ef8b4ee8f..3ac023b1d 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -23,6 +23,8 @@ class KDF; namespace TLS { +class Policy; + /** * SSL/TLS Handshake State */ @@ -49,7 +51,8 @@ class Handshake_State choose_sig_format(const Private_Key* key, std::string& hash_algo, std::string& sig_algo, - bool for_client_auth); + bool for_client_auth, + const Policy& policy); std::string srp_identifier() const; diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index 0760b1815..0bca2f44c 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -338,6 +338,7 @@ class Certificate_Verify : public Handshake_Message Certificate_Verify(Record_Writer& writer, Handshake_State* state, + const Policy& policy, RandomNumberGenerator& rng, const Private_Key* key); |