aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/tls/msg_cert_verify.cpp2
-rw-r--r--src/tls/msg_client_kex.cpp24
-rw-r--r--src/tls/msg_finished.cpp2
-rw-r--r--src/tls/msg_server_kex.cpp16
-rw-r--r--src/tls/tls_channel.cpp8
-rw-r--r--src/tls/tls_channel.h8
-rw-r--r--src/tls/tls_client.cpp161
-rw-r--r--src/tls/tls_handshake_hash.cpp4
-rw-r--r--src/tls/tls_handshake_hash.h4
-rw-r--r--src/tls/tls_handshake_state.cpp114
-rw-r--r--src/tls/tls_handshake_state.h117
-rw-r--r--src/tls/tls_messages.h12
-rw-r--r--src/tls/tls_server.cpp246
-rw-r--r--src/tls/tls_session_key.cpp10
-rw-r--r--src/tls/tls_session_key.h2
15 files changed, 436 insertions, 294 deletions
diff --git a/src/tls/msg_cert_verify.cpp b/src/tls/msg_cert_verify.cpp
index a6ec298c9..79e7bcaf6 100644
--- a/src/tls/msg_cert_verify.cpp
+++ b/src/tls/msg_cert_verify.cpp
@@ -92,7 +92,7 @@ std::vector<byte> Certificate_Verify::serialize() const
* Verify a Certificate Verify message
*/
bool Certificate_Verify::verify(const X509_Certificate& cert,
- Handshake_State* state)
+ const Handshake_State* state) const
{
std::unique_ptr<Public_Key> key(cert.subject_public_key());
diff --git a/src/tls/msg_client_kex.cpp b/src/tls/msg_client_kex.cpp
index 176187d08..0fbd03b72 100644
--- a/src/tls/msg_client_kex.cpp
+++ b/src/tls/msg_client_kex.cpp
@@ -61,13 +61,13 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
{
std::string identity_hint = "";
- if(state->server_kex)
+ if(state->server_kex())
{
- TLS_Data_Reader reader(state->server_kex->params());
+ TLS_Data_Reader reader(state->server_kex()->params());
identity_hint = reader.get_string(2, 0, 65535);
}
- const std::string hostname = state->client_hello->sni_hostname();
+ const std::string hostname = state->client_hello()->sni_hostname();
const std::string psk_identity = creds.psk_identity("tls-client",
hostname,
@@ -82,9 +82,9 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
append_tls_length_value(m_pre_master, zeros, 2);
append_tls_length_value(m_pre_master, psk.bits_of(), 2);
}
- else if(state->server_kex)
+ else if(state->server_kex())
{
- TLS_Data_Reader reader(state->server_kex->params());
+ TLS_Data_Reader reader(state->server_kex()->params());
SymmetricKey psk;
@@ -92,7 +92,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
{
std::string identity_hint = reader.get_string(2, 0, 65535);
- const std::string hostname = state->client_hello->sni_hostname();
+ const std::string hostname = state->client_hello()->sni_hostname();
const std::string psk_identity = creds.psk_identity("tls-client",
hostname,
@@ -238,7 +238,7 @@ Client_Key_Exchange::Client_Key_Exchange(Handshake_IO& io,
if(const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(pub_key.get()))
{
- const Protocol_Version offered_version = state->client_hello->version();
+ const Protocol_Version offered_version = state->client_hello()->version();
m_pre_master = rng.random_vec(48);
m_pre_master[0] = offered_version.major_version();
@@ -275,7 +275,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents,
if(kex_algo == "RSA")
{
- BOTAN_ASSERT(state->server_certs && !state->server_certs->cert_chain().empty(),
+ BOTAN_ASSERT(state->server_certs() && !state->server_certs()->cert_chain().empty(),
"RSA key exchange negotiated so server sent a certificate");
const Private_Key* private_key = state->server_rsa_kex_key;
@@ -288,7 +288,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents,
PK_Decryptor_EME decryptor(*private_key, "PKCS1v15");
- Protocol_Version client_version = state->client_hello->version();
+ Protocol_Version client_version = state->client_hello()->version();
try
{
@@ -328,7 +328,7 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents,
const std::string psk_identity = reader.get_string(2, 0, 65535);
psk = creds.psk("tls-server",
- state->client_hello->sni_hostname(),
+ state->client_hello()->sni_hostname(),
psk_identity);
if(psk.length() == 0)
@@ -349,14 +349,14 @@ Client_Key_Exchange::Client_Key_Exchange(const std::vector<byte>& contents,
}
else if(kex_algo == "SRP_SHA")
{
- SRP6_Server_Session& srp = state->server_kex->server_srp_params();
+ SRP6_Server_Session& srp = state->server_kex()->server_srp_params();
m_pre_master = srp.step2(BigInt::decode(reader.get_range<byte>(2, 0, 65535))).bits_of();
}
else if(kex_algo == "DH" || kex_algo == "DHE_PSK" ||
kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
{
- const Private_Key& private_key = state->server_kex->server_kex_key();
+ const Private_Key& private_key = state->server_kex()->server_kex_key();
const PK_Key_Agreement_Key* ka_key =
dynamic_cast<const PK_Key_Agreement_Key*>(&private_key);
diff --git a/src/tls/msg_finished.cpp b/src/tls/msg_finished.cpp
index 4f4f384c5..9a38b822b 100644
--- a/src/tls/msg_finished.cpp
+++ b/src/tls/msg_finished.cpp
@@ -94,7 +94,7 @@ Finished::Finished(const std::vector<byte>& buf)
* Verify a Finished message
*/
bool Finished::verify(Handshake_State* state,
- Connection_Side side)
+ Connection_Side side) const
{
return (m_verification_data == finished_compute_verify(state, side));
}
diff --git a/src/tls/msg_server_kex.cpp b/src/tls/msg_server_kex.cpp
index 2d27c6f0d..6e238c4fd 100644
--- a/src/tls/msg_server_kex.cpp
+++ b/src/tls/msg_server_kex.cpp
@@ -35,7 +35,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
const Private_Key* signing_key) :
m_kex_key(nullptr), m_srp_params(nullptr)
{
- const std::string hostname = state->client_hello->sni_hostname();
+ const std::string hostname = state->client_hello()->sni_hostname();
const std::string kex_algo = state->suite.kex_algo();
if(kex_algo == "PSK" || kex_algo == "DHE_PSK" || kex_algo == "ECDHE_PSK")
@@ -58,7 +58,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
else if(kex_algo == "ECDH" || kex_algo == "ECDHE_PSK")
{
const std::vector<std::string>& curves =
- state->client_hello->supported_ecc_curves();
+ state->client_hello()->supported_ecc_curves();
if(curves.empty())
throw Internal_Error("Client sent no ECC extension but we negotiated ECDH");
@@ -91,7 +91,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
}
else if(kex_algo == "SRP_SHA")
{
- const std::string srp_identifier = state->client_hello->srp_identifier();
+ const std::string srp_identifier = state->client_hello()->srp_identifier();
std::string group_id;
BigInt v;
@@ -130,8 +130,8 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
PK_Signer signer(*signing_key, format.first, format.second);
- signer.update(state->client_hello->random());
- signer.update(state->server_hello->random());
+ signer.update(state->client_hello()->random());
+ signer.update(state->server_hello()->random());
signer.update(params());
m_signature = signer.signature(rng);
}
@@ -270,8 +270,8 @@ bool Server_Key_Exchange::verify(const X509_Certificate& cert,
PK_Verifier verifier(*key, format.first, format.second);
- verifier.update(state->client_hello->random());
- verifier.update(state->server_hello->random());
+ verifier.update(state->client_hello()->random());
+ verifier.update(state->server_hello()->random());
verifier.update(params());
return verifier.check_signature(m_signature);
@@ -284,7 +284,7 @@ const Private_Key& Server_Key_Exchange::server_kex_key() const
}
// Only valid for SRP negotiation
-SRP6_Server_Session& Server_Key_Exchange::server_srp_params()
+SRP6_Server_Session& Server_Key_Exchange::server_srp_params() const
{
BOTAN_ASSERT_NONNULL(m_srp_params);
return *m_srp_params;
diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp
index 2951bbeb0..253110c81 100644
--- a/src/tls/tls_channel.cpp
+++ b/src/tls/tls_channel.cpp
@@ -228,7 +228,7 @@ void Channel::send_alert(const Alert& alert)
}
}
-void Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello)
+void Channel::Secure_Renegotiation_State::update(const Client_Hello* client_hello)
{
if(initial_handshake())
{
@@ -260,7 +260,7 @@ void Channel::Secure_Renegotiation_State::update(Client_Hello* client_hello)
}
}
-void Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello)
+void Channel::Secure_Renegotiation_State::update(const Server_Hello* server_hello)
{
if(initial_handshake())
{
@@ -298,8 +298,8 @@ void Channel::Secure_Renegotiation_State::update(Server_Hello* server_hello)
m_initial_handshake = false;
}
-void Channel::Secure_Renegotiation_State::update(Finished* client_finished,
- Finished* server_finished)
+void Channel::Secure_Renegotiation_State::update(const Finished* client_finished,
+ const Finished* server_finished)
{
m_client_verify = client_finished->verify_data();
m_server_verify = server_finished->verify_data();
diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h
index 7a538fb9d..ae8791f6b 100644
--- a/src/tls/tls_channel.h
+++ b/src/tls/tls_channel.h
@@ -118,11 +118,11 @@ class BOTAN_DLL Channel
m_secure_renegotiation(false)
{}
- void update(class Client_Hello* client_hello);
- void update(class Server_Hello* server_hello);
+ void update(const class Client_Hello* client_hello);
+ void update(const class Server_Hello* server_hello);
- void update(class Finished* client_finished,
- class Finished* server_finished);
+ void update(const class Finished* client_finished,
+ const class Finished* server_finished);
const std::vector<byte>& for_client_hello() const
{ return m_client_verify; }
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index e72dcbc8f..e0f9b11d8 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -51,7 +51,7 @@ Handshake_State* Client::new_handshake_state()
*/
void Client::renegotiate(bool force_full_renegotiation)
{
- if(m_state && m_state->client_hello)
+ if(m_state && m_state->client_hello())
return; // currently in active handshake
m_state.reset();
@@ -86,23 +86,23 @@ void Client::initiate_handshake(bool force_full_renegotiation,
{
if(srp_identifier == "" || session_info.srp_identifier() == srp_identifier)
{
- m_state->client_hello = new Client_Hello(
+ m_state->client_hello(new Client_Hello(
m_state->handshake_io(),
m_state->hash,
m_policy,
m_rng,
m_secure_renegotiation.for_client_hello(),
session_info,
- send_npn_request);
+ send_npn_request));
m_state->resume_master_secret = session_info.master_secret();
}
}
}
- if(!m_state->client_hello) // not resuming
+ if(!m_state->client_hello()) // not resuming
{
- m_state->client_hello = new Client_Hello(
+ m_state->client_hello(new Client_Hello(
m_state->handshake_io(),
m_state->hash,
version,
@@ -111,10 +111,10 @@ void Client::initiate_handshake(bool force_full_renegotiation,
m_secure_renegotiation.for_client_hello(),
send_npn_request,
m_hostname,
- srp_identifier);
+ srp_identifier));
}
- m_secure_renegotiation.update(m_state->client_hello);
+ m_secure_renegotiation.update(m_state->client_hello());
}
void Client::alert_notify(const Alert& alert)
@@ -140,7 +140,7 @@ void Client::process_handshake_msg(Handshake_Type type,
Hello_Request hello_request(contents);
// Ignore request entirely if we are currently negotiating a handshake
- if(m_state->client_hello)
+ if(m_state->client_hello())
return;
if(!m_secure_renegotiation.supported() && !m_policy.allow_insecure_renegotiation())
@@ -172,58 +172,57 @@ void Client::process_handshake_msg(Handshake_Type type,
std::unique_ptr<Client_Hello> client_hello_w_cookie(
new Client_Hello(m_state->handshake_io(),
m_state->hash,
- *m_state->client_hello,
+ *m_state->client_hello(),
hello_verify_request));
- delete m_state->client_hello;
- m_state->client_hello = client_hello_w_cookie.release();
+ m_state->client_hello(client_hello_w_cookie.release());
}
else if(type == SERVER_HELLO)
{
- m_state->server_hello = new Server_Hello(contents);
+ m_state->server_hello(new Server_Hello(contents));
- if(!m_state->client_hello->offered_suite(m_state->server_hello->ciphersuite()))
+ if(!m_state->client_hello()->offered_suite(m_state->server_hello()->ciphersuite()))
{
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server replied with ciphersuite we didn't send");
}
- if(!value_exists(m_state->client_hello->compression_methods(),
- m_state->server_hello->compression_method()))
+ if(!value_exists(m_state->client_hello()->compression_methods(),
+ m_state->server_hello()->compression_method()))
{
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server replied with compression method we didn't send");
}
- if(!m_state->client_hello->next_protocol_notification() &&
- m_state->server_hello->next_protocol_notification())
+ if(!m_state->client_hello()->next_protocol_notification() &&
+ m_state->server_hello()->next_protocol_notification())
{
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server sent next protocol but we didn't request it");
}
- if(m_state->server_hello->supports_session_ticket())
+ if(m_state->server_hello()->supports_session_ticket())
{
- if(!m_state->client_hello->supports_session_ticket())
+ if(!m_state->client_hello()->supports_session_ticket())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server sent session ticket extension but we did not");
}
- m_state->set_version(m_state->server_hello->version());
+ m_state->set_version(m_state->server_hello()->version());
m_writer.set_version(m_state->version());
m_reader.set_version(m_state->version());
- m_secure_renegotiation.update(m_state->server_hello);
+ m_secure_renegotiation.update(m_state->server_hello());
- m_peer_supports_heartbeats = m_state->server_hello->supports_heartbeats();
- m_heartbeat_sending_allowed = m_state->server_hello->peer_can_send_heartbeats();
+ m_peer_supports_heartbeats = m_state->server_hello()->supports_heartbeats();
+ m_heartbeat_sending_allowed = m_state->server_hello()->peer_can_send_heartbeats();
- m_state->suite = Ciphersuite::by_id(m_state->server_hello->ciphersuite());
+ m_state->suite = Ciphersuite::by_id(m_state->server_hello()->ciphersuite());
const bool server_returned_same_session_id =
- !m_state->server_hello->session_id().empty() &&
- (m_state->server_hello->session_id() == m_state->client_hello->session_id());
+ !m_state->server_hello()->session_id().empty() &&
+ (m_state->server_hello()->session_id() == m_state->client_hello()->session_id());
if(server_returned_same_session_id)
{
@@ -233,7 +232,7 @@ void Client::process_handshake_msg(Handshake_Type type,
* In this case, we offered the version used in the original
* session, and the server must resume with the same version.
*/
- if(m_state->server_hello->version() != m_state->client_hello->version())
+ if(m_state->server_hello()->version() != m_state->client_hello()->version())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server resumed session but with wrong version");
@@ -242,7 +241,7 @@ void Client::process_handshake_msg(Handshake_Type type,
true);
// The server is not strictly required to send us a new ticket
- if(m_state->server_hello->supports_session_ticket())
+ if(m_state->server_hello()->supports_session_ticket())
m_state->set_expected_next(NEW_SESSION_TICKET);
m_state->set_expected_next(HANDSHAKE_CCS);
@@ -251,7 +250,7 @@ void Client::process_handshake_msg(Handshake_Type type,
{
// new session
- if(m_state->version() > m_state->client_hello->version())
+ if(m_state->version() > m_state->client_hello()->version())
{
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Server replied with later version than in hello");
@@ -303,9 +302,9 @@ void Client::process_handshake_msg(Handshake_Type type,
m_state->set_expected_next(SERVER_HELLO_DONE);
}
- m_state->server_certs = new Certificate(contents);
+ m_state->server_certs(new Certificate(contents));
- m_peer_certs = m_state->server_certs->cert_chain();
+ m_peer_certs = m_state->server_certs()->cert_chain();
if(m_peer_certs.empty())
throw TLS_Exception(Alert::HANDSHAKE_FAILURE,
"Client: No certificates sent by server");
@@ -330,14 +329,16 @@ void Client::process_handshake_msg(Handshake_Type type,
m_state->set_expected_next(CERTIFICATE_REQUEST); // optional
m_state->set_expected_next(SERVER_HELLO_DONE);
- m_state->server_kex = new Server_Key_Exchange(contents,
- m_state->suite.kex_algo(),
- m_state->suite.sig_algo(),
- m_state->version());
+ m_state->server_kex(
+ new Server_Key_Exchange(contents,
+ m_state->suite.kex_algo(),
+ m_state->suite.sig_algo(),
+ m_state->version())
+ );
if(m_state->suite.sig_algo() != "")
{
- if(!m_state->server_kex->verify(m_peer_certs[0], m_state.get()))
+ if(!m_state->server_kex()->verify(m_peer_certs[0], m_state.get()))
{
throw TLS_Exception(Alert::DECRYPT_ERROR,
"Bad signature on server key exchange");
@@ -347,53 +348,62 @@ void Client::process_handshake_msg(Handshake_Type type,
else if(type == CERTIFICATE_REQUEST)
{
m_state->set_expected_next(SERVER_HELLO_DONE);
- m_state->cert_req = new Certificate_Req(contents, m_state->version());
+ m_state->cert_req(
+ new Certificate_Req(contents, m_state->version())
+ );
}
else if(type == SERVER_HELLO_DONE)
{
- m_state->server_hello_done = new Server_Hello_Done(contents);
+ m_state->server_hello_done(
+ new Server_Hello_Done(contents)
+ );
if(m_state->received_handshake_msg(CERTIFICATE_REQUEST))
{
const std::vector<std::string>& types =
- m_state->cert_req->acceptable_cert_types();
+ m_state->cert_req()->acceptable_cert_types();
std::vector<X509_Certificate> client_certs =
m_creds.cert_chain(types,
"tls-client",
m_hostname);
- m_state->client_certs = new Certificate(m_state->handshake_io(),
- m_state->hash,
- client_certs);
+ m_state->client_certs(
+ new Certificate(m_state->handshake_io(),
+ m_state->hash,
+ client_certs)
+ );
}
- m_state->client_kex =
+ m_state->client_kex(
new Client_Key_Exchange(m_state->handshake_io(),
m_state.get(),
m_policy,
m_creds,
m_peer_certs,
m_hostname,
- m_rng);
+ m_rng)
+ );
m_state->keys = Session_Keys(m_state.get(),
- m_state->client_kex->pre_master_secret(),
+ m_state->client_kex()->pre_master_secret(),
false);
if(m_state->received_handshake_msg(CERTIFICATE_REQUEST) &&
- !m_state->client_certs->empty())
+ !m_state->client_certs()->empty())
{
Private_Key* private_key =
- m_creds.private_key_for(m_state->client_certs->cert_chain()[0],
+ m_creds.private_key_for(m_state->client_certs()->cert_chain()[0],
"tls-client",
m_hostname);
- m_state->client_verify = new Certificate_Verify(m_state->handshake_io(),
- m_state.get(),
- m_policy,
- m_rng,
- private_key);
+ m_state->client_verify(
+ new Certificate_Verify(m_state->handshake_io(),
+ m_state.get(),
+ m_policy,
+ m_rng,
+ private_key)
+ );
}
m_writer.send(CHANGE_CIPHER_SPEC, 1);
@@ -401,27 +411,30 @@ void Client::process_handshake_msg(Handshake_Type type,
m_writer.change_cipher_spec(CLIENT,
m_state->suite,
m_state->keys,
- m_state->server_hello->compression_method());
+ m_state->server_hello()->compression_method());
- if(m_state->server_hello->next_protocol_notification())
+ if(m_state->server_hello()->next_protocol_notification())
{
const std::string protocol =
- m_state->client_npn_cb(m_state->server_hello->next_protocols());
+ m_state->client_npn_cb(m_state->server_hello()->next_protocols());
- m_state->next_protocol = new Next_Protocol(m_state->handshake_io(), m_state->hash, protocol);
+ m_state->next_protocol(
+ new Next_Protocol(m_state->handshake_io(), m_state->hash, protocol)
+ );
}
- m_state->client_finished = new Finished(m_state->handshake_io(),
- m_state.get(), CLIENT);
+ m_state->client_finished(
+ new Finished(m_state->handshake_io(), m_state.get(), CLIENT)
+ );
- if(m_state->server_hello->supports_session_ticket())
+ if(m_state->server_hello()->supports_session_ticket())
m_state->set_expected_next(NEW_SESSION_TICKET);
else
m_state->set_expected_next(HANDSHAKE_CCS);
}
else if(type == NEW_SESSION_TICKET)
{
- m_state->new_session_ticket = new New_Session_Ticket(contents);
+ m_state->new_session_ticket(new New_Session_Ticket(contents));
m_state->set_expected_next(HANDSHAKE_CCS);
}
@@ -432,36 +445,38 @@ void Client::process_handshake_msg(Handshake_Type type,
m_reader.change_cipher_spec(CLIENT,
m_state->suite,
m_state->keys,
- m_state->server_hello->compression_method());
+ m_state->server_hello()->compression_method());
}
else if(type == FINISHED)
{
m_state->set_expected_next(HELLO_REQUEST);
- m_state->server_finished = new Finished(contents);
+ m_state->server_finished(new Finished(contents));
- if(!m_state->server_finished->verify(m_state.get(), SERVER))
+ if(!m_state->server_finished()->verify(m_state.get(), SERVER))
throw TLS_Exception(Alert::DECRYPT_ERROR,
"Finished message didn't verify");
m_state->hash.update(m_state->handshake_io().format(contents, type));
- if(!m_state->client_finished) // session resume case
+ if(!m_state->client_finished()) // session resume case
{
m_writer.send(CHANGE_CIPHER_SPEC, 1);
m_writer.change_cipher_spec(CLIENT,
m_state->suite,
m_state->keys,
- m_state->server_hello->compression_method());
+ m_state->server_hello()->compression_method());
- m_state->client_finished = new Finished(m_state->handshake_io(),
- m_state.get(), CLIENT);
+ m_state->client_finished(
+ new Finished(m_state->handshake_io(), m_state.get(), CLIENT)
+ );
}
- m_secure_renegotiation.update(m_state->client_finished, m_state->server_finished);
+ m_secure_renegotiation.update(m_state->client_finished(),
+ m_state->server_finished());
- std::vector<byte> session_id = m_state->server_hello->session_id();
+ std::vector<byte> session_id = m_state->server_hello()->session_id();
const std::vector<byte>& session_ticket = m_state->session_ticket();
@@ -471,12 +486,12 @@ void Client::process_handshake_msg(Handshake_Type type,
Session session_info(
session_id,
m_state->keys.master_secret(),
- m_state->server_hello->version(),
- m_state->server_hello->ciphersuite(),
- m_state->server_hello->compression_method(),
+ m_state->server_hello()->version(),
+ m_state->server_hello()->ciphersuite(),
+ m_state->server_hello()->compression_method(),
CLIENT,
m_secure_renegotiation.supported(),
- m_state->server_hello->fragment_size(),
+ m_state->server_hello()->fragment_size(),
m_peer_certs,
session_ticket,
m_hostname,
diff --git a/src/tls/tls_handshake_hash.cpp b/src/tls/tls_handshake_hash.cpp
index ba3ee52db..440c6fb82 100644
--- a/src/tls/tls_handshake_hash.cpp
+++ b/src/tls/tls_handshake_hash.cpp
@@ -19,7 +19,7 @@ namespace TLS {
* Return a TLS Handshake Hash
*/
secure_vector<byte> Handshake_Hash::final(Protocol_Version version,
- const std::string& mac_algo)
+ const std::string& mac_algo) const
{
Algorithm_Factory& af = global_state().algorithm_factory();
@@ -42,7 +42,7 @@ secure_vector<byte> Handshake_Hash::final(Protocol_Version version,
/**
* Return a SSLv3 Handshake Hash
*/
-secure_vector<byte> Handshake_Hash::final_ssl3(const secure_vector<byte>& secret)
+secure_vector<byte> Handshake_Hash::final_ssl3(const secure_vector<byte>& secret) const
{
const byte PAD_INNER = 0x36, PAD_OUTER = 0x5C;
diff --git a/src/tls/tls_handshake_hash.h b/src/tls/tls_handshake_hash.h
index e7fc24f64..840895963 100644
--- a/src/tls/tls_handshake_hash.h
+++ b/src/tls/tls_handshake_hash.h
@@ -31,9 +31,9 @@ class Handshake_Hash
{ data += in; }
secure_vector<byte> final(Protocol_Version version,
- const std::string& mac_algo);
+ const std::string& mac_algo) const;
- secure_vector<byte> final_ssl3(const secure_vector<byte>& master_secret);
+ secure_vector<byte> final_ssl3(const secure_vector<byte>& master_secret) const;
const std::vector<byte>& get_contents() const
{ return data; }
diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp
index 2046652ec..8e9d6b0ba 100644
--- a/src/tls/tls_handshake_state.cpp
+++ b/src/tls/tls_handshake_state.cpp
@@ -1,6 +1,6 @@
/*
* TLS Handshaking
-* (C) 2004-2006,2011 Jack Lloyd
+* (C) 2004-2006,2011,2012 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -91,6 +91,73 @@ Handshake_State::Handshake_State(Handshake_IO* io) :
{
}
+Handshake_State::~Handshake_State() {}
+
+void Handshake_State::client_hello(Client_Hello* client_hello)
+ {
+ m_client_hello.reset(client_hello);
+ }
+
+void Handshake_State::server_hello(Server_Hello* server_hello)
+ {
+ m_server_hello.reset(server_hello);
+ }
+
+void Handshake_State::server_certs(Certificate* server_certs)
+ {
+ m_server_certs.reset(server_certs);
+ }
+
+void Handshake_State::server_kex(Server_Key_Exchange* server_kex)
+ {
+ m_server_kex.reset(server_kex);
+ }
+
+void Handshake_State::cert_req(Certificate_Req* cert_req)
+ {
+ m_cert_req.reset(cert_req);
+ }
+
+void Handshake_State::server_hello_done(Server_Hello_Done* server_hello_done)
+ {
+ m_server_hello_done.reset(server_hello_done);
+ }
+
+void Handshake_State::client_certs(Certificate* client_certs)
+ {
+ m_client_certs.reset(client_certs);
+ }
+
+void Handshake_State::client_kex(Client_Key_Exchange* client_kex)
+ {
+ m_client_kex.reset(client_kex);
+ }
+
+void Handshake_State::client_verify(Certificate_Verify* client_verify)
+ {
+ m_client_verify.reset(client_verify);
+ }
+
+void Handshake_State::next_protocol(Next_Protocol* next_protocol)
+ {
+ m_next_protocol.reset(next_protocol);
+ }
+
+void Handshake_State::new_session_ticket(New_Session_Ticket* new_session_ticket)
+ {
+ m_new_session_ticket.reset(new_session_ticket);
+ }
+
+void Handshake_State::server_finished(Finished* server_finished)
+ {
+ m_server_finished.reset(server_finished);
+ }
+
+void Handshake_State::client_finished(Finished* client_finished)
+ {
+ m_client_finished.reset(client_finished);
+ }
+
void Handshake_State::set_version(const Protocol_Version& version)
{
m_version = version;
@@ -132,20 +199,20 @@ bool Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) const
std::string Handshake_State::srp_identifier() const
{
if(suite.valid() && suite.kex_algo() == "SRP_SHA")
- return client_hello->srp_identifier();
+ return client_hello()->srp_identifier();
return "";
}
const std::vector<byte>& Handshake_State::session_ticket() const
{
- if(new_session_ticket && !new_session_ticket->ticket().empty())
- return new_session_ticket->ticket();
+ if(new_session_ticket() && !new_session_ticket()->ticket().empty())
+ return new_session_ticket()->ticket();
- return client_hello->session_ticket();
+ return client_hello()->session_ticket();
}
-KDF* Handshake_State::protocol_specific_prf()
+KDF* Handshake_State::protocol_specific_prf() const
{
if(version() == Protocol_Version::SSL_V3)
{
@@ -173,8 +240,8 @@ std::string choose_hash(const std::string& sig_algo,
Protocol_Version negotiated_version,
const Policy& policy,
bool for_client_auth,
- Client_Hello* client_hello,
- Certificate_Req* cert_req)
+ const Client_Hello* client_hello,
+ const Certificate_Req* cert_req)
{
if(!negotiated_version.supports_negotiable_signature_algorithms())
{
@@ -226,7 +293,7 @@ Handshake_State::choose_sig_format(const Private_Key* key,
std::string& hash_algo_out,
std::string& sig_algo_out,
bool for_client_auth,
- const Policy& policy)
+ const Policy& policy) const
{
const std::string sig_algo = key->algo_name();
@@ -235,8 +302,8 @@ Handshake_State::choose_sig_format(const Private_Key* key,
this->version(),
policy,
for_client_auth,
- client_hello,
- cert_req);
+ client_hello(),
+ cert_req());
if(this->version().supports_negotiable_signature_algorithms())
{
@@ -264,7 +331,7 @@ std::pair<std::string, Signature_Format>
Handshake_State::understand_sig_format(const Public_Key* key,
std::string hash_algo,
std::string sig_algo,
- bool for_client_auth)
+ bool for_client_auth) const
{
const std::string algo_name = key->algo_name();
@@ -323,29 +390,6 @@ Handshake_State::understand_sig_format(const Public_Key* key,
throw Invalid_Argument(algo_name + " is invalid/unknown for TLS signatures");
}
-/*
-* Destroy the SSL/TLS Handshake State
-*/
-Handshake_State::~Handshake_State()
- {
- delete client_hello;
- delete server_hello;
- delete server_certs;
- delete server_kex;
- delete cert_req;
- delete server_hello_done;
- delete next_protocol;
- delete new_session_ticket;
-
- delete client_certs;
- delete client_kex;
- delete client_verify;
- delete client_finished;
- delete server_finished;
-
- delete m_handshake_io;
- }
-
}
}
diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h
index 49470fecb..7dea555cc 100644
--- a/src/tls/tls_handshake_state.h
+++ b/src/tls/tls_handshake_state.h
@@ -1,6 +1,6 @@
/*
* TLS Handshake State
-* (C) 2004-2006 Jack Lloyd
+* (C) 2004-2006,2011,2012 Jack Lloyd
*
* Released under the terms of the Botan license
*/
@@ -16,6 +16,7 @@
#include <functional>
#include <utility>
+#include <memory>
namespace Botan {
@@ -25,6 +26,19 @@ namespace TLS {
class Policy;
+class Client_Hello;
+class Server_Hello;
+class Certificate;
+class Server_Key_Exchange;
+class Certificate_Req;
+class Server_Hello_Done;
+class Certificate;
+class Client_Key_Exchange;
+class Certificate_Verify;
+class Next_Protocol;
+class New_Session_Ticket;
+class Finished;
+
/**
* SSL/TLS Handshake State
*/
@@ -38,6 +52,8 @@ class Handshake_State
Handshake_State(const Handshake_State&) = delete;
Handshake_State& operator=(const Handshake_State&) = delete;
+ Handshake_IO& handshake_io() { return *m_handshake_io; }
+
bool received_handshake_msg(Handshake_Type handshake_msg) const;
void confirm_transition_to(Handshake_Type handshake_msg);
@@ -49,70 +65,119 @@ class Handshake_State
understand_sig_format(const Public_Key* key,
std::string hash_algo,
std::string sig_algo,
- bool for_client_auth);
+ bool for_client_auth) const;
std::pair<std::string, Signature_Format>
choose_sig_format(const Private_Key* key,
std::string& hash_algo,
std::string& sig_algo,
bool for_client_auth,
- const Policy& policy);
+ const Policy& policy) const;
std::string srp_identifier() const;
- KDF* protocol_specific_prf();
+ KDF* protocol_specific_prf() const;
Protocol_Version version() const { return m_version; }
void set_version(const Protocol_Version& version);
- class Client_Hello* client_hello = nullptr;
- class Server_Hello* server_hello = nullptr;
- class Certificate* server_certs = nullptr;
- class Server_Key_Exchange* server_kex = nullptr;
- class Certificate_Req* cert_req = nullptr;
- class Server_Hello_Done* server_hello_done = nullptr;
+ void client_hello(Client_Hello* client_hello);
+ void server_hello(Server_Hello* server_hello);
+ void server_certs(Certificate* server_certs);
+ void server_kex(Server_Key_Exchange* server_kex);
+ void cert_req(Certificate_Req* cert_req);
+ void server_hello_done(Server_Hello_Done* server_hello_done);
+ void client_certs(Certificate* client_certs);
+ void client_kex(Client_Key_Exchange* client_kex);
+ void client_verify(Certificate_Verify* client_verify);
+ void next_protocol(Next_Protocol* next_protocol);
+ void new_session_ticket(New_Session_Ticket* new_session_ticket);
+ void server_finished(Finished* server_finished);
+ void client_finished(Finished* client_finished);
+
+ const Client_Hello* client_hello() const
+ { return m_client_hello.get(); }
+
+ const Server_Hello* server_hello() const
+ { return m_server_hello.get(); }
+
+ const Certificate* server_certs() const
+ { return m_server_certs.get(); }
+
+ const Server_Key_Exchange* server_kex() const
+ { return m_server_kex.get(); }
+
+ const Certificate_Req* cert_req() const
+ { return m_cert_req.get(); }
- class Certificate* client_certs = nullptr;
- class Client_Key_Exchange* client_kex = nullptr;
- class Certificate_Verify* client_verify = nullptr;
+ const Server_Hello_Done* server_hello_done() const
+ { return m_server_hello_done.get(); }
- class Next_Protocol* next_protocol = nullptr;
- class New_Session_Ticket* new_session_ticket = nullptr;
+ const Certificate* client_certs() const
+ { return m_client_certs.get(); }
- class Finished* client_finished = nullptr;
- class Finished* server_finished = nullptr;
+ const Client_Key_Exchange* client_kex() const
+ { return m_client_kex.get(); }
+
+ const Certificate_Verify* client_verify() const
+ { return m_client_verify.get(); }
+
+ const Next_Protocol* next_protocol() const
+ { return m_next_protocol.get(); }
+
+ const New_Session_Ticket* new_session_ticket() const
+ { return m_new_session_ticket.get(); }
+
+ const Finished* server_finished() const
+ { return m_server_finished.get(); }
+
+ const Finished* client_finished() const
+ { return m_client_finished.get(); }
// Used by the server only, in case of RSA key exchange
- Private_Key* server_rsa_kex_key = nullptr;
+ Private_Key* server_rsa_kex_key = nullptr; // FIXME make private
- Ciphersuite suite;
- Session_Keys keys;
- Handshake_Hash hash;
+ Ciphersuite suite; // FIXME make private
+ Session_Keys keys; // FIXME make private
+ Handshake_Hash hash; // FIXME make private
/*
* Only used by clients for session resumption
*/
- secure_vector<byte> resume_master_secret;
+ secure_vector<byte> resume_master_secret; // FIXME make private
/*
* Used by the server to know if resumption should be allowed on
* a server-initiated renegotiation
*/
- bool allow_session_resumption = true;
+ bool allow_session_resumption = true; // FIXME make private
/**
- * Used by client using NPN
+ * Used by client using NPN FIXME make private
*/
std::function<std::string (std::vector<std::string>)> client_npn_cb;
- Handshake_IO& handshake_io() { return *m_handshake_io; }
private:
- Handshake_IO* m_handshake_io = nullptr;
+ std::unique_ptr<Handshake_IO> m_handshake_io;
u32bit m_hand_expecting_mask = 0;
u32bit m_hand_received_mask = 0;
Protocol_Version m_version;
+
+ std::unique_ptr<Client_Hello> m_client_hello;
+ std::unique_ptr<Server_Hello> m_server_hello;
+ std::unique_ptr<Certificate> m_server_certs;
+ std::unique_ptr<Server_Key_Exchange> m_server_kex;
+ std::unique_ptr<Certificate_Req> m_cert_req;
+ std::unique_ptr<Server_Hello_Done> m_server_hello_done;
+ std::unique_ptr<Certificate> m_client_certs;
+ std::unique_ptr<Client_Key_Exchange> m_client_kex;
+ std::unique_ptr<Certificate_Verify> m_client_verify;
+ std::unique_ptr<Next_Protocol> m_next_protocol;
+ std::unique_ptr<New_Session_Ticket> m_new_session_ticket;
+ std::unique_ptr<Finished> m_server_finished;
+ std::unique_ptr<Finished> m_client_finished;
};
}
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 2834a916e..23b1d5634 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -91,7 +91,7 @@ class Client_Hello : public Handshake_Message
bool secure_renegotiation() const { return m_secure_renegotiation; }
- const std::vector<byte>& renegotiation_info()
+ const std::vector<byte>& renegotiation_info() const
{ return m_renegotiation_info; }
bool offered_suite(u16bit ciphersuite) const;
@@ -172,7 +172,7 @@ class Server_Hello : public Handshake_Message
public:
Handshake_Type type() const { return SERVER_HELLO; }
- Protocol_Version version() { return m_version; }
+ Protocol_Version version() const { return m_version; }
const std::vector<byte>& random() const { return m_random; }
@@ -193,7 +193,7 @@ class Server_Hello : public Handshake_Message
size_t fragment_size() const { return m_fragment_size; }
- const std::vector<byte>& renegotiation_info()
+ const std::vector<byte>& renegotiation_info() const
{ return m_renegotiation_info; }
bool supports_heartbeats() const { return m_supports_heartbeats; }
@@ -338,7 +338,7 @@ class Certificate_Verify : public Handshake_Message
* @param state the handshake state
*/
bool verify(const X509_Certificate& cert,
- Handshake_State* state);
+ const Handshake_State* state) const;
Certificate_Verify(Handshake_IO& io,
Handshake_State* state,
@@ -368,7 +368,7 @@ class Finished : public Handshake_Message
{ return m_verification_data; }
bool verify(Handshake_State* state,
- Connection_Side side);
+ Connection_Side side) const;
Finished(Handshake_IO& io,
Handshake_State* state,
@@ -413,7 +413,7 @@ class Server_Key_Exchange : public Handshake_Message
const Private_Key& server_kex_key() const;
// Only valid for SRP negotiation
- SRP6_Server_Session& server_srp_params();
+ SRP6_Server_Session& server_srp_params() const;
Server_Key_Exchange(Handshake_IO& io,
Handshake_State* state,
diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp
index 25716c144..9669693c5 100644
--- a/src/tls/tls_server.cpp
+++ b/src/tls/tls_server.cpp
@@ -21,7 +21,7 @@ namespace {
bool check_for_resume(Session& session_info,
Session_Manager& session_manager,
Credentials_Manager& credentials,
- Client_Hello* client_hello,
+ const Client_Hello* client_hello,
std::chrono::seconds session_ticket_lifetime)
{
const std::vector<byte>& client_session_id = client_hello->session_id();
@@ -271,12 +271,12 @@ void Server::process_handshake_msg(Handshake_Type type,
return;
}
- m_state->client_hello = new Client_Hello(contents, type);
+ m_state->client_hello(new Client_Hello(contents, type));
- if(m_state->client_hello->sni_hostname() != "")
- m_hostname = m_state->client_hello->sni_hostname();
+ if(m_state->client_hello()->sni_hostname() != "")
+ m_hostname = m_state->client_hello()->sni_hostname();
- Protocol_Version client_version = m_state->client_hello->version();
+ Protocol_Version client_version = m_state->client_hello()->version();
const Protocol_Version prev_version = m_reader.get_version();
const bool is_renegotiation = prev_version.valid();
@@ -328,10 +328,10 @@ void Server::process_handshake_msg(Handshake_Type type,
"Client version is unacceptable by policy");
}
- m_secure_renegotiation.update(m_state->client_hello);
+ m_secure_renegotiation.update(m_state->client_hello());
- m_peer_supports_heartbeats = m_state->client_hello->supports_heartbeats();
- m_heartbeat_sending_allowed = m_state->client_hello->peer_can_send_heartbeats();
+ m_peer_supports_heartbeats = m_state->client_hello()->supports_heartbeats();
+ m_heartbeat_sending_allowed = m_state->client_hello()->peer_can_send_heartbeats();
m_writer.set_version(m_state->version());
m_reader.set_version(m_state->version());
@@ -342,7 +342,7 @@ void Server::process_handshake_msg(Handshake_Type type,
check_for_resume(session_info,
m_session_manager,
m_creds,
- m_state->client_hello,
+ m_state->client_hello(),
std::chrono::seconds(m_policy.session_ticket_lifetime()));
bool have_session_ticket_key = false;
@@ -358,25 +358,30 @@ void Server::process_handshake_msg(Handshake_Type type,
{
// resume session
- m_state->server_hello = new Server_Hello(
- m_state->handshake_io(),
- m_state->hash,
- m_state->client_hello->session_id(),
- Protocol_Version(session_info.version()),
- session_info.ciphersuite_code(),
- session_info.compression_method(),
- session_info.fragment_size(),
- m_secure_renegotiation.supported(),
- m_secure_renegotiation.for_server_hello(),
- (m_state->client_hello->supports_session_ticket() &&
- m_state->client_hello->session_ticket().empty() &&
- have_session_ticket_key),
- m_state->client_hello->next_protocol_notification(),
- m_possible_protocols,
- m_state->client_hello->supports_heartbeats(),
- m_rng);
+ const bool offer_new_session_ticket =
+ (m_state->client_hello()->supports_session_ticket() &&
+ m_state->client_hello()->session_ticket().empty() &&
+ have_session_ticket_key);
+
+ m_state->server_hello(
+ new Server_Hello(
+ m_state->handshake_io(),
+ m_state->hash,
+ m_state->client_hello()->session_id(),
+ Protocol_Version(session_info.version()),
+ session_info.ciphersuite_code(),
+ session_info.compression_method(),
+ session_info.fragment_size(),
+ m_secure_renegotiation.supported(),
+ m_secure_renegotiation.for_server_hello(),
+ offer_new_session_ticket,
+ m_state->client_hello()->next_protocol_notification(),
+ m_possible_protocols,
+ m_state->client_hello()->supports_heartbeats(),
+ m_rng)
+ );
- m_secure_renegotiation.update(m_state->server_hello);
+ m_secure_renegotiation.update(m_state->server_hello());
if(session_info.fragment_size())
{
@@ -384,7 +389,7 @@ void Server::process_handshake_msg(Handshake_Type type,
m_writer.set_maximum_fragment_size(session_info.fragment_size());
}
- m_state->suite = Ciphersuite::by_id(m_state->server_hello->ciphersuite());
+ m_state->suite = Ciphersuite::by_id(m_state->server_hello()->ciphersuite());
m_state->keys = Session_Keys(m_state.get(), session_info.master_secret(), true);
@@ -392,33 +397,35 @@ void Server::process_handshake_msg(Handshake_Type type,
{
m_session_manager.remove_entry(session_info.session_id());
- if(m_state->server_hello->supports_session_ticket()) // send an empty ticket
+ if(m_state->server_hello()->supports_session_ticket()) // send an empty ticket
{
- m_state->new_session_ticket =
+ m_state->new_session_ticket(
new New_Session_Ticket(m_state->handshake_io(),
- m_state->hash);
+ m_state->hash)
+ );
}
}
- if(m_state->server_hello->supports_session_ticket() && !m_state->new_session_ticket)
+ if(m_state->server_hello()->supports_session_ticket() && !m_state->new_session_ticket())
{
try
{
const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", "");
- m_state->new_session_ticket =
+ m_state->new_session_ticket(
new New_Session_Ticket(m_state->handshake_io(),
m_state->hash,
session_info.encrypt(ticket_key, m_rng),
- m_policy.session_ticket_lifetime());
+ m_policy.session_ticket_lifetime())
+ );
}
catch(...) {}
- if(!m_state->new_session_ticket)
+ if(!m_state->new_session_ticket())
{
- m_state->new_session_ticket =
- new New_Session_Ticket(m_state->handshake_io(),
- m_state->hash);
+ m_state->new_session_ticket(
+ new New_Session_Ticket(m_state->handshake_io(), m_state->hash)
+ );
}
}
@@ -427,10 +434,11 @@ void Server::process_handshake_msg(Handshake_Type type,
m_writer.change_cipher_spec(SERVER,
m_state->suite,
m_state->keys,
- m_state->server_hello->compression_method());
+ m_state->server_hello()->compression_method());
- m_state->server_finished = new Finished(m_state->handshake_io(),
- m_state.get(), SERVER);
+ m_state->server_finished(
+ new Finished(m_state->handshake_io(), m_state.get(), SERVER)
+ );
m_state->set_expected_next(HANDSHAKE_CCS);
}
@@ -455,35 +463,37 @@ void Server::process_handshake_msg(Handshake_Type type,
send_alert(Alert(Alert::UNRECOGNIZED_NAME));
}
- m_state->server_hello = new Server_Hello(
- m_state->handshake_io(),
- m_state->hash,
- make_hello_random(m_rng), // new session ID
- m_state->version(),
- choose_ciphersuite(m_policy,
- m_state->version(),
- m_creds,
- cert_chains,
- m_state->client_hello),
- choose_compression(m_policy, m_state->client_hello->compression_methods()),
- m_state->client_hello->fragment_size(),
- m_secure_renegotiation.supported(),
- m_secure_renegotiation.for_server_hello(),
- m_state->client_hello->supports_session_ticket() && have_session_ticket_key,
- m_state->client_hello->next_protocol_notification(),
- m_possible_protocols,
- m_state->client_hello->supports_heartbeats(),
- m_rng);
+ m_state->server_hello(
+ new Server_Hello(
+ m_state->handshake_io(),
+ m_state->hash,
+ make_hello_random(m_rng), // new session ID
+ m_state->version(),
+ choose_ciphersuite(m_policy,
+ m_state->version(),
+ m_creds,
+ cert_chains,
+ m_state->client_hello()),
+ choose_compression(m_policy, m_state->client_hello()->compression_methods()),
+ m_state->client_hello()->fragment_size(),
+ m_secure_renegotiation.supported(),
+ m_secure_renegotiation.for_server_hello(),
+ m_state->client_hello()->supports_session_ticket() && have_session_ticket_key,
+ m_state->client_hello()->next_protocol_notification(),
+ m_possible_protocols,
+ m_state->client_hello()->supports_heartbeats(),
+ m_rng)
+ );
- m_secure_renegotiation.update(m_state->server_hello);
+ m_secure_renegotiation.update(m_state->server_hello());
- if(m_state->client_hello->fragment_size())
+ if(m_state->client_hello()->fragment_size())
{
- m_reader.set_maximum_fragment_size(m_state->client_hello->fragment_size());
- m_writer.set_maximum_fragment_size(m_state->client_hello->fragment_size());
+ m_reader.set_maximum_fragment_size(m_state->client_hello()->fragment_size());
+ m_writer.set_maximum_fragment_size(m_state->client_hello()->fragment_size());
}
- m_state->suite = Ciphersuite::by_id(m_state->server_hello->ciphersuite());
+ m_state->suite = Ciphersuite::by_id(m_state->server_hello()->ciphersuite());
const std::string sig_algo = m_state->suite.sig_algo();
const std::string kex_algo = m_state->suite.kex_algo();
@@ -493,9 +503,11 @@ void Server::process_handshake_msg(Handshake_Type type,
BOTAN_ASSERT(!cert_chains[sig_algo].empty(),
"Attempting to send empty certificate chain");
- m_state->server_certs = new Certificate(m_state->handshake_io(),
- m_state->hash,
- cert_chains[sig_algo]);
+ m_state->server_certs(
+ new Certificate(m_state->handshake_io(),
+ m_state->hash,
+ cert_chains[sig_algo])
+ );
}
Private_Key* private_key = nullptr;
@@ -503,7 +515,7 @@ void Server::process_handshake_msg(Handshake_Type type,
if(kex_algo == "RSA" || sig_algo != "")
{
private_key = m_creds.private_key_for(
- m_state->server_certs->cert_chain()[0],
+ m_state->server_certs()->cert_chain()[0],
"tls-server",
m_hostname);
@@ -517,13 +529,14 @@ void Server::process_handshake_msg(Handshake_Type type,
}
else
{
- m_state->server_kex =
+ m_state->server_kex(
new Server_Key_Exchange(m_state->handshake_io(),
m_state.get(),
m_policy,
m_creds,
m_rng,
- private_key);
+ private_key)
+ );
}
std::vector<X509_Certificate> client_auth_CAs =
@@ -531,11 +544,13 @@ void Server::process_handshake_msg(Handshake_Type type,
if(!client_auth_CAs.empty() && m_state->suite.sig_algo() != "")
{
- m_state->cert_req = new Certificate_Req(m_state->handshake_io(),
- m_state->hash,
- m_policy,
- client_auth_CAs,
- m_state->version());
+ m_state->cert_req(
+ new Certificate_Req(m_state->handshake_io(),
+ m_state->hash,
+ m_policy,
+ client_auth_CAs,
+ m_state->version())
+ );
m_state->set_expected_next(CERTIFICATE);
}
@@ -547,42 +562,41 @@ void Server::process_handshake_msg(Handshake_Type type,
*/
m_state->set_expected_next(CLIENT_KEX);
- m_state->server_hello_done = new Server_Hello_Done(m_state->handshake_io(),
- m_state->hash);
+ m_state->server_hello_done(
+ new Server_Hello_Done(m_state->handshake_io(), m_state->hash)
+ );
}
}
else if(type == CERTIFICATE)
{
- m_state->client_certs = new Certificate(contents);
+ m_state->client_certs(new Certificate(contents));
m_state->set_expected_next(CLIENT_KEX);
}
else if(type == CLIENT_KEX)
{
- if(m_state->received_handshake_msg(CERTIFICATE) && !m_state->client_certs->empty())
+ if(m_state->received_handshake_msg(CERTIFICATE) && !m_state->client_certs()->empty())
m_state->set_expected_next(CERTIFICATE_VERIFY);
else
m_state->set_expected_next(HANDSHAKE_CCS);
- m_state->client_kex = new Client_Key_Exchange(contents,
- m_state.get(),
- m_creds,
- m_policy,
- m_rng);
+ m_state->client_kex(
+ new Client_Key_Exchange(contents, m_state.get(), m_creds, m_policy, m_rng)
+ );
m_state->keys = Session_Keys(m_state.get(),
- m_state->client_kex->pre_master_secret(),
+ m_state->client_kex()->pre_master_secret(),
false);
}
else if(type == CERTIFICATE_VERIFY)
{
- m_state->client_verify = new Certificate_Verify(contents, m_state->version());
+ m_state->client_verify(new Certificate_Verify(contents, m_state->version()));
- m_peer_certs = m_state->client_certs->cert_chain();
+ m_peer_certs = m_state->client_certs()->cert_chain();
const bool sig_valid =
- m_state->client_verify->verify(m_peer_certs[0], m_state.get());
+ m_state->client_verify()->verify(m_peer_certs[0], m_state.get());
m_state->hash.update(m_state->handshake_io().format(contents, type));
@@ -607,7 +621,7 @@ void Server::process_handshake_msg(Handshake_Type type,
}
else if(type == HANDSHAKE_CCS)
{
- if(m_state->server_hello->next_protocol_notification())
+ if(m_state->server_hello()->next_protocol_notification())
m_state->set_expected_next(NEXT_PROTOCOL);
else
m_state->set_expected_next(FINISHED);
@@ -615,41 +629,42 @@ void Server::process_handshake_msg(Handshake_Type type,
m_reader.change_cipher_spec(SERVER,
m_state->suite,
m_state->keys,
- m_state->server_hello->compression_method());
+ m_state->server_hello()->compression_method());
}
else if(type == NEXT_PROTOCOL)
{
m_state->set_expected_next(FINISHED);
- m_state->next_protocol = new Next_Protocol(contents);
+ m_state->next_protocol(new Next_Protocol(contents));
- m_next_protocol = m_state->next_protocol->protocol();
+ // should this be a callback?
+ m_next_protocol = m_state->next_protocol()->protocol();
}
else if(type == FINISHED)
{
m_state->set_expected_next(HANDSHAKE_NONE);
- m_state->client_finished = new Finished(contents);
+ m_state->client_finished(new Finished(contents));
- if(!m_state->client_finished->verify(m_state.get(), CLIENT))
+ if(!m_state->client_finished()->verify(m_state.get(), CLIENT))
throw TLS_Exception(Alert::DECRYPT_ERROR,
"Finished message didn't verify");
- if(!m_state->server_finished)
+ if(!m_state->server_finished())
{
// already sent finished if resuming, so this is a new session
m_state->hash.update(m_state->handshake_io().format(contents, type));
Session session_info(
- m_state->server_hello->session_id(),
+ m_state->server_hello()->session_id(),
m_state->keys.master_secret(),
- m_state->server_hello->version(),
- m_state->server_hello->ciphersuite(),
- m_state->server_hello->compression_method(),
+ m_state->server_hello()->version(),
+ m_state->server_hello()->ciphersuite(),
+ m_state->server_hello()->compression_method(),
SERVER,
m_secure_renegotiation.supported(),
- m_state->server_hello->fragment_size(),
+ m_state->server_hello()->fragment_size(),
m_peer_certs,
std::vector<byte>(),
m_hostname,
@@ -658,17 +673,18 @@ void Server::process_handshake_msg(Handshake_Type type,
if(m_handshake_fn(session_info))
{
- if(m_state->server_hello->supports_session_ticket())
+ if(m_state->server_hello()->supports_session_ticket())
{
try
{
const SymmetricKey ticket_key = m_creds.psk("tls-server", "session-ticket", "");
- m_state->new_session_ticket =
+ m_state->new_session_ticket(
new New_Session_Ticket(m_state->handshake_io(),
m_state->hash,
session_info.encrypt(ticket_key, m_rng),
- m_policy.session_ticket_lifetime());
+ m_policy.session_ticket_lifetime())
+ );
}
catch(...) {}
}
@@ -676,11 +692,12 @@ void Server::process_handshake_msg(Handshake_Type type,
m_session_manager.save(session_info);
}
- if(m_state->server_hello->supports_session_ticket() && !m_state->new_session_ticket)
+ if(!m_state->new_session_ticket() &&
+ m_state->server_hello()->supports_session_ticket())
{
- m_state->new_session_ticket = new New_Session_Ticket(m_state->handshake_io(),
- m_state->hash);
-
+ m_state->new_session_ticket(
+ new New_Session_Ticket(m_state->handshake_io(), m_state->hash)
+ );
}
m_writer.send(CHANGE_CIPHER_SPEC, 1);
@@ -688,16 +705,17 @@ void Server::process_handshake_msg(Handshake_Type type,
m_writer.change_cipher_spec(SERVER,
m_state->suite,
m_state->keys,
- m_state->server_hello->compression_method());
+ m_state->server_hello()->compression_method());
- m_state->server_finished = new Finished(m_state->handshake_io(),
- m_state.get(), SERVER);
+ m_state->server_finished(
+ new Finished(m_state->handshake_io(), m_state.get(), SERVER)
+ );
}
- m_secure_renegotiation.update(m_state->client_finished,
- m_state->server_finished);
+ m_secure_renegotiation.update(m_state->client_finished(),
+ m_state->server_finished());
- m_active_session = m_state->server_hello->session_id();
+ m_active_session = m_state->server_hello()->session_id();
m_state.reset();
m_handshake_completed = true;
}
diff --git a/src/tls/tls_session_key.cpp b/src/tls/tls_session_key.cpp
index 0cd74a63a..bc636c0cb 100644
--- a/src/tls/tls_session_key.cpp
+++ b/src/tls/tls_session_key.cpp
@@ -18,7 +18,7 @@ namespace TLS {
/**
* Session_Keys Constructor
*/
-Session_Keys::Session_Keys(Handshake_State* state,
+Session_Keys::Session_Keys(const Handshake_State* state,
const secure_vector<byte>& pre_master_secret,
bool resuming)
{
@@ -50,8 +50,8 @@ Session_Keys::Session_Keys(Handshake_State* state,
if(state->version() != Protocol_Version::SSL_V3)
salt += std::make_pair(MASTER_SECRET_MAGIC, sizeof(MASTER_SECRET_MAGIC));
- salt += state->client_hello->random();
- salt += state->server_hello->random();
+ salt += state->client_hello()->random();
+ salt += state->server_hello()->random();
master_sec = prf->derive_key(48, pre_master_secret, salt);
}
@@ -59,8 +59,8 @@ Session_Keys::Session_Keys(Handshake_State* state,
secure_vector<byte> salt;
if(state->version() != Protocol_Version::SSL_V3)
salt += std::make_pair(KEY_GEN_MAGIC, sizeof(KEY_GEN_MAGIC));
- salt += state->server_hello->random();
- salt += state->client_hello->random();
+ salt += state->server_hello()->random();
+ salt += state->client_hello()->random();
SymmetricKey keyblock = prf->derive_key(prf_gen, master_sec, salt);
diff --git a/src/tls/tls_session_key.h b/src/tls/tls_session_key.h
index 0021694e3..b67606a08 100644
--- a/src/tls/tls_session_key.h
+++ b/src/tls/tls_session_key.h
@@ -35,7 +35,7 @@ class Session_Keys
Session_Keys() {}
- Session_Keys(class Handshake_State* state,
+ Session_Keys(const class Handshake_State* state,
const secure_vector<byte>& pre_master,
bool resuming);