aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/tls/c_kex.cpp68
-rw-r--r--src/tls/tls_client.cpp30
-rw-r--r--src/tls/tls_extensions.cpp2
-rw-r--r--src/tls/tls_handshake_state.cpp2
-rw-r--r--src/tls/tls_handshake_state.h1
-rw-r--r--src/tls/tls_messages.h8
6 files changed, 59 insertions, 52 deletions
diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp
index 8abea8fcd..b2dd0b861 100644
--- a/src/tls/c_kex.cpp
+++ b/src/tls/c_kex.cpp
@@ -40,42 +40,66 @@ SecureVector<byte> strip_leading_zeros(const MemoryRegion<byte>& input)
* Create a new Client Key Exchange message
*/
Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer,
- TLS_Handshake_Hash& hash,
- RandomNumberGenerator& rng,
- const Public_Key* pub_key,
- Version_Code using_version,
- Version_Code pref_version)
+ TLS_Handshake_State* state,
+ const std::vector<X509_Certificate>& peer_certs,
+ RandomNumberGenerator& rng)
{
include_length = true;
- if(const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(pub_key))
+ if(state->server_kex)
{
- DH_PrivateKey priv_key(rng, dh_pub->get_domain());
+ std::auto_ptr<Public_Key> pub_key(state->server_kex->key());
- PK_Key_Agreement ka(priv_key, "Raw");
+ if(pub_key->algo_name() != state->suite.kex_algo())
+ throw TLS_Exception(HANDSHAKE_FAILURE,
+ "Server sent a " + pub_key->algo_name() +
+ " key but we expected " + state->suite.kex_algo());
- pre_master = strip_leading_zeros(
- ka.derive_key(0, dh_pub->public_value()).bits_of());
+ if(const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(pub_key.get()))
+ {
+ DH_PrivateKey priv_key(rng, dh_pub->get_domain());
+
+ PK_Key_Agreement ka(priv_key, "Raw");
- key_material = priv_key.public_value();
+ pre_master = strip_leading_zeros(
+ ka.derive_key(0, dh_pub->public_value()).bits_of());
+
+ key_material = priv_key.public_value();
+ }
+ else
+ throw Internal_Error("Server key exchange not a known key type");
}
- else if(const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(pub_key))
+ else
{
- pre_master = rng.random_vec(48);
- pre_master[0] = (pref_version >> 8) & 0xFF;
- pre_master[1] = (pref_version ) & 0xFF;
+ // No server key exchange msg better mean a RSA key in the cert
+
+ std::auto_ptr<Public_Key> pub_key(peer_certs[0].subject_public_key());
- PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15");
+ if(peer_certs.empty())
+ throw Internal_Error("No certificate and no server key exchange");
- key_material = encryptor.encrypt(pre_master, rng);
+ if(const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(pub_key.get()))
+ {
+ const Version_Code pref_version = state->client_hello->version();
- if(using_version == SSL_V3)
- include_length = false;
+ pre_master = rng.random_vec(48);
+ pre_master[0] = (pref_version >> 8) & 0xFF;
+ pre_master[1] = (pref_version ) & 0xFF;
+
+ PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15");
+
+ key_material = encryptor.encrypt(pre_master, rng);
+
+ if(state->version == SSL_V3)
+ include_length = false;
+ }
+ else
+ throw TLS_Exception(HANDSHAKE_FAILURE,
+ "Expected a RSA key in server cert but got " +
+ pub_key->algo_name());
}
- else
- throw Invalid_Argument("Client_Key_Exchange: Key not RSA or DH");
- send(writer, hash);
+ send(writer, state->hash);
}
/*
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index 1d79327e8..48f0aec16 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -9,9 +9,7 @@
#include <botan/internal/tls_handshake_state.h>
#include <botan/internal/tls_messages.h>
#include <botan/internal/stl_util.h>
-#include <botan/rsa.h>
-#include <botan/dsa.h>
-#include <botan/dh.h>
+#include <memory>
namespace Botan {
@@ -255,9 +253,9 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
throw TLS_Exception(BAD_CERTIFICATE,
"TLS_Client: Server certificate is not valid");
- state->kex_pub = peer_certs[0].subject_public_key();
+ std::auto_ptr<Public_Key> peer_key(peer_certs[0].subject_public_key());
- if(state->kex_pub->algo_name() != state->suite.sig_algo())
+ if(peer_key->algo_name() != state->suite.sig_algo())
throw TLS_Exception(ILLEGAL_PARAMETER,
"Certificate key type did not match ciphersuite");
}
@@ -276,22 +274,9 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
if(!state->server_kex->verify(peer_certs[0], state))
{
throw TLS_Exception(DECRYPT_ERROR,
- "Bad signature on server key exchange");
+ "Bad signature on server key exchange");
}
}
-
- if(state->kex_pub)
- delete state->kex_pub;
-
- state->kex_pub = state->server_kex->key();
-
- // this should be in client_key_exchange
- if(dynamic_cast<DH_PublicKey*>(state->kex_pub) &&
- state->suite.kex_algo() != "DH")
- {
- throw TLS_Exception(HANDSHAKE_FAILURE,
- "Server sent DH key but negotiated something else");
- }
}
else if(type == CERTIFICATE_REQUEST)
{
@@ -319,9 +304,10 @@ void TLS_Client::process_handshake_msg(Handshake_Type type,
}
state->client_kex =
- new Client_Key_Exchange(writer, state->hash, rng,
- state->kex_pub, state->version,
- state->client_hello->version());
+ new Client_Key_Exchange(writer,
+ state,
+ peer_certs,
+ rng);
state->keys = Session_Keys(state,
state->client_kex->pre_master_secret(),
diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp
index d9351fdb1..570c7161c 100644
--- a/src/tls/tls_extensions.cpp
+++ b/src/tls/tls_extensions.cpp
@@ -364,6 +364,8 @@ MemoryVector<byte> Supported_Elliptic_Curves::serialize() const
buf[0] = get_byte<u16bit>(0, buf.size()-2);
buf[1] = get_byte<u16bit>(1, buf.size()-2);
+
+ return buf;
}
Supported_Elliptic_Curves::Supported_Elliptic_Curves()
diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp
index c424c9726..6ad9b630c 100644
--- a/src/tls/tls_handshake_state.cpp
+++ b/src/tls/tls_handshake_state.cpp
@@ -89,7 +89,6 @@ TLS_Handshake_State::TLS_Handshake_State()
client_finished = 0;
server_finished = 0;
- kex_pub = 0;
kex_priv = 0;
version = SSL_V3;
@@ -264,7 +263,6 @@ TLS_Handshake_State::~TLS_Handshake_State()
delete client_finished;
delete server_finished;
- delete kex_pub;
delete kex_priv;
}
diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h
index b2ed0dd20..18b289fe1 100644
--- a/src/tls/tls_handshake_state.h
+++ b/src/tls/tls_handshake_state.h
@@ -76,7 +76,6 @@ class TLS_Handshake_State
class Finished* client_finished;
class Finished* server_finished;
- Public_Key* kex_pub;
Private_Key* kex_priv;
TLS_Ciphersuite suite;
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index ffc325a89..e58a3bfbf 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -210,11 +210,9 @@ class Client_Key_Exchange : public Handshake_Message
Version_Code version);
Client_Key_Exchange(Record_Writer& output,
- TLS_Handshake_Hash& hash,
- RandomNumberGenerator& rng,
- const Public_Key* my_key,
- Version_Code using_version,
- Version_Code pref_version);
+ TLS_Handshake_State* state,
+ const std::vector<X509_Certificate>& peer_certs,
+ RandomNumberGenerator& rng);
Client_Key_Exchange(const MemoryRegion<byte>& buf,
const TLS_Ciphersuite& suite,