diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/tls/info.txt | 3 | ||||
-rw-r--r-- | src/tls/rec_read.cpp | 116 | ||||
-rw-r--r-- | src/tls/tls_channel.cpp | 58 | ||||
-rw-r--r-- | src/tls/tls_channel.h | 17 | ||||
-rw-r--r-- | src/tls/tls_handshake_io.cpp | 1 | ||||
-rw-r--r-- | src/tls/tls_record.cpp | 2 | ||||
-rw-r--r-- | src/tls/tls_record.h | 53 |
7 files changed, 56 insertions, 194 deletions
diff --git a/src/tls/info.txt b/src/tls/info.txt index 0c31b268b..7ffc26438 100644 --- a/src/tls/info.txt +++ b/src/tls/info.txt @@ -16,7 +16,6 @@ tls_exceptn.h tls_handshake_msg.h tls_magic.h tls_policy.h -tls_record.h tls_server.h tls_session.h tls_session_manager.h @@ -31,6 +30,7 @@ tls_handshake_state.h tls_heartbeats.h tls_messages.h tls_reader.h +tls_record.h tls_session_key.h </header:internal> @@ -46,7 +46,6 @@ msg_next_protocol.cpp msg_server_hello.cpp msg_server_kex.cpp msg_session_ticket.cpp -rec_read.cpp tls_alert.cpp tls_channel.cpp tls_ciphersuite.cpp diff --git a/src/tls/rec_read.cpp b/src/tls/rec_read.cpp deleted file mode 100644 index 10184e735..000000000 --- a/src/tls/rec_read.cpp +++ /dev/null @@ -1,116 +0,0 @@ -/* -* TLS Record Reading -* (C) 2004-2012 Jack Lloyd -* -* Released under the terms of the Botan license -*/ - -#include <botan/tls_record.h> -#include <botan/tls_exceptn.h> -#include <botan/internal/rounding.h> - -namespace Botan { - -namespace TLS { - -Record_Reader::Record_Reader() : - m_readbuf(TLS_HEADER_SIZE + MAX_CIPHERTEXT_SIZE) - { - reset(); - set_maximum_fragment_size(0); - } - -/* -* Reset the state -*/ -void Record_Reader::reset() - { - set_maximum_fragment_size(0); - - zeroise(m_readbuf); - m_readbuf_pos = 0; - - m_read_cipherstate.reset(); - - m_version = Protocol_Version(); - m_read_seq_no = 0; - } - -void Record_Reader::set_maximum_fragment_size(size_t max_fragment) - { - if(max_fragment == 0) - m_max_fragment = MAX_PLAINTEXT_SIZE; - else - m_max_fragment = clamp(max_fragment, 128, MAX_PLAINTEXT_SIZE); - } - -/* -* Set the version to use -*/ -void Record_Reader::set_version(Protocol_Version version) - { - m_version = version; - } - -Protocol_Version Record_Reader::get_version() const - { - return m_version; - } - -/* -* Set the keys for reading -*/ -void Record_Reader::change_cipher_spec(Connection_Side side, - const Ciphersuite& suite, - const Session_Keys& keys, - byte compression_method) - { - if(compression_method != NO_COMPRESSION) - throw Internal_Error("Negotiated unknown compression algorithm"); - - m_read_seq_no = 0; - - // flip side as we are reading - side = (side == CLIENT) ? SERVER : CLIENT; - - m_read_cipherstate.reset( - new Connection_Cipher_State(m_version, side, suite, keys) - ); - } - -/* -* Retrieve the next record -*/ -size_t Record_Reader::add_input(const byte input_array[], size_t input_sz, - size_t& consumed, - byte& msg_type, - std::vector<byte>& msg, - u64bit& msg_sequence) - { - const size_t needed = read_record(m_readbuf, - m_readbuf_pos, - input_array, - input_sz, - consumed, - msg_type, - msg, - m_read_seq_no, - m_version, - m_read_cipherstate.get()); - - if(needed) - return needed; - - // full message decoded - if(msg.size() > m_max_fragment) - throw TLS_Exception(Alert::RECORD_OVERFLOW, "Plaintext record is too large"); - - msg_sequence = m_read_seq_no; - m_read_seq_no += 1; - - return 0; - } - -} - -} diff --git a/src/tls/tls_channel.cpp b/src/tls/tls_channel.cpp index 11a4971c2..024aec099 100644 --- a/src/tls/tls_channel.cpp +++ b/src/tls/tls_channel.cpp @@ -9,6 +9,7 @@ #include <botan/internal/tls_handshake_state.h> #include <botan/internal/tls_messages.h> #include <botan/internal/tls_heartbeats.h> +#include <botan/internal/tls_record.h> #include <botan/internal/assert.h> #include <botan/internal/rounding.h> #include <botan/loadstor.h> @@ -28,29 +29,29 @@ Channel::Channel(std::function<void (const byte[], size_t)> output_fn, m_session_manager(session_manager), m_proc_fn(proc_fn), m_output_fn(output_fn), - m_writebuf(TLS_HEADER_SIZE + MAX_CIPHERTEXT_SIZE) + m_writebuf(TLS_HEADER_SIZE + MAX_CIPHERTEXT_SIZE), + m_readbuf(TLS_HEADER_SIZE + MAX_CIPHERTEXT_SIZE) { } Channel::~Channel() { + // So unique_ptr destructors run correctly } void Channel::set_protocol_version(Protocol_Version version) { + m_current_version = version; m_state->set_version(version); - m_reader.set_version(version); } Protocol_Version Channel::current_protocol_version() const { - return m_reader.get_version(); + return m_current_version; } void Channel::set_maximum_fragment_size(size_t max_fragment) { - m_reader.set_maximum_fragment_size(max_fragment); - if(max_fragment == 0) m_max_fragment = MAX_PLAINTEXT_SIZE; else @@ -59,10 +60,20 @@ void Channel::set_maximum_fragment_size(size_t max_fragment) void Channel::change_cipher_spec_reader(Connection_Side side) { - m_reader.change_cipher_spec(side, - m_state->ciphersuite(), - m_state->session_keys(), - m_state->server_hello()->compression_method()); + if(m_state->server_hello()->compression_method()!= NO_COMPRESSION) + throw Internal_Error("Negotiated unknown compression algorithm"); + + m_read_seq_no = 0; + + // flip side as we are reading + side = (side == CLIENT) ? SERVER : CLIENT; + + m_read_cipherstate.reset( + new Connection_Cipher_State(current_protocol_version(), + side, + m_state->ciphersuite(), + m_state->session_keys()) + ); } void Channel::change_cipher_spec_writer(Connection_Side side) @@ -114,11 +125,26 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) size_t consumed = 0; - const size_t needed = m_reader.add_input(buf, buf_size, - consumed, - rec_type, - record, - record_number); + const size_t needed = TLS::read_record(m_readbuf, + m_readbuf_pos, + buf, + buf_size, + consumed, + rec_type, + record, + m_read_seq_no, + m_current_version, + m_read_cipherstate.get()); + + if(needed == 0) // full message decoded + { + if(record.size() > m_max_fragment) + throw TLS_Exception(Alert::RECORD_OVERFLOW, + "Plaintext record is too large"); + + record_number = m_read_seq_no; + m_read_seq_no += 1; + } BOTAN_ASSERT(consumed <= buf_size, "Record reader consumed sane amount"); @@ -206,7 +232,7 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) if(alert_msg.type() == Alert::CLOSE_NOTIFY) { if(m_connection_closed) - m_reader.reset(); + m_read_cipherstate.reset(); else send_alert(Alert(Alert::CLOSE_NOTIFY)); // reply in kind } @@ -225,7 +251,7 @@ size_t Channel::received_data(const byte buf[], size_t buf_size) m_state.reset(); m_write_cipherstate.reset(); - m_reader.reset(); + m_read_cipherstate.reset(); } } else diff --git a/src/tls/tls_channel.h b/src/tls/tls_channel.h index 3b53d3539..1730be792 100644 --- a/src/tls/tls_channel.h +++ b/src/tls/tls_channel.h @@ -9,7 +9,6 @@ #define BOTAN_TLS_CHANNEL_H__ #include <botan/tls_policy.h> -#include <botan/tls_record.h> #include <botan/tls_session.h> #include <botan/tls_alert.h> #include <botan/tls_session_manager.h> @@ -164,9 +163,7 @@ class BOTAN_DLL Channel RandomNumberGenerator& m_rng; Session_Manager& m_session_manager; - private: - Record_Reader m_reader; - protected: + std::vector<X509_Certificate> m_peer_certs; Secure_Renegotiation_State m_secure_renegotiation; @@ -176,13 +173,23 @@ class BOTAN_DLL Channel void write_record(byte type, const byte input[], size_t length); + /* callbacks */ std::function<void (const byte[], size_t, Alert)> m_proc_fn; std::function<void (const byte[], size_t)> m_output_fn; + /* writing cipher state */ std::vector<byte> m_writebuf; - std::unique_ptr<Connection_Cipher_State> m_write_cipherstate; + std::unique_ptr<class Connection_Cipher_State> m_write_cipherstate; u64bit m_write_seq_no = 0; + /* reading cipher state */ + std::vector<byte> m_readbuf; + size_t m_readbuf_pos = 0; + std::unique_ptr<class Connection_Cipher_State> m_read_cipherstate; + u64bit m_read_seq_no = 0; + + /* connection parameters */ + Protocol_Version m_current_version; size_t m_max_fragment = MAX_PLAINTEXT_SIZE; bool m_peer_supports_heartbeats = false; diff --git a/src/tls/tls_handshake_io.cpp b/src/tls/tls_handshake_io.cpp index 85bd85c41..fd2e7ea98 100644 --- a/src/tls/tls_handshake_io.cpp +++ b/src/tls/tls_handshake_io.cpp @@ -7,7 +7,6 @@ #include <botan/internal/tls_handshake_io.h> #include <botan/internal/tls_messages.h> -#include <botan/tls_record.h> #include <botan/exceptn.h> namespace Botan { diff --git a/src/tls/tls_record.cpp b/src/tls/tls_record.cpp index 8609b65eb..07804c53c 100644 --- a/src/tls/tls_record.cpp +++ b/src/tls/tls_record.cpp @@ -5,7 +5,7 @@ * Released under the terms of the Botan license */ -#include <botan/tls_record.h> +#include <botan/internal/tls_record.h> #include <botan/libstate.h> #include <botan/loadstor.h> #include <botan/internal/tls_session_key.h> diff --git a/src/tls/tls_record.h b/src/tls/tls_record.h index a1abec9e5..228e8e4a4 100644 --- a/src/tls/tls_record.h +++ b/src/tls/tls_record.h @@ -95,59 +95,6 @@ size_t read_record(std::vector<byte>& read_buffer, Protocol_Version version, Connection_Cipher_State* cipherstate); -/** -* TLS Record Reader -*/ -class BOTAN_DLL Record_Reader - { - public: - - /** - * @param input new input data (may be NULL if input_size == 0) - * @param input_size size of input in bytes - * @param input_consumed is set to the number of bytes of input - * that were consumed - * @param msg_type is set to the type of the message just read if - * this function returns 0 - * @param msg is set to the contents of the record - * @param msg_sequence is set to this records sequence number - * @return number of bytes still needed (minimum), or 0 if success - */ - size_t add_input(const byte input[], size_t input_size, - size_t& input_consumed, - byte& msg_type, - std::vector<byte>& msg, - u64bit& msg_sequence); - - void change_cipher_spec(Connection_Side side, - const Ciphersuite& suite, - const Session_Keys& keys, - byte compression_method); - - void set_version(Protocol_Version version); - - Protocol_Version get_version() const; - - void reset(); - - void set_maximum_fragment_size(size_t max_fragment); - - Record_Reader(); - - Record_Reader(const Record_Reader&) = delete; - Record_Reader& operator=(const Record_Reader&) = delete; - private: - std::vector<byte> m_readbuf; - size_t m_readbuf_pos = 0; - - std::unique_ptr<Connection_Cipher_State> m_read_cipherstate; - - size_t m_max_fragment = MAX_PLAINTEXT_SIZE; - - u64bit m_read_seq_no = 0; - Protocol_Version m_version; - }; - } } |