aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2013-03-21 13:59:24 +0000
committerlloyd <[email protected]>2013-03-21 13:59:24 +0000
commit8a664104ab7d712783223fa4a2abb9ac675243be (patch)
treea0a7377d64e310629783dd8b8782b2e6fccf2565 /src
parent45f384ec0b4848a73bfd9c23bd2ec657e21ee299 (diff)
Add TLS::Policy::server_uses_own_ciphersuite_preferences()
Previously the server always took its most-preferred cipher out of the client's list, but this policy allows telling a server to follow the client's preferences insetad.
Diffstat (limited to 'src')
-rw-r--r--src/tls/tls_policy.cpp8
-rw-r--r--src/tls/tls_policy.h7
-rw-r--r--src/tls/tls_server.cpp15
-rw-r--r--src/tls/tls_version.h8
4 files changed, 33 insertions, 5 deletions
diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp
index 98e3c6bca..1048e0a62 100644
--- a/src/tls/tls_policy.cpp
+++ b/src/tls/tls_policy.cpp
@@ -131,6 +131,14 @@ u32bit Policy::session_ticket_lifetime() const
bool Policy::acceptable_protocol_version(Protocol_Version version) const
{
return version.known_version(); // accept any version we know about
+
+ // maybe someday...
+ //return version >= Protocol_Version::TLS_V11;
+ }
+
+bool Policy::server_uses_own_ciphersuite_preferences() const
+ {
+ return true;
}
namespace {
diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h
index 125faa665..7176f7fd5 100644
--- a/src/tls/tls_policy.h
+++ b/src/tls/tls_policy.h
@@ -126,6 +126,13 @@ class BOTAN_DLL Policy
*/
virtual bool acceptable_protocol_version(Protocol_Version version) const;
+ /**
+ * @return true if servers should choose the ciphersuite matching
+ * their highest preference, rather than the clients.
+ * Has no effect on client side.
+ */
+ virtual bool server_uses_own_ciphersuite_preferences() const;
+
virtual ~Policy() {}
};
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 2c393b32d..d8e827b39 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -112,6 +112,8 @@ u16bit choose_ciphersuite(
const std::map<std::string, std::vector<X509_Certificate> >& cert_chains,
const Client_Hello* client_hello)
{
+ const bool our_choice = policy.server_uses_own_ciphersuite_preferences();
+
const bool have_srp = creds.attempt_srp("tls-server",
client_hello->sni_hostname());
@@ -128,12 +130,15 @@ u16bit choose_ciphersuite(
const bool have_shared_ecc_curve =
(policy.choose_curve(client_hello->supported_ecc_curves()) != "");
- // Ordering by our preferences rather than by clients
- for(size_t i = 0; i != server_suites.size(); ++i)
- {
- const u16bit suite_id = server_suites[i];
+ std::vector<u16bit> pref_list = server_suites;
+ std::vector<u16bit> other_list = client_suites;
- if(!value_exists(client_suites, suite_id))
+ if(!our_choice)
+ std::swap(pref_list, other_list);
+
+ for(auto suite_id : pref_list)
+ {
+ if(!value_exists(other_list, suite_id))
continue;
Ciphersuite suite = Ciphersuite::by_id(suite_id);
diff --git a/src/tls/tls_version.h b/src/tls/tls_version.h
index 39712db27..2fb5365dc 100644
--- a/src/tls/tls_version.h
+++ b/src/tls/tls_version.h
@@ -129,6 +129,14 @@ class BOTAN_DLL Protocol_Version
*/
bool operator>(const Protocol_Version& other) const;
+ /**
+ * @return if this version is later than or equal to other
+ */
+ bool operator>=(const Protocol_Version& other) const
+ {
+ return (*this == other || *this > other);
+ }
+
private:
u16bit m_version;
};