diff options
Diffstat (limited to 'src/ssl/rec_wri.cpp')
-rw-r--r-- | src/ssl/rec_wri.cpp | 270 |
1 files changed, 0 insertions, 270 deletions
diff --git a/src/ssl/rec_wri.cpp b/src/ssl/rec_wri.cpp deleted file mode 100644 index 59dead3cd..000000000 --- a/src/ssl/rec_wri.cpp +++ /dev/null @@ -1,270 +0,0 @@ -/* -* TLS Record Writing -* (C) 2004-2010 Jack Lloyd -* -* Released under the terms of the Botan license -*/ - -#include <botan/tls_record.h> -#include <botan/internal/tls_handshake_hash.h> -#include <botan/lookup.h> -#include <botan/loadstor.h> -#include <botan/libstate.h> - -namespace Botan { - -/** -* Record_Writer Constructor -*/ -Record_Writer::Record_Writer(std::tr1::function<void (const byte[], size_t)> out) : - output_fn(out), - buffer(DEFAULT_BUFFERSIZE) - { - mac = 0; - reset(); - } - -/** -* Reset the state -*/ -void Record_Writer::reset() - { - cipher.reset(); - - delete mac; - mac = 0; - - zeroise(buffer); - buf_pos = 0; - - major = minor = buf_type = 0; - block_size = 0; - mac_size = 0; - iv_size = 0; - - seq_no = 0; - } - -/** -* Set the version to use -*/ -void Record_Writer::set_version(Version_Code version) - { - if(version != SSL_V3 && version != TLS_V10 && version != TLS_V11) - throw Invalid_Argument("Record_Writer: Invalid protocol version"); - - major = (version >> 8) & 0xFF; - minor = (version & 0xFF); - } - -/** -* Set the keys for writing -*/ -void Record_Writer::set_keys(const CipherSuite& suite, const SessionKeys& keys, - Connection_Side side) - { - cipher.reset(); - delete mac; - mac = 0; - - SymmetricKey mac_key, cipher_key; - InitializationVector iv; - - if(side == CLIENT) - { - cipher_key = keys.client_cipher_key(); - iv = keys.client_iv(); - mac_key = keys.client_mac_key(); - } - else - { - cipher_key = keys.server_cipher_key(); - iv = keys.server_iv(); - mac_key = keys.server_mac_key(); - } - - const std::string cipher_algo = suite.cipher_algo(); - const std::string mac_algo = suite.mac_algo(); - - if(have_block_cipher(cipher_algo)) - { - cipher.append(get_cipher( - cipher_algo + "/CBC/NoPadding", - cipher_key, iv, ENCRYPTION) - ); - block_size = block_size_of(cipher_algo); - - if(major > 3 || (major == 3 && minor >= 2)) - iv_size = block_size; - else - iv_size = 0; - } - else if(have_stream_cipher(cipher_algo)) - { - cipher.append(get_cipher(cipher_algo, cipher_key, ENCRYPTION)); - block_size = 0; - iv_size = 0; - } - else - throw Invalid_Argument("Record_Writer: Unknown cipher " + cipher_algo); - - if(have_hash(mac_algo)) - { - Algorithm_Factory& af = global_state().algorithm_factory(); - - if(major == 3 && minor == 0) - mac = af.make_mac("SSL3-MAC(" + mac_algo + ")"); - else - mac = af.make_mac("HMAC(" + mac_algo + ")"); - - mac->set_key(mac_key); - mac_size = mac->output_length(); - } - else - throw Invalid_Argument("Record_Writer: Unknown hash " + mac_algo); - } - -/** -* Send one or more records to the other side -*/ -void Record_Writer::send(byte type, const byte input[], size_t length) - { - if(type != buf_type) - flush(); - - const size_t BUFFER_SIZE = buffer.size(); - buf_type = type; - - // FIXME: compression right here - - buffer.copy(buf_pos, input, length); - if(buf_pos + length >= BUFFER_SIZE) - { - send_record(buf_type, &buffer[0], length); - input += (BUFFER_SIZE - buf_pos); - length -= (BUFFER_SIZE - buf_pos); - while(length >= BUFFER_SIZE) - { - send_record(buf_type, input, BUFFER_SIZE); - input += BUFFER_SIZE; - length -= BUFFER_SIZE; - } - buffer.copy(input, length); - buf_pos = 0; - } - buf_pos += length; - } - -/** -* Split buffer into records, and send them all -*/ -void Record_Writer::flush() - { - const byte* buf_ptr = &buffer[0]; - size_t offset = 0; - - while(offset != buf_pos) - { - size_t record_size = buf_pos - offset; - if(record_size > MAX_PLAINTEXT_SIZE) - record_size = MAX_PLAINTEXT_SIZE; - - send_record(buf_type, buf_ptr + offset, record_size); - offset += record_size; - } - buf_type = 0; - buf_pos = 0; - } - -/** -* Encrypt and send the record -*/ -void Record_Writer::send_record(byte type, const byte buf[], size_t length) - { - if(length >= MAX_COMPRESSED_SIZE) - throw TLS_Exception(INTERNAL_ERROR, - "Record_Writer: Compressed packet is too big"); - - if(mac_size == 0) - send_record(type, major, minor, buf, length); - else - { - mac->update_be(seq_no); - mac->update(type); - - if(major > 3 || (major == 3 && minor != 0)) - { - mac->update(major); - mac->update(minor); - } - - mac->update(get_byte<u16bit>(0, length)); - mac->update(get_byte<u16bit>(1, length)); - mac->update(buf, length); - - SecureVector<byte> buf_mac = mac->final(); - - // TODO: This could all use a single buffer - cipher.start_msg(); - - if(iv_size) - { - RandomNumberGenerator& rng = global_state().global_rng(); - - SecureVector<byte> random_iv(iv_size); - - rng.randomize(&random_iv[0], random_iv.size()); - - cipher.write(random_iv); - } - - cipher.write(buf, length); - cipher.write(buf_mac); - - if(block_size) - { - size_t pad_val = - (block_size - (1 + length + buf_mac.size())) % block_size; - - for(size_t i = 0; i != pad_val + 1; ++i) - cipher.write(pad_val); - } - cipher.end_msg(); - - SecureVector<byte> output = cipher.read_all(Pipe::LAST_MESSAGE); - - send_record(type, major, minor, &output[0], output.size()); - - seq_no++; - } - } - -/** -* Send a final record packet -*/ -void Record_Writer::send_record(byte type, byte major, byte minor, - const byte out[], size_t length) - { - if(length >= MAX_CIPHERTEXT_SIZE) - throw TLS_Exception(INTERNAL_ERROR, - "Record_Writer: Record is too big"); - - byte header[5] = { type, major, minor, 0 }; - for(size_t i = 0; i != 2; ++i) - header[i+3] = get_byte<u16bit>(i, length); - - output_fn(header, 5); - output_fn(out, length); - } - -/** -* Send an alert -*/ -void Record_Writer::alert(Alert_Level level, Alert_Type type) - { - byte alert[2] = { level, type }; - send(ALERT, alert, sizeof(alert)); - flush(); - } - -} |