aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorlloyd <[email protected]>2012-09-07 19:40:54 +0000
committerlloyd <[email protected]>2012-09-07 19:40:54 +0000
commit4f1d7f4a08201b6495dae63af5f96d36687bff6e (patch)
treea382819aca1284106768678c1297d1ebf4508f3d
parent3a05ab962a7bb4fe4ecb19ac2972f76ac6756b09 (diff)
Save the peer public key in the handshake state instead of pulling it
out of the cert repeatedly.
-rw-r--r--src/tls/msg_cert_verify.cpp4
-rw-r--r--src/tls/msg_server_kex.cpp10
-rw-r--r--src/tls/tls_client.cpp17
-rw-r--r--src/tls/tls_handshake_state.cpp8
-rw-r--r--src/tls/tls_handshake_state.h4
-rw-r--r--src/tls/tls_messages.h2
6 files changed, 29 insertions, 16 deletions
diff --git a/src/tls/msg_cert_verify.cpp b/src/tls/msg_cert_verify.cpp
index 18d851e53..8cdadfe7d 100644
--- a/src/tls/msg_cert_verify.cpp
+++ b/src/tls/msg_cert_verify.cpp
@@ -28,7 +28,7 @@ Certificate_Verify::Certificate_Verify(Handshake_IO& io,
BOTAN_ASSERT_NONNULL(priv_key);
std::pair<std::string, Signature_Format> format =
- state.choose_sig_format(priv_key, m_hash_algo, m_sig_algo, true, policy);
+ state.choose_sig_format(*priv_key, m_hash_algo, m_sig_algo, true, policy);
PK_Signer signer(*priv_key, format.first, format.second);
@@ -97,7 +97,7 @@ bool Certificate_Verify::verify(const X509_Certificate& cert,
std::unique_ptr<Public_Key> key(cert.subject_public_key());
std::pair<std::string, Signature_Format> format =
- state.understand_sig_format(key.get(), m_hash_algo, m_sig_algo, true);
+ state.understand_sig_format(*key.get(), m_hash_algo, m_sig_algo, true);
PK_Verifier verifier(*key, format.first, format.second);
diff --git a/src/tls/msg_server_kex.cpp b/src/tls/msg_server_kex.cpp
index 250a8c126..de50080ec 100644
--- a/src/tls/msg_server_kex.cpp
+++ b/src/tls/msg_server_kex.cpp
@@ -125,7 +125,7 @@ Server_Key_Exchange::Server_Key_Exchange(Handshake_IO& io,
BOTAN_ASSERT(signing_key, "Signing key was set");
std::pair<std::string, Signature_Format> format =
- state.choose_sig_format(signing_key, m_hash_algo, m_sig_algo, false, policy);
+ state.choose_sig_format(*signing_key, m_hash_algo, m_sig_algo, false, policy);
PK_Signer signer(*signing_key, format.first, format.second);
@@ -254,15 +254,13 @@ std::vector<byte> Server_Key_Exchange::serialize() const
/**
* Verify a Server Key Exchange message
*/
-bool Server_Key_Exchange::verify(const X509_Certificate& cert,
+bool Server_Key_Exchange::verify(const Public_Key& server_key,
const Handshake_State& state) const
{
- std::unique_ptr<Public_Key> key(cert.subject_public_key());
-
std::pair<std::string, Signature_Format> format =
- state.understand_sig_format(key.get(), m_hash_algo, m_sig_algo, false);
+ state.understand_sig_format(server_key, m_hash_algo, m_sig_algo, false);
- PK_Verifier verifier(*key, format.first, format.second);
+ PK_Verifier verifier(server_key, format.first, format.second);
verifier.update(state.client_hello()->random());
verifier.update(state.server_hello()->random());
diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp
index eac8e263b..ec1c40549 100644
--- a/src/tls/tls_client.cpp
+++ b/src/tls/tls_client.cpp
@@ -9,6 +9,7 @@
#include <botan/internal/tls_handshake_state.h>
#include <botan/internal/tls_messages.h>
#include <botan/internal/stl_util.h>
+#include <botan/internal/assert.h>
#include <memory>
namespace Botan {
@@ -27,9 +28,17 @@ class Client_Handshake_State : public Handshake_State
std::function<void (const Handshake_Message&)>()) :
Handshake_State(io, msg_callback) {}
+ const Public_Key& get_server_public_Key() const
+ {
+ BOTAN_ASSERT(server_public_key, "Server sent us a certificate");
+ return *server_public_key.get();
+ }
+
// Used during session resumption
secure_vector<byte> resume_master_secret;
+ std::unique_ptr<Public_Key> server_public_key;
+
// Used by client using NPN
std::function<std::string (std::vector<std::string>)> client_npn_cb;
};
@@ -328,6 +337,9 @@ void Client::process_handshake_msg(const Handshake_State* /*active_state*/,
if(peer_key->algo_name() != state.ciphersuite().sig_algo())
throw TLS_Exception(Alert::ILLEGAL_PARAMETER,
"Certificate key type did not match ciphersuite");
+
+ dynamic_cast<Client_Handshake_State&>(state).
+ server_public_key.reset(peer_key.release());
}
else if(type == SERVER_KEX)
{
@@ -343,7 +355,10 @@ void Client::process_handshake_msg(const Handshake_State* /*active_state*/,
if(state.ciphersuite().sig_algo() != "")
{
- if(!state.server_kex()->verify(m_peer_certs[0], state))
+ const Public_Key& server_key =
+ dynamic_cast<Client_Handshake_State&>(state).get_server_public_Key();
+
+ if(!state.server_kex()->verify(server_key, state))
{
throw TLS_Exception(Alert::DECRYPT_ERROR,
"Bad signature on server key exchange");
diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp
index 24e00772d..ff03ca6dd 100644
--- a/src/tls/tls_handshake_state.cpp
+++ b/src/tls/tls_handshake_state.cpp
@@ -326,13 +326,13 @@ std::string choose_hash(const std::string& sig_algo,
}
std::pair<std::string, Signature_Format>
-Handshake_State::choose_sig_format(const Private_Key* key,
+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
{
- const std::string sig_algo = key->algo_name();
+ const std::string sig_algo = key.algo_name();
const std::string hash_algo =
choose_hash(sig_algo,
@@ -365,12 +365,12 @@ Handshake_State::choose_sig_format(const Private_Key* key,
}
std::pair<std::string, Signature_Format>
-Handshake_State::understand_sig_format(const Public_Key* key,
+Handshake_State::understand_sig_format(const Public_Key& key,
std::string hash_algo,
std::string sig_algo,
bool for_client_auth) const
{
- const std::string algo_name = key->algo_name();
+ const std::string algo_name = key.algo_name();
/*
FIXME: This should check what was sent against the client hello
diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h
index 486e6bfb8..0ada6cfd7 100644
--- a/src/tls/tls_handshake_state.h
+++ b/src/tls/tls_handshake_state.h
@@ -80,13 +80,13 @@ class Handshake_State
const std::vector<byte>& session_ticket() const;
std::pair<std::string, Signature_Format>
- understand_sig_format(const Public_Key* key,
+ understand_sig_format(const Public_Key& key,
std::string hash_algo,
std::string sig_algo,
bool for_client_auth) const;
std::pair<std::string, Signature_Format>
- choose_sig_format(const Private_Key* key,
+ choose_sig_format(const Private_Key& key,
std::string& hash_algo,
std::string& sig_algo,
bool for_client_auth,
diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h
index 6fd7f675c..5a9363669 100644
--- a/src/tls/tls_messages.h
+++ b/src/tls/tls_messages.h
@@ -397,7 +397,7 @@ class Server_Key_Exchange : public Handshake_Message
const std::vector<byte>& params() const { return m_params; }
- bool verify(const X509_Certificate& cert,
+ bool verify(const Public_Key& server_key,
const Handshake_State& state) const;
// Only valid for certain kex types