/* * Copyright (c) 2020, Ali Mohammad Pur * Copyright (c) 2025, Altomani Gianluca * * SPDX-License-Identifier: BSD-2-Clause */ #pragma once #include #include #include namespace TLS { struct Options { #define OPTION_WITH_DEFAULTS(typ, name, ...) \ static typ default_##name() \ { \ return typ { __VA_ARGS__ }; \ } \ typ name = default_##name(); \ Options& set_##name(typ new_value) & \ { \ name = move(new_value); \ return *this; \ } \ Options&& set_##name(typ new_value) && \ { \ name = move(new_value); \ return move(*this); \ } OPTION_WITH_DEFAULTS(Optional, root_certificates_path, ) OPTION_WITH_DEFAULTS(bool, blocking, true) }; class TLSv12 final : public Core::Socket { public: /// Reads into a buffer, with the maximum size being the size of the buffer. /// The amount of bytes read can be smaller than the size of the buffer. /// Returns either the bytes that were read, or an error in the case of /// failure. virtual ErrorOr read_some(Bytes) override; /// Tries to write the entire contents of the buffer. It is possible for /// less than the full buffer to be written. Returns either the amount of /// bytes written into the stream, or an error in the case of failure. virtual ErrorOr write_some(ReadonlyBytes) override; virtual bool is_eof() const override; virtual bool is_open() const override; virtual void close() override; virtual ErrorOr pending_bytes() const override; virtual ErrorOr can_read_without_blocking(int = 0) const override; virtual ErrorOr set_blocking(bool block) override; virtual ErrorOr set_close_on_exec(bool enabled) override; static ErrorOr> connect(Core::SocketAddress const&, ByteString const& host, Options = {}); static ErrorOr> connect(ByteString const& host, u16 port, Options = {}); ~TLSv12() override; private: explicit TLSv12(NonnullOwnPtr, SSL_CTX*, SSL*); static ErrorOr> connect_internal(NonnullOwnPtr, ByteString const&, Options); void handle_fatal_error(); SSL_CTX* m_ssl_ctx { nullptr }; SSL* m_ssl { nullptr }; // Keep this around or the socket will be closed NonnullOwnPtr m_socket; }; }