aboutsummaryrefslogtreecommitdiffstats
path: root/src/lib/tls/msg_server_kex.cpp
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2016-10-21 11:25:53 -0400
committerJack Lloyd <[email protected]>2016-10-21 16:54:43 -0400
commitf44bd90a3ff9c2928eef825a0ff5394160b1a01c (patch)
treed5bec5ca3c501122c747fd492c8a16270135b935 /src/lib/tls/msg_server_kex.cpp
parent6aa855bba613c7b6fedfbe71d15930964acb1633 (diff)
X25519 key exchange for TLS
Client interops with google.com, server not tested against an independent client yet.
Diffstat (limited to 'src/lib/tls/msg_server_kex.cpp')
-rw-r--r--src/lib/tls/msg_server_kex.cpp44
1 files changed, 30 insertions, 14 deletions
diff --git a/src/lib/tls/msg_server_kex.cpp b/src/lib/tls/msg_server_kex.cpp
index 325e5d1b0..4515ea450 100644
--- a/src/lib/tls/msg_server_kex.cpp
+++ b/src/lib/tls/msg_server_kex.cpp
@@ -17,8 +17,12 @@
#include <botan/dh.h>
#include <botan/ecdh.h>
+#if defined(BOTAN_HAS_CURVE_25519)
+ #include <botan/curve25519.h>
+#endif
+
#if defined(BOTAN_HAS_SRP6)
-#include <botan/srp6.h>
+ #include <botan/srp6.h>
#endif
namespace Botan {
@@ -69,28 +73,40 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Could not agree on an ECC curve with the client");
- EC_Group ec_group(curve_name);
+ const uint16_t named_curve_id = Supported_Elliptic_Curves::name_to_curve_id(curve_name);
+ if(named_curve_id == 0)
+ throw Internal_Error("TLS does not support ECC with " + curve_name);
- std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
+ std::vector<byte> ecdh_public_val;
- const std::string ecdh_domain_oid = ecdh->domain().get_oid();
- const std::string domain = OIDS::lookup(OID(ecdh_domain_oid));
+ if(curve_name == "x25519")
+ {
+#if defined(BOTAN_HAS_CURVE_25519)
+ std::unique_ptr<Curve25519_PrivateKey> x25519(new Curve25519_PrivateKey(rng));
+ ecdh_public_val = x25519->public_value();
+ m_kex_key.reset(x25519.release());
+#else
+ throw Internal_Error("Negotiated X25519 somehow, but it is disabled");
+#endif
+ }
+ else
+ {
+ EC_Group ec_group(curve_name);
+ std::unique_ptr<ECDH_PrivateKey> ecdh(new ECDH_PrivateKey(rng, ec_group));
- if(domain == "")
- throw Internal_Error("Could not find name of ECDH domain " + ecdh_domain_oid);
+ // follow client's preference for point compression
+ ecdh_public_val = ecdh->public_value(
+ state.client_hello()->prefers_compressed_ec_points() ?
+ PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED);
- const u16bit named_curve_id = Supported_Elliptic_Curves::name_to_curve_id(domain);
+ m_kex_key.reset(ecdh.release());
+ }
m_params.push_back(3); // named curve
m_params.push_back(get_byte(0, named_curve_id));
m_params.push_back(get_byte(1, named_curve_id));
- // follow client's preference for point compression
- append_tls_length_value(m_params,
- ecdh->public_value(state.client_hello()->prefers_compressed_ec_points() ?
- PointGFp::COMPRESSED : PointGFp::UNCOMPRESSED), 1);
-
- m_kex_key.reset(ecdh.release());
+ append_tls_length_value(m_params, ecdh_public_val, 1);
}
#if defined(BOTAN_HAS_SRP6)
else if(kex_algo == "SRP_SHA")