2020-04-21 01:57:23 +04:30
|
|
|
/*
|
2021-04-23 00:43:01 +04:30
|
|
|
* Copyright (c) 2020, Ali Mohammad Pur <mpfard@serenityos.org>
|
2025-02-14 09:49:33 +01:00
|
|
|
* Copyright (c) 2025, Altomani Gianluca <altomanigianluca@gmail.com>
|
2020-04-21 01:57:23 +04:30
|
|
|
*
|
2021-04-22 01:24:48 -07:00
|
|
|
* SPDX-License-Identifier: BSD-2-Clause
|
2020-04-21 01:57:23 +04:30
|
|
|
*/
|
|
|
|
|
|
|
|
#pragma once
|
|
|
|
|
2023-02-08 23:05:44 +01:00
|
|
|
#include <LibCore/Socket.h>
|
2024-11-24 21:55:03 +01:00
|
|
|
#include <LibCrypto/Certificate/Certificate.h>
|
2025-02-14 09:49:33 +01:00
|
|
|
#include <LibTLS/OpenSSLForward.h>
|
2020-04-21 01:57:23 +04:30
|
|
|
|
|
|
|
namespace TLS {
|
|
|
|
|
2024-07-06 23:12:39 +02:00
|
|
|
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); \
|
|
|
|
}
|
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
OPTION_WITH_DEFAULTS(Optional<ByteString>, root_certificates_path, )
|
2025-02-19 14:20:26 +01:00
|
|
|
OPTION_WITH_DEFAULTS(bool, blocking, true)
|
2024-07-06 23:12:39 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
class TLSv12 final : public Core::Socket {
|
2020-04-21 01:57:23 +04:30
|
|
|
public:
|
2024-07-06 23:12:39 +02:00
|
|
|
/// 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.
|
2025-02-14 09:49:33 +01:00
|
|
|
/// Returns either the bytes that were read, or an error in the case of
|
2024-07-06 23:12:39 +02:00
|
|
|
/// failure.
|
|
|
|
virtual ErrorOr<Bytes> 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
|
2025-02-14 09:49:33 +01:00
|
|
|
/// bytes written into the stream, or an error in the case of failure.
|
2024-07-06 23:12:39 +02:00
|
|
|
virtual ErrorOr<size_t> write_some(ReadonlyBytes) override;
|
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
virtual bool is_eof() const override;
|
|
|
|
virtual bool is_open() const override;
|
2024-07-06 23:12:39 +02:00
|
|
|
|
|
|
|
virtual void close() override;
|
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
virtual ErrorOr<size_t> pending_bytes() const override;
|
|
|
|
virtual ErrorOr<bool> can_read_without_blocking(int = 0) const override;
|
|
|
|
virtual ErrorOr<void> set_blocking(bool block) override;
|
|
|
|
virtual ErrorOr<void> set_close_on_exec(bool enabled) override;
|
2022-02-02 19:21:55 +03:30
|
|
|
|
2025-02-22 12:42:48 +01:00
|
|
|
static ErrorOr<NonnullOwnPtr<TLSv12>> connect(Core::SocketAddress const&, ByteString const& host, Options = {});
|
2024-07-06 23:12:39 +02:00
|
|
|
static ErrorOr<NonnullOwnPtr<TLSv12>> connect(ByteString const& host, u16 port, Options = {});
|
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
~TLSv12() override;
|
2020-04-21 01:57:23 +04:30
|
|
|
|
|
|
|
private:
|
2025-02-14 09:49:33 +01:00
|
|
|
explicit TLSv12(NonnullOwnPtr<Core::TCPSocket>, SSL_CTX*, SSL*, BIO*);
|
2024-07-06 23:12:39 +02:00
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
static ErrorOr<NonnullOwnPtr<TLSv12>> connect_internal(NonnullOwnPtr<Core::TCPSocket>, ByteString const&, Options);
|
2024-07-06 23:12:39 +02:00
|
|
|
|
2025-02-22 12:44:22 +01:00
|
|
|
void handle_fatal_error();
|
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
SSL_CTX* m_ssl_ctx { nullptr };
|
|
|
|
SSL* m_ssl { nullptr };
|
|
|
|
BIO* m_bio { nullptr };
|
2024-07-06 23:12:39 +02:00
|
|
|
|
2025-02-14 09:49:33 +01:00
|
|
|
// Keep this around or the socket will be closed
|
|
|
|
NonnullOwnPtr<Core::TCPSocket> m_socket;
|
2020-04-21 01:57:23 +04:30
|
|
|
};
|
2024-07-06 23:12:39 +02:00
|
|
|
|
2020-04-21 01:57:23 +04:30
|
|
|
}
|