diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/c_kex.cpp | 68 | ||||
-rw-r--r-- | src/tls/tls_client.cpp | 30 | ||||
-rw-r--r-- | src/tls/tls_extensions.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_handshake_state.h | 1 | ||||
-rw-r--r-- | src/tls/tls_messages.h | 8 |
6 files changed, 59 insertions, 52 deletions
diff --git a/src/tls/c_kex.cpp b/src/tls/c_kex.cpp index 8abea8fcd..b2dd0b861 100644 --- a/src/tls/c_kex.cpp +++ b/src/tls/c_kex.cpp @@ -40,42 +40,66 @@ SecureVector<byte> strip_leading_zeros(const MemoryRegion<byte>& input) * Create a new Client Key Exchange message */ Client_Key_Exchange::Client_Key_Exchange(Record_Writer& writer, - TLS_Handshake_Hash& hash, - RandomNumberGenerator& rng, - const Public_Key* pub_key, - Version_Code using_version, - Version_Code pref_version) + TLS_Handshake_State* state, + const std::vector<X509_Certificate>& peer_certs, + RandomNumberGenerator& rng) { include_length = true; - if(const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(pub_key)) + if(state->server_kex) { - DH_PrivateKey priv_key(rng, dh_pub->get_domain()); + std::auto_ptr<Public_Key> pub_key(state->server_kex->key()); - PK_Key_Agreement ka(priv_key, "Raw"); + if(pub_key->algo_name() != state->suite.kex_algo()) + throw TLS_Exception(HANDSHAKE_FAILURE, + "Server sent a " + pub_key->algo_name() + + " key but we expected " + state->suite.kex_algo()); - pre_master = strip_leading_zeros( - ka.derive_key(0, dh_pub->public_value()).bits_of()); + if(const DH_PublicKey* dh_pub = dynamic_cast<const DH_PublicKey*>(pub_key.get())) + { + DH_PrivateKey priv_key(rng, dh_pub->get_domain()); + + PK_Key_Agreement ka(priv_key, "Raw"); - key_material = priv_key.public_value(); + pre_master = strip_leading_zeros( + ka.derive_key(0, dh_pub->public_value()).bits_of()); + + key_material = priv_key.public_value(); + } + else + throw Internal_Error("Server key exchange not a known key type"); } - else if(const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(pub_key)) + else { - pre_master = rng.random_vec(48); - pre_master[0] = (pref_version >> 8) & 0xFF; - pre_master[1] = (pref_version ) & 0xFF; + // No server key exchange msg better mean a RSA key in the cert + + std::auto_ptr<Public_Key> pub_key(peer_certs[0].subject_public_key()); - PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15"); + if(peer_certs.empty()) + throw Internal_Error("No certificate and no server key exchange"); - key_material = encryptor.encrypt(pre_master, rng); + if(const RSA_PublicKey* rsa_pub = dynamic_cast<const RSA_PublicKey*>(pub_key.get())) + { + const Version_Code pref_version = state->client_hello->version(); - if(using_version == SSL_V3) - include_length = false; + pre_master = rng.random_vec(48); + pre_master[0] = (pref_version >> 8) & 0xFF; + pre_master[1] = (pref_version ) & 0xFF; + + PK_Encryptor_EME encryptor(*rsa_pub, "PKCS1v15"); + + key_material = encryptor.encrypt(pre_master, rng); + + if(state->version == SSL_V3) + include_length = false; + } + else + throw TLS_Exception(HANDSHAKE_FAILURE, + "Expected a RSA key in server cert but got " + + pub_key->algo_name()); } - else - throw Invalid_Argument("Client_Key_Exchange: Key not RSA or DH"); - send(writer, hash); + send(writer, state->hash); } /* diff --git a/src/tls/tls_client.cpp b/src/tls/tls_client.cpp index 1d79327e8..48f0aec16 100644 --- a/src/tls/tls_client.cpp +++ b/src/tls/tls_client.cpp @@ -9,9 +9,7 @@ #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> -#include <botan/dh.h> +#include <memory> namespace Botan { @@ -255,9 +253,9 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, throw TLS_Exception(BAD_CERTIFICATE, "TLS_Client: Server certificate is not valid"); - state->kex_pub = peer_certs[0].subject_public_key(); + std::auto_ptr<Public_Key> peer_key(peer_certs[0].subject_public_key()); - if(state->kex_pub->algo_name() != state->suite.sig_algo()) + if(peer_key->algo_name() != state->suite.sig_algo()) throw TLS_Exception(ILLEGAL_PARAMETER, "Certificate key type did not match ciphersuite"); } @@ -276,22 +274,9 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, if(!state->server_kex->verify(peer_certs[0], state)) { throw TLS_Exception(DECRYPT_ERROR, - "Bad signature on server key exchange"); + "Bad signature on server key exchange"); } } - - if(state->kex_pub) - delete state->kex_pub; - - state->kex_pub = state->server_kex->key(); - - // this should be in client_key_exchange - if(dynamic_cast<DH_PublicKey*>(state->kex_pub) && - state->suite.kex_algo() != "DH") - { - throw TLS_Exception(HANDSHAKE_FAILURE, - "Server sent DH key but negotiated something else"); - } } else if(type == CERTIFICATE_REQUEST) { @@ -319,9 +304,10 @@ void TLS_Client::process_handshake_msg(Handshake_Type type, } state->client_kex = - new Client_Key_Exchange(writer, state->hash, rng, - state->kex_pub, state->version, - state->client_hello->version()); + new Client_Key_Exchange(writer, + state, + peer_certs, + rng); state->keys = Session_Keys(state, state->client_kex->pre_master_secret(), diff --git a/src/tls/tls_extensions.cpp b/src/tls/tls_extensions.cpp index d9351fdb1..570c7161c 100644 --- a/src/tls/tls_extensions.cpp +++ b/src/tls/tls_extensions.cpp @@ -364,6 +364,8 @@ MemoryVector<byte> Supported_Elliptic_Curves::serialize() const buf[0] = get_byte<u16bit>(0, buf.size()-2); buf[1] = get_byte<u16bit>(1, buf.size()-2); + + return buf; } Supported_Elliptic_Curves::Supported_Elliptic_Curves() diff --git a/src/tls/tls_handshake_state.cpp b/src/tls/tls_handshake_state.cpp index c424c9726..6ad9b630c 100644 --- a/src/tls/tls_handshake_state.cpp +++ b/src/tls/tls_handshake_state.cpp @@ -89,7 +89,6 @@ TLS_Handshake_State::TLS_Handshake_State() client_finished = 0; server_finished = 0; - kex_pub = 0; kex_priv = 0; version = SSL_V3; @@ -264,7 +263,6 @@ TLS_Handshake_State::~TLS_Handshake_State() delete client_finished; delete server_finished; - delete kex_pub; delete kex_priv; } diff --git a/src/tls/tls_handshake_state.h b/src/tls/tls_handshake_state.h index b2ed0dd20..18b289fe1 100644 --- a/src/tls/tls_handshake_state.h +++ b/src/tls/tls_handshake_state.h @@ -76,7 +76,6 @@ class TLS_Handshake_State class Finished* client_finished; class Finished* server_finished; - Public_Key* kex_pub; Private_Key* kex_priv; TLS_Ciphersuite suite; diff --git a/src/tls/tls_messages.h b/src/tls/tls_messages.h index ffc325a89..e58a3bfbf 100644 --- a/src/tls/tls_messages.h +++ b/src/tls/tls_messages.h @@ -210,11 +210,9 @@ class Client_Key_Exchange : public Handshake_Message Version_Code version); Client_Key_Exchange(Record_Writer& output, - TLS_Handshake_Hash& hash, - RandomNumberGenerator& rng, - const Public_Key* my_key, - Version_Code using_version, - Version_Code pref_version); + TLS_Handshake_State* state, + const std::vector<X509_Certificate>& peer_certs, + RandomNumberGenerator& rng); Client_Key_Exchange(const MemoryRegion<byte>& buf, const TLS_Ciphersuite& suite, |