aboutsummaryrefslogtreecommitdiffstats
path: root/src/tls
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-04-05 01:30:24 +0000
committerlloyd <[email protected]>2012-04-05 01:30:24 +0000
commit47908b70683d9d0789be4fd4168c7e1ec52307ea (patch)
tree605d709f4603da8c42b93094631f7e9734b67937 /src/tls
parentf4ae793a4af5d0c9883a2a1555a539c925982239 (diff)
Initial client-side support for SRP (finally!). Tested against OpenSSL
1.0.1, only the certificate versions tested currently as OpenSSL doesn't support anon SRP.
Diffstat (limited to 'src/tls')
-rw-r--r--src/tls/c_kex.cpp29
-rw-r--r--src/tls/s_kex.cpp14
-rw-r--r--src/tls/tls_client.cpp1
-rw-r--r--src/tls/tls_messages.h1
4 files changed, 45 insertions, 0 deletions
diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp
index ed571852c..0a6339bd0 100644
--- a/src/tls/c_kex.cpp
+++ b/src/tls/c_kex.cpp
@@ -15,6 +15,7 @@
#include <botan/dh.h>
#include <botan/ecdh.h>
#include <botan/rsa.h>
+#include <botan/srp6.h>
#include <botan/rng.h>
#include <botan/loadstor.h>
#include <memory>
@@ -50,6 +51,7 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer,
Handshake_State* state,
Credentials_Manager& creds,
const std::vector<X509_Certificate>& peer_certs,
+ const std::string& hostname,
RandomNumberGenerator& rng)
{
const std::string kex_algo = state->suite.kex_algo();
@@ -171,6 +173,33 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer,
append_tls_length_value(key_material, priv_key.public_value(), 1);
}
+ else if(kex_algo == "SRP_SHA")
+ {
+ const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
+ const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
+ MemoryVector<byte> salt = reader.get_range<byte>(1, 1, 255);
+ const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
+
+ const std::string srp_group = srp6_group_identifier(N, g);
+
+ const std::string srp_identifier =
+ creds.srp_identifier("tls-client", hostname);
+
+ const std::string srp_password =
+ creds.srp_password("tls-client", hostname, srp_identifier);
+
+ std::pair<BigInt, SymmetricKey> srp_vals =
+ srp6_client_agree(srp_identifier,
+ srp_password,
+ srp_group,
+ "SHA-1",
+ salt,
+ B,
+ rng);
+
+ append_tls_length_value(key_material, BigInt::encode(srp_vals.first), 2);
+ pre_master = srp_vals.second.bits_of();
+ }
else
{
throw Internal_Error("Client_Key_Exchange: Unknown kex " +
diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp
index 6707d2611..a5c8ff8d7 100644
--- a/src/tls/s_kex.cpp
+++ b/src/tls/s_kex.cpp
@@ -167,6 +167,20 @@ Server_Key_Exchange::Server_Key_Exchange(const MemoryRegion<byte>& buf,
m_params.push_back(get_byte(1, curve_id));
append_tls_length_value(m_params, ecdh_key, 1);
}
+ else if(kex_algo == "SRP_SHA")
+ {
+ // 2 bigints (N,g) then salt, then server B
+
+ const BigInt N = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
+ const BigInt g = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
+ MemoryVector<byte> salt = reader.get_range<byte>(1, 1, 255);
+ const BigInt B = BigInt::decode(reader.get_range<byte>(2, 1, 65535));
+
+ append_tls_length_value(m_params, BigInt::encode(N), 2);
+ append_tls_length_value(m_params, BigInt::encode(g), 2);
+ append_tls_length_value(m_params, salt, 1);
+ append_tls_length_value(m_params, BigInt::encode(B), 2);
+ }
else if(kex_algo != "PSK")
throw Decoding_Error("Server_Key_Exchange: Unsupported kex type " + kex_algo);
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 2ec7eec2e..850d053a2 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -342,6 +342,7 @@ void Client::process_handshake_msg(Handshake_Type type,
state,
creds,
peer_certs,
+ state->client_hello->sni_hostname(),
rng);
state->keys = Session_Keys(state,
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 920a1c7a7..ff6ebda4d 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -238,6 +238,7 @@ class Client_Key_Exchange : public Handshake_Message
Handshake_State* state,
Credentials_Manager& creds,
const std::vector<X509_Certificate>& peer_certs,
+ const std::string& hostname,
RandomNumberGenerator& rng);
Client_Key_Exchange(const MemoryRegion<byte>& buf,