diff options
Diffstat (limited to 'src/tls')
-rw-r--r-- | src/tls/cert_ver.cpp | 80 | ||||
-rw-r--r-- | src/tls/finished.cpp | 103 | ||||
-rw-r--r-- | src/tls/rec_read.cpp | 2 | ||||
-rw-r--r-- | src/tls/rec_wri.cpp | 2 | ||||
-rw-r--r-- | src/tls/s_kex.cpp | 77 | ||||
-rw-r--r-- | src/tls/tls_channel.cpp | 3 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 2 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 46 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.cpp | 42 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.h | 41 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 39 | ||||
-rw-r--r-- | src/tls/tls_record.h | 6 | ||||
-rw-r--r-- | src/tls/tls_server.cpp | 37 | ||||
-rw-r--r-- | src/tls/tls_session_key.cpp | 37 | ||||
-rw-r--r-- | src/tls/tls_session_key.h | 13 |
15 files changed, 219 insertions, 311 deletions
diff --git a/src/tls/cert_ver.cpp b/src/tls/cert_ver.cpp index 3463a82ee..81d529e88 100644 --- a/src/tls/cert_ver.cpp +++ b/src/tls/cert_ver.cpp @@ -21,56 +21,36 @@ namespace Botan { * Create a new Certificate Verify message */ Certificate_Verify::Certificate_Verify(Record_Writer& writer, - TLS_Handshake_Hash& hash, + TLS_Handshake_State* state, RandomNumberGenerator& rng, - Version_Code version, - const SecureVector<byte>& master_secret, const Private_Key* priv_key) { BOTAN_ASSERT_NONNULL(priv_key); - std::string padding = ""; - Signature_Format format = IEEE_1363; + std::pair<std::string, Signature_Format> format = + state->choose_sig_format(priv_key, true); - if(priv_key->algo_name() == "RSA") - { - if(version == SSL_V3) - padding = "EMSA3(Raw)"; - else - padding = "EMSA3(TLS.Digest.0)"; - } - else if(priv_key->algo_name() == "DSA") - { - if(version == SSL_V3) - padding = "Raw"; - else - padding = "EMSA1(SHA-1)"; - format = DER_SEQUENCE; - } - else - throw Invalid_Argument(priv_key->algo_name() + - " is invalid/unknown for TLS signatures"); + PK_Signer signer(*priv_key, format.first, format.second); - PK_Signer signer(*priv_key, padding, format); - - if(version == SSL_V3) + if(state->version == SSL_V3) { - SecureVector<byte> md5_sha = hash.final_ssl3(master_secret); + SecureVector<byte> md5_sha = state->hash.final_ssl3( + state->keys.master_secret()); if(priv_key->algo_name() == "DSA") signature = signer.sign_message(&md5_sha[16], md5_sha.size()-16, rng); else signature = signer.sign_message(md5_sha, rng); } - else if(version == TLS_V10 || version == TLS_V11) + else if(state->version == TLS_V10 || state->version == TLS_V11) { - signature = signer.sign_message(hash.get_contents(), rng); + signature = signer.sign_message(state->hash.get_contents(), rng); } else throw TLS_Exception(PROTOCOL_VERSION, "Unknown TLS version in certificate verification"); - send(writer, hash); + send(writer, state->hash); } /* @@ -101,45 +81,27 @@ void Certificate_Verify::deserialize(const MemoryRegion<byte>& buf) * Verify a Certificate Verify message */ bool Certificate_Verify::verify(const X509_Certificate& cert, - TLS_Handshake_Hash& hash, - Version_Code version, - const SecureVector<byte>& master_secret) + TLS_Handshake_State* state) { std::auto_ptr<Public_Key> key(cert.subject_public_key()); - std::string padding = ""; - Signature_Format format = IEEE_1363; - - if(key->algo_name() == "RSA") - { - if(version == SSL_V3) - padding = "EMSA3(Raw)"; - else - padding = "EMSA3(TLS.Digest.0)"; - } - else if(key->algo_name() == "DSA") - { - if(version == SSL_V3) - padding = "Raw"; - else - padding = "EMSA1(SHA-1)"; - format = DER_SEQUENCE; - } - else - throw Invalid_Argument(key->algo_name() + - " is invalid/unknown for TLS signatures"); + std::pair<std::string, Signature_Format> format = + state->choose_sig_format(key.get(), true); - PK_Verifier verifier(*key, padding, format); + PK_Verifier verifier(*key, format.first, format.second); - if(version == SSL_V3) + if(state->version == SSL_V3) { - SecureVector<byte> md5_sha = hash.final_ssl3(master_secret); + SecureVector<byte> md5_sha = state->hash.final_ssl3( + state->keys.master_secret()); return verifier.verify_message(&md5_sha[16], md5_sha.size()-16, &signature[0], signature.size()); } - else if(version == TLS_V10 || version == TLS_V11) - return verifier.verify_message(hash.get_contents(), signature); + else if(state->version == TLS_V10 || state->version == TLS_V11) + { + return verifier.verify_message(state->hash.get_contents(), signature); + } else throw TLS_Exception(PROTOCOL_VERSION, "Unknown TLS version in certificate verification"); diff --git a/src/tls/finished.cpp b/src/tls/finished.cpp index 70b714bfd..836512f81 100644 --- a/src/tls/finished.cpp +++ b/src/tls/finished.cpp @@ -1,6 +1,6 @@ /* * Finished Message -* (C) 2004-2006 Jack Lloyd +* (C) 2004-2006,2012 Jack Lloyd * * Released under the terms of the Botan license */ @@ -10,58 +10,15 @@ namespace Botan { -/* -* Create a new Finished message -*/ -Finished::Finished(Record_Writer& writer, - TLS_Handshake_Hash& hash, - Version_Code version, - Connection_Side side, - const MemoryRegion<byte>& master_secret) - { - verification_data = compute_verify(master_secret, hash, side, version); - send(writer, hash); - } - -/* -* Serialize a Finished message -*/ -MemoryVector<byte> Finished::serialize() const - { - return verification_data; - } - -/* -* Deserialize a Finished message -*/ -void Finished::deserialize(const MemoryRegion<byte>& buf) - { - verification_data = buf; - } - -/* -* Verify a Finished message -*/ -bool Finished::verify(const MemoryRegion<byte>& secret, - Version_Code version, - const TLS_Handshake_Hash& hash, - Connection_Side side) - { - MemoryVector<byte> computed = compute_verify(secret, hash, side, version); - if(computed == verification_data) - return true; - return false; - } +namespace { /* * Compute the verify_data */ -MemoryVector<byte> Finished::compute_verify(const MemoryRegion<byte>& secret, - TLS_Handshake_Hash hash, - Connection_Side side, - Version_Code version) +MemoryVector<byte> finished_compute_verify(TLS_Handshake_State* state, + Connection_Side side) { - if(version == SSL_V3) + if(state->version == SSL_V3) { const byte SSL_CLIENT_LABEL[] = { 0x43, 0x4C, 0x4E, 0x54 }; const byte SSL_SERVER_LABEL[] = { 0x53, 0x52, 0x56, 0x52 }; @@ -69,13 +26,13 @@ MemoryVector<byte> Finished::compute_verify(const MemoryRegion<byte>& secret, MemoryVector<byte> ssl3_finished; if(side == CLIENT) - hash.update(SSL_CLIENT_LABEL, sizeof(SSL_CLIENT_LABEL)); + state->hash.update(SSL_CLIENT_LABEL, sizeof(SSL_CLIENT_LABEL)); else - hash.update(SSL_SERVER_LABEL, sizeof(SSL_SERVER_LABEL)); + state->hash.update(SSL_SERVER_LABEL, sizeof(SSL_SERVER_LABEL)); - return hash.final_ssl3(secret); + return state->hash.final_ssl3(state->keys.master_secret()); } - else if(version == TLS_V10 || version == TLS_V11) + else if(state->version == TLS_V10 || state->version == TLS_V11) { const byte TLS_CLIENT_LABEL[] = { 0x63, 0x6C, 0x69, 0x65, 0x6E, 0x74, 0x20, 0x66, 0x69, 0x6E, 0x69, @@ -92,12 +49,50 @@ MemoryVector<byte> Finished::compute_verify(const MemoryRegion<byte>& secret, input += std::make_pair(TLS_CLIENT_LABEL, sizeof(TLS_CLIENT_LABEL)); else input += std::make_pair(TLS_SERVER_LABEL, sizeof(TLS_SERVER_LABEL)); - input += hash.final(); + input += state->hash.final(); - return prf.derive_key(12, secret, input); + return prf.derive_key(12, state->keys.master_secret(), input); } else throw Invalid_Argument("Finished message: Unknown protocol version"); } } + +/* +* Create a new Finished message +*/ +Finished::Finished(Record_Writer& writer, + TLS_Handshake_State* state, + Connection_Side side) + { + verification_data = finished_compute_verify(state, side); + send(writer, state->hash); + } + +/* +* Serialize a Finished message +*/ +MemoryVector<byte> Finished::serialize() const + { + return verification_data; + } + +/* +* Deserialize a Finished message +*/ +void Finished::deserialize(const MemoryRegion<byte>& buf) + { + verification_data = buf; + } + +/* +* Verify a Finished message +*/ +bool Finished::verify(TLS_Handshake_State* state, + Connection_Side side) + { + return (verification_data == finished_compute_verify(state, side)); + } + +} diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp index f8e6bab26..20dfaae2e 100644 --- a/src/tls/rec_read.cpp +++ b/src/tls/rec_read.cpp @@ -68,7 +68,7 @@ void Record_Reader::set_version(Version_Code version) * Set the keys for reading */ void Record_Reader::activate(const TLS_Cipher_Suite& suite, - const SessionKeys& keys, + const Session_Keys& keys, Connection_Side side) { m_cipher.reset(); diff --git a/src/tls/rec_wri.cpp b/src/tls/rec_wri.cpp index fdcb98cc9..c0a79a631 100644 --- a/src/tls/rec_wri.cpp +++ b/src/tls/rec_wri.cpp @@ -71,7 +71,7 @@ void Record_Writer::set_version(Version_Code version) * Set the keys for writing */ void Record_Writer::activate(const TLS_Cipher_Suite& suite, - const SessionKeys& keys, + const Session_Keys& keys, Connection_Side side) { m_cipher.reset(); diff --git a/src/tls/s_kex.cpp b/src/tls/s_kex.cpp index 150f13474..69531c7c4 100644 --- a/src/tls/s_kex.cpp +++ b/src/tls/s_kex.cpp @@ -9,8 +9,6 @@ #include <botan/internal/tls_reader.h> #include <botan/pubkey.h> #include <botan/dh.h> -#include <botan/rsa.h> -#include <botan/dsa.h> #include <botan/loadstor.h> #include <memory> @@ -20,15 +18,11 @@ namespace Botan { * Create a new Server Key Exchange message */ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, - TLS_Handshake_Hash& hash, + TLS_Handshake_State* state, RandomNumberGenerator& rng, - const Public_Key* kex_key, - const Private_Key* priv_key, - const MemoryRegion<byte>& c_random, - const MemoryRegion<byte>& s_random) + const Private_Key* private_key) { - const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(kex_key); - const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(kex_key); + const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(state->kex_priv); if(dh_pub) { @@ -36,37 +30,21 @@ Server_Key_Exchange::Server_Key_Exchange(Record_Writer& writer, params.push_back(dh_pub->get_domain().get_g()); params.push_back(BigInt::decode(dh_pub->public_value())); } - else if(rsa_pub) - { - params.push_back(rsa_pub->get_n()); - params.push_back(rsa_pub->get_e()); - } else - throw Invalid_Argument("Bad key for TLS key exchange: not DH or RSA"); - - // FIXME: cut and paste - std::string padding = ""; - Signature_Format format = IEEE_1363; + throw Invalid_Argument("Unknown key type " + state->kex_priv->algo_name() + + " for TLS key exchange"); - if(priv_key->algo_name() == "RSA") - padding = "EMSA3(TLS.Digest.0)"; - else if(priv_key->algo_name() == "DSA") - { - padding = "EMSA1(SHA-1)"; - format = DER_SEQUENCE; - } - else - throw Invalid_Argument(priv_key->algo_name() + - " is invalid/unknown for TLS signatures"); + std::pair<std::string, Signature_Format> format = + state->choose_sig_format(private_key, false); - PK_Signer signer(*priv_key, padding, format); + PK_Signer signer(*private_key, format.first, format.second); - signer.update(c_random); - signer.update(s_random); + signer.update(state->client_hello->random()); + signer.update(state->server_hello->random()); signer.update(serialize_params()); signature = signer.signature(rng); - send(writer, hash); + send(writer, state->hash); } /** @@ -135,9 +113,7 @@ void Server_Key_Exchange::deserialize(const MemoryRegion<byte>& buf) */ Public_Key* Server_Key_Exchange::key() const { - if(params.size() == 2) - return new RSA_PublicKey(params[0], params[1]); - else if(params.size() == 3) + if(params.size() == 3) return new DH_PublicKey(DL_Group(params[0], params[1]), params[2]); else throw Internal_Error("Server_Key_Exchange::key: No key set"); @@ -147,33 +123,18 @@ Public_Key* Server_Key_Exchange::key() const * Verify a Server Key Exchange message */ bool Server_Key_Exchange::verify(const X509_Certificate& cert, - const MemoryRegion<byte>& c_random, - const MemoryRegion<byte>& s_random) const + TLS_Handshake_State* state) const { - std::auto_ptr<Public_Key> key(cert.subject_public_key()); - // FIXME: cut and paste - std::string padding = ""; - Signature_Format format = IEEE_1363; - - if(key->algo_name() == "RSA") - padding = "EMSA3(TLS.Digest.0)"; - else if(key->algo_name() == "DSA") - { - padding = "EMSA1(SHA-1)"; - format = DER_SEQUENCE; - } - else - throw Invalid_Argument(key->algo_name() + - " is invalid/unknown for TLS signatures"); + std::pair<std::string, Signature_Format> format = + state->choose_sig_format(key.get(), false); - PK_Verifier verifier(*key, padding, format); + PK_Verifier verifier(*key, format.first, format.second); - MemoryVector<byte> params_got = serialize_params(); - verifier.update(c_random); - verifier.update(s_random); - verifier.update(params_got); + verifier.update(state->client_hello->random()); + verifier.update(state->server_hello->random()); + verifier.update(serialize_params()); return verifier.check_signature(signature); } diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index e688f354d..a1e9fd8cd 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -8,6 +8,7 @@ #include <botan/tls_channel.h> #include <botan/internal/tls_alerts.h> #include <botan/internal/tls_handshake_state.h> +#include <botan/internal/tls_messages.h> #include <botan/internal/assert.h> #include <botan/loadstor.h> @@ -135,7 +136,7 @@ void TLS_Channel::read_handshake(byte rec_type, if(rec_type == HANDSHAKE) { if(!state) - state = new Handshake_State; + state = new TLS_Handshake_State; state->queue.write(&rec_buf[0], rec_buf.size()); } diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index c86b48f09..2b4e6d161 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -90,7 +90,7 @@ class BOTAN_DLL TLS_Channel std::vector<X509_Certificate> peer_certs; - class Handshake_State* state; + class TLS_Handshake_State* state; class Secure_Renegotiation_State { diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index ca4a56007..ef96c04fb 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -6,8 +6,8 @@ */ #include <botan/tls_client.h> -#include <botan/internal/tls_session_key.h> #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> @@ -35,7 +35,7 @@ TLS_Client::TLS_Client(std::tr1::function<void (const byte[], size_t)> output_fn { writer.set_version(SSL_V3); - state = new Handshake_State; + state = new TLS_Handshake_State; state->set_expected_next(SERVER_HELLO); state->client_npn_cb = next_protocol; @@ -87,7 +87,7 @@ void TLS_Client::renegotiate() if(state) return; // currently in handshake - state = new Handshake_State; + state = new TLS_Handshake_State; state->set_expected_next(SERVER_HELLO); state->client_hello = new Client_Hello(writer, state->hash, policy, rng, @@ -188,18 +188,16 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, // successful resumption /* - * In this case, we offered the original session and the server - * must resume with it + * In this case, we offered the version used in the original + * session, and the server must resume with the same version. */ if(state->server_hello->version() != state->client_hello->version()) throw TLS_Exception(HANDSHAKE_FAILURE, "Server resumed session but with wrong version"); - state->keys = SessionKeys(state->suite, state->version, - state->resume_master_secret, - state->client_hello->random(), - state->server_hello->random(), - true); + state->keys = Session_Keys(state, + state->resume_master_secret, + true); state->set_expected_next(HANDSHAKE_CCS); } @@ -295,11 +293,11 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, if(state->suite.sig_type() != TLS_ALGO_SIGNER_ANON) { - if(!state->server_kex->verify(peer_certs[0], - state->client_hello->random(), - state->server_hello->random())) + if(!state->server_kex->verify(peer_certs[0], state)) + { throw TLS_Exception(DECRYPT_ERROR, "Bad signature on server key exchange"); + } } } else if(type == CERTIFICATE_REQUEST) @@ -333,10 +331,9 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->kex_pub, state->version, state->client_hello->version()); - state->keys = SessionKeys(state->suite, state->version, - state->client_kex->pre_master_secret(), - state->client_hello->random(), - state->server_hello->random()); + state->keys = Session_Keys(state, + state->client_kex->pre_master_secret(), + false); if(state->received_handshake_msg(CERTIFICATE_REQUEST) && !state->client_certs->empty()) @@ -347,10 +344,8 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->client_hello->sni_hostname()); state->client_verify = new Certificate_Verify(writer, - state->hash, + state, rng, - state->version, - state->keys.master_secret(), private_key); } @@ -366,9 +361,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->next_protocol = new Next_Protocol(writer, state->hash, protocol); } - state->client_finished = new Finished(writer, state->hash, - state->version, CLIENT, - state->keys.master_secret()); + state->client_finished = new Finished(writer, state, CLIENT); } else if(type == HANDSHAKE_CCS) { @@ -382,8 +375,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, state->server_finished = new Finished(contents); - if(!state->server_finished->verify(state->keys.master_secret(), - state->version, state->hash, SERVER)) + if(!state->server_finished->verify(state, SERVER)) throw TLS_Exception(DECRYPT_ERROR, "Finished message didn't verify"); @@ -395,9 +387,7 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, writer.activate(state->suite, state->keys, CLIENT); - state->client_finished = new Finished(writer, state->hash, - state->version, CLIENT, - state->keys.master_secret()); + state->client_finished = new Finished(writer, state, CLIENT); } TLS_Session session_info( diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index d6f215067..f2f6a2baf 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -6,6 +6,7 @@ */ #include <botan/internal/tls_handshake_state.h> +#include <botan/internal/tls_messages.h> namespace Botan { @@ -71,7 +72,7 @@ u32bit bitmask_for_handshake_type(Handshake_Type type) /* * Initialize the SSL/TLS Handshake State */ -Handshake_State::Handshake_State() +TLS_Handshake_State::TLS_Handshake_State() { client_hello = 0; server_hello = 0; @@ -96,7 +97,7 @@ Handshake_State::Handshake_State() hand_received_mask = 0; } -void Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) +void TLS_Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) { const u32bit mask = bitmask_for_handshake_type(handshake_msg); @@ -116,22 +117,53 @@ void Handshake_State::confirm_transition_to(Handshake_Type handshake_msg) hand_expecting_mask = 0; } -void Handshake_State::set_expected_next(Handshake_Type handshake_msg) +void TLS_Handshake_State::set_expected_next(Handshake_Type handshake_msg) { hand_expecting_mask |= bitmask_for_handshake_type(handshake_msg); } -bool Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) const +bool TLS_Handshake_State::received_handshake_msg(Handshake_Type handshake_msg) const { const u32bit mask = bitmask_for_handshake_type(handshake_msg); return (hand_received_mask & mask); } +std::pair<std::string, Signature_Format> +TLS_Handshake_State::choose_sig_format(const Public_Key* key, bool for_client_auth) + { + const std::string algo_name = key->algo_name(); + + if(algo_name == "RSA") + { + std::string padding = ""; + + if(for_client_auth && this->version == SSL_V3) + padding = "EMSA3(Raw)"; + else + padding = "EMSA3(TLS.Digest.0)"; + + return std::make_pair(padding, IEEE_1363); + } + else if(algo_name == "DSA") + { + std::string padding = ""; + + if(for_client_auth && this->version == SSL_V3) + padding = "Raw"; + else + padding = "EMSA1(SHA-1)"; + + return std::make_pair(padding, DER_SEQUENCE); + } + + throw Invalid_Argument(algo_name + " is invalid/unknown for TLS signatures"); + } + /* * Destroy the SSL/TLS Handshake State */ -Handshake_State::~Handshake_State() +TLS_Handshake_State::~TLS_Handshake_State() { delete client_hello; delete server_hello; diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index 7ca2dae94..e58a83f3e 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -8,9 +8,13 @@ #ifndef BOTAN_TLS_HANDSHAKE_STATE_H__ #define BOTAN_TLS_HANDSHAKE_STATE_H__ -#include <botan/internal/tls_messages.h> +#include <botan/internal/tls_handshake_hash.h> #include <botan/internal/tls_session_key.h> #include <botan/secqueue.h> +#include <botan/pk_keys.h> +#include <botan/pubkey.h> + +#include <utility> #if defined(BOTAN_USE_STD_TR1) @@ -31,40 +35,43 @@ namespace Botan { /** * SSL/TLS Handshake State */ -class Handshake_State +class TLS_Handshake_State { public: - Handshake_State(); - ~Handshake_State(); + TLS_Handshake_State(); + ~TLS_Handshake_State(); bool received_handshake_msg(Handshake_Type handshake_msg) const; void confirm_transition_to(Handshake_Type handshake_msg); void set_expected_next(Handshake_Type handshake_msg); + std::pair<std::string, Signature_Format> + choose_sig_format(const Public_Key* key, bool for_client_auth); + Version_Code version; - Client_Hello* client_hello; - Server_Hello* server_hello; - Certificate* server_certs; - Server_Key_Exchange* server_kex; - Certificate_Req* cert_req; - Server_Hello_Done* server_hello_done; + class Client_Hello* client_hello; + class Server_Hello* server_hello; + class Certificate* server_certs; + class Server_Key_Exchange* server_kex; + class Certificate_Req* cert_req; + class Server_Hello_Done* server_hello_done; - Certificate* client_certs; - Client_Key_Exchange* client_kex; - Certificate_Verify* client_verify; + class Certificate* client_certs; + class Client_Key_Exchange* client_kex; + class Certificate_Verify* client_verify; - Next_Protocol* next_protocol; + class Next_Protocol* next_protocol; - Finished* client_finished; - Finished* server_finished; + class Finished* client_finished; + class Finished* server_finished; Public_Key* kex_pub; Private_Key* kex_priv; TLS_Cipher_Suite suite; - SessionKeys keys; + Session_Keys keys; TLS_Handshake_Hash hash; SecureQueue queue; diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index ee05031c0..0b43545dc 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -8,7 +8,7 @@ #ifndef BOTAN_TLS_MESSAGES_H__ #define BOTAN_TLS_MESSAGES_H__ -#include <botan/internal/tls_handshake_hash.h> +#include <botan/internal/tls_handshake_state.h> #include <botan/tls_session.h> #include <botan/tls_policy.h> #include <botan/tls_magic.h> @@ -290,20 +290,14 @@ class Certificate_Verify : public Handshake_Message /** * Check the signature on a certificate verify message * @param cert the purported certificate - * @param hash the running handshake message hash - * @param version the version number we negotiated - * @param master_secret the session key (only used if version is SSL_V3) + * @param state the handshake state */ bool verify(const X509_Certificate& cert, - TLS_Handshake_Hash& hash, - Version_Code version, - const SecureVector<byte>& master_secret); + TLS_Handshake_State* state); Certificate_Verify(Record_Writer& writer, - TLS_Handshake_Hash& hash, + TLS_Handshake_State* state, RandomNumberGenerator& rng, - Version_Code version, - const SecureVector<byte>& master_secret, const Private_Key* key); Certificate_Verify(const MemoryRegion<byte>& buf) { deserialize(buf); } @@ -325,27 +319,18 @@ class Finished : public Handshake_Message MemoryVector<byte> verify_data() const { return verification_data; } - bool verify(const MemoryRegion<byte>& buf, - Version_Code version, - const TLS_Handshake_Hash& hash, + bool verify(TLS_Handshake_State* state, Connection_Side side); Finished(Record_Writer& writer, - TLS_Handshake_Hash& hash, - Version_Code version, - Connection_Side side, - const MemoryRegion<byte>& master_secret); + TLS_Handshake_State* state, + Connection_Side side); Finished(const MemoryRegion<byte>& buf) { deserialize(buf); } private: MemoryVector<byte> serialize() const; void deserialize(const MemoryRegion<byte>&); - MemoryVector<byte> compute_verify(const MemoryRegion<byte>& master_secret, - TLS_Handshake_Hash hash, - Connection_Side side, - Version_Code version); - Connection_Side side; MemoryVector<byte> verification_data; }; @@ -375,16 +360,12 @@ class Server_Key_Exchange : public Handshake_Message Public_Key* key() const; bool verify(const X509_Certificate& cert, - const MemoryRegion<byte>& c_random, - const MemoryRegion<byte>& s_random) const; + TLS_Handshake_State* state) const; Server_Key_Exchange(Record_Writer& writer, - TLS_Handshake_Hash& hash, + TLS_Handshake_State* state, RandomNumberGenerator& rng, - const Public_Key* kex_key, - const Private_Key* priv_key, - const MemoryRegion<byte>& c_random, - const MemoryRegion<byte>& s_random); + const Private_Key* priv_key); Server_Key_Exchange(const MemoryRegion<byte>& buf) { deserialize(buf); } private: diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h index c7d2d0018..a9bcb8f26 100644 --- a/src/tls/tls_record.h +++ b/src/tls/tls_record.h @@ -30,7 +30,7 @@ namespace Botan { -class SessionKeys; +class Session_Keys; /** * TLS Record Writer @@ -44,7 +44,7 @@ class BOTAN_DLL Record_Writer void alert(Alert_Level level, Alert_Type type); void activate(const TLS_Cipher_Suite& suite, - const SessionKeys& keys, + const Session_Keys& keys, Connection_Side side); void set_version(Version_Code version); @@ -98,7 +98,7 @@ class BOTAN_DLL Record_Reader MemoryVector<byte>& msg); void activate(const TLS_Cipher_Suite& suite, - const SessionKeys& keys, + const Session_Keys& keys, Connection_Side side); void set_version(Version_Code version); diff --git a/src/tls/tls_server.cpp b/src/tls/tls_server.cpp index ccba16629..e3e2fe208 100644 --- a/src/tls/tls_server.cpp +++ b/src/tls/tls_server.cpp @@ -6,8 +6,8 @@ */ #include <botan/tls_server.h> -#include <botan/internal/tls_session_key.h> #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/dh.h> @@ -104,7 +104,7 @@ void TLS_Server::renegotiate() if(state) return; // currently in handshake - state = new Handshake_State; + state = new TLS_Handshake_State; state->set_expected_next(CLIENT_HELLO); Hello_Request hello_req(writer); } @@ -129,7 +129,7 @@ void TLS_Server::read_handshake(byte rec_type, { if(rec_type == HANDSHAKE && !state) { - state = new Handshake_State; + state = new TLS_Handshake_State; state->set_expected_next(CLIENT_HELLO); } @@ -207,19 +207,13 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->suite = TLS_Cipher_Suite(state->server_hello->ciphersuite()); - state->keys = SessionKeys(state->suite, state->version, - session_info.master_secret(), - state->client_hello->random(), - state->server_hello->random(), - true); + state->keys = Session_Keys(state, session_info.master_secret(), true); writer.send(CHANGE_CIPHER_SPEC, 1); writer.activate(state->suite, state->keys, SERVER); - state->server_finished = new Finished(writer, state->hash, - state->version, SERVER, - state->keys.master_secret()); + state->server_finished = new Finished(writer, state, SERVER); if(!handshake_fn(session_info)) session_manager.remove_entry(session_info.session_id()); @@ -275,10 +269,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, throw Internal_Error("TLS_Server: Unknown ciphersuite kex type"); state->server_kex = - new Server_Key_Exchange(writer, state->hash, rng, - state->kex_priv, private_key, - state->client_hello->random(), - state->server_hello->random()); + new Server_Key_Exchange(writer, state, rng, private_key); } else state->kex_priv = PKCS8::copy_key(*private_key, rng); @@ -330,9 +321,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->client_kex->pre_master_secret(rng, state->kex_priv, state->client_hello->version()); - state->keys = SessionKeys(state->suite, state->version, pre_master, - state->client_hello->random(), - state->server_hello->random()); + state->keys = Session_Keys(state, pre_master, false); } else if(type == CERTIFICATE_VERIFY) { @@ -342,10 +331,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->client_certs->cert_chain(); const bool sig_valid = - state->client_verify->verify(client_certs[0], - state->hash, - state->server_hello->version(), - state->keys.master_secret()); + state->client_verify->verify(client_certs[0], state); state->hash.update(type, contents); @@ -384,8 +370,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, state->client_finished = new Finished(contents); - if(!state->client_finished->verify(state->keys.master_secret(), - state->version, state->hash, CLIENT)) + if(!state->client_finished->verify(state, CLIENT)) throw TLS_Exception(DECRYPT_ERROR, "Finished message didn't verify"); @@ -398,9 +383,7 @@ void TLS_Server::process_handshake_msg(Handshake_Type type, writer.activate(state->suite, state->keys, SERVER); - state->server_finished = new Finished(writer, state->hash, - state->version, SERVER, - state->keys.master_secret()); + state->server_finished = new Finished(writer, state, SERVER); if(state->client_certs && state->client_verify) peer_certs = state->client_certs->cert_chain(); diff --git a/src/tls/tls_session_key.cpp b/src/tls/tls_session_key.cpp index f0ddc4493..66a02542b 100644 --- a/src/tls/tls_session_key.cpp +++ b/src/tls/tls_session_key.cpp @@ -6,6 +6,8 @@ */ #include <botan/internal/tls_session_key.h> +#include <botan/internal/tls_handshake_state.h> +#include <botan/internal/tls_messages.h> #include <botan/lookup.h> #include <memory> @@ -20,29 +22,26 @@ std::string lookup_prf_name(Version_Code version) else if(version == TLS_V10 || version == TLS_V11) return "TLS-PRF"; else - throw Invalid_Argument("SessionKeys: Unknown version code"); + throw Invalid_Argument("Session_Keys: Unknown version code"); } } /** -* SessionKeys Constructor +* Session_Keys Constructor */ -SessionKeys::SessionKeys(const TLS_Cipher_Suite& suite, - Version_Code version, - const MemoryRegion<byte>& pre_master_secret, - const MemoryRegion<byte>& client_random, - const MemoryRegion<byte>& server_random, - bool resuming) +Session_Keys::Session_Keys(TLS_Handshake_State* state, + const MemoryRegion<byte>& pre_master_secret, + bool resuming) { - const std::string prf_name = lookup_prf_name(version); + const std::string prf_name = lookup_prf_name(state->version); - const size_t mac_keylen = output_length_of(suite.mac_algo()); - const size_t cipher_keylen = suite.cipher_keylen(); + const size_t mac_keylen = output_length_of(state->suite.mac_algo()); + const size_t cipher_keylen = state->suite.cipher_keylen(); size_t cipher_ivlen = 0; - if(have_block_cipher(suite.cipher_algo())) - cipher_ivlen = block_size_of(suite.cipher_algo()); + if(have_block_cipher(state->suite.cipher_algo())) + cipher_ivlen = block_size_of(state->suite.cipher_algo()); const size_t prf_gen = 2 * (mac_keylen + cipher_keylen + cipher_ivlen); @@ -62,20 +61,20 @@ SessionKeys::SessionKeys(const TLS_Cipher_Suite& suite, { SecureVector<byte> salt; - if(version != SSL_V3) + if(state->version != SSL_V3) salt += std::make_pair(MASTER_SECRET_MAGIC, sizeof(MASTER_SECRET_MAGIC)); - salt += client_random; - salt += server_random; + salt += state->client_hello->random(); + salt += state->server_hello->random(); master_sec = prf->derive_key(48, pre_master_secret, salt); } SecureVector<byte> salt; - if(version != SSL_V3) + if(state->version != SSL_V3) salt += std::make_pair(KEY_GEN_MAGIC, sizeof(KEY_GEN_MAGIC)); - salt += server_random; - salt += client_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 a698dfcfc..8ba3d2b72 100644 --- a/src/tls/tls_session_key.h +++ b/src/tls/tls_session_key.h @@ -17,7 +17,7 @@ namespace Botan { /** * TLS Session Keys */ -class SessionKeys +class Session_Keys { public: SymmetricKey client_cipher_key() const { return c_cipher; } @@ -31,14 +31,11 @@ class SessionKeys const SecureVector<byte>& master_secret() const { return master_sec; } - SessionKeys() {} + Session_Keys() {} - SessionKeys(const TLS_Cipher_Suite& suite, - Version_Code version, - const MemoryRegion<byte>& pre_master, - const MemoryRegion<byte>& client_random, - const MemoryRegion<byte>& server_random, - bool resuming = false); + Session_Keys(class TLS_Handshake_State* state, + const MemoryRegion<byte>& pre_master, + bool resuming); private: SecureVector<byte> master_sec; |