Botan
1.11.15
|
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