userver: userver/engine/io/tls_wrapper.hpp Source File
Loading...
Searching...
No Matches
tls_wrapper.hpp
Go to the documentation of this file.
1#pragma once
2
3/// @file userver/engine/io/tls_wrapper.hpp
4/// @brief TLS socket wrappers
5
6#include <string>
7#include <vector>
8
9#include <userver/crypto/certificate.hpp>
10#include <userver/crypto/private_key.hpp>
11#include <userver/engine/deadline.hpp>
12#include <userver/engine/io/common.hpp>
13#include <userver/engine/io/socket.hpp>
14#include <userver/utils/fast_pimpl.hpp>
15
16USERVER_NAMESPACE_BEGIN
17
18namespace engine::io {
19
20/// Class for TLS communications over a Socket.
21///
22/// Not thread safe. E.g. you MAY NOT read and write concurrently from multiple
23/// coroutines.
24///
25/// Usage example:
26/// @snippet src/engine/io/tls_wrapper_test.cpp TLS wrapper usage
27class [[nodiscard]] TlsWrapper final : public RwBase {
28public:
29 /// Starts a TLS client on an opened socket
30 static TlsWrapper StartTlsClient(Socket&& socket, const std::string& server_name, Deadline deadline);
31
32 /// Starts a TLS client with client cert on an opened socket
33 static TlsWrapper StartTlsClient(
34 Socket&& socket,
35 const std::string& server_name,
36 const crypto::Certificate& cert,
37 const crypto::PrivateKey& key,
38 Deadline deadline,
39 const std::vector<crypto::Certificate>& extra_cert_authorities = {}
40 );
41
42 /// Starts a TLS server on an opened socket
43 static TlsWrapper StartTlsServer(
44 Socket&& socket,
45 const crypto::Certificate& cert,
46 const crypto::PrivateKey& key,
47 Deadline deadline,
48 const std::vector<crypto::Certificate>& extra_cert_authorities = {}
49 );
50
51 ~TlsWrapper() override;
52
53 TlsWrapper(const TlsWrapper&) = delete;
54 TlsWrapper(TlsWrapper&&) noexcept;
55
56 /// Whether the socket is valid.
57 explicit operator bool() const { return IsValid(); }
58
59 /// Whether the socket is valid.
60 bool IsValid() const override;
61
62 /// Suspends current task until the socket has data available.
63 [[nodiscard]] bool WaitReadable(Deadline) override;
64
65 /// Suspends current task until the socket can accept more data.
66 [[nodiscard]] bool WaitWriteable(Deadline) override;
67
68 /// @brief Receives at least one byte from the socket.
69 /// @returns 0 if connection is closed on one side and no data could be
70 /// received any more, received bytes count otherwise.
71 [[nodiscard]] size_t RecvSome(void* buf, size_t len, Deadline deadline);
72
73 /// @brief Receives exactly len bytes from the socket.
74 /// @note Can return less than len if socket is closed by peer.
75 [[nodiscard]] size_t RecvAll(void* buf, size_t len, Deadline deadline);
76
77 /// @brief Sends exactly len bytes to the socket.
78 /// @note Can return less than len if socket is closed by peer.
79 [[nodiscard]] size_t SendAll(const void* buf, size_t len, Deadline deadline);
80
81 /// @brief Finishes TLS session and returns the socket.
82 /// @warning Wrapper becomes invalid on entry and can only be used to retry
83 /// socket extraction if interrupted.
84 [[nodiscard]] Socket StopTls(Deadline deadline);
85
86 /// @brief Receives at least one byte from the socket.
87 /// @returns 0 if connection is closed on one side and no data could be
88 /// received any more, received bytes count otherwise.
89 [[nodiscard]] size_t ReadSome(void* buf, size_t len, Deadline deadline) override {
90 return RecvSome(buf, len, deadline);
91 }
92
93 /// @brief Receives exactly len bytes from the socket.
94 /// @note Can return less than len if socket is closed by peer.
95 [[nodiscard]] size_t ReadAll(void* buf, size_t len, Deadline deadline) override {
96 return RecvAll(buf, len, deadline);
97 }
98
99 /// @brief Writes exactly len bytes to the socket.
100 /// @note Can return less than len if socket is closed by peer.
101 [[nodiscard]] size_t WriteAll(const void* buf, size_t len, Deadline deadline) override {
102 return SendAll(buf, len, deadline);
103 }
104
105 [[nodiscard]] size_t WriteAll(std::initializer_list<IoData> list, Deadline deadline) override;
106
107 int GetRawFd();
108
109private:
110 explicit TlsWrapper(Socket&&);
111
112 void SetupContextAccessors();
113
114 class Impl;
115 class ReadContextAccessor;
116 constexpr static size_t kSize = 336;
117 constexpr static size_t kAlignment = 8;
118 utils::FastPimpl<Impl, kSize, kAlignment> impl_;
119};
120
121} // namespace engine::io
122
123USERVER_NAMESPACE_END