aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-01-27 16:34:17 +0000
committerlloyd <[email protected]>2012-01-27 16:34:17 +0000
commit133bda471c547842044bd66a44bfe64668e966da (patch)
tree0420a87f6ac61740bd0b44888df9e97d8e3b5495
parentb96fde715dddbb3fe1eb6a9077bb92182dfa1635 (diff)
Server side PSK kex
-rw-r--r--src/tls/c_kex.cpp35
-rw-r--r--src/tls/tls_messages.h5
-rw-r--r--src/tls/tls_policy.cpp5
-rw-r--r--src/tls/tls_server.cpp5
4 files changed, 37 insertions, 13 deletions
diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp
index 9f492c5a5..f5afcc100 100644
--- a/src/tls/c_kex.cpp
+++ b/src/tls/c_kex.cpp
@@ -185,21 +185,38 @@ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer,
* Read a Client Key Exchange message
*/
Client_Key_Exchange::Client_Key_Exchange(const MemoryRegion<byte>& contents,
- const Ciphersuite& suite,
- Protocol_Version using_version)
+ const Handshake_State* state,
+ Credentials_Manager& creds)
{
- if(suite.kex_algo() == "RSA" && using_version == Protocol_Version::SSL_V3)
+ const std::string kex_algo = state->suite.kex_algo();
+
+ if(kex_algo == "RSA" && state->version == Protocol_Version::SSL_V3)
key_material = contents;
else
{
TLS_Data_Reader reader(contents);
- if(suite.kex_algo() == "RSA" || suite.kex_algo() == "DH")
+ if(kex_algo == "RSA" || kex_algo == "DH")
key_material = reader.get_range<byte>(2, 0, 65535);
- else if(suite.kex_algo() == "ECDH")
+ else if(kex_algo == "ECDH")
key_material = reader.get_range<byte>(1, 1, 255);
+ else if(kex_algo == "PSK")
+ {
+ const std::string psk_identity = reader.get_string(2, 0, 65535);
+
+ SymmetricKey psk = creds.psk("tls-server",
+ state->client_hello->sni_hostname(),
+ psk_identity);
+
+ MemoryVector<byte> zeros(psk.length());
+
+ append_tls_length_value(key_material, zeros, 2);
+ append_tls_length_value(key_material, psk.bits_of(), 2);
+
+ pre_master = key_material;
+ }
else
- throw Internal_Error("Unknown client key exch type " + suite.kex_algo());
+ throw Internal_Error("Client_Key_Exchange received unknown kex type " + kex_algo);
}
}
@@ -212,7 +229,11 @@ Client_Key_Exchange::pre_master_secret(RandomNumberGenerator& rng,
{
const std::string kex_algo = state->suite.kex_algo();
- if(kex_algo == "RSA")
+ if(kex_algo == "PSK")
+ {
+ return key_material;
+ }
+ else if(kex_algo == "RSA")
{
BOTAN_ASSERT(state->server_certs && !state->server_certs->cert_chain().empty(),
"No server certificate to use for RSA");
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 41ab6ece4..b29aac600 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -223,8 +223,9 @@ class Client_Key_Exchange : public Handshake_Message
RandomNumberGenerator& rng);
Client_Key_Exchange(const MemoryRegion<byte>& buf,
- const Ciphersuite& suite,
- Protocol_Version using_version);
+ const Handshake_State* state,
+ Credentials_Manager& creds);
+
private:
MemoryVector<byte> serialize() const { return key_material; }
diff --git a/src/tls/tls_policy.cpp b/src/tls/tls_policy.cpp
index a547e8fd5..6718b2e1e 100644
--- a/src/tls/tls_policy.cpp
+++ b/src/tls/tls_policy.cpp
@@ -245,8 +245,11 @@ u16bit Policy::choose_suite(const std::vector<u16bit>& client_suites,
continue;
}
- if(!value_exists(available_cert_types, suite.sig_algo()))
+ if(suite.sig_algo() != "" &&
+ !value_exists(available_cert_types, suite.sig_algo()))
+ {
continue;
+ }
if(value_exists(client_suites, suite_id))
return suite_id;
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 9002c3e05..9c4410938 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -308,7 +308,7 @@ void Server::process_handshake_msg(Handshake_Type type,
{
state->server_rsa_kex_key = private_key;
}
- else
+ else if(kex_algo != "PSK") // FIXME: means we never send identity hint
{
state->server_kex =
new Server_Key_Exchange(writer, state, policy, rng, private_key);
@@ -358,8 +358,7 @@ void Server::process_handshake_msg(Handshake_Type type,
else
state->set_expected_next(HANDSHAKE_CCS);
- state->client_kex = new Client_Key_Exchange(contents, state->suite,
- state->version);
+ state->client_kex = new Client_Key_Exchange(contents, state, creds);
SecureVector<byte> pre_master =
state->client_kex->pre_master_secret(rng, state);