Botan
1.11.15
|
00001 /* 00002 * TLS Hello Request and Client Hello Messages 00003 * (C) 2004-2011 Jack Lloyd 00004 * 00005 * Botan is released under the Simplified BSD License (see license.txt) 00006 */ 00007 00008 #include <botan/internal/tls_messages.h> 00009 #include <botan/internal/tls_reader.h> 00010 #include <botan/internal/tls_session_key.h> 00011 #include <botan/internal/tls_handshake_io.h> 00012 #include <botan/internal/stl_util.h> 00013 #include <chrono> 00014 00015 namespace Botan { 00016 00017 namespace TLS { 00018 00019 enum { 00020 TLS_EMPTY_RENEGOTIATION_INFO_SCSV = 0x00FF, 00021 TLS_FALLBACK_SCSV = 0x5600 00022 }; 00023 00024 std::vector<byte> make_hello_random(RandomNumberGenerator& rng, 00025 const Policy& policy) 00026 { 00027 std::vector<byte> buf(32); 00028 rng.randomize(&buf[0], buf.size()); 00029 00030 if(policy.include_time_in_hello_random()) 00031 { 00032 const u32bit time32 = static_cast<u32bit>( 00033 std::chrono::system_clock::to_time_t(std::chrono::system_clock::now())); 00034 00035 store_be(time32, &buf[0]); 00036 } 00037 00038 return buf; 00039 } 00040 00041 /* 00042 * Create a new Hello Request message 00043 */ 00044 Hello_Request::Hello_Request(Handshake_IO& io) 00045 { 00046 io.send(*this); 00047 } 00048 00049 /* 00050 * Deserialize a Hello Request message 00051 */ 00052 Hello_Request::Hello_Request(const std::vector<byte>& buf) 00053 { 00054 if(buf.size()) 00055 throw Decoding_Error("Bad Hello_Request, has non-zero size"); 00056 } 00057 00058 /* 00059 * Serialize a Hello Request message 00060 */ 00061 std::vector<byte> Hello_Request::serialize() const 00062 { 00063 return std::vector<byte>(); 00064 } 00065 00066 /* 00067 * Create a new Client Hello message 00068 */ 00069 Client_Hello::Client_Hello(Handshake_IO& io, 00070 Handshake_Hash& hash, 00071 Protocol_Version version, 00072 const Policy& policy, 00073 RandomNumberGenerator& rng, 00074 const std::vector<byte>& reneg_info, 00075 bool next_protocol, 00076 const std::string& hostname, 00077 const std::string& srp_identifier) : 00078 m_version(version), 00079 m_random(make_hello_random(rng, policy)), 00080 m_suites(policy.ciphersuite_list(m_version, (srp_identifier != ""))), 00081 m_comp_methods(policy.compression()) 00082 { 00083 m_extensions.add(new Renegotiation_Extension(reneg_info)); 00084 m_extensions.add(new SRP_Identifier(srp_identifier)); 00085 m_extensions.add(new Server_Name_Indicator(hostname)); 00086 m_extensions.add(new Session_Ticket()); 00087 m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves())); 00088 00089 if(policy.negotiate_heartbeat_support()) 00090 m_extensions.add(new Heartbeat_Support_Indicator(true)); 00091 00092 if(m_version.supports_negotiable_signature_algorithms()) 00093 m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), 00094 policy.allowed_signature_methods())); 00095 00096 if(m_version.is_datagram_protocol()) 00097 m_extensions.add(new SRTP_Protection_Profiles(policy.srtp_profiles())); 00098 00099 if(reneg_info.empty() && next_protocol) 00100 m_extensions.add(new Next_Protocol_Notification()); 00101 00102 BOTAN_ASSERT(policy.acceptable_protocol_version(version), 00103 "Our policy accepts the version we are offering"); 00104 00105 if(policy.send_fallback_scsv(version)) 00106 m_suites.push_back(TLS_FALLBACK_SCSV); 00107 00108 hash.update(io.send(*this)); 00109 } 00110 00111 /* 00112 * Create a new Client Hello message (session resumption case) 00113 */ 00114 Client_Hello::Client_Hello(Handshake_IO& io, 00115 Handshake_Hash& hash, 00116 const Policy& policy, 00117 RandomNumberGenerator& rng, 00118 const std::vector<byte>& reneg_info, 00119 const Session& session, 00120 bool next_protocol) : 00121 m_version(session.version()), 00122 m_session_id(session.session_id()), 00123 m_random(make_hello_random(rng, policy)), 00124 m_suites(policy.ciphersuite_list(m_version, (session.srp_identifier() != ""))), 00125 m_comp_methods(policy.compression()) 00126 { 00127 if(!value_exists(m_suites, session.ciphersuite_code())) 00128 m_suites.push_back(session.ciphersuite_code()); 00129 00130 if(!value_exists(m_comp_methods, session.compression_method())) 00131 m_comp_methods.push_back(session.compression_method()); 00132 00133 m_extensions.add(new Renegotiation_Extension(reneg_info)); 00134 m_extensions.add(new SRP_Identifier(session.srp_identifier())); 00135 m_extensions.add(new Server_Name_Indicator(session.server_info().hostname())); 00136 m_extensions.add(new Session_Ticket(session.session_ticket())); 00137 m_extensions.add(new Supported_Elliptic_Curves(policy.allowed_ecc_curves())); 00138 00139 if(policy.negotiate_heartbeat_support()) 00140 m_extensions.add(new Heartbeat_Support_Indicator(true)); 00141 00142 if(session.fragment_size() != 0) 00143 m_extensions.add(new Maximum_Fragment_Length(session.fragment_size())); 00144 00145 if(m_version.supports_negotiable_signature_algorithms()) 00146 m_extensions.add(new Signature_Algorithms(policy.allowed_signature_hashes(), 00147 policy.allowed_signature_methods())); 00148 00149 if(reneg_info.empty() && next_protocol) 00150 m_extensions.add(new Next_Protocol_Notification()); 00151 00152 hash.update(io.send(*this)); 00153 } 00154 00155 void Client_Hello::update_hello_cookie(const Hello_Verify_Request& hello_verify) 00156 { 00157 if(!m_version.is_datagram_protocol()) 00158 throw std::runtime_error("Cannot use hello cookie with stream protocol"); 00159 00160 m_hello_cookie = hello_verify.cookie(); 00161 } 00162 00163 /* 00164 * Serialize a Client Hello message 00165 */ 00166 std::vector<byte> Client_Hello::serialize() const 00167 { 00168 std::vector<byte> buf; 00169 00170 buf.push_back(m_version.major_version()); 00171 buf.push_back(m_version.minor_version()); 00172 buf += m_random; 00173 00174 append_tls_length_value(buf, m_session_id, 1); 00175 00176 if(m_version.is_datagram_protocol()) 00177 append_tls_length_value(buf, m_hello_cookie, 1); 00178 00179 append_tls_length_value(buf, m_suites, 2); 00180 append_tls_length_value(buf, m_comp_methods, 1); 00181 00182 /* 00183 * May not want to send extensions at all in some cases. If so, 00184 * should include SCSV value (if reneg info is empty, if not we are 00185 * renegotiating with a modern server) 00186 */ 00187 00188 buf += m_extensions.serialize(); 00189 00190 return buf; 00191 } 00192 00193 /* 00194 * Read a counterparty client hello 00195 */ 00196 Client_Hello::Client_Hello(const std::vector<byte>& buf) 00197 { 00198 if(buf.size() == 0) 00199 throw Decoding_Error("Client_Hello: Packet corrupted"); 00200 00201 if(buf.size() < 41) 00202 throw Decoding_Error("Client_Hello: Packet corrupted"); 00203 00204 TLS_Data_Reader reader("ClientHello", buf); 00205 00206 const byte major_version = reader.get_byte(); 00207 const byte minor_version = reader.get_byte(); 00208 00209 m_version = Protocol_Version(major_version, minor_version); 00210 00211 m_random = reader.get_fixed<byte>(32); 00212 00213 if(m_version.is_datagram_protocol()) 00214 m_hello_cookie = reader.get_range<byte>(1, 0, 255); 00215 00216 m_session_id = reader.get_range<byte>(1, 0, 32); 00217 00218 m_suites = reader.get_range_vector<u16bit>(2, 1, 32767); 00219 00220 m_comp_methods = reader.get_range_vector<byte>(1, 1, 255); 00221 00222 m_extensions.deserialize(reader); 00223 00224 if(offered_suite(static_cast<u16bit>(TLS_EMPTY_RENEGOTIATION_INFO_SCSV))) 00225 { 00226 if(Renegotiation_Extension* reneg = m_extensions.get<Renegotiation_Extension>()) 00227 { 00228 if(!reneg->renegotiation_info().empty()) 00229 throw TLS_Exception(Alert::HANDSHAKE_FAILURE, 00230 "Client sent renegotiation SCSV and non-empty extension"); 00231 } 00232 else 00233 { 00234 // add fake extension 00235 m_extensions.add(new Renegotiation_Extension()); 00236 } 00237 } 00238 } 00239 00240 bool Client_Hello::sent_fallback_scsv() const 00241 { 00242 return offered_suite(static_cast<u16bit>(TLS_FALLBACK_SCSV)); 00243 } 00244 00245 /* 00246 * Check if we offered this ciphersuite 00247 */ 00248 bool Client_Hello::offered_suite(u16bit ciphersuite) const 00249 { 00250 for(size_t i = 0; i != m_suites.size(); ++i) 00251 if(m_suites[i] == ciphersuite) 00252 return true; 00253 return false; 00254 } 00255 00256 } 00257 00258 }