Botan  1.11.15
src/lib/tls/msg_server_hello.cpp
Go to the documentation of this file.
00001 ;/*
00002 * TLS Server Hello and Server Hello Done
00003 * (C) 2004-2011,2015 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_extensions.h>
00012 #include <botan/internal/tls_handshake_io.h>
00013 #include <botan/internal/stl_util.h>
00014 
00015 namespace Botan {
00016 
00017 namespace TLS {
00018 
00019 // New session case
00020 Server_Hello::Server_Hello(Handshake_IO& io,
00021                            Handshake_Hash& hash,
00022                            const Policy& policy,
00023                            RandomNumberGenerator& rng,
00024                            const std::vector<byte>& reneg_info,
00025                            const Client_Hello& client_hello,
00026                            const std::vector<byte>& new_session_id,
00027                            Protocol_Version new_session_version,
00028                            u16bit ciphersuite,
00029                            byte compression,
00030                            bool offer_session_ticket,
00031                            const std::vector<std::string>& next_protocols) :
00032    m_version(new_session_version),
00033    m_session_id(new_session_id),
00034    m_random(make_hello_random(rng, policy)),
00035    m_ciphersuite(ciphersuite),
00036    m_comp_method(compression)
00037    {
00038    if(client_hello.secure_renegotiation())
00039       m_extensions.add(new Renegotiation_Extension(reneg_info));
00040 
00041    if(client_hello.supports_session_ticket() && offer_session_ticket)
00042       m_extensions.add(new Session_Ticket());
00043 
00044    if(size_t max_fragment_size = client_hello.fragment_size())
00045       m_extensions.add(new Maximum_Fragment_Length(max_fragment_size));
00046 
00047    if(policy.negotiate_heartbeat_support() && client_hello.supports_heartbeats())
00048       m_extensions.add(new Heartbeat_Support_Indicator(true));
00049 
00050    if(client_hello.next_protocol_notification())
00051       m_extensions.add(new Next_Protocol_Notification(next_protocols));
00052 
00053    if(m_version.is_datagram_protocol())
00054       {
00055       const std::vector<u16bit> server_srtp = policy.srtp_profiles();
00056       const std::vector<u16bit> client_srtp = client_hello.srtp_profiles();
00057 
00058       if(!server_srtp.empty() && !client_srtp.empty())
00059          {
00060          u16bit shared = 0;
00061          // always using server preferences for now
00062          for(auto s : server_srtp)
00063             for(auto c : client_srtp)
00064                {
00065                if(shared == 0 && s == c)
00066                   shared = s;
00067                }
00068 
00069          if(shared)
00070             m_extensions.add(new SRTP_Protection_Profiles(shared));
00071          }
00072       }
00073 
00074    hash.update(io.send(*this));
00075    }
00076 
00077 // Resuming
00078 Server_Hello::Server_Hello(Handshake_IO& io,
00079                            Handshake_Hash& hash,
00080                            const Policy& policy,
00081                            RandomNumberGenerator& rng,
00082                            const std::vector<byte>& reneg_info,
00083                            const Client_Hello& client_hello,
00084                            Session& resumed_session,
00085                            bool offer_session_ticket,
00086                            const std::vector<std::string>& next_protocols) :
00087    m_version(resumed_session.version()),
00088    m_session_id(client_hello.session_id()),
00089    m_random(make_hello_random(rng, policy)),
00090    m_ciphersuite(resumed_session.ciphersuite_code()),
00091    m_comp_method(resumed_session.compression_method())
00092    {
00093    if(client_hello.secure_renegotiation())
00094       m_extensions.add(new Renegotiation_Extension(reneg_info));
00095 
00096    if(client_hello.supports_session_ticket() && offer_session_ticket)
00097       m_extensions.add(new Session_Ticket());
00098 
00099    if(size_t max_fragment_size = resumed_session.fragment_size())
00100       m_extensions.add(new Maximum_Fragment_Length(max_fragment_size));
00101 
00102    if(policy.negotiate_heartbeat_support() && client_hello.supports_heartbeats())
00103       m_extensions.add(new Heartbeat_Support_Indicator(true));
00104 
00105    if(client_hello.next_protocol_notification())
00106       m_extensions.add(new Next_Protocol_Notification(next_protocols));
00107 
00108    hash.update(io.send(*this));
00109    }
00110 
00111 /*
00112 * Deserialize a Server Hello message
00113 */
00114 Server_Hello::Server_Hello(const std::vector<byte>& buf)
00115    {
00116    if(buf.size() < 38)
00117       throw Decoding_Error("Server_Hello: Packet corrupted");
00118 
00119    TLS_Data_Reader reader("ServerHello", buf);
00120 
00121    const byte major_version = reader.get_byte();
00122    const byte minor_version = reader.get_byte();
00123 
00124    m_version = Protocol_Version(major_version, minor_version);
00125 
00126    m_random = reader.get_fixed<byte>(32);
00127 
00128    m_session_id = reader.get_range<byte>(1, 0, 32);
00129 
00130    m_ciphersuite = reader.get_u16bit();
00131 
00132    m_comp_method = reader.get_byte();
00133 
00134    m_extensions.deserialize(reader);
00135    }
00136 
00137 /*
00138 * Serialize a Server Hello message
00139 */
00140 std::vector<byte> Server_Hello::serialize() const
00141    {
00142    std::vector<byte> buf;
00143 
00144    buf.push_back(m_version.major_version());
00145    buf.push_back(m_version.minor_version());
00146    buf += m_random;
00147 
00148    append_tls_length_value(buf, m_session_id, 1);
00149 
00150    buf.push_back(get_byte(0, m_ciphersuite));
00151    buf.push_back(get_byte(1, m_ciphersuite));
00152 
00153    buf.push_back(m_comp_method);
00154 
00155    buf += m_extensions.serialize();
00156 
00157    return buf;
00158    }
00159 
00160 /*
00161 * Create a new Server Hello Done message
00162 */
00163 Server_Hello_Done::Server_Hello_Done(Handshake_IO& io,
00164                                      Handshake_Hash& hash)
00165    {
00166    hash.update(io.send(*this));
00167    }
00168 
00169 /*
00170 * Deserialize a Server Hello Done message
00171 */
00172 Server_Hello_Done::Server_Hello_Done(const std::vector<byte>& buf)
00173    {
00174    if(buf.size())
00175       throw Decoding_Error("Server_Hello_Done: Must be empty, and is not");
00176    }
00177 
00178 /*
00179 * Serialize a Server Hello Done message
00180 */
00181 std::vector<byte> Server_Hello_Done::serialize() const
00182    {
00183    return std::vector<byte>();
00184    }
00185 
00186 }
00187 
00188 }