// // Copyright (c) 2021 Kasper Laudrup (laudrup at stacktrace dot dk) // // Distributed under the Boost Software License, Version 1.0. (See accompanying // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt) // #include "tls_record.hpp" namespace { std::uint8_t net_to_host(std::uint8_t value) { return value; } std::uint16_t net_to_host(std::uint16_t value) { return ntohs(value); } std::uint32_t net_to_host(std::uint32_t value) { return ntohl(value); } template SizeType read_value(net::const_buffer& buffer) { BOOST_ASSERT(buffer.size() >= sizeof(SizeType)); SizeType ret = *reinterpret_cast(buffer.data()); buffer += sizeof(SizeType); return net_to_host(ret); } std::uint32_t read_three_byte_value(net::const_buffer& buffer) { BOOST_ASSERT(buffer.size() >= 3); std::array value{}; std::copy_n(reinterpret_cast(buffer.data()), 3, value.begin() + 1); buffer += 3; return net_to_host(*reinterpret_cast(value.data())); } tls_record::message_type read_message(tls_record::record_type type, net::const_buffer& buffer) { switch(type) { case tls_record::record_type::change_cipher_spec: return tls_change_cipher_spec{}; case tls_record::record_type::alert: return tls_alert{}; case tls_record::record_type::handshake: return tls_handshake{buffer}; case tls_record::record_type::application_data: return tls_application_data{}; } BOOST_UNREACHABLE_RETURN(0); } tls_handshake::message_type read_message(tls_handshake::handshake_type t, net::const_buffer&) { switch(t) { case tls_handshake::handshake_type::hello_request: return tls_handshake::hello_request{}; case tls_handshake::handshake_type::client_hello: return tls_handshake::client_hello{}; case tls_handshake::handshake_type::server_hello: return tls_handshake::server_hello{}; case tls_handshake::handshake_type::certificate: return tls_handshake::certificate{}; case tls_handshake::handshake_type::server_key_exchange: return tls_handshake::server_key_exchange{}; case tls_handshake::handshake_type::certificate_request: return tls_handshake::certificate_request{}; case tls_handshake::handshake_type::server_done: return tls_handshake::server_done{}; case tls_handshake::handshake_type::certificate_verify: return tls_handshake::certificate_verify{}; case tls_handshake::handshake_type::client_key_exchange: return tls_handshake::client_key_exchange{}; case tls_handshake::handshake_type::finished: return tls_handshake::finished{}; } BOOST_UNREACHABLE_RETURN(0); } } // namespace tls_handshake::tls_handshake(net::const_buffer data) : type(static_cast(read_value(data))) , size(read_three_byte_value(data)) , message(read_message(type, data)) { } tls_record::tls_record(net::const_buffer data) : type(static_cast(read_value(data))) , version(static_cast(read_value(data))) , size(read_value(data)) , message(read_message(type, data)) { }