include/boost/corosio/tls_stream.hpp

100.0% Lines (6/6) 100.0% Functions (4/4) 100.0% Branches (2/2)
include/boost/corosio/tls_stream.hpp
Line Branch TLA Hits Source Code
1 //
2 // Copyright (c) 2025 Vinnie Falco ([email protected])
3 //
4 // Distributed under the Boost Software License, Version 1.0. (See accompanying
5 // file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
6 //
7 // Official repository: https://github.com/cppalliance/corosio
8 //
9
10 #ifndef BOOST_COROSIO_TLS_STREAM_HPP
11 #define BOOST_COROSIO_TLS_STREAM_HPP
12
13 #include <boost/corosio/detail/config.hpp>
14 #include <boost/capy/buffers.hpp>
15 #include <boost/capy/buffers/buffer_array.hpp>
16 #include <boost/capy/io/any_stream.hpp>
17 #include <boost/capy/io_task.hpp>
18
19 #include <cstddef>
20 #include <string_view>
21
22 namespace boost::corosio {
23
24 /** Abstract base class for TLS streams.
25
26 This class provides a runtime-polymorphic interface for TLS
27 implementations. Derived classes (openssl_stream, wolfssl_stream)
28 implement the virtual functions to provide backend-specific
29 TLS functionality.
30
31 Unlike @ref io_stream which represents OS-level I/O completed
32 by the kernel, TLS streams are coroutine-based: their operations
33 are implemented as coroutines that orchestrate sub-operations
34 on the underlying stream.
35
36 The non-virtual template wrappers (`read_some`, `write_some`)
37 satisfy the `capy::Stream` concept, enabling TLS streams to
38 be used anywhere a Stream is expected.
39
40 @par Thread Safety
41 Distinct objects: Safe.@n
42 Shared objects: Unsafe.
43
44 @see openssl_stream, wolfssl_stream
45 */
46 class BOOST_COROSIO_DECL tls_stream
47 {
48 public:
49 /** Different handshake types. */
50 enum handshake_type
51 {
52 /** Perform handshaking as a client. */
53 client,
54
55 /** Perform handshaking as a server. */
56 server
57 };
58
59 /** Destructor. */
60 2171 virtual ~tls_stream() = default;
61
62 tls_stream(tls_stream const&) = delete;
63 tls_stream& operator=(tls_stream const&) = delete;
64
65 /** Initiate an asynchronous read operation.
66
67 Reads decrypted data into the provided buffer sequence. The
68 operation completes when at least one byte has been read,
69 or an error occurs.
70
71 This non-virtual template wrapper satisfies the `capy::Stream`
72 concept by delegating to the virtual `do_read_some`.
73
74 @param buffers The buffer sequence to read data into.
75
76 @return An awaitable yielding `(error_code,std::size_t)`.
77 */
78 template<capy::MutableBufferSequence Buffers>
79 32732 auto read_some(Buffers const& buffers)
80 {
81
1/1
✓ Branch 3 → 4 taken 32732 times.
32732 return do_read_some(buffers);
82 }
83
84 /** Initiate an asynchronous write operation.
85
86 Encrypts and writes data from the provided buffer sequence.
87 The operation completes when at least one byte has been
88 written, or an error occurs.
89
90 This non-virtual template wrapper satisfies the `capy::Stream`
91 concept by delegating to the virtual `do_write_some`.
92
93 @param buffers The buffer sequence containing data to write.
94
95 @return An awaitable yielding `(error_code,std::size_t)`.
96 */
97 template<capy::ConstBufferSequence Buffers>
98 32709 auto write_some(Buffers const& buffers)
99 {
100
1/1
✓ Branch 3 → 4 taken 32709 times.
32709 return do_write_some(buffers);
101 }
102
103 /** Perform the TLS handshake asynchronously.
104
105 Initiates the TLS handshake process. For client connections,
106 this sends the ClientHello and processes the server's response.
107 For server connections, this waits for the ClientHello and
108 sends the server's response.
109
110 @param type The type of handshaking to perform (client or server).
111
112 @return An awaitable yielding `(error_code)`.
113 */
114 virtual capy::io_task<> handshake(handshake_type type) = 0;
115
116 /** Perform a graceful TLS shutdown asynchronously.
117
118 Initiates the TLS shutdown sequence by sending a close_notify
119 alert and waiting for the peer's close_notify response.
120
121 @return An awaitable yielding `(error_code)`.
122 */
123 virtual capy::io_task<> shutdown() = 0;
124
125 /** Reset TLS session state for reuse.
126
127 Releases TLS session state including session keys and peer
128 certificates, returning the stream to a state where
129 `handshake()` can be called again. Internal memory
130 allocations (I/O buffers) are preserved.
131
132 Calling `handshake()` on a previously-used stream
133 implicitly performs a reset first, so explicit calls
134 are only needed to eagerly release session state.
135
136 @par Preconditions
137 No TLS operation (handshake, read, write, shutdown) is
138 in progress.
139
140 @par Thread Safety
141 Not thread safe. The caller must ensure no concurrent
142 operations are in progress on this stream.
143
144 @note If called mid-session before `shutdown()`, pending
145 TLS data is discarded and the peer will observe a
146 truncated stream.
147 */
148 virtual void reset() = 0;
149
150 /** Returns a reference to the underlying stream.
151
152 Provides access to the type-erased underlying stream for
153 operations like cancellation or accessing native handles.
154
155 @warning Do not reseat (assign to) the returned reference.
156 The TLS implementation holds internal state bound to
157 the original stream. Replacing it causes undefined
158 behavior.
159
160 @return Reference to the wrapped stream.
161 */
162 virtual capy::any_stream& next_layer() noexcept = 0;
163
164 /** Returns a const reference to the underlying stream.
165
166 @return Const reference to the wrapped stream.
167 */
168 virtual capy::any_stream const& next_layer() const noexcept = 0;
169
170 /** Returns the name of the TLS backend.
171
172 @return A string identifying the TLS implementation,
173 such as "openssl" or "wolfssl".
174 */
175 virtual std::string_view name() const noexcept = 0;
176
177 protected:
178 2171 tls_stream() = default;
179
180 /** Virtual read implementation.
181
182 Derived classes override this to perform TLS decryption
183 and read operations.
184
185 @param buffers Buffer sequence to read into.
186
187 @return An awaitable yielding `(error_code,std::size_t)`.
188 */
189 virtual capy::io_task<std::size_t> do_read_some(
190 capy::mutable_buffer_array<capy::detail::max_iovec_> buffers) = 0;
191
192 /** Virtual write implementation.
193
194 Derived classes override this to perform TLS encryption
195 and write operations.
196
197 @param buffers Buffer sequence to write from.
198
199 @return An awaitable yielding `(error_code,std::size_t)`.
200 */
201 virtual capy::io_task<std::size_t> do_write_some(
202 capy::const_buffer_array<capy::detail::max_iovec_> buffers) = 0;
203 };
204
205 } // namespace boost::corosio
206
207 #endif
208