aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJack Lloyd <[email protected]>2017-12-07 21:22:21 -0500
committerJack Lloyd <[email protected]>2017-12-07 21:22:21 -0500
commit73ffce8d75cc9388f085a80d8e8796fcbbf40c59 (patch)
tree76d8ef20ae653956a33f0700f9d7a4b3d2b2459d
parente581ec624ba31f1134fb746731c3957d669050da (diff)
parent968d2a5fcdd9c6e2943eabbd67eb6372c1b62d77 (diff)
Merge GH #1342 Fix accessing peer cert chain in resumption sessions
-rw-r--r--src/lib/tls/tls_channel.cpp5
-rw-r--r--src/lib/tls/tls_channel.h2
-rw-r--r--src/lib/tls/tls_client.cpp17
-rw-r--r--src/lib/tls/tls_server.cpp14
4 files changed, 33 insertions, 5 deletions
diff --git a/src/lib/tls/tls_channel.cpp b/src/lib/tls/tls_channel.cpp
index 892e1a399..f56cff24b 100644
--- a/src/lib/tls/tls_channel.cpp
+++ b/src/lib/tls/tls_channel.cpp
@@ -117,6 +117,11 @@ std::vector<X509_Certificate> Channel::peer_cert_chain() const
return std::vector<X509_Certificate>();
}
+bool Channel::save_session(const Session& session)
+ {
+ return callbacks().tls_session_established(session);
+ }
+
Handshake_State& Channel::create_handshake_state(Protocol_Version version)
{
if(pending_state())
diff --git a/src/lib/tls/tls_channel.h b/src/lib/tls/tls_channel.h
index 070a190dd..0362faaa8 100644
--- a/src/lib/tls/tls_channel.h
+++ b/src/lib/tls/tls_channel.h
@@ -237,7 +237,7 @@ class BOTAN_PUBLIC_API(2,0) Channel
const Policy& policy() const { return m_policy; }
- bool save_session(const Session& session) const { return callbacks().tls_session_established(session); }
+ bool save_session(const Session& session);
Callbacks& callbacks() const { return m_callbacks; }
private:
diff --git a/src/lib/tls/tls_client.cpp b/src/lib/tls/tls_client.cpp
index ad8fdfa2d..631779e99 100644
--- a/src/lib/tls/tls_client.cpp
+++ b/src/lib/tls/tls_client.cpp
@@ -33,10 +33,13 @@ class Client_Handshake_State final : public Handshake_State
return *server_public_key.get();
}
- // Used during session resumption
- secure_vector<uint8_t> resume_master_secret;
+ bool is_a_resumption() const { return (resume_master_secret.empty() == false); }
std::unique_ptr<Public_Key> server_public_key;
+
+ // Used during session resumption
+ secure_vector<uint8_t> resume_master_secret;
+ std::vector<X509_Certificate> resume_peer_certs;
};
}
@@ -119,6 +122,10 @@ Handshake_State* Client::new_handshake_state(Handshake_IO* io)
std::vector<X509_Certificate>
Client::get_peer_cert_chain(const Handshake_State& state) const
{
+ const Client_Handshake_State& cstate = dynamic_cast<const Client_Handshake_State&>(state);
+ if(cstate.resume_peer_certs.size() > 0)
+ return cstate.resume_peer_certs;
+
if(state.server_certs())
return state.server_certs()->cert_chain();
return std::vector<X509_Certificate>();
@@ -168,6 +175,7 @@ void Client::send_client_hello(Handshake_State& state_base,
next_protocols));
state.resume_master_secret = session_info.master_secret();
+ state.resume_peer_certs = session_info.peer_certs();
}
}
}
@@ -321,6 +329,9 @@ void Client::process_handshake_msg(const Handshake_State* active_state,
{
// new session
+ state.resume_master_secret.clear();
+ state.resume_peer_certs.clear();
+
if(state.client_hello()->version().is_datagram_protocol() !=
state.server_hello()->version().is_datagram_protocol())
{
@@ -611,7 +622,7 @@ void Client::process_handshake_msg(const Handshake_State* active_state,
const bool should_save = save_session(session_info);
- if(!session_id.empty())
+ if(session_id.size() > 0 && state.is_a_resumption() == false)
{
if(should_save)
session_manager().save(session_info);
diff --git a/src/lib/tls/tls_server.cpp b/src/lib/tls/tls_server.cpp
index 5bc5410f5..cd52c92f2 100644
--- a/src/lib/tls/tls_server.cpp
+++ b/src/lib/tls/tls_server.cpp
@@ -31,6 +31,11 @@ class Server_Handshake_State final : public Handshake_State
void set_allow_session_resumption(bool allow_session_resumption)
{ m_allow_session_resumption = allow_session_resumption; }
+ const std::vector<X509_Certificate>& resume_peer_certs() const
+ { return m_resume_peer_certs; }
+
+ void set_resume_certs(const std::vector<X509_Certificate>& certs)
+ { m_resume_peer_certs = certs; }
private:
// Used by the server only, in case of RSA key exchange. Not owned
@@ -41,6 +46,8 @@ class Server_Handshake_State final : public Handshake_State
* a server-initiated renegotiation
*/
bool m_allow_session_resumption = true;
+
+ std::vector<X509_Certificate> m_resume_peer_certs;
};
namespace {
@@ -359,8 +366,12 @@ Handshake_State* Server::new_handshake_state(Handshake_IO* io)
}
std::vector<X509_Certificate>
-Server::get_peer_cert_chain(const Handshake_State& state) const
+Server::get_peer_cert_chain(const Handshake_State& state_base) const
{
+ const Server_Handshake_State& state = dynamic_cast<const Server_Handshake_State&>(state_base);
+ if(state.resume_peer_certs().size() > 0)
+ return state.resume_peer_certs();
+
if(state.client_certs())
return state.client_certs()->cert_chain();
return std::vector<X509_Certificate>();
@@ -725,6 +736,7 @@ void Server::session_resume(Server_Handshake_State& pending_state,
secure_renegotiation_check(pending_state.server_hello());
pending_state.compute_session_keys(session_info.master_secret());
+ pending_state.set_resume_certs(session_info.peer_certs());
if(!save_session(session_info))
{