aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-01-24 14:54:40 +0000
committerlloyd <[email protected]>2012-01-24 14:54:40 +0000
commit92f6a575bca25d8985aa87304e28cd63867310e2 (patch)
tree772ed25014be71f74482cef8cc55f5dd984ea765 /src
parentd0d097337d652e2205d88e0037725d4aac05eab3 (diff)
Get the list of supported ECC curves out of the client hello, and
avoid negotiating an ECDH key exchange if the client didn't send any curves that we know about.
Diffstat (limited to 'src')
-rw-r--r--src/tls/c_hello.cpp3
-rw-r--r--src/tls/s_hello.cpp4
-rw-r--r--src/tls/tls_messages.h3
-rw-r--r--src/tls/tls_policy.cpp10
-rw-r--r--src/tls/tls_policy.h1
5 files changed, 17 insertions, 4 deletions
diff --git a/src/tls/c_hello.cpp b/src/tls/c_hello.cpp
index 55bf39318..9e3824c57 100644
--- a/src/tls/c_hello.cpp
+++ b/src/tls/c_hello.cpp
@@ -287,6 +287,9 @@ void Client_Hello::deserialize(const MemoryRegion<byte>& buf)
m_renegotiation_info = reneg->renegotiation_info();
}
+ if(Supported_Elliptic_Curves* ecc = extensions.get<Supported_Elliptic_Curves>())
+ m_supported_curves = ecc->curves();
+
if(Signature_Algorithms* sigs = extensions.get<Signature_Algorithms>())
{
m_supported_algos = sigs->supported_signature_algorthms();
diff --git a/src/tls/s_hello.cpp b/src/tls/s_hello.cpp
index b027c6cc6..10e3a96fa 100644
--- a/src/tls/s_hello.cpp
+++ b/src/tls/s_hello.cpp
@@ -51,7 +51,9 @@ Server_Hello::Server_Hello(Record_Writer& writer,
have_dsa = true;
}
- suite = policy.choose_suite(c_hello.ciphersuites(), have_rsa, have_dsa, false);
+ suite = policy.choose_suite(c_hello.ciphersuites(),
+ !c_hello.supported_ecc_curves().empty(),
+ have_rsa, have_dsa, false);
if(suite == 0)
throw TLS_Exception(HANDSHAKE_FAILURE,
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index c3dbaaf42..ec2229c21 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -63,6 +63,8 @@ class Client_Hello : public Handshake_Message
std::vector<std::pair<std::string, std::string> > supported_algos() const
{ return m_supported_algos; }
+ const std::vector<std::string> supported_ecc_curves() const { return m_supported_curves; }
+
std::vector<u16bit> ciphersuites() const { return m_suites; }
std::vector<byte> compression_methods() const { return m_comp_methods; }
@@ -119,6 +121,7 @@ class Client_Hello : public Handshake_Message
MemoryVector<byte> m_renegotiation_info;
std::vector<std::pair<std::string, std::string> > m_supported_algos;
+ std::vector<std::string> m_supported_curves;
};
/**
diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp
index 1ef132ba0..bdcebab71 100644
--- a/src/tls/tls_policy.cpp
+++ b/src/tls/tls_policy.cpp
@@ -182,9 +182,10 @@ std::vector<byte> Policy::compression() const
* Choose which ciphersuite to use
*/
u16bit Policy::choose_suite(const std::vector<u16bit>& client_suites,
- bool have_rsa,
- bool have_dsa,
- bool have_srp) const
+ bool have_shared_ecc_curve,
+ bool have_rsa,
+ bool have_dsa,
+ bool have_srp) const
{
for(size_t i = 0; i != client_suites.size(); ++i)
{
@@ -194,6 +195,9 @@ u16bit Policy::choose_suite(const std::vector<u16bit>& client_suites,
if(suite.cipher_keylen() == 0)
continue; // not a ciphersuite we know
+ if(suite.kex_algo() == "ECDH" && !have_shared_ecc_curve)
+ continue;
+
if(suite.sig_algo() == "RSA" && have_rsa)
return suite_id;
diff --git a/src/tls/tls_policy.h b/src/tls/tls_policy.h
index ec915c635..50793c899 100644
--- a/src/tls/tls_policy.h
+++ b/src/tls/tls_policy.h
@@ -92,6 +92,7 @@ class BOTAN_DLL Policy
std::vector<u16bit> ciphersuite_list(bool have_srp) const;
u16bit choose_suite(const std::vector<u16bit>& client_suites,
+ bool have_shared_ecc_curve,
bool have_rsa,
bool have_dsa,
bool have_srp) const;