Botan  1.11.15
src/lib/tls/tls_record.h
Go to the documentation of this file.
00001 /*
00002 * TLS Record Handling
00003 * (C) 2004-2012 Jack Lloyd
00004 *
00005 * Botan is released under the Simplified BSD License (see license.txt)
00006 */
00007 
00008 #ifndef BOTAN_TLS_RECORDS_H__
00009 #define BOTAN_TLS_RECORDS_H__
00010 
00011 #include <botan/tls_magic.h>
00012 #include <botan/tls_version.h>
00013 #include <botan/aead.h>
00014 #include <botan/block_cipher.h>
00015 #include <botan/stream_cipher.h>
00016 #include <botan/mac.h>
00017 #include <vector>
00018 #include <chrono>
00019 
00020 namespace Botan {
00021 
00022 namespace TLS {
00023 
00024 class Ciphersuite;
00025 class Session_Keys;
00026 
00027 class Connection_Sequence_Numbers;
00028 
00029 /**
00030 * TLS Cipher State
00031 */
00032 class Connection_Cipher_State
00033    {
00034    public:
00035       /**
00036       * Initialize a new cipher state
00037       */
00038       Connection_Cipher_State(Protocol_Version version,
00039                               Connection_Side which_side,
00040                               bool is_our_side,
00041                               const Ciphersuite& suite,
00042                               const Session_Keys& keys);
00043 
00044       AEAD_Mode* aead() { return m_aead.get(); }
00045 
00046       const secure_vector<byte>& aead_nonce(u64bit seq);
00047 
00048       const secure_vector<byte>& aead_nonce(const byte record[], size_t record_len, u64bit seq);
00049 
00050       const secure_vector<byte>& format_ad(u64bit seq, byte type,
00051                                            Protocol_Version version,
00052                                            u16bit ptext_length);
00053 
00054       BlockCipher* block_cipher() { return m_block_cipher.get(); }
00055 
00056       StreamCipher* stream_cipher() { return m_stream_cipher.get(); }
00057 
00058       MessageAuthenticationCode* mac() { return m_mac.get(); }
00059 
00060       secure_vector<byte>& cbc_state() { return m_block_cipher_cbc_state; }
00061 
00062       size_t block_size() const { return m_block_size; }
00063 
00064       size_t mac_size() const { return m_mac->output_length(); }
00065 
00066       size_t iv_size() const { return m_iv_size; }
00067 
00068       size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; }
00069 
00070       size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; }
00071 
00072       bool cbc_without_explicit_iv() const
00073          { return (m_block_size > 0) && (m_iv_size == 0); }
00074 
00075       std::chrono::seconds age() const
00076          {
00077          return std::chrono::duration_cast<std::chrono::seconds>(
00078             std::chrono::system_clock::now() - m_start_time);
00079          }
00080 
00081    private:
00082       std::chrono::system_clock::time_point m_start_time;
00083       std::unique_ptr<BlockCipher> m_block_cipher;
00084       secure_vector<byte> m_block_cipher_cbc_state;
00085       std::unique_ptr<StreamCipher> m_stream_cipher;
00086       std::unique_ptr<MessageAuthenticationCode> m_mac;
00087 
00088       std::unique_ptr<AEAD_Mode> m_aead;
00089       secure_vector<byte> m_nonce, m_ad;
00090 
00091       size_t m_block_size = 0;
00092       size_t m_nonce_bytes_from_handshake;
00093       size_t m_nonce_bytes_from_record;
00094       size_t m_iv_size = 0;
00095    };
00096 
00097 /**
00098 * Create a TLS record
00099 * @param write_buffer the output record is placed here
00100 * @param msg_type is the type of the message (handshake, alert, ...)
00101 * @param msg is the plaintext message
00102 * @param msg_length is the length of msg
00103 * @param msg_sequence is the sequence number
00104 * @param version is the protocol version
00105 * @param cipherstate is the writing cipher state
00106 * @param rng is a random number generator
00107 * @return number of bytes written to write_buffer
00108 */
00109 void write_record(secure_vector<byte>& write_buffer,
00110                   byte msg_type, const byte msg[], size_t msg_length,
00111                   Protocol_Version version,
00112                   u64bit msg_sequence,
00113                   Connection_Cipher_State* cipherstate,
00114                   RandomNumberGenerator& rng);
00115 
00116 // epoch -> cipher state
00117 typedef std::function<std::shared_ptr<Connection_Cipher_State> (u16bit)> get_cipherstate_fn;
00118 
00119 /**
00120 * Decode a TLS record
00121 * @return zero if full message, else number of bytes still needed
00122 */
00123 size_t read_record(secure_vector<byte>& read_buffer,
00124                    const byte input[],
00125                    size_t input_length,
00126                    bool is_datagram,
00127                    size_t& input_consumed,
00128                    secure_vector<byte>& record,
00129                    u64bit* record_sequence,
00130                    Protocol_Version* record_version,
00131                    Record_Type* record_type,
00132                    Connection_Sequence_Numbers* sequence_numbers,
00133                    get_cipherstate_fn get_cipherstate);
00134 
00135 }
00136 
00137 }
00138 
00139 #endif