mirror of
https://github.com/Icinga/icinga2.git
synced 2025-08-25 03:28:12 +02:00
93 lines
3.1 KiB
C++
93 lines
3.1 KiB
C++
//
|
|
// 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 <typename SizeType>
|
|
SizeType read_value(net::const_buffer& buffer) {
|
|
BOOST_ASSERT(buffer.size() >= sizeof(SizeType));
|
|
SizeType ret = *reinterpret_cast<const SizeType*>(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<char, 4> value{};
|
|
std::copy_n(reinterpret_cast<const char*>(buffer.data()), 3, value.begin() + 1);
|
|
buffer += 3;
|
|
return net_to_host(*reinterpret_cast<std::uint32_t*>(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<handshake_type>(read_value<std::uint8_t>(data)))
|
|
, size(read_three_byte_value(data))
|
|
, message(read_message(type, data)) {
|
|
}
|
|
|
|
tls_record::tls_record(net::const_buffer data)
|
|
: type(static_cast<record_type>(read_value<std::uint8_t>(data)))
|
|
, version(static_cast<tls_version>(read_value<std::uint16_t>(data)))
|
|
, size(read_value<std::uint16_t>(data))
|
|
, message(read_message(type, data)) {
|
|
}
|