aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--doc/relnotes/1_11_3.rst7
-rw-r--r--doc/tls.rst16
-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
6 files changed, 54 insertions, 7 deletions
diff --git a/doc/relnotes/1_11_3.rst b/doc/relnotes/1_11_3.rst
index 6b0ba1492..ac4de76aa 100644
--- a/doc/relnotes/1_11_3.rst
+++ b/doc/relnotes/1_11_3.rst
@@ -1,6 +1,13 @@
Version 1.11.3, Not Yet Released
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+* A new TLS policy mechanism
+ :cpp:func:`TLS::Policy::server_uses_own_ciphersuite_preferences`
+ controls how a server chooses a ciphersuite. Previously it always
+ chose its most preferred cipher out of the client's list, but this
+ can allow configuring a server to choose by the client's preferences
+ instead.
+
* Implementations of the OCB and GCM authenticated cipher modes are
now included
diff --git a/doc/tls.rst b/doc/tls.rst
index 83503fcb1..406b94d93 100644
--- a/doc/tls.rst
+++ b/doc/tls.rst
@@ -526,17 +526,24 @@ be negotiated during a handshake.
Default: "secp521r1", "secp384r1", "secp256r1",
"secp256k1", "secp224r1", "secp224k1"
- Also allowed: "secp192r1", "secp192k1", "secp160r2", "secp160r1", "secp160k1"
+ Also allowed: "secp192r1", "secp192k1", "secp160r2", "secp160r1",
+ "secp160k1"
.. cpp:function:: std::vector<byte> compression() const
Return the list of compression methods we are willing to use, in order of
- preference.
+ preference. Default is null compression only.
.. note::
TLS compression is not currently supported.
+ .. cpp:function:: bool server_uses_own_ciphersuite_preferences() const
+
+ If this returns true, a server will pick the cipher it prefers the
+ most out of the client's list. Otherwise, it will negotiate the
+ first cipher in the client's ciphersuite list that it supports.
+
.. cpp:function:: bool negotiate_heartbeat_support() const
If this function returns true, clients will offer the heartbeat
@@ -545,6 +552,11 @@ be negotiated during a handshake.
support and servers will ignore clients offering heartbeat
support.
+ If this returns true, callers should expect to handle heartbeat
+ data in their ``proc_fn``.
+
+ Default
+
.. cpp:function:: bool allow_server_initiated_renegotiation() const
If this function returns true, a client will accept a
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;
};