1 /* 2 * TLS Record Handling 3 * (C) 2004-2012 Jack Lloyd 4 * 2016 Matthias Gierlings 5 * 6 * Botan is released under the Simplified BSD License (see license.txt) 7 */ 8 9 #ifndef BOTAN_TLS_RECORDS_H_ 10 #define BOTAN_TLS_RECORDS_H_ 11 12 #include <botan/tls_algos.h> 13 #include <botan/tls_magic.h> 14 #include <botan/tls_version.h> 15 #include <botan/aead.h> 16 #include <vector> 17 #include <chrono> 18 #include <functional> 19 20 namespace Botan { 21 22 namespace TLS { 23 24 class Ciphersuite; 25 class Session_Keys; 26 27 class Connection_Sequence_Numbers; 28 29 /** 30 * TLS Cipher State 31 */ 32 class Connection_Cipher_State final 33 { 34 public: 35 /** 36 * Initialize a new cipher state 37 */ 38 Connection_Cipher_State(Protocol_Version version, 39 Connection_Side which_side, 40 bool is_our_side, 41 const Ciphersuite& suite, 42 const Session_Keys& keys, 43 bool uses_encrypt_then_mac); 44 aead()45 AEAD_Mode& aead() 46 { 47 BOTAN_ASSERT_NONNULL(m_aead.get()); 48 return *m_aead.get(); 49 } 50 51 std::vector<uint8_t> aead_nonce(uint64_t seq, RandomNumberGenerator& rng); 52 53 std::vector<uint8_t> aead_nonce(const uint8_t record[], size_t record_len, uint64_t seq); 54 55 std::vector<uint8_t> format_ad(uint64_t seq, uint8_t type, 56 Protocol_Version version, 57 uint16_t ptext_length); 58 nonce_bytes_from_handshake()59 size_t nonce_bytes_from_handshake() const { return m_nonce_bytes_from_handshake; } nonce_bytes_from_record()60 size_t nonce_bytes_from_record() const { return m_nonce_bytes_from_record; } 61 nonce_format()62 Nonce_Format nonce_format() const { return m_nonce_format; } 63 age()64 std::chrono::seconds age() const 65 { 66 return std::chrono::duration_cast<std::chrono::seconds>( 67 std::chrono::system_clock::now() - m_start_time); 68 } 69 70 private: 71 std::chrono::system_clock::time_point m_start_time; 72 std::unique_ptr<AEAD_Mode> m_aead; 73 74 std::vector<uint8_t> m_nonce; 75 Nonce_Format m_nonce_format; 76 size_t m_nonce_bytes_from_handshake; 77 size_t m_nonce_bytes_from_record; 78 }; 79 80 class Record_Header final 81 { 82 public: Record_Header(uint64_t sequence,Protocol_Version version,Record_Type type)83 Record_Header(uint64_t sequence, 84 Protocol_Version version, 85 Record_Type type) : 86 m_needed(0), 87 m_sequence(sequence), 88 m_version(version), 89 m_type(type) 90 {} 91 Record_Header(size_t needed)92 Record_Header(size_t needed) : 93 m_needed(needed), 94 m_sequence(0), 95 m_version(Protocol_Version()), 96 m_type(NO_RECORD) 97 {} 98 needed()99 size_t needed() const { return m_needed; } 100 version()101 Protocol_Version version() const 102 { 103 BOTAN_ASSERT_NOMSG(m_needed == 0); 104 return m_version; 105 } 106 sequence()107 uint64_t sequence() const 108 { 109 BOTAN_ASSERT_NOMSG(m_needed == 0); 110 return m_sequence; 111 } 112 epoch()113 uint16_t epoch() const 114 { 115 return static_cast<uint16_t>(sequence() >> 48); 116 } 117 type()118 Record_Type type() const 119 { 120 BOTAN_ASSERT_NOMSG(m_needed == 0); 121 return m_type; 122 } 123 124 private: 125 size_t m_needed; 126 uint64_t m_sequence; 127 Protocol_Version m_version; 128 Record_Type m_type; 129 }; 130 131 /** 132 * Create an initial (unencrypted) TLS handshake record 133 * @param write_buffer the output record is placed here 134 * @param record_type the record layer type 135 * @param record_version the record layer version 136 * @param record_sequence the record layer sequence number 137 * @param message the record contents 138 * @param message_len is size of message 139 */ 140 void write_unencrypted_record(secure_vector<uint8_t>& write_buffer, 141 uint8_t record_type, 142 Protocol_Version record_version, 143 uint64_t record_sequence, 144 const uint8_t* message, 145 size_t message_len); 146 147 /** 148 * Create a TLS record 149 * @param write_buffer the output record is placed here 150 * @param record_type the record layer type 151 * @param record_version the record layer version 152 * @param record_sequence the record layer sequence number 153 * @param message the record contents 154 * @param message_len is size of message 155 * @param cipherstate is the writing cipher state 156 * @param rng is a random number generator 157 */ 158 void write_record(secure_vector<uint8_t>& write_buffer, 159 uint8_t record_type, 160 Protocol_Version record_version, 161 uint64_t record_sequence, 162 const uint8_t* message, 163 size_t message_len, 164 Connection_Cipher_State& cipherstate, 165 RandomNumberGenerator& rng); 166 167 // epoch -> cipher state 168 typedef std::function<std::shared_ptr<Connection_Cipher_State> (uint16_t)> get_cipherstate_fn; 169 170 /** 171 * Decode a TLS record 172 * @return zero if full message, else number of bytes still needed 173 */ 174 Record_Header read_record(bool is_datagram, 175 secure_vector<uint8_t>& read_buffer, 176 const uint8_t input[], 177 size_t input_len, 178 size_t& consumed, 179 secure_vector<uint8_t>& record_buf, 180 Connection_Sequence_Numbers* sequence_numbers, 181 get_cipherstate_fn get_cipherstate, 182 bool allow_epoch0_restart); 183 184 } 185 186 } 187 188 #endif 189