diff options
author | Jack Lloyd <[email protected]> | 2017-12-07 21:22:21 -0500 |
---|---|---|
committer | Jack Lloyd <[email protected]> | 2017-12-07 21:22:21 -0500 |
commit | 73ffce8d75cc9388f085a80d8e8796fcbbf40c59 (patch) | |
tree | 76d8ef20ae653956a33f0700f9d7a4b3d2b2459d | |
parent | e581ec624ba31f1134fb746731c3957d669050da (diff) | |
parent | 968d2a5fcdd9c6e2943eabbd67eb6372c1b62d77 (diff) |
Merge GH #1342 Fix accessing peer cert chain in resumption sessions
-rw-r--r-- | src/lib/tls/tls_channel.cpp | 5 | ||||
-rw-r--r-- | src/lib/tls/tls_channel.h | 2 | ||||
-rw-r--r-- | src/lib/tls/tls_client.cpp | 17 | ||||
-rw-r--r-- | src/lib/tls/tls_server.cpp | 14 |
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)) { |